// x-run: tcc -Wextra -Wall -run cbt.c #ifndef _CBT_H_ #define _CBT_H_ #include #include #include extern int cbt_verbosity; extern char *cbt_cc; void cbt__init(int argc, char **argv); #define CBT_INIT(ARGC, ARGV) cbt__init(ARGC, ARGV); enum cbt_loglevel { CBT_LOG_FATAL, CBT_LOG_ERROR, CBT_LOG_WARNING, CBT_LOG_INFO, CBT_LOG_DEBUG, CBT_LOG_ALL }; const extern char *cbt_log__colors[CBT_LOG_ALL + 1]; const extern char *cbt_log__typecolors[8]; void cbt_log(enum cbt_loglevel lvl, const char *fmt, ...); unsigned long cbt_get_modtime(const char *filename); bool cbt_needs_recompilation(const char *input, const char *output); struct cbt_proc_args { char **items; size_t size, cap; }; struct cbt_proc { FILE *fp_stdin, *fp_stdout, *fp_stderr; #ifdef _WIN32 HANDLE *handle; #else int pid; #endif }; struct cbt_procgroup { struct cbt_proc *items; size_t size, cap; }; #define CBT_ARRLEN(ARR) (sizeof(ARR)/sizeof(ARR[0])) #ifndef CBT_REALLOC #define CBT_REALLOC realloc #endif #define CBT_DA_INIT_SIZE 256 #define cbt_da_add(ARR, ITEM) { \ if (ARR.size >= ARR.cap) { \ size_t size = ARR.size == 0 ? CBT_DA_INIT_SIZE : ARR.size * 2; \ ARR.items = CBT_REALLOC(NULL, size); \ } \ ARR.items[ARR.size] = (ITEM); \ ARR.size++; \ } #endif // Implementation #ifdef CBT_IMPLEMENTATION #include #include int cbt_verbosity = 0; char *cbt_cc = NULL; const char *cbt_log__colors[CBT_LOG_ALL + 1] = { "\x1b[1;31m", "\x1b[31m", "\x1b[33m", "\x1b[32m", "\x1b[34m", "\x1b[35m" }; const char *cbt_log__typecolors[8] = { /* int */ "\x1b[31m", /* float */ "\x1b[33m", /* char* */ "\x1b[34m", /* void* */ "\x1b[35m", /* bool */ NULL, /* */ "", /* */ "", /* */ "", }; void cbt__init(int argc, char **argv) { cbt_cc = getenv("CC"); if (!cbt_cc) cbt_cc = "cc"; cbt_log(CBT_LOG_INFO, "omg hii hiiii hello %s", "world"); } struct cbt_proc cbt_proc__open(void); /* * Simplified version of printf, but with pretty colors depending on the type * * Supported format specifiers: * %{len}d %{len}u - signed and unsigned integer * %(len}(.{len})f - float/double * %{len}s - string * %p - raw pointer */ void cbt_log(enum cbt_loglevel lvl, const char *fmt, ...) { const char *fmt_ptr = fmt; for (const char *fmt_ptr = fmt; *fmt_ptr != 0; fmt_ptr++) { if (*fmt_ptr != '%') { putchar(*fmt_ptr); } else { // todo } } putchar('\n'); } #endif