From 2f381d9c24c1418af5b27243428622d4a2b9c467 Mon Sep 17 00:00:00 2001 From: anon Date: Wed, 2 Jul 2025 09:52:28 +0200 Subject: init --- chad/experimental/bits.h | 25 ++++++++++++++++++ chad/experimental/nargs.h | 20 +++++++++++++++ chad/experimental/strlist.h | 60 ++++++++++++++++++++++++++++++++++++++++++++ chad/experimental/terminal.h | 31 +++++++++++++++++++++++ chad/narg.h | 55 ++++++++++++++++++++++++++++++++++++++++ 5 files changed, 191 insertions(+) create mode 100644 chad/experimental/bits.h create mode 100644 chad/experimental/nargs.h create mode 100644 chad/experimental/strlist.h create mode 100644 chad/experimental/terminal.h create mode 100644 chad/narg.h (limited to 'chad') diff --git a/chad/experimental/bits.h b/chad/experimental/bits.h new file mode 100644 index 0000000..a1518e2 --- /dev/null +++ b/chad/experimental/bits.h @@ -0,0 +1,25 @@ +#ifndef CHAD_BITS_H +#define CHAD_BITS_H + +#include +#include + +#define UNUSED(x) ((void)x) + +#define MIN(x, y) (((x) < (y)) ? (x) : (y)) +#define MAX(x, y) (((x) > (y)) ? (x) : (y)) +#define STRINGIFY(x) #x + +// could be a generic +static inline +long map( + long x, + long in_min, + long in_max, + long out_min, + long out_max +) { + return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; +} + +#endif diff --git a/chad/experimental/nargs.h b/chad/experimental/nargs.h new file mode 100644 index 0000000..c4224c9 --- /dev/null +++ b/chad/experimental/nargs.h @@ -0,0 +1,20 @@ +#ifndef CHAD_NARGS_H +#define CHAD_NARGS_H + +#include "nargs.h" +#include + +#define _max_function(T) \ +static inline _max_function_ ## T (size_t n, ...) { \ + va_list args; \ + va_start(args, n); \ + T r = 0; \ + for (size_t i = 0; i < n; i++) { \ + T c = + if () + } \ + + return r; +} + +#endif diff --git a/chad/experimental/strlist.h b/chad/experimental/strlist.h new file mode 100644 index 0000000..f72e356 --- /dev/null +++ b/chad/experimental/strlist.h @@ -0,0 +1,60 @@ +/* The string based list is a common pattern, + * as it is the most intuitive way to serialize a list. + * + * In many languages you would handle it by instantiating + * an actual list by means of splitting, + * but in C we can often do better + * (and we dont have general lists to begin with). + * + * Examples would include: + * + file paths (a/b) + * + file extensions (a.b) + * + unix style option lists (a:b) + * + symbol hierarchies (a->b) + */ + +typedef const char * const * const sep_t; +sep_t UNIX_PATH_SEP = { "/", NULL, }; +sep_t DOS_PATH_SEP = { "\\", NULL, }; +sep_t UNIX_SEP = { ":", NULL, }; +sep_t CPP_SEP = { "::", ".", "->", NULL, }; +sep_t EXT_SEP = { ".", NULL, }; + +size_t strlist_len(char * list, sep_t sep); + +/* This function in an abstract sense performs list indexing. + * The result overwrites the `list` argument and is returned. + * (We know that this may never result in an overflow.) + */ +char * strlist_component(char * list, size_t n, sep_t sep); +/* This function returns a range. + */ +char * strlist_components(char * list, size_t from, size_t to, sep_t sep); + +/* The following are shorthands for component()/components(), + * with a specific numbers which may or may not be lenght specific + * + * Visual explanation: + * this/is/my/example/path + * Root <----------------> + * Base <--> + * Head <--> + * Tail <----------------> + */ +char * strlist_root(char * list, sep_t sep); +char * strlist_base(char * list, sep_t sep); +char * strlist_head(char * list, sep_t sep); +char * strlist_tail(char * list, sep_t sep); + +/* Notes: + * + we very contiously made the decision to not take a destination operand; + * you would have to allocate it just the same, + * copying the source string is not a real performance concern, + * but we want our interface to be as clean as possible + */ + +/* Example: + * Getting the absolute basename of a file. + * char name[] = "this/is/my.file.example"; + * name = strlist_head(strlist_base(name, UNIX_PATH_SEP), EXT_SEP); + */ diff --git a/chad/experimental/terminal.h b/chad/experimental/terminal.h new file mode 100644 index 0000000..e36ddf6 --- /dev/null +++ b/chad/experimental/terminal.h @@ -0,0 +1,31 @@ +#ifndef CHAD_TERMINAL_H +#define CHAD_TERMINAL_H + +#define VT100_RESET "\033[0m" + +#define VT100_BOLD "\033[1m" +#define VT100_ITALICS "\033[3m" +#define VT100_REVERSE "\033[7m" + +#define VT100_FG_BLACK "\033[30m" +#define VT100_FG_RED "\033[31m" +#define VT100_FG_GREEN "\033[32m" +#define VT100_FG_YELLOW "\033[33m" +#define VT100_FG_BLUE "\033[34m" +#define VT100_FG_MAGENTA "\033[35m" +#define VT100_FG_CYAN "\033[36m" +#define VT100_FG_WHITE "\033[37m" + +#define VT100_BG_BLACK "\033[40m" +#define VT100_BG_RED "\033[41m" +#define VT100_BG_GREEN "\033[42m" +#define VT100_BG_YELLOW "\033[43m" +#define VT100_BG_BLUE "\033[44m" +#define VT100_BG_MAGENTA "\033[45m" +#define VT100_BG_CYAN "\033[46m" +#define VT100_BG_WHITE "\033[47m" + +#define VT100_SAVE_CUR "\033[s" +#define VT100_RESTORE_CUR "\033[u" + +#endif diff --git a/chad/narg.h b/chad/narg.h new file mode 100644 index 0000000..a965e85 --- /dev/null +++ b/chad/narg.h @@ -0,0 +1,55 @@ +#ifndef NARG_H +#define NARG_H + +/* A common problem when writting comfortable interfaces is that you want variable arguments, + but without the baggage. + Passing a terminator or the argument count is error prone. + This is a convenience header exactly for that. + The idea is that you define your function to take the argument count: + `_my_comfy_interface(int n, ...)` + Then you wrap it with our macro magick: + `#define my_comfy_interface _my_comfy_interface(NARG(__VA_ARGS__), __VA_ARGS__)` + And it just werks™. +*/ + +#define NARG(...) \ + PP_NARG_(__VA_ARGS__,PP_RSEQ_N()) +#define PP_NARG_(...) \ + PP_128TH_ARG(__VA_ARGS__) +#define PP_128TH_ARG( \ + _1, _2, _3, _4, _5, _6, _7, _8, \ + _9, _10, _11, _12, _13, _14, _15, _16, \ + _17, _18, _19, _20, _21, _22, _23, _24, \ + _25, _26, _27, _28, _29, _30, _31, _32, \ + _33, _34, _35, _36, _37, _38, _39, _40, \ + _41, _42, _43, _44, _45, _46, _47, _48, \ + _49, _50, _51, _52, _53, _54, _55, _56, \ + _57, _58, _59, _60, _61, _62, _63, _64, \ + _65, _66, _67, _68, _69, _70, _71, _72, \ + _73, _74, _75, _76, _77, _78, _79, _80, \ + _81, _82, _83, _84, _85, _86, _87, _88, \ + _89, _90, _91, _92, _93, _94, _95, _96, \ + _97, _98, _99,_100,_101,_102,_103,_104, \ + _105,_106,_107,_108,_109,_110,_111,_112, \ + _113,_114,_115,_116,_117,_118,_119,_120, \ + _121,_122,_123,_124,_125,_126,_127, N, ... \ + ) N +#define PP_RSEQ_N() \ + 127,126,125,124,123,122,121,120, \ + 119,118,117,116,115,114,113,112, \ + 111,110,109,108,107,106,105,104, \ + 103,102,101,100, 99, 98, 97, 96, \ + 95, 94, 93, 92, 91, 90, 89, 88, \ + 87, 86, 85, 84, 83, 82, 81, 80, \ + 79, 78, 77, 76, 75, 74, 73, 72, \ + 71, 70, 69, 68, 67, 66, 65, 64, \ + 63, 62, 61, 60, 59, 58, 57, 56, \ + 55, 54, 53, 52, 51, 50, 49, 48, \ + 47, 46, 45, 44, 43, 42, 41, 40, \ + 39, 38, 37, 36, 35, 34, 33, 32, \ + 31, 30, 29, 28, 27, 26, 25, 24, \ + 23, 22, 21, 20, 19, 18, 17, 16, \ + 15, 14, 13, 12, 11, 10, 9, 8, \ + 7, 6, 5, 4, 3, 2, 1, 0 + +#endif -- cgit v1.2.3