aboutsummaryrefslogtreecommitdiff
path: root/chad/experimental/strlist.h
blob: f72e356f49002e13a63c46d903ce1e028313f356 (plain) (blame)
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
/* 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);
 */