Init
This commit is contained in:
413
5bin/expr.c
Normal file
413
5bin/expr.c
Normal file
@@ -0,0 +1,413 @@
|
||||
/* Copyright (c) 1984 AT&T */
|
||||
/* All Rights Reserved */
|
||||
|
||||
/* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T */
|
||||
/* The copyright notice above does not evidence any */
|
||||
/* actual or intended publication of such source code. */
|
||||
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)expr.c 1.1 94/10/31 SMI"; /* from S5R3 1.13 */
|
||||
#endif
|
||||
|
||||
# define A_STRING 258
|
||||
# define NOARG 259
|
||||
# define OR 260
|
||||
# define AND 261
|
||||
# define EQ 262
|
||||
# define LT 263
|
||||
# define GT 264
|
||||
# define GEQ 265
|
||||
# define LEQ 266
|
||||
# define NEQ 267
|
||||
# define ADD 268
|
||||
# define SUBT 269
|
||||
# define MULT 270
|
||||
# define DIV 271
|
||||
# define REM 272
|
||||
# define MCH 273
|
||||
# define MATCH 274
|
||||
|
||||
#define ESIZE 256
|
||||
#define EQL(x,y) !strcmp(x,y)
|
||||
|
||||
#define INIT register char *sp = instring;
|
||||
#define GETC() (*sp++)
|
||||
#define PEEKC() (*sp)
|
||||
#define UNGETC(c) (--sp)
|
||||
#define RETURN(c) return
|
||||
#define ERROR(c) errxx(c)
|
||||
#include <regexp.h>
|
||||
|
||||
long atol();
|
||||
char *ltoa(), *strcpy(), *strncpy();
|
||||
void exit();
|
||||
char **Av;
|
||||
char *buf;
|
||||
int Ac;
|
||||
int Argi;
|
||||
int noarg;
|
||||
int paren;
|
||||
|
||||
char Mstring[1][128];
|
||||
char *malloc();
|
||||
|
||||
|
||||
char *operator[] = {
|
||||
"|", "&", "+", "-", "*", "/", "%", ":",
|
||||
"=", "==", "<", "<=", ">", ">=", "!=",
|
||||
"match", "\0" };
|
||||
int op[] = {
|
||||
OR, AND, ADD, SUBT, MULT, DIV, REM, MCH,
|
||||
EQ, EQ, LT, LEQ, GT, GEQ, NEQ,
|
||||
MATCH };
|
||||
int pri[] = {
|
||||
1,2,3,3,3,3,3,3,4,4,5,5,5,6,7};
|
||||
yylex() {
|
||||
register char *p;
|
||||
register i;
|
||||
|
||||
if(Argi >= Ac) return NOARG;
|
||||
|
||||
p = Av[Argi];
|
||||
|
||||
if((*p == '(' || *p == ')') && p[1] == '\0' )
|
||||
return (int)*p;
|
||||
for(i = 0; *operator[i]; ++i)
|
||||
if(EQL(operator[i], p))
|
||||
return op[i];
|
||||
|
||||
|
||||
return A_STRING;
|
||||
}
|
||||
|
||||
char *rel(oper, r1, r2) register char *r1, *r2;
|
||||
{
|
||||
register long i;
|
||||
|
||||
if(ematch(r1, "-\\{0,1\\}[0-9]*$") && ematch(r2, "-\\{0,1\\}[0-9]*$"))
|
||||
i = atol(r1) - atol(r2);
|
||||
else
|
||||
i = strcmp(r1, r2);
|
||||
switch(oper) {
|
||||
case EQ:
|
||||
i = i==0;
|
||||
break;
|
||||
case GT:
|
||||
i = i>0;
|
||||
break;
|
||||
case GEQ:
|
||||
i = i>=0;
|
||||
break;
|
||||
case LT:
|
||||
i = i<0;
|
||||
break;
|
||||
case LEQ:
|
||||
i = i<=0;
|
||||
break;
|
||||
case NEQ:
|
||||
i = i!=0;
|
||||
break;
|
||||
}
|
||||
return i? "1": "0";
|
||||
}
|
||||
|
||||
char *arith(oper, r1, r2) char *r1, *r2;
|
||||
{
|
||||
long i1, i2;
|
||||
register char *rv;
|
||||
|
||||
if(!(ematch(r1, "-\\{0,1\\}[0-9]*$") && ematch(r2, "-\\{0,1\\}[0-9]*$")))
|
||||
yyerror("non-numeric argument");
|
||||
i1 = atol(r1);
|
||||
i2 = atol(r2);
|
||||
|
||||
switch(oper) {
|
||||
case ADD:
|
||||
i1 = i1 + i2;
|
||||
break;
|
||||
case SUBT:
|
||||
i1 = i1 - i2;
|
||||
break;
|
||||
case MULT:
|
||||
i1 = i1 * i2;
|
||||
break;
|
||||
case DIV:
|
||||
if (i2 == 0)
|
||||
yyerror("division by zero");
|
||||
i1 = i1 / i2;
|
||||
break;
|
||||
case REM:
|
||||
if (i2 == 0)
|
||||
yyerror("division by zero");
|
||||
i1 = i1 % i2;
|
||||
break;
|
||||
}
|
||||
rv = malloc(16);
|
||||
(void) strcpy(rv, ltoa(i1));
|
||||
return rv;
|
||||
}
|
||||
char *conj(oper, r1, r2) char *r1, *r2;
|
||||
{
|
||||
register char *rv;
|
||||
|
||||
switch(oper) {
|
||||
|
||||
case OR:
|
||||
if(EQL(r1, "0")
|
||||
|| EQL(r1, ""))
|
||||
if(EQL(r2, "0")
|
||||
|| EQL(r2, ""))
|
||||
rv = "0";
|
||||
else
|
||||
rv = r2;
|
||||
else
|
||||
rv = r1;
|
||||
break;
|
||||
case AND:
|
||||
if(EQL(r1, "0")
|
||||
|| EQL(r1, ""))
|
||||
rv = "0";
|
||||
else if(EQL(r2, "0")
|
||||
|| EQL(r2, ""))
|
||||
rv = "0";
|
||||
else
|
||||
rv = r1;
|
||||
break;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
char *match(s, p)
|
||||
char *s, *p;
|
||||
{
|
||||
register char *rv;
|
||||
|
||||
(void) strcpy(rv=malloc(8), ltoa((long)ematch(s, p)));
|
||||
if(nbra) {
|
||||
rv = malloc((unsigned) strlen(Mstring[0]) + 1);
|
||||
(void) strcpy(rv, Mstring[0]);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
ematch(s, p)
|
||||
char *s;
|
||||
register char *p;
|
||||
{
|
||||
static char expbuf[ESIZE];
|
||||
char *compile();
|
||||
register num;
|
||||
extern char *braslist[], *braelist[], *loc2;
|
||||
|
||||
compile(p, expbuf, &expbuf[ESIZE], 0);
|
||||
if(nbra > 1)
|
||||
yyerror("Too many '\\('s");
|
||||
if(advance(s, expbuf)) {
|
||||
if(nbra == 1) {
|
||||
p = braslist[0];
|
||||
num = braelist[0] - p;
|
||||
if ((num > 127) || (num < 0)) yyerror("Paren problem");
|
||||
(void) strncpy(Mstring[0], p, num);
|
||||
Mstring[0][num] = '\0';
|
||||
}
|
||||
return(loc2-s);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
errxx(err)
|
||||
register err;
|
||||
{
|
||||
register char *message;
|
||||
|
||||
switch(err) {
|
||||
case 11:
|
||||
message = "Range endpoint too large";
|
||||
break;
|
||||
case 16:
|
||||
message = "Bad number";
|
||||
break;
|
||||
case 25:
|
||||
message = "``\\digit'' out of range";
|
||||
break;
|
||||
case 36:
|
||||
message = "Illegal or missing delimiter";
|
||||
break;
|
||||
case 41:
|
||||
message = "No remembered search string";
|
||||
break;
|
||||
case 42:
|
||||
message = "\\( \\) imbalance";
|
||||
break;
|
||||
case 43:
|
||||
message = "Too many \\(";
|
||||
break;
|
||||
case 44:
|
||||
message = "More than 2 numbers given in \\{ \\}";
|
||||
break;
|
||||
case 45:
|
||||
message = "} expected after \\";
|
||||
break;
|
||||
case 46:
|
||||
message = "First number exceeds second in \\{ \\}";
|
||||
break;
|
||||
case 49:
|
||||
message = "[ ] imbalance";
|
||||
break;
|
||||
case 50:
|
||||
message = "Regular expression too long";
|
||||
break;
|
||||
default:
|
||||
message = "Unknown regexp error code!!";
|
||||
break;
|
||||
}
|
||||
yyerror(message);
|
||||
}
|
||||
|
||||
yyerror(s)
|
||||
char *s;
|
||||
{
|
||||
(void) write(2, "expr: ", 6);
|
||||
(void) write(2, s, (unsigned) strlen(s));
|
||||
(void) write(2, "\n", 1);
|
||||
exit(2);
|
||||
}
|
||||
|
||||
char *ltoa(l)
|
||||
long l;
|
||||
{
|
||||
static char str[20];
|
||||
register char *sp;
|
||||
register i;
|
||||
register neg;
|
||||
|
||||
if(l == 0x80000000L)
|
||||
return "-2147483648";
|
||||
neg = 0;
|
||||
if(l < 0)
|
||||
++neg, l = -l;
|
||||
sp = &str[20];
|
||||
*--sp = '\0';
|
||||
do {
|
||||
i = l % 10;
|
||||
*--sp = '0' + i;
|
||||
l /= 10;
|
||||
}
|
||||
while(l);
|
||||
if(neg)
|
||||
*--sp = '-';
|
||||
return sp;
|
||||
}
|
||||
char *expres(prior,par) int prior, par;
|
||||
{
|
||||
int ylex, temp, op1;
|
||||
char *r1, *ra, *rb;
|
||||
ylex = yylex();
|
||||
if (ylex == ')' || (ylex >= NOARG && ylex < MATCH)) {
|
||||
yyerror("syntax error");
|
||||
}
|
||||
if (ylex == A_STRING) {
|
||||
r1 = Av[Argi++];
|
||||
temp = Argi;
|
||||
}
|
||||
else {
|
||||
if (ylex == '(') {
|
||||
paren++;
|
||||
Argi++;
|
||||
r1 = expres(0,Argi);
|
||||
Argi--;
|
||||
}
|
||||
temp = -1;
|
||||
}
|
||||
lop:
|
||||
ylex = yylex();
|
||||
if (ylex > NOARG && ylex < MATCH) {
|
||||
op1 = ylex;
|
||||
Argi++;
|
||||
if (pri[op1-OR] <= prior )
|
||||
return r1;
|
||||
else {
|
||||
switch(op1) {
|
||||
case OR:
|
||||
case AND:
|
||||
r1 = conj(op1,r1,expres(pri[op1-OR],0));
|
||||
break;
|
||||
case EQ:
|
||||
case LT:
|
||||
case GT:
|
||||
case LEQ:
|
||||
case GEQ:
|
||||
case NEQ:
|
||||
r1=rel(op1,r1,expres(pri[op1-OR],0));
|
||||
break;
|
||||
case ADD:
|
||||
case SUBT:
|
||||
case MULT:
|
||||
case DIV:
|
||||
case REM:
|
||||
r1=arith(op1,r1,expres(pri[op1-OR],0));
|
||||
break;
|
||||
case MCH:
|
||||
r1=match(r1,expres(pri[op1-OR],0));
|
||||
break;
|
||||
}
|
||||
if(noarg == 1) {
|
||||
return r1;
|
||||
}
|
||||
Argi--;
|
||||
goto lop;
|
||||
}
|
||||
}
|
||||
ylex = yylex();
|
||||
if(ylex == ')') {
|
||||
if(par == Argi) {
|
||||
yyerror("syntax error");
|
||||
}
|
||||
if(par != 0) {
|
||||
paren--;
|
||||
Argi++;
|
||||
}
|
||||
Argi++;
|
||||
return r1;
|
||||
}
|
||||
ylex = yylex();
|
||||
if(ylex > MCH && ylex <= MATCH) {
|
||||
if (Argi == temp) {
|
||||
return r1;
|
||||
}
|
||||
op1 = ylex;
|
||||
Argi++;
|
||||
switch(op1) {
|
||||
case MATCH:
|
||||
rb = expres(pri[op1-OR],0);
|
||||
ra = expres(pri[op1-OR],0);
|
||||
r1 = match(rb,ra);
|
||||
break;
|
||||
}
|
||||
if(noarg == 1) {
|
||||
return r1;
|
||||
}
|
||||
Argi--;
|
||||
goto lop;
|
||||
}
|
||||
ylex = yylex();
|
||||
if (ylex == NOARG) {
|
||||
noarg = 1;
|
||||
}
|
||||
return r1;
|
||||
}
|
||||
main(argc, argv) char **argv;
|
||||
{
|
||||
Ac = argc;
|
||||
Argi = 1;
|
||||
noarg = 0;
|
||||
paren = 0;
|
||||
Av = argv;
|
||||
buf = expres(0,1);
|
||||
if(Ac != Argi || paren != 0) {
|
||||
yyerror("syntax error");
|
||||
}
|
||||
(void) write(1, buf, (unsigned) strlen(buf));
|
||||
(void) write(1, "\n", 1);
|
||||
exit((!strcmp(buf, "0") || !buf[0])? 1: 0);
|
||||
}
|
||||
Reference in New Issue
Block a user