Changeset 1210 in kBuild for trunk/src/kash/parser.c
- Timestamp:
- Oct 7, 2007 6:33:36 PM (17 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/kash/parser.c
r1208 r1210 68 68 #include "myhistedit.h" 69 69 #endif 70 #include "shinstance.h" 70 71 71 72 /* … … 91 92 92 93 93 static int noalias = 0; /* when set, don't handle aliases */94 struct heredoc *heredoclist; /* list of here documents to read */95 int parsebackquote; /* nonzero if we are inside backquotes */96 int doprompt; /* if set, prompt the user */97 int needprompt; /* true if interactive and at start of line */98 int lasttoken; /* last token read */99 MKINIT int tokpushback; /* last token pushed back */100 char *wordtext; /* text of last word returned by readtoken */101 MKINIT int checkkwd; /* 1 == check for kwds, 2 == also eat newlines */102 struct nodelist *backquotelist;103 union node *redirnode;104 struct heredoc *heredoc;105 int quoteflag; /* set if (part of) last token was quoted */106 int startlinno; /* line # where last token started */107 108 109 STATIC union node *list( int);110 STATIC union node *andor( void);111 STATIC union node *pipeline( void);112 STATIC union node *command( void);113 STATIC union node *simplecmd( union node **, union node *);114 STATIC union node *makename( void);115 STATIC void parsefname( void);116 STATIC void parseheredoc( void);117 STATIC int peektoken( void);118 STATIC int readtoken( void);119 STATIC int xxreadtoken( void);120 STATIC int readtoken1( int, char const *, char *, int);121 STATIC int noexpand( char *);122 STATIC void synexpect( int) __attribute__((__noreturn__));123 STATIC void synerror( const char *) __attribute__((__noreturn__));124 STATIC void setprompt( int);94 //static int noalias = 0; /* when set, don't handle aliases */ 95 //struct heredoc *heredoclist; /* list of here documents to read */ 96 //int parsebackquote; /* nonzero if we are inside backquotes */ 97 //int doprompt; /* if set, prompt the user */ 98 //int needprompt; /* true if interactive and at start of line */ 99 //int lasttoken; /* last token read */ 100 //MKINIT int tokpushback; /* last token pushed back */ 101 //char *wordtext; /* text of last word returned by readtoken */ 102 //MKINIT int checkkwd; /* 1 == check for kwds, 2 == also eat newlines */ 103 //struct nodelist *backquotelist; 104 //union node *redirnode; 105 //struct heredoc *heredoc; 106 //int quoteflag; /* set if (part of) last token was quoted */ 107 //int startlinno; /* line # where last token started */ 108 109 110 STATIC union node *list(shinstance *, int); 111 STATIC union node *andor(shinstance *); 112 STATIC union node *pipeline(shinstance *); 113 STATIC union node *command(shinstance *); 114 STATIC union node *simplecmd(shinstance *, union node **, union node *); 115 STATIC union node *makename(shinstance *); 116 STATIC void parsefname(shinstance *); 117 STATIC void parseheredoc(shinstance *); 118 STATIC int peektoken(shinstance *); 119 STATIC int readtoken(shinstance *); 120 STATIC int xxreadtoken(shinstance *); 121 STATIC int readtoken1(shinstance *, int, char const *, char *, int); 122 STATIC int noexpand(shinstance *, char *); 123 STATIC void synexpect(shinstance *, int) __attribute__((__noreturn__)); 124 STATIC void synerror(shinstance *, const char *) __attribute__((__noreturn__)); 125 STATIC void setprompt(shinstance *, int); 125 126 126 127 … … 131 132 132 133 union node * 133 parsecmd( int interact)134 parsecmd(shinstance *psh, int interact) 134 135 { 135 136 int t; 136 137 137 tokpushback = 0;138 doprompt = interact;139 if ( doprompt)140 setprompt( 1);138 psh->tokpushback = 0; 139 psh->doprompt = interact; 140 if (psh->doprompt) 141 setprompt(psh, 1); 141 142 else 142 setprompt( 0);143 needprompt = 0;144 t = readtoken( );143 setprompt(psh, 0); 144 psh->needprompt = 0; 145 t = readtoken(psh); 145 146 if (t == TEOF) 146 147 return NEOF; 147 148 if (t == TNL) 148 149 return NULL; 149 tokpushback++;150 return list( 1);150 psh->tokpushback++; 151 return list(psh, 1); 151 152 } 152 153 153 154 154 155 STATIC union node * 155 list( int nlflag)156 list(shinstance *psh, int nlflag) 156 157 { 157 158 union node *n1, *n2, *n3; 158 159 int tok; 159 160 160 checkkwd = 2;161 if (nlflag == 0 && tokendlist[peektoken( )])161 psh->checkkwd = 2; 162 if (nlflag == 0 && tokendlist[peektoken(psh)]) 162 163 return NULL; 163 164 n1 = NULL; 164 165 for (;;) { 165 n2 = andor( );166 tok = readtoken( );166 n2 = andor(psh); 167 tok = readtoken(psh); 167 168 if (tok == TBACKGND) { 168 169 if (n2->type == NCMD || n2->type == NPIPE) { … … 191 192 case TBACKGND: 192 193 case TSEMI: 193 tok = readtoken( );194 tok = readtoken(psh); 194 195 /* fall through */ 195 196 case TNL: 196 197 if (tok == TNL) { 197 parseheredoc( );198 parseheredoc(psh); 198 199 if (nlflag) 199 200 return n1; 200 201 } else { 201 tokpushback++;202 } 203 checkkwd = 2;204 if (tokendlist[peektoken( )])202 psh->tokpushback++; 203 } 204 psh->checkkwd = 2; 205 if (tokendlist[peektoken(psh)]) 205 206 return n1; 206 207 break; 207 208 case TEOF: 208 if ( heredoclist)209 parseheredoc( );209 if (psh->heredoclist) 210 parseheredoc(psh); 210 211 else 211 212 pungetc(psh); /* push back EOF on input */ … … 213 214 default: 214 215 if (nlflag) 215 synexpect( -1);216 tokpushback++;216 synexpect(psh, -1); 217 psh->tokpushback++; 217 218 return n1; 218 219 } … … 223 224 224 225 STATIC union node * 225 andor( void)226 andor(shinstance *psh) 226 227 { 227 228 union node *n1, *n2, *n3; 228 229 int t; 229 230 230 n1 = pipeline( );231 n1 = pipeline(psh); 231 232 for (;;) { 232 if ((t = readtoken( )) == TAND) {233 if ((t = readtoken(psh)) == TAND) { 233 234 t = NAND; 234 235 } else if (t == TOR) { 235 236 t = NOR; 236 237 } else { 237 tokpushback++;238 psh->tokpushback++; 238 239 return n1; 239 240 } 240 n2 = pipeline( );241 n2 = pipeline(psh); 241 242 n3 = (union node *)stalloc(psh, sizeof (struct nbinary)); 242 243 n3->type = t; … … 250 251 251 252 STATIC union node * 252 pipeline( void)253 pipeline(shinstance *psh) 253 254 { 254 255 union node *n1, *n2, *pipenode; … … 258 259 negate = 0; 259 260 TRACE((psh, "pipeline: entered\n")); 260 while (readtoken( ) == TNOT)261 while (readtoken(psh) == TNOT) 261 262 negate = !negate; 262 tokpushback++;263 n1 = command( );264 if (readtoken( ) == TPIPE) {263 psh->tokpushback++; 264 n1 = command(psh); 265 if (readtoken(psh) == TPIPE) { 265 266 pipenode = (union node *)stalloc(psh, sizeof (struct npipe)); 266 267 pipenode->type = NPIPE; … … 272 273 prev = lp; 273 274 lp = (struct nodelist *)stalloc(psh, sizeof (struct nodelist)); 274 lp->n = command( );275 lp->n = command(psh); 275 276 prev->next = lp; 276 } while (readtoken( ) == TPIPE);277 } while (readtoken(psh) == TPIPE); 277 278 lp->next = NULL; 278 279 n1 = pipenode; 279 280 } 280 tokpushback++;281 psh->tokpushback++; 281 282 if (negate) { 282 283 n2 = (union node *)stalloc(psh, sizeof (struct nnot)); … … 291 292 292 293 STATIC union node * 293 command( void)294 command(shinstance *psh) 294 295 { 295 296 union node *n1, *n2; … … 299 300 int t, negate = 0; 300 301 301 checkkwd = 2;302 psh->checkkwd = 2; 302 303 redir = NULL; 303 304 n1 = NULL; … … 305 306 306 307 /* Check for redirection which may precede command */ 307 while (readtoken( ) == TREDIR) {308 *rpp = n2 = redirnode;308 while (readtoken(psh) == TREDIR) { 309 *rpp = n2 = psh->redirnode; 309 310 rpp = &n2->nfile.next; 310 parsefname( );311 } 312 tokpushback++;313 314 while (readtoken( ) == TNOT) {311 parsefname(psh); 312 } 313 psh->tokpushback++; 314 315 while (readtoken(psh) == TNOT) { 315 316 TRACE((psh, "command: TNOT recognized\n")); 316 317 negate = !negate; 317 318 } 318 tokpushback++;319 320 switch (readtoken( )) {319 psh->tokpushback++; 320 321 switch (readtoken(psh)) { 321 322 case TIF: 322 323 n1 = (union node *)stalloc(psh, sizeof (struct nif)); 323 324 n1->type = NIF; 324 n1->nif.test = list( 0);325 if (readtoken( ) != TTHEN)326 synexpect( TTHEN);327 n1->nif.ifpart = list( 0);325 n1->nif.test = list(psh, 0); 326 if (readtoken(psh) != TTHEN) 327 synexpect(psh, TTHEN); 328 n1->nif.ifpart = list(psh, 0); 328 329 n2 = n1; 329 while (readtoken( ) == TELIF) {330 while (readtoken(psh) == TELIF) { 330 331 n2->nif.elsepart = (union node *)stalloc(psh, sizeof (struct nif)); 331 332 n2 = n2->nif.elsepart; 332 333 n2->type = NIF; 333 n2->nif.test = list( 0);334 if (readtoken( ) != TTHEN)335 synexpect( TTHEN);336 n2->nif.ifpart = list( 0);337 } 338 if ( lasttoken == TELSE)339 n2->nif.elsepart = list( 0);334 n2->nif.test = list(psh, 0); 335 if (readtoken(psh) != TTHEN) 336 synexpect(psh, TTHEN); 337 n2->nif.ifpart = list(psh, 0); 338 } 339 if (psh->lasttoken == TELSE) 340 n2->nif.elsepart = list(psh, 0); 340 341 else { 341 342 n2->nif.elsepart = NULL; 342 tokpushback++;343 } 344 if (readtoken( ) != TFI)345 synexpect( TFI);346 checkkwd = 1;343 psh->tokpushback++; 344 } 345 if (readtoken(psh) != TFI) 346 synexpect(psh, TFI); 347 psh->checkkwd = 1; 347 348 break; 348 349 case TWHILE: … … 350 351 int got; 351 352 n1 = (union node *)stalloc(psh, sizeof (struct nbinary)); 352 n1->type = ( lasttoken == TWHILE)? NWHILE : NUNTIL;353 n1->nbinary.ch1 = list( 0);354 if ((got=readtoken( )) != TDO) {355 TRACE((psh, "expecting DO got %s %s\n", tokname[got], got == TWORD ? wordtext : ""));356 synexpect( TDO);357 } 358 n1->nbinary.ch2 = list( 0);359 if (readtoken( ) != TDONE)360 synexpect( TDONE);361 checkkwd = 1;353 n1->type = (psh->lasttoken == TWHILE)? NWHILE : NUNTIL; 354 n1->nbinary.ch1 = list(psh, 0); 355 if ((got=readtoken(psh)) != TDO) { 356 TRACE((psh, "expecting DO got %s %s\n", tokname[got], got == TWORD ? psh->wordtext : "")); 357 synexpect(psh, TDO); 358 } 359 n1->nbinary.ch2 = list(psh, 0); 360 if (readtoken(psh) != TDONE) 361 synexpect(psh, TDONE); 362 psh->checkkwd = 1; 362 363 break; 363 364 } 364 365 case TFOR: 365 if (readtoken( ) != TWORD || quoteflag || ! goodname(wordtext))366 synerror( "Bad for loop variable");366 if (readtoken(psh) != TWORD || psh->quoteflag || ! goodname(psh->wordtext)) 367 synerror(psh, "Bad for loop variable"); 367 368 n1 = (union node *)stalloc(psh, sizeof (struct nfor)); 368 369 n1->type = NFOR; 369 n1->nfor.var = wordtext;370 if (readtoken( ) == TWORD && ! quoteflag && equal(wordtext, "in")) {370 n1->nfor.var = psh->wordtext; 371 if (readtoken(psh) == TWORD && ! psh->quoteflag && equal(psh->wordtext, "in")) { 371 372 app = ≈ 372 while (readtoken( ) == TWORD) {373 while (readtoken(psh) == TWORD) { 373 374 n2 = (union node *)stalloc(psh, sizeof (struct narg)); 374 375 n2->type = NARG; 375 n2->narg.text = wordtext;376 n2->narg.backquote = backquotelist;376 n2->narg.text = psh->wordtext; 377 n2->narg.backquote = psh->backquotelist; 377 378 *app = n2; 378 379 app = &n2->narg.next; … … 380 381 *app = NULL; 381 382 n1->nfor.args = ap; 382 if ( lasttoken != TNL &&lasttoken != TSEMI)383 synexpect( -1);383 if (psh->lasttoken != TNL && psh->lasttoken != TSEMI) 384 synexpect(psh, -1); 384 385 } else { 385 386 static char argvars[5] = {CTLVAR, VSNORMAL|VSQUOTE, … … 395 396 * that the original Bourne shell only allowed NL). 396 397 */ 397 if ( lasttoken != TNL &&lasttoken != TSEMI)398 tokpushback++;399 } 400 checkkwd = 2;401 if ((t = readtoken( )) == TDO)398 if (psh->lasttoken != TNL && psh->lasttoken != TSEMI) 399 psh->tokpushback++; 400 } 401 psh->checkkwd = 2; 402 if ((t = readtoken(psh)) == TDO) 402 403 t = TDONE; 403 404 else if (t == TBEGIN) 404 405 t = TEND; 405 406 else 406 synexpect( -1);407 n1->nfor.body = list( 0);408 if (readtoken( ) != t)409 synexpect( t);410 checkkwd = 1;407 synexpect(psh, -1); 408 n1->nfor.body = list(psh, 0); 409 if (readtoken(psh) != t) 410 synexpect(psh, t); 411 psh->checkkwd = 1; 411 412 break; 412 413 case TCASE: 413 414 n1 = (union node *)stalloc(psh, sizeof (struct ncase)); 414 415 n1->type = NCASE; 415 if (readtoken( ) != TWORD)416 synexpect( TWORD);416 if (readtoken(psh) != TWORD) 417 synexpect(psh, TWORD); 417 418 n1->ncase.expr = n2 = (union node *)stalloc(psh, sizeof (struct narg)); 418 419 n2->type = NARG; 419 n2->narg.text = wordtext;420 n2->narg.backquote = backquotelist;420 n2->narg.text = psh->wordtext; 421 n2->narg.backquote = psh->backquotelist; 421 422 n2->narg.next = NULL; 422 while (readtoken( ) == TNL);423 if ( lasttoken != TWORD || ! equal(wordtext, "in"))424 synerror( "expecting \"in\"");423 while (readtoken(psh) == TNL); 424 if (psh->lasttoken != TWORD || ! equal(psh->wordtext, "in")) 425 synerror(psh, "expecting \"in\""); 425 426 cpp = &n1->ncase.cases; 426 noalias = 1;427 checkkwd = 2, readtoken();427 psh->noalias = 1; 428 psh->checkkwd = 2, readtoken(psh); 428 429 do { 429 430 *cpp = cp = (union node *)stalloc(psh, sizeof (struct nclist)); … … 433 434 *app = ap = (union node *)stalloc(psh, sizeof (struct narg)); 434 435 ap->type = NARG; 435 ap->narg.text = wordtext;436 ap->narg.backquote = backquotelist;437 if ( checkkwd = 2, readtoken() != TPIPE)436 ap->narg.text = psh->wordtext; 437 ap->narg.backquote = psh->backquotelist; 438 if (psh->checkkwd = 2, readtoken(psh) != TPIPE) 438 439 break; 439 440 app = &ap->narg.next; 440 readtoken( );441 readtoken(psh); 441 442 } 442 443 ap->narg.next = NULL; 443 noalias = 0;444 if ( lasttoken != TRP) {445 synexpect( TRP);446 } 447 cp->nclist.body = list( 0);448 449 checkkwd = 2;450 if ((t = readtoken( )) != TESAC) {444 psh->noalias = 0; 445 if (psh->lasttoken != TRP) { 446 synexpect(psh, TRP); 447 } 448 cp->nclist.body = list(psh, 0); 449 450 psh->checkkwd = 2; 451 if ((t = readtoken(psh)) != TESAC) { 451 452 if (t != TENDCASE) { 452 noalias = 0;453 synexpect( TENDCASE);453 psh->noalias = 0; 454 synexpect(psh, TENDCASE); 454 455 } else { 455 noalias = 1;456 checkkwd = 2;457 readtoken( );456 psh->noalias = 1; 457 psh->checkkwd = 2; 458 readtoken(psh); 458 459 } 459 460 } 460 461 cpp = &cp->nclist.next; 461 } while( lasttoken != TESAC);462 noalias = 0;462 } while(psh->lasttoken != TESAC); 463 psh->noalias = 0; 463 464 *cpp = NULL; 464 checkkwd = 1;465 psh->checkkwd = 1; 465 466 break; 466 467 case TLP: 467 468 n1 = (union node *)stalloc(psh, sizeof (struct nredir)); 468 469 n1->type = NSUBSHELL; 469 n1->nredir.n = list( 0);470 n1->nredir.n = list(psh, 0); 470 471 n1->nredir.redirect = NULL; 471 if (readtoken( ) != TRP)472 synexpect( TRP);473 checkkwd = 1;472 if (readtoken(psh) != TRP) 473 synexpect(psh, TRP); 474 psh->checkkwd = 1; 474 475 break; 475 476 case TBEGIN: 476 n1 = list( 0);477 if (readtoken( ) != TEND)478 synexpect( TEND);479 checkkwd = 1;477 n1 = list(psh, 0); 478 if (readtoken(psh) != TEND) 479 synexpect(psh, TEND); 480 psh->checkkwd = 1; 480 481 break; 481 482 /* Handle an empty command like other simple commands. */ … … 486 487 */ 487 488 if (!redir) 488 synexpect( -1);489 synexpect(psh, -1); 489 490 case TAND: 490 491 case TOR: … … 493 494 case TWORD: 494 495 case TRP: 495 tokpushback++;496 n1 = simplecmd( rpp, redir);496 psh->tokpushback++; 497 n1 = simplecmd(psh, rpp, redir); 497 498 goto checkneg; 498 499 default: 499 synexpect( -1);500 synexpect(psh, -1); 500 501 /* NOTREACHED */ 501 502 } 502 503 503 504 /* Now check for redirection which may follow command */ 504 while (readtoken( ) == TREDIR) {505 *rpp = n2 = redirnode;505 while (readtoken(psh) == TREDIR) { 506 *rpp = n2 = psh->redirnode; 506 507 rpp = &n2->nfile.next; 507 parsefname( );508 } 509 tokpushback++;508 parsefname(psh); 509 } 510 psh->tokpushback++; 510 511 *rpp = NULL; 511 512 if (redir) { … … 532 533 533 534 STATIC union node * 534 simplecmd( union node **rpp, union node *redir)535 simplecmd(shinstance *psh, union node **rpp, union node *redir) 535 536 { 536 537 union node *args, **app; … … 553 554 orig_rpp = rpp; 554 555 555 while (readtoken( ) == TNOT) {556 while (readtoken(psh) == TNOT) { 556 557 TRACE((psh, "command: TNOT recognized\n")); 557 558 negate = !negate; 558 559 } 559 tokpushback++;560 psh->tokpushback++; 560 561 561 562 for (;;) { 562 if (readtoken( ) == TWORD) {563 if (readtoken(psh) == TWORD) { 563 564 n = (union node *)stalloc(psh, sizeof (struct narg)); 564 565 n->type = NARG; 565 n->narg.text = wordtext;566 n->narg.backquote = backquotelist;566 n->narg.text = psh->wordtext; 567 n->narg.backquote = psh->backquotelist; 567 568 *app = n; 568 569 app = &n->narg.next; 569 } else if ( lasttoken == TREDIR) {570 *rpp = n = redirnode;570 } else if (psh->lasttoken == TREDIR) { 571 *rpp = n = psh->redirnode; 571 572 rpp = &n->nfile.next; 572 parsefname( ); /* read name of redirection file */573 } else if ( lasttoken == TLP && app == &args->narg.next573 parsefname(psh); /* read name of redirection file */ 574 } else if (psh->lasttoken == TLP && app == &args->narg.next 574 575 && rpp == orig_rpp) { 575 576 /* We have a function */ 576 if (readtoken( ) != TRP)577 synexpect( TRP);577 if (readtoken(psh) != TRP) 578 synexpect(psh, TRP); 578 579 #ifdef notdef 579 580 if (! goodname(n->narg.text)) 580 synerror( "Bad function name");581 synerror(psh, "Bad function name"); 581 582 #endif 582 583 n->type = NDEFUN; 583 n->narg.next = command( );584 n->narg.next = command(psh); 584 585 goto checkneg; 585 586 } else { 586 tokpushback++;587 psh->tokpushback++; 587 588 break; 588 589 } … … 608 609 609 610 STATIC union node * 610 makename( void)611 makename(shinstance *psh) 611 612 { 612 613 union node *n; … … 615 616 n->type = NARG; 616 617 n->narg.next = NULL; 617 n->narg.text = wordtext;618 n->narg.backquote = backquotelist;618 n->narg.text = psh->wordtext; 619 n->narg.backquote = psh->backquotelist; 619 620 return n; 620 621 } 621 622 622 void fixredir( union node *n, const char *text, int err)623 void fixredir(shinstance *psh, union node *n, const char *text, int err) 623 624 { 624 625 TRACE((psh, "Fix redir %s %d\n", text, err)); … … 633 634 634 635 if (err) 635 synerror( "Bad fd number");636 synerror(psh, "Bad fd number"); 636 637 else 637 n->ndup.vname = makename( );638 n->ndup.vname = makename(psh); 638 639 } 639 640 } … … 641 642 642 643 STATIC void 643 parsefname( void)644 { 645 union node *n = redirnode;646 647 if (readtoken( ) != TWORD)648 synexpect( -1);644 parsefname(shinstance *psh) 645 { 646 union node *n = psh->redirnode; 647 648 if (readtoken(psh) != TWORD) 649 synexpect(psh, -1); 649 650 if (n->type == NHERE) { 650 struct heredoc *here = heredoc;651 struct heredoc *here = psh->heredoc; 651 652 struct heredoc *p; 652 int i;653 654 if ( quoteflag == 0)653 size_t i; 654 655 if (psh->quoteflag == 0) 655 656 n->type = NXHERE; 656 657 TRACE((psh, "Here document %d\n", n->type)); 657 658 if (here->striptabs) { 658 while (* wordtext == '\t')659 wordtext++;660 } 661 if (! noexpand( wordtext) || (i = strlen(wordtext)) == 0 || i > EOFMARKLEN)662 synerror( "Illegal eof marker for << redirection");663 rmescapes(psh, wordtext);664 here->eofmark = wordtext;659 while (*psh->wordtext == '\t') 660 psh->wordtext++; 661 } 662 if (! noexpand(psh, psh->wordtext) || (i = strlen(psh->wordtext)) == 0 || i > EOFMARKLEN) 663 synerror(psh, "Illegal eof marker for << redirection"); 664 rmescapes(psh, psh->wordtext); 665 here->eofmark = psh->wordtext; 665 666 here->next = NULL; 666 if ( heredoclist == NULL)667 heredoclist = here;667 if (psh->heredoclist == NULL) 668 psh->heredoclist = here; 668 669 else { 669 for (p = heredoclist ; p->next ; p = p->next);670 for (p = psh->heredoclist ; p->next ; p = p->next); 670 671 p->next = here; 671 672 } 672 673 } else if (n->type == NTOFD || n->type == NFROMFD) { 673 fixredir( n,wordtext, 0);674 fixredir(psh, n, psh->wordtext, 0); 674 675 } else { 675 n->nfile.fname = makename( );676 n->nfile.fname = makename(psh); 676 677 } 677 678 } … … 683 684 684 685 STATIC void 685 parseheredoc( void)686 parseheredoc(shinstance *psh) 686 687 { 687 688 struct heredoc *here; 688 689 union node *n; 689 690 690 while ( heredoclist) {691 here = heredoclist;692 heredoclist = here->next;693 if ( needprompt) {694 setprompt( 2);695 needprompt = 0;696 } 697 readtoken1(p getc(psh), here->here->type == NHERE? SQSYNTAX : DQSYNTAX,691 while (psh->heredoclist) { 692 here = psh->heredoclist; 693 psh->heredoclist = here->next; 694 if (psh->needprompt) { 695 setprompt(psh, 2); 696 psh->needprompt = 0; 697 } 698 readtoken1(psh, pgetc(psh), here->here->type == NHERE? SQSYNTAX : DQSYNTAX, 698 699 here->eofmark, here->striptabs); 699 700 n = (union node *)stalloc(psh, sizeof (struct narg)); 700 701 n->narg.type = NARG; 701 702 n->narg.next = NULL; 702 n->narg.text = wordtext;703 n->narg.backquote = backquotelist;703 n->narg.text = psh->wordtext; 704 n->narg.backquote = psh->backquotelist; 704 705 here->here->nhere.doc = n; 705 706 } … … 707 708 708 709 STATIC int 709 peektoken( void)710 peektoken(shinstance *psh) 710 711 { 711 712 int t; 712 713 713 t = readtoken( );714 tokpushback++;714 t = readtoken(psh); 715 psh->tokpushback++; 715 716 return (t); 716 717 } 717 718 718 719 STATIC int 719 readtoken( void)720 readtoken(shinstance *psh) 720 721 { 721 722 int t; 722 int savecheckkwd = checkkwd;723 int savecheckkwd = psh->checkkwd; 723 724 #ifdef DEBUG 724 int alreadyseen = tokpushback;725 int alreadyseen = psh->tokpushback; 725 726 #endif 726 727 struct alias *ap; 727 728 728 729 top: 729 t = xxreadtoken( );730 731 if ( checkkwd) {730 t = xxreadtoken(psh); 731 732 if (psh->checkkwd) { 732 733 /* 733 734 * eat newlines 734 735 */ 735 if ( checkkwd == 2) {736 checkkwd = 0;736 if (psh->checkkwd == 2) { 737 psh->checkkwd = 0; 737 738 while (t == TNL) { 738 parseheredoc( );739 t = xxreadtoken( );739 parseheredoc(psh); 740 t = xxreadtoken(psh); 740 741 } 741 742 } else 742 checkkwd = 0;743 psh->checkkwd = 0; 743 744 /* 744 745 * check for keywords and aliases 745 746 */ 746 if (t == TWORD && ! quoteflag)747 if (t == TWORD && !psh->quoteflag) 747 748 { 748 749 const char *const *pp; 749 750 750 751 for (pp = parsekwd; *pp; pp++) { 751 if (**pp == * wordtext && equal(*pp,wordtext))752 if (**pp == *psh->wordtext && equal(*pp, psh->wordtext)) 752 753 { 753 lasttoken = t =pp -754 parsekwd + KWDOFFSET ;754 psh->lasttoken = t = (int)(pp - 755 parsekwd + KWDOFFSET); 755 756 TRACE((psh, "keyword %s recognized\n", tokname[t])); 756 757 goto out; 757 758 } 758 759 } 759 if(! noalias &&760 (ap = lookupalias(psh, wordtext, 1)) != NULL) {760 if(!psh->noalias && 761 (ap = lookupalias(psh, psh->wordtext, 1)) != NULL) { 761 762 pushstring(psh, ap->val, strlen(ap->val), ap); 762 checkkwd = savecheckkwd;763 psh->checkkwd = savecheckkwd; 763 764 goto top; 764 765 } 765 766 } 766 767 out: 767 checkkwd = (t == TNOT) ? savecheckkwd : 0;768 psh->checkkwd = (t == TNOT) ? savecheckkwd : 0; 768 769 } 769 770 #ifdef DEBUG 770 771 if (!alreadyseen) 771 TRACE((psh, "token %s %s\n", tokname[t], t == TWORD ? wordtext : ""));772 TRACE((psh, "token %s %s\n", tokname[t], t == TWORD ? psh->wordtext : "")); 772 773 else 773 TRACE((psh, "reread token %s %s\n", tokname[t], t == TWORD ? wordtext : ""));774 TRACE((psh, "reread token %s %s\n", tokname[t], t == TWORD ? psh->wordtext : "")); 774 775 #endif 775 776 return (t); … … 779 780 /* 780 781 * Read the next input token. 781 * If the token is a word, we set backquotelist to the list of cmds in782 * backquotes. We set quoteflag to true if any part of the word was782 * If the token is a word, we set psh->backquotelist to the list of cmds in 783 * backquotes. We set psh->quoteflag to true if any part of the word was 783 784 * quoted. 784 * If the token is TREDIR, then we set redirnode to a structure containing785 * If the token is TREDIR, then we set psh->redirnode to a structure containing 785 786 * the redirection. 786 * In all cases, the variable startlinno is set to the number of the line787 * In all cases, the variable psh->startlinno is set to the number of the line 787 788 * on which the token starts. 788 789 * … … 795 796 */ 796 797 797 #define RETURN(token) return lasttoken = token798 #define RETURN(token) return psh->lasttoken = token 798 799 799 800 STATIC int 800 xxreadtoken( void)801 xxreadtoken(shinstance *psh) 801 802 { 802 803 int c; 803 804 804 if ( tokpushback) {805 tokpushback = 0;806 return lasttoken;807 } 808 if ( needprompt) {809 setprompt( 2);810 needprompt = 0;811 } 812 startlinno =plinno;805 if (psh->tokpushback) { 806 psh->tokpushback = 0; 807 return psh->lasttoken; 808 } 809 if (psh->needprompt) { 810 setprompt(psh, 2); 811 psh->needprompt = 0; 812 } 813 psh->startlinno = psh->plinno; 813 814 for (;;) { /* until token or start of word found */ 814 815 c = pgetc_macro(psh); … … 824 825 case '\\': 825 826 if (pgetc(psh) == '\n') { 826 startlinno = ++plinno;827 if ( doprompt)828 setprompt( 2);827 psh->startlinno = ++psh->plinno; 828 if (psh->doprompt) 829 setprompt(psh, 2); 829 830 else 830 setprompt( 0);831 setprompt(psh, 0); 831 832 continue; 832 833 } … … 834 835 goto breakloop; 835 836 case '\n': 836 p linno++;837 needprompt =doprompt;837 psh->plinno++; 838 psh->needprompt = psh->doprompt; 838 839 RETURN(TNL); 839 840 case PEOF: … … 863 864 } 864 865 breakloop: 865 return readtoken1( c, BASESYNTAX, (char *)NULL, 0);866 return readtoken1(psh, c, BASESYNTAX, (char *)NULL, 0); 866 867 #undef RETURN 867 868 } … … 911 912 912 913 STATIC int 913 readtoken1( int firstc, char const *syntax, char *eofmark, int striptabs)914 readtoken1(shinstance *psh, int firstc, char const *syntax, char *eofmark, int striptabs) 914 915 { 915 916 int c = firstc; … … 942 943 #endif 943 944 944 startlinno =plinno;945 psh->startlinno = psh->plinno; 945 946 dblquote = 0; 946 947 varnest = 0; … … 956 957 loop: { /* for each line, until end of word */ 957 958 #if ATTY 958 if (c == '\034' && doprompt959 if (c == '\034' && psh->doprompt 959 960 && attyset() && ! equal(termval(), "emacs")) { 960 961 attyline(); 961 962 if (syntax == BASESYNTAX) 962 return readtoken( );963 return readtoken(psh); 963 964 c = pgetc(psh); 964 965 goto loop; … … 973 974 goto endword; /* exit outer loop */ 974 975 USTPUTC(psh, c, out); 975 p linno++;976 if ( doprompt)977 setprompt( 2);976 psh->plinno++; 977 if (psh->doprompt) 978 setprompt(psh, 2); 978 979 else 979 setprompt( 0);980 setprompt(psh, 0); 980 981 c = pgetc(psh); 981 982 goto loop; /* continue outer loop */ … … 996 997 } 997 998 if (c == '\n') { 998 if ( doprompt)999 setprompt( 2);999 if (psh->doprompt) 1000 setprompt(psh, 2); 1000 1001 else 1001 setprompt( 0);1002 setprompt(psh, 0); 1002 1003 break; 1003 1004 } … … 1128 1129 endword: 1129 1130 if (syntax == ARISYNTAX) 1130 synerror( "Missing '))'");1131 if (syntax != BASESYNTAX && ! p arsebackquote && eofmark == NULL)1132 synerror( "Unterminated quoted string");1131 synerror(psh, "Missing '))'"); 1132 if (syntax != BASESYNTAX && ! psh->parsebackquote && eofmark == NULL) 1133 synerror(psh, "Unterminated quoted string"); 1133 1134 if (varnest != 0) { 1134 startlinno =plinno;1135 psh->startlinno = psh->plinno; 1135 1136 /* { */ 1136 synerror( "Missing '}'");1137 synerror(psh, "Missing '}'"); 1137 1138 } 1138 1139 USTPUTC(psh, '\0', out); 1139 len = out - stackblock(psh);1140 len = (int)(out - stackblock(psh)); 1140 1141 out = stackblock(psh); 1141 1142 if (eofmark == NULL) { … … 1145 1146 && (*out == '\0' || is_digit(*out))) { 1146 1147 PARSEREDIR(); 1147 return lasttoken = TREDIR;1148 return psh->lasttoken = TREDIR; 1148 1149 } else { 1149 1150 pungetc(psh); 1150 1151 } 1151 1152 } 1152 quoteflag = quotef;1153 backquotelist = bqlist;1153 psh->quoteflag = quotef; 1154 psh->backquotelist = bqlist; 1154 1155 grabstackblock(psh, len); 1155 wordtext = out;1156 psh->wordtext = out; 1156 1157 if (dblquotep != NULL) 1157 1158 ckfree(dblquotep); 1158 return lasttoken = TWORD;1159 return psh->lasttoken = TWORD; 1159 1160 /* end of readtoken routine */ 1160 1161 … … 1181 1182 if (*p == '\n' && *q == '\0') { 1182 1183 c = PEOF; 1183 p linno++;1184 needprompt =doprompt;1184 psh->plinno++; 1185 psh->needprompt = psh->doprompt; 1185 1186 } else { 1186 1187 pushstring(psh, line, strlen(line), NULL); … … 1226 1227 } 1227 1228 np->type = NHERE; 1228 heredoc = (struct heredoc *)stalloc(psh, sizeof (struct heredoc));1229 heredoc->here = np;1229 psh->heredoc = (struct heredoc *)stalloc(psh, sizeof (struct heredoc)); 1230 psh->heredoc->here = np; 1230 1231 if ((c = pgetc(psh)) == '-') { 1231 heredoc->striptabs = 1;1232 psh->heredoc->striptabs = 1; 1232 1233 } else { 1233 heredoc->striptabs = 0;1234 psh->heredoc->striptabs = 0; 1234 1235 pungetc(psh); 1235 1236 } … … 1252 1253 if (fd != '\0') 1253 1254 np->nfile.fd = digit_val(fd); 1254 redirnode = np;1255 psh->redirnode = np; 1255 1256 goto parseredir_return; 1256 1257 } … … 1282 1283 } else { 1283 1284 USTPUTC(psh, CTLVAR, out); 1284 typeloc = out - stackblock(psh);1285 typeloc = (int)(out - stackblock(psh)); 1285 1286 USTPUTC(psh, VSNORMAL, out); 1286 1287 subtype = VSNORMAL; … … 1312 1313 } 1313 1314 else 1314 badsub: synerror( "Bad substitution");1315 badsub: synerror(psh, "Bad substitution"); 1315 1316 1316 1317 STPUTC(psh, '=', out); … … 1326 1327 if (p == NULL) 1327 1328 goto badsub; 1328 subtype = p - types + VSNORMAL;1329 subtype = (int)(p - types + VSNORMAL); 1329 1330 break; 1330 1331 case '%': … … 1381 1382 #endif 1382 1383 1383 savepbq = p arsebackquote;1384 savepbq = psh->parsebackquote; 1384 1385 if (setjmp(jmploc.loc)) { 1385 1386 if (str) 1386 1387 ckfree(str); 1387 p arsebackquote = 0;1388 psh->parsebackquote = 0; 1388 1389 psh->handler = savehandler; 1389 1390 longjmp(psh->handler->loc, 1); … … 1391 1392 INTOFF; 1392 1393 str = NULL; 1393 savelen = out - stackblock(psh);1394 savelen = (int)(out - stackblock(psh)); 1394 1395 if (savelen > 0) { 1395 1396 str = ckmalloc(savelen); … … 1411 1412 STARTSTACKSTR(psh, pout); 1412 1413 for (;;) { 1413 if ( needprompt) {1414 setprompt( 2);1415 needprompt = 0;1414 if (psh->needprompt) { 1415 setprompt(psh, 2); 1416 psh->needprompt = 0; 1416 1417 } 1417 1418 switch (pc = pgetc(psh)) { … … 1421 1422 case '\\': 1422 1423 if ((pc = pgetc(psh)) == '\n') { 1423 p linno++;1424 if ( doprompt)1425 setprompt( 2);1424 psh->plinno++; 1425 if (psh->doprompt) 1426 setprompt(psh, 2); 1426 1427 else 1427 setprompt( 0);1428 setprompt(psh, 0); 1428 1429 /* 1429 1430 * If eating a newline, avoid putting … … 1440 1441 1441 1442 case '\n': 1442 p linno++;1443 needprompt =doprompt;1443 psh->plinno++; 1444 psh->needprompt = psh->doprompt; 1444 1445 break; 1445 1446 1446 1447 case PEOF: 1447 startlinno =plinno;1448 synerror( "EOF in backquote substitution");1448 psh->startlinno = psh->plinno; 1449 synerror(psh, "EOF in backquote substitution"); 1449 1450 break; 1450 1451 … … 1456 1457 done: 1457 1458 STPUTC(psh, '\0', pout); 1458 psavelen = pout - stackblock(psh);1459 psavelen = (int)(pout - stackblock(psh)); 1459 1460 if (psavelen > 0) { 1460 1461 pstr = grabstackstr(psh, pout); … … 1467 1468 *nlpp = (struct nodelist *)stalloc(psh, sizeof (struct nodelist)); 1468 1469 (*nlpp)->next = NULL; 1469 p arsebackquote = oldstyle;1470 psh->parsebackquote = oldstyle; 1470 1471 1471 1472 if (oldstyle) { 1472 saveprompt = doprompt;1473 doprompt = 0;1474 } 1475 1476 n = list( 0);1473 saveprompt = psh->doprompt; 1474 psh->doprompt = 0; 1475 } 1476 1477 n = list(psh, 0); 1477 1478 1478 1479 if (oldstyle) 1479 doprompt = saveprompt;1480 psh->doprompt = saveprompt; 1480 1481 else { 1481 if (readtoken( ) != TRP)1482 synexpect( TRP);1482 if (readtoken(psh) != TRP) 1483 synexpect(psh, TRP); 1483 1484 } 1484 1485 … … 1490 1491 */ 1491 1492 popfile(psh); 1492 tokpushback = 0;1493 psh->tokpushback = 0; 1493 1494 } 1494 1495 while (stackblocksize(psh) <= savelen) … … 1503 1504 INTON; 1504 1505 } 1505 p arsebackquote = savepbq;1506 psh->parsebackquote = savepbq; 1506 1507 psh->handler = savehandler; 1507 1508 if (arinest || ISDBLQUOTE()) … … 1544 1545 #ifdef mkinit 1545 1546 RESET { 1546 tokpushback = 0;1547 checkkwd = 0;1547 psh->tokpushback = 0; 1548 psh->checkkwd = 0; 1548 1549 } 1549 1550 #endif … … 1555 1556 1556 1557 STATIC int 1557 noexpand( char *text)1558 noexpand(shinstance *psh, char *text) 1558 1559 { 1559 1560 char *p; … … 1579 1580 1580 1581 int 1581 goodname(c har *name)1582 1583 c har *p;1582 goodname(const char *name) 1583 { 1584 const char *p; 1584 1585 1585 1586 p = name; … … 1601 1602 1602 1603 STATIC void 1603 synexpect( int token)1604 synexpect(shinstance *psh, int token) 1604 1605 { 1605 1606 char msg[64]; … … 1607 1608 if (token >= 0) { 1608 1609 fmtstr(msg, 64, "%s unexpected (expecting %s)", 1609 tokname[ lasttoken], tokname[token]);1610 tokname[psh->lasttoken], tokname[token]); 1610 1611 } else { 1611 fmtstr(msg, 64, "%s unexpected", tokname[ lasttoken]);1612 } 1613 synerror( msg);1612 fmtstr(msg, 64, "%s unexpected", tokname[psh->lasttoken]); 1613 } 1614 synerror(psh, msg); 1614 1615 /* NOTREACHED */ 1615 1616 } … … 1617 1618 1618 1619 STATIC void 1619 synerror( const char *msg)1620 { 1621 if ( commandname)1622 outfmt(&psh->errout, "%s: %d: ", commandname,startlinno);1620 synerror(shinstance *psh, const char *msg) 1621 { 1622 if (psh->commandname) 1623 outfmt(&psh->errout, "%s: %d: ", psh->commandname, psh->startlinno); 1623 1624 outfmt(&psh->errout, "Syntax error: %s\n", msg); 1624 1625 error(psh, (char *)NULL); … … 1627 1628 1628 1629 STATIC void 1629 setprompt( int which)1630 setprompt(shinstance *psh, int which) 1630 1631 { 1631 1632 psh->whichprompt = which; … … 1634 1635 if (!el) 1635 1636 #endif 1636 out2str( getprompt(NULL));1637 out2str(psh, getprompt(psh, NULL)); 1637 1638 } 1638 1639 … … 1642 1643 */ 1643 1644 const char * 1644 getprompt( void *unused)1645 1645 getprompt(shinstance *psh, void *unused) 1646 { 1646 1647 switch (psh->whichprompt) { 1647 1648 case 0: 1648 1649 return ""; 1649 1650 case 1: 1650 return ps1val( );1651 return ps1val(psh); 1651 1652 case 2: 1652 return ps2val( );1653 return ps2val(psh); 1653 1654 default: 1654 1655 return "<internal prompt error>";
Note:
See TracChangeset
for help on using the changeset viewer.