Added correct formatting; started docstrings; added min size rel build

develop
Jef Roosens 2020-12-02 12:40:21 +01:00
parent 32184c498c
commit 1052dd6244
6 changed files with 1970 additions and 1909 deletions

1
.clang-format 100644
View File

@ -0,0 +1 @@
IndentWidth: 4

View File

@ -1,17 +1,20 @@
# =====CONFIG=====
SRC_DIR := src
BUILD_DIR := build
RELEASE_DIR := $(BUILD_DIR)/release
DEBUG_DIR := $(BUILD_DIR)/debug
MINSIZEREL_DIR := $(BUILD_DIR)/min_size_rel
BINARY := stj
CORES := $(shell nproc --all)
PREFIX := /usr/local
MANPREFIX := $(PREFIX)/share/man
all: debug
.PHONY: all
# Installation & removal
# =====INSTALL & UNINSTALL=====
install: release
mkdir -p $(DESTDIR)$(PREFIX)/bin
cp -f build/release/stj $(DESTDIR)$(PREFIX)/bin
@ -21,47 +24,16 @@ install: release
chmod 644 $(DESTDIR)$(MANPREFIX)/man1/stj.1
tic -sx data/stj.info
cp -f data/stj.desktop $(DESTDIR)$(PREFIX)/share/applications
.PHONY: install
uninstall:
rm -f $(DESTDIR)$(PREFIX)/bin/stj
rm -f $(DESTDIR)$(MANPREFIX)/man1/stj.1
rm -f $(DESTDIR)$(PREFIX)/share/applications/stj.desktop
.PHONY: uninstall
# Full clean
clean:
@ [ ! -e '$(BINARY)' ] || rm '$(BINARY)'
@ rm -rf '$(BUILD_DIR)'
.PHONY: clean
# Release
run-release: release
@ ./'$(RELEASE_DIR)/$(BINARY)'
.PHONY: run-release
release: $(RELEASE_DIR)/Makefile
@ make -C '$(RELEASE_DIR)' -j'$(CORES)' && \
ln -sf '$(RELEASE_DIR)'/'$(BINARY)' ./'$(BINARY)'
.PHONY: release
$(RELEASE_DIR)/Makefile: $(SRC_DIR)/CMakeLists.txt
@ cmake \
-H'$(SRC_DIR)' \
-B'$(RELEASE_DIR)' \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_EXPORT_COMPILE_COMMANDS=ON
clean-release:
@ rm -rf '$(RELEASE_DIR)'
.PHONY: clean-release
# Debug
run-debug: debug
@ ./'$(DEBUG_DIR)/$(BINARY)'
.PHONY: run-debug
# =====DEBUG=====
debug: $(DEBUG_DIR)/Makefile
@ make -C '$(DEBUG_DIR)' -j'$(CORES)' && \
ln -sf '$(DEBUG_DIR)/$(BINARY)' ./'$(BINARY)'
@ -74,6 +46,48 @@ $(DEBUG_DIR)/Makefile: $(SRC_DIR)/CMakeLists.txt
-DCMAKE_BUILD_TYPE=Debug \
-DCMAKE_EXPORT_COMPILE_COMMANDS=ON
# =====RELEASE=====
release: $(RELEASE_DIR)/Makefile
@ make -C '$(RELEASE_DIR)' -j'$(CORES)' && \
ln -sf '$(RELEASE_DIR)'/'$(BINARY)' ./'$(BINARY)'
.PHONY: release
$(RELEASE_DIR)/Makefile: $(SRC_DIR)/CMakeLists.txt
@ cmake \
-H'$(SRC_DIR)' \
-B'$(RELEASE_DIR)' \
-DCMAKE_BUILD_TYPE=Release \
# =====MINIMUM SIZE RELEASE=====
minsizerel: $(MINSIZEREL_DIR)/Makefile
@ make -C '$(MINSIZEREL_DIR)' -j'$(CORES)' && \
ln -sf '$(MINSIZEREL_DIR)'/'$(BINARY)' ./'$(BINARY)'
.PHONY: minsizerel
$(MINSIZEREL_DIR)/Makefile: $(SRC_DIR)/CMakeLists.txt
@ cmake \
-H'$(SRC_DIR)' \
-B'$(MINSIZEREL_DIR)' \
-DCMAKE_BUILD_TYPE=MinSizeRel \
# =====CLEANING=====
clean:
@ [ ! -e '$(BINARY)' ] || rm '$(BINARY)'
@ rm -rf '$(BUILD_DIR)'
.PHONY: clean
clean-release:
@ rm -rf '$(RELEASE_DIR)'
.PHONY: clean-release
clean-debug:
@ rm -rf '$(DEBUG_DIR)'
.PHONY: clean-debug
# =====FORMAT CODE=====
format:
@ clang-format -i --style=file src/**/*.c src/**/*.h

