# 2.11BSD#431 - /usr/src/bin/tcsh/sh.glob.c

##### Functions

    Gcat              X
    Gmatch            X
    dobackp           X
    ginit             X
    globall           X
    globone           X
    rscan             X
    sortscmp          X
    tglob             X
    trim              X

##### Variables

    gargc             X
    gargv             X
    pargc             X
    pargv             X

##### Macros

    EOS               X
    GLOBSPACE         X
    G_CSH             X
    G_GLOB            X
    G_NONE            X
    LBRC              X
    LBRK              X
    RBRC              X
    RBRK              X
    TC_BUFSIZ         X

       1: /* $Header: /home/hyperion/mu/christos/src/sys/tcsh-6.00/RCS/sh.glob.c,v 3.0 1991/07/04 21:49:28 christos Exp $ */
       2: /*
       3:  * sh.glob.c: Regular expression expansion
       4:  */
       5: /*-
       6:  * Copyright (c) 1980, 1991 The Regents of the University of California.
       7:  * All rights reserved.
       8:  *
       9:  * Redistribution and use in source and binary forms, with or without
      10:  * modification, are permitted provided that the following conditions
      11:  * are met:
      12:  * 1. Redistributions of source code must retain the above copyright
      13:  *    notice, this list of conditions and the following disclaimer.
      14:  * 2. Redistributions in binary form must reproduce the above copyright
      15:  *    notice, this list of conditions and the following disclaimer in the
      16:  *    documentation and/or other materials provided with the distribution.
      17:  * 3. All advertising materials mentioning features or use of this software
      18:  *    must display the following acknowledgement:
      19:  *	This product includes software developed by the University of
      20:  *	California, Berkeley and its contributors.
      21:  * 4. Neither the name of the University nor the names of its contributors
      22:  *    may be used to endorse or promote products derived from this software
      23:  *    without specific prior written permission.
      24:  *
      25:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
      26:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
      27:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
      28:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
      29:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
      30:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
      31:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
      32:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
      33:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
      34:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
      35:  * SUCH DAMAGE.
      36:  */
      37: #include "config.h"
      38: #if !defined(lint) && !defined(pdp11)
      39: static char *rcsid()
      40:     { return "$Id: sh.glob.c,v 3.0 1991/07/04 21:49:28 christos Exp $"; }
      41: #endif
      42:
      43: #include "sh.h"
      44: #include <glob.h>
      45:
      46: static int noglob, nonomatch;
      47: static int pargsiz, gargsiz;
      48:
      49: /*
      50:  * Values for gflag
      51:  */
      52: #define G_NONE  0       /* No globbing needed			*/
      53: #define G_GLOB  1       /* string contains *?[] characters	*/
      54: #define G_CSH   2       /* string contains ~`{ characters	*/
      55:
      56: #define GLOBSPACE   100 /* Alloc increment			*/
      57:
      58: #define LBRC '{'
      59: #define RBRC '}'
      60: #define LBRK '['
      61: #define RBRK ']'
      62: #define EOS '\0'
      63:
      64: Char  **gargv = NULL;
      65: Char  **pargv = NULL;
      66: #ifdef  notdef
      67: int    gargc = 0;
      68: int    pargc = 0;
      69: #else
      70: long    gargc = 0;
      71: long    pargc = 0;
      72: #endif	/* pdp11 */
      73:
      74: /*
      75:  * globbing is now done in two stages. In the first pass we expand
      76:  * csh globbing idioms ~`{ and then we proceed doing the normal
      77:  * globbing if needed ?*[
      78:  *
      79:  * Csh type globbing is handled in globexpand() and the rest is
      80:  * handled in glob() which is part of the 4.4BSD libc.
      81:  *
      82:  */
      83: static  Char     *globtilde __P((Char **, Char *));
      84: static  Char     *globequal __P((Char **, Char *));
      85: static  Char    **libglob   __P((Char **));
      86: static  Char    **globexpand    __P((Char **));
      87: static  int   globbrace __P((Char *, Char *, Char ***));
      88: static  void      pword     __P((void));
      89: static  void      psave     __P((int));
      90: static  void      backeval  __P((Char *, bool));
      91:
      92: static Char *
      93: globtilde(nv, s)
      94:     Char  **nv, *s;
      95: {
      96:     Char    gbuf[MAXPATHLEN], *gstart, *b, *u, *e;
      97: #ifdef apollo
      98:     int slash;
      99: #endif
     100:
     101:     gstart = gbuf;
     102:     *gstart++ = *s++;
     103:     u = s;
     104:     for (b = gstart, e = &gbuf[MAXPATHLEN - 1]; *s && *s != '/' && b < e;
     105:      *b++ = *s++);
     106:     *b = EOS;
     107:     if (gethdir(gstart)) {
     108:     blkfree(nv);
     109:     if (*gstart)
     110:         stderror(ERR_UNKUSER, short2str(gstart));
     111:     else
     112:         stderror(ERR_NOHOME);
     113:     }
     114:     b = &gstart[Strlen(gstart)];
     115: #ifdef apollo
     116:     slash = gstart[0] == '/' && gstart[1] == '\0';
     117: #endif
     118:     while (*s)
     119:     *b++ = *s++;
     120:     *b = EOS;
     121:     --u;
     122:     xfree((ptr_t) u);
     123: #ifdef apollo
     124:     if (slash && gstart[1] == '/')
     125:     gstart++;
     126: #endif
     127:     return (Strsave(gstart));
     128: }
     129:
     130: static Char *
     131: globequal(nv, s)
     132:     Char  **nv, *s;
     133: {
     134:     int     dig;
     135:     Char    gp[MAXPATHLEN], *b, *d;
     136:
     137:     /*
     138:      * kfk - 17 Jan 1984 - stack hack allows user to get at arbitrary dir names
     139:      * in stack. PWP: let =foobar pass through (for X windows)
     140:      */
     141:     if ((Isdigit(s[1]) || s[1] == '-') && (s[2] == '\0' || s[2] == '/')) {
     142:     dig = (s[1] == '-') ? -1 : s[1] - '0';
     143:     if (!getstakd(gp, dig)) {
     144:         blkfree(nv);
     145:         stderror(ERR_DEEP);
     146:     }
     147:     for (b = &s[2], d = &gp[Strlen(gp)]; *d++ = *b++;);
     148:     xfree((ptr_t) s);
     149:     return (Strsave(gp));
     150:     }
     151:     else
     152:     return (s);
     153: }
     154:
     155: static int
     156: globbrace(s, p, bl)
     157:     Char   *s, *p, ***bl;
     158: {
     159:     int     i, len;
     160:     Char   *pm, *pe, *lm, *pl;
     161:     Char  **nv, **vl;
     162:     Char    gbuf[MAXPATHLEN];
     163:     int     size = GLOBSPACE;
     164:
     165:     nv = vl = (Char **) xmalloc((size_t) sizeof(Char *) * size);
     166:     *vl = NULL;
     167:
     168:     len = 0;
     169:     /* copy part up to the brace */
     170:     for (lm = gbuf, p = s; *p != LBRC; *lm++ = *p++)
     171:     continue;
     172:
     173:     /* check for balanced braces */
     174:     for (i = 0, pe = ++p; *pe; pe++)
     175:     if (*pe == LBRK) {
     176:         /* Ignore everything between [] */
     177:         for (++pe; *pe != RBRK && *pe != EOS; pe++)
     178:         continue;
     179:         if (*pe == EOS) {
     180:         blkfree(nv);
     181:         return (-RBRK);
     182:         }
     183:     }
     184:     else if (*pe == LBRC)
     185:         i++;
     186:     else if (*pe == RBRC) {
     187:         if (i == 0)
     188:         break;
     189:         i--;
     190:     }
     191:
     192:     if (i != 0 || *pe == '\0') {
     193:     blkfree(nv);
     194:     return (-RBRC);
     195:     }
     196:
     197:     for (i = 0, pl = pm = p; pm <= pe; pm++)
     198:     switch (*pm) {
     199:     case LBRK:
     200:         for (++pm; *pm != RBRK && *pm != EOS; pm++)
     201:         continue;
     202:         if (*pm == EOS) {
     203:         *vl = NULL;
     204:         blkfree(nv);
     205:         return (-RBRK);
     206:         }
     207:         break;
     208:     case LBRC:
     209:         i++;
     210:         break;
     211:     case RBRC:
     212:         if (i) {
     213:         i--;
     214:         break;
     215:         }
     216:         /* FALLTHROUGH */
     217:     case ',':
     218:         if (i && *pm == ',')
     219:         break;
     220:         else {
     221:         Char    savec = *pm;
     222:
     223:         *pm = EOS;
     224:         (void) Strcpy(lm, pl);
     225:         (void) Strcat(gbuf, pe + 1);
     226:         *pm = savec;
     227:         *vl++ = Strsave(gbuf);
     228:         len++;
     229:         pl = pm + 1;
     230:         if (vl == &nv[size]) {
     231:             size += GLOBSPACE;
     232:             nv = (Char **) xrealloc((ptr_t) nv, (size_t)
     233:                         size * sizeof(Char *));
     234:             vl = &nv[size - GLOBSPACE];
     235:         }
     236:         }
     237:         break;
     238:     }
     239:     *vl = NULL;
     240:     *bl = nv;
     241:     return (len);
     242: }
     243:
     244: static Char **
     245: globexpand(v)
     246:     Char  **v;
     247: {
     248:     Char   *s;
     249:     Char  **nv, **vl, **el;
     250:     int     size = GLOBSPACE;
     251:
     252:
     253:     nv = vl = (Char **) xmalloc((size_t) sizeof(Char *) * size);
     254:     *vl = NULL;
     255:
     256:     /*
     257:      * Step 1: expand backquotes.
     258:      */
     259:     while (s = *v++) {
     260:     if (Strchr(s, '`')) {
     261:         int     i;
     262:
     263:         (void) dobackp(s, 0);
     264:         for (i = 0; i < (int)pargc; i++) {
     265:         *vl++ = pargv[i];
     266:         if (vl == &nv[size]) {
     267:             size += GLOBSPACE;
     268:             nv = (Char **) xrealloc((ptr_t) nv,
     269:                         (size_t) size * sizeof(Char *));
     270:             vl = &nv[size - GLOBSPACE];
     271:         }
     272:         }
     273:         xfree((ptr_t) pargv);
     274:         pargv = NULL;
     275:     }
     276:     else {
     277:         *vl++ = Strsave(s);
     278:         if (vl == &nv[size]) {
     279:         size += GLOBSPACE;
     280:         nv = (Char **) xrealloc((ptr_t) nv, (size_t)
     281:                     size * sizeof(Char *));
     282:         vl = &nv[size - GLOBSPACE];
     283:         }
     284:     }
     285:     }
     286:     *vl = NULL;
     287:
     288:     if (noglob)
     289:     return (nv);
     290:
     291:     /*
     292:      * Step 2: expand braces
     293:      */
     294:     el = vl;
     295:     vl = nv;
     296:     for (s = *vl; s; s = *++vl) {
     297:     Char   *b;
     298:     Char  **vp, **bp;
     299:
     300:     if (b = Strchr(s, LBRC)) {
     301:         Char  **bl;
     302:         int     len;
     303:
     304:         if ((len = globbrace(s, b, &bl)) < 0) {
     305:         blkfree(nv);
     306:         stderror(ERR_MISSING, -len);
     307:         }
     308:         xfree((ptr_t) s);
     309:         if (len == 1) {
     310:         *vl-- = *bl;
     311:         xfree((ptr_t) bl);
     312:         continue;
     313:         }
     314:         len = blklen(bl);
     315:         if (&el[len] >= &nv[size]) {
     316:         int     l, e;
     317:
     318:         l = &el[len] - &nv[size];
     319:         size += GLOBSPACE > l ? GLOBSPACE : l;
     320:         l = vl - nv;
     321:         e = el - nv;
     322:         nv = (Char **) xrealloc((ptr_t) nv, (size_t)
     323:                     size * sizeof(Char *));
     324:         vl = nv + l;
     325:         el = nv + e;
     326:         }
     327:         vp = vl--;
     328:         *vp = *bl;
     329:         len--;
     330:         for (bp = el; bp != vp; bp--)
     331:         bp[len] = *bp;
     332:         el += len;
     333:         vp++;
     334:         for (bp = bl + 1; *bp; *vp++ = *bp++)
     335:         continue;
     336:         xfree((ptr_t) bl);
     337:     }
     338:
     339:     }
     340:
     341:     /*
     342:      * Step 3: expand ~ =
     343:      */
     344:     vl = nv;
     345:     for (s = *vl; s; s = *++vl)
     346:     switch (*s) {
     347:     case '~':
     348:         *vl = globtilde(nv, s);
     349:         break;
     350:     case '=':
     351:         *vl = globequal(nv, s);
     352:         break;
     353:     default:
     354:         break;
     355:     }
     356:     vl = nv;
     357:     return (vl);
     358: }
     359:
     360: static Char *
     361: handleone(str, vl, action)
     362:     Char   *str, **vl;
     363:     int     action;
     364: {
     365:
     366:     Char   *cp, **vlp = vl;
     367:
     368:     switch (action) {
     369:     case G_ERROR:
     370:     setname(short2str(str));
     371:     blkfree(vl);
     372:     stderror(ERR_NAME | ERR_AMBIG);
     373:     break;
     374:     case G_APPEND:
     375:     trim(vlp);
     376:     str = Strsave(*vlp++);
     377:     do {
     378:         cp = Strspl(str, STRspace);
     379:         xfree((ptr_t) str);
     380:         str = Strspl(cp, *vlp);
     381:         xfree((ptr_t) cp);
     382:     }
     383:     while (*++vlp);
     384:     blkfree(vl);
     385:     break;
     386:     case G_IGNORE:
     387:     str = Strsave(strip(*vlp));
     388:     blkfree(vl);
     389:     break;
     390:     }
     391:     return (str);
     392: }
     393:
     394: static Char **
     395: libglob(vl)
     396:     Char  **vl;
     397: {
     398:     int     gflgs = GLOB_QUOTE | GLOB_NOCHECK | GLOB_ALTNOT;
     399:     glob_t  globv;
     400:     char   *ptr;
     401:
     402:     globv.gl_offs = 0;
     403:     globv.gl_p_v = 0;
     404:     globv.gl_p_c = 0;
     405:     nonomatch = adrof(STRnonomatch) != 0;
     406:     do {
     407:     ptr = short2qstr(*vl);
     408:     switch (glob(ptr, gflgs, 0, &globv)) {
     409:     case GLOB_ABEND:
     410:         setname(ptr);
     411:         globfree(&globv);
     412:         stderror(ERR_NAME | ERR_GLOB);
     413:         /* NOTREACHED */
     414:     case GLOB_NOSPACE:
     415:         globfree(&globv);
     416:         stderror(ERR_NOMEM);
     417:         /* NOTREACHED */
     418:     default:
     419:         break;
     420:     }
     421:     if (!nonomatch && (globv.gl_matchc == 0) &&
     422:         (globv.gl_flags & GLOB_MAGCHAR)) {
     423:         globfree(&globv);
     424:         return (NULL);
     425:     }
     426:     gflgs |= GLOB_APPEND;
     427:     }
     428:     while (*++vl);
     429:     vl = blk2short(globv.gl_p_v);
     430:     globfree(&globv);
     431:     return (vl);
     432: }
     433:
     434: Char   *
     435: globone(str, action)
     436:     Char   *str;
     437:     int     action;
     438: {
     439:
     440:     Char   *v[2], **vl, **vo;
     441:
     442:     noglob = adrof(STRnoglob) != 0;
     443:     gflag = 0;
     444:     v[0] = str;
     445:     v[1] = 0;
     446:     tglob(v);
     447:     if (gflag == G_NONE)
     448:     return (strip(Strsave(str)));
     449:
     450:     if (gflag & G_CSH) {
     451:     /*
     452: 	 * Expand back-quote, tilde and brace
     453: 	 */
     454:     vo = globexpand(v);
     455:     if (noglob || (gflag & G_GLOB) == 0) {
     456:         if (vo[0] == NULL) {
     457:         xfree((ptr_t) vo);
     458:         return (Strsave(STRNULL));
     459:         }
     460:         if (vo[1] != NULL)
     461:         return (handleone(str, vo, action));
     462:         else {
     463:         str = strip(vo[0]);
     464:         xfree((ptr_t) vo);
     465:         return (str);
     466:         }
     467:     }
     468:     }
     469:     else if (noglob || (gflag & G_GLOB) == 0)
     470:     return (strip(Strsave(str)));
     471:     else
     472:     vo = v;
     473:
     474:     vl = libglob(vo);
     475:     if (gflag & G_CSH)
     476:     blkfree(vo);
     477:     if (vl == NULL) {
     478:     setname(short2str(str));
     479:     stderror(ERR_NAME | ERR_NOMATCH);
     480:     }
     481:     if (vl[0] == NULL) {
     482:     xfree((ptr_t) vl);
     483:     return (Strsave(STRNULL));
     484:     }
     485:     if (vl[1])
     486:     return (handleone(str, vl, action));
     487:     else {
     488:     str = strip(*vl);
     489:     xfree((ptr_t) vl);
     490:     return (str);
     491:     }
     492: }
     493:
     494: Char  **
     495: globall(v)
     496:     Char  **v;
     497: {
     498:     Char  **vl, **vo;
     499:
     500:     if (!v || !v[0]) {
     501:     gargv = saveblk(v);
     502:     gargc = blklen(gargv);
     503:     return (gargv);
     504:     }
     505:
     506:     noglob = adrof(STRnoglob) != 0;
     507:
     508:     if (gflag & G_CSH)
     509:     /*
     510: 	 * Expand back-quote, tilde and brace
     511: 	 */
     512:     vl = vo = globexpand(v);
     513:     else
     514:     vl = vo = saveblk(v);
     515:
     516:     if (!noglob && (gflag & G_GLOB)) {
     517:     vl = libglob(vo);
     518:     if (gflag & G_CSH)
     519:         blkfree(vo);
     520:     }
     521:
     522:     gargc = vl ? blklen(vl) : 0;
     523:     return (gargv = vl);
     524: }
     525:
     526: void
     527: ginit()
     528: {
     529:     gargsiz = GLOBSPACE;
     530:     gargv = (Char **) xmalloc((size_t) sizeof(Char *) * gargsiz);
     531:     gargv[0] = 0;
     532:     gargc = 0;
     533: }
     534:
     535: void
     536: rscan(t, f)
     537:     register Char **t;
     538:     void    (*f) ();
     539: {
     540:     register Char *p;
     541:
     542:     while (p = *t++)
     543:     while (*p)
     544:         (*f) (*p++);
     545: }
     546:
     547: void
     548: trim(t)
     549:     register Char **t;
     550: {
     551:     register Char *p;
     552:
     553:     while (p = *t++)
     554:     while (*p)
     555:         *p++ &= TRIM;
     556: }
     557:
     558: void
     559: tglob(t)
     560:     register Char **t;
     561: {
     562:     register Char *p, c;
     563:
     564:     while (p = *t++) {
     565:     if (*p == '~' || *p == '=')
     566:         gflag |= G_CSH;
     567:     else if (*p == '{' &&
     568:          (p[1] == '\0' || p[1] == '}' && p[2] == '\0'))
     569:         continue;
     570:     while (c = *p++)
     571:         if (isglob(c))
     572:         gflag |= (c == '{' || c == '`') ? G_CSH : G_GLOB;
     573:     }
     574: }
     575:
     576: /*
     577:  * Command substitute cp.  If literal, then this is a substitution from a
     578:  * << redirection, and so we should not crunch blanks and tabs, separating
     579:  * words only at newlines.
     580:  */
     581: #ifndef TC_BUFSIZ
     582:     /* jpn: needs to fit TERMCAP doing eval of tset results */
     583: #define TC_BUFSIZ 1024+4
     584: #endif
     585:
     586: Char  **
     587: dobackp(cp, literal)
     588:     Char   *cp;
     589:     bool    literal;
     590: {
     591:     register Char *lp, *rp;
     592:     Char   *ep, word[TC_BUFSIZ];
     593:
     594:     if (pargv) {
     595: #ifdef notdef
     596:     abort();
     597: #endif
     598:     blkfree(pargv);
     599:     }
     600:     pargsiz = GLOBSPACE;
     601:     pargv = (Char **) xmalloc((size_t) sizeof(Char *) * pargsiz);
     602:     pargv[0] = NOSTR;
     603:     pargcp = pargs = word;
     604:     pargc = 0;
     605:     pnleft = TC_BUFSIZ - 4;
     606:     for (;;) {
     607:     for (lp = cp; *lp != '`'; lp++) {
     608:         if (*lp == 0) {
     609:         if (pargcp != pargs)
     610:             pword();
     611:         return (pargv);
     612:         }
     613:         psave(*lp);
     614:     }
     615:     lp++;
     616:     for (rp = lp; *rp && *rp != '`'; rp++)
     617:         if (*rp == '\\') {
     618:         rp++;
     619:         if (!*rp)
     620:             goto oops;
     621:         }
     622:     if (!*rp)
     623:     oops:  stderror(ERR_UNMATCHED, '`');
     624:     ep = Strsave(lp);
     625:     ep[rp - lp] = 0;
     626:     backeval(ep, literal);
     627:     cp = rp + 1;
     628:     }
     629: }
     630:
     631: static void
     632: backeval(cp, literal)
     633:     Char   *cp;
     634:     bool    literal;
     635: {
     636:     register int icnt, c;
     637:     register Char *ip;
     638:     struct command faket;
     639:     bool    hadnl;
     640:     int     pvec[2], quoted;
     641:     Char   *fakecom[2], ibuf[BUFSIZ];
     642:     char    tibuf[BUFSIZ];
     643:
     644:     hadnl = 0;
     645:     icnt = 0;
     646:     quoted = (literal || (cp[0] & QUOTE)) ? QUOTE : 0;
     647:     faket.t_dtyp = NODE_COMMAND;
     648:     faket.t_dflg = 0;
     649:     faket.t_dlef = 0;
     650:     faket.t_drit = 0;
     651:     faket.t_dspr = 0;
     652:     faket.t_dcom = fakecom;
     653:     fakecom[0] = STRfk_com1;
     654:     fakecom[1] = 0;
     655:
     656:     /*
     657:      * We do the psave job to temporarily change the current job so that the
     658:      * following fork is considered a separate job.  This is so that when
     659:      * backquotes are used in a builtin function that calls glob the "current
     660:      * job" is not corrupted.  We only need one level of pushed jobs as long as
     661:      * we are sure to fork here.
     662:      */
     663:     psavejob();
     664:
     665:     /*
     666:      * It would be nicer if we could integrate this redirection more with the
     667:      * routines in sh.sem.c by doing a fake execute on a builtin function that
     668:      * was piped out.
     669:      */
     670:     mypipe(pvec);
     671:     if (pfork(&faket, -1) == 0) {
     672:     struct wordent paraml;
     673:     struct command *t;
     674:
     675:     (void) close(pvec[0]);
     676:     (void) dmove(pvec[1], 1);
     677:     (void) dmove(SHDIAG, 2);
     678:     initdesc();
     679:     /*
     680: 	 * Bugfix for nested backquotes by Michael Greim <greim@sbsvax.UUCP>,
     681: 	 * posted to comp.bugs.4bsd 12 Sep. 1989.
     682: 	 */
     683:     if (pargv)      /* mg, 21.dec.88 */
     684:         blkfree(pargv), pargv = 0, pargsiz = 0;
     685:     /* mg, 21.dec.88 */
     686:     arginp = cp;
     687:     while (*cp)
     688:         *cp++ &= TRIM;
     689:     (void) lex(&paraml);
     690:     if (seterr)
     691:         stderror(ERR_OLD);
     692:     alias(&paraml);
     693:     t = syntax(paraml.next, &paraml, 0);
     694:     if (seterr)
     695:         stderror(ERR_OLD);
     696:     if (t)
     697:         t->t_dflg |= F_NOFORK;
     698: #ifdef SIGTSTP
     699:     (void) sigignore(SIGTSTP);
     700: #endif
     701: #ifdef SIGTTIN
     702:     (void) sigignore(SIGTTIN);
     703: #endif
     704: #ifdef SIGTTOU
     705:     (void) sigignore(SIGTTOU);
     706: #endif
     707:     execute(t, -1, NULL, NULL);
     708:     exitstat();
     709:     }
     710:     xfree((ptr_t) cp);
     711:     (void) close(pvec[1]);
     712:     c = 0;
     713:     ip = NULL;
     714:     do {
     715:     int     cnt = 0;
     716:
     717:     for (;;) {
     718:         if (icnt == 0) {
     719:         int     i;
     720:
     721:         ip = ibuf;
     722:         do
     723:             icnt = read(pvec[0], tibuf, BUFSIZ);
     724:         while (icnt == -1 && errno == EINTR);
     725:         if (icnt <= 0) {
     726:             c = -1;
     727:             break;
     728:         }
     729:         for (i = 0; i < icnt; i++)
     730:             ip[i] = (unsigned char) tibuf[i];
     731:         }
     732:         if (hadnl)
     733:         break;
     734:         --icnt;
     735:         c = (*ip++ & TRIM);
     736:         if (c == 0)
     737:         break;
     738:         if (c == '\n') {
     739:         /*
     740: 		 * Continue around the loop one more time, so that we can eat
     741: 		 * the last newline without terminating this word.
     742: 		 */
     743:         hadnl = 1;
     744:         continue;
     745:         }
     746:         if (!quoted && (c == ' ' || c == '\t'))
     747:         break;
     748:         cnt++;
     749:         psave(c | quoted);
     750:     }
     751:     /*
     752: 	 * Unless at end-of-file, we will form a new word here if there were
     753: 	 * characters in the word, or in any case when we take text literally.
     754: 	 * If we didn't make empty words here when literal was set then we
     755: 	 * would lose blank lines.
     756: 	 */
     757:     if (c != -1 && (cnt || literal))
     758:         pword();
     759:     hadnl = 0;
     760:     } while (c >= 0);
     761:     (void) close(pvec[0]);
     762:     pwait();
     763:     prestjob();
     764: }
     765:
     766: static void
     767: psave(c)
     768:     Char    c;
     769: {
     770:     if (--pnleft <= 0)
     771:     stderror(ERR_WTOOLONG);
     772:     *pargcp++ = c;
     773: }
     774:
     775: static void
     776: pword()
     777: {
     778:     psave(0);
     779:     if ((int)pargc == pargsiz - 1) {
     780:     pargsiz += GLOBSPACE;
     781:     pargv = (Char **) xrealloc((ptr_t) pargv,
     782:                    (size_t) pargsiz * sizeof(Char *));
     783:     }
     784:     pargv[(int)pargc++] = Strsave(pargs);
     785:     pargv[(int)pargc] = NOSTR;
     786:     pargcp = pargs;
     787:     pnleft = TC_BUFSIZ - 4;
     788: }
     789:
     790: int
     791: Gmatch(string, pattern)
     792:     register Char *string, *pattern;
     793: {
     794:     register Char stringc, pat_c;
     795:     int     match;
     796:     Char    rangec;
     797:
     798:     for (;; ++string) {
     799:     stringc = *string & TRIM;
     800:     /*
     801: 	 * apollo comp_r bug: switch (pat_c = *pattern++) { dies
     802: 	 */
     803:     pat_c = *pattern++;
     804:     switch (pat_c) {
     805:     case 0:
     806:         return (stringc == 0);
     807:     case '?':
     808:         if (stringc == 0)
     809:         return (0);
     810:         break;
     811:     case '*':
     812:         if (!*pattern)
     813:         return (1);
     814:         while (*string)
     815:         if (Gmatch(string++, pattern))
     816:             return (1);
     817:         return (0);
     818:     case '[':
     819:         match = 0;
     820:         while (rangec = *pattern++) {
     821:         if (rangec == ']')
     822:             if (match)
     823:             break;
     824:             else
     825:             return (0);
     826:         if (match)
     827:             continue;
     828:         if (rangec == '-' && *(pattern-2) != '[' && *pattern  != ']') {
     829:             match = (stringc <= (*pattern & TRIM) &&
     830:                   (*(pattern-2) & TRIM) <= stringc);
     831:             pattern++;
     832:         }
     833:         else
     834:             match = (stringc == (rangec & TRIM));
     835:         }
     836:         if (rangec == 0)
     837:         stderror(ERR_NAME | ERR_MISSING, ']');
     838:         break;
     839:     default:
     840:         if ((pat_c & TRIM) != stringc)
     841:         return (0);
     842:         break;
     843:
     844:     }
     845:     }
     846: }
     847:
     848: void
     849: Gcat(s1, s2)
     850:     Char   *s1, *s2;
     851: {
     852:     register Char *p, *q;
     853:     int     n;
     854:
     855:     for (p = s1; *p++;);
     856:     for (q = s2; *q++;);
     857:     n = (p - s1) + (q - s2) - 1;
     858:     if ((int)++gargc >= gargsiz) {
     859:     gargsiz += GLOBSPACE;
     860:     gargv = (Char **) xrealloc((ptr_t) gargv,
     861:                    (size_t) gargsiz * sizeof(Char *));
     862:     }
     863:     gargv[(int)gargc] = 0;
     864:     p = gargv[(int)gargc - 1] = (Char *) xmalloc((size_t) n * sizeof(Char));
     865:     for (q = s1; *p++ = *q++;);
     866:     for (p--, q = s2; *p++ = *q++;);
     867: }
     868:
     869: #ifdef FILEC
     870: int
     871: sortscmp(a, b)
     872:     register Char **a, **b;
     873: {
     874: #if defined(NLS) && !defined(NOSTRCOLL)
     875:     char    buf[2048];
     876:
     877: #endif
     878:
     879:     if (!a)         /* check for NULL */
     880:     return (b ? 1 : 0);
     881:     if (!b)
     882:     return (-1);
     883:
     884:     if (!*a)            /* check for NULL */
     885:     return (*b ? 1 : 0);
     886:     if (!*b)
     887:     return (-1);
     888:
     889: #if defined(NLS) && !defined(NOSTRCOLL)
     890:     (void) strcpy(buf, short2str(*a));
     891:     return ((int) strcoll(buf, short2str(*b)));
     892: #else
     893:     return ((int) Strcmp(*a, *b));
     894: #endif
     895: }
     896:
     897: #endif

