Raw source file available here .
// 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 <stdarg.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
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