summaryrefslogtreecommitdiff
path: root/src/util/string.h
blob: 1ef07d1e7535377fff05167861888dcb40b67195 (plain)
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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
#ifndef _SK_UTIL_STRING_H
#define _SK_UTIL_STRING_H

#include "array.h"

#include <stddef.h>

/**
 * stringize:
 * Convert value of preprocessor macro to C string literal.
 *
 * @param x: the name of the macro
 */
#define stringize(x) quote(x)

/**
 * quote:
 * Quote literally whatever is passed into this macro as a C string.
 *
 * @param x: the value to quote
 *
 */
#ifdef HAVE_STRINGIZE
#define quote(x) #x
#else
#error "No CPP stringize operator available?"
#endif

/**
 * boolstr:
 * Make string out of bool.
 *
 * @param b: the boolean variable
 * @returns "true" or "false"
 */
#define boolstr(b) (b ? "true" : "false")

/**
 * strdup:
 * like strdup(3p).
 */
char *strdup(const char *s);

/**
 * strajoin:
 * Joins a C string array using a separator character.
 *
 * The returned string should be free()d.
 *
 * @param sep: a char to insert between each element of the array
 * @param a: the array to join (NULL terminated)
 * @return a newly-allocated C string containing all of the elements joined
 */
#define strajoin(sep, a) stranjoin(sep, a, anullidx((void *)a))

/**
 * strajoin_r:
 * Joins a C string array using a separator character into a caller allocated
 * buffer.
 *
 * NOTE: the return value of this function is the length of the result if the
 * buffer would’ve been large enough. Use this to check for truncation.
 * If the destination buffer wasn’t large enough, the resulting string won’t be
 * NUL terminated.
 *
 * @param buf: the destination buffer (nothing will be written to it if NULL)
 * @param buflen: the length of @buf
 * @param sep: a char to insert between eaach element of the array
 * @param a: the array to join (NULL terminated)
 * @return the length of the full result string
 */
#define strajoin_r(buf, buflen, sep, a, nmemb) \
	stranjoin_r(buf, buflen, sep, a, anullidx((void *)a))

/**
 * stranjoin:
 * Joins a C string array using a separator character.
 *
 * The returned string should be free()d.
 *
 * @param sep: a char to insert between each element of the array
 * @param a: the array to join
 * @param nmemb: the number of elements of @a
 * @return a newly-allocated C string containing all of the elements joined
 */
char *stranjoin(char sep, const char *a[], size_t nmemb);

/**
 * stranjoin_r:
 * Joins a C string array using a separator character into a caller allocated
 * buffer.
 *
 * NOTE: the return value of this function is the length of the result if the
 * buffer would’ve been large enough. Use this to check for truncation.
 * If the destination buffer wasn’t large enough, the resulting string won’t be
 * NUL terminated.
 *
 * @param buf: the destination buffer (nothing will be written to it if NULL)
 * @param buflen: the length of @buf
 * @param sep: a char to insert between each element of @a
 * @param a: the array to join (NULL terminated)
 * @param nmemb: the number of elements of @a
 * @return the length of the untruncated joined string
 */
size_t stranjoin_r(
	char *restrict buf, size_t buflen, char sep, const char *restrict a[],
	size_t nmemb);


char *_strjoin(  /* internal */
	char sep, /* const char * */...);
size_t _strjoin_r(  /* internal */
	char *restrict buf, size_t buflen, char sep, /* const char * */...);

/**
 * strjoin:
 * Joins a number of strings together to form one long string, with the
 * @separator inserted between each of them. The returned string
 * should be free()d.
 *
 * @param sep: a char to insert between each of the strings
 * @param ...: a list of strings to join
 * @return a newly-allocated string containing all of the strings joined
 */
#define strjoin(sep, ...) _strjoin(sep, __VA_ARGS__, NULL)

/**
 * strjoin_r:
 * Joins a number of strings together to form one long string stored in a
 * caller-allocated buffer with the @separator inserted betwween each of them.
 *
 * @param buf: the destination buffer (nothing will be written to it if NULL)
 * @param buflen: the length of @buf
 * @param sep: a char to insert between each of the strings
 * @param ...: a list of strings to join
 * @return the length of the untruncated joined string
 */
#define strjoin_r(sep, ...) _strjoin_r(sep, __VA_ARGS__, NULL)

/**
 * pathjoin:
 * Joins a number of path components together to form one single path.
 * The returned string should be free()d.
 *
 * @param ...: a list of path components to join
 * @return a newly-allocated string containing all of the path components joined
 */
#define pathjoin(...) strjoin(stringize(DIRSEP)[0], __VA_ARGS__)

/**
 * pathjoin_r:
 * Joins a number of path components together to form one single path.
 * The result is stored in a caller-allocated buffer.
 *
 * @param buf: the destination buffer (nothing will be weitten to it if NULL)
 * @param buflen: the length of @buf
 * @param ...: a list of path components to join
 * @return the length of the untruncated joined string
 */
#define pathjoin_r(buf, buflen, ...) \
	strjoin_r(buf, buflen, stringize(DIRSEP)[0], __VA_ARGS__)

/**
 * strsplit:
 * Splits a string into a NULL-terminated array by a given separator.
 *
 * Call this function with a NULL buffer to determine the size of the resulting
 * array.
 *
 * @param str: the input string (null-terminated)
 * @param sep: a string containing one or more separator characters
 * @param buf: a buffer to put the array into
 * @returns the number of bytes written into buf
 */
size_t strsplit(const char *restrict in, const char *restrict sep, void *buf);

#endif