View File

@ -5,6 +5,8 @@ if (NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Release)
endif()
set(SYSTEM_TYPE x64)
# =====COMPILER=====
set(CMAKE_C_COMPILER "clang-11")
@ -19,13 +21,21 @@ add_definitions(-DVERSION="${CMAKE_PROJECT_VERSION}" -D_XOPEN_SOURCE=600)
# Debug flags
# -g flag gets auto-added by CMake for the debug build
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -Wall -O0 -march=native")
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -fno-omit-frame-pointer -fsanitize=address")
set(CMAKE_LINKER_FLAGS_DEBUG "${CMAKE_LINKER_FLAGS_DEBUG} -fno-omit-frame-pointer -fsanitize=address -pedantic")
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -g -Weverything -O0 -fsanitize=address -fno-omit-frame-pointer")
set(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} -fno-omit-frame-pointer -fsanitize=address -pedantic")
# Arch doesn't use static libraries
if(NOT EXISTS "/etc/arch-release")
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -static-libasan")
set(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} -static-libasan")
endif()
# Release flags
# -O3 gets added automatically by CMake
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -Werror -march=native -pedantic-errors")
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -O3 -Werror -pedantic-errors")
# MinSizeRel flags
# This one's just here for fun
set(CMAKE_C_FLAGS_MINSIZEREL "${CMAKE_C_FLAGS_MINSIZEREL} -Oz -Werror -pedantic-errors")
# =====EXECUTABLE=====
@ -39,8 +49,10 @@ add_executable(stj x.c "${st_SRC}" "${main_SRC}")
find_package(Freetype 2 REQUIRED)
target_include_directories(stj PRIVATE "${FREETYPE_INCLUDE_DIRS}")
target_link_libraries(stj PRIVATE "${FREETYPE_LIBRARIES}")
target_link_libraries(stj PRIVATE Xft)
target_link_libraries(stj PRIVATE Xrender)
find_package(Fontconfig REQUIRED)
find_package(Fontconfig 2 REQUIRED)
target_include_directories(stj PRIVATE "${Fontconfig_INCLUDE_DIRS}")
target_link_libraries(stj PRIVATE "${Fontconfig_LIBRARIES}")
@ -48,8 +60,9 @@ find_package(X11 REQUIRED)
target_include_directories(stj PRIVATE "${X11_INCLUDE_DIR}")
target_link_libraries(stj PRIVATE "${X11_LIBRARIES}")
# Normally provided with clang
target_link_libraries(stj PRIVATE m)
target_link_libraries(stj PRIVATE rt)
# I'm not sure if I actually need this, so keeping it here for reference
# target_link_libraries(stj PRIVATE rt)
target_link_libraries(stj PRIVATE util)
target_link_libraries(stj PRIVATE Xft)
target_link_libraries(stj PRIVATE Xrender)

View File