#### Defined functions

Gcat defined in line 848; used 4 times

- in /usr/src/bin/tcsh/sh.dol.c line 176, 187, 195, 234

Gmatch defined in line 790; used 7 times

- in line 815
- in /usr/src/bin/tcsh/sh.exp.c line 239-243(2)
- in /usr/src/bin/tcsh/sh.func.c line 737, 1100
- in /usr/src/bin/tcsh/sh.glob.c line 815
- in /usr/src/bin/tcsh/sh.set.c line 463

backeval defined in line 631; used 1 times

- in line 626

dobackp defined in line 586; used 2 times

- in line 263
- in /usr/src/bin/tcsh/sh.dol.c line 806

ginit defined in line 526; used 1 times

- in /usr/src/bin/tcsh/sh.dol.c line 147

globall defined in line 494; used 12 times

- in /usr/src/bin/tcsh/sh.exec.c line 119, 151
- in /usr/src/bin/tcsh/sh.func.c line 447, 926, 1680
- in /usr/src/bin/tcsh/sh.proc.c line 1389
- in /usr/src/bin/tcsh/sh.set.c line 509
- in /usr/src/bin/tcsh/tc.func.c line 189, 1166
- in /usr/src/bin/tcsh/tc.os.c line 453, 896
- in /usr/src/bin/tcsh/tw.parse.c line 378

