This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
perl 4.0 patch 8: patch #4, continued
[perl5.git] / toke.c
CommitLineData
35c8bce7 1/* $RCSfile: toke.c,v $$Revision: 4.0.1.1 $$Date: 91/04/12 09:18:18 $
a687059c
LW
2 *
3 * Copyright (c) 1989, Larry Wall
4 *
5 * You may distribute under the terms of the GNU General Public License
6 * as specified in the README file that comes with the perl 3.0 kit.
378cc40b
LW
7 *
8 * $Log: toke.c,v $
35c8bce7
LW
9 * Revision 4.0.1.1 91/04/12 09:18:18 lwall
10 * patch1: perl -de "print" wouldn't stop at the first statement
11 *
fe14fcc3
LW
12 * Revision 4.0 91/03/20 01:42:14 lwall
13 * 4.0 baseline.
378cc40b
LW
14 *
15 */
16
17#include "EXTERN.h"
18#include "perl.h"
19#include "perly.h"
20
395c3793
LW
21#ifdef I_FCNTL
22#include <fcntl.h>
23#endif
fe14fcc3
LW
24#ifdef I_SYS_FILE
25#include <sys/file.h>
26#endif
395c3793
LW
27
28/* which backslash sequences to keep in m// or s// */
29
30static char *patleave = "\\.^$@dDwWsSbB+*?|()-nrtf0123456789[{]}";
31
fe14fcc3
LW
32char *reparse; /* if non-null, scanident found ${foo[$bar]} */
33
34void checkcomma();
a687059c 35
ae986130
LW
36#ifdef CLINE
37#undef CLINE
38#endif
e929a76b 39#define CLINE (cmdline = (curcmd->c_line < cmdline ? curcmd->c_line : cmdline))
378cc40b 40
a687059c
LW
41#define META(c) ((c) | 128)
42
378cc40b
LW
43#define RETURN(retval) return (bufptr = s,(int)retval)
44#define OPERATOR(retval) return (expectterm = TRUE,bufptr = s,(int)retval)
45#define TERM(retval) return (CLINE, expectterm = FALSE,bufptr = s,(int)retval)
46#define LOOPX(f) return(yylval.ival=f,expectterm = FALSE,bufptr = s,(int)LOOPEX)
378cc40b
LW
47#define FTST(f) return(yylval.ival=f,expectterm = TRUE,bufptr = s,(int)FILETEST)
48#define FUN0(f) return(yylval.ival = f,expectterm = FALSE,bufptr = s,(int)FUNC0)
49#define FUN1(f) return(yylval.ival = f,expectterm = FALSE,bufptr = s,(int)FUNC1)
50#define FUN2(f) return(yylval.ival = f,expectterm = FALSE,bufptr = s,(int)FUNC2)
395c3793 51#define FUN2x(f) return(yylval.ival = f,expectterm = FALSE,bufptr = s,(int)FUNC2x)
378cc40b 52#define FUN3(f) return(yylval.ival = f,expectterm = FALSE,bufptr = s,(int)FUNC3)
395c3793
LW
53#define FUN4(f) return(yylval.ival = f,expectterm = FALSE,bufptr = s,(int)FUNC4)
54#define FUN5(f) return(yylval.ival = f,expectterm = FALSE,bufptr = s,(int)FUNC5)
a687059c
LW
55#define FL(f) return(yylval.ival=f,expectterm = FALSE,bufptr = s,(int)FLIST)
56#define FL2(f) return(yylval.ival=f,expectterm = FALSE,bufptr = s,(int)FLIST2)
57#define HFUN(f) return(yylval.ival=f,expectterm = TRUE,bufptr = s,(int)HSHFUN)
58#define HFUN3(f) return(yylval.ival=f,expectterm = FALSE,bufptr = s,(int)HSHFUN3)
59#define LFUN(f) return(yylval.ival=f,expectterm = TRUE,bufptr = s,(int)LVALFUN)
a687059c
LW
60#define AOP(f) return(yylval.ival=f,expectterm = TRUE,bufptr = s,(int)ADDOP)
61#define MOP(f) return(yylval.ival=f,expectterm = TRUE,bufptr = s,(int)MULOP)
62#define EOP(f) return(yylval.ival=f,expectterm = TRUE,bufptr = s,(int)EQOP)
63#define ROP(f) return(yylval.ival=f,expectterm = TRUE,bufptr = s,(int)RELOP)
64#define FOP(f) return(yylval.ival=f,expectterm = FALSE,bufptr = s,(int)FILOP)
65#define FOP2(f) return(yylval.ival=f,expectterm = FALSE,bufptr = s,(int)FILOP2)
66#define FOP3(f) return(yylval.ival=f,expectterm = FALSE,bufptr = s,(int)FILOP3)
67#define FOP4(f) return(yylval.ival=f,expectterm = FALSE,bufptr = s,(int)FILOP4)
68#define FOP22(f) return(yylval.ival=f,expectterm = FALSE,bufptr = s,(int)FILOP22)
69#define FOP25(f) return(yylval.ival=f,expectterm = FALSE,bufptr = s,(int)FILOP25)
70
71/* This bit of chicanery makes a unary function followed by
72 * a parenthesis into a function with one argument, highest precedence.
73 */
74#define UNI(f) return(yylval.ival = f,expectterm = TRUE,bufptr = s, \
75 (*s == '(' || (s = skipspace(s), *s == '(') ? (int)FUNC1 : (int)UNIOP) )
76
77/* This does similarly for list operators, merely by pretending that the
78 * paren came before the listop rather than after.
79 */
35c8bce7 80#define LOP(f) return(CLINE, *s == '(' || (s = skipspace(s), *s == '(') ? \
a687059c
LW
81 (*s = META('('), bufptr = oldbufptr, '(') : \
82 (yylval.ival=f,expectterm = TRUE,bufptr = s,(int)LISTOP))
9f68db38
LW
83/* grandfather return to old style */
84#define OLDLOP(f) return(yylval.ival=f,expectterm = TRUE,bufptr = s,(int)LISTOP)
a687059c
LW
85
86char *
87skipspace(s)
88register char *s;
89{
90 while (s < bufend && isascii(*s) && isspace(*s))
91 s++;
92 return s;
93}
378cc40b 94
ffed7fef
LW
95#ifdef CRIPPLED_CC
96
97#undef UNI
98#undef LOP
99#define UNI(f) return uni(f,s)
100#define LOP(f) return lop(f,s)
101
102int
103uni(f,s)
104int f;
105char *s;
106{
107 yylval.ival = f;
108 expectterm = TRUE;
109 bufptr = s;
110 if (*s == '(')
111 return FUNC1;
112 s = skipspace(s);
113 if (*s == '(')
114 return FUNC1;
115 else
116 return UNIOP;
117}
118
119int
120lop(f,s)
121int f;
122char *s;
123{
35c8bce7 124 CLINE;
ffed7fef
LW
125 if (*s != '(')
126 s = skipspace(s);
127 if (*s == '(') {
128 *s = META('(');
129 bufptr = oldbufptr;
130 return '(';
131 }
132 else {
133 yylval.ival=f;
134 expectterm = TRUE;
135 bufptr = s;
136 return LISTOP;
137 }
138}
139
140#endif /* CRIPPLED_CC */
141
378cc40b
LW
142yylex()
143{
144 register char *s = bufptr;
145 register char *d;
146 register int tmp;
147 static bool in_format = FALSE;
148 static bool firstline = TRUE;
a687059c
LW
149 extern int yychar; /* last token */
150
151 oldoldbufptr = oldbufptr;
152 oldbufptr = s;
378cc40b
LW
153
154 retry:
155#ifdef YYDEBUG
ae986130 156 if (debug & 1)
378cc40b
LW
157 if (index(s,'\n'))
158 fprintf(stderr,"Tokener at %s",s);
159 else
160 fprintf(stderr,"Tokener at %s\n",s);
161#endif
e929a76b
LW
162#ifdef BADSWITCH
163 if (*s & 128) {
164 if ((*s & 127) == '(')
165 *s++ = '(';
166 else
fe14fcc3 167 warn("Unrecognized character \\%03o ignored", *s++ & 255);
e929a76b
LW
168 goto retry;
169 }
170#endif
378cc40b
LW
171 switch (*s) {
172 default:
a687059c
LW
173 if ((*s & 127) == '(')
174 *s++ = '(';
175 else
fe14fcc3 176 warn("Unrecognized character \\%03o ignored", *s++ & 255);
378cc40b 177 goto retry;
e929a76b
LW
178 case 4:
179 case 26:
180 goto fake_eof; /* emulate EOF on ^D or ^Z */
378cc40b 181 case 0:
378cc40b
LW
182 if (!rsfp)
183 RETURN(0);
a687059c
LW
184 if (s++ < bufend)
185 goto retry; /* ignore stray nulls */
186 if (firstline) {
187 firstline = FALSE;
188 if (minus_n || minus_p || perldb) {
189 str_set(linestr,"");
395c3793
LW
190 if (perldb) {
191 char *getenv();
192 char *pdb = getenv("PERLDB");
193
194 str_cat(linestr, pdb ? pdb : "require 'perldb.pl'");
195 str_cat(linestr, ";");
196 }
a687059c
LW
197 if (minus_n || minus_p) {
198 str_cat(linestr,"line: while (<>) {");
fe14fcc3
LW
199 if (minus_l)
200 str_cat(linestr,"chop;");
a687059c
LW
201 if (minus_a)
202 str_cat(linestr,"@F=split(' ');");
203 }
204 oldoldbufptr = oldbufptr = s = str_get(linestr);
205 bufend = linestr->str_ptr + linestr->str_cur;
206 goto retry;
207 }
208 }
378cc40b 209 if (in_format) {
0f85fab0 210 bufptr = bufend;
a687059c 211 yylval.formval = load_format();
378cc40b 212 in_format = FALSE;
a687059c
LW
213 oldoldbufptr = oldbufptr = s = str_get(linestr) + 1;
214 bufend = linestr->str_ptr + linestr->str_cur;
e929a76b
LW
215 OPERATOR(FORMLIST);
216 }
217 curcmd->c_line++;
218#ifdef CRYPTSCRIPT
219 cryptswitch();
220#endif /* CRYPTSCRIPT */
221 do {
222 if ((s = str_gets(linestr, rsfp, 0)) == Nullch) {
223 fake_eof:
395c3793
LW
224 if (rsfp) {
225 if (preprocess)
226 (void)mypclose(rsfp);
227 else if (rsfp == stdin)
228 clearerr(stdin);
229 else
230 (void)fclose(rsfp);
231 rsfp = Nullfp;
232 }
e929a76b
LW
233 if (minus_n || minus_p) {
234 str_set(linestr,minus_p ? ";}continue{print" : "");
235 str_cat(linestr,";}");
236 oldoldbufptr = oldbufptr = s = str_get(linestr);
237 bufend = linestr->str_ptr + linestr->str_cur;
238 minus_n = minus_p = 0;
239 goto retry;
240 }
a687059c 241 oldoldbufptr = oldbufptr = s = str_get(linestr);
e929a76b
LW
242 str_set(linestr,"");
243 RETURN(';'); /* not infinite loop because rsfp is NULL now */
378cc40b 244 }
e929a76b
LW
245 if (doextract && *linestr->str_ptr == '#')
246 doextract = FALSE;
247 } while (doextract);
a687059c
LW
248 oldoldbufptr = oldbufptr = bufptr = s;
249 if (perldb) {
250 STR *str = Str_new(85,0);
251
252 str_sset(str,linestr);
395c3793 253 astore(stab_xarray(curcmd->c_filestab),(int)curcmd->c_line,str);
a687059c 254 }
378cc40b 255#ifdef DEBUG
a687059c 256 if (firstline) {
378cc40b
LW
257 char *showinput();
258 s = showinput();
259 }
260#endif
a687059c 261 bufend = linestr->str_ptr + linestr->str_cur;
e929a76b 262 if (curcmd->c_line == 1) {
9f68db38
LW
263 if (*s == '#' && s[1] == '!') {
264 if (!in_eval && !instr(s,"perl") && instr(origargv[0],"perl")) {
265 char **newargv;
266 char *cmd;
267
268 s += 2;
269 if (*s == ' ')
270 s++;
271 cmd = s;
272 while (s < bufend && !isspace(*s))
273 s++;
274 *s++ = '\0';
275 while (s < bufend && isspace(*s))
276 s++;
277 if (s < bufend) {
278 Newz(899,newargv,origargc+3,char*);
279 newargv[1] = s;
280 while (s < bufend && !isspace(*s))
281 s++;
282 *s = '\0';
283 Copy(origargv+1, newargv+2, origargc+1, char*);
284 }
285 else
286 newargv = origargv;
287 newargv[0] = cmd;
288 execv(cmd,newargv);
289 fatal("Can't exec %s", cmd);
290 }
291 }
292 else {
293 while (s < bufend && isspace(*s))
294 s++;
295 if (*s == ':') /* for csh's that have to exec sh scripts */
296 s++;
297 }
ae986130 298 }
378cc40b 299 goto retry;
fe14fcc3 300 case ' ': case '\t': case '\f': case '\r': case 013:
378cc40b
LW
301 s++;
302 goto retry;
378cc40b
LW
303 case '#':
304 if (preprocess && s == str_get(linestr) &&
305 s[1] == ' ' && isdigit(s[2])) {
e929a76b 306 curcmd->c_line = atoi(s+2)-1;
378cc40b 307 for (s += 2; isdigit(*s); s++) ;
a687059c
LW
308 d = bufend;
309 while (s < d && isspace(*s)) s++;
378cc40b
LW
310 s[strlen(s)-1] = '\0'; /* wipe out newline */
311 if (*s == '"') {
312 s++;
313 s[strlen(s)-1] = '\0'; /* wipe out trailing quote */
314 }
315 if (*s)
395c3793 316 curcmd->c_filestab = fstab(s);
378cc40b 317 else
395c3793 318 curcmd->c_filestab = fstab(origfilename);
a687059c 319 oldoldbufptr = oldbufptr = s = str_get(linestr);
378cc40b 320 }
e929a76b
LW
321 /* FALL THROUGH */
322 case '\n':
a687059c
LW
323 if (in_eval && !rsfp) {
324 d = bufend;
325 while (s < d && *s != '\n')
378cc40b 326 s++;
0f85fab0 327 if (s < d)
378cc40b 328 s++;
395c3793
LW
329 if (perldb) {
330 STR *str = Str_new(85,0);
331
332 str_nset(str,linestr->str_ptr, s - linestr->str_ptr);
333 astore(stab_xarray(curcmd->c_filestab),(int)curcmd->c_line,str);
334 str_chop(linestr, s);
335 }
0f85fab0
LW
336 if (in_format) {
337 bufptr = s;
338 yylval.formval = load_format();
339 in_format = FALSE;
340 oldoldbufptr = oldbufptr = s = bufptr + 1;
341 TERM(FORMLIST);
a687059c 342 }
e929a76b 343 curcmd->c_line++;
378cc40b 344 }
a687059c 345 else {
378cc40b 346 *s = '\0';
a687059c
LW
347 bufend = s;
348 }
378cc40b
LW
349 goto retry;
350 case '-':
351 if (s[1] && isalpha(s[1]) && !isalpha(s[2])) {
352 s++;
353 switch (*s++) {
354 case 'r': FTST(O_FTEREAD);
355 case 'w': FTST(O_FTEWRITE);
356 case 'x': FTST(O_FTEEXEC);
357 case 'o': FTST(O_FTEOWNED);
358 case 'R': FTST(O_FTRREAD);
359 case 'W': FTST(O_FTRWRITE);
360 case 'X': FTST(O_FTREXEC);
361 case 'O': FTST(O_FTROWNED);
362 case 'e': FTST(O_FTIS);
363 case 'z': FTST(O_FTZERO);
364 case 's': FTST(O_FTSIZE);
365 case 'f': FTST(O_FTFILE);
366 case 'd': FTST(O_FTDIR);
367 case 'l': FTST(O_FTLINK);
368 case 'p': FTST(O_FTPIPE);
369 case 'S': FTST(O_FTSOCK);
370 case 'u': FTST(O_FTSUID);
371 case 'g': FTST(O_FTSGID);
372 case 'k': FTST(O_FTSVTX);
373 case 'b': FTST(O_FTBLK);
374 case 'c': FTST(O_FTCHR);
375 case 't': FTST(O_FTTTY);
376 case 'T': FTST(O_FTTEXT);
377 case 'B': FTST(O_FTBINARY);
395c3793
LW
378 case 'M': stabent("\024",TRUE); FTST(O_FTMTIME);
379 case 'A': stabent("\024",TRUE); FTST(O_FTATIME);
380 case 'C': stabent("\024",TRUE); FTST(O_FTCTIME);
378cc40b
LW
381 default:
382 s -= 2;
383 break;
384 }
385 }
a687059c
LW
386 tmp = *s++;
387 if (*s == tmp) {
388 s++;
389 RETURN(DEC);
390 }
391 if (expectterm)
392 OPERATOR('-');
393 else
394 AOP(O_SUBTRACT);
378cc40b 395 case '+':
a687059c
LW
396 tmp = *s++;
397 if (*s == tmp) {
378cc40b 398 s++;
a687059c 399 RETURN(INC);
378cc40b 400 }
a687059c
LW
401 if (expectterm)
402 OPERATOR('+');
403 else
404 AOP(O_ADD);
405
378cc40b 406 case '*':
a687059c 407 if (expectterm) {
fe14fcc3 408 s = scanident(s,bufend,tokenbuf);
a687059c
LW
409 yylval.stabval = stabent(tokenbuf,TRUE);
410 TERM(STAR);
411 }
412 tmp = *s++;
413 if (*s == tmp) {
414 s++;
415 OPERATOR(POW);
416 }
417 MOP(O_MULTIPLY);
378cc40b 418 case '%':
a687059c 419 if (expectterm) {
fe14fcc3 420 s = scanident(s,bufend,tokenbuf);
6eb13c3b 421 yylval.stabval = hadd(stabent(tokenbuf,TRUE));
a687059c
LW
422 TERM(HSH);
423 }
424 s++;
425 MOP(O_MODULO);
426
378cc40b
LW
427 case '^':
428 case '~':
429 case '(':
430 case ',':
431 case ':':
432 case '[':
433 tmp = *s++;
434 OPERATOR(tmp);
435 case '{':
436 tmp = *s++;
437 if (isspace(*s) || *s == '#')
438 cmdline = NOLINE; /* invalidate current command line number */
439 OPERATOR(tmp);
440 case ';':
e929a76b
LW
441 if (curcmd->c_line < cmdline)
442 cmdline = curcmd->c_line;
378cc40b
LW
443 tmp = *s++;
444 OPERATOR(tmp);
445 case ')':
446 case ']':
447 tmp = *s++;
448 TERM(tmp);
449 case '}':
450 tmp = *s++;
ffed7fef 451 RETURN(tmp);
378cc40b
LW
452 case '&':
453 s++;
454 tmp = *s++;
455 if (tmp == '&')
456 OPERATOR(ANDAND);
457 s--;
a687059c
LW
458 if (expectterm) {
459 d = bufend;
460 while (s < d && isspace(*s))
461 s++;
462 if (isalpha(*s) || *s == '_' || *s == '\'')
463 *(--s) = '\\'; /* force next ident to WORD */
464 OPERATOR(AMPER);
465 }
378cc40b
LW
466 OPERATOR('&');
467 case '|':
468 s++;
469 tmp = *s++;
470 if (tmp == '|')
471 OPERATOR(OROR);
472 s--;
473 OPERATOR('|');
474 case '=':
475 s++;
476 tmp = *s++;
477 if (tmp == '=')
a687059c 478 EOP(O_EQ);
378cc40b
LW
479 if (tmp == '~')
480 OPERATOR(MATCH);
481 s--;
482 OPERATOR('=');
483 case '!':
484 s++;
485 tmp = *s++;
486 if (tmp == '=')
a687059c 487 EOP(O_NE);
378cc40b
LW
488 if (tmp == '~')
489 OPERATOR(NMATCH);
490 s--;
491 OPERATOR('!');
492 case '<':
493 if (expectterm) {
494 s = scanstr(s);
495 TERM(RSTRING);
496 }
497 s++;
498 tmp = *s++;
499 if (tmp == '<')
500 OPERATOR(LS);
395c3793
LW
501 if (tmp == '=') {
502 tmp = *s++;
503 if (tmp == '>')
504 EOP(O_NCMP);
505 s--;
a687059c 506 ROP(O_LE);
395c3793 507 }
378cc40b 508 s--;
a687059c 509 ROP(O_LT);
378cc40b
LW
510 case '>':
511 s++;
512 tmp = *s++;
513 if (tmp == '>')
514 OPERATOR(RS);
515 if (tmp == '=')
a687059c 516 ROP(O_GE);
378cc40b 517 s--;
a687059c 518 ROP(O_GT);
378cc40b
LW
519
520#define SNARFWORD \
521 d = tokenbuf; \
a687059c
LW
522 while (isascii(*s) && \
523 (isalpha(*s) || isdigit(*s) || *s == '_' || *s == '\'')) \
378cc40b 524 *d++ = *s++; \
663a0e37 525 while (d[-1] == '\'') \
a687059c 526 d--,s--; \
378cc40b
LW
527 *d = '\0'; \
528 d = tokenbuf;
529
530 case '$':
531 if (s[1] == '#' && (isalpha(s[2]) || s[2] == '_')) {
532 s++;
fe14fcc3 533 s = scanident(s,bufend,tokenbuf);
378cc40b
LW
534 yylval.stabval = aadd(stabent(tokenbuf,TRUE));
535 TERM(ARYLEN);
536 }
a687059c 537 d = s;
fe14fcc3 538 s = scanident(s,bufend,tokenbuf);
a687059c
LW
539 if (reparse) { /* turn ${foo[bar]} into ($foo[bar]) */
540 do_reparse:
541 s[-1] = ')';
542 s = d;
543 s[1] = s[0];
544 s[0] = '(';
545 goto retry;
546 }
378cc40b
LW
547 yylval.stabval = stabent(tokenbuf,TRUE);
548 TERM(REG);
549
550 case '@':
a687059c 551 d = s;
fe14fcc3 552 s = scanident(s,bufend,tokenbuf);
a687059c
LW
553 if (reparse)
554 goto do_reparse;
e929a76b 555 yylval.stabval = aadd(stabent(tokenbuf,TRUE));
378cc40b
LW
556 TERM(ARY);
557
558 case '/': /* may either be division or pattern */
559 case '?': /* may either be conditional or pattern */
560 if (expectterm) {
561 s = scanpat(s);
562 TERM(PATTERN);
563 }
564 tmp = *s++;
a687059c
LW
565 if (tmp == '/')
566 MOP(O_DIVIDE);
378cc40b
LW
567 OPERATOR(tmp);
568
569 case '.':
570 if (!expectterm || !isdigit(s[1])) {
378cc40b 571 tmp = *s++;
a687059c
LW
572 if (*s == tmp) {
573 s++;
378cc40b 574 OPERATOR(DOTDOT);
a687059c
LW
575 }
576 AOP(O_CONCAT);
378cc40b
LW
577 }
578 /* FALL THROUGH */
579 case '0': case '1': case '2': case '3': case '4':
580 case '5': case '6': case '7': case '8': case '9':
581 case '\'': case '"': case '`':
582 s = scanstr(s);
583 TERM(RSTRING);
584
a687059c
LW
585 case '\\': /* some magic to force next word to be a WORD */
586 s++; /* used by do and sub to force a separate namespace */
587 /* FALL THROUGH */
378cc40b
LW
588 case '_':
589 SNARFWORD;
e929a76b
LW
590 if (d[1] == '_') {
591 if (strEQ(d,"__LINE__") || strEQ(d,"__FILE__")) {
592 ARG *arg = op_new(1);
593
594 yylval.arg = arg;
595 arg->arg_type = O_ITEM;
596 if (d[2] == 'L')
597 (void)sprintf(tokenbuf,"%ld",(long)curcmd->c_line);
598 else
395c3793 599 strcpy(tokenbuf, stab_val(curcmd->c_filestab)->str_ptr);
e929a76b
LW
600 arg[1].arg_type = A_SINGLE;
601 arg[1].arg_ptr.arg_str = str_make(tokenbuf,strlen(tokenbuf));
602 TERM(RSTRING);
603 }
395c3793
LW
604 else if (strEQ(d,"__END__")) {
605#ifndef TAINT
606 STAB *stab;
607 int fd;
608
609 if (stab = stabent("DATA",FALSE)) {
610 stab->str_pok |= SP_MULTI;
611 stab_io(stab) = stio_new();
612 stab_io(stab)->ifp = rsfp;
fe14fcc3 613#if defined(HAS_FCNTL) && defined(F_SETFD)
395c3793
LW
614 fd = fileno(rsfp);
615 fcntl(fd,F_SETFD,fd >= 3);
616#endif
617 if (preprocess)
618 stab_io(stab)->type = '|';
619 else if (rsfp == stdin)
620 stab_io(stab)->type = '-';
621 else
622 stab_io(stab)->type = '<';
623 rsfp = Nullfp;
624 }
625#endif
e929a76b 626 goto fake_eof;
395c3793 627 }
e929a76b 628 }
a687059c 629 break;
378cc40b
LW
630 case 'a': case 'A':
631 SNARFWORD;
34de22dd
LW
632 if (strEQ(d,"alarm"))
633 UNI(O_ALARM);
a687059c
LW
634 if (strEQ(d,"accept"))
635 FOP22(O_ACCEPT);
636 if (strEQ(d,"atan2"))
637 FUN2(O_ATAN2);
638 break;
378cc40b
LW
639 case 'b': case 'B':
640 SNARFWORD;
a687059c
LW
641 if (strEQ(d,"bind"))
642 FOP2(O_BIND);
0f85fab0
LW
643 if (strEQ(d,"binmode"))
644 FOP(O_BINMODE);
a687059c 645 break;
378cc40b
LW
646 case 'c': case 'C':
647 SNARFWORD;
a687059c
LW
648 if (strEQ(d,"chop"))
649 LFUN(O_CHOP);
378cc40b
LW
650 if (strEQ(d,"continue"))
651 OPERATOR(CONTINUE);
9f68db38
LW
652 if (strEQ(d,"chdir")) {
653 (void)stabent("ENV",TRUE); /* may use HOME */
378cc40b 654 UNI(O_CHDIR);
9f68db38 655 }
378cc40b 656 if (strEQ(d,"close"))
a687059c
LW
657 FOP(O_CLOSE);
658 if (strEQ(d,"closedir"))
659 FOP(O_CLOSEDIR);
395c3793
LW
660 if (strEQ(d,"cmp"))
661 EOP(O_SCMP);
662 if (strEQ(d,"caller"))
663 UNI(O_CALLER);
a687059c
LW
664 if (strEQ(d,"crypt")) {
665#ifdef FCRYPT
666 init_des();
667#endif
378cc40b 668 FUN2(O_CRYPT);
378cc40b 669 }
a687059c
LW
670 if (strEQ(d,"chmod"))
671 LOP(O_CHMOD);
672 if (strEQ(d,"chown"))
673 LOP(O_CHOWN);
674 if (strEQ(d,"connect"))
675 FOP2(O_CONNECT);
676 if (strEQ(d,"cos"))
677 UNI(O_COS);
678 if (strEQ(d,"chroot"))
679 UNI(O_CHROOT);
680 break;
378cc40b
LW
681 case 'd': case 'D':
682 SNARFWORD;
a687059c
LW
683 if (strEQ(d,"do")) {
684 d = bufend;
685 while (s < d && isspace(*s))
686 s++;
687 if (isalpha(*s) || *s == '_')
688 *(--s) = '\\'; /* force next ident to WORD */
378cc40b 689 OPERATOR(DO);
a687059c 690 }
378cc40b 691 if (strEQ(d,"die"))
a687059c
LW
692 LOP(O_DIE);
693 if (strEQ(d,"defined"))
694 LFUN(O_DEFINED);
378cc40b
LW
695 if (strEQ(d,"delete"))
696 OPERATOR(DELETE);
a687059c
LW
697 if (strEQ(d,"dbmopen"))
698 HFUN3(O_DBMOPEN);
699 if (strEQ(d,"dbmclose"))
700 HFUN(O_DBMCLOSE);
701 if (strEQ(d,"dump"))
702 LOOPX(O_DUMP);
703 break;
378cc40b
LW
704 case 'e': case 'E':
705 SNARFWORD;
706 if (strEQ(d,"else"))
707 OPERATOR(ELSE);
708 if (strEQ(d,"elsif")) {
e929a76b 709 yylval.ival = curcmd->c_line;
378cc40b
LW
710 OPERATOR(ELSIF);
711 }
712 if (strEQ(d,"eq") || strEQ(d,"EQ"))
a687059c 713 EOP(O_SEQ);
378cc40b
LW
714 if (strEQ(d,"exit"))
715 UNI(O_EXIT);
716 if (strEQ(d,"eval")) {
717 allstabs = TRUE; /* must initialize everything since */
718 UNI(O_EVAL); /* we don't know what will be used */
719 }
720 if (strEQ(d,"eof"))
a687059c 721 FOP(O_EOF);
378cc40b 722 if (strEQ(d,"exp"))
a687059c 723 UNI(O_EXP);
378cc40b 724 if (strEQ(d,"each"))
a687059c 725 HFUN(O_EACH);
378cc40b 726 if (strEQ(d,"exec")) {
a687059c 727 set_csh();
395c3793 728 LOP(O_EXEC_OP);
378cc40b 729 }
a687059c
LW
730 if (strEQ(d,"endhostent"))
731 FUN0(O_EHOSTENT);
732 if (strEQ(d,"endnetent"))
733 FUN0(O_ENETENT);
734 if (strEQ(d,"endservent"))
735 FUN0(O_ESERVENT);
736 if (strEQ(d,"endprotoent"))
737 FUN0(O_EPROTOENT);
738 if (strEQ(d,"endpwent"))
739 FUN0(O_EPWENT);
740 if (strEQ(d,"endgrent"))
741 FUN0(O_EGRENT);
742 break;
378cc40b
LW
743 case 'f': case 'F':
744 SNARFWORD;
9f68db38 745 if (strEQ(d,"for") || strEQ(d,"foreach")) {
e929a76b 746 yylval.ival = curcmd->c_line;
378cc40b 747 OPERATOR(FOR);
9f68db38 748 }
378cc40b 749 if (strEQ(d,"format")) {
a687059c
LW
750 d = bufend;
751 while (s < d && isspace(*s))
752 s++;
753 if (isalpha(*s) || *s == '_')
754 *(--s) = '\\'; /* force next ident to WORD */
378cc40b 755 in_format = TRUE;
a687059c
LW
756 allstabs = TRUE; /* must initialize everything since */
757 OPERATOR(FORMAT); /* we don't know what will be used */
378cc40b
LW
758 }
759 if (strEQ(d,"fork"))
760 FUN0(O_FORK);
a687059c
LW
761 if (strEQ(d,"fcntl"))
762 FOP3(O_FCNTL);
763 if (strEQ(d,"fileno"))
764 FOP(O_FILENO);
765 if (strEQ(d,"flock"))
766 FOP2(O_FLOCK);
767 break;
378cc40b
LW
768 case 'g': case 'G':
769 SNARFWORD;
770 if (strEQ(d,"gt") || strEQ(d,"GT"))
a687059c 771 ROP(O_SGT);
378cc40b 772 if (strEQ(d,"ge") || strEQ(d,"GE"))
a687059c
LW
773 ROP(O_SGE);
774 if (strEQ(d,"grep"))
775 FL2(O_GREP);
378cc40b
LW
776 if (strEQ(d,"goto"))
777 LOOPX(O_GOTO);
778 if (strEQ(d,"gmtime"))
a687059c
LW
779 UNI(O_GMTIME);
780 if (strEQ(d,"getc"))
781 FOP(O_GETC);
782 if (strnEQ(d,"get",3)) {
783 d += 3;
784 if (*d == 'p') {
785 if (strEQ(d,"ppid"))
786 FUN0(O_GETPPID);
787 if (strEQ(d,"pgrp"))
788 UNI(O_GETPGRP);
789 if (strEQ(d,"priority"))
790 FUN2(O_GETPRIORITY);
791 if (strEQ(d,"protobyname"))
792 UNI(O_GPBYNAME);
793 if (strEQ(d,"protobynumber"))
794 FUN1(O_GPBYNUMBER);
795 if (strEQ(d,"protoent"))
796 FUN0(O_GPROTOENT);
797 if (strEQ(d,"pwent"))
798 FUN0(O_GPWENT);
799 if (strEQ(d,"pwnam"))
800 FUN1(O_GPWNAM);
801 if (strEQ(d,"pwuid"))
802 FUN1(O_GPWUID);
803 if (strEQ(d,"peername"))
804 FOP(O_GETPEERNAME);
805 }
806 else if (*d == 'h') {
807 if (strEQ(d,"hostbyname"))
808 UNI(O_GHBYNAME);
809 if (strEQ(d,"hostbyaddr"))
810 FUN2(O_GHBYADDR);
811 if (strEQ(d,"hostent"))
812 FUN0(O_GHOSTENT);
813 }
814 else if (*d == 'n') {
815 if (strEQ(d,"netbyname"))
816 UNI(O_GNBYNAME);
817 if (strEQ(d,"netbyaddr"))
818 FUN2(O_GNBYADDR);
819 if (strEQ(d,"netent"))
820 FUN0(O_GNETENT);
821 }
822 else if (*d == 's') {
823 if (strEQ(d,"servbyname"))
824 FUN2(O_GSBYNAME);
825 if (strEQ(d,"servbyport"))
826 FUN2(O_GSBYPORT);
827 if (strEQ(d,"servent"))
828 FUN0(O_GSERVENT);
829 if (strEQ(d,"sockname"))
830 FOP(O_GETSOCKNAME);
831 if (strEQ(d,"sockopt"))
832 FOP3(O_GSOCKOPT);
833 }
834 else if (*d == 'g') {
835 if (strEQ(d,"grent"))
836 FUN0(O_GGRENT);
837 if (strEQ(d,"grnam"))
838 FUN1(O_GGRNAM);
839 if (strEQ(d,"grgid"))
840 FUN1(O_GGRGID);
841 }
842 else if (*d == 'l') {
843 if (strEQ(d,"login"))
844 FUN0(O_GETLOGIN);
845 }
846 d -= 3;
847 }
848 break;
378cc40b
LW
849 case 'h': case 'H':
850 SNARFWORD;
851 if (strEQ(d,"hex"))
a687059c
LW
852 UNI(O_HEX);
853 break;
378cc40b
LW
854 case 'i': case 'I':
855 SNARFWORD;
856 if (strEQ(d,"if")) {
e929a76b 857 yylval.ival = curcmd->c_line;
378cc40b
LW
858 OPERATOR(IF);
859 }
860 if (strEQ(d,"index"))
395c3793 861 FUN2x(O_INDEX);
378cc40b 862 if (strEQ(d,"int"))
a687059c
LW
863 UNI(O_INT);
864 if (strEQ(d,"ioctl"))
865 FOP3(O_IOCTL);
866 break;
378cc40b
LW
867 case 'j': case 'J':
868 SNARFWORD;
869 if (strEQ(d,"join"))
a687059c
LW
870 FL2(O_JOIN);
871 break;
378cc40b
LW
872 case 'k': case 'K':
873 SNARFWORD;
874 if (strEQ(d,"keys"))
a687059c
LW
875 HFUN(O_KEYS);
876 if (strEQ(d,"kill"))
877 LOP(O_KILL);
878 break;
378cc40b
LW
879 case 'l': case 'L':
880 SNARFWORD;
881 if (strEQ(d,"last"))
882 LOOPX(O_LAST);
883 if (strEQ(d,"local"))
884 OPERATOR(LOCAL);
885 if (strEQ(d,"length"))
a687059c 886 UNI(O_LENGTH);
378cc40b 887 if (strEQ(d,"lt") || strEQ(d,"LT"))
a687059c 888 ROP(O_SLT);
378cc40b 889 if (strEQ(d,"le") || strEQ(d,"LE"))
a687059c 890 ROP(O_SLE);
378cc40b 891 if (strEQ(d,"localtime"))
a687059c 892 UNI(O_LOCALTIME);
378cc40b 893 if (strEQ(d,"log"))
a687059c 894 UNI(O_LOG);
378cc40b
LW
895 if (strEQ(d,"link"))
896 FUN2(O_LINK);
a687059c
LW
897 if (strEQ(d,"listen"))
898 FOP2(O_LISTEN);
899 if (strEQ(d,"lstat"))
900 FOP(O_LSTAT);
901 break;
378cc40b 902 case 'm': case 'M':
663a0e37
LW
903 if (s[1] == '\'') {
904 d = "m";
905 s++;
906 }
907 else {
908 SNARFWORD;
909 }
378cc40b
LW
910 if (strEQ(d,"m")) {
911 s = scanpat(s-1);
a687059c
LW
912 if (yylval.arg)
913 TERM(PATTERN);
914 else
915 RETURN(1); /* force error */
378cc40b 916 }
395c3793
LW
917 switch (d[1]) {
918 case 'k':
919 if (strEQ(d,"mkdir"))
920 FUN2(O_MKDIR);
921 break;
922 case 's':
923 if (strEQ(d,"msgctl"))
924 FUN3(O_MSGCTL);
925 if (strEQ(d,"msgget"))
926 FUN2(O_MSGGET);
927 if (strEQ(d,"msgrcv"))
928 FUN5(O_MSGRCV);
929 if (strEQ(d,"msgsnd"))
930 FUN3(O_MSGSND);
931 break;
932 }
a687059c 933 break;
378cc40b
LW
934 case 'n': case 'N':
935 SNARFWORD;
936 if (strEQ(d,"next"))
937 LOOPX(O_NEXT);
938 if (strEQ(d,"ne") || strEQ(d,"NE"))
a687059c
LW
939 EOP(O_SNE);
940 break;
378cc40b
LW
941 case 'o': case 'O':
942 SNARFWORD;
943 if (strEQ(d,"open"))
944 OPERATOR(OPEN);
945 if (strEQ(d,"ord"))
a687059c 946 UNI(O_ORD);
378cc40b 947 if (strEQ(d,"oct"))
a687059c
LW
948 UNI(O_OCT);
949 if (strEQ(d,"opendir"))
950 FOP2(O_OPENDIR);
951 break;
378cc40b
LW
952 case 'p': case 'P':
953 SNARFWORD;
954 if (strEQ(d,"print")) {
a687059c
LW
955 checkcomma(s,"filehandle");
956 LOP(O_PRINT);
378cc40b
LW
957 }
958 if (strEQ(d,"printf")) {
a687059c
LW
959 checkcomma(s,"filehandle");
960 LOP(O_PRTF);
378cc40b
LW
961 }
962 if (strEQ(d,"push")) {
963 yylval.ival = O_PUSH;
964 OPERATOR(PUSH);
965 }
966 if (strEQ(d,"pop"))
967 OPERATOR(POP);
a687059c
LW
968 if (strEQ(d,"pack"))
969 FL2(O_PACK);
970 if (strEQ(d,"package"))
971 OPERATOR(PACKAGE);
9f68db38
LW
972 if (strEQ(d,"pipe"))
973 FOP22(O_PIPE);
a687059c 974 break;
378cc40b
LW
975 case 'q': case 'Q':
976 SNARFWORD;
a687059c
LW
977 if (strEQ(d,"q")) {
978 s = scanstr(s-1);
979 TERM(RSTRING);
980 }
981 if (strEQ(d,"qq")) {
982 s = scanstr(s-2);
983 TERM(RSTRING);
984 }
fe14fcc3
LW
985 if (strEQ(d,"qx")) {
986 s = scanstr(s-2);
987 TERM(RSTRING);
988 }
a687059c 989 break;
378cc40b
LW
990 case 'r': case 'R':
991 SNARFWORD;
a687059c 992 if (strEQ(d,"return"))
9f68db38 993 OLDLOP(O_RETURN);
e929a76b
LW
994 if (strEQ(d,"require")) {
995 allstabs = TRUE; /* must initialize everything since */
996 UNI(O_REQUIRE); /* we don't know what will be used */
997 }
378cc40b
LW
998 if (strEQ(d,"reset"))
999 UNI(O_RESET);
1000 if (strEQ(d,"redo"))
1001 LOOPX(O_REDO);
1002 if (strEQ(d,"rename"))
1003 FUN2(O_RENAME);
a687059c
LW
1004 if (strEQ(d,"rand"))
1005 UNI(O_RAND);
1006 if (strEQ(d,"rmdir"))
1007 UNI(O_RMDIR);
1008 if (strEQ(d,"rindex"))
395c3793 1009 FUN2x(O_RINDEX);
a687059c
LW
1010 if (strEQ(d,"read"))
1011 FOP3(O_READ);
1012 if (strEQ(d,"readdir"))
1013 FOP(O_READDIR);
1014 if (strEQ(d,"rewinddir"))
1015 FOP(O_REWINDDIR);
1016 if (strEQ(d,"recv"))
1017 FOP4(O_RECV);
1018 if (strEQ(d,"reverse"))
1019 LOP(O_REVERSE);
1020 if (strEQ(d,"readlink"))
1021 UNI(O_READLINK);
1022 break;
378cc40b 1023 case 's': case 'S':
663a0e37
LW
1024 if (s[1] == '\'') {
1025 d = "s";
1026 s++;
1027 }
1028 else {
1029 SNARFWORD;
1030 }
378cc40b
LW
1031 if (strEQ(d,"s")) {
1032 s = scansubst(s);
a687059c
LW
1033 if (yylval.arg)
1034 TERM(SUBST);
1035 else
1036 RETURN(1); /* force error */
1037 }
1038 switch (d[1]) {
1039 case 'a':
1040 case 'b':
395c3793 1041 break;
a687059c 1042 case 'c':
395c3793
LW
1043 if (strEQ(d,"scalar"))
1044 UNI(O_SCALAR);
1045 break;
a687059c
LW
1046 case 'd':
1047 break;
1048 case 'e':
1049 if (strEQ(d,"select"))
e929a76b 1050 OPERATOR(SSELECT);
a687059c
LW
1051 if (strEQ(d,"seek"))
1052 FOP3(O_SEEK);
395c3793
LW
1053 if (strEQ(d,"semctl"))
1054 FUN4(O_SEMCTL);
1055 if (strEQ(d,"semget"))
1056 FUN3(O_SEMGET);
1057 if (strEQ(d,"semop"))
1058 FUN2(O_SEMOP);
a687059c
LW
1059 if (strEQ(d,"send"))
1060 FOP3(O_SEND);
1061 if (strEQ(d,"setpgrp"))
1062 FUN2(O_SETPGRP);
1063 if (strEQ(d,"setpriority"))
1064 FUN3(O_SETPRIORITY);
1065 if (strEQ(d,"sethostent"))
1066 FUN1(O_SHOSTENT);
1067 if (strEQ(d,"setnetent"))
1068 FUN1(O_SNETENT);
1069 if (strEQ(d,"setservent"))
1070 FUN1(O_SSERVENT);
1071 if (strEQ(d,"setprotoent"))
1072 FUN1(O_SPROTOENT);
1073 if (strEQ(d,"setpwent"))
1074 FUN0(O_SPWENT);
1075 if (strEQ(d,"setgrent"))
1076 FUN0(O_SGRENT);
1077 if (strEQ(d,"seekdir"))
1078 FOP2(O_SEEKDIR);
1079 if (strEQ(d,"setsockopt"))
1080 FOP4(O_SSOCKOPT);
1081 break;
1082 case 'f':
1083 case 'g':
1084 break;
1085 case 'h':
1086 if (strEQ(d,"shift"))
1087 TERM(SHIFT);
395c3793
LW
1088 if (strEQ(d,"shmctl"))
1089 FUN3(O_SHMCTL);
1090 if (strEQ(d,"shmget"))
1091 FUN3(O_SHMGET);
1092 if (strEQ(d,"shmread"))
1093 FUN4(O_SHMREAD);
1094 if (strEQ(d,"shmwrite"))
1095 FUN4(O_SHMWRITE);
a687059c
LW
1096 if (strEQ(d,"shutdown"))
1097 FOP2(O_SHUTDOWN);
1098 break;
1099 case 'i':
1100 if (strEQ(d,"sin"))
1101 UNI(O_SIN);
1102 break;
1103 case 'j':
1104 case 'k':
1105 break;
1106 case 'l':
1107 if (strEQ(d,"sleep"))
1108 UNI(O_SLEEP);
1109 break;
1110 case 'm':
1111 case 'n':
1112 break;
1113 case 'o':
1114 if (strEQ(d,"socket"))
1115 FOP4(O_SOCKET);
1116 if (strEQ(d,"socketpair"))
e929a76b 1117 FOP25(O_SOCKPAIR);
a687059c
LW
1118 if (strEQ(d,"sort")) {
1119 checkcomma(s,"subroutine name");
1120 d = bufend;
1121 while (s < d && isascii(*s) && isspace(*s)) s++;
1122 if (*s == ';' || *s == ')') /* probably a close */
1123 fatal("sort is now a reserved word");
1124 if (isascii(*s) && (isalpha(*s) || *s == '_')) {
1125 for (d = s; isalpha(*d) || isdigit(*d) || *d == '_'; d++) ;
03a14243
LW
1126 strncpy(tokenbuf,s,d-s);
1127 if (strNE(tokenbuf,"keys") &&
1128 strNE(tokenbuf,"values") &&
1129 strNE(tokenbuf,"split") &&
1130 strNE(tokenbuf,"grep") &&
1131 strNE(tokenbuf,"readdir") &&
1132 strNE(tokenbuf,"unpack") &&
1133 strNE(tokenbuf,"do") &&
1134 (d >= bufend || isspace(*d)) )
a687059c
LW
1135 *(--s) = '\\'; /* force next ident to WORD */
1136 }
1137 LOP(O_SORT);
1138 }
1139 break;
1140 case 'p':
1141 if (strEQ(d,"split"))
1142 TERM(SPLIT);
1143 if (strEQ(d,"sprintf"))
1144 FL(O_SPRINTF);
79a0689e
LW
1145 if (strEQ(d,"splice")) {
1146 yylval.ival = O_SPLICE;
1147 OPERATOR(PUSH);
1148 }
a687059c
LW
1149 break;
1150 case 'q':
1151 if (strEQ(d,"sqrt"))
1152 UNI(O_SQRT);
1153 break;
1154 case 'r':
1155 if (strEQ(d,"srand"))
1156 UNI(O_SRAND);
1157 break;
1158 case 's':
1159 break;
1160 case 't':
1161 if (strEQ(d,"stat"))
1162 FOP(O_STAT);
1163 if (strEQ(d,"study")) {
1164 sawstudy++;
1165 LFUN(O_STUDY);
1166 }
1167 break;
1168 case 'u':
1169 if (strEQ(d,"substr"))
395c3793 1170 FUN2x(O_SUBSTR);
a687059c 1171 if (strEQ(d,"sub")) {
e929a76b 1172 subline = curcmd->c_line;
a687059c
LW
1173 d = bufend;
1174 while (s < d && isspace(*s))
1175 s++;
1176 if (isalpha(*s) || *s == '_' || *s == '\'') {
1177 if (perldb) {
1178 str_sset(subname,curstname);
1179 str_ncat(subname,"'",1);
1180 for (d = s+1;
1181 isalpha(*d) || isdigit(*d) || *d == '_' || *d == '\'';
1182 d++);
1183 if (d[-1] == '\'')
1184 d--;
1185 str_ncat(subname,s,d-s);
1186 }
1187 *(--s) = '\\'; /* force next ident to WORD */
1188 }
1189 else if (perldb)
1190 str_set(subname,"?");
1191 OPERATOR(SUB);
1192 }
1193 break;
1194 case 'v':
1195 case 'w':
1196 case 'x':
1197 break;
1198 case 'y':
1199 if (strEQ(d,"system")) {
1200 set_csh();
1201 LOP(O_SYSTEM);
1202 }
1203 if (strEQ(d,"symlink"))
1204 FUN2(O_SYMLINK);
1205 if (strEQ(d,"syscall"))
1206 LOP(O_SYSCALL);
395c3793
LW
1207 if (strEQ(d,"sysread"))
1208 FOP3(O_SYSREAD);
1209 if (strEQ(d,"syswrite"))
1210 FOP3(O_SYSWRITE);
a687059c
LW
1211 break;
1212 case 'z':
1213 break;
1214 }
1215 break;
378cc40b
LW
1216 case 't': case 'T':
1217 SNARFWORD;
1218 if (strEQ(d,"tr")) {
1219 s = scantrans(s);
a687059c
LW
1220 if (yylval.arg)
1221 TERM(TRANS);
1222 else
1223 RETURN(1); /* force error */
378cc40b
LW
1224 }
1225 if (strEQ(d,"tell"))
a687059c
LW
1226 FOP(O_TELL);
1227 if (strEQ(d,"telldir"))
1228 FOP(O_TELLDIR);
378cc40b
LW
1229 if (strEQ(d,"time"))
1230 FUN0(O_TIME);
1231 if (strEQ(d,"times"))
1232 FUN0(O_TMS);
e929a76b
LW
1233 if (strEQ(d,"truncate"))
1234 FOP2(O_TRUNCATE);
a687059c 1235 break;
378cc40b
LW
1236 case 'u': case 'U':
1237 SNARFWORD;
1238 if (strEQ(d,"using"))
1239 OPERATOR(USING);
1240 if (strEQ(d,"until")) {
e929a76b 1241 yylval.ival = curcmd->c_line;
378cc40b
LW
1242 OPERATOR(UNTIL);
1243 }
1244 if (strEQ(d,"unless")) {
e929a76b 1245 yylval.ival = curcmd->c_line;
378cc40b
LW
1246 OPERATOR(UNLESS);
1247 }
a687059c
LW
1248 if (strEQ(d,"unlink"))
1249 LOP(O_UNLINK);
1250 if (strEQ(d,"undef"))
1251 LFUN(O_UNDEF);
1252 if (strEQ(d,"unpack"))
1253 FUN2(O_UNPACK);
1254 if (strEQ(d,"utime"))
1255 LOP(O_UTIME);
378cc40b 1256 if (strEQ(d,"umask"))
a687059c 1257 UNI(O_UMASK);
378cc40b
LW
1258 if (strEQ(d,"unshift")) {
1259 yylval.ival = O_UNSHIFT;
1260 OPERATOR(PUSH);
1261 }
a687059c 1262 break;
378cc40b
LW
1263 case 'v': case 'V':
1264 SNARFWORD;
1265 if (strEQ(d,"values"))
a687059c
LW
1266 HFUN(O_VALUES);
1267 if (strEQ(d,"vec")) {
1268 sawvec = TRUE;
1269 FUN3(O_VEC);
1270 }
1271 break;
378cc40b
LW
1272 case 'w': case 'W':
1273 SNARFWORD;
378cc40b 1274 if (strEQ(d,"while")) {
e929a76b 1275 yylval.ival = curcmd->c_line;
378cc40b
LW
1276 OPERATOR(WHILE);
1277 }
a687059c
LW
1278 if (strEQ(d,"warn"))
1279 LOP(O_WARN);
378cc40b
LW
1280 if (strEQ(d,"wait"))
1281 FUN0(O_WAIT);
395c3793
LW
1282 if (strEQ(d,"waitpid"))
1283 FUN2(O_WAITPID);
a687059c
LW
1284 if (strEQ(d,"wantarray")) {
1285 yylval.arg = op_new(1);
1286 yylval.arg->arg_type = O_ITEM;
1287 yylval.arg[1].arg_type = A_WANTARRAY;
1288 TERM(RSTRING);
1289 }
1290 if (strEQ(d,"write"))
1291 FOP(O_WRITE);
1292 break;
378cc40b
LW
1293 case 'x': case 'X':
1294 SNARFWORD;
1295 if (!expectterm && strEQ(d,"x"))
a687059c
LW
1296 MOP(O_REPEAT);
1297 break;
378cc40b 1298 case 'y': case 'Y':
663a0e37
LW
1299 if (s[1] == '\'') {
1300 d = "y";
1301 s++;
1302 }
1303 else {
1304 SNARFWORD;
1305 }
378cc40b
LW
1306 if (strEQ(d,"y")) {
1307 s = scantrans(s);
1308 TERM(TRANS);
1309 }
a687059c 1310 break;
378cc40b
LW
1311 case 'z': case 'Z':
1312 SNARFWORD;
a687059c
LW
1313 break;
1314 }
1315 yylval.cval = savestr(d);
1316 expectterm = FALSE;
1317 if (oldoldbufptr && oldoldbufptr < bufptr) {
1318 while (isspace(*oldoldbufptr))
1319 oldoldbufptr++;
1320 if (*oldoldbufptr == 'p' && strnEQ(oldoldbufptr,"print",5))
1321 expectterm = TRUE;
1322 else if (*oldoldbufptr == 's' && strnEQ(oldoldbufptr,"sort",4))
1323 expectterm = TRUE;
1324 }
1325 return (CLINE, bufptr = s, (int)WORD);
1326}
1327
fe14fcc3 1328void
a687059c
LW
1329checkcomma(s,what)
1330register char *s;
1331char *what;
1332{
fe14fcc3 1333 char *someword;
e929a76b 1334
a687059c
LW
1335 if (*s == '(')
1336 s++;
1337 while (s < bufend && isascii(*s) && isspace(*s))
1338 s++;
1339 if (isascii(*s) && (isalpha(*s) || *s == '_')) {
fe14fcc3 1340 someword = s++;
a687059c
LW
1341 while (isalpha(*s) || isdigit(*s) || *s == '_')
1342 s++;
1343 while (s < bufend && isspace(*s))
1344 s++;
e929a76b
LW
1345 if (*s == ',') {
1346 *s = '\0';
fe14fcc3 1347 someword = instr(
e929a76b
LW
1348 "tell eof times getlogin wait length shift umask getppid \
1349 cos exp int log rand sin sqrt ord wantarray",
fe14fcc3 1350 someword);
e929a76b 1351 *s = ',';
fe14fcc3 1352 if (someword)
e929a76b 1353 return;
a687059c 1354 fatal("No comma allowed after %s", what);
e929a76b 1355 }
378cc40b
LW
1356 }
1357}
1358
1359char *
fe14fcc3 1360scanident(s,send,dest)
378cc40b 1361register char *s;
a687059c 1362register char *send;
378cc40b
LW
1363char *dest;
1364{
1365 register char *d;
a687059c 1366 int brackets = 0;
378cc40b 1367
a687059c 1368 reparse = Nullch;
378cc40b
LW
1369 s++;
1370 d = dest;
1371 if (isdigit(*s)) {
a687059c 1372 while (isdigit(*s))
378cc40b
LW
1373 *d++ = *s++;
1374 }
1375 else {
a687059c 1376 while (isalpha(*s) || isdigit(*s) || *s == '_' || *s == '\'')
378cc40b
LW
1377 *d++ = *s++;
1378 }
663a0e37 1379 while (d > dest+1 && d[-1] == '\'')
a687059c 1380 d--,s--;
378cc40b
LW
1381 *d = '\0';
1382 d = dest;
1383 if (!*d) {
1384 *d = *s++;
a687059c 1385 if (*d == '{' /* } */ ) {
378cc40b 1386 d = dest;
a687059c
LW
1387 brackets++;
1388 while (s < send && brackets) {
1389 if (!reparse && (d == dest || (*s && isascii(*s) &&
1390 (isalpha(*s) || isdigit(*s) || *s == '_') ))) {
1391 *d++ = *s++;
1392 continue;
1393 }
1394 else if (!reparse)
1395 reparse = s;
1396 switch (*s++) {
1397 /* { */
1398 case '}':
1399 brackets--;
1400 if (reparse && reparse == s - 1)
1401 reparse = Nullch;
1402 break;
1403 case '{': /* } */
1404 brackets++;
1405 break;
1406 }
1407 }
378cc40b
LW
1408 *d = '\0';
1409 d = dest;
378cc40b
LW
1410 }
1411 else
1412 d[1] = '\0';
1413 }
fe14fcc3
LW
1414 if (*d == '^' && (isupper(*s) || index("[\\]^_?",*s)))
1415 *d = *s++ ^ 64;
378cc40b
LW
1416 return s;
1417}
1418
1419STR *
a687059c 1420scanconst(string,len)
378cc40b 1421char *string;
a687059c 1422int len;
378cc40b
LW
1423{
1424 register STR *retstr;
1425 register char *t;
1426 register char *d;
a687059c 1427 register char *e;
378cc40b
LW
1428
1429 if (index(string,'|')) {
1430 return Nullstr;
1431 }
a687059c
LW
1432 retstr = Str_new(86,len);
1433 str_nset(retstr,string,len);
378cc40b 1434 t = str_get(retstr);
a687059c
LW
1435 e = t + len;
1436 retstr->str_u.str_useful = 100;
1437 for (d=t; d < e; ) {
378cc40b 1438 switch (*d) {
a687059c
LW
1439 case '{':
1440 if (isdigit(d[1]))
1441 e = d;
1442 else
1443 goto defchar;
1444 break;
1445 case '.': case '[': case '$': case '(': case ')': case '|': case '+':
1446 e = d;
378cc40b
LW
1447 break;
1448 case '\\':
fe14fcc3 1449 if (d[1] && index("wWbB0123456789sSdDlLuUE",d[1])) {
a687059c 1450 e = d;
378cc40b
LW
1451 break;
1452 }
a687059c
LW
1453 (void)bcopy(d+1,d,e-d);
1454 e--;
378cc40b
LW
1455 switch(*d) {
1456 case 'n':
1457 *d = '\n';
1458 break;
1459 case 't':
1460 *d = '\t';
1461 break;
1462 case 'f':
1463 *d = '\f';
1464 break;
1465 case 'r':
1466 *d = '\r';
1467 break;
fe14fcc3
LW
1468 case 'e':
1469 *d = '\033';
1470 break;
1471 case 'a':
1472 *d = '\007';
1473 break;
378cc40b
LW
1474 }
1475 /* FALL THROUGH */
1476 default:
a687059c
LW
1477 defchar:
1478 if (d[1] == '*' || (d[1] == '{' && d[2] == '0') || d[1] == '?') {
1479 e = d;
378cc40b
LW
1480 break;
1481 }
1482 d++;
1483 }
1484 }
a687059c 1485 if (d == t) {
378cc40b
LW
1486 str_free(retstr);
1487 return Nullstr;
1488 }
a687059c
LW
1489 *d = '\0';
1490 retstr->str_cur = d - t;
378cc40b
LW
1491 return retstr;
1492}
1493
1494char *
1495scanpat(s)
1496register char *s;
1497{
a687059c 1498 register SPAT *spat;
378cc40b 1499 register char *d;
a687059c
LW
1500 register char *e;
1501 int len;
1502 SPAT savespat;
395c3793 1503 STR *str = Str_new(93,0);
378cc40b 1504
a687059c
LW
1505 Newz(801,spat,1,SPAT);
1506 spat->spat_next = curstash->tbl_spatroot; /* link into spat list */
1507 curstash->tbl_spatroot = spat;
378cc40b
LW
1508
1509 switch (*s++) {
1510 case 'm':
1511 s++;
1512 break;
1513 case '/':
1514 break;
1515 case '?':
1516 spat->spat_flags |= SPAT_ONCE;
1517 break;
1518 default:
1519 fatal("panic: scanpat");
1520 }
395c3793 1521 s = str_append_till(str,s,bufend,s[-1],patleave);
a687059c 1522 if (s >= bufend) {
395c3793 1523 str_free(str);
a687059c
LW
1524 yyerror("Search pattern not terminated");
1525 yylval.arg = Nullarg;
1526 return s;
1527 }
378cc40b 1528 s++;
a687059c
LW
1529 while (*s == 'i' || *s == 'o') {
1530 if (*s == 'i') {
1531 s++;
1532 sawi = TRUE;
1533 spat->spat_flags |= SPAT_FOLD;
1534 }
1535 if (*s == 'o') {
1536 s++;
1537 spat->spat_flags |= SPAT_KEEP;
1538 }
378cc40b 1539 }
395c3793
LW
1540 len = str->str_cur;
1541 e = str->str_ptr + len;
1542 for (d = str->str_ptr; d < e; d++) {
e929a76b
LW
1543 if (*d == '\\')
1544 d++;
1545 else if ((*d == '$' && d[1] && d[1] != '|' && d[1] != ')') ||
1546 (*d == '@')) {
378cc40b
LW
1547 register ARG *arg;
1548
1549 spat->spat_runtime = arg = op_new(1);
1550 arg->arg_type = O_ITEM;
1551 arg[1].arg_type = A_DOUBLE;
395c3793 1552 arg[1].arg_ptr.arg_str = str_smake(str);
fe14fcc3 1553 d = scanident(d,bufend,buf);
a687059c
LW
1554 (void)stabent(buf,TRUE); /* make sure it's created */
1555 for (; d < e; d++) {
e929a76b
LW
1556 if (*d == '\\')
1557 d++;
1558 else if (*d == '$' && d[1] && d[1] != '|' && d[1] != ')') {
fe14fcc3 1559 d = scanident(d,bufend,buf);
a687059c
LW
1560 (void)stabent(buf,TRUE);
1561 }
e929a76b 1562 else if (*d == '@') {
fe14fcc3 1563 d = scanident(d,bufend,buf);
a687059c
LW
1564 if (strEQ(buf,"ARGV") || strEQ(buf,"ENV") ||
1565 strEQ(buf,"SIG") || strEQ(buf,"INC"))
1566 (void)stabent(buf,TRUE);
1567 }
1568 }
378cc40b
LW
1569 goto got_pat; /* skip compiling for now */
1570 }
1571 }
a687059c
LW
1572 if (spat->spat_flags & SPAT_FOLD)
1573#ifdef STRUCTCOPY
1574 savespat = *spat;
1575#else
1576 (void)bcopy((char *)spat, (char *)&savespat, sizeof(SPAT));
1577#endif
395c3793
LW
1578 if (*str->str_ptr == '^') {
1579 spat->spat_short = scanconst(str->str_ptr+1,len-1);
a687059c
LW
1580 if (spat->spat_short) {
1581 spat->spat_slen = spat->spat_short->str_cur;
1582 if (spat->spat_slen == len - 1)
1583 spat->spat_flags |= SPAT_ALL;
378cc40b 1584 }
378cc40b 1585 }
a687059c
LW
1586 else {
1587 spat->spat_flags |= SPAT_SCANFIRST;
395c3793 1588 spat->spat_short = scanconst(str->str_ptr,len);
a687059c
LW
1589 if (spat->spat_short) {
1590 spat->spat_slen = spat->spat_short->str_cur;
1591 if (spat->spat_slen == len)
1592 spat->spat_flags |= SPAT_ALL;
1593 }
1594 }
1595 if ((spat->spat_flags & SPAT_ALL) && (spat->spat_flags & SPAT_SCANFIRST)) {
1596 fbmcompile(spat->spat_short, spat->spat_flags & SPAT_FOLD);
395c3793 1597 spat->spat_regexp = regcomp(str->str_ptr,str->str_ptr+len,
e929a76b 1598 spat->spat_flags & SPAT_FOLD);
a687059c
LW
1599 /* Note that this regexp can still be used if someone says
1600 * something like /a/ && s//b/; so we can't delete it.
1601 */
1602 }
1603 else {
1604 if (spat->spat_flags & SPAT_FOLD)
1605#ifdef STRUCTCOPY
1606 *spat = savespat;
1607#else
1608 (void)bcopy((char *)&savespat, (char *)spat, sizeof(SPAT));
1609#endif
1610 if (spat->spat_short)
1611 fbmcompile(spat->spat_short, spat->spat_flags & SPAT_FOLD);
395c3793 1612 spat->spat_regexp = regcomp(str->str_ptr,str->str_ptr+len,
fe14fcc3 1613 spat->spat_flags & SPAT_FOLD);
a687059c
LW
1614 hoistmust(spat);
1615 }
378cc40b 1616 got_pat:
395c3793 1617 str_free(str);
378cc40b
LW
1618 yylval.arg = make_match(O_MATCH,stab2arg(A_STAB,defstab),spat);
1619 return s;
1620}
1621
1622char *
1623scansubst(s)
1624register char *s;
1625{
a687059c 1626 register SPAT *spat;
378cc40b 1627 register char *d;
a687059c
LW
1628 register char *e;
1629 int len;
395c3793 1630 STR *str = Str_new(93,0);
378cc40b 1631
a687059c
LW
1632 Newz(802,spat,1,SPAT);
1633 spat->spat_next = curstash->tbl_spatroot; /* link into spat list */
1634 curstash->tbl_spatroot = spat;
378cc40b 1635
395c3793 1636 s = str_append_till(str,s+1,bufend,*s,patleave);
a687059c 1637 if (s >= bufend) {
395c3793 1638 str_free(str);
a687059c
LW
1639 yyerror("Substitution pattern not terminated");
1640 yylval.arg = Nullarg;
1641 return s;
1642 }
395c3793
LW
1643 len = str->str_cur;
1644 e = str->str_ptr + len;
1645 for (d = str->str_ptr; d < e; d++) {
1646 if (*d == '\\')
1647 d++;
1648 else if ((*d == '$' && d[1] && d[1] != '|' && /*(*/ d[1] != ')') ||
1649 *d == '@' ) {
378cc40b
LW
1650 register ARG *arg;
1651
1652 spat->spat_runtime = arg = op_new(1);
1653 arg->arg_type = O_ITEM;
1654 arg[1].arg_type = A_DOUBLE;
395c3793 1655 arg[1].arg_ptr.arg_str = str_smake(str);
fe14fcc3 1656 d = scanident(d,bufend,buf);
a687059c
LW
1657 (void)stabent(buf,TRUE); /* make sure it's created */
1658 for (; *d; d++) {
1659 if (*d == '$' && d[1] && d[-1] != '\\' && d[1] != '|') {
fe14fcc3 1660 d = scanident(d,bufend,buf);
a687059c
LW
1661 (void)stabent(buf,TRUE);
1662 }
1663 else if (*d == '@' && d[-1] != '\\') {
fe14fcc3 1664 d = scanident(d,bufend,buf);
a687059c
LW
1665 if (strEQ(buf,"ARGV") || strEQ(buf,"ENV") ||
1666 strEQ(buf,"SIG") || strEQ(buf,"INC"))
1667 (void)stabent(buf,TRUE);
1668 }
1669 }
378cc40b
LW
1670 goto get_repl; /* skip compiling for now */
1671 }
1672 }
395c3793
LW
1673 if (*str->str_ptr == '^') {
1674 spat->spat_short = scanconst(str->str_ptr+1,len-1);
378cc40b 1675 if (spat->spat_short)
a687059c 1676 spat->spat_slen = spat->spat_short->str_cur;
378cc40b
LW
1677 }
1678 else {
1679 spat->spat_flags |= SPAT_SCANFIRST;
395c3793 1680 spat->spat_short = scanconst(str->str_ptr,len);
378cc40b 1681 if (spat->spat_short)
a687059c
LW
1682 spat->spat_slen = spat->spat_short->str_cur;
1683 }
378cc40b
LW
1684get_repl:
1685 s = scanstr(s);
a687059c 1686 if (s >= bufend) {
395c3793 1687 str_free(str);
a687059c
LW
1688 yyerror("Substitution replacement not terminated");
1689 yylval.arg = Nullarg;
1690 return s;
1691 }
378cc40b
LW
1692 spat->spat_repl = yylval.arg;
1693 spat->spat_flags |= SPAT_ONCE;
a687059c
LW
1694 if ((spat->spat_repl[1].arg_type & A_MASK) == A_SINGLE)
1695 spat->spat_flags |= SPAT_CONST;
1696 else if ((spat->spat_repl[1].arg_type & A_MASK) == A_DOUBLE) {
1697 STR *tmpstr;
1698 register char *t;
1699
1700 spat->spat_flags |= SPAT_CONST;
1701 tmpstr = spat->spat_repl[1].arg_ptr.arg_str;
1702 e = tmpstr->str_ptr + tmpstr->str_cur;
1703 for (t = tmpstr->str_ptr; t < e; t++) {
9f68db38
LW
1704 if (*t == '$' && t[1] && (index("`'&+0123456789",t[1]) ||
1705 (t[1] == '{' /*}*/ && isdigit(t[2])) ))
a687059c
LW
1706 spat->spat_flags &= ~SPAT_CONST;
1707 }
1708 }
1709 while (*s == 'g' || *s == 'i' || *s == 'e' || *s == 'o') {
1710 if (*s == 'e') {
1711 s++;
1712 if ((spat->spat_repl[1].arg_type & A_MASK) == A_DOUBLE)
1713 spat->spat_repl[1].arg_type = A_SINGLE;
395c3793 1714 spat->spat_repl = make_op(O_EVAL,2,
a687059c
LW
1715 spat->spat_repl,
1716 Nullarg,
395c3793 1717 Nullarg);
a687059c
LW
1718 spat->spat_flags &= ~SPAT_CONST;
1719 }
378cc40b
LW
1720 if (*s == 'g') {
1721 s++;
1722 spat->spat_flags &= ~SPAT_ONCE;
1723 }
1724 if (*s == 'i') {
1725 s++;
a687059c 1726 sawi = TRUE;
378cc40b 1727 spat->spat_flags |= SPAT_FOLD;
a687059c
LW
1728 if (!(spat->spat_flags & SPAT_SCANFIRST)) {
1729 str_free(spat->spat_short); /* anchored opt doesn't do */
1730 spat->spat_short = Nullstr; /* case insensitive match */
1731 spat->spat_slen = 0;
1732 }
1733 }
1734 if (*s == 'o') {
1735 s++;
1736 spat->spat_flags |= SPAT_KEEP;
378cc40b
LW
1737 }
1738 }
a687059c
LW
1739 if (spat->spat_short && (spat->spat_flags & SPAT_SCANFIRST))
1740 fbmcompile(spat->spat_short, spat->spat_flags & SPAT_FOLD);
378cc40b 1741 if (!spat->spat_runtime) {
395c3793 1742 spat->spat_regexp = regcomp(str->str_ptr,str->str_ptr+len,
fe14fcc3 1743 spat->spat_flags & SPAT_FOLD);
378cc40b 1744 hoistmust(spat);
378cc40b
LW
1745 }
1746 yylval.arg = make_match(O_SUBST,stab2arg(A_STAB,defstab),spat);
395c3793 1747 str_free(str);
378cc40b
LW
1748 return s;
1749}
1750
1751hoistmust(spat)
1752register SPAT *spat;
1753{
1754 if (spat->spat_regexp->regmust) { /* is there a better short-circuit? */
1755 if (spat->spat_short &&
a687059c
LW
1756 str_eq(spat->spat_short,spat->spat_regexp->regmust))
1757 {
378cc40b
LW
1758 if (spat->spat_flags & SPAT_SCANFIRST) {
1759 str_free(spat->spat_short);
1760 spat->spat_short = Nullstr;
1761 }
1762 else {
1763 str_free(spat->spat_regexp->regmust);
1764 spat->spat_regexp->regmust = Nullstr;
1765 return;
1766 }
1767 }
1768 if (!spat->spat_short || /* promote the better string */
1769 ((spat->spat_flags & SPAT_SCANFIRST) &&
1770 (spat->spat_short->str_cur < spat->spat_regexp->regmust->str_cur) )){
1771 str_free(spat->spat_short); /* ok if null */
1772 spat->spat_short = spat->spat_regexp->regmust;
1773 spat->spat_regexp->regmust = Nullstr;
1774 spat->spat_flags |= SPAT_SCANFIRST;
1775 }
1776 }
1777}
1778
1779char *
a687059c 1780expand_charset(s,len,retlen)
378cc40b 1781register char *s;
a687059c
LW
1782int len;
1783int *retlen;
378cc40b 1784{
e929a76b 1785 char t[520];
378cc40b
LW
1786 register char *d = t;
1787 register int i;
a687059c 1788 register char *send = s + len;
378cc40b 1789
e929a76b 1790 while (s < send && d - t <= 256) {
a687059c 1791 if (s[1] == '-' && s+2 < send) {
fe14fcc3 1792 for (i = (s[0] & 0377); i <= (s[2] & 0377); i++)
378cc40b
LW
1793 *d++ = i;
1794 s += 3;
1795 }
1796 else
1797 *d++ = *s++;
1798 }
1799 *d = '\0';
a687059c
LW
1800 *retlen = d - t;
1801 return nsavestr(t,d-t);
378cc40b
LW
1802}
1803
1804char *
1805scantrans(s)
1806register char *s;
1807{
1808 ARG *arg =
a687059c 1809 l(make_op(O_TRANS,2,stab2arg(A_STAB,defstab),Nullarg,Nullarg));
378cc40b
LW
1810 register char *t;
1811 register char *r;
395c3793 1812 register short *tbl;
378cc40b 1813 register int i;
13281fa4 1814 register int j;
a687059c 1815 int tlen, rlen;
395c3793
LW
1816 int squash;
1817 int delete;
1818 int complement;
378cc40b 1819
395c3793 1820 New(803,tbl,256,short);
378cc40b 1821 arg[2].arg_type = A_NULL;
395c3793 1822 arg[2].arg_ptr.arg_cval = (char*) tbl;
378cc40b 1823 s = scanstr(s);
a687059c
LW
1824 if (s >= bufend) {
1825 yyerror("Translation pattern not terminated");
1826 yylval.arg = Nullarg;
1827 return s;
1828 }
1829 t = expand_charset(yylval.arg[1].arg_ptr.arg_str->str_ptr,
1830 yylval.arg[1].arg_ptr.arg_str->str_cur,&tlen);
fe14fcc3 1831 arg_free(yylval.arg);
378cc40b 1832 s = scanstr(s-1);
a687059c
LW
1833 if (s >= bufend) {
1834 yyerror("Translation replacement not terminated");
1835 yylval.arg = Nullarg;
1836 return s;
1837 }
395c3793
LW
1838 complement = delete = squash = 0;
1839 while (*s == 'c' || *s == 'd' || *s == 's') {
1840 if (*s == 'c')
1841 complement = 1;
1842 else if (*s == 'd')
1843 delete = 2;
1844 else
1845 squash = 1;
1846 s++;
1847 }
a687059c
LW
1848 r = expand_charset(yylval.arg[1].arg_ptr.arg_str->str_ptr,
1849 yylval.arg[1].arg_ptr.arg_str->str_cur,&rlen);
fe14fcc3 1850 arg_free(yylval.arg);
395c3793 1851 arg[2].arg_len = delete|squash;
378cc40b 1852 yylval.arg = arg;
395c3793 1853 if (!rlen && !delete) {
a687059c 1854 Safefree(r);
ffed7fef 1855 r = t; rlen = tlen;
378cc40b 1856 }
395c3793
LW
1857 if (complement) {
1858 Zero(tbl, 256, short);
1859 for (i = 0; i < tlen; i++)
1860 tbl[t[i] & 0377] = -1;
fe14fcc3 1861 for (i = 0, j = 0; i < 256; i++) {
395c3793
LW
1862 if (!tbl[i]) {
1863 if (j >= rlen) {
fe14fcc3 1864 if (delete)
395c3793 1865 tbl[i] = -2;
fe14fcc3
LW
1866 else
1867 tbl[i] = r[j-1];
395c3793 1868 }
fe14fcc3
LW
1869 else
1870 tbl[i] = r[j++];
395c3793
LW
1871 }
1872 }
1873 }
1874 else {
1875 for (i = 0; i < 256; i++)
1876 tbl[i] = -1;
1877 for (i = 0, j = 0; i < tlen; i++,j++) {
1878 if (j >= rlen) {
1879 if (delete) {
1880 if (tbl[t[i] & 0377] == -1)
1881 tbl[t[i] & 0377] = -2;
1882 continue;
1883 }
1884 --j;
1885 }
1886 if (tbl[t[i] & 0377] == -1)
34de22dd 1887 tbl[t[i] & 0377] = r[j] & 0377;
395c3793 1888 }
378cc40b
LW
1889 }
1890 if (r != t)
a687059c
LW
1891 Safefree(r);
1892 Safefree(t);
378cc40b
LW
1893 return s;
1894}
1895
1896char *
1897scanstr(s)
1898register char *s;
1899{
1900 register char term;
1901 register char *d;
1902 register ARG *arg;
a687059c 1903 register char *send;
378cc40b
LW
1904 register bool makesingle = FALSE;
1905 register STAB *stab;
a687059c
LW
1906 bool alwaysdollar = FALSE;
1907 bool hereis = FALSE;
1908 STR *herewas;
e929a76b 1909 STR *str;
fe14fcc3 1910 char *leave = "\\$@nrtfbeacx0123456789[{]}lLuUE"; /* which backslash sequences to keep */
a687059c 1911 int len;
378cc40b
LW
1912
1913 arg = op_new(1);
1914 yylval.arg = arg;
1915 arg->arg_type = O_ITEM;
1916
1917 switch (*s) {
1918 default: /* a substitution replacement */
1919 arg[1].arg_type = A_DOUBLE;
1920 makesingle = TRUE; /* maybe disable runtime scanning */
1921 term = *s;
1922 if (term == '\'')
1923 leave = Nullch;
1924 goto snarf_it;
1925 case '0':
1926 {
395c3793 1927 unsigned long i;
378cc40b
LW
1928 int shift;
1929
1930 arg[1].arg_type = A_SINGLE;
1931 if (s[1] == 'x') {
1932 shift = 4;
1933 s += 2;
1934 }
1935 else if (s[1] == '.')
1936 goto decimal;
1937 else
1938 shift = 3;
1939 i = 0;
1940 for (;;) {
1941 switch (*s) {
1942 default:
1943 goto out;
1944 case '8': case '9':
1945 if (shift != 4)
a687059c 1946 yyerror("Illegal octal digit");
378cc40b
LW
1947 /* FALL THROUGH */
1948 case '0': case '1': case '2': case '3': case '4':
1949 case '5': case '6': case '7':
1950 i <<= shift;
1951 i += *s++ & 15;
1952 break;
1953 case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
1954 case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
1955 if (shift != 4)
1956 goto out;
1957 i <<= 4;
1958 i += (*s++ & 7) + 9;
1959 break;
1960 }
1961 }
1962 out:
e929a76b
LW
1963 str = Str_new(92,0);
1964 str_numset(str,(double)i);
1965 if (str->str_ptr) {
1966 Safefree(str->str_ptr);
1967 str->str_ptr = Nullch;
1968 str->str_len = str->str_cur = 0;
1969 }
1970 arg[1].arg_ptr.arg_str = str;
378cc40b
LW
1971 }
1972 break;
1973 case '1': case '2': case '3': case '4': case '5':
1974 case '6': case '7': case '8': case '9': case '.':
1975 decimal:
1976 arg[1].arg_type = A_SINGLE;
1977 d = tokenbuf;
1978 while (isdigit(*s) || *s == '_') {
1979 if (*s == '_')
1980 s++;
1981 else
1982 *d++ = *s++;
1983 }
a687059c 1984 if (*s == '.' && s[1] && index("0123456789eE ;",s[1])) {
378cc40b
LW
1985 *d++ = *s++;
1986 while (isdigit(*s) || *s == '_') {
1987 if (*s == '_')
1988 s++;
1989 else
1990 *d++ = *s++;
1991 }
1992 }
a687059c 1993 if (*s && index("eE",*s) && index("+-0123456789",s[1])) {
378cc40b
LW
1994 *d++ = *s++;
1995 if (*s == '+' || *s == '-')
1996 *d++ = *s++;
1997 while (isdigit(*s))
1998 *d++ = *s++;
1999 }
2000 *d = '\0';
e929a76b
LW
2001 str = Str_new(92,0);
2002 str_numset(str,atof(tokenbuf));
2003 if (str->str_ptr) {
2004 Safefree(str->str_ptr);
2005 str->str_ptr = Nullch;
2006 str->str_len = str->str_cur = 0;
2007 }
2008 arg[1].arg_ptr.arg_str = str;
378cc40b 2009 break;
378cc40b 2010 case '<':
a687059c
LW
2011 if (*++s == '<') {
2012 hereis = TRUE;
2013 d = tokenbuf;
2014 if (!rsfp)
2015 *d++ = '\n';
2016 if (*++s && index("`'\"",*s)) {
2017 term = *s++;
2018 s = cpytill(d,s,bufend,term,&len);
2019 if (s < bufend)
2020 s++;
2021 d += len;
2022 }
2023 else {
2024 if (*s == '\\')
2025 s++, term = '\'';
2026 else
2027 term = '"';
2028 while (isascii(*s) && (isalpha(*s) || isdigit(*s) || *s == '_'))
2029 *d++ = *s++;
2030 } /* assuming tokenbuf won't clobber */
2031 *d++ = '\n';
2032 *d = '\0';
2033 len = d - tokenbuf;
2034 d = "\n";
2035 if (rsfp || !(d=ninstr(s,bufend,d,d+1)))
2036 herewas = str_make(s,bufend-s);
2037 else
2038 s--, herewas = str_make(s,d-s);
2039 s += herewas->str_cur;
2040 if (term == '\'')
2041 goto do_single;
2042 if (term == '`')
2043 goto do_back;
2044 goto do_double;
2045 }
378cc40b 2046 d = tokenbuf;
a687059c
LW
2047 s = cpytill(d,s,bufend,'>',&len);
2048 if (s < bufend)
378cc40b
LW
2049 s++;
2050 if (*d == '$') d++;
a687059c
LW
2051 while (*d &&
2052 (isalpha(*d) || isdigit(*d) || *d == '_' || *d == '\''))
2053 d++;
2054 if (d - tokenbuf != len) {
378cc40b
LW
2055 d = tokenbuf;
2056 arg[1].arg_type = A_GLOB;
a687059c 2057 d = nsavestr(d,len);
378cc40b 2058 arg[1].arg_ptr.arg_stab = stab = genstab();
a687059c
LW
2059 stab_io(stab) = stio_new();
2060 stab_val(stab) = str_make(d,len);
a687059c
LW
2061 Safefree(d);
2062 set_csh();
378cc40b
LW
2063 }
2064 else {
2065 d = tokenbuf;
a687059c
LW
2066 if (!len)
2067 (void)strcpy(d,"ARGV");
378cc40b
LW
2068 if (*d == '$') {
2069 arg[1].arg_type = A_INDREAD;
2070 arg[1].arg_ptr.arg_stab = stabent(d+1,TRUE);
2071 }
2072 else {
2073 arg[1].arg_type = A_READ;
378cc40b 2074 arg[1].arg_ptr.arg_stab = stabent(d,TRUE);
a687059c
LW
2075 if (!stab_io(arg[1].arg_ptr.arg_stab))
2076 stab_io(arg[1].arg_ptr.arg_stab) = stio_new();
378cc40b 2077 if (strEQ(d,"ARGV")) {
a687059c
LW
2078 (void)aadd(arg[1].arg_ptr.arg_stab);
2079 stab_io(arg[1].arg_ptr.arg_stab)->flags |=
378cc40b
LW
2080 IOF_ARGV|IOF_START;
2081 }
2082 }
2083 }
2084 break;
a687059c
LW
2085
2086 case 'q':
2087 s++;
2088 if (*s == 'q') {
2089 s++;
2090 goto do_double;
2091 }
fe14fcc3
LW
2092 if (*s == 'x') {
2093 s++;
2094 goto do_back;
2095 }
a687059c
LW
2096 /* FALL THROUGH */
2097 case '\'':
2098 do_single:
2099 term = *s;
2100 arg[1].arg_type = A_SINGLE;
2101 leave = Nullch;
2102 goto snarf_it;
2103
378cc40b 2104 case '"':
a687059c
LW
2105 do_double:
2106 term = *s;
378cc40b
LW
2107 arg[1].arg_type = A_DOUBLE;
2108 makesingle = TRUE; /* maybe disable runtime scanning */
a687059c 2109 alwaysdollar = TRUE; /* treat $) and $| as variables */
378cc40b
LW
2110 goto snarf_it;
2111 case '`':
a687059c 2112 do_back:
378cc40b 2113 term = *s;
a687059c
LW
2114 arg[1].arg_type = A_BACKTICK;
2115 set_csh();
2116 alwaysdollar = TRUE; /* treat $) and $| as variables */
378cc40b
LW
2117 snarf_it:
2118 {
2119 STR *tmpstr;
378cc40b
LW
2120 char *tmps;
2121
e929a76b 2122 multi_start = curcmd->c_line;
a687059c
LW
2123 if (hereis)
2124 multi_open = multi_close = '<';
2125 else {
2126 multi_open = term;
395c3793 2127 if (term && (tmps = index("([{< )]}> )]}>",term)))
a687059c
LW
2128 term = tmps[5];
2129 multi_close = term;
2130 }
9f68db38 2131 tmpstr = Str_new(87,80);
a687059c
LW
2132 if (hereis) {
2133 term = *tokenbuf;
2134 if (!rsfp) {
2135 d = s;
2136 while (s < bufend &&
2137 (*s != term || bcmp(s,tokenbuf,len) != 0) ) {
2138 if (*s++ == '\n')
e929a76b 2139 curcmd->c_line++;
a687059c
LW
2140 }
2141 if (s >= bufend) {
e929a76b 2142 curcmd->c_line = multi_start;
a687059c
LW
2143 fatal("EOF in string");
2144 }
2145 str_nset(tmpstr,d+1,s-d);
2146 s += len - 1;
2147 str_ncat(herewas,s,bufend-s);
2148 str_replace(linestr,herewas);
2149 oldoldbufptr = oldbufptr = bufptr = s = str_get(linestr);
2150 bufend = linestr->str_ptr + linestr->str_cur;
2151 hereis = FALSE;
2152 }
e929a76b
LW
2153 else
2154 str_nset(tmpstr,"",0); /* avoid "uninitialized" warning */
a687059c
LW
2155 }
2156 else
2157 s = str_append_till(tmpstr,s+1,bufend,term,leave);
2158 while (s >= bufend) { /* multiple line string? */
2159 if (!rsfp ||
2160 !(oldoldbufptr = oldbufptr = s = str_gets(linestr, rsfp, 0))) {
e929a76b 2161 curcmd->c_line = multi_start;
378cc40b
LW
2162 fatal("EOF in string");
2163 }
e929a76b 2164 curcmd->c_line++;
a687059c
LW
2165 if (perldb) {
2166 STR *str = Str_new(88,0);
2167
2168 str_sset(str,linestr);
395c3793
LW
2169 astore(stab_xarray(curcmd->c_filestab),
2170 (int)curcmd->c_line,str);
a687059c
LW
2171 }
2172 bufend = linestr->str_ptr + linestr->str_cur;
2173 if (hereis) {
2174 if (*s == term && bcmp(s,tokenbuf,len) == 0) {
2175 s = bufend - 1;
2176 *s = ' ';
2177 str_scat(linestr,herewas);
2178 bufend = linestr->str_ptr + linestr->str_cur;
2179 }
2180 else {
2181 s = bufend;
2182 str_scat(tmpstr,linestr);
2183 }
2184 }
2185 else
2186 s = str_append_till(tmpstr,s,bufend,term,leave);
378cc40b 2187 }
e929a76b 2188 multi_end = curcmd->c_line;
378cc40b 2189 s++;
a687059c
LW
2190 if (tmpstr->str_cur + 5 < tmpstr->str_len) {
2191 tmpstr->str_len = tmpstr->str_cur + 1;
2192 Renew(tmpstr->str_ptr, tmpstr->str_len, char);
2193 }
2194 if ((arg[1].arg_type & A_MASK) == A_SINGLE) {
378cc40b
LW
2195 arg[1].arg_ptr.arg_str = tmpstr;
2196 break;
2197 }
2198 tmps = s;
2199 s = tmpstr->str_ptr;
a687059c
LW
2200 send = s + tmpstr->str_cur;
2201 while (s < send) { /* see if we can make SINGLE */
378cc40b 2202 if (*s == '\\' && s[1] && isdigit(s[1]) && !isdigit(s[2]) &&
e929a76b 2203 !alwaysdollar && s[1] != '0')
378cc40b 2204 *s = '$'; /* grandfather \digit in subst */
a687059c
LW
2205 if ((*s == '$' || *s == '@') && s+1 < send &&
2206 (alwaysdollar || (s[1] != ')' && s[1] != '|'))) {
378cc40b
LW
2207 makesingle = FALSE; /* force interpretation */
2208 }
a687059c 2209 else if (*s == '\\' && s+1 < send) {
fe14fcc3
LW
2210 if (index("lLuUE",s[1]))
2211 makesingle = FALSE;
378cc40b
LW
2212 s++;
2213 }
2214 s++;
2215 }
2216 s = d = tmpstr->str_ptr; /* assuming shrinkage only */
a687059c
LW
2217 while (s < send) {
2218 if ((*s == '$' && s+1 < send &&
2219 (alwaysdollar || /*(*/ (s[1] != ')' && s[1] != '|')) ) ||
2220 (*s == '@' && s+1 < send) ) {
fe14fcc3 2221 len = scanident(s,send,tokenbuf) - s;
a687059c
LW
2222 if (*s == '$' || strEQ(tokenbuf,"ARGV")
2223 || strEQ(tokenbuf,"ENV")
2224 || strEQ(tokenbuf,"SIG")
2225 || strEQ(tokenbuf,"INC") )
2226 (void)stabent(tokenbuf,TRUE); /* make sure it exists */
378cc40b
LW
2227 while (len--)
2228 *d++ = *s++;
2229 continue;
2230 }
a687059c 2231 else if (*s == '\\' && s+1 < send) {
378cc40b
LW
2232 s++;
2233 switch (*s) {
2234 default:
a687059c 2235 if (!makesingle && (!leave || (*s && index(leave,*s))))
378cc40b
LW
2236 *d++ = '\\';
2237 *d++ = *s++;
2238 continue;
2239 case '0': case '1': case '2': case '3':
2240 case '4': case '5': case '6': case '7':
fe14fcc3
LW
2241 *d++ = scanoct(s, 3, &len);
2242 s += len;
2243 continue;
2244 case 'x':
2245 *d++ = scanhex(++s, 2, &len);
2246 s += len;
2247 continue;
2248 case 'c':
2249 s++;
2250 *d = *s++;
2251 if (islower(*d))
2252 *d = toupper(*d);
2253 *d++ ^= 64;
378cc40b
LW
2254 continue;
2255 case 'b':
2256 *d++ = '\b';
2257 break;
2258 case 'n':
2259 *d++ = '\n';
2260 break;
2261 case 'r':
2262 *d++ = '\r';
2263 break;
2264 case 'f':
2265 *d++ = '\f';
2266 break;
2267 case 't':
2268 *d++ = '\t';
2269 break;
fe14fcc3
LW
2270 case 'e':
2271 *d++ = '\033';
2272 break;
2273 case 'a':
2274 *d++ = '\007';
2275 break;
378cc40b
LW
2276 }
2277 s++;
2278 continue;
2279 }
2280 *d++ = *s++;
2281 }
2282 *d = '\0';
2283
a687059c
LW
2284 if ((arg[1].arg_type & A_MASK) == A_DOUBLE && makesingle)
2285 arg[1].arg_type = A_SINGLE; /* now we can optimize on it */
2286
a687059c 2287 tmpstr->str_cur = d - tmpstr->str_ptr;
378cc40b
LW
2288 arg[1].arg_ptr.arg_str = tmpstr;
2289 s = tmps;
2290 break;
2291 }
2292 }
a687059c
LW
2293 if (hereis)
2294 str_free(herewas);
378cc40b
LW
2295 return s;
2296}
2297
2298FCMD *
2299load_format()
2300{
2301 FCMD froot;
2302 FCMD *flinebeg;
0f85fab0 2303 char *eol;
378cc40b
LW
2304 register FCMD *fprev = &froot;
2305 register FCMD *fcmd;
2306 register char *s;
2307 register char *t;
a687059c 2308 register STR *str;
378cc40b 2309 bool noblank;
a687059c 2310 bool repeater;
378cc40b 2311
a687059c 2312 Zero(&froot, 1, FCMD);
0f85fab0 2313 s = bufptr;
27e2fb84 2314 while (s < bufend || (rsfp && (s = str_gets(linestr,rsfp, 0)) != Nullch)) {
e929a76b 2315 curcmd->c_line++;
0f85fab0
LW
2316 if (in_eval && !rsfp) {
2317 eol = index(s,'\n');
2318 if (!eol++)
2319 eol = bufend;
2320 }
2321 else
2322 eol = bufend = linestr->str_ptr + linestr->str_cur;
395c3793
LW
2323 if (perldb) {
2324 STR *tmpstr = Str_new(89,0);
2325
2326 str_nset(tmpstr, s, eol-s);
2327 astore(stab_xarray(curcmd->c_filestab), (int)curcmd->c_line,tmpstr);
2328 }
27e2fb84
LW
2329 if (*s == '.') {
2330 for (t = s+1; *t == ' ' || *t == '\t'; t++) ;
2331 if (*t == '\n') {
2332 bufptr = s;
2333 return froot.f_next;
2334 }
378cc40b 2335 }
0f85fab0
LW
2336 if (*s == '#') {
2337 s = eol;
378cc40b 2338 continue;
0f85fab0 2339 }
378cc40b
LW
2340 flinebeg = Nullfcmd;
2341 noblank = FALSE;
a687059c 2342 repeater = FALSE;
0f85fab0 2343 while (s < eol) {
a687059c 2344 Newz(804,fcmd,1,FCMD);
378cc40b
LW
2345 fprev->f_next = fcmd;
2346 fprev = fcmd;
0f85fab0 2347 for (t=s; t < eol && *t != '@' && *t != '^'; t++) {
378cc40b
LW
2348 if (*t == '~') {
2349 noblank = TRUE;
2350 *t = ' ';
a687059c
LW
2351 if (t[1] == '~') {
2352 repeater = TRUE;
2353 t[1] = ' ';
2354 }
378cc40b
LW
2355 }
2356 }
a687059c
LW
2357 fcmd->f_pre = nsavestr(s, t-s);
2358 fcmd->f_presize = t-s;
378cc40b 2359 s = t;
0f85fab0 2360 if (s >= eol) {
378cc40b
LW
2361 if (noblank)
2362 fcmd->f_flags |= FC_NOBLANK;
a687059c
LW
2363 if (repeater)
2364 fcmd->f_flags |= FC_REPEAT;
378cc40b
LW
2365 break;
2366 }
2367 if (!flinebeg)
2368 flinebeg = fcmd; /* start values here */
2369 if (*s++ == '^')
2370 fcmd->f_flags |= FC_CHOP; /* for doing text filling */
2371 switch (*s) {
2372 case '*':
2373 fcmd->f_type = F_LINES;
2374 *s = '\0';
2375 break;
2376 case '<':
2377 fcmd->f_type = F_LEFT;
2378 while (*s == '<')
2379 s++;
2380 break;
2381 case '>':
2382 fcmd->f_type = F_RIGHT;
2383 while (*s == '>')
2384 s++;
2385 break;
2386 case '|':
2387 fcmd->f_type = F_CENTER;
2388 while (*s == '|')
2389 s++;
2390 break;
395c3793
LW
2391 case '#':
2392 case '.':
2393 /* Catch the special case @... and handle it as a string
2394 field. */
2395 if (*s == '.' && s[1] == '.') {
2396 goto default_format;
2397 }
2398 fcmd->f_type = F_DECIMAL;
2399 {
2400 char *p;
2401
2402 /* Read a format in the form @####.####, where either group
2403 of ### may be empty, or the final .### may be missing. */
2404 while (*s == '#')
2405 s++;
2406 if (*s == '.') {
2407 s++;
2408 p = s;
2409 while (*s == '#')
2410 s++;
2411 fcmd->f_decimals = s-p;
2412 fcmd->f_flags |= FC_DP;
2413 } else {
2414 fcmd->f_decimals = 0;
2415 }
2416 }
2417 break;
378cc40b 2418 default:
395c3793 2419 default_format:
378cc40b
LW
2420 fcmd->f_type = F_LEFT;
2421 break;
2422 }
2423 if (fcmd->f_flags & FC_CHOP && *s == '.') {
2424 fcmd->f_flags |= FC_MORE;
2425 while (*s == '.')
2426 s++;
2427 }
2428 fcmd->f_size = s-t;
2429 }
2430 if (flinebeg) {
2431 again:
27e2fb84
LW
2432 if (s >= bufend &&
2433 (!rsfp || (s = str_gets(linestr, rsfp, 0)) == Nullch) )
378cc40b 2434 goto badform;
e929a76b 2435 curcmd->c_line++;
0f85fab0
LW
2436 if (in_eval && !rsfp) {
2437 eol = index(s,'\n');
2438 if (!eol++)
2439 eol = bufend;
2440 }
2441 else
2442 eol = bufend = linestr->str_ptr + linestr->str_cur;
395c3793
LW
2443 if (perldb) {
2444 STR *tmpstr = Str_new(90,0);
2445
2446 str_nset(tmpstr, s, eol-s);
2447 astore(stab_xarray(curcmd->c_filestab),
2448 (int)curcmd->c_line,tmpstr);
2449 }
0f85fab0 2450 if (strnEQ(s,".\n",2)) {
a687059c 2451 bufptr = s;
378cc40b
LW
2452 yyerror("Missing values line");
2453 return froot.f_next;
2454 }
0f85fab0
LW
2455 if (*s == '#') {
2456 s = eol;
378cc40b 2457 goto again;
0f85fab0
LW
2458 }
2459 str = flinebeg->f_unparsed = Str_new(91,eol - s);
a687059c
LW
2460 str->str_u.str_hash = curstash;
2461 str_nset(str,"(",1);
e929a76b 2462 flinebeg->f_line = curcmd->c_line;
0f85fab0
LW
2463 eol[-1] = '\0';
2464 if (!flinebeg->f_next->f_type || index(s, ',')) {
2465 eol[-1] = '\n';
2466 str_ncat(str, s, eol - s - 1);
a687059c 2467 str_ncat(str,",$$);",5);
0f85fab0 2468 s = eol;
a687059c
LW
2469 }
2470 else {
0f85fab0
LW
2471 eol[-1] = '\n';
2472 while (s < eol && isspace(*s))
a687059c
LW
2473 s++;
2474 t = s;
0f85fab0 2475 while (s < eol) {
a687059c
LW
2476 switch (*s) {
2477 case ' ': case '\t': case '\n': case ';':
2478 str_ncat(str, t, s - t);
2479 str_ncat(str, "," ,1);
0f85fab0 2480 while (s < eol && (isspace(*s) || *s == ';'))
a687059c
LW
2481 s++;
2482 t = s;
2483 break;
2484 case '$':
2485 str_ncat(str, t, s - t);
2486 t = s;
fe14fcc3 2487 s = scanident(s,eol,tokenbuf);
a687059c
LW
2488 str_ncat(str, t, s - t);
2489 t = s;
0f85fab0 2490 if (s < eol && *s && index("$'\"",*s))
a687059c
LW
2491 str_ncat(str, ",", 1);
2492 break;
2493 case '"': case '\'':
2494 str_ncat(str, t, s - t);
2495 t = s;
2496 s++;
0f85fab0 2497 while (s < eol && (*s != *t || s[-1] == '\\'))
a687059c 2498 s++;
0f85fab0 2499 if (s < eol)
a687059c
LW
2500 s++;
2501 str_ncat(str, t, s - t);
2502 t = s;
0f85fab0 2503 if (s < eol && *s && index("$'\"",*s))
a687059c
LW
2504 str_ncat(str, ",", 1);
2505 break;
2506 default:
2507 yyerror("Please use commas to separate fields");
378cc40b 2508 }
378cc40b 2509 }
a687059c 2510 str_ncat(str,"$$);",4);
378cc40b 2511 }
378cc40b
LW
2512 }
2513 }
2514 badform:
2515 bufptr = str_get(linestr);
2516 yyerror("Format not terminated");
2517 return froot.f_next;
2518}
a687059c
LW
2519
2520set_csh()
2521{
ae986130
LW
2522#ifdef CSH
2523 if (!cshlen)
2524 cshlen = strlen(cshname);
2525#endif
a687059c 2526}