// Written by retoor@molodetz.nl // This source code provides a custom printing library for formatted output with optional color effects. It implements functions to print // strings with various color enhancements and control codes for terminal manipulation. // Includes: The code uses a custom header "rtime.h" to work with time-related functions. // MIT License: Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, // publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, // subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial // portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED // TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR // IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #ifndef RPRINT_H #define RPRINT_H #include "rtime.h" #include #include #include #include #include long rpline_number = 0; nsecs_t rprtime = 0; int8_t _env_rdisable_colors = -1; bool _rprint_enable_colors = true; bool rprint_is_color_enabled() { if (_env_rdisable_colors == -1) { _env_rdisable_colors = getenv("RDISABLE_COLORS") != NULL; } if (_env_rdisable_colors) { _rprint_enable_colors = false; } return _rprint_enable_colors; } void rprint_disable_colors() { _rprint_enable_colors = false; } void rprint_enable_colors() { _rprint_enable_colors = true; } void rprint_toggle_colors() { _rprint_enable_colors = !_rprint_enable_colors; } void rclear() { printf("\033[2J"); } void rprintpf(FILE *f, const char *prefix, const char *format, va_list args) { bool reset_color = false; bool press_any_key = false; char new_format[4096]; bool enable_color = rprint_is_color_enabled(); memset(new_format, 0, sizeof(new_format)); int new_format_length = 0; char temp[1000]; memset(temp, 0, sizeof(temp)); if (enable_color && prefix[0]) { strcat(new_format, prefix); new_format_length += strlen(prefix); reset_color = true; } while (*format) { if (format[0] == '\\' && format[1] == 'i') { strcat(new_format, "\e[3m"); new_format_length += strlen("\e[3m"); reset_color = true; format += 2; } else if (format[0] == '\\' && format[1] == 'u') { strcat(new_format, "\e[4m"); new_format_length += strlen("\e[4m"); reset_color = true; format += 2; } else if (format[0] == '\\' && format[1] == 'b') { strcat(new_format, "\e[1m"); new_format_length += strlen("\e[1m"); reset_color = true; format += 2; } else if (format[0] == '\\' && format[1] == 'C') { press_any_key = true; rpline_number++; format += 2; reset_color = false; } else if (format[0] == '\\' && format[1] == 'k') { press_any_key = true; rpline_number++; format += 2; } else if (format[0] == '\\' && format[1] == 'c') { rpline_number++; strcat(new_format, "\e[2J\e[H"); new_format_length += strlen("\e[2J\e[H"); format += 2; } else if (format[0] == '\\' && format[1] == 'L') { rpline_number++; sprintf(temp, "%ld", rpline_number); strcat(new_format, temp); new_format_length += strlen(temp); format += 2; } else if (format[0] == '\\' && format[1] == 'l') { rpline_number++; sprintf(temp, "%.5ld", rpline_number); strcat(new_format, temp); new_format_length += strlen(temp); format += 2; } else if (format[0] == '\\' && format[1] == 'T') { nsecs_t nsecs_now = nsecs(); nsecs_t end = rprtime ? nsecs_now - rprtime : 0; sprintf(temp, "%s", format_time(end)); strcat(new_format, temp); new_format_length += strlen(temp); rprtime = nsecs_now; format += 2; } else if (format[0] == '\\' && format[1] == 't') { rprtime = nsecs(); format += 2; } else { new_format[new_format_length++] = *format++; } } if (reset_color) { strcat(new_format, "\e[0m"); new_format_length += strlen("\e[0m"); } new_format[new_format_length] = '\0'; vfprintf(f, new_format, args); fflush(stdout); if (press_any_key) { nsecs_t s = nsecs(); fgetc(stdin); rprtime += nsecs() - s; } } void rprintp(const char *format, ...) { va_list args; va_start(args, format); rprintpf(stdout, "", format, args); va_end(args); } void rprintf(FILE *f, const char *format, ...) { va_list args; va_start(args, format); rprintpf(f, "", format, args); va_end(args); } void rprint(const char *format, ...) { va_list args; va_start(args, format); rprintpf(stdout, "", format, args); va_end(args); } #define printf rprint void rprintlf(FILE *f, const char *format, ...) { va_list args; va_start(args, format); rprintpf(f, "\\l", format, args); va_end(args); } void rprintl(const char *format, ...) { va_list args; va_start(args, format); rprintpf(stdout, "\\l", format, args); va_end(args); } void rprintkf(FILE *f, const char *format, ...) { va_list args; va_start(args, format); rprintpf(f, "\e[30m", format, args); va_end(args); } void rprintk(const char *format, ...) { va_list args; va_start(args, format); rprintpf(stdout, "\e[30m", format, args); va_end(args); } void rprintrf(FILE *f, const char *format, ...) { va_list args; va_start(args, format); rprintpf(f, "\e[31m", format, args); va_end(args); } void rprintr(const char *format, ...) { va_list args; va_start(args, format); rprintpf(stdout, "\e[31m", format, args); va_end(args); } void rprintgf(FILE *f, const char *format, ...) { va_list args; va_start(args, format); rprintpf(f, "\e[32m", format, args); va_end(args); } void rprintg(const char *format, ...) { va_list args; va_start(args, format); rprintpf(stdout, "\e[32m", format, args); va_end(args); } void rprintyf(FILE *f, const char *format, ...) { va_list args; va_start(args, format); rprintpf(f, "\e[33m", format, args); va_end(args); } void rprinty(const char *format, ...) { va_list args; va_start(args, format); rprintpf(stdout, "\e[33m", format, args); va_end(args); } void rprintbf(FILE *f, const char *format, ...) { va_list args; va_start(args, format); rprintpf(f, "\e[34m", format, args); va_end(args); } void rprintb(const char *format, ...) { va_list args; va_start(args, format); rprintpf(stdout, "\e[34m", format, args); va_end(args); } void rprintmf(FILE *f, const char *format, ...) { va_list args; va_start(args, format); rprintpf(f, "\e[35m", format, args); va_end(args); } void rprintm(const char *format, ...) { va_list args; va_start(args, format); rprintpf(stdout, "\e[35m", format, args); va_end(args); } void rprintcf(FILE *f, const char *format, ...) { va_list args; va_start(args, format); rprintpf(f, "\e[36m", format, args); va_end(args); } void rprintc(const char *format, ...) { va_list args; va_start(args, format); rprintpf(stdout, "\e[36m", format, args); va_end(args); } void rprintwf(FILE *f, const char *format, ...) { va_list args; va_start(args, format); rprintpf(f, "\e[37m", format, args); va_end(args); } void rprintw(const char *format, ...) { va_list args; va_start(args, format); rprintpf(stdout, "\e[37m", format, args); va_end(args); } #endif