globbrace defined in line 155; used 1 times

- in line 304

globequal defined in line 130; used 1 times

- in line 351

globexpand defined in line 244; used 2 times

- in line 454, 512

globone defined in line 434; used 11 times

- in /usr/src/bin/tcsh/sh.c line 1536
- in /usr/src/bin/tcsh/sh.dir.c line 446
- in /usr/src/bin/tcsh/sh.exp.c line 511, 591
- in /usr/src/bin/tcsh/sh.func.c line 370, 392, 1037
- in /usr/src/bin/tcsh/sh.sem.c line 647, 686
- in /usr/src/bin/tcsh/sh.set.c line 226
- in /usr/src/bin/tcsh/tc.os.c line 132

globtilde defined in line 92; used 1 times

- in line 348

handleone defined in line 360; used 2 times

- in line 461, 486

libglob defined in line 394; used 2 times

- in line 474, 517

psave defined in line 766; used 3 times

- in line 613, 749, 778

pword defined in line 775; used 2 times

- in line 610, 758

rcsid defined in line 39; never used
rscan defined in line 535; used 1 times

- in /usr/src/bin/tcsh/sh.dol.c line 716

sortscmp defined in line 870; used 1 times

- in /usr/src/bin/tcsh/sh.file.c line 568

tglob defined in line 558; used 14 times

