ttest.c - plan9port - [fork] Plan 9 from user space
git clone git://src.adamsgaard.dk/plan9port
Log
Files
Refs
README
LICENSE
---
ttest.c (5813B)
---
     1 /*
     2  * POSIX standard
     3  *        test expression
     4  *        [ expression ]
     5  *
     6  * Plan 9 additions:
     7  *        -A file exists and is append-only
     8  *        -L file exists and is exclusive-use
     9  *        -T file exists and is temporary
    10  */
    11 
    12 #include 
    13 #include 
    14 
    15 #define isatty plan9_isatty
    16 
    17 #define EQ(a,b)        ((tmp=a)==0?0:(strcmp(tmp,b)==0))
    18 
    19 int        ap;
    20 int        ac;
    21 char        **av;
    22 char        *tmp;
    23 
    24 void        synbad(char *, char *);
    25 int        fsizep(char *);
    26 int        isdir(char *);
    27 int        isreg(char *);
    28 int        isatty(int);
    29 int        isint(char *, int *);
    30 int        isolder(char *, char *);
    31 int        isolderthan(char *, char *);
    32 int        isnewerthan(char *, char *);
    33 int        hasmode(char *, ulong);
    34 int        tio(char *, int);
    35 int        e(void), e1(void), e2(void), e3(void);
    36 char        *nxtarg(int);
    37 
    38 void
    39 main(int argc, char *argv[])
    40 {
    41         int r;
    42         char *c;
    43 
    44         ac = argc; av = argv; ap = 1;
    45         if(EQ(argv[0],"[")) {
    46                 if(!EQ(argv[--ac],"]"))
    47                         synbad("] missing","");
    48         }
    49         argv[ac] = 0;
    50         if (ac<=1)
    51                 exits("usage");
    52         r = e();
    53         /*
    54          * nice idea but short-circuit -o and -a operators may have
    55          * not consumed their right-hand sides.
    56          */
    57         if(0 && (c = nxtarg(1)) != nil)
    58                 synbad("unexpected operator/operand: ", c);
    59         exits(r?0:"false");
    60 }
    61 
    62 char *
    63 nxtarg(int mt)
    64 {
    65         if(ap>=ac){
    66                 if(mt){
    67                         ap++;
    68                         return(0);
    69                 }
    70                 synbad("argument expected","");
    71         }
    72         return(av[ap++]);
    73 }
    74 
    75 int
    76 nxtintarg(int *pans)
    77 {
    78         if(ap=ac)
   176                         return(isatty(1));
   177                 else if(nxtintarg(&int1))
   178                         return(isatty(int1));
   179                 else
   180                         synbad("not a valid file descriptor number ", "");
   181 
   182         if(EQ(a, "-n"))
   183                 return(!EQ(nxtarg(0), ""));
   184         if(EQ(a, "-z"))
   185                 return(EQ(nxtarg(0), ""));
   186 
   187         p2 = nxtarg(1);
   188         if (p2==0)
   189                 return(!EQ(a,""));
   190         if(EQ(p2, "="))
   191                 return(EQ(nxtarg(0), a));
   192 
   193         if(EQ(p2, "!="))
   194                 return(!EQ(nxtarg(0), a));
   195 
   196         if(EQ(p2, "-older"))
   197                 return(isolder(nxtarg(0), a));
   198 
   199         if(EQ(p2, "-ot"))
   200                 return(isolderthan(nxtarg(0), a));
   201 
   202         if(EQ(p2, "-nt"))
   203                 return(isnewerthan(nxtarg(0), a));
   204 
   205         if(!isint(a, &int1))
   206                 synbad("unexpected operator/operand: ", p2);
   207 
   208         if(nxtintarg(&int2)){
   209                 if(EQ(p2, "-eq"))
   210                         return(int1==int2);
   211                 if(EQ(p2, "-ne"))
   212                         return(int1!=int2);
   213                 if(EQ(p2, "-gt"))
   214                         return(int1>int2);
   215                 if(EQ(p2, "-lt"))
   216                         return(int1=int2);
   219                 if(EQ(p2, "-le"))
   220                         return(int1<=int2);
   221         }
   222 
   223         synbad("unknown operator ",p2);
   224         return 0;                /* to shut ken up */
   225 }
   226 
   227 int
   228 tio(char *a, int f)
   229 {
   230         return access (a, f) >= 0;
   231 }
   232 
   233 /*
   234  * note that the name strings pointed to by Dir members are
   235  * allocated with the Dir itself (by the same call to malloc),
   236  * but are not included in sizeof(Dir), so copying a Dir won't
   237  * copy the strings it points to.
   238  */
   239 
   240 int
   241 hasmode(char *f, ulong m)
   242 {
   243         int r;
   244         Dir *dir;
   245 
   246         dir = dirstat(f);
   247         if (dir == nil)
   248                 return 0;
   249         r = (dir->mode & m) != 0;
   250         free(dir);
   251         return r;
   252 }
   253 
   254 int
   255 isdir(char *f)
   256 {
   257         return hasmode(f, DMDIR);
   258 }
   259 
   260 int
   261 isreg(char *f)
   262 {
   263         int r;
   264         Dir *dir;
   265 
   266         dir = dirstat(f);
   267         if (dir == nil)
   268                 return 0;
   269         r = (dir->mode & DMDIR) == 0;
   270         free(dir);
   271         return r;
   272 }
   273 
   274 int
   275 isatty(int fd)
   276 {
   277         int r;
   278         Dir *d1, *d2;
   279 
   280         d1 = dirfstat(fd);
   281         d2 = dirstat("/dev/cons");
   282         if (d1 == nil || d2 == nil)
   283                 r = 0;
   284         else
   285                 r = d1->type == d2->type && d1->dev == d2->dev &&
   286                         d1->qid.path == d2->qid.path;
   287         free(d1);
   288         free(d2);
   289         return r;
   290 }
   291 
   292 int
   293 fsizep(char *f)
   294 {
   295         int r;
   296         Dir *dir;
   297 
   298         dir = dirstat(f);
   299         if (dir == nil)
   300                 return 0;
   301         r = dir->length > 0;
   302         free(dir);
   303         return r;
   304 }
   305 
   306 void
   307 synbad(char *s1, char *s2)
   308 {
   309         int len;
   310 
   311         write(2, "test: ", 6);
   312         if ((len = strlen(s1)) != 0)
   313                 write(2, s1, len);
   314         if ((len = strlen(s2)) != 0)
   315                 write(2, s2, len);
   316         write(2, "\n", 1);
   317         exits("bad syntax");
   318 }
   319 
   320 int
   321 isint(char *s, int *pans)
   322 {
   323         char *ep;
   324 
   325         *pans = strtol(s, &ep, 0);
   326         return (*ep == 0);
   327 }
   328 
   329 int
   330 isolder(char *pin, char *f)
   331 {
   332         int r;
   333         ulong n, m;
   334         char *p = pin;
   335         Dir *dir;
   336 
   337         dir = dirstat(f);
   338         if (dir == nil)
   339                 return 0;
   340 
   341         /* parse time */
   342         n = 0;
   343         while(*p){
   344                 m = strtoul(p, &p, 0);
   345                 switch(*p){
   346                 case 0:
   347                         n = m;
   348                         break;
   349                 case 'y':
   350                         m *= 12;
   351                         /* fall through */
   352                 case 'M':
   353                         m *= 30;
   354                         /* fall through */
   355                 case 'd':
   356                         m *= 24;
   357                         /* fall through */
   358                 case 'h':
   359                         m *= 60;
   360                         /* fall through */
   361                 case 'm':
   362                         m *= 60;
   363                         /* fall through */
   364                 case 's':
   365                         n += m;
   366                         p++;
   367                         break;
   368                 default:
   369                         synbad("bad time syntax, ", pin);
   370                 }
   371         }
   372 
   373         r = dir->mtime + n < time(0);
   374         free(dir);
   375         return r;
   376 }
   377 
   378 int
   379 isolderthan(char *a, char *b)
   380 {
   381         int r;
   382         Dir *ad, *bd;
   383 
   384         ad = dirstat(a);
   385         bd = dirstat(b);
   386         if (ad == nil || bd == nil)
   387                 r = 0;
   388         else
   389                 r = ad->mtime > bd->mtime;
   390         free(ad);
   391         free(bd);
   392         return r;
   393 }
   394 
   395 int
   396 isnewerthan(char *a, char *b)
   397 {
   398         int r;
   399         Dir *ad, *bd;
   400 
   401         ad = dirstat(a);
   402         bd = dirstat(b);
   403         if (ad == nil || bd == nil)
   404                 r = 0;
   405         else
   406                 r = ad->mtime < bd->mtime;
   407         free(ad);
   408         free(bd);
   409         return r;
   410 }