Ignore:
Timestamp:
Oct 7, 2007, 1:57:35 AM (18 years ago)
Author:
bird
Message:

input.c

File:
1 edited

Legend:

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

    r1199 r1201  
    6969#include "parser.h"
    7070#include "myhistedit.h"
     71#include "shinstance.h"
    7172
    7273#define EOF_NLEFT -99           /* value of parsenleft when EOF pushed back */
    7374
    74 MKINIT
    75 struct strpush {
    76         struct strpush *prev;   /* preceding string on stack */
    77         char *prevstring;
    78         int prevnleft;
    79         int prevlleft;
    80         struct alias *ap;       /* if push was associated with an alias */
    81 };
    82 
    83 /*
    84  * The parsefile structure pointed to by the global variable parsefile
    85  * contains information about the current file being read.
    86  */
    87 
    88 MKINIT
    89 struct parsefile {
    90         struct parsefile *prev; /* preceding file on stack */
    91         int linno;              /* current line */
    92         int fd;                 /* file descriptor (or -1 if string) */
    93         int nleft;              /* number of chars left in this line */
    94         int lleft;              /* number of chars left in this buffer */
    95         char *nextc;            /* next char in buffer */
    96         char *buf;              /* input buffer */
    97         struct strpush *strpush; /* for pushing strings at this level */
    98         struct strpush basestrpush; /* so pushing one is fast */
    99 };
    100 
    101 
    102 int plinno = 1;                 /* input line number */
    103 int parsenleft;                 /* copy of parsefile->nleft */
    104 MKINIT int parselleft;          /* copy of parsefile->lleft */
    105 char *parsenextc;               /* copy of parsefile->nextc */
    106 MKINIT struct parsefile basepf; /* top level input file */
    107 MKINIT char basebuf[BUFSIZ];    /* buffer for top level input file */
    108 struct parsefile *parsefile = &basepf;  /* current input file */
    109 int init_editline = 0;          /* editline library initialized? */
    110 int whichprompt;                /* 1 == PS1, 2 == PS2 */
    111 
    112 #ifndef SMALL
    113 EditLine *el;                   /* cookie for editline package */
    114 #endif
    115 
    116 STATIC void pushfile(void);
    117 static int preadfd(void);
     75//MKINIT
     76//struct strpush {
     77//      struct strpush *prev;   /* preceding string on stack */
     78//      char *prevstring;
     79//      int prevnleft;
     80//      int prevlleft;
     81//      struct alias *ap;       /* if push was associated with an alias */
     82//};
     83//
     84///*
     85// * The parsefile structure pointed to by the global variable parsefile
     86// * contains information about the current file being read.
     87// */
     88//
     89//MKINIT
     90//struct parsefile {
     91//      struct parsefile *prev; /* preceding file on stack */
     92//      int linno;              /* current line */
     93//      int fd;                 /* file descriptor (or -1 if string) */
     94//      int nleft;              /* number of chars left in this line */
     95//      int lleft;              /* number of chars left in this buffer */
     96//      char *nextc;            /* next char in buffer */
     97//      char *buf;              /* input buffer */
     98//      struct strpush *strpush; /* for pushing strings at this level */
     99//      struct strpush basestrpush; /* so pushing one is fast */
     100//};
     101//
     102//
     103//int plinno = 1;                       /* input line number */
     104//int parsenleft;                       /* copy of parsefile->nleft */
     105//MKINIT int parselleft;                /* copy of parsefile->lleft */
     106//char *parsenextc;             /* copy of parsefile->nextc */
     107//MKINIT struct parsefile basepf;       /* top level input file */
     108//MKINIT char basebuf[BUFSIZ];  /* buffer for top level input file */
     109//struct parsefile *parsefile = &basepf;        /* current input file */
     110//int init_editline = 0;                /* editline library initialized? */
     111//int whichprompt;              /* 1 == PS1, 2 == PS2 */
     112//
     113//#ifndef SMALL
     114//EditLine *el;                 /* cookie for editline package */
     115//#endif
     116
     117STATIC void pushfile(shinstance *psh);
     118static int preadfd(shinstance *psh);
    118119
    119120#ifdef mkinit
     
    123124
    124125INIT {
    125         basepf.nextc = basepf.buf = basebuf;
     126        psh->basepf.nextc = psh->basepf.buf = psh->basebuf;
    126127}
    127128
    128129RESET {
    129         if (exception != EXSHELLPROC)
    130                 parselleft = parsenleft = 0;    /* clear input buffer */
    131         popallfiles();
     130        if (psh->exception != EXSHELLPROC)
     131                psh->parselleft = psh->parsenleft = 0;  /* clear input buffer */
     132        popallfiles(psh);
    132133}
    133134
    134135SHELLPROC {
    135         popallfiles();
     136        popallfiles(psh);
    136137}
    137138#endif
     
    143144
    144145char *
    145 pfgets(char *line, int len)
     146pfgets(shinstance *psh, char *line, int len)
    146147{
    147148        char *p = line;
     
    150151
    151152        while (--nleft > 0) {
    152                 c = pgetc_macro();
     153                c = pgetc_macro(psh);
    153154                if (c == PEOF) {
    154155                        if (p == line)
     
    172173
    173174int
    174 pgetc(void)
    175 {
    176         return pgetc_macro();
     175pgetc(shinstance *psh)
     176{
     177        return pgetc_macro(psh);
    177178}
    178179
    179180
    180181static int
    181 preadfd(void)
     182preadfd(shinstance *psh)
    182183{
    183184        int nr;
    184         char *buf =  parsefile->buf;
    185         parsenextc = buf;
     185        char *buf = psh->parsefile->buf;
     186        psh->parsenextc = buf;
    186187
    187188retry:
    188189#ifndef SMALL
    189         if (parsefile->fd == 0 && el) {
     190        if (psh->parsefile->fd == 0 && psh->el) {
    190191                static const char *rl_cp;
    191192                static int el_len;
    192193
    193194                if (rl_cp == NULL)
    194                         rl_cp = el_gets(el, &el_len);
     195                        rl_cp = el_gets(psh->el, &el_len);
    195196                if (rl_cp == NULL)
    196197                        nr = 0;
     
    209210        } else
    210211#endif
    211                 nr = read(parsefile->fd, buf, BUFSIZ - 8);
     212                nr = shfile_read(&psh->fdtab, psh->parsefile->fd, buf, BUFSIZ - 8);
    212213
    213214
     
    216217                        if (errno == EINTR)
    217218                                goto retry;
    218                         if (parsefile->fd == 0 && errno == EWOULDBLOCK) {
    219                                 int flags = fcntl(0, F_GETFL, 0);
     219                        if (psh->parsefile->fd == 0 && errno == EWOULDBLOCK) {
     220                                int flags = shfile_fcntl(&psh->fdtab, 0, F_GETFL, 0);
    220221                                if (flags >= 0 && flags & O_NONBLOCK) {
    221222                                        flags &=~ O_NONBLOCK;
    222                                         if (fcntl(0, F_SETFL, flags) >= 0) {
     223                                        if (shfile_fcntl(&psh->fdtab, 0, F_SETFL, flags) >= 0) {
    223224                                                out2str(psh, "sh: turning off NDELAY mode\n");
    224225                                                goto retry;
     
    243244
    244245int
    245 preadbuffer(void)
     246preadbuffer(shinstance *psh)
    246247{
    247248        char *p, *q;
     
    250251        char savec;
    251252
    252         if (parsefile->strpush) {
    253                 popstring();
    254                 if (--parsenleft >= 0)
    255                         return (*parsenextc++);
    256         }
    257         if (parsenleft == EOF_NLEFT || parsefile->buf == NULL)
     253        if (psh->parsefile->strpush) {
     254                popstring(psh);
     255                if (--psh->parsenleft >= 0)
     256                        return (*psh->parsenextc++);
     257        }
     258        if (psh->parsenleft == EOF_NLEFT || psh->parsefile->buf == NULL)
    258259                return PEOF;
    259         flushout(&output);
    260         flushout(&errout);
     260        flushout(&psh->output);
     261        flushout(&psh->errout);
    261262
    262263again:
    263         if (parselleft <= 0) {
    264                 if ((parselleft = preadfd()) == -1) {
    265                         parselleft = parsenleft = EOF_NLEFT;
     264        if (psh->parselleft <= 0) {
     265                if ((psh->parselleft = preadfd(psh)) == -1) {
     266                        psh->parselleft = psh->parsenleft = EOF_NLEFT;
    266267                        return PEOF;
    267268                }
    268269        }
    269270
    270         q = p = parsenextc;
     271        q = p = psh->parsenextc;
    271272
    272273        /* delete nul characters */
     
    283284
    284285                case '\n':
    285                         parsenleft = q - parsenextc;
     286                        psh->parsenleft = (int)(q - psh->parsenextc);
    286287                        more = 0; /* Stop processing here */
    287288                        break;
     
    294295                *q++ = *p++;
    295296check:
    296                 if (--parselleft <= 0) {
    297                         parsenleft = q - parsenextc - 1;
    298                         if (parsenleft < 0)
     297                if (--psh->parselleft <= 0) {
     298                        psh->parsenleft = (int)(q - psh->parsenextc - 1);
     299                        if (psh->parsenleft < 0)
    299300                                goto again;
    300301                        *q = '\0';
     
    307308
    308309#ifndef SMALL
    309         if (parsefile->fd == 0 && hist && something) {
     310        if (psh->parsefile->fd == 0 && hist && something) {
    310311                HistEvent he;
    311312                INTOFF;
    312                 history(hist, &he, whichprompt == 1? H_ENTER : H_APPEND,
    313                     parsenextc);
     313                history(hist, &he, psh->whichprompt == 1? H_ENTER : H_APPEND,
     314                    psh->parsenextc);
    314315                INTON;
    315316        }
     
    317318
    318319        if (vflag(psh)) {
    319                 out2str(psh, parsenextc);
    320                 flushout(out2);
     320                out2str(psh, psh->parsenextc);
     321                flushout(psh->out2);
    321322        }
    322323
    323324        *q = savec;
    324325
    325         return *parsenextc++;
     326        return *psh->parsenextc++;
    326327}
    327328
     
    332333
    333334void
    334 pungetc(void)
    335 {
    336         parsenleft++;
    337         parsenextc--;
     335pungetc(shinstance *psh)
     336{
     337        psh->parsenleft++;
     338        psh->parsenextc--;
    338339}
    339340
     
    343344 */
    344345void
    345 pushstring(char *s, int len, void *ap)
     346pushstring(shinstance *psh, char *s, int len, void *ap)
    346347{
    347348        struct strpush *sp;
     
    349350        INTOFF;
    350351/*dprintf("*** calling pushstring: %s, %d\n", s, len);*/
    351         if (parsefile->strpush) {
     352        if (psh->parsefile->strpush) {
    352353                sp = ckmalloc(sizeof (struct strpush));
    353                 sp->prev = parsefile->strpush;
    354                 parsefile->strpush = sp;
     354                sp->prev = psh->parsefile->strpush;
     355                psh->parsefile->strpush = sp;
    355356        } else
    356                 sp = parsefile->strpush = &(parsefile->basestrpush);
    357         sp->prevstring = parsenextc;
    358         sp->prevnleft = parsenleft;
    359         sp->prevlleft = parselleft;
     357                sp = psh->parsefile->strpush = &(psh->parsefile->basestrpush);
     358        sp->prevstring = psh->parsenextc;
     359        sp->prevnleft = psh->parsenleft;
     360        sp->prevlleft = psh->parselleft;
    360361        sp->ap = (struct alias *)ap;
    361362        if (ap)
    362363                ((struct alias *)ap)->flag |= ALIASINUSE;
    363         parsenextc = s;
    364         parsenleft = len;
     364        psh->parsenextc = s;
     365        psh->parsenleft = len;
    365366        INTON;
    366367}
    367368
    368369void
    369 popstring(void)
    370 {
    371         struct strpush *sp = parsefile->strpush;
     370popstring(shinstance *psh)
     371{
     372        struct strpush *sp = psh->parsefile->strpush;
    372373
    373374        INTOFF;
    374         parsenextc = sp->prevstring;
    375         parsenleft = sp->prevnleft;
    376         parselleft = sp->prevlleft;
    377 /*dprintf("*** calling popstring: restoring to '%s'\n", parsenextc);*/
     375        psh->parsenextc = sp->prevstring;
     376        psh->parsenleft = sp->prevnleft;
     377        psh->parselleft = sp->prevlleft;
     378/*dprintf("*** calling popstring: restoring to '%s'\n", psh->parsenextc);*/
    378379        if (sp->ap)
    379380                sp->ap->flag &= ~ALIASINUSE;
    380         parsefile->strpush = sp->prev;
    381         if (sp != &(parsefile->basestrpush))
     381        psh->parsefile->strpush = sp->prev;
     382        if (sp != &(psh->parsefile->basestrpush))
    382383                ckfree(sp);
    383384        INTON;
     
    390391
    391392void
    392 setinputfile(const char *fname, int push)
     393setinputfile(shinstance *psh, const char *fname, int push)
    393394{
    394395        int fd;
     
    396397
    397398        INTOFF;
    398         if ((fd = open(fname, O_RDONLY)) < 0)
     399/** @todo shfile fixme */
     400        if ((fd = shfile_open(&psh->fdtab, fname, O_RDONLY)) < 0)
    399401                error(psh, "Can't open %s", fname);
    400402        if (fd < 10) {
    401                 fd2 = copyfd(fd, 10);
    402                 close(fd);
     403                fd2 = copyfd(psh, fd, 10);
     404                shfile_close(&psh->fdtab, fd);
    403405                if (fd2 < 0)
    404406                        error(psh, "Out of file descriptors");
    405407                fd = fd2;
    406408        }
    407         setinputfd(fd, push);
     409        setinputfd(psh, fd, push);
    408410        INTON;
    409411}
     
    416418
    417419void
    418 setinputfd(int fd, int push)
    419 {
    420         (void) fcntl(fd, F_SETFD, FD_CLOEXEC);
     420setinputfd(shinstance *psh, int fd, int push)
     421{
     422        (void) shfile_fcntl(&psh->fdtab, fd, F_SETFD, FD_CLOEXEC);
    421423        if (push) {
    422                 pushfile();
    423                 parsefile->buf = ckmalloc(BUFSIZ);
    424         }
    425         if (parsefile->fd > 0)
    426                 close(parsefile->fd);
    427         parsefile->fd = fd;
    428         if (parsefile->buf == NULL)
    429                 parsefile->buf = ckmalloc(BUFSIZ);
    430         parselleft = parsenleft = 0;
    431         plinno = 1;
     424                pushfile(psh);
     425                psh->parsefile->buf = ckmalloc(BUFSIZ);
     426        }
     427        if (psh->parsefile->fd > 0)
     428                shfile_close(&psh->fdtab, psh->parsefile->fd);
     429        psh->parsefile->fd = fd;
     430        if (psh->parsefile->buf == NULL)
     431                psh->parsefile->buf = ckmalloc(BUFSIZ);
     432        psh->parselleft = psh->parsenleft = 0;
     433        psh->plinno = 1;
    432434}
    433435
     
    438440
    439441void
    440 setinputstring(char *string, int push)
     442setinputstring(shinstance *psh, char *string, int push)
    441443{
    442444        INTOFF;
    443445        if (push)
    444                 pushfile();
    445         parsenextc = string;
    446         parselleft = parsenleft = strlen(string);
    447         parsefile->buf = NULL;
    448         plinno = 1;
     446                pushfile(psh);
     447        psh->parsenextc = string;
     448        psh->parselleft = psh->parsenleft = (int)strlen(string);
     449        psh->parsefile->buf = NULL;
     450        psh->plinno = 1;
    449451        INTON;
    450452}
     
    458460
    459461STATIC void
    460 pushfile(void)
     462pushfile(shinstance *psh)
    461463{
    462464        struct parsefile *pf;
    463465
    464         parsefile->nleft = parsenleft;
    465         parsefile->lleft = parselleft;
    466         parsefile->nextc = parsenextc;
    467         parsefile->linno = plinno;
     466        psh->parsefile->nleft = psh->parsenleft;
     467        psh->parsefile->lleft = psh->parselleft;
     468        psh->parsefile->nextc = psh->parsenextc;
     469        psh->parsefile->linno = psh->plinno;
    468470        pf = (struct parsefile *)ckmalloc(sizeof (struct parsefile));
    469         pf->prev = parsefile;
     471        pf->prev = psh->parsefile;
    470472        pf->fd = -1;
    471473        pf->strpush = NULL;
    472474        pf->basestrpush.prev = NULL;
    473         parsefile = pf;
    474 }
    475 
    476 
    477 void
    478 popfile(void)
    479 {
    480         struct parsefile *pf = parsefile;
     475        psh->parsefile = pf;
     476}
     477
     478
     479void
     480popfile(shinstance *psh)
     481{
     482        struct parsefile *pf = psh->parsefile;
    481483
    482484        INTOFF;
    483485        if (pf->fd >= 0)
    484                 close(pf->fd);
     486                shfile_close(&psh->fdtab, pf->fd);
    485487        if (pf->buf)
    486488                ckfree(pf->buf);
    487489        while (pf->strpush)
    488                 popstring();
    489         parsefile = pf->prev;
     490                popstring(psh);
     491        psh->parsefile = pf->prev;
    490492        ckfree(pf);
    491         parsenleft = parsefile->nleft;
    492         parselleft = parsefile->lleft;
    493         parsenextc = parsefile->nextc;
    494         plinno = parsefile->linno;
     493        psh->parsenleft = psh->parsefile->nleft;
     494        psh->parselleft = psh->parsefile->lleft;
     495        psh->parsenextc = psh->parsefile->nextc;
     496        psh->plinno = psh->parsefile->linno;
    495497        INTON;
    496498}
     
    502504
    503505void
    504 popallfiles(void)
    505 {
    506         while (parsefile != &basepf)
    507                 popfile();
     506popallfiles(shinstance *psh)
     507{
     508        while (psh->parsefile != &psh->basepf)
     509                popfile(psh);
    508510}
    509511
     
    525527
    526528void
    527 closescript(int vforked)
     529closescript(shinstance *psh, int vforked)
    528530{
    529531        if (vforked)
    530532                return;
    531         popallfiles();
    532         if (parsefile->fd > 0) {
    533                 close(parsefile->fd);
    534                 parsefile->fd = 0;
    535         }
    536 }
     533        popallfiles(psh);
     534        if (psh->parsefile->fd > 0) {
     535                shfile_close(&psh->fdtab, psh->parsefile->fd);
     536                psh->parsefile->fd = 0;
     537        }
     538}
Note: See TracChangeset for help on using the changeset viewer.