- in line 446
- in /usr/src/bin/tcsh/sh.exec.c line 117, 149
- in /usr/src/bin/tcsh/sh.func.c line 446, 924, 1678
- in /usr/src/bin/tcsh/sh.glob.c line 446
- in /usr/src/bin/tcsh/sh.proc.c line 1387
- in /usr/src/bin/tcsh/sh.set.c line 507
- in /usr/src/bin/tcsh/tc.func.c line 187, 1164
- in /usr/src/bin/tcsh/tc.os.c line 451, 894
- in /usr/src/bin/tcsh/tw.parse.c line 374

trim defined in line 547; used 13 times

- in line 375
- in /usr/src/bin/tcsh/sh.dol.c line 715
- in /usr/src/bin/tcsh/sh.exec.c line 129, 167
- in /usr/src/bin/tcsh/sh.func.c line 932, 1689
- in /usr/src/bin/tcsh/sh.glob.c line 375
- in /usr/src/bin/tcsh/sh.proc.c line 1395
- in /usr/src/bin/tcsh/sh.set.c line 547
- in /usr/src/bin/tcsh/tc.func.c line 195, 1172
- in /usr/src/bin/tcsh/tc.os.c line 459, 902

#### Defined variables

gargc defined in line 70; used 7 times

- in line 502, 522, 532, 858-864(3)
- in /usr/src/bin/tcsh/tw.parse.c line 392

