Annotation of coherent/d/bin/test/test.y, revision 1.1

1.1     ! root        1: %{
        !             2: /*
        !             3:  * Set return status based on
        !             4:  * various specified conditions,
        !             5:  * mostly related to files.
        !             6:  * Used mostly in shell files.
        !             7:  */
        !             8: 
        !             9: #include <stdio.h>
        !            10: #include <sys/stat.h>
        !            11: #include <access.h>
        !            12: #include "testnode.h"
        !            13: 
        !            14: #define        NPRIM   (sizeof(prims)/sizeof(prims[0]))
        !            15: #define        NFNAME  500             /* size of filename buffer */
        !            16: %}
        !            17: %start command
        !            18: 
        !            19: %union {
        !            20:        NODE *nodeptr;
        !            21:        char *fname;
        !            22:        }
        !            23: 
        !            24: %left  OR
        !            25: %left  AND
        !            26: %left  '!'
        !            27: %token _R _W _F _D _S _T _Z _N
        !            28: %token SEQ SNEQ
        !            29: %token _EQ _NE _GT _GE _LT _LE
        !            30: %type  <nodeptr> exp
        !            31: %token <fname> STR
        !            32: %%
        !            33: 
        !            34: command:
        !            35:        exp '\n'                { code = $1; return; }
        !            36:        ;
        !            37: 
        !            38: exp:
        !            39:         '(' exp ')'            { $$ = $2; }
        !            40:       | '!' exp                        { $$ = bnode('!', $2, NULL); }
        !            41:       | exp OR exp             { $$ = bnode(OR, $1, $3); }
        !            42:       | exp AND exp            { $$ = bnode(AND, $1, $3); }
        !            43:       | _R STR                 { $$ = lnode(xr, $2, NULL); }
        !            44:       | _W STR                 { $$ = lnode(xw, $2, NULL); }
        !            45:       | _F STR                 { $$ = lnode(xf, $2, NULL); }
        !            46:       | _D STR                 { $$ = lnode(xd, $2, NULL); }
        !            47:       | _S STR                 { $$ = lnode(xs, $2, NULL); }
        !            48:       | _T STR                 { $$ = lnode(xt, $2, NULL); }
        !            49:       | _T                     { $$ = lnode(xt, "1", NULL); }
        !            50:       | _Z STR                 { $$ = lnode(xz, $2, NULL); }
        !            51:       | _N STR                 { $$ = lnode(xn, $2, NULL); }
        !            52:       | STR SEQ STR            { $$ = lnode(xseq, $1, $3); }
        !            53:       | STR SNEQ STR           { $$ = lnode(xsneq, $1, $3); }
        !            54:       | STR _EQ STR            { $$ = lnode(xeq, $1, $3); }
        !            55:       | STR _NE STR            { $$ = lnode(xne, $1, $3); }
        !            56:       | STR _GT STR            { $$ = lnode(xgt, $1, $3); }
        !            57:       | STR _GE STR            { $$ = lnode(xge, $1, $3); }
        !            58:       | STR _LT STR            { $$ = lnode(xlt, $1, $3); }
        !            59:       | STR _LE STR            { $$ = lnode(xle, $1, $3); }
        !            60:       | STR                    { $$ = lnode(xn, $1, NULL); }
        !            61:        ;
        !            62: 
        !            63: %%
        !            64: struct prim    {
        !            65:        char    *p_name;
        !            66:        int     p_lval;
        !            67:        int     p_bin;
        !            68: }      prims[] = {
        !            69:        "-r", _R, 0,
        !            70:        "-w", _W, 0,
        !            71:        "-f", _F, 0,
        !            72:        "-d", _D, 0,
        !            73:        "-s", _S, 0,
        !            74:        "-t", _T, 0,
        !            75:        "-z", _Z, 0,
        !            76:        "-n", _N, 0,
        !            77:        "-eq", _EQ, 1,
        !            78:        "-ne", _NE, 1,
        !            79:        "-gt", _GT, 1,
        !            80:        "-ge", _GE, 1,
        !            81:        "-lt", _LT, 1,
        !            82:        "-le", _LE, 1,
        !            83:        "-o", OR, 1,
        !            84:        "-a", AND, 1
        !            85: };
        !            86: 
        !            87: 
        !            88: char   **gav;
        !            89: int    gac;
        !            90: 
        !            91: struct stat    sb;
        !            92: 
        !            93: NODE   *code;
        !            94: 
        !            95: char   *next();
        !            96: NODE   *bnode();
        !            97: NODE   *lnode();
        !            98: long   atol();
        !            99: int    xr();
        !           100: int    xw();
        !           101: int    xf();
        !           102: int    xd();
        !           103: int    xs();
        !           104: int    xt();
        !           105: int    xz();
        !           106: int    xn();
        !           107: int    xseq();
        !           108: int    xsneq();
        !           109: int    xeq();
        !           110: int    xne();
        !           111: int    xgt();
        !           112: int    xge();
        !           113: int    xlt();
        !           114: 
        !           115: main(argc, argv)
        !           116: char *argv[];
        !           117: {
        !           118:        gav = argv+1;
        !           119:        gac = argc-1;
        !           120:        if (argv[0][0]=='[' && argv[0][1]=='\0') {
        !           121:                if (strcmp(argv[gac], "]") != 0)
        !           122:                        tsterr("unbalanced [..]");
        !           123:                gac--;
        !           124:        }
        !           125:        if (gac == 0)
        !           126:                exit(1);
        !           127:        yyparse();
        !           128:        exit(!execute(code));
        !           129: }
        !           130: 
        !           131: /*
        !           132:  * Lexical analyser
        !           133:  */
        !           134: yylex()
        !           135: {
        !           136:        static char laststr = 0; /* 1 if last token was string */
        !           137:        register char *ap;
        !           138:        register struct prim *pp;
        !           139: 
        !           140:        if ((yylval.fname = ap = next()) == NULL)
        !           141:                return ('\n');
        !           142: 
        !           143:        if (*ap == '-') {
        !           144:                for (pp = prims; pp < &prims[NPRIM]; pp++) {
        !           145:                        if (strcmp(pp->p_name, ap) == 0) {
        !           146:                                if (!laststr && pp->p_bin)
        !           147:                                        break;
        !           148:                                laststr = 0;
        !           149:                                return (pp->p_lval);
        !           150:                        }
        !           151:                }
        !           152:        }
        !           153:        else {
        !           154:                laststr = 0;
        !           155:                if (strcmp("!=", ap) == 0)
        !           156:                        return (SNEQ);
        !           157: 
        !           158:                if (ap[1] == '\0') {
        !           159:                        if (ap[0]==')') {
        !           160:                                laststr = 1;
        !           161:                                return(')');
        !           162:                        }
        !           163:                        if (ap[0]=='(' || ap[0]=='!')
        !           164:                                return (ap[0]);
        !           165:                        if (ap[0]=='=')
        !           166:                                return (SEQ);
        !           167:                }
        !           168:        }
        !           169:        laststr = 1;
        !           170:        return (STR);
        !           171: }
        !           172: 
        !           173: yyerror()
        !           174: {
        !           175:        fprintf(stderr, "Test expression syntax error\n");
        !           176:        usage();
        !           177: }
        !           178: 
        !           179: /*
        !           180:  * Return the next argument from the arg list.
        !           181:  */
        !           182: char *
        !           183: next()
        !           184: {
        !           185:        if (gac < 1)
        !           186:                return (NULL);
        !           187:        gac--;
        !           188:        return (*gav++);
        !           189: }
        !           190: 
        !           191: /*
        !           192:  * Build an expression tree node (non-leaf)
        !           193:  */
        !           194: NODE *
        !           195: bnode(op, left, right)
        !           196: int op;
        !           197: NODE *left, *right;
        !           198: {
        !           199:        register NODE *np;
        !           200:        char *malloc();
        !           201: 
        !           202:        if ((np = (NODE *)malloc(sizeof (NODE))) == NULL)
        !           203:                tsterr("Out of space");
        !           204:        np->n_un.n_op = op;
        !           205:        np->n_left = left;
        !           206:        np->n_right = right;
        !           207:        return (np);
        !           208: }
        !           209: 
        !           210: /*
        !           211:  * Build a leaf node in expression tree.
        !           212:  */
        !           213: NODE *
        !           214: lnode(fn, str1, str2)
        !           215: int (*fn)();
        !           216: char *str1, *str2;
        !           217: {
        !           218:        register NODE *np;
        !           219:        char *malloc();
        !           220: 
        !           221:        if ((np = (NODE *)malloc(sizeof (NODE))) == NULL)
        !           222:                tsterr("Out of space");
        !           223:        np->n_left = np->n_right = NULL;
        !           224:        np->n_un.n_fun = fn;
        !           225:        np->n_s1 = str1;
        !           226:        np->n_s2 = str2;
        !           227:        return (np);
        !           228: }
        !           229: 
        !           230: /*
        !           231:  * Execute compiled code.
        !           232:  */
        !           233: execute(np)
        !           234: register NODE *np;
        !           235: {
        !           236:        if (np->n_left != NULL)
        !           237:                switch (np->n_un.n_op) {
        !           238:                case AND:
        !           239:                        if (execute(np->n_left) && execute(np->n_right))
        !           240:                                return (1);
        !           241:                        return (0);
        !           242: 
        !           243:                case OR:
        !           244:                        if (execute(np->n_left) || execute(np->n_right))
        !           245:                                return (1);
        !           246:                        return (0);
        !           247: 
        !           248:                case '!':
        !           249:                        return (!execute(np->n_left));
        !           250: 
        !           251:                default:
        !           252:                        tsterr("Panic: bad tree (op %d)", np->n_un.n_op);
        !           253:                }
        !           254:        else
        !           255:                return ((*np->n_un.n_fun)(np));
        !           256:        /* NOTREACHED */
        !           257: }
        !           258: 
        !           259: /*
        !           260:  * Check to see if the file exists
        !           261:  * and if readable.
        !           262:  */
        !           263: xr(np)
        !           264: NODE *np;
        !           265: {
        !           266:        return (access(np->n_s1, AREAD) >= 0);
        !           267: }
        !           268: 
        !           269: /*
        !           270:  * Check if the file exists and is
        !           271:  * writeable.
        !           272:  */
        !           273: xw(np)
        !           274: NODE *np;
        !           275: {
        !           276:        return (access(np->n_s1, AWRITE) >= 0);
        !           277: }
        !           278: 
        !           279: /*
        !           280:  * Check if the file exists and is not
        !           281:  * a directory.
        !           282:  */
        !           283: xf(np)
        !           284: NODE *np;
        !           285: {
        !           286:        return (stat(np->n_s1, &sb)>=0 && (sb.st_mode&S_IFMT)!=S_IFDIR);
        !           287: }
        !           288: 
        !           289: /*
        !           290:  * Check to see if the file exists
        !           291:  * and is a directory.
        !           292:  */
        !           293: xd(np)
        !           294: NODE *np;
        !           295: {
        !           296:        return (stat(np->n_s1, &sb)>=0 && (sb.st_mode&S_IFMT)==S_IFDIR);
        !           297: }
        !           298: 
        !           299: /*
        !           300:  * Check to see if the file exists
        !           301:  * and has a non-zero size.
        !           302:  */
        !           303: xs(np)
        !           304: NODE *np;
        !           305: {
        !           306:        return (stat(np->n_s1, &sb)>=0 && sb.st_size>0);
        !           307: }
        !           308: 
        !           309: /*
        !           310:  * Check to see if the file
        !           311:  * descriptor is associated
        !           312:  * with a terminal.
        !           313:  */
        !           314: xt(np)
        !           315: NODE *np;
        !           316: {
        !           317:        return (isatty(atoi(np->n_s1)));
        !           318: }
        !           319: 
        !           320: /*
        !           321:  * True if the length of the given
        !           322:  * string is zero.
        !           323:  */
        !           324: xz(np)
        !           325: NODE *np;
        !           326: {
        !           327:        return (np->n_s1[0] == '\0');
        !           328: }
        !           329: 
        !           330: /*
        !           331:  * True if the length of the given
        !           332:  * string is non-zero.
        !           333:  */
        !           334: xn(np)
        !           335: NODE *np;
        !           336: {
        !           337:        return (np->n_s1[0] != '\0');
        !           338: }
        !           339: 
        !           340: /*
        !           341:  * True if the two strings are
        !           342:  * lexicographically equal.
        !           343:  */
        !           344: xseq(np)
        !           345: register NODE *np;
        !           346: {
        !           347:        return (strcmp(np->n_s1, np->n_s2) == 0);
        !           348: }
        !           349: 
        !           350: /*
        !           351:  * True if the two strings are
        !           352:  * lexicographically unequal.
        !           353:  */
        !           354: xsneq(np)
        !           355: register NODE *np;
        !           356: {
        !           357:        return (strcmp(np->n_s1, np->n_s2) != 0);
        !           358: }
        !           359: 
        !           360: /*
        !           361:  * True if the two numbers are
        !           362:  * equal.
        !           363:  */
        !           364: xeq(np)
        !           365: register NODE *np;
        !           366: {
        !           367:        return (atol(np->n_s1) == atol(np->n_s2));
        !           368: }
        !           369: 
        !           370: /*
        !           371:  * True if the two numbers are
        !           372:  * not equal.
        !           373:  */
        !           374: xne(np)
        !           375: register NODE *np;
        !           376: {
        !           377:        return (atol(np->n_s1) != atol(np->n_s2));
        !           378: }
        !           379: 
        !           380: /*
        !           381:  * True if the first number is
        !           382:  * greater than the second.
        !           383:  */
        !           384: xgt(np)
        !           385: register NODE *np;
        !           386: {
        !           387:        return (atol(np->n_s1) > atol(np->n_s2));
        !           388: }
        !           389: 
        !           390: /*
        !           391:  * True if the first number is
        !           392:  * greater than or equal to the second.
        !           393:  */
        !           394: xge(np)
        !           395: register NODE *np;
        !           396: {
        !           397:        return (atol(np->n_s1) >= atol(np->n_s2));
        !           398: }
        !           399: 
        !           400: /*
        !           401:  * True if the first number is
        !           402:  * less than the second.
        !           403:  */
        !           404: xlt(np)
        !           405: register NODE *np;
        !           406: {
        !           407:        return (atol(np->n_s1) < atol(np->n_s2));
        !           408: }
        !           409: 
        !           410: /*
        !           411:  * True if the first number is
        !           412:  * less than or equal to the second.
        !           413:  */
        !           414: xle(np)
        !           415: register NODE *np;
        !           416: {
        !           417:        return (atol(np->n_s1) <= atol(np->n_s2));
        !           418: }
        !           419: 
        !           420: /*
        !           421:  * Error messages.
        !           422:  */
        !           423: /* VARARGS */
        !           424: tsterr(x)
        !           425: {
        !           426:        fprintf(stderr, "test: %r\n", &x);
        !           427:        exit(1);
        !           428: }
        !           429: 
        !           430: usage()
        !           431: {
        !           432:        fprintf(stderr, "Usage: test expression\n");
        !           433:        exit(1);
        !           434: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.