@ -229,80 +229,119 @@ static uchar utfmask[UTF_SIZE + 1] = {0xC0, 0x80, 0xE0, 0xF0, 0xF8};
static Rune utfmin[UTF_SIZE + 1] = {0, 0, 0x80, 0x800, 0x10000};
static Rune utfmax[UTF_SIZE + 1] = {0x10FFFF, 0x7F, 0x7FF, 0xFFFF, 0x10FFFF};
ssize_t xwrite(int fd, const char *s, size_t len) {
size_t aux = len;
/**
* Same as write, but ensures that all bytes are written to the descriptor
* (write sometimes isn't able to write all bytes)
*
* @param p_file_desc file descriptor to write to; same logic as write
* @param p_str char array to write to the file descriptor
* @param p_nbytes amount of bytes to write
* @return p_nbytes if the write was successful, otherwise return negative error
* value of write
*/
ssize_t xwrite(int p_file_desc, const char *p_str, size_t p_nbytes) {
size_t aux = p_nbytes;
ssize_t result;
while (len > 0) {
result = write(fd, s, len);
while (p_nbytes > 0) {
result = write(p_file_desc, p_str, p_nbytes);
// This means an error occured in write, so it passes the error along
if (result < 0)
return result;
len -= result;
s += result;
p_nbytes -= (size_t)result;
p_str += result;
}
return aux;
return (ssize_t)aux;
}
// Same as malloc, but stops entire program if malloc fails
void *safe_malloc(size_t len) {
/**
* same as malloc, but kill the program if it fails
*
* @param p_len bytes to allocate
* @return pointer to allocated memory
*/
void *safe_malloc(size_t p_len) {
void *ptr;
if (!(ptr = malloc(len)))
if (!(ptr = malloc(p_len)))
die("malloc: %s\n", strerror(errno));
return ptr;
}
// Same as realloc, but stops entire program if malloc fails
void *safe_realloc(void *ptr, size_t len) {
if ((ptr = realloc(ptr, len)) == NULL)
/**
* same as realloc, but kill the program if it fails
*
* @param p_ptr pointer to re-allocate
* @param p_len bytes to re-allocate
* @return pointer to re-allocated memory
*/
void *safe_realloc(void *p_ptr, size_t p_len) {
if ((p_ptr = realloc(p_ptr, p_len)) == NULL)
die("realloc: %s\n", strerror(errno));
return ptr;
return p_ptr;
}
char *safe_strdup(char *s) {
if ((s = strdup(s)) == NULL)
/**
* same as strdup, but kill the program if it fails
*
* @param p_str string to copy
* @return pointer to copy of original string
*/
char *safe_strdup(char *p_str) {
if ((p_str = strdup(p_str)) == NULL)
die("strdup: %s\n", strerror(errno));
return s;
return p_str;
}
size_t utf8decode(const char *chr, Rune *u, size_t chr_len) {
size_t i, j, len, type;
Rune udecoded;
/**
* Decode a given char array into a utf8 Rune
*
* @param p_char char array to decode
* @param p_rune rune pointer to decode to
* @param p_char_len length of the char array
* @return size of the decoded rune
*/
size_t utf8decode(const char *p_char, Rune *p_rune, size_t p_char_len) {
size_t decoded_len, type;
Rune rune_decoded;
*u = UTF_INVALID;
if (!chr_len) // chr_len is 0, so just return 0
*p_rune = UTF_INVALID;
if (!p_char_len) // chr_len is 0, so just return 0
return 0;
udecoded = utf8decodebyte(chr[0], &len);
if (!BETWEEN(len, 1, UTF_SIZE))
rune_decoded = utf8decodebyte(p_char[0], &decoded_len);
if (!BETWEEN(decoded_len, 1, UTF_SIZE))
return 1;
for (i = 1, j = 1; i < chr_len && j < len; ++i, ++j) {
udecoded = (udecoded << 6) | utf8decodebyte(chr[i], &type);
size_t i, j;
for (i = 1, j = 1; i < p_char_len && j < decoded_len; ++i, ++j) {
rune_decoded = (rune_decoded << 6) | utf8decodebyte(p_char[i], &type);
if (type != 0)
return j;
}
if (j < len)
if (j < decoded_len)
return 0;
*u = udecoded;
utf8validate(u, len);
*p_rune = rune_decoded;
utf8validate(p_rune, decoded_len);
return len;
return decoded_len;
}
Rune utf8decodebyte(char c, size_t *i) {
for (*i = 0; *i < LEN(utfmask); ++(*i))
if (((uchar)c & utfmask[*i]) == utfbyte[*i])
return (uchar)c & ~utfmask[*i];
Rune utf8decodebyte(char p_char, size_t *i) {
for (*i = 0; *i < LEN(utfmask); ++(*i)) {
if (((uchar)p_char & utfmask[*i]) == utfbyte[*i])
return (uchar)p_char & ~utfmask[*i];
}
return 0;
}
@ -1019,7 +1058,8 @@ void selscroll(int orig, int n) {
if (sel.ob.x == -1)
return;
if (BETWEEN(sel.nb.y, orig, term.bot) != BETWEEN(sel.ne.y, orig, term.bot)) {
if (BETWEEN(sel.nb.y, orig, term.bot) !=
BETWEEN(sel.ne.y, orig, term.bot)) {
selclear();
} else if (BETWEEN(sel.nb.y, orig, term.bot)) {
sel.ob.y += n;
@ -1247,8 +1287,8 @@ void tsetattr(int *attr, int l) {
switch (attr[i]) {
case 0:
term.c.attr.mode &=
~(ATTR_BOLD | ATTR_FAINT | ATTR_ITALIC | ATTR_UNDERLINE | ATTR_BLINK |
ATTR_REVERSE | ATTR_INVISIBLE | ATTR_STRUCK);
~(ATTR_BOLD | ATTR_FAINT | ATTR_ITALIC | ATTR_UNDERLINE |
ATTR_BLINK | ATTR_REVERSE | ATTR_INVISIBLE | ATTR_STRUCK);
term.c.attr.fg = defaultfg;
term.c.attr.bg = defaultbg;
break;
@ -1323,7 +1363,8 @@ void tsetattr(int *attr, int l) {
} else if (BETWEEN(attr[i], 100, 107)) {
term.c.attr.bg = attr[i] - 100 + 8;
} else {
fprintf(stderr, "erresc(default): gfx attr %d unknown\n", attr[i]);
fprintf(stderr, "erresc(default): gfx attr %d unknown\n",
attr[i]);
csidump();
}
break;
@ -1441,7 +1482,8 @@ void tsetmode(int priv, int set, int *args, int narg) {
codes. */
break;
default:
fprintf(stderr, "erresc: unknown private set/reset mode %d\n", *args);
fprintf(stderr, "erresc: unknown private set/reset mode %d\n",
*args);
break;
}
} else {
@ -1619,7 +1661,8 @@ void csihandle(void) {
break;
case 'X': /* ECH -- Erase <n> char */
DEFAULT(csiescseq.arg[0], 1);
tclearregion(term.c.x, term.c.y, term.c.x + csiescseq.arg[0] - 1, term.c.y);
tclearregion(term.c.x, term.c.y, term.c.x + csiescseq.arg[0] - 1,
term.c.y);
break;
case 'P': /* DCH -- Delete <n> char */
DEFAULT(csiescseq.arg[0], 1);
@ -1641,8 +1684,8 @@ void csihandle(void) {
break;
case 'n': /* DSR Device Status Report (cursor position) */
if (csiescseq.arg[0] == 6) {
len =
snprintf(buf, sizeof(buf), "\033[%i;%iR", term.c.y + 1, term.c.x + 1);
len = snprintf(buf, sizeof(buf), "\033[%i;%iR", term.c.y + 1,
term.c.x + 1);
ttywrite(buf, len, 0);
}
break;
@ -2108,8 +2151,8 @@ int eschandle(uchar ascii) {
strhandle();
break;
default:
fprintf(stderr, "erresc: unknown sequence ESC 0x%02X '%c'\n", (uchar)ascii,
isprint(ascii) ? ascii : '.');
fprintf(stderr, "erresc: unknown sequence ESC 0x%02X '%c'\n",
(uchar)ascii, isprint(ascii) ? ascii : '.');
break;
}
return 1;

View File

@ -3,9 +3,9 @@
#ifndef ST_H
#define ST_H
#include <stddef.h>
#include <stdint.h>
#include <sys/types.h>
#include <stddef.h>
enum glyph_attribute {
ATTR_NULL = 0,
@ -23,21 +23,11 @@ enum glyph_attribute {
ATTR_BOLD_FAINT = ATTR_BOLD | ATTR_FAINT,
};
enum selection_mode {
SEL_IDLE = 0,
SEL_EMPTY = 1,
SEL_READY = 2
};
enum selection_mode { SEL_IDLE = 0, SEL_EMPTY = 1, SEL_READY = 2 };
enum selection_type {
SEL_REGULAR = 1,
SEL_RECTANGULAR = 2
};
enum selection_type { SEL_REGULAR = 1, SEL_RECTANGULAR = 2 };
enum selection_snap {
SNAP_WORD = 1,
SNAP_LINE = 2
};
enum selection_snap { SNAP_WORD = 1, SNAP_LINE = 2 };
typedef unsigned char uchar;
typedef unsigned int uint;