aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2024-06-14 22:45:08 +0200
committerBad Diode <bd@badd10de.dev>2024-06-14 22:45:08 +0200
commitf584bc5e4dc7da4ac20306f5072a2b2b01147c4b (patch)
tree83bdf4157747e425ae80c17601be72f421d7756c /src
parentf343f6f13f470915f971f3ca9361ff267960ca6a (diff)
downloadbdl-f584bc5e4dc7da4ac20306f5072a2b2b01147c4b.tar.gz
bdl-f584bc5e4dc7da4ac20306f5072a2b2b01147c4b.zip
Add a custom logging dsl
Diffstat (limited to 'src')
-rw-r--r--src/badlib.h237
-rw-r--r--src/main.c58
2 files changed, 268 insertions, 27 deletions
diff --git a/src/badlib.h b/src/badlib.h
index 8ce4634..bc3312f 100644
--- a/src/badlib.h
+++ b/src/badlib.h
@@ -11,6 +11,9 @@
11// - Sort arrays / linked lists with custom functions? 11// - Sort arrays / linked lists with custom functions?
12// - Implement binary search for searching into an array: 12// - Implement binary search for searching into an array:
13// SearchResult find_array(Array haystack, Array needle). 13// SearchResult find_array(Array haystack, Array needle).
14// - Move logger functions to str_from_int, str_from_float etc.
15// - Logger functions for hash map, arrays and growable arrays (print the entire
16// thing or at least a small range).
14// 17//
15 18
16#include <stdbool.h> 19#include <stdbool.h>
@@ -453,6 +456,59 @@ str_insert(Str orig, Str value, sz position, Arena *a) {
453// }; 456// };
454// } 457// }
455 458
459char
460str_next(Str *s) {
461 assert(s->mem);
462 if (s->size == 0) {
463 return EOF;
464 }
465 char c = *s->mem++;
466 s->size--;
467 return c;
468}
469
470char
471str_peek(Str s) {
472 assert(s.mem);
473 return *s.mem;
474}
475
476sz
477str_to_int(Str s) {
478 sz num = 0;
479 if (str_has_prefix(s, cstr("0b"))) {
480 // Binary number.
481 s = str_remove_prefix(s, cstr("0b"));
482 while (s.size) {
483 char c = str_next(&s);
484 assert(c == '0' || c == '1');
485 num = num * 2 + (c - '0');
486 }
487 } else if (str_has_prefix(s, cstr("0x"))) {
488 // Hex number.
489 s = str_remove_prefix(s, cstr("0x"));
490 while (s.size) {
491 char c = str_next(&s);
492 assert((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f'));
493 if (c >= '0' && c <= '9') {
494 num = num * 16 + (c - '0');
495 } else if (c >= 'a' && c <= 'f') {
496 num = num * 16 + (c - 'a' + 10);
497 } else if (c >= 'A' && c <= 'F') {
498 num = num * 16 + (c - 'A' + 10);
499 }
500 }
501 } else {
502 // Decimal number.
503 while (s.size) {
504 char c = str_next(&s);
505 assert(c >= '0' && c <= '9');
506 num = num * 10 + (c - '0');
507 }
508 }
509 return num;
510}
511
456// 512//
457// Queue. 513// Queue.
458// 514//
@@ -901,6 +957,7 @@ void
901log_flush(Logger *l) { 957log_flush(Logger *l) {
902 if (l->buf.size) { 958 if (l->buf.size) {
903 fprintf(l->dest, "%.*s", (int)l->buf.size, l->buf.mem); 959 fprintf(l->dest, "%.*s", (int)l->buf.size, l->buf.mem);
960 l->buf.size = 0;
904 } 961 }
905} 962}
906 963
@@ -931,6 +988,7 @@ void
931log_byte(Logger *l, u8 b) { 988log_byte(Logger *l, u8 b) {
932 assert(l); 989 assert(l);
933 Buf *buf = &l->buf; 990 Buf *buf = &l->buf;
991 if (buf->size == 0) log_init(l);
934 sz avail = buf->cap - buf->size; 992 sz avail = buf->cap - buf->size;
935 if (avail == 0) { 993 if (avail == 0) {
936 log_flush(l); 994 log_flush(l);
@@ -1051,4 +1109,183 @@ log_float(Logger *l, f64 num, sz precision) {
1051 log_int(l, fractional); 1109 log_int(l, fractional);
1052} 1110}
1053 1111
1112#include <stdarg.h>
1113
1114typedef struct Vec2 {
1115 sz x, y;
1116} Vec2;
1117
1118typedef void(LogFunc)(Logger *l, void *in);
1119
1120void
1121log_vec2(Logger *l, void *v) {
1122 assert(l);
1123 Vec2 *vec = v;
1124 log_str(l, cstr("Vec2 { x: "));
1125 log_int(l, vec->x);
1126 log_str(l, cstr(", y: "));
1127 log_int(l, vec->y);
1128 log_str(l, cstr(" }"));
1129}
1130
1131void
1132log_func_arena(Logger *l, void *in) {
1133 assert(l);
1134 Arena *val = in;
1135 log_str(l, cstr("Arena{ size: "));
1136 log_int(l, val->size);
1137 log_str(l, cstr(" cap: "));
1138 log_int(l, val->cap);
1139 log_str(l, cstr(" mem: "));
1140 log_hex(l, (ptrsize)val->beg, 16);
1141 log_str(l, cstr(" }"));
1142}
1143
1144void
1145log_func_buf(Logger *l, void *in) {
1146 assert(l);
1147 Buf *val = in;
1148 log_str(l, cstr("Buf{ size: "));
1149 log_int(l, val->size);
1150 log_str(l, cstr(" cap: "));
1151 log_int(l, val->cap);
1152 log_str(l, cstr(" mem: "));
1153 log_hex(l, (ptrsize)val->mem, 16);
1154 log_str(l, cstr(" }"));
1155}
1156
1157void
1158log_func_array(Logger *l, void *in) {
1159 assert(l);
1160 Array *val = in;
1161 log_str(l, cstr("Buf{ size: "));
1162 log_int(l, val->size);
1163 log_str(l, cstr(" mem: "));
1164 log_hex(l, (ptrsize)val->mem, 16);
1165 log_str(l, cstr(" }"));
1166}
1167
1168typedef struct LogFuncMap {
1169 Str name;
1170 LogFunc *func;
1171} LogFuncMap;
1172
1173LogFuncMap log_funcs[] = {
1174 {cstr("Arena"), log_func_arena},
1175 {cstr("Buf"), log_func_buf},
1176 {cstr("Array"), log_func_array},
1177};
1178
1179void
1180log_print(Logger *l, Str format, ...) {
1181 va_list argp;
1182 va_start(argp, format);
1183 va_start(argp, format);
1184 while (format.size) {
1185 char c = str_next(&format);
1186 if (c == '%') {
1187 c = str_next(&format);
1188 switch (c) {
1189 case '%': {
1190 log_byte(l, '%');
1191 } break;
1192 case 'd': {
1193 // Integer decimal formatting.
1194 sz num = va_arg(argp, sz);
1195 log_int(l, num);
1196 } break;
1197 case 'x': {
1198 // Hex number formatting.
1199 sz num = va_arg(argp, sz);
1200 char n = str_peek(format);
1201 sz zeroes = 0;
1202 if (n == '{') {
1203 str_next(&format);
1204 SearchResult res = array_find_next(format, cstr("}"));
1205 if (res.found) {
1206 Str arg = format;
1207 arg.size = res.pos;
1208 sz inc = res.pos + res.matched;
1209 format.mem += inc;
1210 format.size -= inc;
1211 zeroes = str_to_int(arg);
1212 } else {
1213 break;
1214 }
1215 }
1216 log_hex(l, num, zeroes);
1217 } break;
1218 case 'b': {
1219 // Binary number formatting.
1220 sz num = va_arg(argp, sz);
1221 char n = str_peek(format);
1222 sz zeroes = 0;
1223 if (n == '{') {
1224 str_next(&format);
1225 SearchResult res = array_find_next(format, cstr("}"));
1226 if (res.found) {
1227 Str arg = format;
1228 arg.size = res.pos;
1229 sz inc = res.pos + res.matched;
1230 format.mem += inc;
1231 format.size -= inc;
1232 zeroes = str_to_int(arg);
1233 } else {
1234 break;
1235 }
1236 }
1237 log_bin(l, num, zeroes);
1238 } break;
1239 case 'f': {
1240 // Floating point formatting.
1241 f64 num = va_arg(argp, f64);
1242 char n = str_peek(format);
1243 sz precision = 4;
1244 if (n == '{') {
1245 str_next(&format);
1246 SearchResult res = array_find_next(format, cstr("}"));
1247 if (res.found) {
1248 Str arg = format;
1249 arg.size = res.pos;
1250 sz inc = res.pos + res.matched;
1251 format.mem += inc;
1252 format.size -= inc;
1253 precision = str_to_int(arg);
1254 } else {
1255 break;
1256 }
1257 }
1258 log_float(l, num, precision);
1259 } break;
1260 case 's': {
1261 // String formatting.
1262 Str val = va_arg(argp, Str);
1263 log_str(l, val);
1264 } break;
1265 case '{': {
1266 SearchResult res = array_find_next(format, cstr("}"));
1267 if (res.found) {
1268 Str arg = format;
1269 arg.size = res.pos;
1270 sz inc = res.pos + res.matched;
1271 format.mem += inc;
1272 format.size -= inc;
1273 void *val = va_arg(argp, void *);
1274 for (sz i = 0; i < LEN(log_funcs); i++) {
1275 if (str_eq(arg, log_funcs[i].name)) {
1276 log_funcs[i].func(l, val);
1277 break;
1278 }
1279 }
1280 }
1281 } break;
1282 }
1283 continue;
1284 }
1285 log_byte(l, c);
1286 }
1287 log_flush(l);
1288 va_end(argp);
1289}
1290
1054#endif // BADLIB_H 1291#endif // BADLIB_H
diff --git a/src/main.c b/src/main.c
index b6a0da4..f5f2065 100644
--- a/src/main.c
+++ b/src/main.c
@@ -49,33 +49,37 @@ process_file(Str path) {
49 .dest = stdout, 49 .dest = stdout,
50 .storage = &logger_arena, 50 .storage = &logger_arena,
51 }; 51 };
52 log_str(&logger_info, cstr("<<< ")); 52 log_print(&logger_info, cstr("<<< %x{4} %b{4} %f{2} %s %{Vec2} %{Vec2} %{Arena} >>>\n"),
53 log_int(&logger_info, -1234); 53 123, 3, 1.345, cstr("BOOM!"), &(Vec2){100, 255}, &(Vec2){10, 15}, &logger_arena);
54 log_str(&logger_info, cstr(" | ")); 54 // log_print(&logger_info, cstr("<<< %x{4} >>>\n"),
55 log_hex(&logger_info, (sz)&logger_info, 16); 55 // 123);
56 log_str(&logger_info, cstr(" | ")); 56 // log_str(&logger_info, cstr("<<< "));
57 log_hex(&logger_info, 15, 8); 57 // log_int(&logger_info, -1234);
58 log_str(&logger_info, cstr(" | ")); 58 // log_str(&logger_info, cstr(" | "));
59 log_hex(&logger_info, 16, 8); 59 // log_hex(&logger_info, (sz)&logger_info, 16);
60 log_str(&logger_info, cstr(" | ")); 60 // log_str(&logger_info, cstr(" | "));
61 log_bin(&logger_info, 15, 8); 61 // log_hex(&logger_info, 15, 8);
62 log_str(&logger_info, cstr(" | ")); 62 // log_str(&logger_info, cstr(" | "));
63 log_bin(&logger_info, 16, 8); 63 // log_hex(&logger_info, 16, 8);
64 log_str(&logger_info, cstr(" | ")); 64 // log_str(&logger_info, cstr(" | "));
65 log_float(&logger_info, 3.1234, 0); 65 // log_bin(&logger_info, 15, 8);
66 log_str(&logger_info, cstr(" | ")); 66 // log_str(&logger_info, cstr(" | "));
67 log_float(&logger_info, 3.14, 4); 67 // log_bin(&logger_info, 16, 8);
68 log_str(&logger_info, cstr(" | ")); 68 // log_str(&logger_info, cstr(" | "));
69 log_float(&logger_info, -0.01415, 8); 69 // log_float(&logger_info, 3.1234, 0);
70 log_str(&logger_info, cstr(" | ")); 70 // log_str(&logger_info, cstr(" | "));
71 log_float(&logger_info, (f64)0x7ff0000000000000L, 0); 71 // log_float(&logger_info, 3.14, 4);
72 log_str(&logger_info, cstr(" | ")); 72 // log_str(&logger_info, cstr(" | "));
73 log_float(&logger_info, (f64)0xfff0000000000000L, 0); 73 // log_float(&logger_info, -0.01415, 8);
74 log_str(&logger_info, cstr(" | ")); 74 // log_str(&logger_info, cstr(" | "));
75 log_float(&logger_info, (f64)0x7ff8000000000000L, 0); 75 // log_float(&logger_info, (f64)0x7ff0000000000000L, 0);
76 log_str(&logger_info, cstr(" >>>")); 76 // log_str(&logger_info, cstr(" | "));
77 log_str(&logger_info, cstr("\n")); 77 // log_float(&logger_info, (f64)0xfff0000000000000L, 0);
78 log_flush(&logger_info); 78 // log_str(&logger_info, cstr(" | "));
79 // log_float(&logger_info, (f64)0x7ff8000000000000L, 0);
80 // log_str(&logger_info, cstr(" >>>"));
81 // log_str(&logger_info, cstr("\n"));
82 // log_flush(&logger_info);
79 83
80 // Logger logger_err = { 84 // Logger logger_err = {
81 // .dest = stderr, 85 // .dest = stderr,