2 /********************************************
4 copyright 1991, Michael D. Brennan
6 This is a source file for mawk, an implementation of
7 the AWK programming language.
9 Mawk is distributed without warranty under the terms of
10 the GNU General Public License, version 2, 1991.
11 ********************************************/
14 * Revision 1.3 1996/02/01 04:39:42 mike
15 * dynamic array scheme
17 * Revision 1.2 1993/07/15 01:55:03 mike
20 * Revision 1.1.1.1 1993/07/03 18:58:21 mike
23 * Revision 5.4 1993/05/08 18:06:00 mike
26 * Revision 5.3 1993/01/01 21:30:48 mike
27 * split new_STRING() into new_STRING and new_STRING0
29 * Revision 5.2 1992/07/08 21:19:09 brennan
31 * change in split() requires that
32 * bi_split() call load_array() even
35 * Revision 5.1 1991/12/05 07:56:31 brennan
43 /* For all splitting up to MAX_SPLIT fields go into
44 split_buff[], the rest go onto split_ov_list ( split
47 We can split one of three ways:
49 space_split() and space_ov_split()
50 (2) By regular expression:
51 re_split() and re_ov_split()
52 (3) By "" (null -- split into characters)
53 null_split() and null_ov_split()
56 #define TEMPBUFF_GOES_HERE
67 SPLIT_OV *split_ov_list ;
69 static int PROTO(re_ov_split, (char *, PTR)) ;
70 static int PROTO(space_ov_split, (char *, char *)) ;
71 static int PROTO(null_ov_split, (char *)) ;
73 /* split string s of length slen on SPACE without changing s.
74 load the pieces into STRINGS and ptrs into
76 return the number of pieces */
83 char *back = s + slen ;
88 int lcnt = MAX_SPLIT / 3 ;
90 #define EAT_SPACE() while ( scan_code[*(unsigned char*)s] ==\
92 #define EAT_NON_SPACE() \
93 *back = ' ' ; /* sentinel */\
94 while ( scan_code[*(unsigned char*)s] != SC_SPACE ) s++ ;\
101 if (*s == 0) goto done ;
102 /* mark the front with q */
105 sval = split_buff[i++] = new_STRING0(len = s - q) ;
106 memcpy(sval->str, q, len) ;
109 if (*s == 0) goto done ;
112 sval = split_buff[i++] = new_STRING0(len = s - q) ;
113 memcpy(sval->str, q, len) ;
116 if (*s == 0) goto done ;
119 sval = split_buff[i++] = new_STRING0(len = s - q) ;
120 memcpy(sval->str, q, len) ;
123 /* we've overflowed */
124 return i + space_ov_split(s, back) ;
131 space_ov_split(s, back)
137 register SPLIT_OV *tail = &dummy ;
145 if (*s == 0) break ; /* done */
149 tail = tail->link = ZMALLOC(SPLIT_OV) ;
150 tail->sval = new_STRING0(len = s - q) ;
151 memcpy(tail->sval->str, q, len) ;
155 tail->link = (SPLIT_OV *) 0 ;
156 split_ov_list = dummy.link ;
160 /* match a string with a regular expression, but
161 only matches of positive length count */
163 re_pos_match(s, re, lenp)
165 PTR re ; unsigned *lenp ;
167 while ((s = REmatch(s, re, lenp)))
168 if (*lenp) return s ;
169 else if (*s == 0) break ;
184 int lcnt = MAX_SPLIT / 3 ;
188 if (!(t = re_pos_match(s, re, &mlen))) goto done ;
189 sval = split_buff[i++] = new_STRING0(len = t - s) ;
190 memcpy(sval->str, s, len) ;
193 if (!(t = re_pos_match(s, re, &mlen))) goto done ;
194 sval = split_buff[i++] = new_STRING0(len = t - s) ;
195 memcpy(sval->str, s, len) ;
198 if (!(t = re_pos_match(s, re, &mlen))) goto done ;
199 sval = split_buff[i++] = new_STRING0(len = t - s) ;
200 memcpy(sval->str, s, len) ;
203 /* we've overflowed */
204 return i + re_ov_split(s, re) ;
207 split_buff[i++] = new_STRING(s) ;
212 we've overflowed split_buff[] , put
213 the rest on the split_ov_list
214 return number of pieces
223 register SPLIT_OV *tail = &dummy ;
228 while ((t = re_pos_match(s, re, &mlen)))
230 tail = tail->link = ZMALLOC(SPLIT_OV) ;
231 tail->sval = new_STRING0(len = t - s) ;
232 memcpy(tail->sval->str, s, len) ;
237 tail = tail->link = ZMALLOC(SPLIT_OV) ;
238 tail->sval = new_STRING(s) ;
239 tail->link = (SPLIT_OV *) 0 ;
240 split_ov_list = dummy.link ;
250 int cnt = 0 ; /* number of fields split */
252 int i = 0 ; /* indexes split_buff[] */
256 if (cnt == MAX_SPLIT) return cnt + null_ov_split(s) ;
258 sval = new_STRING0(1) ;
259 sval->str[0] = *s++ ;
260 split_buff[i++] = sval ;
271 SPLIT_OV *ovp = &dummy ;
276 ovp = ovp->link = ZMALLOC(SPLIT_OV) ;
277 ovp->sval = new_STRING0(1) ;
278 ovp->sval->str[0] = *s++ ;
281 ovp->link = (SPLIT_OV *) 0 ;
282 split_ov_list = dummy.link ;
288 split s into array X on r
298 int cnt ; /* the number of pieces */
301 if (sp->type < C_RE) cast_for_split(sp) ;
302 /* can be C_RE, C_SPACE or C_SNULL */
304 if (sp->type < C_STRING) cast1_to_s(sp) ;
306 if (string(sp)->len == 0) /* nothing to split */
309 switch ((sp + 2)->type)
312 cnt = re_split(string(sp)->str, (sp + 2)->ptr) ;
316 cnt = space_split(string(sp)->str, string(sp)->len) ;
319 case C_SNULL: /* split on empty string */
320 cnt = null_split(string(sp)->str) ;
324 bozo("bad splitting cell in bi_split") ;
328 free_STRING(string(sp)) ;
329 sp->type = C_DOUBLE ;
330 sp->dval = (double) cnt ;
332 array_load((ARRAY) (sp + 1)->ptr, cnt) ;