clang-format

This commit is contained in:
Casey 2023-11-18 14:02:12 +03:00
parent 869553f402
commit ea1dc41d61
Signed by: hkc
GPG Key ID: F0F6CFE11CDB0960
4 changed files with 116 additions and 93 deletions

2
.gitignore vendored
View File

@ -1,2 +1,4 @@
cbt cbt
cbt_impl.c
state state
add_impl.py

4
cbt.c
View File

@ -3,10 +3,10 @@
#include "cbt.h" #include "cbt.h"
int main(int argc, char **argv) { int main(int argc, char **argv) {
cbt_verbosity = CBT_LOG_DEBUG;
CBT_INIT(argc, argv); CBT_INIT(argc, argv);
struct cbt_proc proc = cbt_proc_new(CBT_PROC_NORMAL, "sh", "-c", "echo 'owo'"); struct cbt_proc proc =
cbt_proc_new(CBT_PROC_NORMAL, "sh", "-c", "echo 'owo'");
cbt_proc_wait(proc); cbt_proc_wait(proc);
cbt_cleanup(); cbt_cleanup();

185
cbt.h
View File

@ -33,7 +33,6 @@ bool cbt_needs_recompilation(const char *input, const char *output);
const char *cbt_escape_shell(char *arg); const char *cbt_escape_shell(char *arg);
const char *cbt_escape_args(char **args); const char *cbt_escape_args(char **args);
#ifndef CBT_FMT_NBUFS #ifndef CBT_FMT_NBUFS
#define CBT_FMT_NBUFS 64 #define CBT_FMT_NBUFS 64
#endif #endif
@ -42,10 +41,8 @@ const char *cbt_escape_args(char **args);
#define CBT_FMT_BUFSIZE 1024 #define CBT_FMT_BUFSIZE 1024
#endif #endif
const char *cbt_fmt(const char *fmt, ...); const char *cbt_fmt(const char *fmt, ...);
struct cbt_proc_args { struct cbt_proc_args {
char **items; char **items;
size_t size, cap; size_t size, cap;
@ -73,7 +70,7 @@ struct cbt_proc _cbt_proc_new(enum cbt_proc_mode mode, ...);
struct cbt_proc cbt_proc_newv(enum cbt_proc_mode mode, va_list args); struct cbt_proc cbt_proc_newv(enum cbt_proc_mode mode, va_list args);
int cbt_proc_wait(struct cbt_proc proc); int cbt_proc_wait(struct cbt_proc proc);
#define CBT_ARRLEN(ARR) (sizeof(ARR)/sizeof(ARR[0])) #define CBT_ARRLEN(ARR) (sizeof(ARR) / sizeof(ARR[0]))
#ifndef CBT_REALLOC #ifndef CBT_REALLOC
#define CBT_REALLOC realloc #define CBT_REALLOC realloc
@ -81,43 +78,48 @@ int cbt_proc_wait(struct cbt_proc proc);
#define CBT_DA_INIT_SIZE 256 #define CBT_DA_INIT_SIZE 256
#define cbt_da_add(ARR, ITEM) { \ #define cbt_da_add(ARR, ITEM) \
{ \
if (ARR.size >= ARR.cap) { \ if (ARR.size >= ARR.cap) { \
size_t size = ARR.size == 0 ? CBT_DA_INIT_SIZE : ARR.size * 2; \ size_t size = ARR.size == 0 ? CBT_DA_INIT_SIZE : ARR.size * 2; \
ARR.items = CBT_REALLOC(ARR.items, size * sizeof(ARR.items[0])); \ ARR.items = CBT_REALLOC(ARR.items, size * sizeof(ARR.items[0])); \
} \ } \
ARR.items[ARR.size] = (ITEM); \ ARR.items[ARR.size] = (ITEM); \
ARR.size++; \ ARR.size++; \
} }
#define cbt_da_remove(ARR, I) if (I >= 0 && I < ARR.size) { \ #define cbt_da_remove(ARR, I) \
memmove(&ARR.items[I], \ if (I >= 0 && I < ARR.size) { \
&ARR.items[I+1], \ memmove(&ARR.items[I], &ARR.items[I + 1], \
(ARR.size - 1) * sizeof((ARR).items[0])); \ (ARR.size - 1) * sizeof((ARR).items[0])); \
ARR.size--; \ ARR.size--; \
} }
#ifdef CBT_IMPLEMENTATION #ifdef CBT_IMPLEMENTATION
//-*- begin cbt_impl.c 5
#define __USE_GNU #define __USE_GNU
#include <stdbool.h>
#include <stdlib.h>
#include <unistd.h>
#include <ctype.h> #include <ctype.h>
#include <stdarg.h> #include <errno.h>
#include <string.h>
#include <time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <poll.h> #include <poll.h>
#include <pthread.h> #include <pthread.h>
#include <signal.h> #include <signal.h>
#include <errno.h> #include <stdarg.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <time.h>
#include <unistd.h>
#define CBT_FAIL(COND) if (COND) { cbt_log(CBT_LOG_FATAL, "condition %s failed, %s", #COND, strerror(errno)); abort(); }; #define CBT_FAIL(COND) \
if (COND) { \
cbt_log(CBT_LOG_FATAL, "condition %s failed, %s", #COND, strerror(errno)); \
abort(); \
};
enum cbt_loglevel cbt_verbosity = 0; enum cbt_loglevel cbt_verbosity = CBT_LOG_INFO;
char *cbt_cc = NULL; char *cbt_cc = NULL;
long cbt_start_time = 0; long cbt_start_time = 0;
bool cbt_running = false; bool cbt_running = false;
@ -125,7 +127,7 @@ bool cbt_running = false;
struct _cbt__autoproc_fdset { struct _cbt__autoproc_fdset {
struct pollfd *items; struct pollfd *items;
size_t size, cap; size_t size, cap;
} cbt__autoproc_fdset = { 0 }; } cbt__autoproc_fdset = {0};
struct _cbt__autoproc_set { struct _cbt__autoproc_set {
struct _cbt__autoproc_set__item { struct _cbt__autoproc_set__item {
@ -133,25 +135,18 @@ struct _cbt__autoproc_set {
bool is_err; bool is_err;
} *items; } *items;
size_t size, cap; size_t size, cap;
} cbt__autoproc_set = { 0 }; } cbt__autoproc_set = {0};
struct cbt_procgroup cbt__default_procgroup = { .items = 0, .size = 0, .cap = 4 }; struct cbt_procgroup cbt__default_procgroup = {.items = 0, .size = 0, .cap = 4};
pthread_t _cbt__autoproc_thread; pthread_t _cbt__autoproc_thread;
pthread_mutex_t _cbt__autoproc_mut = PTHREAD_MUTEX_INITIALIZER; pthread_mutex_t _cbt__autoproc_mut = PTHREAD_MUTEX_INITIALIZER;
const char *cbt_log__colors[CBT_LOG_ALL + 1] = { const char *cbt_log__colors[CBT_LOG_ALL + 1] = {
"\x1b[1;31m", "\x1b[1;31m", "\x1b[31m", "\x1b[33m", "\x1b[32m", "\x1b[34m", "\x1b[35m"};
"\x1b[31m",
"\x1b[33m",
"\x1b[32m",
"\x1b[34m",
"\x1b[35m"
};
const char *cbt_log__text[CBT_LOG_ALL + 1] = { const char *cbt_log__text[CBT_LOG_ALL + 1] = {"FATAL", "ERROR", "WARN ",
"FATAL", "ERROR", "WARN ", "INFO ", "DEBUG", "TRACE" "INFO ", "DEBUG", "TRACE"};
};
void *cbt__line_processor(void *); void *cbt__line_processor(void *);
@ -160,16 +155,20 @@ void cbt__init(int argc, char **argv, const char *source_file) {
cbt_running = true; cbt_running = true;
(void)argc; (void)argc;
cbt_log(CBT_LOG_INFO, "Running CBT build %s %s from %s", __DATE__, __TIME__, __FILE__); cbt_log(CBT_LOG_INFO, "Running CBT build %s %s from %s", __DATE__, __TIME__,
__FILE__);
if (!cbt_cc) cbt_cc = getenv("CC"); if (!cbt_cc)
if (!cbt_cc) cbt_cc = "cc"; cbt_cc = getenv("CC");
if (!cbt_cc)
cbt_cc = "cc";
cbt_log(CBT_LOG_INFO, "Found C Compiler: %s", cbt_cc); cbt_log(CBT_LOG_INFO, "Found C Compiler: %s", cbt_cc);
cbt_log(CBT_LOG_DEBUG, "Args: %s", cbt_escape_args(argv)); cbt_log(CBT_LOG_DEBUG, "Args: %s", cbt_escape_args(argv));
cbt_log(CBT_LOG_DEBUG, "%s", cbt_fmt("format test: %s", "ok")); cbt_log(CBT_LOG_DEBUG, "%s", cbt_fmt("format test: %s", "ok"));
cbt__default_procgroup.items = calloc(cbt__default_procgroup.cap, sizeof(struct cbt_proc)); cbt__default_procgroup.items =
calloc(cbt__default_procgroup.cap, sizeof(struct cbt_proc));
cbt_log(CBT_LOG_DEBUG, "Starting line processor thread"); cbt_log(CBT_LOG_DEBUG, "Starting line processor thread");
// TODO: error checking // TODO: error checking
@ -177,7 +176,8 @@ void cbt__init(int argc, char **argv, const char *source_file) {
if (cbt_needs_recompilation(source_file, argv[0])) { if (cbt_needs_recompilation(source_file, argv[0])) {
cbt_log(CBT_LOG_INFO, "Recompiling..."); cbt_log(CBT_LOG_INFO, "Recompiling...");
struct cbt_proc cc = cbt_proc_new(CBT_PROC_NORMAL, cbt_cc, source_file, "-o", argv[0], "-Wall", "-Wextra", NULL); struct cbt_proc cc = cbt_proc_new(CBT_PROC_NORMAL, cbt_cc, source_file,
"-o", argv[0], "-Wall", "-Wextra", NULL);
int status = cbt_proc_wait(cc); int status = cbt_proc_wait(cc);
cbt_log(CBT_LOG_INFO, "CC returned %d", status); cbt_log(CBT_LOG_INFO, "CC returned %d", status);
if (status == 0) { if (status == 0) {
@ -187,7 +187,6 @@ void cbt__init(int argc, char **argv, const char *source_file) {
exit(0); exit(0);
} }
} }
} }
void cbt_cleanup(void) { void cbt_cleanup(void) {
@ -219,10 +218,12 @@ long cbt_get_time(void) {
} }
void cbt_log(enum cbt_loglevel lvl, const char *fmt, ...) { void cbt_log(enum cbt_loglevel lvl, const char *fmt, ...) {
if (lvl > cbt_verbosity) return; if (lvl > cbt_verbosity)
return;
double time_delta = (double)(cbt_get_time() - cbt_start_time) / 1000.0L; double time_delta = (double)(cbt_get_time() - cbt_start_time) / 1000.0L;
printf("[%10.3lf] [%s%s\x1b[0m] ", time_delta, cbt_log__colors[lvl], cbt_log__text[lvl]); printf("[%10.3lf] [%s%s\x1b[0m] ", time_delta, cbt_log__colors[lvl],
cbt_log__text[lvl]);
va_list args; va_list args;
va_start(args, fmt); va_start(args, fmt);
@ -242,26 +243,33 @@ const char *cbt_escape_shell(char *arg) {
for (i = 0; i < n; i++) { for (i = 0; i < n; i++) {
if (arg[i] == '\'') { if (arg[i] == '\'') {
if (j + 4 >= CBT_FMT_BUFSIZE) { return NULL; } if (j + 4 >= CBT_FMT_BUFSIZE) {
return NULL;
}
esc[j] = '\''; esc[j] = '\'';
esc[j+1] = '\\'; esc[j + 1] = '\\';
esc[j+2] = '\''; esc[j + 2] = '\'';
esc[j+3] = '\''; esc[j + 3] = '\'';
j += 4; j += 4;
} else { } else {
if (j >= CBT_FMT_BUFSIZE) { return NULL; } if (j >= CBT_FMT_BUFSIZE) {
return NULL;
}
esc[j++] = arg[i]; esc[j++] = arg[i];
} }
} }
if (j >= CBT_FMT_BUFSIZE) { return NULL; } if (j >= CBT_FMT_BUFSIZE) {
return NULL;
}
esc[j] = '\''; esc[j] = '\'';
return esc; return esc;
} }
const char *cbt_escape_args(char **args) { const char *cbt_escape_args(char **args) {
if (args == NULL || args[0] == NULL) return cbt_fmt(""); if (args == NULL || args[0] == NULL)
return cbt_fmt("");
char *out = (char *)cbt_escape_shell(args[0]); char *out = (char *)cbt_escape_shell(args[0]);
for (int i = 1; args[i] != NULL; i++) { for (int i = 1; args[i] != NULL; i++) {
out = (char *)cbt_fmt("%s %s", out, cbt_escape_shell(args[i])); out = (char *)cbt_fmt("%s %s", out, cbt_escape_shell(args[i]));
@ -272,7 +280,8 @@ const char *cbt_escape_args(char **args) {
unsigned long cbt_get_modtime(const char *filename) { unsigned long cbt_get_modtime(const char *filename) {
struct stat st; struct stat st;
int ret = lstat(filename, &st); int ret = lstat(filename, &st);
if (ret == -1) return -1; if (ret == -1)
return -1;
cbt_log(CBT_LOG_DEBUG, "stat(%s) -> %ld", filename, st.st_mtim.tv_sec); cbt_log(CBT_LOG_DEBUG, "stat(%s) -> %ld", filename, st.st_mtim.tv_sec);
return st.st_mtim.tv_sec; return st.st_mtim.tv_sec;
@ -282,7 +291,8 @@ bool cbt_needs_recompilation(const char *input, const char *output) {
unsigned long mod_in = cbt_get_modtime(input), unsigned long mod_in = cbt_get_modtime(input),
mod_out = cbt_get_modtime(output); mod_out = cbt_get_modtime(output);
if (mod_in == (unsigned long)-1) { if (mod_in == (unsigned long)-1) {
cbt_log(CBT_LOG_WARNING, "cbt_needs_recompilation(): input file %s does not exist", input); cbt_log(CBT_LOG_WARNING, "cbt_needs_recompilation(): %s does not exist",
input);
return false; return false;
} }
@ -298,9 +308,7 @@ void cbt__add_fd(int fd, bool is_err) {
pfd.fd = fd; pfd.fd = fd;
pfd.events = POLLIN | POLLOUT; pfd.events = POLLIN | POLLOUT;
struct _cbt__autoproc_set__item info = { struct _cbt__autoproc_set__item info = {.is_err = is_err};
.is_err = is_err
};
cbt_da_add(cbt__autoproc_fdset, pfd); cbt_da_add(cbt__autoproc_fdset, pfd);
cbt_da_add(cbt__autoproc_set, info); cbt_da_add(cbt__autoproc_set, info);
@ -316,22 +324,23 @@ struct cbt_proc _cbt_proc_new(enum cbt_proc_mode mode, ...) {
} }
struct cbt_proc cbt_proc_newv(enum cbt_proc_mode mode, va_list args) { struct cbt_proc cbt_proc_newv(enum cbt_proc_mode mode, va_list args) {
struct cbt_proc procinfo = { 0 }; struct cbt_proc procinfo = {0};
struct cbt_proc_args args_da = { 0 }; struct cbt_proc_args args_da = {0};
while (true) { while (true) {
const char *arg = va_arg(args, const char *); const char *arg = va_arg(args, const char *);
if (arg == NULL) break; if (arg == NULL)
break;
cbt_da_add(args_da, strdup(arg)); cbt_da_add(args_da, strdup(arg));
} }
cbt_da_add(args_da, NULL); cbt_da_add(args_da, NULL);
cbt_log(CBT_LOG_DEBUG, "Spawning process with mode %d and args %s", mode, cbt_escape_args(args_da.items)); cbt_log(CBT_LOG_DEBUG, "Spawning process with mode %d and args %s", mode,
cbt_escape_args(args_da.items));
int pipe_fds_sout[2] = { 0 }, int pipe_fds_sout[2] = {0}, pipe_fds_serr[2] = {0}, pipe_fds_sin[2] = {0};
pipe_fds_serr[2] = { 0 }, if (mode & CBT_PROC_W)
pipe_fds_sin[2] = { 0 }; CBT_FAIL(pipe(pipe_fds_sin) == -1);
if (mode & CBT_PROC_W) CBT_FAIL(pipe(pipe_fds_sin) == -1);
CBT_FAIL(pipe(pipe_fds_sout) == -1); CBT_FAIL(pipe(pipe_fds_sout) == -1);
CBT_FAIL(pipe(pipe_fds_serr) == -1); CBT_FAIL(pipe(pipe_fds_serr) == -1);
@ -341,30 +350,36 @@ struct cbt_proc cbt_proc_newv(enum cbt_proc_mode mode, va_list args) {
goto cbt_proc_new_cleanup; goto cbt_proc_new_cleanup;
} }
if (procinfo.pid == 0) { // child if (procinfo.pid == 0) { // child
if (mode & CBT_PROC_W) CBT_FAIL(dup2(pipe_fds_sin[1], STDIN_FILENO) == -1); if (mode & CBT_PROC_W)
CBT_FAIL(dup2(pipe_fds_sin[1], STDIN_FILENO) == -1);
CBT_FAIL(dup2(pipe_fds_sout[1], STDOUT_FILENO) == -1); CBT_FAIL(dup2(pipe_fds_sout[1], STDOUT_FILENO) == -1);
CBT_FAIL(dup2(pipe_fds_serr[1], STDERR_FILENO) == -1); CBT_FAIL(dup2(pipe_fds_serr[1], STDERR_FILENO) == -1);
execvp(args_da.items[0], (char* const*)args_da.items); execvp(args_da.items[0], (char *const *)args_da.items);
__builtin_unreachable(); __builtin_unreachable();
} else { } else {
if (mode & CBT_PROC_W) procinfo.fp_stdin = fdopen(pipe_fds_sin[0], "w"); if (mode & CBT_PROC_W)
if (mode & CBT_PROC_R) procinfo.fp_stdout = fdopen(pipe_fds_sout[0], "r"); procinfo.fp_stdin = fdopen(pipe_fds_sin[0], "w");
if (mode & CBT_PROC_R) procinfo.fp_stderr = fdopen(pipe_fds_serr[0], "r"); if (mode & CBT_PROC_R)
procinfo.fp_stdout = fdopen(pipe_fds_sout[0], "r");
if (mode & CBT_PROC_R)
procinfo.fp_stderr = fdopen(pipe_fds_serr[0], "r");
cbt_log(CBT_LOG_DEBUG, "stdin: %p (fd=%d)", procinfo.fp_stdin, pipe_fds_sin[0]); cbt_log(CBT_LOG_DEBUG, "stdin: %p (fd=%d)", procinfo.fp_stdin,
cbt_log(CBT_LOG_DEBUG, "stdout: %p (fd=%d)", procinfo.fp_stdout, pipe_fds_sout[0]); pipe_fds_sin[0]);
cbt_log(CBT_LOG_DEBUG, "stderr: %p (fd=%d)", procinfo.fp_stderr, pipe_fds_serr[0]); cbt_log(CBT_LOG_DEBUG, "stdout: %p (fd=%d)", procinfo.fp_stdout,
pipe_fds_sout[0]);
cbt_log(CBT_LOG_DEBUG, "stderr: %p (fd=%d)", procinfo.fp_stderr,
pipe_fds_serr[0]);
if (!(mode & CBT_PROC_R)) { if (!(mode & CBT_PROC_R)) {
cbt__add_fd(pipe_fds_sout[0], false); cbt__add_fd(pipe_fds_sout[0], false);
cbt__add_fd(pipe_fds_serr[0], true); cbt__add_fd(pipe_fds_serr[0], true);
} }
cbt_proc_new_cleanup: cbt_proc_new_cleanup:
cbt_log(CBT_LOG_DEBUG, "freeing up args"); cbt_log(CBT_LOG_DEBUG, "freeing up args");
for (size_t i = 0; i < args_da.size; i++) { for (size_t i = 0; i < args_da.size; i++) {
free(args_da.items[i]); free(args_da.items[i]);
@ -380,9 +395,11 @@ int cbt_proc_wait(struct cbt_proc proc) {
do { do {
pid_t w = waitpid(proc.pid, &wstatus, WUNTRACED | WCONTINUED); pid_t w = waitpid(proc.pid, &wstatus, WUNTRACED | WCONTINUED);
cbt_log(CBT_LOG_DEBUG, "waitpid(%d) -> %d, status = %d", proc.pid, w, wstatus); cbt_log(CBT_LOG_DEBUG, "waitpid(%d) -> %d, status = %d", proc.pid, w,
wstatus);
if (w == -1) { if (w == -1) {
cbt_log(CBT_LOG_WARNING, "waitpid(%d) -> %d (%s)", proc.pid, w, strerror(errno)); cbt_log(CBT_LOG_WARNING, "waitpid(%d) -> %d (%s)", proc.pid, w,
strerror(errno));
return -2000; return -2000;
} }
@ -395,13 +412,11 @@ int cbt_proc_wait(struct cbt_proc proc) {
return -1000; return -1000;
} }
static void cbt__line_processor_sig_handler(int signal) { static void cbt__line_processor_sig_handler(int signal) { (void)signal; }
(void)signal;
}
void *cbt__line_processor(void *arg) { void *cbt__line_processor(void *arg) {
(void)arg; (void)arg;
struct timespec timeout = { .tv_sec = 0, .tv_nsec = 100 }; struct timespec timeout = {.tv_sec = 0, .tv_nsec = 100};
sigset_t sigmask; sigset_t sigmask;
sigemptyset(&sigmask); sigemptyset(&sigmask);
@ -418,14 +433,16 @@ void *cbt__line_processor(void *arg) {
pthread_mutex_lock(&_cbt__autoproc_mut); pthread_mutex_lock(&_cbt__autoproc_mut);
#if 1 #if 1
int res = ppoll(cbt__autoproc_fdset.items, cbt__autoproc_fdset.size, &timeout, &sigmask); int res = ppoll(cbt__autoproc_fdset.items, cbt__autoproc_fdset.size,
&timeout, &sigmask);
if (res < 0) { if (res < 0) {
cbt_log(CBT_LOG_ERROR, "ppoll() -> %d (%s)", res, strerror(errno)); cbt_log(CBT_LOG_ERROR, "ppoll() -> %d (%s)", res, strerror(errno));
break; break;
} }
#else #else
for (int i = 0; i < cbt__autoproc_set.size; i++) { for (int i = 0; i < cbt__autoproc_set.size; i++) {
cbt_log(CBT_LOG_DEBUG, "fdset[%d] = { %d, %d }", i, cbt__autoproc_set.items[i].fd, cbt__autoproc_set.items[i].events); cbt_log(CBT_LOG_DEBUG, "fdset[%d] = { %d, %d }", i,
cbt__autoproc_set.items[i].fd, cbt__autoproc_set.items[i].events);
} }
cbt_log(CBT_LOG_DEBUG, "poll(_, %d, _) ...", cbt__autoproc_set.size); cbt_log(CBT_LOG_DEBUG, "poll(_, %d, _) ...", cbt__autoproc_set.size);
int res = poll(cbt__autoproc_set.items, cbt__autoproc_set.size, 1000); int res = poll(cbt__autoproc_set.items, cbt__autoproc_set.size, 1000);
@ -438,7 +455,8 @@ void *cbt__line_processor(void *arg) {
if (pfd.revents != 0) { if (pfd.revents != 0) {
if (pfd.revents & POLLIN) { if (pfd.revents & POLLIN) {
ssize_t s = read(pfd.fd, buf, sizeof(buf)); ssize_t s = read(pfd.fd, buf, sizeof(buf));
cbt_log(item.is_err ? CBT_LOG_ERROR : CBT_LOG_INFO, "fd(%d): %.*s", pfd.fd, (int)s - 1, buf); cbt_log(item.is_err ? CBT_LOG_ERROR : CBT_LOG_INFO, "fd(%d): %.*s",
pfd.fd, (int)s - 1, buf);
} }
} }
} }
@ -450,6 +468,7 @@ void *cbt__line_processor(void *arg) {
} }
#undef CBT_FAIL #undef CBT_FAIL
//-*- end
#endif #endif
#endif #endif

2
compile_flags.txt Normal file
View File

@ -0,0 +1,2 @@
-Wall
-Wextra