toybox/toys/pending/test.c
<<
>>
Prefs
   1/* test.c - evaluate expression
   2 *
   3 * Copyright 2013 Rob Landley <rob@landley.net>
   4 *
   5 * See http://pubs.opengroup.org/onlinepubs/9699919799/utilities/test.html
   6
   7USE_TEST(NEWTOY(test, NULL, TOYFLAG_USR|TOYFLAG_BIN))
   8
   9config TEST
  10  bool "test"
  11  default n
  12  help
  13    usage: test [-bcdefghLPrSsuwx PATH] [-nz STRING] [-t FD] [X ?? Y]
  14
  15    Return true or false by performing tests. (With no arguments return false.)
  16
  17    --- Tests with a single argument (after the option):
  18    PATH is/has:
  19      -b  block device   -f  regular file   -p  fifo           -u  setuid bit
  20      -c  char device    -g  setgid         -r  read bit       -w  write bit
  21      -d  directory      -h  symlink        -S  socket         -x  execute bit
  22      -e  exists         -L  symlink        -s  nonzero size
  23    STRING is:
  24      -n  nonzero size   -z  zero size      (STRING by itself implies -n)
  25    FD (integer file descriptor) is:
  26      -t  a TTY
  27
  28    --- Tests with one argument on each side of an operator:
  29    Two strings:
  30      =  are identical   !=  differ
  31    Two integers:
  32      -eq  equal         -gt  first > second    -lt  first < second
  33      -ne  not equal     -ge  first >= second   -le  first <= second
  34
  35    --- Modify or combine tests:
  36      ! EXPR     not (swap true/false)   EXPR -a EXPR    and (are both true)
  37      ( EXPR )   evaluate this first     EXPR -o EXPR    or (is either true)
  38*/
  39
  40#include "toys.h"
  41
  42void test_main(void)
  43{
  44  int id, not;
  45  char *s, *err_fmt = "Bad flag '%s'";
  46
  47  toys.exitval = 2;
  48  if (!strcmp("[", toys.which->name))
  49    if (!strcmp("]", toys.optargs[--toys.optc])) error_exit("Missing ']'");
  50  if (!strcmp("!", toys.optargs[0])) {
  51    not = 1;
  52    toys.optargs++;
  53    toys.optc--;
  54  }
  55  if (!toys.optc) toys.exitval = 0;
  56  else if (toys.optargs[0][0] == '-') {
  57    id = stridx("bcdefghLpSsurwxznt", toys.optargs[0][1]);
  58    if (id == -1 || toys.optargs[0][2]) error_exit(err_fmt, toys.optargs[0]);
  59    if (id < 12) {
  60      struct stat st;
  61      int nolink;
  62
  63      toys.exitval = 1;
  64      if (lstat(toys.optargs[1], &st) == -1) return;
  65      nolink = !S_ISLNK(st.st_mode);
  66      if (!nolink && (stat(toys.optargs[1], &st) == -1)) return;
  67
  68      if (id == 0) toys.exitval = !S_ISBLK(st.st_mode); // b
  69      else if (id == 1) toys.exitval = !S_ISCHR(st.st_mode); // c
  70      else if (id == 2) toys.exitval = !S_ISDIR(st.st_mode); // d
  71      else if (id == 3) toys.exitval = 0; // e
  72      else if (id == 4) toys.exitval = !S_ISREG(st.st_mode); // f
  73      else if (id == 5) toys.exitval = !(st.st_mode & S_ISGID); // g
  74      else if ((id == 6) || (id == 7)) toys.exitval = nolink; // hL
  75      else if (id == 8) toys.exitval = !S_ISFIFO(st.st_mode); // p
  76      else if (id == 9) toys.exitval = !S_ISSOCK(st.st_mode); // S
  77      else if (id == 10) toys.exitval = st.st_size == 0; // s
  78      else toys.exitval = !(st.st_mode & S_ISUID); // u
  79    }
  80    else if (id < 15) // rwx
  81      toys.exitval = access(toys.optargs[1], 1 << (id - 12)) == -1;
  82    else if (id < 17) // zn
  83      toys.exitval = toys.optargs[1] && !*toys.optargs[1] ^ (id - 15);
  84    else { // t
  85      struct termios termios;
  86      toys.exitval = tcgetattr(atoi(toys.optargs[1]), &termios) == -1;
  87    }
  88  }
  89  else if (toys.optc == 1) toys.exitval = *toys.optargs[0] == 0;
  90  else if (toys.optc == 3) {
  91    if (*toys.optargs[1] == '-') {
  92      long a = atol(toys.optargs[0]), b = atol(toys.optargs[2]);
  93      
  94      s = toys.optargs[1] + 1;
  95      if (!strcmp("eq", s)) toys.exitval = a != b;
  96      else if (!strcmp("ne", s)) toys.exitval = a == b;
  97      else if (!strcmp("gt", s)) toys.exitval = a < b;
  98      else if (!strcmp("ge", s)) toys.exitval = a <= b;
  99      else if (!strcmp("lt", s)) toys.exitval = a > b;
 100      else if (!strcmp("le", s)) toys.exitval = a >= b;
 101      else error_exit(err_fmt, toys.optargs[1]);
 102    }
 103    else {
 104      int result = strcmp(toys.optargs[0], toys.optargs[2]);
 105
 106      s = toys.optargs[1];
 107      if (!strcmp("=", s)) toys.exitval = !!result;
 108      else if (!strcmp("!=", s)) toys.exitval = !result;
 109      else error_exit(err_fmt, toys.optargs[1]);
 110    }
 111  }
 112  toys.exitval ^= not;
 113  return;
 114}
 115