xref: /plan9-contrib/sys/src/libc/port/getfields.c (revision 219b2ee8daee37f4aad58d63f21287faa8e4ffdc)
1 #include	<u.h>
2 #include	<libc.h>
3 
4 static char is_sep[256] =
5 {
6 	0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
7 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
8 	1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
9 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
10 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
11 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
12 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
13 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
14 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
15 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
16 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
17 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
18 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
19 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
20 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
21 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
22 };
23 static char is_field[256] =
24 {
25 	0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1,
26 	1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
27 	0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
28 	1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
29 	1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
30 	1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
31 	1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
32 	1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
33 	1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
34 	1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
35 	1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
36 	1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
37 	1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
38 	1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
39 	1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
40 	1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
41 };
42 static char last_sep[256];
43 
44 char *
45 setfields(char *arg)
46 {
47 	uchar *s;
48 	register i;
49 
50 	for(i = 1, s = (uchar*)last_sep; i < 256; i++)
51 		if(is_sep[i])
52 			*s++ = i;
53 	*s = 0;
54 	memset(is_sep, 0, sizeof is_sep);
55 	memset(is_field, 1, sizeof is_field);
56 	for(s = (uchar*)arg; *s;){
57 		is_sep[*s] = 1;
58 		is_field[*s++] = 0;
59 	}
60 	is_field[0] = 0;
61 	return last_sep;
62 }
63 
64 int
65 getfields(char *ss, char **sp, int nptrs)
66 {
67 	uchar *s = (uchar*)ss;
68 	uchar **p = (uchar**)sp;
69 	uint c;
70 
71 	c = 0;
72 	for(;;){
73 		if(--nptrs < 0)
74 			break;
75 		*p++ = s;
76 		do {
77 			c = *s++;
78 		} while(is_field[c]);
79 		if(c == 0)
80 			break;
81 		s[-1] = 0;
82 	}
83 	if(nptrs > 0)
84 		*p = 0;
85 	else
86 	if(--s >= (uchar*)ss)
87 		*s = c;
88 	return p - (uchar**)sp;
89 }
90 
91 int
92 getmfields(char *ss, char **sp, int nptrs)
93 {
94 	uchar *s = (uchar*)ss;
95 	uchar **p = (uchar**)sp;
96 	uint c;
97 
98 	if(nptrs <= 0)
99 		return 0;
100 	goto flushdelim;
101 	for(;;){
102 		*p++ = s;
103 		if(--nptrs == 0)
104 			break;
105 		while(is_field[c = *s++])
106 			;
107 		/*
108 		 *  s is now pointing 1 past the delimiter of the last field
109 		 *  c is the delimiter
110 		 */
111 		if(c == 0)
112 			break;
113 		s[-1] = 0;
114 	flushdelim:
115 		while(is_sep[c = *s++])
116 			;
117 		/*
118 		 *  s is now pointing 1 past the beginning of the next field
119 		 *  c is the first letter of the field
120 		 */
121 		if(c == 0)
122 			break;
123 		s--;
124 		/*
125 		 *  s is now pointing to the beginning of the next field
126 		 *  c is the first letter of the field
127 		 */
128 	}
129 	if(nptrs > 0)
130 		*p = 0;
131 	return p - (uchar**)sp;
132 }
133 
134 #ifdef	MAIN
135 #include	<fio.h>
136 
137 main(void)
138 {
139 	char *fields[256];
140 	char *s;
141 	int n, i;
142 	char buf[1024];
143 
144 	print("go:\n");
145 	while(s = Frdline(0)){
146 		strcpy(buf, s);
147 		Fprint(1, "getf:");
148 		n = getfields(s, fields, 4);
149 		for(i = 0; i < n; i++)
150 			Fprint(1, " >%s<", fields[i]);
151 		Fputc(1, '\n');
152 		Fprint(1, "getmf:");
153 		n = getmfields(buf, fields, 4);
154 		for(i = 0; i < n; i++)
155 			Fprint(1, " >%s<", fields[i]);
156 		Fputc(1, '\n');
157 		Fflush(1);
158 	}
159 	exits(0);
160 }
161 #endif
162