root/trunk/ash/ash-0.4.0-cumulative_fixes-1.patch

Revision 545, 126.6 KB (checked in by jim, 5 years ago)

Naming Scheme Update

  • ash-0.4.0.

    Submitted By: Tushar Teredesai <tushar@linuxfromscratch.org>
    Date: 2003-10-02
    Initial Package Version: 0.4.0
    Origin: Slackware Source
    Description: This is a collection of patches from Debian via Slackware
    (don't you love Open Source:-) along with a minor bison related fix
    from me. Additionally I removed debian specific stuff.
    ash can be downloaded from any slackware mirror.
    diff -Nur ash-0.4.0.orig/Makefile ash-0.4.0.fixed/Makefile
    old new  
    77SHSRCS= alias.c cd.c echo.c error.c eval.c exec.c expand.c \ 
    88        histedit.c input.c jobs.c mail.c main.c memalloc.c miscbltin.c \ 
    99        mystring.c options.c parser.c redir.c show.c trap.c output.c var.c \ 
    10         test.c 
    11 GENSRCS=arith.c arith.h arith_lex.c builtins.c builtins.h init.c nodes.c \ 
    12         nodes.h syntax.c syntax.h token.h 
     10        test.c setmode.c test.c hetio.c 
     11GENSRCS=builtins.c builtins.h init.c nodes.c arith.c arith.h lex.yy.c \ 
     12        nodes.h syntax.c syntax.h token.h signames.c 
    1313SRCS=   ${SHSRCS} ${GENSRCS} 
    1414 
    15 LDADD+= -ll -ledit -ltermcap 
    16 DPADD+= ${LIBL} ${LIBEDIT} ${LIBTERMCAP} 
     15OBJS=alias.o cd.o bltin/echo.o error.o eval.o exec.o expand.o \ 
     16        histedit.o input.o jobs.o mail.o main.o memalloc.o miscbltin.o \ 
     17        mystring.o options.o output.o parser.o redir.o show.o \ 
     18        trap.o var.o bltin/test.o signames.o \ 
     19        builtins.o init.o nodes.o syntax.o arith.o lex.yy.o \ 
     20        setmode.o bltin/times.o hetio.o 
     21 
     22OPT_FLAGS=-O2 -g 
     23LDFLAGS=-g 
     24CFLAGS=$(OPT_FLAGS) -DSHELL -I. -DNO_HISTORY -DBSD=1 -DSMALL -D_GNU_SOURCE \ 
     25        -DGLOB_BROKEN -D__COPYRIGHT\(x\)= -D__RCSID\(x\)= -D_DIAGASSERT\(x\)= \ 
     26        -DHETIO 
     27 
     28all: $(PROG) 
     29 
     30$(PROG): build-tools $(GENSRCS) $(GENHDRS) $(OBJS) 
     31        $(CC) $(LDFLAGS) -o $(PROG) $(OBJS) $(LDLIBS) -lfl 
     32         
     33lex.yy.c: arith_lex.l 
     34        flex -8 $<  
     35         
     36CLEANFILES+= mkinit mkinit.o mknodes mknodes.o \ 
     37        mksyntax mksyntax.o 
     38         
     39CLEANFILES+= ${GENSRCS} ${GENHDRS} 
     40 
     41build-tools: mkinit mknodes mksyntax 
     42 
     43.ORDER: builtins.c builtins.h 
     44builtins.c builtins.h: mkbuiltins builtins.def 
     45        sh mkbuiltins shell.h builtins.def `pwd` 
     46 
     47INIT_DEPS = alias.c eval.c exec.c input.c jobs.c options.c parser.c \ 
     48        redir.c trap.c var.c output.c 
     49         
     50init.c: mkinit $(INIT_DEPS) 
     51        ./mkinit $(INIT_DEPS) 
     52 
     53mkinit: mkinit.o 
     54mknodes: mknodes.o 
     55mksyntax: mksyntax.o 
    1756 
    18 LFLAGS= -8      # 8-bit lex scanner for arithmetic 
    19 YFLAGS= -d 
    20  
    21 CPPFLAGS+=-DSHELL -I. -I${.CURDIR} 
    22  
    23 .PATH:  ${.CURDIR}/bltin ${.CURDIR}/../../usr.bin/printf ${.CURDIR}/../test 
    24  
    25 CLEANFILES+= mkinit mknodes mksyntax 
    26 CLEANFILES+= ${GENSRCS} y.tab.h 
    27  
    28 token.h: mktokens 
    29         sh ${.ALLSRC} 
    30  
    31 builtins.c builtins.h: mkbuiltins shell.h builtins.def 
    32         sh ${.ALLSRC} ${.OBJDIR} 
    33  
    34 init.c: mkinit ${SHSRCS} 
    35         ./${.ALLSRC} 
     57signames.c: mksignames 
     58        ./mksignames 
    3659 
    3760nodes.c nodes.h: mknodes nodetypes nodes.c.pat 
    38         ./${.ALLSRC} 
     61        ./mknodes ./nodetypes ./nodes.c.pat 
    3962 
    4063syntax.c syntax.h: mksyntax 
    41         ./${.ALLSRC} 
    42  
    43 mkinit: mkinit.c 
    44         ${HOST_LINK.c} -o mkinit ${.IMPSRC} 
    45  
    46 mknodes: mknodes.c 
    47         ${HOST_LINK.c} -o mknodes ${.IMPSRC} 
     64        ./mksyntax 
    4865 
    49 .if     (${MACHINE_ARCH} == "powerpc") || \ 
    50         (${MACHINE_ARCH} == "arm32") || \ 
    51         (${MACHINE_ARCH} == "arm26") 
    52 TARGET_CHARFLAG= -DTARGET_CHAR="u_int8_t" 
    53 .else 
    54 TARGET_CHARFLAG= -DTARGET_CHAR="int8_t" 
    55 .endif 
     66arith.c arith.h: arith.y 
     67        yacc -d arith.y 
     68        mv y.tab.h arith.h 
     69        mv y.tab.c arith.c 
    5670 
    57 mksyntax: mksyntax.c 
    58         ${HOST_LINK.c} ${TARGET_CHARFLAG} -o mksyntax ${.IMPSRC} 
    59  
    60 .include <bsd.prog.mk> 
     71token.h: mktokens 
     72        sh ./mktokens 
    6173 
    62 ${OBJS}: builtins.h nodes.h syntax.h token.h 
     74clean: 
     75        rm -f $(PROG) $(OBJS) $(CLEANFILES) core 
  • ash-0.4.0.

    diff -Nur ash-0.4.0.orig/arith.y ash-0.4.0.fixed/arith.y
    old new  
    150150%left ARITH_UNARYMINUS ARITH_UNARYPLUS ARITH_NOT ARITH_BNOT 
    151151%% 
    152152 
    153 exp:    expr = { 
     153exp:    expr { 
    154154                        return ($1); 
    155155                } 
    156156        ; 
    157157 
    158158 
    159 expr:   ARITH_LPAREN expr ARITH_RPAREN = { $$ = $2; } 
    160         | expr ARITH_OR expr    = { $$ = $1 ? $1 : $3 ? $3 : 0; } 
    161         | expr ARITH_AND expr   = { $$ = $1 ? ( $3 ? $3 : 0 ) : 0; } 
    162         | expr ARITH_BOR expr   = { $$ = $1 | $3; } 
    163         | expr ARITH_BXOR expr  = { $$ = $1 ^ $3; } 
    164         | expr ARITH_BAND expr  = { $$ = $1 & $3; } 
    165         | expr ARITH_EQ expr    = { $$ = $1 == $3; } 
    166         | expr ARITH_GT expr    = { $$ = $1 > $3; } 
    167         | expr ARITH_GE expr    = { $$ = $1 >= $3; } 
    168         | expr ARITH_LT expr    = { $$ = $1 < $3; } 
    169         | expr ARITH_LE expr    = { $$ = $1 <= $3; } 
    170         | expr ARITH_NE expr    = { $$ = $1 != $3; } 
    171         | expr ARITH_LSHIFT expr = { $$ = $1 << $3; } 
    172         | expr ARITH_RSHIFT expr = { $$ = $1 >> $3; } 
    173         | expr ARITH_ADD expr   = { $$ = $1 + $3; } 
    174         | expr ARITH_SUB expr   = { $$ = $1 - $3; } 
    175         | expr ARITH_MUL expr   = { $$ = $1 * $3; } 
    176         | expr ARITH_DIV expr   = { 
     159expr:   ARITH_LPAREN expr ARITH_RPAREN { $$ = $2; } 
     160        | expr ARITH_OR expr    { $$ = $1 ? $1 : $3 ? $3 : 0; } 
     161        | expr ARITH_AND expr   { $$ = $1 ? ( $3 ? $3 : 0 ) : 0; } 
     162        | expr ARITH_BOR expr   { $$ = $1 | $3; } 
     163        | expr ARITH_BXOR expr  { $$ = $1 ^ $3; } 
     164        | expr ARITH_BAND expr  { $$ = $1 & $3; } 
     165        | expr ARITH_EQ expr    { $$ = $1 == $3; } 
     166        | expr ARITH_GT expr    { $$ = $1 > $3; } 
     167        | expr ARITH_GE expr    { $$ = $1 >= $3; } 
     168        | expr ARITH_LT expr    { $$ = $1 < $3; } 
     169        | expr ARITH_LE expr    { $$ = $1 <= $3; } 
     170        | expr ARITH_NE expr    { $$ = $1 != $3; } 
     171        | expr ARITH_LSHIFT expr { $$ = $1 << $3; } 
     172        | expr ARITH_RSHIFT expr { $$ = $1 >> $3; } 
     173        | expr ARITH_ADD expr   { $$ = $1 + $3; } 
     174        | expr ARITH_SUB expr   { $$ = $1 - $3; } 
     175        | expr ARITH_MUL expr   { $$ = $1 * $3; } 
     176        | expr ARITH_DIV expr   { 
    177177                        if ($3 == 0) 
    178178                                yyerror("division by zero"); 
    179179                        $$ = $1 / $3; 
    180180                        } 
    181         | expr ARITH_REM expr   = { 
     181        | expr ARITH_REM expr   { 
    182182                        if ($3 == 0) 
    183183                                yyerror("division by zero"); 
    184184                        $$ = $1 % $3; 
    185185                        } 
    186         | ARITH_NOT expr        = { $$ = !($2); } 
    187         | ARITH_BNOT expr       = { $$ = ~($2); } 
    188         | ARITH_SUB expr %prec ARITH_UNARYMINUS = { $$ = -($2); } 
    189         | ARITH_ADD expr %prec ARITH_UNARYPLUS = { $$ = $2; } 
     186        | ARITH_NOT expr        { $$ = !($2); } 
     187        | ARITH_BNOT expr       { $$ = ~($2); } 
     188        | ARITH_SUB expr %prec ARITH_UNARYMINUS { $$ = -($2); } 
     189        | ARITH_ADD expr %prec ARITH_UNARYPLUS { $$ = $2; } 
    190190        | ARITH_NUM 
    191191        ; 
    192192%% 
     
    195195        const char *s; 
    196196{ 
    197197 
    198         yyerrok; 
    199198        yyclearin; 
    200199        arith_lex_reset();      /* reprime lex */ 
    201200        error("arithmetic expression: %s: \"%s\"", s, arith_startbuf); 
  • bltin/bltin.h

    diff -Nur ash-0.4.0.orig/bltin/bltin.h ash-0.4.0.fixed/bltin/bltin.h
    old new  
    4646 
    4747#include "../shell.h" 
    4848#include "../mystring.h" 
     49#include "../memalloc.h" 
    4950#ifdef SHELL 
    5051#include "../output.h" 
     52#ifndef _GNU_SOURCE 
    5153#define stdout out1 
    5254#define stderr out2 
    5355#define printf out1fmt 
     
    5658#define fprintf outfmt 
    5759#define fputs outstr 
    5860#define fflush flushout 
    59 #define INITARGS(argv) 
    6061#define warnx(a, b, c) {                                \ 
    6162        char buf[64];                                   \ 
    6263        (void)snprintf(buf, sizeof(buf), a, b, c);      \ 
    6364        error("%s", buf);                               \ 
    6465} 
     66#endif 
     67#define INITARGS(argv) 
    6568 
    6669#else 
    6770#undef NULL 
  • bltin/echo.c

    diff -Nur ash-0.4.0.orig/bltin/echo.c ash-0.4.0.fixed/bltin/echo.c
    old new  
    4444 
    4545#define main echocmd 
    4646 
     47#ifdef _GNU_SOURCE 
     48#include <stdio.h> 
     49 
     50#include "../mystring.h" 
     51#else 
    4752#include "bltin.h" 
     53#endif 
    4854 
    4955/* #define eflag 1 */ 
    5056 
     
    5359        register char **ap; 
    5460        register char *p; 
    5561        register char c; 
    56         int count; 
    5762        int nflag = 0; 
    5863#ifndef eflag 
    5964        int eflag = 0; 
     
    6267        ap = argv; 
    6368        if (argc) 
    6469                ap++; 
    65         if ((p = *ap) != NULL) { 
     70        while ((p = *ap) != NULL && *p == '-') { 
    6671                if (equal(p, "-n")) { 
    67                         nflag++; 
    68                         ap++; 
     72                        nflag = 1; 
    6973                } else if (equal(p, "-e")) { 
    7074#ifndef eflag 
    71                         eflag++; 
     75                        eflag = 1; 
     76#endif 
     77                } else if (equal(p, "-E")) { 
     78#ifndef eflag 
     79                        eflag = 0; 
    7280#endif 
    73                         ap++; 
    7481                } 
     82                else break; 
     83                ap++; 
    7584        } 
    7685        while ((p = *ap++) != NULL) { 
    7786                while ((c = *p++) != '\0') { 
    7887                        if (c == '\\' && eflag) { 
    79                                 switch (*p++) { 
     88                                switch (c = *p++) { 
     89                                case 'a':  c = '\007'; break; 
    8090                                case 'b':  c = '\b';  break; 
    8191                                case 'c':  return 0;            /* exit */ 
     92                                case 'e':  c = '\033';  break; 
    8293                                case 'f':  c = '\f';  break; 
    8394                                case 'n':  c = '\n';  break; 
    8495                                case 'r':  c = '\r';  break; 
    8596                                case 't':  c = '\t';  break; 
    8697                                case 'v':  c = '\v';  break; 
    8798                                case '\\':  break;              /* c = '\\' */ 
    88                                 case '0': 
    89                                         c = 0; 
    90                                         count = 3; 
    91                                         while (--count >= 0 && (unsigned)(*p - '0') < 8) 
    92                                                 c = (c << 3) + (*p++ - '0'); 
     99                                case '0': case '1': case '2': case '3': 
     100                                case '4': case '5': case '6': case '7': 
     101                                        c -= '0'; 
     102                                        if (*p >= '0' && *p <= '7') 
     103                                                c = c * 8 + (*p++ - '0'); 
     104                                        if (*p >= '0' && *p <= '7') 
     105                                        c = c * 8 + (*p++ - '0'); 
    93106                                        break; 
    94107                                default: 
    95108                                        p--; 
     
    103116        } 
    104117        if (! nflag) 
    105118                putchar('\n'); 
     119#ifdef _GNU_SOURCE 
     120        fflush(stdout); 
     121        if (ferror(stdout)) { 
     122                clearerr(stdout); 
     123                return 1; 
     124        } 
     125#endif 
    106126        return 0; 
    107127} 
  • bltin/test.c

    diff -Nur ash-0.4.0.orig/bltin/test.c ash-0.4.0.fixed/bltin/test.c
    old new  
     1/*      $NetBSD: test.c,v 1.22 2000/04/09 23:24:59 christos Exp $       */ 
     2 
     3/* 
     4 * test(1); version 7-like  --  author Erik Baalbergen 
     5 * modified by Eric Gisin to be used as built-in. 
     6 * modified by Arnold Robbins to add SVR3 compatibility 
     7 * (-x -c -b -p -u -g -k) plus Korn's -L -nt -ot -ef and new -S (socket). 
     8 * modified by J.T. Conklin for NetBSD. 
     9 * 
     10 * This program is in the Public Domain. 
     11 */ 
     12 
     13#include <sys/cdefs.h> 
     14#ifndef lint 
     15__RCSID("$NetBSD: test.c,v 1.22 2000/04/09 23:24:59 christos Exp $"); 
     16#endif 
     17 
     18#include <sys/types.h> 
     19#include <sys/stat.h> 
     20#include <unistd.h> 
     21#include <ctype.h> 
     22#include <errno.h> 
     23#include <stdio.h> 
     24#include <stdlib.h> 
     25#include <string.h> 
     26#include <err.h> 
     27#ifdef __STDC__ 
     28#include <stdarg.h> 
     29#else 
     30#include <varargs.h> 
     31#endif 
     32 
     33/* test(1) accepts the following grammar: 
     34        oexpr   ::= aexpr | aexpr "-o" oexpr ; 
     35        aexpr   ::= nexpr | nexpr "-a" aexpr ; 
     36        nexpr   ::= primary | "!" primary 
     37        primary ::= unary-operator operand 
     38                | operand binary-operator operand 
     39                | operand 
     40                | "(" oexpr ")" 
     41                ; 
     42        unary-operator ::= "-r"|"-w"|"-x"|"-f"|"-d"|"-c"|"-b"|"-p"| 
     43                "-u"|"-g"|"-k"|"-s"|"-t"|"-z"|"-n"|"-o"|"-O"|"-G"|"-L"|"-S"; 
     44 
     45        binary-operator ::= "="|"!="|"-eq"|"-ne"|"-ge"|"-gt"|"-le"|"-lt"| 
     46                        "-nt"|"-ot"|"-ef"; 
     47        operand ::= <any legal UNIX file name> 
     48*/ 
     49 
     50enum token { 
     51        EOI, 
     52        FILRD, 
     53        FILWR, 
     54        FILEX, 
     55        FILEXIST, 
     56        FILREG, 
     57        FILDIR, 
     58        FILCDEV, 
     59        FILBDEV, 
     60        FILFIFO, 
     61        FILSOCK, 
     62        FILSYM, 
     63        FILGZ, 
     64        FILTT, 
     65        FILSUID, 
     66        FILSGID, 
     67        FILSTCK, 
     68        FILNT, 
     69        FILOT, 
     70        FILEQ, 
     71        FILUID, 
     72        FILGID, 
     73        STREZ, 
     74        STRNZ, 
     75        STREQ, 
     76        STRNE, 
     77        STRLT, 
     78        STRGT, 
     79        INTEQ, 
     80        INTNE, 
     81        INTGE, 
     82        INTGT, 
     83        INTLE, 
     84        INTLT, 
     85        UNOT, 
     86        BAND, 
     87        BOR, 
     88        LPAREN, 
     89        RPAREN, 
     90        OPERAND 
     91}; 
     92 
     93enum token_types { 
     94        UNOP, 
     95        BINOP, 
     96        BUNOP, 
     97        BBINOP, 
     98        PAREN 
     99}; 
     100 
     101static struct t_op { 
     102        const char *op_text; 
     103        short op_num, op_type; 
     104} const ops [] = { 
     105        {"-r",  FILRD,  UNOP}, 
     106        {"-w",  FILWR,  UNOP}, 
     107        {"-x",  FILEX,  UNOP}, 
     108        {"-e",  FILEXIST,UNOP}, 
     109        {"-f",  FILREG, UNOP}, 
     110        {"-d",  FILDIR, UNOP}, 
     111        {"-c",  FILCDEV,UNOP}, 
     112        {"-b",  FILBDEV,UNOP}, 
     113        {"-p",  FILFIFO,UNOP}, 
     114        {"-u",  FILSUID,UNOP}, 
     115        {"-g",  FILSGID,UNOP}, 
     116        {"-k",  FILSTCK,UNOP}, 
     117        {"-s",  FILGZ,  UNOP}, 
     118        {"-t",  FILTT,  UNOP}, 
     119        {"-z",  STREZ,  UNOP}, 
     120        {"-n",  STRNZ,  UNOP}, 
     121        {"-h",  FILSYM, UNOP},          /* for backwards compat */ 
     122        {"-O",  FILUID, UNOP}, 
     123        {"-G",  FILGID, UNOP}, 
     124        {"-L",  FILSYM, UNOP}, 
     125        {"-S",  FILSOCK,UNOP}, 
     126        {"=",   STREQ,  BINOP}, 
     127        {"!=",  STRNE,  BINOP}, 
     128        {"<",   STRLT,  BINOP}, 
     129        {">",   STRGT,  BINOP}, 
     130        {"-eq", INTEQ,  BINOP}, 
     131        {"-ne", INTNE,  BINOP}, 
     132        {"-ge", INTGE,  BINOP}, 
     133        {"-gt", INTGT,  BINOP}, 
     134        {"-le", INTLE,  BINOP}, 
     135        {"-lt", INTLT,  BINOP}, 
     136        {"-nt", FILNT,  BINOP}, 
     137        {"-ot", FILOT,  BINOP}, 
     138        {"-ef", FILEQ,  BINOP}, 
     139        {"!",   UNOT,   BUNOP}, 
     140        {"-a",  BAND,   BBINOP}, 
     141        {"-o",  BOR,    BBINOP}, 
     142        {"(",   LPAREN, PAREN}, 
     143        {")",   RPAREN, PAREN}, 
     144        {0,     0,      0} 
     145}; 
     146 
     147static char **t_wp; 
     148static struct t_op const *t_wp_op; 
     149static gid_t *group_array = NULL; 
     150static int ngroups; 
     151 
     152static void syntax __P((const char *, const char *)); 
     153static int oexpr __P((enum token)); 
     154static int aexpr __P((enum token)); 
     155static int nexpr __P((enum token)); 
     156static int primary __P((enum token)); 
     157static int binop __P((void)); 
     158static int filstat __P((char *, enum token)); 
     159static enum token t_lex __P((char *)); 
     160static int isoperand __P((void)); 
     161static int getn __P((const char *)); 
     162static int newerf __P((const char *, const char *)); 
     163static int olderf __P((const char *, const char *)); 
     164static int equalf __P((const char *, const char *)); 
     165static int test_eaccess(); 
     166static int bash_group_member(); 
     167static void initialize_group_array(); 
     168 
     169#if defined(SHELL) 
     170extern void error __P((const char *, ...)) __attribute__((__noreturn__)); 
     171#else 
     172static void error __P((const char *, ...)) __attribute__((__noreturn__)); 
     173 
     174static void 
     175#ifdef __STDC__ 
     176error(const char *msg, ...) 
     177#else 
     178error(va_alist) 
     179        va_dcl 
     180#endif 
     181{ 
     182        va_list ap; 
     183#ifndef __STDC__ 
     184        const char *msg; 
     185 
     186        va_start(ap); 
     187        msg = va_arg(ap, const char *); 
     188#else 
     189        va_start(ap, msg); 
     190#endif 
     191        verrx(2, msg, ap); 
     192        /*NOTREACHED*/ 
     193        va_end(ap); 
     194} 
     195#endif 
     196 
     197#ifdef SHELL 
     198int testcmd __P((int, char **)); 
     199 
     200int 
     201testcmd(argc, argv) 
     202        int argc; 
     203        char **argv; 
     204#else 
     205int main __P((int, char **)); 
     206 
     207int 
     208main(argc, argv) 
     209        int argc; 
     210        char **argv; 
     211#endif 
     212{ 
     213        int     res; 
     214 
     215 
     216        if (strcmp(argv[0], "[") == 0) { 
     217                if (strcmp(argv[--argc], "]")) 
     218                        error("missing ]"); 
     219                argv[argc] = NULL; 
     220        } 
     221 
     222        if (argc < 2) 
     223                return 1; 
     224 
     225        t_wp = &argv[1]; 
     226        res = !oexpr(t_lex(*t_wp)); 
     227 
     228        if (*t_wp != NULL && *++t_wp != NULL) 
     229                syntax(*t_wp, "unexpected operator"); 
     230 
     231        return res; 
     232} 
     233 
     234static void 
     235syntax(op, msg) 
     236        const char      *op; 
     237        const char      *msg; 
     238{ 
     239        if (op && *op) 
     240                error("%s: %s", op, msg); 
     241        else 
     242                error("%s", msg); 
     243} 
     244 
     245static int 
     246oexpr(n) 
     247        enum token n; 
     248{ 
     249        int res; 
     250 
     251        res = aexpr(n); 
     252        if (t_lex(*++t_wp) == BOR) 
     253                return oexpr(t_lex(*++t_wp)) || res; 
     254        t_wp--; 
     255        return res; 
     256} 
     257 
     258static int 
     259aexpr(n) 
     260        enum token n; 
     261{ 
     262        int res; 
     263 
     264        res = nexpr(n); 
     265        if (t_lex(*++t_wp) == BAND) 
     266                return aexpr(t_lex(*++t_wp)) && res; 
     267        t_wp--; 
     268        return res; 
     269} 
     270 
     271static int 
     272nexpr(n) 
     273        enum token n;                   /* token */ 
     274{ 
     275        if (n == UNOT) 
     276                return !nexpr(t_lex(*++t_wp)); 
     277        return primary(n); 
     278} 
     279 
     280static int 
     281primary(n) 
     282        enum token n; 
     283{ 
     284        enum token nn; 
     285        int res; 
     286 
     287        if (n == EOI) 
     288                return 0;               /* missing expression */ 
     289        if (n == LPAREN) { 
     290                if ((nn = t_lex(*++t_wp)) == RPAREN) 
     291                        return 0;       /* missing expression */ 
     292                res = oexpr(nn); 
     293                if (t_lex(*++t_wp) != RPAREN) 
     294                        syntax(NULL, "closing paren expected"); 
     295                return res; 
     296        } 
     297        if (t_wp_op && t_wp_op->op_type == UNOP) { 
     298                /* unary expression */ 
     299                if (*++t_wp == NULL) 
     300                        syntax(t_wp_op->op_text, "argument expected"); 
     301                switch (n) { 
     302                case STREZ: 
     303                        return strlen(*t_wp) == 0; 
     304                case STRNZ: 
     305                        return strlen(*t_wp) != 0; 
     306                case FILTT: 
     307                        return isatty(getn(*t_wp)); 
     308                default: 
     309                        return filstat(*t_wp, n); 
     310                } 
     311        } 
     312 
     313        if (t_lex(t_wp[1]), t_wp_op && t_wp_op->op_type == BINOP) { 
     314                return binop(); 
     315        }          
     316 
     317        return strlen(*t_wp) > 0; 
     318} 
     319 
     320static int 
     321binop() 
     322{ 
     323        const char *opnd1, *opnd2; 
     324        struct t_op const *op; 
     325 
     326        opnd1 = *t_wp; 
     327        (void) t_lex(*++t_wp); 
     328        op = t_wp_op; 
     329 
     330        if ((opnd2 = *++t_wp) == (char *)0) 
     331                syntax(op->op_text, "argument expected"); 
     332                 
     333        switch (op->op_num) { 
     334        case STREQ: 
     335                return strcmp(opnd1, opnd2) == 0; 
     336        case STRNE: 
     337                return strcmp(opnd1, opnd2) != 0; 
     338        case STRLT: 
     339                return strcmp(opnd1, opnd2) < 0; 
     340        case STRGT: 
     341                return strcmp(opnd1, opnd2) > 0; 
     342        case INTEQ: 
     343                return getn(opnd1) == getn(opnd2); 
     344        case INTNE: 
     345                return getn(opnd1) != getn(opnd2); 
     346        case INTGE: 
     347                return getn(opnd1) >= getn(opnd2); 
     348        case INTGT: 
     349                return getn(opnd1) > getn(opnd2); 
     350        case INTLE: 
     351                return getn(opnd1) <= getn(opnd2); 
     352        case INTLT: 
     353                return getn(opnd1) < getn(opnd2); 
     354        case FILNT: 
     355                return newerf (opnd1, opnd2); 
     356        case FILOT: 
     357                return olderf (opnd1, opnd2); 
     358        case FILEQ: 
     359                return equalf (opnd1, opnd2); 
     360        default: 
     361                abort(); 
     362                /* NOTREACHED */ 
     363        } 
     364} 
     365 
     366static int 
     367filstat(nm, mode) 
     368        char *nm; 
     369        enum token mode; 
     370{ 
     371        struct stat s; 
     372 
     373        if (mode == FILSYM ? lstat(nm, &s) : stat(nm, &s)) 
     374                return 0; 
     375 
     376        switch (mode) { 
     377        case FILRD: 
     378                return test_eaccess(nm, R_OK) == 0; 
     379        case FILWR: 
     380                return test_eaccess(nm, W_OK) == 0; 
     381        case FILEX: 
     382                return test_eaccess(nm, X_OK) == 0; 
     383        case FILEXIST: 
     384                return 1; 
     385        case FILREG: 
     386                return S_ISREG(s.st_mode); 
     387        case FILDIR: 
     388                return S_ISDIR(s.st_mode); 
     389        case FILCDEV: 
     390                return S_ISCHR(s.st_mode); 
     391        case FILBDEV: 
     392                return S_ISBLK(s.st_mode); 
     393        case FILFIFO: 
     394                return S_ISFIFO(s.st_mode); 
     395        case FILSOCK: 
     396                return S_ISSOCK(s.st_mode); 
     397        case FILSYM: 
     398                return S_ISLNK(s.st_mode); 
     399        case FILSUID: 
     400                return (s.st_mode & S_ISUID) != 0; 
     401        case FILSGID: 
     402                return (s.st_mode & S_ISGID) != 0; 
     403        case FILSTCK: 
     404                return (s.st_mode & S_ISVTX) != 0; 
     405        case FILGZ: 
     406                return s.st_size > (off_t)0; 
     407        case FILUID: 
     408                return s.st_uid == geteuid(); 
     409        case FILGID: 
     410                return s.st_gid == getegid(); 
     411        default: