Files
vimdir/source/dictate.c
2025-01-23 09:41:36 +01:00

223 lines
6.9 KiB
C

#include "dictate.h"
/* ## Dictate Imeplementation
*/
// Do not ever set by hand, might be subject to change
static int color_enabled_global__ = 1;
static int pedantic_flushing__ = 1;
void dictate_pedantic_flush(int b) { pedantic_flushing__ = b; }
void dictate_color_enabled(int b) { color_enabled_global__ = b; }
// Every other function is ultimetly a wrapper around this one
static
void vararg_file_margin_dictate_conditional_format(
FILE * f,
char margin,
int do_process_format,
const char * fmt,
va_list args
) {
inline
void print_margin(char margin) {
const int margin_width = 3;
if (margin) {
for (int i = 0; i < margin_width; i++) {
fputc(margin, f);
}
fputc(' ', f);
}
}
print_margin(margin);
for (const char * s = fmt; *s != '\0'; s++) {
switch (*s) {
case '$': { // Color handling
if (color_enabled_global__) {
switch (*(++s)) {
case 'r': fprintf(f, "\033[31m"); break;
case 'g': fprintf(f, "\033[32m"); break;
case 'b': fprintf(f, "\033[34m"); break;
case 'y': fprintf(f, "\033[33m"); break;
case 'm': fprintf(f, "\033[35m"); break;
case 'c': fprintf(f, "\033[36m"); break;
case 'B': fprintf(f, "\033[1m"); break;
case 'I': fprintf(f, "\033[3m"); break;
case '0': fprintf(f, "\033[0m"); break;
default: --s; break; // Invalid color code, backtrack
}
} else {
switch (*(++s)) {
// Don't echo valid color sequences
case 'r': ;
case 'g': ;
case 'b': ;
case 'y': ;
case 'm': ;
case 'c': ;
case 'B': ;
case 'I': ;
case '0': break;
default: --s; break;
}
}
} break;
case '%': { // fmt specifiers
if (!do_process_format) {
fputc('%', f);
break;
}
switch (*(++s)) {
case 'd': { // Decimal
long long val = va_arg(args, long long);
fprintf(f, "%lld", val);
} break;
case 'x': { // Hex
unsigned int val = va_arg(args, unsigned int);
fprintf(f, "%x", val);
} break;
case 's': { // String
const char * str = va_arg(args, const char *);
fprintf(f, "%s", str);
} break;
case 'c': { // Char
char ch = (char)va_arg(args, int);
fprintf(f, "%c", ch);
} break;
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
{ // Static width
int width;
for (width = 0; *s >= '0' && *s <= '9'; s++) {
width = width * 10 + (*s - '0');
}
--s;
goto p;
case '*': // Dynamic width
width = va_arg(args, long long);
p:
switch (*(++s)) {
case 'd': {
long long x = va_arg(args, long long);
fprintf(f, "%*lld", width, x);
} break;
case 'x': {
unsigned int x = va_arg(args, unsigned int);
fprintf(f, "%*x", width, x);
} break;
case 's': {
const char * x = va_arg(args, const char *);
fprintf(f, "%*s", width, x);
} break;
case 'c': {
char x = (char)va_arg(args, int);
fprintf(f, "%*c", width, x);
} break;
default: --s; break;
}
} break;
default: --s;
} break;
} break;
case '\n': { // Margin handling
fputc('\n', f);
if (*(s+1) != '\0') {
print_margin(margin);
}
} break;
default: { // Regular characters
fputc(*s, f);
} break;
}
}
if (pedantic_flushing__) {
fflush(f);
}
}
static
void file_margin_dictate_conditional_format(FILE *f, char margin, const char * str, ...) {
va_list args;
va_start(args, str);
vararg_file_margin_dictate_conditional_format(f, margin, 0, str, args);
va_end(args);
}
void vafmdictatef(FILE * f, char margin, const char * fmt, va_list args) {
vararg_file_margin_dictate_conditional_format(f, margin, 1, fmt, args);
}
void fmdictate(FILE *f, char margin, const char * str) {
file_margin_dictate_conditional_format(f, margin, str);
fputs("\n", f);
}
// Wrapping fmdictate
void dictate(const char * str) {
fmdictate(stdout, '\00', str);
}
void fdictate(FILE * f, const char * str) {
fmdictate(f, '\00', str);
}
void mdictate(char margin, const char * str) {
fmdictate(stdout, margin, str);
}
// Wrapping vafmdictatef
void fmdictatef(FILE * f, char margin, const char * fmt, ...) {
va_list args;
va_start(args, fmt);
vafmdictatef(f, margin, fmt, args);
va_end(args);
}
void dictatef(const char * fmt, ...) {
va_list args;
va_start(args, fmt);
vafmdictatef(stdout, '\00', fmt, args);
va_end(args);
}
void vadictatef(const char * fmt, va_list args) {
vafmdictatef(stdout, '\00', fmt, args);
}
void fdictatef(FILE * f, const char * fmt, ...) {
va_list args;
va_start(args, fmt);
vafmdictatef(f, '\00', fmt, args);
va_end(args);
}
void vafdictatef(FILE * f, const char * fmt, va_list args) {
vafmdictatef(f, '\00', fmt, args);
}
void mdictatef(char margin, const char * fmt, ...) {
va_list args;
va_start(args, fmt);
vafmdictatef(stdout, margin, fmt, args);
va_end(args);
}
void vamdictatef(char margin, const char * fmt, va_list args) {
vafmdictatef(stdout, margin, fmt, args);
}
// Dictate is in the Public Domain, and if say this is not a legal notice, I will sue you.