/** * @file common.c * * Implementations for the base library. */ #include "base/common.h" #include #include #include #include #include double debug_verbosity = 0.0; int abort_on_nonfatal = 0; int pause_on_nonfatal = 0; int print_notify_headers = 0; #ifdef VERBOSE int print_got_heres = 1; int print_warnings = 1; #else int print_got_heres = 0; int print_warnings = 0; #endif void fl_pause(void) { if (isatty(0)) { char c; fprintf(stderr, "=*=*= Press Return to continue =*=*="); fflush(stderr); while ((c = getchar()) != EOF && c != '\n'); } } const char *fl_filename(const char *name) { const char *found = strstr(name, "/c/"); if (found) { return found + 3; } else { const char *prev = 0; const char *last = 0; found = name; while ((found = strchr(found + 1, '/'))) { prev = last; last = found; } if (prev) { return prev; } else { return name; } } } void fl_msg_header(char type, const char *color, const char *file, const char *func, int line) { fprintf(stderr, "%s[%c]%s %s:%s:%d: ", color, type, ANSI_CLEAR, fl_filename(file), func, line); } void fatal(const char *file, const char *func, int line, const char *format, ...) { va_list vl; fl_msg_header('X', ANSI_HRED, file, func, line); va_start(vl, format); vfprintf(stderr, format, vl); va_end(vl); fprintf(stderr, "\n"); *(int*)NULL = 0; abort(); } void nonfatal(const char *file, const char *func, int line, const char *format, ...) { va_list vl; fl_msg_header('!', ANSI_HYELLOW, file, func, line); va_start(vl, format); vfprintf(stderr, format, vl); va_end(vl); fprintf(stderr, "\n"); if (abort_on_nonfatal) { *(int*)NULL = 0; abort(); } else if (pause_on_nonfatal) { fl_pause(); } } void notify(const char *file, const char *func, int line, const char *format, ...) { va_list vl; if (print_notify_headers) { fl_msg_header('.', ANSI_BLUE, file, func, line); } va_start(vl, format); vfprintf(stderr, format, vl); va_end(vl); fprintf(stderr, "\n"); } static char tsprintf_pool[TSPRINTF_COUNT][TSPRINTF_LENGTH]; static int tsprintf_index = 0; char *tsprintf(const char *format, ...) { char *s = tsprintf_pool[tsprintf_index]; va_list vl; tsprintf_index = (tsprintf_index + 1) % TSPRINTF_COUNT; va_start(vl, format); vsnprintf(s, TSPRINTF_LENGTH, format, vl); va_end(vl); return s; } void percent_indicator(const char *what, uint64 numerator, uint64 denominator) { char buf[80]; int length = 50; int i = 0; if (numerator == denominator) { for (; i < sizeof(buf) - 1; i++) { buf[i] = ' '; } buf[i] = '\0'; fprintf(stderr, "%s\r", buf); } else { int percent = (int)(numerator * 100 / denominator); for (i = 0; i < percent * length / 100; i++) { buf[i] = '#'; } for (; i < length; i++) { buf[i] = '.'; } buf[i] = '\0'; fprintf(stderr, ANSI_BLUE"STATUS: [%s] %02d%% %s"ANSI_CLEAR"\r", buf, percent, what); } }