VirtualBox

Changeset 1210 in kBuild for trunk/src/kash/parser.c


Ignore:
Timestamp:
Oct 7, 2007 6:33:36 PM (17 years ago)
Author:
bird
Message:

var.c ++

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/kash/parser.c

    r1208 r1210  
    6868#include "myhistedit.h"
    6969#endif
     70#include "shinstance.h"
    7071
    7172/*
     
    9192
    9293
    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
     110STATIC union node *list(shinstance *, int);
     111STATIC union node *andor(shinstance *);
     112STATIC union node *pipeline(shinstance *);
     113STATIC union node *command(shinstance *);
     114STATIC union node *simplecmd(shinstance *, union node **, union node *);
     115STATIC union node *makename(shinstance *);
     116STATIC void parsefname(shinstance *);
     117STATIC void parseheredoc(shinstance *);
     118STATIC int peektoken(shinstance *);
     119STATIC int readtoken(shinstance *);
     120STATIC int xxreadtoken(shinstance *);
     121STATIC int readtoken1(shinstance *, int, char const *, char *, int);
     122STATIC int noexpand(shinstance *, char *);
     123STATIC void synexpect(shinstance *, int) __attribute__((__noreturn__));
     124STATIC void synerror(shinstance *, const char *) __attribute__((__noreturn__));
     125STATIC void setprompt(shinstance *, int);
    125126
    126127
     
    131132
    132133union node *
    133 parsecmd(int interact)
     134parsecmd(shinstance *psh, int interact)
    134135{
    135136        int t;
    136137
    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);
    141142        else
    142                 setprompt(0);
    143         needprompt = 0;
    144         t = readtoken();
     143                setprompt(psh, 0);
     144        psh->needprompt = 0;
     145        t = readtoken(psh);
    145146        if (t == TEOF)
    146147                return NEOF;
    147148        if (t == TNL)
    148149                return NULL;
    149         tokpushback++;
    150         return list(1);
     150        psh->tokpushback++;
     151        return list(psh, 1);
    151152}
    152153
    153154
    154155STATIC union node *
    155 list(int nlflag)
     156list(shinstance *psh, int nlflag)
    156157{
    157158        union node *n1, *n2, *n3;
    158159        int tok;
    159160
    160         checkkwd = 2;
    161         if (nlflag == 0 && tokendlist[peektoken()])
     161        psh->checkkwd = 2;
     162        if (nlflag == 0 && tokendlist[peektoken(psh)])
    162163                return NULL;
    163164        n1 = NULL;
    164165        for (;;) {
    165                 n2 = andor();
    166                 tok = readtoken();
     166                n2 = andor(psh);
     167                tok = readtoken(psh);
    167168                if (tok == TBACKGND) {
    168169                        if (n2->type == NCMD || n2->type == NPIPE) {
     
    191192                case TBACKGND:
    192193                case TSEMI:
    193                         tok = readtoken();
     194                        tok = readtoken(psh);
    194195                        /* fall through */
    195196                case TNL:
    196197                        if (tok == TNL) {
    197                                 parseheredoc();
     198                                parseheredoc(psh);
    198199                                if (nlflag)
    199200                                        return n1;
    200201                        } else {
    201                                 tokpushback++;
    202                         }
    203                         checkkwd = 2;
    204                         if (tokendlist[peektoken()])
     202                                psh->tokpushback++;
     203                        }
     204                        psh->checkkwd = 2;
     205                        if (tokendlist[peektoken(psh)])
    205206                                return n1;
    206207                        break;
    207208                case TEOF:
    208                         if (heredoclist)
    209                                 parseheredoc();
     209                        if (psh->heredoclist)
     210                                parseheredoc(psh);
    210211                        else
    211212                                pungetc(psh);           /* push back EOF on input */
     
    213214                default:
    214215                        if (nlflag)
    215                                 synexpect(-1);
    216                         tokpushback++;
     216                                synexpect(psh, -1);
     217                        psh->tokpushback++;
    217218                        return n1;
    218219                }
     
    223224
    224225STATIC union node *
    225 andor(void)
     226andor(shinstance *psh)
    226227{
    227228        union node *n1, *n2, *n3;
    228229        int t;
    229230
    230         n1 = pipeline();
     231        n1 = pipeline(psh);
    231232        for (;;) {
    232                 if ((t = readtoken()) == TAND) {
     233                if ((t = readtoken(psh)) == TAND) {
    233234                        t = NAND;
    234235                } else if (t == TOR) {
    235236                        t = NOR;
    236237                } else {
    237                         tokpushback++;
     238                        psh->tokpushback++;
    238239                        return n1;
    239240                }
    240                 n2 = pipeline();
     241                n2 = pipeline(psh);
    241242                n3 = (union node *)stalloc(psh, sizeof (struct nbinary));
    242243                n3->type = t;
     
    250251
    251252STATIC union node *
    252 pipeline(void)
     253pipeline(shinstance *psh)
    253254{
    254255        union node *n1, *n2, *pipenode;
     
    258259        negate = 0;
    259260        TRACE((psh, "pipeline: entered\n"));
    260         while (readtoken() == TNOT)
     261        while (readtoken(psh) == TNOT)
    261262                negate = !negate;
    262         tokpushback++;
    263         n1 = command();
    264         if (readtoken() == TPIPE) {
     263        psh->tokpushback++;
     264        n1 = command(psh);
     265        if (readtoken(psh) == TPIPE) {
    265266                pipenode = (union node *)stalloc(psh, sizeof (struct npipe));
    266267                pipenode->type = NPIPE;
     
    272273                        prev = lp;
    273274                        lp = (struct nodelist *)stalloc(psh, sizeof (struct nodelist));
    274                         lp->n = command();
     275                        lp->n = command(psh);
    275276                        prev->next = lp;
    276                 } while (readtoken() == TPIPE);
     277                } while (readtoken(psh) == TPIPE);
    277278                lp->next = NULL;
    278279                n1 = pipenode;
    279280        }
    280         tokpushback++;
     281        psh->tokpushback++;
    281282        if (negate) {
    282283                n2 = (union node *)stalloc(psh, sizeof (struct nnot));
     
    291292
    292293STATIC union node *
    293 command(void)
     294command(shinstance *psh)
    294295{
    295296        union node *n1, *n2;
     
    299300        int t, negate = 0;
    300301
    301         checkkwd = 2;
     302        psh->checkkwd = 2;
    302303        redir = NULL;
    303304        n1 = NULL;
     
    305306
    306307        /* 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;
    309310                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) {
    315316                TRACE((psh, "command: TNOT recognized\n"));
    316317                negate = !negate;
    317318        }
    318         tokpushback++;
    319 
    320         switch (readtoken()) {
     319        psh->tokpushback++;
     320
     321        switch (readtoken(psh)) {
    321322        case TIF:
    322323                n1 = (union node *)stalloc(psh, sizeof (struct nif));
    323324                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);
    328329                n2 = n1;
    329                 while (readtoken() == TELIF) {
     330                while (readtoken(psh) == TELIF) {
    330331                        n2->nif.elsepart = (union node *)stalloc(psh, sizeof (struct nif));
    331332                        n2 = n2->nif.elsepart;
    332333                        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);
    340341                else {
    341342                        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;
    347348                break;
    348349        case TWHILE:
     
    350351                int got;
    351352                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) {
     356TRACE((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;
    362363                break;
    363364        }
    364365        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");
    367368                n1 = (union node *)stalloc(psh, sizeof (struct nfor));
    368369                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")) {
    371372                        app = ≈
    372                         while (readtoken() == TWORD) {
     373                        while (readtoken(psh) == TWORD) {
    373374                                n2 = (union node *)stalloc(psh, sizeof (struct narg));
    374375                                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;
    377378                                *app = n2;
    378379                                app = &n2->narg.next;
     
    380381                        *app = NULL;
    381382                        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);
    384385                } else {
    385386                        static char argvars[5] = {CTLVAR, VSNORMAL|VSQUOTE,
     
    395396                         * that the original Bourne shell only allowed NL).
    396397                         */
    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)
    402403                        t = TDONE;
    403404                else if (t == TBEGIN)
    404405                        t = TEND;
    405406                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;
    411412                break;
    412413        case TCASE:
    413414                n1 = (union node *)stalloc(psh, sizeof (struct ncase));
    414415                n1->type = NCASE;
    415                 if (readtoken() != TWORD)
    416                         synexpect(TWORD);
     416                if (readtoken(psh) != TWORD)
     417                        synexpect(psh, TWORD);
    417418                n1->ncase.expr = n2 = (union node *)stalloc(psh, sizeof (struct narg));
    418419                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;
    421422                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\"");
    425426                cpp = &n1->ncase.cases;
    426                 noalias = 1;
    427                 checkkwd = 2, readtoken();
     427                psh->noalias = 1;
     428                psh->checkkwd = 2, readtoken(psh);
    428429                do {
    429430                        *cpp = cp = (union node *)stalloc(psh, sizeof (struct nclist));
     
    433434                                *app = ap = (union node *)stalloc(psh, sizeof (struct narg));
    434435                                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)
    438439                                        break;
    439440                                app = &ap->narg.next;
    440                                 readtoken();
     441                                readtoken(psh);
    441442                        }
    442443                        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) {
    451452                                if (t != TENDCASE) {
    452                                         noalias = 0;
    453                                         synexpect(TENDCASE);
     453                                        psh->noalias = 0;
     454                                        synexpect(psh, TENDCASE);
    454455                                } else {
    455                                         noalias = 1;
    456                                         checkkwd = 2;
    457                                         readtoken();
     456                                        psh->noalias = 1;
     457                                        psh->checkkwd = 2;
     458                                        readtoken(psh);
    458459                                }
    459460                        }
    460461                        cpp = &cp->nclist.next;
    461                 } while(lasttoken != TESAC);
    462                 noalias = 0;
     462                } while(psh->lasttoken != TESAC);
     463                psh->noalias = 0;
    463464                *cpp = NULL;
    464                 checkkwd = 1;
     465                psh->checkkwd = 1;
    465466                break;
    466467        case TLP:
    467468                n1 = (union node *)stalloc(psh, sizeof (struct nredir));
    468469                n1->type = NSUBSHELL;
    469                 n1->nredir.n = list(0);
     470                n1->nredir.n = list(psh, 0);
    470471                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;
    474475                break;
    475476        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;
    480481                break;
    481482        /* Handle an empty command like other simple commands.  */
     
    486487                 */
    487488                if (!redir)
    488                         synexpect(-1);
     489                        synexpect(psh, -1);
    489490        case TAND:
    490491        case TOR:
     
    493494        case TWORD:
    494495        case TRP:
    495                 tokpushback++;
    496                 n1 = simplecmd(rpp, redir);
     496                psh->tokpushback++;
     497                n1 = simplecmd(psh, rpp, redir);
    497498                goto checkneg;
    498499        default:
    499                 synexpect(-1);
     500                synexpect(psh, -1);
    500501                /* NOTREACHED */
    501502        }
    502503
    503504        /* 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;
    506507                rpp = &n2->nfile.next;
    507                 parsefname();
    508         }
    509         tokpushback++;
     508                parsefname(psh);
     509        }
     510        psh->tokpushback++;
    510511        *rpp = NULL;
    511512        if (redir) {
     
    532533
    533534STATIC union node *
    534 simplecmd(union node **rpp, union node *redir)
     535simplecmd(shinstance *psh, union node **rpp, union node *redir)
    535536{
    536537        union node *args, **app;
     
    553554        orig_rpp = rpp;
    554555
    555         while (readtoken() == TNOT) {
     556        while (readtoken(psh) == TNOT) {
    556557                TRACE((psh, "command: TNOT recognized\n"));
    557558                negate = !negate;
    558559        }
    559         tokpushback++;
     560        psh->tokpushback++;
    560561
    561562        for (;;) {
    562                 if (readtoken() == TWORD) {
     563                if (readtoken(psh) == TWORD) {
    563564                        n = (union node *)stalloc(psh, sizeof (struct narg));
    564565                        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;
    567568                        *app = n;
    568569                        app = &n->narg.next;
    569                 } else if (lasttoken == TREDIR) {
    570                         *rpp = n = redirnode;
     570                } else if (psh->lasttoken == TREDIR) {
     571                        *rpp = n = psh->redirnode;
    571572                        rpp = &n->nfile.next;
    572                         parsefname();   /* read name of redirection file */
    573                 } else if (lasttoken == TLP && app == &args->narg.next
     573                        parsefname(psh);        /* read name of redirection file */
     574                } else if (psh->lasttoken == TLP && app == &args->narg.next
    574575                                            && rpp == orig_rpp) {
    575576                        /* We have a function */
    576                         if (readtoken() != TRP)
    577                                 synexpect(TRP);
     577                        if (readtoken(psh) != TRP)
     578                                synexpect(psh, TRP);
    578579#ifdef notdef
    579580                        if (! goodname(n->narg.text))
    580                                 synerror("Bad function name");
     581                                synerror(psh, "Bad function name");
    581582#endif
    582583                        n->type = NDEFUN;
    583                         n->narg.next = command();
     584                        n->narg.next = command(psh);
    584585                        goto checkneg;
    585586                } else {
    586                         tokpushback++;
     587                        psh->tokpushback++;
    587588                        break;
    588589                }
     
    608609
    609610STATIC union node *
    610 makename(void)
     611makename(shinstance *psh)
    611612{
    612613        union node *n;
     
    615616        n->type = NARG;
    616617        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;
    619620        return n;
    620621}
    621622
    622 void fixredir(union node *n, const char *text, int err)
     623void fixredir(shinstance *psh, union node *n, const char *text, int err)
    623624        {
    624625        TRACE((psh, "Fix redir %s %d\n", text, err));
     
    633634
    634635                if (err)
    635                         synerror("Bad fd number");
     636                        synerror(psh, "Bad fd number");
    636637                else
    637                         n->ndup.vname = makename();
     638                        n->ndup.vname = makename(psh);
    638639        }
    639640}
     
    641642
    642643STATIC void
    643 parsefname(void)
    644 {
    645         union node *n = redirnode;
    646 
    647         if (readtoken() != TWORD)
    648                 synexpect(-1);
     644parsefname(shinstance *psh)
     645{
     646        union node *n = psh->redirnode;
     647
     648        if (readtoken(psh) != TWORD)
     649                synexpect(psh, -1);
    649650        if (n->type == NHERE) {
    650                 struct heredoc *here = heredoc;
     651                struct heredoc *here = psh->heredoc;
    651652                struct heredoc *p;
    652                 int i;
    653 
    654                 if (quoteflag == 0)
     653                size_t i;
     654
     655                if (psh->quoteflag == 0)
    655656                        n->type = NXHERE;
    656657                TRACE((psh, "Here document %d\n", n->type));
    657658                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;
    665666                here->next = NULL;
    666                 if (heredoclist == NULL)
    667                         heredoclist = here;
     667                if (psh->heredoclist == NULL)
     668                        psh->heredoclist = here;
    668669                else {
    669                         for (p = heredoclist ; p->next ; p = p->next);
     670                        for (p = psh->heredoclist ; p->next ; p = p->next);
    670671                        p->next = here;
    671672                }
    672673        } else if (n->type == NTOFD || n->type == NFROMFD) {
    673                 fixredir(n, wordtext, 0);
     674                fixredir(psh, n, psh->wordtext, 0);
    674675        } else {
    675                 n->nfile.fname = makename();
     676                n->nfile.fname = makename(psh);
    676677        }
    677678}
     
    683684
    684685STATIC void
    685 parseheredoc(void)
     686parseheredoc(shinstance *psh)
    686687{
    687688        struct heredoc *here;
    688689        union node *n;
    689690
    690         while (heredoclist) {
    691                 here = heredoclist;
    692                 heredoclist = here->next;
    693                 if (needprompt) {
    694                         setprompt(2);
    695                         needprompt = 0;
    696                 }
    697                 readtoken1(pgetc(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,
    698699                                here->eofmark, here->striptabs);
    699700                n = (union node *)stalloc(psh, sizeof (struct narg));
    700701                n->narg.type = NARG;
    701702                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;
    704705                here->here->nhere.doc = n;
    705706        }
     
    707708
    708709STATIC int
    709 peektoken(void)
     710peektoken(shinstance *psh)
    710711{
    711712        int t;
    712713
    713         t = readtoken();
    714         tokpushback++;
     714        t = readtoken(psh);
     715        psh->tokpushback++;
    715716        return (t);
    716717}
    717718
    718719STATIC int
    719 readtoken(void)
     720readtoken(shinstance *psh)
    720721{
    721722        int t;
    722         int savecheckkwd = checkkwd;
     723        int savecheckkwd = psh->checkkwd;
    723724#ifdef DEBUG
    724         int alreadyseen = tokpushback;
     725        int alreadyseen = psh->tokpushback;
    725726#endif
    726727        struct alias *ap;
    727728
    728729        top:
    729         t = xxreadtoken();
    730 
    731         if (checkkwd) {
     730        t = xxreadtoken(psh);
     731
     732        if (psh->checkkwd) {
    732733                /*
    733734                 * eat newlines
    734735                 */
    735                 if (checkkwd == 2) {
    736                         checkkwd = 0;
     736                if (psh->checkkwd == 2) {
     737                        psh->checkkwd = 0;
    737738                        while (t == TNL) {
    738                                 parseheredoc();
    739                                 t = xxreadtoken();
     739                                parseheredoc(psh);
     740                                t = xxreadtoken(psh);
    740741                        }
    741742                } else
    742                         checkkwd = 0;
     743                        psh->checkkwd = 0;
    743744                /*
    744745                 * check for keywords and aliases
    745746                 */
    746                 if (t == TWORD && !quoteflag)
     747                if (t == TWORD && !psh->quoteflag)
    747748                {
    748749                        const char *const *pp;
    749750
    750751                        for (pp = parsekwd; *pp; pp++) {
    751                                 if (**pp == *wordtext && equal(*pp, wordtext))
     752                                if (**pp == *psh->wordtext && equal(*pp, psh->wordtext))
    752753                                {
    753                                         lasttoken = t = pp -
    754                                             parsekwd + KWDOFFSET;
     754                                        psh->lasttoken = t = (int)(pp -
     755                                            parsekwd + KWDOFFSET);
    755756                                        TRACE((psh, "keyword %s recognized\n", tokname[t]));
    756757                                        goto out;
    757758                                }
    758759                        }
    759                         if(!noalias &&
    760                             (ap = lookupalias(psh, wordtext, 1)) != NULL) {
     760                        if(!psh->noalias &&
     761                            (ap = lookupalias(psh, psh->wordtext, 1)) != NULL) {
    761762                                pushstring(psh, ap->val, strlen(ap->val), ap);
    762                                 checkkwd = savecheckkwd;
     763                                psh->checkkwd = savecheckkwd;
    763764                                goto top;
    764765                        }
    765766                }
    766767out:
    767                 checkkwd = (t == TNOT) ? savecheckkwd : 0;
     768                psh->checkkwd = (t == TNOT) ? savecheckkwd : 0;
    768769        }
    769770#ifdef DEBUG
    770771        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 : ""));
    772773        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 : ""));
    774775#endif
    775776        return (t);
     
    779780/*
    780781 * Read the next input token.
    781  * If the token is a word, we set backquotelist to the list of cmds in
    782  *      backquotes.  We set quoteflag to true if any part of the word was
     782 * 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
    783784 *      quoted.
    784  * If the token is TREDIR, then we set redirnode to a structure containing
     785 * If the token is TREDIR, then we set psh->redirnode to a structure containing
    785786 *      the redirection.
    786  * In all cases, the variable startlinno is set to the number of the line
     787 * In all cases, the variable psh->startlinno is set to the number of the line
    787788 *      on which the token starts.
    788789 *
     
    795796 */
    796797
    797 #define RETURN(token)   return lasttoken = token
     798#define RETURN(token)   return psh->lasttoken = token
    798799
    799800STATIC int
    800 xxreadtoken(void)
     801xxreadtoken(shinstance *psh)
    801802{
    802803        int c;
    803804
    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;
    813814        for (;;) {      /* until token or start of word found */
    814815                c = pgetc_macro(psh);
     
    824825                case '\\':
    825826                        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);
    829830                                else
    830                                         setprompt(0);
     831                                        setprompt(psh, 0);
    831832                                continue;
    832833                        }
     
    834835                        goto breakloop;
    835836                case '\n':
    836                         plinno++;
    837                         needprompt = doprompt;
     837                        psh->plinno++;
     838                        psh->needprompt = psh->doprompt;
    838839                        RETURN(TNL);
    839840                case PEOF:
     
    863864        }
    864865breakloop:
    865         return readtoken1(c, BASESYNTAX, (char *)NULL, 0);
     866        return readtoken1(psh, c, BASESYNTAX, (char *)NULL, 0);
    866867#undef RETURN
    867868}
     
    911912
    912913STATIC int
    913 readtoken1(int firstc, char const *syntax, char *eofmark, int striptabs)
     914readtoken1(shinstance *psh, int firstc, char const *syntax, char *eofmark, int striptabs)
    914915{
    915916        int c = firstc;
     
    942943#endif
    943944
    944         startlinno = plinno;
     945        psh->startlinno = psh->plinno;
    945946        dblquote = 0;
    946947        varnest = 0;
     
    956957        loop: { /* for each line, until end of word */
    957958#if ATTY
    958                 if (c == '\034' && doprompt
     959                if (c == '\034' && psh->doprompt
    959960                 && attyset() && ! equal(termval(), "emacs")) {
    960961                        attyline();
    961962                        if (syntax == BASESYNTAX)
    962                                 return readtoken();
     963                                return readtoken(psh);
    963964                        c = pgetc(psh);
    964965                        goto loop;
     
    973974                                        goto endword;   /* exit outer loop */
    974975                                USTPUTC(psh, c, out);
    975                                 plinno++;
    976                                 if (doprompt)
    977                                         setprompt(2);
     976                                psh->plinno++;
     977                                if (psh->doprompt)
     978                                        setprompt(psh, 2);
    978979                                else
    979                                         setprompt(0);
     980                                        setprompt(psh, 0);
    980981                                c = pgetc(psh);
    981982                                goto loop;              /* continue outer loop */
     
    996997                                }
    997998                                if (c == '\n') {
    998                                         if (doprompt)
    999                                                 setprompt(2);
     999                                        if (psh->doprompt)
     1000                                                setprompt(psh, 2);
    10001001                                        else
    1001                                                 setprompt(0);
     1002                                                setprompt(psh, 0);
    10021003                                        break;
    10031004                                }
     
    11281129endword:
    11291130        if (syntax == ARISYNTAX)
    1130                 synerror("Missing '))'");
    1131         if (syntax != BASESYNTAX && ! parsebackquote && 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");
    11331134        if (varnest != 0) {
    1134                 startlinno = plinno;
     1135                psh->startlinno = psh->plinno;
    11351136                /* { */
    1136                 synerror("Missing '}'");
     1137                synerror(psh, "Missing '}'");
    11371138        }
    11381139        USTPUTC(psh, '\0', out);
    1139         len = out - stackblock(psh);
     1140        len = (int)(out - stackblock(psh));
    11401141        out = stackblock(psh);
    11411142        if (eofmark == NULL) {
     
    11451146                 && (*out == '\0' || is_digit(*out))) {
    11461147                        PARSEREDIR();
    1147                         return lasttoken = TREDIR;
     1148                        return psh->lasttoken = TREDIR;
    11481149                } else {
    11491150                        pungetc(psh);
    11501151                }
    11511152        }
    1152         quoteflag = quotef;
    1153         backquotelist = bqlist;
     1153        psh->quoteflag = quotef;
     1154        psh->backquotelist = bqlist;
    11541155        grabstackblock(psh, len);
    1155         wordtext = out;
     1156        psh->wordtext = out;
    11561157        if (dblquotep != NULL)
    11571158            ckfree(dblquotep);
    1158         return lasttoken = TWORD;
     1159        return psh->lasttoken = TWORD;
    11591160/* end of readtoken routine */
    11601161
     
    11811182                                if (*p == '\n' && *q == '\0') {
    11821183                                        c = PEOF;
    1183                                         plinno++;
    1184                                         needprompt = doprompt;
     1184                                        psh->plinno++;
     1185                                        psh->needprompt = psh->doprompt;
    11851186                                } else {
    11861187                                        pushstring(psh, line, strlen(line), NULL);
     
    12261227                        }
    12271228                        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;
    12301231                        if ((c = pgetc(psh)) == '-') {
    1231                                 heredoc->striptabs = 1;
     1232                                psh->heredoc->striptabs = 1;
    12321233                        } else {
    1233                                 heredoc->striptabs = 0;
     1234                                psh->heredoc->striptabs = 0;
    12341235                                pungetc(psh);
    12351236                        }
     
    12521253        if (fd != '\0')
    12531254                np->nfile.fd = digit_val(fd);
    1254         redirnode = np;
     1255        psh->redirnode = np;
    12551256        goto parseredir_return;
    12561257}
     
    12821283        } else {
    12831284                USTPUTC(psh, CTLVAR, out);
    1284                 typeloc = out - stackblock(psh);
     1285                typeloc = (int)(out - stackblock(psh));
    12851286                USTPUTC(psh, VSNORMAL, out);
    12861287                subtype = VSNORMAL;
     
    13121313                }
    13131314                else
    1314 badsub:                 synerror("Bad substitution");
     1315badsub:                 synerror(psh, "Bad substitution");
    13151316
    13161317                STPUTC(psh, '=', out);
     
    13261327                                if (p == NULL)
    13271328                                        goto badsub;
    1328                                 subtype = p - types + VSNORMAL;
     1329                                subtype = (int)(p - types + VSNORMAL);
    13291330                                break;
    13301331                        case '%':
     
    13811382#endif
    13821383
    1383         savepbq = parsebackquote;
     1384        savepbq = psh->parsebackquote;
    13841385        if (setjmp(jmploc.loc)) {
    13851386                if (str)
    13861387                        ckfree(str);
    1387                 parsebackquote = 0;
     1388                psh->parsebackquote = 0;
    13881389                psh->handler = savehandler;
    13891390                longjmp(psh->handler->loc, 1);
     
    13911392        INTOFF;
    13921393        str = NULL;
    1393         savelen = out - stackblock(psh);
     1394        savelen = (int)(out - stackblock(psh));
    13941395        if (savelen > 0) {
    13951396                str = ckmalloc(savelen);
     
    14111412                STARTSTACKSTR(psh, pout);
    14121413                for (;;) {
    1413                         if (needprompt) {
    1414                                 setprompt(2);
    1415                                 needprompt = 0;
     1414                        if (psh->needprompt) {
     1415                                setprompt(psh, 2);
     1416                                psh->needprompt = 0;
    14161417                        }
    14171418                        switch (pc = pgetc(psh)) {
     
    14211422                        case '\\':
    14221423                                if ((pc = pgetc(psh)) == '\n') {
    1423                                         plinno++;
    1424                                         if (doprompt)
    1425                                                 setprompt(2);
     1424                                        psh->plinno++;
     1425                                        if (psh->doprompt)
     1426                                                setprompt(psh, 2);
    14261427                                        else
    1427                                                 setprompt(0);
     1428                                                setprompt(psh, 0);
    14281429                                        /*
    14291430                                         * If eating a newline, avoid putting
     
    14401441
    14411442                        case '\n':
    1442                                 plinno++;
    1443                                 needprompt = doprompt;
     1443                                psh->plinno++;
     1444                                psh->needprompt = psh->doprompt;
    14441445                                break;
    14451446
    14461447                        case PEOF:
    1447                                 startlinno = plinno;
    1448                                 synerror("EOF in backquote substitution");
     1448                                psh->startlinno = psh->plinno;
     1449                                synerror(psh, "EOF in backquote substitution");
    14491450                                break;
    14501451
     
    14561457done:
    14571458                STPUTC(psh, '\0', pout);
    1458                 psavelen = pout - stackblock(psh);
     1459                psavelen = (int)(pout - stackblock(psh));
    14591460                if (psavelen > 0) {
    14601461                        pstr = grabstackstr(psh, pout);
     
    14671468        *nlpp = (struct nodelist *)stalloc(psh, sizeof (struct nodelist));
    14681469        (*nlpp)->next = NULL;
    1469         parsebackquote = oldstyle;
     1470        psh->parsebackquote = oldstyle;
    14701471
    14711472        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);
    14771478
    14781479        if (oldstyle)
    1479                 doprompt = saveprompt;
     1480                psh->doprompt = saveprompt;
    14801481        else {
    1481                 if (readtoken() != TRP)
    1482                         synexpect(TRP);
     1482                if (readtoken(psh) != TRP)
     1483                        synexpect(psh, TRP);
    14831484        }
    14841485
     
    14901491                 */
    14911492                popfile(psh);
    1492                 tokpushback = 0;
     1493                psh->tokpushback = 0;
    14931494        }
    14941495        while (stackblocksize(psh) <= savelen)
     
    15031504                INTON;
    15041505        }
    1505         parsebackquote = savepbq;
     1506        psh->parsebackquote = savepbq;
    15061507        psh->handler = savehandler;
    15071508        if (arinest || ISDBLQUOTE())
     
    15441545#ifdef mkinit
    15451546RESET {
    1546         tokpushback = 0;
    1547         checkkwd = 0;
     1547        psh->tokpushback = 0;
     1548        psh->checkkwd = 0;
    15481549}
    15491550#endif
     
    15551556
    15561557STATIC int
    1557 noexpand(char *text)
     1558noexpand(shinstance *psh, char *text)
    15581559{
    15591560        char *p;
     
    15791580
    15801581int
    1581 goodname(char *name)
    1582         {
    1583         char *p;
     1582goodname(const char *name)
     1583{
     1584        const char *p;
    15841585
    15851586        p = name;
     
    16011602
    16021603STATIC void
    1603 synexpect(int token)
     1604synexpect(shinstance *psh, int token)
    16041605{
    16051606        char msg[64];
     
    16071608        if (token >= 0) {
    16081609                fmtstr(msg, 64, "%s unexpected (expecting %s)",
    1609                         tokname[lasttoken], tokname[token]);
     1610                        tokname[psh->lasttoken], tokname[token]);
    16101611        } 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);
    16141615        /* NOTREACHED */
    16151616}
     
    16171618
    16181619STATIC void
    1619 synerror(const char *msg)
    1620 {
    1621         if (commandname)
    1622                 outfmt(&psh->errout, "%s: %d: ", commandname, startlinno);
     1620synerror(shinstance *psh, const char *msg)
     1621{
     1622        if (psh->commandname)
     1623                outfmt(&psh->errout, "%s: %d: ", psh->commandname, psh->startlinno);
    16231624        outfmt(&psh->errout, "Syntax error: %s\n", msg);
    16241625        error(psh, (char *)NULL);
     
    16271628
    16281629STATIC void
    1629 setprompt(int which)
     1630setprompt(shinstance *psh, int which)
    16301631{
    16311632        psh->whichprompt = which;
     
    16341635        if (!el)
    16351636#endif
    1636                 out2str(getprompt(NULL));
     1637                out2str(psh, getprompt(psh, NULL));
    16371638}
    16381639
     
    16421643 */
    16431644const char *
    1644 getprompt(void *unused)
    1645         {
     1645getprompt(shinstance *psh, void *unused)
     1646{
    16461647        switch (psh->whichprompt) {
    16471648        case 0:
    16481649                return "";
    16491650        case 1:
    1650                 return ps1val();
     1651                return ps1val(psh);
    16511652        case 2:
    1652                 return ps2val();
     1653                return ps2val(psh);
    16531654        default:
    16541655                return "<internal prompt error>";
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette