unix/fiss-minit

split.c in master
Repositories | Summary | Log | Files | README | COPYING

split.c (1104B) download


 1#include <stdlib.h>
 2
 3/* split buf into n strings that are separated by c.  return n as *len.
 4 * Allocate plus more slots and leave the first ofs of them alone. */
 5char** split(char* buf, int c, size_t* len, size_t plus, size_t ofs) {
 6	int    n = 1;
 7	char** v = 0;
 8	char** w;
 9	/* step 1: count tokens */
10	char* s;
11	for (s = buf; *s; s++)
12		if (*s == c) n++;
13	/* step 2: allocate space for pointers */
14	v = (char**) malloc((n + plus) * sizeof(char*));
15	if (!v) return 0;
16	w    = v + ofs;
17	*w++ = buf;
18	for (s = buf;; s++) {
19		while (*s && *s != c) s++;
20		if (*s == 0) break;
21		if (*s == c) {
22			*s   = 0;
23			*w++ = s + 1;
24		}
25	}
26	*len = w - v;
27	return v;
28}
29
30#ifdef UNITTEST
31#	include <assert.h>
32#	include <stdio.h>
33#	include <string.h>
34
35int main() {
36	char   inp[] = "foo\nbar\nbaz";
37	size_t len;
38	char** x = split(inp, '\n', &len, 2, 1);
39	assert(len == 4 && !strcmp(x[1], "foo") && !strcmp(x[2], "bar") && !strcmp(x[3], "baz") && x[4] == NULL);
40	free(x);
41	char inp2[] = "fnord";
42	x           = split(inp2, '\n', &len, 2, 1);
43	assert(len == 2 && !strcmp(x[1], "fnord") && x[2] == NULL);
44	return 0;
45}
46#endif