aboutsummaryrefslogtreecommitdiff
path: root/chad
diff options
context:
space:
mode:
Diffstat (limited to 'chad')
-rw-r--r--chad/experimental/bits.h25
-rw-r--r--chad/experimental/nargs.h20
-rw-r--r--chad/experimental/strlist.h60
-rw-r--r--chad/experimental/terminal.h31
-rw-r--r--chad/narg.h55
5 files changed, 191 insertions, 0 deletions
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 <stdbool.h>
+#include <iso646>
+
+#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 <stdarg.h>
+
+#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