home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 January
/
usenetsourcesnewsgroupsinfomagicjanuary1994.iso
/
sources
/
net
/
v7.test
< prev
next >
Wrap
Internet Message Format
|
1987-04-03
|
5KB
From erikb@cs.vu.nl Fri Apr 3 01:06:13 1987
Path: seismo!mcvax!botter!erikb
From: erikb@cs.vu.nl (Erik Baalbergen)
Newsgroups: comp.os.minix
Subject: source for test(1)
Keywords: test, shell script
Message-ID: <1132@botter.cs.vu.nl>
Date: 3 Apr 87 06:06:13 GMT
Sender: remote@cs.vu.nl
Reply-To: erikb@cs.vu.nl (Erik Baalbergen)
Distribution: world
Organization: V.U. Informatica, Amsterdam
Lines: 244
Here's the source for a version 7-like test. (See UNIX v7 manual, test(1)).
I wrote this program from scratch so there should be no copyright problems.
It is tested on Minix. Compile with cc and see how it goes!
Please report bugs and suggestions to erikb@cs.vu.nl.
Erik Baalbergen
-- cut here --
/* test(1); version 7-like -- author Erik Baalbergen */
#include <sys/types.h>
#include <sys/stat.h>
/* test(1) accepts the following grammar:
expr ::= bexpr | bexpr "-o" expr ;
bexpr ::= primary | primary "-a" bexpr ;
primary ::= unary-operator operand
| operand binary-operator operand
| operand
| "(" expr ")"
| "!" expr
;
unary-operator ::= "-r"|"-w"|"-f"|"-d"|"-s"|"-t"|"-z"|"-n";
binary-operator ::= "="|"!="|"-eq"|"-ne"|"-ge"|"-gt"|"-le"|"-lt";
operand ::= <any legal UNIX file name>
*/
#define EOI 0
#define FILRD 1
#define FILWR 2
#define FILND 3
#define FILID 4
#define FILGZ 5
#define FILTT 6
#define STZER 7
#define STNZE 8
#define STEQL 9
#define STNEQ 10
#define INTEQ 11
#define INTNE 12
#define INTGE 13
#define INTGT 14
#define INTLE 15
#define INTLT 16
#define UNEGN 17
#define BAND 18
#define BOR 19
#define LPAREN 20
#define RPAREN 21
#define OPERAND 22
#define UNOP 1
#define BINOP 2
#define BUNOP 3
#define BBINOP 4
#define PAREN 5
struct op {
char *op_text;
short op_num, op_type;
} ops[] = {
{"-r", FILRD, UNOP},
{"-w", FILWR, UNOP},
{"-f", FILND, UNOP},
{"-d", FILID, UNOP},
{"-s", FILGZ, UNOP},
{"-t", FILTT, UNOP},
{"-z", STZER, UNOP},
{"-n", STNZE, UNOP},
{"=", STEQL, BINOP},
{"!=", STNEQ, BINOP},
{"-eq", INTEQ, BINOP},
{"-ne", INTNE, BINOP},
{"-ge", INTGE, BINOP},
{"-gt", INTGT, BINOP},
{"-le", INTLE, BINOP},
{"-lt", INTLT, BINOP},
{"!", UNEGN, BUNOP},
{"-a", BAND, BBINOP},
{"-o", BOR, BBINOP},
{"(", LPAREN, PAREN},
{")", RPAREN, PAREN},
{0, 0, 0}
};
long num();
char **ip;
char *prog;
struct op *ip_op;
main(argc, argv)
char *argv[];
{
prog = argv[0];
ip = &argv[1];
exit(!(expr(lex(*ip)) && *++ip == 0));
}
expr(n)
{
int res;
if (n == EOI)
syntax();
res = bexpr(n);
if (lex(*++ip) == BOR)
return expr(lex(*++ip)) || res;
ip--;
return res;
}
bexpr(n)
{
int res;
if (n == EOI)
syntax();
res = primary(n);
if (lex(*++ip) == BAND)
return bexpr(lex(*++ip)) && res;
ip--;
return res;
}
primary(n)
{
register char *opnd1, *opnd2;
int res;
if (n == EOI)
syntax();
if (n == UNEGN)
return !expr(lex(*++ip));
if (n == LPAREN) {
res = expr(lex(*++ip));
if (lex(*++ip) != RPAREN)
syntax();
return res;
}
if (n == OPERAND) {
opnd1 = *ip;
(void) lex(*++ip);
if (ip_op && ip_op->op_type == BINOP) {
struct op *op = ip_op;
if ((opnd2 = *++ip) == (char *)0)
syntax();
switch (op->op_num) {
case STEQL:
return strcmp(opnd1, opnd2) == 0;
case STNEQ:
return strcmp(opnd1, opnd2) != 0;
case INTEQ:
return num(opnd1) == num(opnd2);
case INTNE:
return num(opnd1) != num(opnd2);
case INTGE:
return num(opnd1) >= num(opnd2);
case INTGT:
return num(opnd1) > num(opnd2);
case INTLE:
return num(opnd1) <= num(opnd2);
case INTLT:
return num(opnd1) < num(opnd2);
}
}
ip--;
return strlen(opnd1) > 0;
}
/* unary expression */
if (ip_op->op_type != UNOP || *++ip == 0)
syntax();
if (n == STZER)
return strlen(*ip) == 0;
if (n == STNZE)
return strlen(*ip) != 0;
return filstat(*ip, n);
}
filstat(nm, mode)
char *nm;
{
struct stat s;
switch (mode) {
case FILRD:
return access(nm, 4) == 0;
case FILWR:
return access(nm, 2) == 0;
case FILND:
return stat(nm, &s) == 0 && ((s.st_mode & S_IFMT) != S_IFDIR);
case FILID:
return stat(nm, &s) == 0 && ((s.st_mode & S_IFMT) == S_IFDIR);
case FILGZ:
return stat(nm, &s) == 0 && (s.st_size > 0L);
case FILTT: /* not implemented */
syntax();
}
}
int
lex(s)
register char *s;
{
register struct op *op = ops;
if (s == 0)
return EOI;
while (op->op_text) {
if (strcmp(s, op->op_text) == 0) {
ip_op = op;
return op->op_num;
}
op++;
}
ip_op = (struct op *)0;
return OPERAND;
}
long
num(s)
register char *s;
{
long l = 0;
long sign = 1;
if (*s == '\0')
syntax();
if (*s == '-') {
sign = -1;
s++;
}
while (*s >= '0' && *s <= '9')
l = l * 10 + *s++ - '0';
if (*s != '\0')
syntax();
return sign * l;
}
syntax()
{
write(2, prog, strlen(prog));
write(2, ": syntax error\n", 15);
exit(1);
}