2 do_split(TARG,spat,limit,gimme,arglast)
9 register ARRAY *ary = stack;
10 STR **st = ary->ary_array;
11 register int sp = arglast[0] + 1;
12 register char *s = str_get(st[sp]);
13 char *strend = s + st[sp--]->str_cur;
17 int maxiters = (strend - s) + 10;
20 int origlimit = limit;
24 fatal("panic: do_split");
25 else if (spat->spat_runtime) {
27 sp = eval(spat->spat_runtime,G_SCALAR,sp);
28 st = stack->ary_array;
29 m = str_get(dstr = st[sp--]);
31 if (*m == ' ' && dstr->str_cur == 1) {
34 spat->spat_flags |= SPAT_SKIPWHITE;
36 if (spat->spat_regexp) {
37 regfree(spat->spat_regexp);
38 spat->spat_regexp = Null(REGEXP*); /* avoid possible double free */
40 spat->spat_regexp = regcomp(m,m+dstr->str_cur,
41 spat->spat_flags & SPAT_FOLD);
42 if (spat->spat_flags & SPAT_KEEP ||
43 (spat->spat_runtime->arg_type == O_ITEM &&
44 (spat->spat_runtime[1].arg_type & A_MASK) == A_SINGLE) ) {
45 arg_free(spat->spat_runtime); /* it won't change, so */
46 spat->spat_runtime = Nullarg; /* no point compiling again */
51 deb("2.SPAT /%s/\n",spat->spat_regexp->precomp);
54 ary = stab_xarray(spat->spat_repl[1].arg_ptr.arg_stab);
55 if (ary && (gimme != G_ARRAY || (spat->spat_flags & SPAT_ONCE))) {
57 if (!(ary->ary_flags & ARF_REAL)) {
58 ary->ary_flags |= ARF_REAL;
59 for (i = ary->ary_fill; i >= 0; i--)
60 ary->ary_array[i] = Nullstr; /* don't free mere refs */
63 sp = -1; /* temporarily switch stacks */
68 if (spat->spat_flags & SPAT_SKIPWHITE) {
74 if (strEQ("\\s+",spat->spat_regexp->precomp)) {
77 for (m = s; m < strend && !isSPACE(*m); m++) ;
80 dstr = Str_new(30,m-s);
84 (void)astore(ary, ++sp, dstr);
86 for (s = m + 1; s < strend && isSPACE(*s); s++) ;
89 else if (strEQ("^",spat->spat_regexp->precomp)) {
92 for (m = s; m < strend && *m != '\n'; m++) ;
96 dstr = Str_new(30,m-s);
100 (void)astore(ary, ++sp, dstr);
104 else if (spat->spat_short) {
105 i = spat->spat_short->str_cur;
107 int fold = (spat->spat_flags & SPAT_FOLD);
109 i = *spat->spat_short->str_ptr;
110 if (fold && isUPPER(i))
115 m < strend && *m != i &&
116 (!isUPPER(*m) || tolower(*m) != i);
117 m++) /*SUPPRESS 530*/
120 else /*SUPPRESS 530*/
121 for (m = s; m < strend && *m != i; m++) ;
124 dstr = Str_new(30,m-s);
125 str_nset(dstr,s,m-s);
128 (void)astore(ary, ++sp, dstr);
134 while (s < strend && --limit &&
135 (m=fbminstr((unsigned char*)s, (unsigned char*)strend,
139 dstr = Str_new(31,m-s);
140 str_nset(dstr,s,m-s);
143 (void)astore(ary, ++sp, dstr);
149 maxiters += (strend - s) * spat->spat_regexp->nparens;
150 while (s < strend && --limit &&
151 regexec(spat->spat_regexp, s, strend, orig, 1, Nullstr, TRUE) ) {
152 if (spat->spat_regexp->subbase
153 && spat->spat_regexp->subbase != orig) {
156 orig = spat->spat_regexp->subbase;
158 strend = s + (strend - m);
160 m = spat->spat_regexp->startp[0];
161 dstr = Str_new(32,m-s);
162 str_nset(dstr,s,m-s);
165 (void)astore(ary, ++sp, dstr);
166 if (spat->spat_regexp->nparens) {
167 for (i = 1; i <= spat->spat_regexp->nparens; i++) {
168 s = spat->spat_regexp->startp[i];
169 m = spat->spat_regexp->endp[i];
170 dstr = Str_new(33,m-s);
171 str_nset(dstr,s,m-s);
174 (void)astore(ary, ++sp, dstr);
177 s = spat->spat_regexp->endp[0];
183 iters = sp - arglast[0];
184 if (iters > maxiters)
186 if (s < strend || origlimit) { /* keep field after final delim? */
187 dstr = Str_new(34,strend-s);
188 str_nset(dstr,s,strend-s);
191 (void)astore(ary, ++sp, dstr);
196 while (iters > 0 && ary->ary_array[sp]->str_cur == 0)
203 zaps = str_get(afetch(ary,sp,FALSE));
207 while (iters > 0 && (!zapb)) {
210 zaps = str_get(afetch(ary,iters-1,FALSE));
218 if (gimme == G_ARRAY) {
220 astore(stack, arglast[0] + 1 + sp, Nullstr);
221 Copy(ary->ary_array, stack->ary_array + arglast[0] + 1, sp, STR*);
222 return arglast[0] + sp;
226 if (gimme == G_ARRAY)
230 str_numset(TARG,(double)iters);