1 /*********************************************************************** 2 * * 3 * This software is part of the ast package * 4 * Copyright (c) 1982-2009 AT&T Intellectual Property * 5 * and is licensed under the * 6 * Common Public License, Version 1.0 * 7 * by AT&T Intellectual Property * 8 * * 9 * A copy of the License is available at * 10 * http://www.opensource.org/licenses/cpl1.0.txt * 11 * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) * 12 * * 13 * Information and Software Systems Research * 14 * AT&T Research * 15 * Florham Park NJ * 16 * * 17 * David Korn <dgk@research.att.com> * 18 * * 19 ***********************************************************************/ 20 #pragma prototyped 21 /* 22 * UNIX shell 23 * 24 * S. R. Bourne 25 * Rewritten by David Korn 26 * AT&T Labs 27 * 28 * This is the parser for a shell language 29 */ 30 31 #if KSHELL 32 #include "defs.h" 33 #else 34 #include <shell.h> 35 #include <ctype.h> 36 #endif 37 #include <fcin.h> 38 #include <error.h> 39 #include "shlex.h" 40 #include "history.h" 41 #include "builtins.h" 42 #include "test.h" 43 #include "history.h" 44 45 #define HERE_MEM 1024 /* size of here-docs kept in memory */ 46 47 #define hash nvlink.hl._hash 48 49 /* These routines are local to this module */ 50 51 static Shnode_t *makeparent(Lex_t*, int, Shnode_t*); 52 static Shnode_t *makelist(Lex_t*, int, Shnode_t*, Shnode_t*); 53 static struct argnod *qscan(struct comnod*, int); 54 static struct ionod *inout(Lex_t*,struct ionod*, int); 55 static Shnode_t *sh_cmd(Lex_t*,int,int); 56 static Shnode_t *term(Lex_t*,int); 57 static Shnode_t *list(Lex_t*,int); 58 static struct regnod *syncase(Lex_t*,int); 59 static Shnode_t *item(Lex_t*,int); 60 static Shnode_t *simple(Lex_t*,int, struct ionod*); 61 static int skipnl(Lex_t*,int); 62 static Shnode_t *test_expr(Lex_t*,int); 63 static Shnode_t *test_and(Lex_t*); 64 static Shnode_t *test_or(Lex_t*); 65 static Shnode_t *test_primary(Lex_t*); 66 67 #define sh_getlineno(lp) (lp->lastline) 68 69 #ifndef NIL 70 # define NIL(type) ((type)0) 71 #endif /* NIL */ 72 #define CNTL(x) ((x)&037) 73 74 75 #if !KSHELL 76 static struct stdata 77 { 78 struct slnod *staklist; 79 int cmdline; 80 } st; 81 #endif 82 83 static int opt_get; 84 static int loop_level; 85 static struct argnod *label_list; 86 static struct argnod *label_last; 87 88 #define getnode(type) ((Shnode_t*)stakalloc(sizeof(struct type))) 89 90 #if SHOPT_KIA 91 #include "path.h" 92 /* 93 * write out entities for each item in the list 94 * type=='V' for variable assignment lists 95 * Otherwise type is determined by the command */ 96 static unsigned long writedefs(Lex_t *lexp,struct argnod *arglist, int line, int type, struct argnod *cmd) 97 { 98 register struct argnod *argp = arglist; 99 register char *cp; 100 register int n,eline; 101 int width=0; 102 unsigned long r=0; 103 static char atbuff[20]; 104 int justify=0; 105 char *attribute = atbuff; 106 unsigned long parent=lexp->script; 107 if(type==0) 108 { 109 parent = lexp->current; 110 type = 'v'; 111 switch(*argp->argval) 112 { 113 case 'a': 114 type='p'; 115 justify = 'a'; 116 break; 117 case 'e': 118 *attribute++ = 'x'; 119 break; 120 case 'r': 121 *attribute++ = 'r'; 122 break; 123 case 'l': 124 break; 125 } 126 while(argp = argp->argnxt.ap) 127 { 128 if((n= *(cp=argp->argval))!='-' && n!='+') 129 break; 130 if(cp[1]==n) 131 break; 132 while((n= *++cp)) 133 { 134 if(isdigit(n)) 135 width = 10*width + n-'0'; 136 else if(n=='L' || n=='R' || n =='Z') 137 justify=n; 138 else 139 *attribute++ = n; 140 } 141 } 142 } 143 else if(cmd) 144 parent=kiaentity(lexp,sh_argstr(cmd),-1,'p',-1,-1,lexp->unknown,'b',0,""); 145 *attribute = 0; 146 while(argp) 147 { 148 if((cp=strchr(argp->argval,'='))||(cp=strchr(argp->argval,'?'))) 149 n = cp-argp->argval; 150 else 151 n = strlen(argp->argval); 152 eline = lexp->sh->inlineno-(lexp->token==NL); 153 r=kiaentity(lexp,argp->argval,n,type,line,eline,parent,justify,width,atbuff); 154 sfprintf(lexp->kiatmp,"p;%..64d;v;%..64d;%d;%d;s;\n",lexp->current,r,line,eline); 155 argp = argp->argnxt.ap; 156 } 157 return(r); 158 } 159 #endif /* SHOPT_KIA */ 160 161 static void typeset_order(const char *str,int line) 162 { 163 register int c,n=0; 164 unsigned const char *cp=(unsigned char*)str; 165 static unsigned char *table; 166 if(*cp!='+' && *cp!='-') 167 return; 168 if(!table) 169 { 170 table = calloc(1,256); 171 for(cp=(unsigned char*)"bflmnprstuxACHS";c = *cp; cp++) 172 table[c] = 1; 173 for(cp=(unsigned char*)"aiEFLRXhTZ";c = *cp; cp++) 174 table[c] = 2; 175 for(c='0'; c <='9'; c++) 176 table[c] = 3; 177 } 178 for(cp=(unsigned char*)str; c= *cp++; n=table[c]) 179 { 180 if(table[c] < n) 181 errormsg(SH_DICT,ERROR_warn(0),e_lextypeset,line,str); 182 } 183 } 184 185 /* 186 * add type definitions when compiling with -n 187 */ 188 static void check_typedef(struct comnod *tp) 189 { 190 char *cp=0; 191 if(tp->comtyp&COMSCAN) 192 { 193 struct argnod *ap = tp->comarg; 194 while(ap = ap->argnxt.ap) 195 { 196 if(!(ap->argflag&ARG_RAW) || memcmp(ap->argval,"--",2)) 197 break; 198 if(sh_isoption(SH_NOEXEC)) 199 typeset_order(ap->argval,tp->comline); 200 if(memcmp(ap->argval,"-T",2)==0) 201 { 202 if(ap->argval[2]) 203 cp = ap->argval+2; 204 else if((ap->argnxt.ap)->argflag&ARG_RAW) 205 cp = (ap->argnxt.ap)->argval; 206 if(cp) 207 break; 208 } 209 } 210 } 211 else 212 { 213 struct dolnod *dp = (struct dolnod*)tp->comarg; 214 char **argv = dp->dolval + dp->dolbot+1; 215 while((cp= *argv++) && memcmp(cp,"--",2)) 216 { 217 if(sh_isoption(SH_NOEXEC)) 218 typeset_order(cp,tp->comline); 219 if(memcmp(cp,"-T",2)==0) 220 { 221 if(cp[2]) 222 cp = cp+2; 223 else 224 cp = *argv; 225 break; 226 } 227 } 228 } 229 if(cp) 230 { 231 Namval_t *mp=(Namval_t*)tp->comnamp ,*bp; 232 bp = sh_addbuiltin(cp,mp->nvalue.bfp, (void*)0); 233 nv_onattr(bp,nv_isattr(mp,NV_PUBLIC)); 234 } 235 } 236 237 /* 238 * Make a parent node for fork() or io-redirection 239 */ 240 static Shnode_t *makeparent(Lex_t *lp, int flag, Shnode_t *child) 241 { 242 register Shnode_t *par = getnode(forknod); 243 par->fork.forktyp = flag; 244 par->fork.forktre = child; 245 par->fork.forkio = 0; 246 par->fork.forkline = sh_getlineno(lp)-1; 247 return(par); 248 } 249 250 static Shnode_t *getanode(Lex_t *lp, struct argnod *ap) 251 { 252 register Shnode_t *t = getnode(arithnod); 253 t->ar.artyp = TARITH; 254 t->ar.arline = sh_getlineno(lp); 255 t->ar.arexpr = ap; 256 if(ap->argflag&ARG_RAW) 257 t->ar.arcomp = sh_arithcomp(ap->argval); 258 else 259 t->ar.arcomp = 0; 260 return(t); 261 } 262 263 /* 264 * Make a node corresponding to a command list 265 */ 266 static Shnode_t *makelist(Lex_t *lexp, int type, Shnode_t *l, Shnode_t *r) 267 { 268 register Shnode_t *t; 269 if(!l || !r) 270 sh_syntax(lexp); 271 else 272 { 273 if((type&COMMSK) == TTST) 274 t = getnode(tstnod); 275 else 276 t = getnode(lstnod); 277 t->lst.lsttyp = type; 278 t->lst.lstlef = l; 279 t->lst.lstrit = r; 280 } 281 return(t); 282 } 283 284 /* 285 * entry to shell parser 286 * Flag can be the union of SH_EOF|SH_NL 287 */ 288 289 void *sh_parse(Shell_t *shp, Sfio_t *iop, int flag) 290 { 291 register Shnode_t *t; 292 Lex_t *lexp = (Lex_t*)shp->lex_context; 293 Fcin_t sav_input; 294 struct argnod *sav_arg = lexp->arg; 295 int sav_prompt = shp->nextprompt; 296 if(shp->binscript && (sffileno(iop)==shp->infd || (flag&SH_FUNEVAL))) 297 return((void*)sh_trestore(shp,iop)); 298 fcsave(&sav_input); 299 shp->st.staklist = 0; 300 lexp->heredoc = 0; 301 lexp->inlineno = shp->inlineno; 302 lexp->firstline = shp->st.firstline; 303 shp->nextprompt = 1; 304 loop_level = 0; 305 label_list = label_last = 0; 306 if(sh_isoption(SH_INTERACTIVE)) 307 sh_onstate(SH_INTERACTIVE); 308 if(sh_isoption(SH_VERBOSE)) 309 sh_onstate(SH_VERBOSE); 310 sh_lexopen(lexp,shp,0); 311 if(fcfopen(iop) < 0) 312 return(NIL(void*)); 313 if(fcfile()) 314 { 315 char *cp = fcfirst(); 316 if( cp[0]==CNTL('k') && cp[1]==CNTL('s') && cp[2]==CNTL('h') && cp[3]==0) 317 { 318 int version; 319 fcseek(4); 320 fcgetc(version); 321 fcclose(); 322 fcrestore(&sav_input); 323 lexp->arg = sav_arg; 324 if(version > 3) 325 errormsg(SH_DICT,ERROR_exit(1),e_lexversion); 326 if(sffileno(iop)==shp->infd || (flag&SH_FUNEVAL)) 327 shp->binscript = 1; 328 sfgetc(iop); 329 return((void*)sh_trestore(shp,iop)); 330 } 331 } 332 flag &= ~SH_FUNEVAL; 333 if((flag&SH_NL) && (shp->inlineno=error_info.line+shp->st.firstline)==0) 334 shp->inlineno=1; 335 #if KSHELL 336 shp->nextprompt = 2; 337 #endif 338 t = sh_cmd(lexp,(flag&SH_EOF)?EOFSYM:'\n',SH_SEMI|SH_EMPTY|(flag&SH_NL)); 339 fcclose(); 340 fcrestore(&sav_input); 341 lexp->arg = sav_arg; 342 /* unstack any completed alias expansions */ 343 if((sfset(iop,0,0)&SF_STRING) && !sfreserve(iop,0,-1)) 344 { 345 Sfio_t *sp = sfstack(iop,NULL); 346 if(sp) 347 sfclose(sp); 348 } 349 shp->nextprompt = sav_prompt; 350 if(flag&SH_NL) 351 { 352 shp->st.firstline = lexp->firstline; 353 shp->inlineno = lexp->inlineno; 354 } 355 stkseek(shp->stk,0); 356 return((void*)t); 357 } 358 359 /* 360 * This routine parses up the matching right parenthesis and returns 361 * the parse tree 362 */ 363 Shnode_t *sh_dolparen(Lex_t* lp) 364 { 365 register Shnode_t *t=0; 366 Sfio_t *sp = fcfile(); 367 int line = lp->sh->inlineno; 368 lp->sh->inlineno = error_info.line+lp->sh->st.firstline; 369 sh_lexopen(lp,lp->sh,1); 370 lp->comsub = 1; 371 switch(sh_lex(lp)) 372 { 373 /* ((...)) arithmetic expression */ 374 case EXPRSYM: 375 t = getanode(lp,lp->arg); 376 break; 377 case LPAREN: 378 t = sh_cmd(lp,RPAREN,SH_NL|SH_EMPTY); 379 break; 380 case LBRACE: 381 t = sh_cmd(lp,RBRACE,SH_NL|SH_EMPTY); 382 break; 383 } 384 lp->comsub = 0; 385 if(!sp && (sp=fcfile())) 386 { 387 /* 388 * This code handles the case where string has been converted 389 * to a file by an alias setup 390 */ 391 register int c; 392 char *cp; 393 if(fcgetc(c) > 0) 394 fcseek(-1); 395 cp = fcseek(0); 396 fcclose(); 397 fcsopen(cp); 398 sfclose(sp); 399 } 400 lp->sh->inlineno = line; 401 return(t); 402 } 403 404 /* 405 * remove temporary files and stacks 406 */ 407 408 void sh_freeup(Shell_t *shp) 409 { 410 if(shp->st.staklist) 411 sh_funstaks(shp->st.staklist,-1); 412 shp->st.staklist = 0; 413 } 414 415 /* 416 * increase reference count for each stack in function list when flag>0 417 * decrease reference count for each stack in function list when flag<=0 418 * stack is freed when reference count is zero 419 */ 420 421 void sh_funstaks(register struct slnod *slp,int flag) 422 { 423 register struct slnod *slpold; 424 while(slpold=slp) 425 { 426 if(slp->slchild) 427 sh_funstaks(slp->slchild,flag); 428 slp = slp->slnext; 429 if(flag<=0) 430 stakdelete(slpold->slptr); 431 else 432 staklink(slpold->slptr); 433 } 434 } 435 /* 436 * cmd 437 * empty 438 * list 439 * list & [ cmd ] 440 * list [ ; cmd ] 441 */ 442 443 static Shnode_t *sh_cmd(Lex_t *lexp, register int sym, int flag) 444 { 445 register Shnode_t *left, *right; 446 register int type = FINT|FAMP; 447 if(sym==NL) 448 lexp->lasttok = 0; 449 left = list(lexp,flag); 450 if(lexp->token==NL) 451 { 452 if(flag&SH_NL) 453 lexp->token=';'; 454 } 455 else if(!left && !(flag&SH_EMPTY)) 456 sh_syntax(lexp); 457 switch(lexp->token) 458 { 459 case COOPSYM: /* set up a cooperating process */ 460 type |= (FPIN|FPOU|FPCL|FCOOP); 461 /* FALL THRU */ 462 case '&': 463 if(left) 464 { 465 /* (...)& -> {...;} & */ 466 if(left->tre.tretyp==TPAR) 467 left = left->par.partre; 468 left = makeparent(lexp,TFORK|type, left); 469 } 470 /* FALL THRU */ 471 case ';': 472 if(!left) 473 sh_syntax(lexp); 474 if(right=sh_cmd(lexp,sym,flag|SH_EMPTY)) 475 left=makelist(lexp,TLST, left, right); 476 break; 477 case EOFSYM: 478 if(sym==NL) 479 break; 480 default: 481 if(sym && sym!=lexp->token) 482 { 483 if(sym!=ELSESYM || (lexp->token!=ELIFSYM && lexp->token!=FISYM)) 484 sh_syntax(lexp); 485 } 486 } 487 return(left); 488 } 489 490 /* 491 * list 492 * term 493 * list && term 494 * list || term 495 * unfortunately, these are equal precedence 496 */ 497 static Shnode_t *list(Lex_t *lexp, register int flag) 498 { 499 register Shnode_t *t = term(lexp,flag); 500 register int token; 501 while(t && ((token=lexp->token)==ANDFSYM || token==ORFSYM)) 502 t = makelist(lexp,(token==ANDFSYM?TAND:TORF), t, term(lexp,SH_NL|SH_SEMI)); 503 return(t); 504 } 505 506 /* 507 * term 508 * item 509 * item | term 510 */ 511 static Shnode_t *term(Lex_t *lexp,register int flag) 512 { 513 register Shnode_t *t; 514 register int token; 515 if(flag&SH_NL) 516 token = skipnl(lexp,flag); 517 else 518 token = sh_lex(lexp); 519 /* check to see if pipeline is to be timed */ 520 if(token==TIMESYM || token==NOTSYM) 521 { 522 t = getnode(parnod); 523 t->par.partyp=TTIME; 524 if(lexp->token==NOTSYM) 525 t->par.partyp |= COMSCAN; 526 t->par.partre = term(lexp,0); 527 } 528 else if((t=item(lexp,SH_NL|SH_EMPTY|(flag&SH_SEMI))) && lexp->token=='|') 529 { 530 register Shnode_t *tt; 531 int showme = t->tre.tretyp&FSHOWME; 532 t = makeparent(lexp,TFORK|FPOU,t); 533 if(tt=term(lexp,SH_NL)) 534 { 535 switch(tt->tre.tretyp&COMMSK) 536 { 537 case TFORK: 538 tt->tre.tretyp |= FPIN|FPCL; 539 break; 540 case TFIL: 541 tt->lst.lstlef->tre.tretyp |= FPIN|FPCL; 542 break; 543 default: 544 tt= makeparent(lexp,TSETIO|FPIN|FPCL,tt); 545 } 546 t=makelist(lexp,TFIL,t,tt); 547 t->tre.tretyp |= showme; 548 } 549 else if(lexp->token) 550 sh_syntax(lexp); 551 } 552 return(t); 553 } 554 555 /* 556 * case statement 557 */ 558 static struct regnod* syncase(Lex_t *lexp,register int esym) 559 { 560 register int tok = skipnl(lexp,0); 561 register struct regnod *r; 562 if(tok==esym) 563 return(NIL(struct regnod*)); 564 r = (struct regnod*)stakalloc(sizeof(struct regnod)); 565 r->regptr=0; 566 r->regflag=0; 567 if(tok==LPAREN) 568 skipnl(lexp,0); 569 while(1) 570 { 571 if(!lexp->arg) 572 sh_syntax(lexp); 573 lexp->arg->argnxt.ap=r->regptr; 574 r->regptr = lexp->arg; 575 if((tok=sh_lex(lexp))==RPAREN) 576 break; 577 else if(tok=='|') 578 sh_lex(lexp); 579 else 580 sh_syntax(lexp); 581 } 582 r->regcom=sh_cmd(lexp,0,SH_NL|SH_EMPTY|SH_SEMI); 583 if((tok=lexp->token)==BREAKCASESYM) 584 r->regnxt=syncase(lexp,esym); 585 else if(tok==FALLTHRUSYM) 586 { 587 r->regflag++; 588 r->regnxt=syncase(lexp,esym); 589 } 590 else 591 { 592 if(tok!=esym && tok!=EOFSYM) 593 sh_syntax(lexp); 594 r->regnxt=0; 595 } 596 if(lexp->token==EOFSYM) 597 return(NIL(struct regnod*)); 598 return(r); 599 } 600 601 /* 602 * This routine creates the parse tree for the arithmetic for 603 * When called, shlex.arg contains the string inside ((...)) 604 * When the first argument is missing, a while node is returned 605 * Otherise a list containing an arithmetic command and a while 606 * is returned. 607 */ 608 static Shnode_t *arithfor(Lex_t *lexp,register Shnode_t *tf) 609 { 610 register Shnode_t *t, *tw = tf; 611 register int offset; 612 register struct argnod *argp; 613 register int n; 614 Stk_t *stkp = lexp->sh->stk; 615 int argflag = lexp->arg->argflag; 616 /* save current input */ 617 Fcin_t sav_input; 618 fcsave(&sav_input); 619 fcsopen(lexp->arg->argval); 620 /* split ((...)) into three expressions */ 621 for(n=0; ; n++) 622 { 623 register int c; 624 argp = (struct argnod*)stkseek(stkp,ARGVAL); 625 argp->argnxt.ap = 0; 626 argp->argchn.cp = 0; 627 argp->argflag = argflag; 628 if(n==2) 629 break; 630 /* copy up to ; onto the stack */ 631 sh_lexskip(lexp,';',1,ST_NESTED); 632 offset = stktell(stkp)-1; 633 if((c=fcpeek(-1))!=';') 634 break; 635 /* remove trailing white space */ 636 while(offset>ARGVAL && ((c= *stkptr(stkp,offset-1)),isspace(c))) 637 offset--; 638 /* check for empty initialization expression */ 639 if(offset==ARGVAL && n==0) 640 continue; 641 stkseek(stkp,offset); 642 /* check for empty condition and treat as while((1)) */ 643 if(offset==ARGVAL) 644 sfputc(stkp,'1'); 645 argp = (struct argnod*)stkfreeze(stkp,1); 646 t = getanode(lexp,argp); 647 if(n==0) 648 tf = makelist(lexp,TLST,t,tw); 649 else 650 tw->wh.whtre = t; 651 } 652 while((offset=fcpeek(0)) && isspace(offset)) 653 fcseek(1); 654 stakputs(fcseek(0)); 655 argp = (struct argnod*)stakfreeze(1); 656 fcrestore(&sav_input); 657 if(n<2) 658 { 659 lexp->token = RPAREN|SYMREP; 660 sh_syntax(lexp); 661 } 662 /* check whether the increment is present */ 663 if(*argp->argval) 664 { 665 t = getanode(lexp,argp); 666 tw->wh.whinc = (struct arithnod*)t; 667 } 668 else 669 tw->wh.whinc = 0; 670 sh_lexopen(lexp, lexp->sh,1); 671 if((n=sh_lex(lexp))==NL) 672 n = skipnl(lexp,0); 673 else if(n==';') 674 n = sh_lex(lexp); 675 if(n!=DOSYM && n!=LBRACE) 676 sh_syntax(lexp); 677 tw->wh.dotre = sh_cmd(lexp,n==DOSYM?DONESYM:RBRACE,SH_NL); 678 tw->wh.whtyp = TWH; 679 return(tf); 680 681 } 682 683 static Shnode_t *funct(Lex_t *lexp) 684 { 685 Shell_t *shp = lexp->sh; 686 register Shnode_t *t; 687 register int flag; 688 struct slnod *volatile slp=0; 689 Stak_t *savstak; 690 Sfoff_t first, last; 691 struct functnod *volatile fp; 692 Sfio_t *iop; 693 #if SHOPT_KIA 694 unsigned long current = lexp->current; 695 #endif /* SHOPT_KIA */ 696 int jmpval, saveloop=loop_level; 697 struct argnod *savelabel = label_last; 698 struct checkpt buff; 699 int save_optget = opt_get; 700 void *in_mktype = shp->mktype; 701 shp->mktype = 0; 702 opt_get = 0; 703 t = getnode(functnod); 704 t->funct.functline = shp->inlineno; 705 t->funct.functtyp=TFUN; 706 t->funct.functargs = 0; 707 if(!(flag = (lexp->token==FUNCTSYM))) 708 t->funct.functtyp |= FPOSIX; 709 else if(sh_lex(lexp)) 710 sh_syntax(lexp); 711 if(!(iop=fcfile())) 712 { 713 iop = sfopen(NIL(Sfio_t*),fcseek(0),"s"); 714 fcclose(); 715 fcfopen(iop); 716 } 717 t->funct.functloc = first = fctell(); 718 if(!shp->st.filename || sffileno(iop)<0) 719 { 720 if(fcfill() >= 0) 721 fcseek(-1); 722 if(sh_isstate(SH_HISTORY) && shp->hist_ptr) 723 t->funct.functloc = sfseek(shp->hist_ptr->histfp,(off_t)0,SEEK_CUR); 724 else 725 { 726 /* copy source to temporary file */ 727 t->funct.functloc = 0; 728 if(lexp->sh->heredocs) 729 t->funct.functloc = sfseek(lexp->sh->heredocs,(Sfoff_t)0, SEEK_END); 730 else 731 lexp->sh->heredocs = sftmp(HERE_MEM); 732 lexp->sh->funlog = lexp->sh->heredocs; 733 t->funct.functtyp |= FPIN; 734 } 735 } 736 t->funct.functnam= (char*)lexp->arg->argval; 737 #if SHOPT_KIA 738 if(lexp->kiafile) 739 lexp->current = kiaentity(lexp,t->funct.functnam,-1,'p',-1,-1,lexp->script,'p',0,""); 740 #endif /* SHOPT_KIA */ 741 if(flag) 742 { 743 lexp->token = sh_lex(lexp); 744 #if SHOPT_BASH 745 if(lexp->token == LPAREN) 746 { 747 if((lexp->token = sh_lex(lexp)) == RPAREN) 748 t->funct.functtyp |= FPOSIX; 749 else 750 sh_syntax(lexp); 751 } 752 #endif 753 } 754 if(t->funct.functtyp&FPOSIX) 755 skipnl(lexp,0); 756 else 757 { 758 if(lexp->token==0) 759 t->funct.functargs = (struct comnod*)simple(lexp,SH_NOIO|SH_FUNDEF,NIL(struct ionod*)); 760 while(lexp->token==NL) 761 lexp->token = sh_lex(lexp); 762 } 763 if((flag && lexp->token!=LBRACE) || lexp->token==EOFSYM) 764 sh_syntax(lexp); 765 sh_pushcontext(&buff,1); 766 jmpval = sigsetjmp(buff.buff,0); 767 if(jmpval == 0) 768 { 769 /* create a new stak frame to compile the command */ 770 savstak = stakcreate(STAK_SMALL); 771 savstak = stakinstall(savstak, 0); 772 slp = (struct slnod*)stakalloc(sizeof(struct slnod)+sizeof(struct functnod)); 773 slp->slchild = 0; 774 slp->slnext = shp->st.staklist; 775 shp->st.staklist = 0; 776 t->funct.functstak = (struct slnod*)slp; 777 /* 778 * store the pathname of function definition file on stack 779 * in name field of fake for node 780 */ 781 fp = (struct functnod*)(slp+1); 782 fp->functtyp = TFUN|FAMP; 783 fp->functnam = 0; 784 fp->functline = t->funct.functline; 785 if(shp->st.filename) 786 fp->functnam = stakcopy(shp->st.filename); 787 loop_level = 0; 788 label_last = label_list; 789 if(!flag && lexp->token==0) 790 { 791 /* copy current word token to current stak frame */ 792 struct argnod *ap; 793 flag = ARGVAL + strlen(lexp->arg->argval); 794 ap = (struct argnod*)stakalloc(flag); 795 memcpy(ap,lexp->arg,flag); 796 lexp->arg = ap; 797 } 798 t->funct.functtre = item(lexp,SH_NOIO); 799 } 800 sh_popcontext(&buff); 801 loop_level = saveloop; 802 label_last = savelabel; 803 /* restore the old stack */ 804 if(slp) 805 { 806 slp->slptr = stakinstall(savstak,0); 807 slp->slchild = shp->st.staklist; 808 } 809 #if SHOPT_KIA 810 lexp->current = current; 811 #endif /* SHOPT_KIA */ 812 if(jmpval) 813 { 814 if(slp && slp->slptr) 815 { 816 shp->st.staklist = slp->slnext; 817 stakdelete(slp->slptr); 818 } 819 siglongjmp(*shp->jmplist,jmpval); 820 } 821 shp->st.staklist = (struct slnod*)slp; 822 last = fctell(); 823 fp->functline = (last-first); 824 fp->functtre = t; 825 shp->mktype = in_mktype; 826 if(lexp->sh->funlog) 827 { 828 if(fcfill()>0) 829 fcseek(-1); 830 lexp->sh->funlog = 0; 831 } 832 #if SHOPT_KIA 833 if(lexp->kiafile) 834 kiaentity(lexp,t->funct.functnam,-1,'p',t->funct.functline,shp->inlineno-1,lexp->current,'p',0,""); 835 #endif /* SHOPT_KIA */ 836 t->funct.functtyp |= opt_get; 837 opt_get = save_optget; 838 return(t); 839 } 840 841 /* 842 * Compound assignment 843 */ 844 static struct argnod *assign(Lex_t *lexp, register struct argnod *ap, int tdef) 845 { 846 register int n; 847 register Shnode_t *t, **tp; 848 register struct comnod *ac; 849 Stk_t *stkp = lexp->sh->stk; 850 int array=0; 851 Namval_t *np; 852 n = strlen(ap->argval)-1; 853 if(ap->argval[n]!='=') 854 sh_syntax(lexp); 855 if(ap->argval[n-1]=='+') 856 { 857 ap->argval[n--]=0; 858 array = ARG_APPEND; 859 } 860 /* shift right */ 861 while(n > 0) 862 { 863 ap->argval[n] = ap->argval[n-1]; 864 n--; 865 } 866 *ap->argval=0; 867 t = getnode(fornod); 868 t->for_.fornam = (char*)(ap->argval+1); 869 t->for_.fortyp = sh_getlineno(lexp); 870 tp = &t->for_.fortre; 871 ap->argchn.ap = (struct argnod*)t; 872 ap->argflag &= ARG_QUOTED; 873 ap->argflag |= array; 874 lexp->assignok = SH_ASSIGN; 875 lexp->aliasok = 1; 876 array=0; 877 if((n=skipnl(lexp,0))==RPAREN || n==LPAREN) 878 { 879 int index= 0; 880 struct argnod **settail; 881 ac = (struct comnod*)getnode(comnod); 882 settail= &ac->comset; 883 memset((void*)ac,0,sizeof(*ac)); 884 ac->comline = sh_getlineno(lexp); 885 while(n==LPAREN) 886 { 887 struct argnod *ap; 888 ap = (struct argnod*)stkseek(stkp,ARGVAL); 889 ap->argflag= ARG_ASSIGN; 890 sfprintf(stkp,"[%d]=",index++); 891 ap = (struct argnod*)stkfreeze(stkp,1); 892 ap->argnxt.ap = 0; 893 ap = assign(lexp,ap,0); 894 ap->argflag |= ARG_MESSAGE; 895 *settail = ap; 896 settail = &(ap->argnxt.ap); 897 while((n = skipnl(lexp,0))==0) 898 { 899 ap = (struct argnod*)stkseek(stkp,ARGVAL); 900 ap->argflag= ARG_ASSIGN; 901 sfprintf(stkp,"[%d]=",index++); 902 stakputs(lexp->arg->argval); 903 ap = (struct argnod*)stkfreeze(stkp,1); 904 ap->argnxt.ap = 0; 905 ap->argflag = lexp->arg->argflag; 906 *settail = ap; 907 settail = &(ap->argnxt.ap); 908 } 909 } 910 } 911 else if(n && n!=FUNCTSYM) 912 sh_syntax(lexp); 913 else if(n!=FUNCTSYM && !(lexp->arg->argflag&ARG_ASSIGN) && !((np=nv_search(lexp->arg->argval,lexp->sh->fun_tree,0)) && (nv_isattr(np,BLT_DCL)|| np==SYSDOT))) 914 { 915 array=SH_ARRAY; 916 if(fcgetc(n)==LPAREN) 917 { 918 int c; 919 if(fcgetc(c)==RPAREN) 920 { 921 lexp->token = SYMRES; 922 array = 0; 923 } 924 else 925 fcseek(-2); 926 } 927 else if(n>0) 928 fcseek(-1); 929 if(array && tdef) 930 sh_syntax(lexp); 931 } 932 while(1) 933 { 934 if((n=lexp->token)==RPAREN) 935 break; 936 if(n==FUNCTSYM || n==SYMRES) 937 ac = (struct comnod*)funct(lexp); 938 else 939 ac = (struct comnod*)simple(lexp,SH_NOIO|SH_ASSIGN|array,NIL(struct ionod*)); 940 if((n=lexp->token)==RPAREN) 941 break; 942 if(n!=NL && n!=';') 943 sh_syntax(lexp); 944 lexp->assignok = SH_ASSIGN; 945 if((n=skipnl(lexp,0)) || array) 946 { 947 if(n==RPAREN) 948 break; 949 if(array || n!=FUNCTSYM) 950 sh_syntax(lexp); 951 } 952 if((n!=FUNCTSYM) && !(lexp->arg->argflag&ARG_ASSIGN) && !((np=nv_search(lexp->arg->argval,lexp->sh->fun_tree,0)) && (nv_isattr(np,BLT_DCL)||np==SYSDOT))) 953 { 954 struct argnod *arg = lexp->arg; 955 if(n!=0) 956 sh_syntax(lexp); 957 /* check for sys5 style function */ 958 if(sh_lex(lexp)!=LPAREN || sh_lex(lexp)!=RPAREN) 959 { 960 lexp->arg = arg; 961 lexp->token = 0; 962 sh_syntax(lexp); 963 } 964 lexp->arg = arg; 965 lexp->token = SYMRES; 966 } 967 t = makelist(lexp,TLST,(Shnode_t*)ac,t); 968 *tp = t; 969 tp = &t->lst.lstrit; 970 } 971 *tp = (Shnode_t*)ac; 972 lexp->assignok = 0; 973 return(ap); 974 } 975 976 /* 977 * item 978 * 979 * ( cmd ) [ < in ] [ > out ] 980 * word word* [ < in ] [ > out ] 981 * if ... then ... else ... fi 982 * for ... while ... do ... done 983 * case ... in ... esac 984 * begin ... end 985 */ 986 987 static Shnode_t *item(Lex_t *lexp,int flag) 988 { 989 register Shnode_t *t; 990 register struct ionod *io; 991 register int tok = (lexp->token&0xff); 992 int savwdval = lexp->lasttok; 993 int savline = lexp->lastline; 994 int showme=0, comsub; 995 if(!(flag&SH_NOIO) && (tok=='<' || tok=='>' || lexp->token==IOVNAME)) 996 io=inout(lexp,NIL(struct ionod*),1); 997 else 998 io=0; 999 if((tok=lexp->token) && tok!=EOFSYM && tok!=FUNCTSYM) 1000 { 1001 lexp->lastline = sh_getlineno(lexp); 1002 lexp->lasttok = lexp->token; 1003 } 1004 switch(tok) 1005 { 1006 /* [[ ... ]] test expression */ 1007 case BTESTSYM: 1008 t = test_expr(lexp,ETESTSYM); 1009 t->tre.tretyp &= ~TTEST; 1010 break; 1011 /* ((...)) arithmetic expression */ 1012 case EXPRSYM: 1013 t = getanode(lexp,lexp->arg); 1014 sh_lex(lexp); 1015 goto done; 1016 1017 /* case statement */ 1018 case CASESYM: 1019 { 1020 int savetok = lexp->lasttok; 1021 int saveline = lexp->lastline; 1022 t = getnode(swnod); 1023 if(sh_lex(lexp)) 1024 sh_syntax(lexp); 1025 t->sw.swarg=lexp->arg; 1026 t->sw.swtyp=TSW; 1027 t->sw.swio = 0; 1028 t->sw.swtyp |= FLINENO; 1029 t->sw.swline = lexp->sh->inlineno; 1030 if((tok=skipnl(lexp,0))!=INSYM && tok!=LBRACE) 1031 sh_syntax(lexp); 1032 if(!(t->sw.swlst=syncase(lexp,tok==INSYM?ESACSYM:RBRACE)) && lexp->token==EOFSYM) 1033 { 1034 lexp->lasttok = savetok; 1035 lexp->lastline = saveline; 1036 sh_syntax(lexp); 1037 } 1038 break; 1039 } 1040 1041 /* if statement */ 1042 case IFSYM: 1043 { 1044 register Shnode_t *tt; 1045 t = getnode(ifnod); 1046 t->if_.iftyp=TIF; 1047 t->if_.iftre=sh_cmd(lexp,THENSYM,SH_NL); 1048 t->if_.thtre=sh_cmd(lexp,ELSESYM,SH_NL|SH_SEMI); 1049 tok = lexp->token; 1050 t->if_.eltre=(tok==ELSESYM?sh_cmd(lexp,FISYM,SH_NL|SH_SEMI): 1051 (tok==ELIFSYM?(lexp->token=IFSYM, tt=item(lexp,SH_NOIO)):0)); 1052 if(tok==ELIFSYM) 1053 { 1054 if(!tt || tt->tre.tretyp!=TSETIO) 1055 goto done; 1056 t->if_.eltre = tt->fork.forktre; 1057 tt->fork.forktre = t; 1058 t = tt; 1059 goto done; 1060 } 1061 break; 1062 } 1063 1064 /* for and select statement */ 1065 case FORSYM: 1066 case SELECTSYM: 1067 { 1068 t = getnode(fornod); 1069 t->for_.fortyp=(lexp->token==FORSYM?TFOR:TSELECT); 1070 t->for_.forlst=0; 1071 t->for_.forline = lexp->sh->inlineno; 1072 if(sh_lex(lexp)) 1073 { 1074 if(lexp->token!=EXPRSYM || t->for_.fortyp!=TFOR) 1075 sh_syntax(lexp); 1076 /* arithmetic for */ 1077 t = arithfor(lexp,t); 1078 break; 1079 } 1080 t->for_.fornam=(char*) lexp->arg->argval; 1081 t->for_.fortyp |= FLINENO; 1082 #if SHOPT_KIA 1083 if(lexp->kiafile) 1084 writedefs(lexp,lexp->arg,lexp->sh->inlineno,'v',NIL(struct argnod*)); 1085 #endif /* SHOPT_KIA */ 1086 while((tok=sh_lex(lexp))==NL); 1087 if(tok==INSYM) 1088 { 1089 if(sh_lex(lexp)) 1090 { 1091 if(lexp->token != NL && lexp->token !=';') 1092 sh_syntax(lexp); 1093 /* some Linux scripts assume this */ 1094 if(sh_isoption(SH_NOEXEC)) 1095 errormsg(SH_DICT,ERROR_warn(0),e_lexemptyfor,lexp->sh->inlineno-(lexp->token=='\n')); 1096 t->for_.forlst = (struct comnod*)getnode(comnod); 1097 (t->for_.forlst)->comarg = 0; 1098 (t->for_.forlst)->comset = 0; 1099 (t->for_.forlst)->comnamp = 0; 1100 (t->for_.forlst)->comnamq = 0; 1101 (t->for_.forlst)->comstate = 0; 1102 (t->for_.forlst)->comio = 0; 1103 (t->for_.forlst)->comtyp = 0; 1104 } 1105 else 1106 t->for_.forlst=(struct comnod*)simple(lexp,SH_NOIO,NIL(struct ionod*)); 1107 if(lexp->token != NL && lexp->token !=';') 1108 sh_syntax(lexp); 1109 tok = skipnl(lexp,0); 1110 } 1111 /* 'for i;do cmd' is valid syntax */ 1112 else if(tok==';') 1113 tok=sh_lex(lexp); 1114 if(tok!=DOSYM && tok!=LBRACE) 1115 sh_syntax(lexp); 1116 loop_level++; 1117 t->for_.fortre=sh_cmd(lexp,tok==DOSYM?DONESYM:RBRACE,SH_NL|SH_SEMI); 1118 if(--loop_level==0) 1119 label_last = label_list; 1120 break; 1121 } 1122 1123 /* This is the code for parsing function definitions */ 1124 case FUNCTSYM: 1125 return(funct(lexp)); 1126 1127 #if SHOPT_NAMESPACE 1128 case NSPACESYM: 1129 t = getnode(fornod); 1130 t->for_.fortyp=TNSPACE; 1131 t->for_.forlst=0; 1132 if(sh_lex(lexp)) 1133 sh_syntax(lexp); 1134 t->for_.fornam=(char*) lexp->arg->argval; 1135 while((tok=sh_lex(lexp))==NL); 1136 if(tok!=LBRACE) 1137 sh_syntax(lexp); 1138 t->for_.fortre = sh_cmd(lexp,RBRACE,SH_NL); 1139 break; 1140 #endif /* SHOPT_NAMESPACE */ 1141 1142 /* while and until */ 1143 case WHILESYM: 1144 case UNTILSYM: 1145 t = getnode(whnod); 1146 t->wh.whtyp=(lexp->token==WHILESYM ? TWH : TUN); 1147 loop_level++; 1148 t->wh.whtre = sh_cmd(lexp,DOSYM,SH_NL); 1149 t->wh.dotre = sh_cmd(lexp,DONESYM,SH_NL|SH_SEMI); 1150 if(--loop_level==0) 1151 label_last = label_list; 1152 t->wh.whinc = 0; 1153 break; 1154 1155 case LABLSYM: 1156 { 1157 register struct argnod *argp = label_list; 1158 while(argp) 1159 { 1160 if(strcmp(argp->argval,lexp->arg->argval)==0) 1161 errormsg(SH_DICT,ERROR_exit(3),e_lexsyntax3,lexp->sh->inlineno,argp->argval); 1162 argp = argp->argnxt.ap; 1163 } 1164 lexp->arg->argnxt.ap = label_list; 1165 label_list = lexp->arg; 1166 label_list->argchn.len = sh_getlineno(lexp); 1167 label_list->argflag = loop_level; 1168 skipnl(lexp,flag); 1169 if(!(t = item(lexp,SH_NL))) 1170 sh_syntax(lexp); 1171 tok = (t->tre.tretyp&(COMSCAN|COMSCAN-1)); 1172 if(sh_isoption(SH_NOEXEC) && tok!=TWH && tok!=TUN && tok!=TFOR && tok!=TSELECT) 1173 errormsg(SH_DICT,ERROR_warn(0),e_lexlabignore,label_list->argchn.len,label_list->argval); 1174 return(t); 1175 } 1176 1177 /* command group with {...} */ 1178 case LBRACE: 1179 comsub = lexp->comsub; 1180 lexp->comsub = 0; 1181 t = sh_cmd(lexp,RBRACE,SH_NL|SH_SEMI); 1182 lexp->comsub = comsub; 1183 break; 1184 1185 case LPAREN: 1186 t = getnode(parnod); 1187 t->par.partre=sh_cmd(lexp,RPAREN,SH_NL|SH_SEMI); 1188 t->par.partyp=TPAR; 1189 break; 1190 1191 default: 1192 if(io==0) 1193 return(0); 1194 1195 case ';': 1196 if(io==0) 1197 { 1198 if(!(flag&SH_SEMI)) 1199 return(0); 1200 if(sh_lex(lexp)==';') 1201 sh_syntax(lexp); 1202 showme = FSHOWME; 1203 } 1204 /* simple command */ 1205 case 0: 1206 t = (Shnode_t*)simple(lexp,flag,io); 1207 if(t->com.comarg && lexp->intypeset && (lexp->sh->shcomp || sh_isoption(SH_NOEXEC) || sh.dot_depth)) 1208 check_typedef(&t->com); 1209 lexp->intypeset = 0; 1210 lexp->inexec = 0; 1211 t->tre.tretyp |= showme; 1212 return(t); 1213 } 1214 sh_lex(lexp); 1215 if(io=inout(lexp,io,0)) 1216 { 1217 if((tok=t->tre.tretyp&COMMSK) != TFORK) 1218 tok = TSETIO; 1219 t=makeparent(lexp,tok,t); 1220 t->tre.treio=io; 1221 } 1222 done: 1223 lexp->lasttok = savwdval; 1224 lexp->lastline = savline; 1225 return(t); 1226 } 1227 1228 static struct argnod *process_sub(Lex_t *lexp,int tok) 1229 { 1230 struct argnod *argp; 1231 Shnode_t *t; 1232 int mode = (tok==OPROCSYM); 1233 t = sh_cmd(lexp,RPAREN,SH_NL); 1234 argp = (struct argnod*)stkalloc(lexp->sh->stk,sizeof(struct argnod)); 1235 *argp->argval = 0; 1236 argp->argchn.ap = (struct argnod*)makeparent(lexp,mode?TFORK|FPIN|FAMP|FPCL:TFORK|FPOU,t); 1237 argp->argflag = (ARG_EXP|mode); 1238 return(argp); 1239 } 1240 1241 1242 /* 1243 * This is for a simple command, for list, or compound assignment 1244 */ 1245 static Shnode_t *simple(Lex_t *lexp,int flag, struct ionod *io) 1246 { 1247 register struct comnod *t; 1248 register struct argnod *argp; 1249 register int tok; 1250 Stk_t *stkp = lexp->sh->stk; 1251 struct argnod **argtail; 1252 struct argnod **settail; 1253 int cmdarg=0; 1254 int argno = 0, argmax=0; 1255 int assignment = 0; 1256 int key_on = (!(flag&SH_NOIO) && sh_isoption(SH_KEYWORD)); 1257 int associative=0; 1258 if((argp=lexp->arg) && (argp->argflag&ARG_ASSIGN) && argp->argval[0]=='[') 1259 { 1260 flag |= SH_ARRAY; 1261 associative = 1; 1262 } 1263 t = (struct comnod*)getnode(comnod); 1264 t->comio=io; /*initial io chain*/ 1265 /* set command line number for error messages */ 1266 t->comline = sh_getlineno(lexp); 1267 argtail = &(t->comarg); 1268 t->comset = 0; 1269 t->comnamp = 0; 1270 t->comnamq = 0; 1271 t->comstate = 0; 1272 settail = &(t->comset); 1273 while(lexp->token==0) 1274 { 1275 argp = lexp->arg; 1276 if(*argp->argval==LBRACE && (flag&SH_FUNDEF) && argp->argval[1]==0) 1277 { 1278 lexp->token = LBRACE; 1279 break; 1280 } 1281 if(associative && argp->argval[0]!='[') 1282 sh_syntax(lexp); 1283 /* check for assignment argument */ 1284 if((argp->argflag&ARG_ASSIGN) && assignment!=2) 1285 { 1286 *settail = argp; 1287 settail = &(argp->argnxt.ap); 1288 lexp->assignok = (flag&SH_ASSIGN)?SH_ASSIGN:1; 1289 if(assignment) 1290 { 1291 struct argnod *ap=argp; 1292 char *last, *cp; 1293 if(assignment==1) 1294 { 1295 last = strchr(argp->argval,'='); 1296 if(last && (last[-1]==']'|| (last[-1]=='+' && last[-2]==']')) && (cp=strchr(argp->argval,'[')) && (cp < last)) 1297 last = cp; 1298 stkseek(stkp,ARGVAL); 1299 sfwrite(stkp,argp->argval,last-argp->argval); 1300 ap=(struct argnod*)stkfreeze(stkp,1); 1301 ap->argflag = ARG_RAW; 1302 ap->argchn.ap = 0; 1303 } 1304 *argtail = ap; 1305 argtail = &(ap->argnxt.ap); 1306 if(argno>=0) 1307 argno++; 1308 } 1309 else /* alias substitutions allowed */ 1310 lexp->aliasok = 1; 1311 } 1312 else 1313 { 1314 if(!(argp->argflag&ARG_RAW)) 1315 { 1316 if(argno>0) 1317 argmax = argno; 1318 argno = -1; 1319 } 1320 if(argno>=0 && argno++==cmdarg && !(flag&SH_ARRAY) && *argp->argval!='/') 1321 { 1322 /* check for builtin command */ 1323 Namval_t *np=nv_bfsearch(argp->argval,lexp->sh->fun_tree, (Namval_t**)&t->comnamq,(char**)0); 1324 if(cmdarg==0) 1325 t->comnamp = (void*)np; 1326 if(np && is_abuiltin(np)) 1327 { 1328 if(nv_isattr(np,BLT_DCL)) 1329 { 1330 assignment = 1+(*argp->argval=='a'); 1331 if(np==SYSTYPESET) 1332 lexp->intypeset = 1; 1333 key_on = 1; 1334 } 1335 else if(np==SYSCOMMAND) 1336 cmdarg++; 1337 else if(np==SYSEXEC) 1338 lexp->inexec = 1; 1339 else if(np->nvalue.bfp==b_getopts) 1340 opt_get |= FOPTGET; 1341 } 1342 } 1343 *argtail = argp; 1344 argtail = &(argp->argnxt.ap); 1345 if(!(lexp->assignok=key_on) && !(flag&SH_NOIO) && sh_isoption(SH_NOEXEC)) 1346 lexp->assignok = SH_COMPASSIGN; 1347 lexp->aliasok = 0; 1348 } 1349 retry: 1350 tok = sh_lex(lexp); 1351 if(tok==LABLSYM && (flag&SH_ASSIGN)) 1352 lexp->token = tok = 0; 1353 #if SHOPT_DEVFD 1354 if((tok==IPROCSYM || tok==OPROCSYM)) 1355 { 1356 argp = process_sub(lexp,tok); 1357 argmax = 0; 1358 argno = -1; 1359 *argtail = argp; 1360 argtail = &(argp->argnxt.ap); 1361 goto retry; 1362 } 1363 #endif /* SHOPT_DEVFD */ 1364 if(tok==LPAREN) 1365 { 1366 if(argp->argflag&ARG_ASSIGN) 1367 { 1368 int intypeset = lexp->intypeset; 1369 int tdef = 0; 1370 lexp->intypeset = 0; 1371 if(t->comnamp==SYSTYPESET && t->comarg->argnxt.ap && strcmp(t->comarg->argnxt.ap->argval,"-T")==0) 1372 tdef = 1; 1373 argp = assign(lexp,argp,tdef); 1374 lexp->intypeset = intypeset; 1375 if(associative) 1376 lexp->assignok |= SH_ASSIGN; 1377 goto retry; 1378 } 1379 else if(argno==1 && !t->comset) 1380 { 1381 /* SVR2 style function */ 1382 if(sh_lex(lexp) == RPAREN) 1383 { 1384 lexp->arg = argp; 1385 return(funct(lexp)); 1386 } 1387 lexp->token = LPAREN; 1388 } 1389 } 1390 else if(flag&SH_ASSIGN) 1391 { 1392 if(tok==RPAREN) 1393 break; 1394 else if(tok==NL && (flag&SH_ARRAY)) 1395 { 1396 lexp->comp_assign = 2; 1397 goto retry; 1398 } 1399 1400 } 1401 if(!(flag&SH_NOIO)) 1402 { 1403 if(io) 1404 { 1405 while(io->ionxt) 1406 io = io->ionxt; 1407 io->ionxt = inout(lexp,(struct ionod*)0,0); 1408 } 1409 else 1410 t->comio = io = inout(lexp,(struct ionod*)0,0); 1411 } 1412 } 1413 *argtail = 0; 1414 if(argno>0) 1415 argmax = argno; 1416 t->comtyp = TCOM | (argmax<<(COMBITS+2)); 1417 #if SHOPT_KIA 1418 if(lexp->kiafile && !(flag&SH_NOIO)) 1419 { 1420 register Namval_t *np=(Namval_t*)t->comnamp; 1421 unsigned long r=0; 1422 int line = t->comline; 1423 argp = t->comarg; 1424 if(np) 1425 r = kiaentity(lexp,nv_name(np),-1,'p',-1,0,lexp->unknown,'b',0,""); 1426 else if(argp) 1427 r = kiaentity(lexp,sh_argstr(argp),-1,'p',-1,0,lexp->unknown,'c',0,""); 1428 if(r>0) 1429 sfprintf(lexp->kiatmp,"p;%..64d;p;%..64d;%d;%d;c;\n",lexp->current,r,line,line); 1430 if(t->comset && argno==0) 1431 writedefs(lexp,t->comset,line,'v',t->comarg); 1432 else if(np && nv_isattr(np,BLT_DCL)) 1433 writedefs(lexp,argp,line,0,NIL(struct argnod*)); 1434 else if(argp && strcmp(argp->argval,"read")==0) 1435 writedefs(lexp,argp,line,0,NIL(struct argnod*)); 1436 #if 0 1437 else if(argp && strcmp(argp->argval,"unset")==0) 1438 writedefs(lexp,argp,line,'u',NIL(struct argnod*)); 1439 #endif 1440 else if(argp && *argp->argval=='.' && argp->argval[1]==0 && (argp=argp->argnxt.ap)) 1441 { 1442 r = kiaentity(lexp,sh_argstr(argp),-1,'p',0,0,lexp->script,'d',0,""); 1443 sfprintf(lexp->kiatmp,"p;%..64d;p;%..64d;%d;%d;d;\n",lexp->current,r,line,line); 1444 } 1445 } 1446 #endif /* SHOPT_KIA */ 1447 if(t->comnamp && (argp=t->comarg->argnxt.ap)) 1448 { 1449 Namval_t *np=(Namval_t*)t->comnamp; 1450 if((np==SYSBREAK || np==SYSCONT) && (argp->argflag&ARG_RAW) && !isdigit(*argp->argval)) 1451 { 1452 register char *cp = argp->argval; 1453 /* convert break/continue labels to numbers */ 1454 tok = 0; 1455 for(argp=label_list;argp!=label_last;argp=argp->argnxt.ap) 1456 { 1457 if(strcmp(cp,argp->argval)) 1458 continue; 1459 tok = loop_level-argp->argflag; 1460 if(tok>=1) 1461 { 1462 argp = t->comarg->argnxt.ap; 1463 if(tok>9) 1464 { 1465 argp->argval[1] = '0'+tok%10; 1466 argp->argval[2] = 0; 1467 tok /= 10; 1468 } 1469 else 1470 argp->argval[1] = 0; 1471 *argp->argval = '0'+tok; 1472 } 1473 break; 1474 } 1475 if(sh_isoption(SH_NOEXEC) && tok==0) 1476 errormsg(SH_DICT,ERROR_warn(0),e_lexlabunknown,lexp->sh->inlineno-(lexp->token=='\n'),cp); 1477 } 1478 else if(sh_isoption(SH_NOEXEC) && np==SYSSET && ((tok= *argp->argval)=='-'||tok=='+') && 1479 (argp->argval[1]==0||strchr(argp->argval,'k'))) 1480 errormsg(SH_DICT,ERROR_warn(0),e_lexobsolete5,lexp->sh->inlineno-(lexp->token=='\n'),argp->argval); 1481 } 1482 /* expand argument list if possible */ 1483 if(argno>0) 1484 t->comarg = qscan(t,argno); 1485 else if(t->comarg) 1486 t->comtyp |= COMSCAN; 1487 lexp->aliasok = 0; 1488 return((Shnode_t*)t); 1489 } 1490 1491 /* 1492 * skip past newlines but issue prompt if interactive 1493 */ 1494 static int skipnl(Lex_t *lexp,int flag) 1495 { 1496 register int token; 1497 while((token=sh_lex(lexp))==NL); 1498 if(token==';' && !(flag&SH_SEMI)) 1499 sh_syntax(lexp); 1500 return(token); 1501 } 1502 1503 /* 1504 * check for and process and i/o redirections 1505 * if flag>0 then an alias can be in the next word 1506 * if flag<0 only one redirection will be processed 1507 */ 1508 static struct ionod *inout(Lex_t *lexp,struct ionod *lastio,int flag) 1509 { 1510 register int iof = lexp->digits, token=lexp->token; 1511 register struct ionod *iop; 1512 Stk_t *stkp = lexp->sh->stk; 1513 char *iovname=0; 1514 register int errout=0; 1515 if(token==IOVNAME) 1516 { 1517 iovname=lexp->arg->argval+1; 1518 token= sh_lex(lexp); 1519 iof = 0; 1520 } 1521 switch(token&0xff) 1522 { 1523 case '<': 1524 if(token==IODOCSYM) 1525 iof |= (IODOC|IORAW); 1526 else if(token==IOMOV0SYM) 1527 iof |= IOMOV; 1528 else if(token==IORDWRSYMT) 1529 iof |= IORDW|IOREWRITE; 1530 else if(token==IORDWRSYM) 1531 iof |= IORDW; 1532 else if((token&SYMSHARP) == SYMSHARP) 1533 { 1534 int n; 1535 iof |= IOLSEEK; 1536 if(fcgetc(n)=='#') 1537 iof |= IOCOPY; 1538 else if(n>0) 1539 fcseek(-1); 1540 } 1541 break; 1542 1543 case '>': 1544 if(iof<0) 1545 { 1546 errout = 1; 1547 iof = 1; 1548 } 1549 iof |= IOPUT; 1550 if(token==IOAPPSYM) 1551 iof |= IOAPP; 1552 else if(token==IOMOV1SYM) 1553 iof |= IOMOV; 1554 else if(token==IOCLOBSYM) 1555 iof |= IOCLOB; 1556 else if((token&SYMSHARP) == SYMSHARP) 1557 iof |= IOLSEEK; 1558 else if((token&SYMSEMI) == SYMSEMI) 1559 iof |= IOREWRITE; 1560 break; 1561 1562 default: 1563 return(lastio); 1564 } 1565 lexp->digits=0; 1566 iop=(struct ionod*) stkalloc(stkp,sizeof(struct ionod)); 1567 iop->iodelim = 0; 1568 if(token=sh_lex(lexp)) 1569 { 1570 if(token==RPAREN && (iof&IOLSEEK) && lexp->comsub) 1571 { 1572 lexp->arg = (struct argnod*)stkalloc(stkp,sizeof(struct argnod)+3); 1573 strcpy(lexp->arg->argval,"CUR"); 1574 lexp->arg->argflag = ARG_RAW; 1575 iof |= IOARITH; 1576 fcseek(-1); 1577 } 1578 else if(token==EXPRSYM && (iof&IOLSEEK)) 1579 iof |= IOARITH; 1580 else if(((token==IPROCSYM && !(iof&IOPUT)) || (token==OPROCSYM && (iof&IOPUT))) && !(iof&(IOLSEEK|IOREWRITE|IOMOV|IODOC))) 1581 { 1582 lexp->arg = process_sub(lexp,token); 1583 iof |= IOPROCSUB; 1584 } 1585 else 1586 sh_syntax(lexp); 1587 } 1588 if( (iof&IOPROCSUB) && !(iof&IOLSEEK)) 1589 iop->ioname= (char*)lexp->arg->argchn.ap; 1590 else 1591 iop->ioname=lexp->arg->argval; 1592 iop->iovname = iovname; 1593 if(iof&IODOC) 1594 { 1595 if(lexp->digits==2) 1596 { 1597 iof |= IOSTRG; 1598 if(!(lexp->arg->argflag&ARG_RAW)) 1599 iof &= ~IORAW; 1600 } 1601 else 1602 { 1603 if(!lexp->sh->heredocs) 1604 lexp->sh->heredocs = sftmp(HERE_MEM); 1605 iop->iolst=lexp->heredoc; 1606 lexp->heredoc=iop; 1607 if(lexp->arg->argflag&ARG_QUOTED) 1608 iof |= IOQUOTE; 1609 if(lexp->digits==3) 1610 iof |= IOLSEEK; 1611 if(lexp->digits) 1612 iof |= IOSTRIP; 1613 } 1614 } 1615 else 1616 { 1617 iop->iolst = 0; 1618 if(lexp->arg->argflag&ARG_RAW) 1619 iof |= IORAW; 1620 } 1621 iop->iofile=iof; 1622 if(flag>0) 1623 /* allow alias substitutions and parameter assignments */ 1624 lexp->aliasok = lexp->assignok = 1; 1625 #if SHOPT_KIA 1626 if(lexp->kiafile) 1627 { 1628 int n = lexp->sh->inlineno-(lexp->token=='\n'); 1629 if(!(iof&IOMOV)) 1630 { 1631 unsigned long r=kiaentity(lexp,(iof&IORAW)?sh_fmtq(iop->ioname):iop->ioname,-1,'f',0,0,lexp->script,'f',0,""); 1632 sfprintf(lexp->kiatmp,"p;%..64d;f;%..64d;%d;%d;%c;%d\n",lexp->current,r,n,n,(iof&IOPUT)?((iof&IOAPP)?'a':'w'):((iof&IODOC)?'h':'r'),iof&IOUFD); 1633 } 1634 } 1635 #endif /* SHOPT_KIA */ 1636 if(flag>=0) 1637 { 1638 struct ionod *ioq=iop; 1639 sh_lex(lexp); 1640 if(errout) 1641 { 1642 /* redirect standard output to standard error */ 1643 ioq = (struct ionod*)stkalloc(stkp,sizeof(struct ionod)); 1644 memset(ioq,0,sizeof(*ioq)); 1645 ioq->ioname = "1"; 1646 ioq->iolst = 0; 1647 ioq->iodelim = 0; 1648 ioq->iofile = IORAW|IOPUT|IOMOV|2; 1649 iop->ionxt=ioq; 1650 } 1651 ioq->ionxt=inout(lexp,lastio,flag); 1652 } 1653 else 1654 iop->ionxt=0; 1655 return(iop); 1656 } 1657 1658 /* 1659 * convert argument chain to argument list when no special arguments 1660 */ 1661 1662 static struct argnod *qscan(struct comnod *ac,int argn) 1663 { 1664 register char **cp; 1665 register struct argnod *ap; 1666 register struct dolnod* dp; 1667 register int special=0; 1668 /* special hack for test -t compatibility */ 1669 if((Namval_t*)ac->comnamp==SYSTEST) 1670 special = 2; 1671 else if(*(ac->comarg->argval)=='[' && ac->comarg->argval[1]==0) 1672 special = 3; 1673 if(special) 1674 { 1675 ap = ac->comarg->argnxt.ap; 1676 if(argn==(special+1) && ap->argval[1]==0 && *ap->argval=='!') 1677 ap = ap->argnxt.ap; 1678 else if(argn!=special) 1679 special=0; 1680 } 1681 if(special) 1682 { 1683 const char *message; 1684 if(strcmp(ap->argval,"-t")) 1685 { 1686 message = "line %d: Invariant test"; 1687 special=0; 1688 } 1689 else 1690 { 1691 message = "line %d: -t requires argument"; 1692 argn++; 1693 } 1694 if(sh_isoption(SH_NOEXEC)) 1695 errormsg(SH_DICT,ERROR_warn(0),message,ac->comline); 1696 } 1697 /* leave space for an extra argument at the front */ 1698 dp = (struct dolnod*)stakalloc((unsigned)sizeof(struct dolnod) + ARG_SPARE*sizeof(char*) + argn*sizeof(char*)); 1699 cp = dp->dolval+ARG_SPARE; 1700 dp->dolnum = argn; 1701 dp->dolbot = ARG_SPARE; 1702 ap = ac->comarg; 1703 while(ap) 1704 { 1705 *cp++ = ap->argval; 1706 ap = ap->argnxt.ap; 1707 } 1708 if(special==3) 1709 { 1710 cp[0] = cp[-1]; 1711 cp[-1] = "1"; 1712 cp++; 1713 } 1714 else if(special) 1715 *cp++ = "1"; 1716 *cp = 0; 1717 return((struct argnod*)dp); 1718 } 1719 1720 static Shnode_t *test_expr(Lex_t *lp,int sym) 1721 { 1722 register Shnode_t *t = test_or(lp); 1723 if(lp->token!=sym) 1724 sh_syntax(lp); 1725 return(t); 1726 } 1727 1728 static Shnode_t *test_or(Lex_t *lp) 1729 { 1730 register Shnode_t *t = test_and(lp); 1731 while(lp->token==ORFSYM) 1732 t = makelist(lp,TORF|TTEST,t,test_and(lp)); 1733 return(t); 1734 } 1735 1736 static Shnode_t *test_and(Lex_t *lp) 1737 { 1738 register Shnode_t *t = test_primary(lp); 1739 while(lp->token==ANDFSYM) 1740 t = makelist(lp,TAND|TTEST,t,test_primary(lp)); 1741 return(t); 1742 } 1743 1744 /* 1745 * convert =~ into == ~(E) 1746 */ 1747 static void ere_match(void) 1748 { 1749 Sfio_t *base, *iop = sfopen((Sfio_t*)0," ~(E)","s"); 1750 register int c; 1751 while( fcgetc(c),(c==' ' || c=='\t')); 1752 if(c) 1753 fcseek(-1); 1754 if(!(base=fcfile())) 1755 base = sfopen(NIL(Sfio_t*),fcseek(0),"s"); 1756 fcclose(); 1757 sfstack(base,iop); 1758 fcfopen(base); 1759 } 1760 1761 static Shnode_t *test_primary(Lex_t *lexp) 1762 { 1763 register struct argnod *arg; 1764 register Shnode_t *t; 1765 register int num,token; 1766 token = skipnl(lexp,0); 1767 num = lexp->digits; 1768 switch(token) 1769 { 1770 case '(': 1771 t = test_expr(lexp,')'); 1772 t = makelist(lexp,TTST|TTEST|TPAREN ,t, (Shnode_t*)pointerof(lexp->sh->inlineno)); 1773 break; 1774 case '!': 1775 if(!(t = test_primary(lexp))) 1776 sh_syntax(lexp); 1777 t->tre.tretyp |= TNEGATE; 1778 return(t); 1779 case TESTUNOP: 1780 if(sh_lex(lexp)) 1781 sh_syntax(lexp); 1782 #if SHOPT_KIA 1783 if(lexp->kiafile && !strchr("sntzoOG",num)) 1784 { 1785 int line = lexp->sh->inlineno- (lexp->token==NL); 1786 unsigned long r; 1787 r=kiaentity(lexp,sh_argstr(lexp->arg),-1,'f',0,0,lexp->script,'t',0,""); 1788 sfprintf(lexp->kiatmp,"p;%..64d;f;%..64d;%d;%d;t;\n",lexp->current,r,line,line); 1789 } 1790 #endif /* SHOPT_KIA */ 1791 t = makelist(lexp,TTST|TTEST|TUNARY|(num<<TSHIFT), 1792 (Shnode_t*)lexp->arg,(Shnode_t*)lexp->arg); 1793 t->tst.tstline = lexp->sh->inlineno; 1794 break; 1795 /* binary test operators */ 1796 case 0: 1797 arg = lexp->arg; 1798 if((token=sh_lex(lexp))==TESTBINOP) 1799 { 1800 num = lexp->digits; 1801 if(num==TEST_REP) 1802 { 1803 ere_match(); 1804 num = TEST_PEQ; 1805 } 1806 } 1807 else if(token=='<') 1808 num = TEST_SLT; 1809 else if(token=='>') 1810 num = TEST_SGT; 1811 else if(token==ANDFSYM||token==ORFSYM||token==ETESTSYM||token==RPAREN) 1812 { 1813 t = makelist(lexp,TTST|TTEST|TUNARY|('n'<<TSHIFT), 1814 (Shnode_t*)arg,(Shnode_t*)arg); 1815 t->tst.tstline = lexp->sh->inlineno; 1816 return(t); 1817 } 1818 else 1819 sh_syntax(lexp); 1820 #if SHOPT_KIA 1821 if(lexp->kiafile && (num==TEST_EF||num==TEST_NT||num==TEST_OT)) 1822 { 1823 int line = lexp->sh->inlineno- (lexp->token==NL); 1824 unsigned long r; 1825 r=kiaentity(lexp,sh_argstr(lexp->arg),-1,'f',0,0,lexp->current,'t',0,""); 1826 sfprintf(lexp->kiatmp,"p;%..64d;f;%..64d;%d;%d;t;\n",lexp->current,r,line,line); 1827 } 1828 #endif /* SHOPT_KIA */ 1829 if(sh_lex(lexp)) 1830 sh_syntax(lexp); 1831 if(num&TEST_PATTERN) 1832 { 1833 if(lexp->arg->argflag&(ARG_EXP|ARG_MAC)) 1834 num &= ~TEST_PATTERN; 1835 } 1836 t = getnode(tstnod); 1837 t->lst.lsttyp = TTST|TTEST|TBINARY|(num<<TSHIFT); 1838 t->lst.lstlef = (Shnode_t*)arg; 1839 t->lst.lstrit = (Shnode_t*)lexp->arg; 1840 t->tst.tstline = lexp->sh->inlineno; 1841 #if SHOPT_KIA 1842 if(lexp->kiafile && (num==TEST_EF||num==TEST_NT||num==TEST_OT)) 1843 { 1844 int line = lexp->sh->inlineno-(lexp->token==NL); 1845 unsigned long r; 1846 r=kiaentity(lexp,sh_argstr(lexp->arg),-1,'f',0,0,lexp->current,'t',0,""); 1847 sfprintf(lexp->kiatmp,"p;%..64d;f;%..64d;%d;%d;t;\n",lexp->current,r,line,line); 1848 } 1849 #endif /* SHOPT_KIA */ 1850 break; 1851 default: 1852 return(0); 1853 } 1854 skipnl(lexp,0); 1855 return(t); 1856 } 1857 1858 #if SHOPT_KIA 1859 /* 1860 * return an entity checksum 1861 * The entity is created if it doesn't exist 1862 */ 1863 unsigned long kiaentity(Lex_t *lexp,const char *name,int len,int type,int first,int last,unsigned long parent, int pkind, int width, const char *attr) 1864 { 1865 Stk_t *stkp = lexp->sh->stk; 1866 Namval_t *np; 1867 long offset = stktell(stkp); 1868 sfputc(stkp,type); 1869 if(len>0) 1870 sfwrite(stkp,name,len); 1871 else 1872 { 1873 if(type=='p') 1874 sfputr(stkp,path_basename(name),0); 1875 else 1876 sfputr(stkp,name,0); 1877 } 1878 np = nv_search(stakptr(offset),lexp->entity_tree,NV_ADD); 1879 stkseek(stkp,offset); 1880 np->nvalue.i = pkind; 1881 nv_setsize(np,width); 1882 if(!nv_isattr(np,NV_TAGGED) && first>=0) 1883 { 1884 nv_onattr(np,NV_TAGGED); 1885 if(!pkind) 1886 pkind = '0'; 1887 if(len>0) 1888 sfprintf(lexp->kiafile,"%..64d;%c;%.*s;%d;%d;%..64d;%..64d;%c;%d;%s\n",np->hash,type,len,name,first,last,parent,lexp->fscript,pkind,width,attr); 1889 else 1890 sfprintf(lexp->kiafile,"%..64d;%c;%s;%d;%d;%..64d;%..64d;%c;%d;%s\n",np->hash,type,name,first,last,parent,lexp->fscript,pkind,width,attr); 1891 } 1892 return(np->hash); 1893 } 1894 1895 static void kia_add(register Namval_t *np, void *data) 1896 { 1897 char *name = nv_name(np); 1898 Lex_t *lp = (Lex_t*)data; 1899 NOT_USED(data); 1900 kiaentity(lp,name+1,-1,*name,0,-1,(*name=='p'?lp->unknown:lp->script),np->nvalue.i,nv_size(np),""); 1901 } 1902 1903 int kiaclose(Lex_t *lexp) 1904 { 1905 register off_t off1,off2; 1906 register int n; 1907 if(lexp->kiafile) 1908 { 1909 unsigned long r = kiaentity(lexp,lexp->scriptname,-1,'p',-1,lexp->sh->inlineno-1,0,'s',0,""); 1910 kiaentity(lexp,lexp->scriptname,-1,'p',1,lexp->sh->inlineno-1,r,'s',0,""); 1911 kiaentity(lexp,lexp->scriptname,-1,'f',1,lexp->sh->inlineno-1,r,'s',0,""); 1912 nv_scan(lexp->entity_tree,kia_add,(void*)lexp,NV_TAGGED,0); 1913 off1 = sfseek(lexp->kiafile,(off_t)0,SEEK_END); 1914 sfseek(lexp->kiatmp,(off_t)0,SEEK_SET); 1915 sfmove(lexp->kiatmp,lexp->kiafile,SF_UNBOUND,-1); 1916 off2 = sfseek(lexp->kiafile,(off_t)0,SEEK_END); 1917 #ifdef SF_BUFCONST 1918 if(off2==off1) 1919 n= sfprintf(lexp->kiafile,"DIRECTORY\nENTITY;%lld;%d\nDIRECTORY;",(Sflong_t)lexp->kiabegin,(size_t)(off1-lexp->kiabegin)); 1920 else 1921 n= sfprintf(lexp->kiafile,"DIRECTORY\nENTITY;%lld;%d\nRELATIONSHIP;%lld;%d\nDIRECTORY;",(Sflong_t)lexp->kiabegin,(size_t)(off1-lexp->kiabegin),(Sflong_t)off1,(size_t)(off2-off1)); 1922 if(off2 >= INT_MAX) 1923 off2 = -(n+12); 1924 sfprintf(lexp->kiafile,"%010.10lld;%010d\n",(Sflong_t)off2+10, n+12); 1925 #else 1926 if(off2==off1) 1927 n= sfprintf(lexp->kiafile,"DIRECTORY\nENTITY;%d;%d\nDIRECTORY;",lexp->kiabegin,off1-lexp->kiabegin); 1928 else 1929 n= sfprintf(lexp->kiafile,"DIRECTORY\nENTITY;%d;%d\nRELATIONSHIP;%d;%d\nDIRECTORY;",lexp->kiabegin,off1-lexp->kiabegin,off1,off2-off1); 1930 sfprintf(lexp->kiafile,"%010d;%010d\n",off2+10, n+12); 1931 #endif 1932 } 1933 return(sfclose(lexp->kiafile)); 1934 } 1935 #endif /* SHOPT_KIA */ 1936