gargsiz defined in line 47; used 5 times

- in line 529-530(2), 858-861(3)

gargv defined in line 64; used 10 times

- in line 501-503(3), 523, 530-531(2), 860-864(4)

noglob defined in line 46; used 6 times

- in line 288, 442, 455, 469, 506, 516

nonomatch defined in line 46; used 2 times

- in line 405, 421

pargc defined in line 71; used 5 times

- in line 264, 604, 779-785(3)

pargsiz defined in line 47; used 6 times

- in line 600-601(2), 684, 779-782(3)

pargv defined in line 65; used 15 times

- in line 265, 273-274(2), 594-602(4), 611, 683-684(3), 781-785(4)

#### Defined macros

EOS defined in line 62; used 7 times

- in line 106, 120, 177-179(2), 200-202(2), 223

GLOBSPACE defined in line 56; used 14 times

- in line 163, 231-234(2), 250, 267-270(2), 279-282(2), 319(2), 529, 600, 780, 859

G_CSH defined in line 54; used 6 times

- in line 450, 475, 508, 518, 566, 572

G_GLOB defined in line 53; used 4 times

- in line 455, 469, 516, 572

G_NONE defined in line 52; used 1 times

- in line 447

LBRC defined in line 58; used 3 times

- in line 170, 184, 300

LBRK defined in line 60; used 1 times

- in line 175

RBRC defined in line 59; used 2 times

- in line 186, 194

RBRK defined in line 61; used 4 times

- in line 177-181(2), 200-205(2)

TC_BUFSIZ defined in line 583; used 4 times

- in line 581, 592, 605, 787

Last modified: 1991-10-06 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 1896 |