From: Kees van Reeuwijk Date: Thu, 22 Apr 2010 13:41:35 +0000 (+0000) Subject: Remove obsolete implementation of awk. X-Git-Tag: v3.1.7~131 X-Git-Url: http://zhaoyanbai.com/repos/zlib_tech.html?a=commitdiff_plain;h=55129194a3941d600a07c103a7a8a9b86ba6cd82;p=minix.git Remove obsolete implementation of awk. --- diff --git a/commands/awk.old/Makefile b/commands/awk.old/Makefile deleted file mode 100644 index 3ce566943..000000000 --- a/commands/awk.old/Makefile +++ /dev/null @@ -1,30 +0,0 @@ -# Makefile for awk. - -CC = exec cc -CFLAGS = -D_MINIX -D_POSIX_SOURCE -wo -w -LDFLAGS = -i -f - -OBJS = m.o e.o n.o l.o r.o v.o y.o regexp.o k.o - -all: awk.old - -awk.old: $(OBJS) - $(CC) $(LDFLAGS) -o $@ $(OBJS) #-lm - install -S 32kw $@ - -install: /usr/bin/awk.old - -/usr/bin/awk.old: awk.old - install -cs -o bin $? $@ - -clean: - rm -f awk awk.old *.o a.out *.bak core - -e.o: awk.h regexp.h -l.o: awk.h -m.o: awk.h -n.o: awk.h -r.o: awk.h regexp.h -regexp.o: regexp.h -v.o: awk.h regexp.h -y.o: awk.h diff --git a/commands/awk.old/README b/commands/awk.old/README deleted file mode 100644 index 61fdb318f..000000000 --- a/commands/awk.old/README +++ /dev/null @@ -1,13 +0,0 @@ -A small AWK clone for the 16-bit Minix - - We have written this program for the Minix 1.2 to fit into 64K+64K -memory. When compiling this program, you need the Peter S. Housel's -Floating Math Package with corrected the atan() function. Original atan() -function has incorrect argument sequence. - - This program supports Japanese Shift-JIS KANJI code and passes -all the test program of the "AWK programming language" written by original -AWK authors except some programs relied upon the way of regular expression -evaluation. - -Kouichi Hirabayashi (kh@mogami-wire.co.jp) diff --git a/commands/awk.old/awk.h b/commands/awk.old/awk.h deleted file mode 100644 index b997e1608..000000000 --- a/commands/awk.old/awk.h +++ /dev/null @@ -1,186 +0,0 @@ -/* - * a small awk clone - * - * (C) 1989 Saeko Hirabauashi & Kouichi Hirabayashi - * - * Absolutely no warranty. Use this software with your own risk. - * - * Permission to use, copy, modify and distribute this software for any - * purpose and without fee is hereby granted, provided that the above - * copyright and disclaimer notice. - * - * This program was written to fit into 64K+64K memory of the Minix 1.2. - */ - -/* lexical/parser tokens and executable statements */ - -#define FIRSTP 256 -#define ARG 256 -#define ARITH 257 -#define ARRAY 258 -#define ASSIGN 259 -#define CALL 260 -#define CAT 261 -#define COND 262 -#define DELETE 263 -#define DO 264 -#define ELEMENT 265 -#define FIELD 266 -#define FOR 267 -#define FORIN 268 -#define GETLINE 269 -#define IF 270 -#define IN 271 -#define JUMP 272 -#define MATHFUN 273 -#define NULPROC 274 -#define P1STAT 275 -#define P2STAT 276 -#define PRINT 277 -#define PRINT0 278 -#define STRFUN 279 -#define SUBST 280 -#define USRFUN 281 -#define WHILE 282 -#define LASTP 282 - /* lexical token */ - -#define ADD 300 /* + */ -#define ADDEQ 301 /* += */ -#define AND 302 /* && */ -#define BEGIN 303 /* BEGIN */ -#define BINAND 304 /* & */ -#define BINOR 305 /* | */ -#define BREAK 306 /* break */ -#define CLOSE 307 /* close */ -#define CONTIN 308 /* continue */ -#define DEC 309 /* -- */ -#define DIV 310 /* / */ -#define DIVEQ 311 /* /= */ -#define ELSE 312 /* else */ -#define END 313 /* END */ -#define EOL 314 /* ; or '\n' */ -#define EQ 315 /* == */ -#define EXIT 316 /* exit */ -#define FUNC 317 /* function */ -#define GE 318 /* >= */ -#define GT 319 /* > */ -#define IDENT 320 /* identifier */ -#define INC 321 /* ++ */ -#define LE 322 /* <= */ -#define LT 323 /* < */ -#define MATCH 324 /* ~ */ -#define MOD 325 /* % */ -#define MODEQ 326 /* %= */ -#define MULT 327 /* * */ -#define MULTEQ 328 /* *= */ -#define NE 329 /* != */ -#define NEXT 330 /* next */ -#define NOMATCH 331 /* !~ */ -#define NOT 332 /* ! */ -#define NUMBER 333 /* integer or floating number */ -#define OR 334 /* || */ -#define POWEQ 335 /* ^= */ -#define POWER 336 /* ^ */ -#define PRINTF 337 /* printf */ -#define REGEXP 338 /* /REG/ */ -#define RETURN 339 /* return */ -#define SHIFTL 340 /* << */ -#define SHIFTR 341 /* >> */ -#define SPRINT 342 /* sprint */ -#define SPRINTF 343 /* sprintf */ -#define STRING 344 /* ".." */ -#define SUB 345 /* - */ -#define SUBEQ 346 /* -= */ -#define SYSTEM 347 /* system */ -#define UMINUS 348 /* - */ - -/* tokens in parser */ - -#define VALUE 400 /* value node */ -#define INCDEC 401 /* ++, -- */ -#define PRE 402 /* pre incre/decre */ -#define POST 403 /* post incre/decre */ - -/* redirect in print(f) statement */ - -#define R_OUT 410 /* > */ -#define R_APD 411 /* >> */ -#define R_PIPE 412 /* | */ -#define R_IN 413 /* < */ -#define R_PIN 414 /* | getline */ -#define R_POUT 415 /* print | */ - -/* function */ - -#define ATAN2 500 /* atan2 */ -#define COS 501 /* cos */ -#define EXP 502 /* exp */ -#define INDEX 503 /* index */ -#define INT 504 /* int */ -#define LENGTH 505 /* length */ -#define LOG 506 /* log */ -#define RAND 507 /* rand */ -#define RGSUB 508 /* gsub */ -#define RMATCH 509 /* match */ -#define RSUB 510 /* sub */ -#define SIN 511 /* sin */ -#define SPLIT 512 /* split */ -#define SQRT 513 /* sqrt */ -#define SRAND 514 /* srand */ -#define SUBSTR 515 /* substr */ - -/* print(f) options */ - -#define FORMAT 1024 /* PRINTF, SPRINTF */ -#define STROUT 2048 /* SPRINTF */ -#define PRMASK 0x3ff /* ~(FORMAT|STROUT) */ - - /* node - used in parsed tree */ - -struct node { - int n_type; /* node type */ - struct node *n_next; /* pointer to next node */ - struct node *n_arg[1]; /* argument (variable length) */ -}; - -typedef struct node NODE; - - /* object cell */ - -struct cell { - int c_type; /* cell type */ - char *c_sval; /* string value */ - double c_fval; /* floating value */ -}; - -typedef struct cell CELL; - - /* cell type */ - -#define UDF 0 /* pass parameter */ -#define VAR 1 /* variable */ -#define NUM 2 /* number */ -#define ARR 4 /* array */ -#define STR 8 /* string */ -#define REC 16 /* record */ -#define FLD 32 /* filed */ -#define PAT 64 /* pattern (compiled REGEXPR) */ -#define BRK 128 /* break */ -#define CNT 256 /* continue */ -#define NXT 512 /* next */ -#define EXT 1024 /* exit */ -#define RTN 2048 /* return */ -#define TMP 4096 /* temp cell */ -#define POS 8192 /* argument position */ -#define FUN 16384 /* function */ - - /* symbol cell - linked to symbol table */ - -struct symbol { - char *s_name; - CELL *s_val; - struct symbol *s_next; -}; - -typedef struct symbol SYMBOL; diff --git a/commands/awk.old/build b/commands/awk.old/build deleted file mode 100755 index 3ee5f0395..000000000 --- a/commands/awk.old/build +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/sh -make clean -make && make install diff --git a/commands/awk.old/e.c b/commands/awk.old/e.c deleted file mode 100644 index 3b6be1374..000000000 --- a/commands/awk.old/e.c +++ /dev/null @@ -1,952 +0,0 @@ -/* - * a small awk clone - * - * (C) 1989 Saeko Hirabauashi & Kouichi Hirabayashi - * - * Absolutely no warranty. Use this software with your own risk. - * - * Permission to use, copy, modify and distribute this software for any - * purpose and without fee is hereby granted, provided that the above - * copyright and disclaimer notice. - * - * This program was written to fit into 64K+64K memory of the Minix 1.2. - */ - - -#include -#include -#include "awk.h" -#include "regexp.h" - -extern char **FS, **OFS, **ORS, **OFMT; -extern double *RSTART, *RLENGTH; -extern char record[]; -extern CELL *field[]; - -extern int r_start, r_length; - -double getfval(), atof(); -char *strsave(), *getsval(), *strcat(), *strstr(); -CELL *mkcell(), *mktmp(); -CELL *Field(), *Split(), *Forin(); -CELL *Arith(), *Assign(), *Stat(), *Mathfun(), *Strfun(), *Cond(); -CELL *Print(), *Cat(), *Array(), *Element(); -CELL *If(), *While(), *For(), *Do(), *Jump(); -CELL *P1stat(), *P2stat(), *Print0(); -CELL *Arg(), *Call(), *Ret(); -CELL *Subst(), *In(), *Getline(), *Delete(), *Close(); -CELL *Nulproc(), *Usrfun(); -CELL *_Arg(); - -FILE *getfp(); /* r.c */ - -CELL truecell = { NUM, NULL, 1.0 }; -CELL falsecell = { NUM, NULL, 0.0 }; -static CELL breakcell = { BRK, NULL, 0.0 }; -static CELL contcell = { CNT, NULL, 0.0 }; -static CELL nextcell = { NXT, NULL, 0.0 }; -static CELL retcell = { RTN, NULL, 0.0 }; - -static CELL *retval; /* function return value */ - -int pateval; /* used in P1STAT & P2STAT */ -static char *r_str; /* STR in 'str ~ STR */ -static regexp *r_pat; /* compiled pattern for STR */ - -CELL *(*proctab[])() = { - Arg, Arith, Array, Assign, Call, Cat, Cond, Delete, Do, Element, - Field, For, Forin, Getline, If, In, Jump, Mathfun, Nulproc, P1stat, - P2stat, Print, Print0, Strfun, Subst, Usrfun, While -}; - -CELL * -execute(p) NODE *p; -{ - int type, i; - CELL *r, *(*proc)(); - - type = p->n_type; - if (type == VALUE) { - if ((r = (CELL *) p->n_arg[0])->c_type & PAT && pateval) { - i = match(r->c_sval, (char *)record) ? 1 : 0; - r = mktmp(NUM, NULL, (double) i); - } - return r; - } - for ( ; p != NULL; p = p->n_next) { -#if 0 - if (p->n_type == VALUE) continue; /* neglect */ -#endif -/* - switch ((int) p->n_type) { - case ARRAY: - r = Array(p); - break; - case ARITH: - r = Arith(p); - break; - case ASSIGN: - r = Assign(p); - break; - case PRINT: - r = Print(p); - break; - case PRINT0: - r = Print0(p); - break; - case CAT: - r = Cat(p); - break; - case MATHFUN: - r = Mathfun(p); - break; - case STRFUN: - r = Strfun(p); - break; - case COND: - r = Cond(p); - break; - case IF: - r = If(p); - break; - case P1STAT: - r = P1stat(p); - break; - case P2STAT: - r = P2stat(p); - break; - case WHILE: - r = While(p); - break; - case DO: - r = Do(p); - break; - case FOR: - r = For(p); - break; - case FORIN: - r = Forin(p); - break; - case FIELD: - r = Field(p); - break; - case JUMP: - r = Jump(p); - break; - case ARG: - r = Arg(p); - break; - case CALL: - r = Call(p); - break; - case SUBST: - r = Subst(p); - break; - case ELEMENT: - r = Element(p); - break; - case IN: - r = In(p); - break; - case GETLINE: - r = Getline(p); - break; - case DELETE: - r = Delete(p); - break; - case NULPROC: - r = &truecell; - break; - default: - printf("PROGRAM ERROR ? ILLEGAL NODE TYPE(%d)\n", type); - exit(1); - break; - } -*/ - i = (int) p->n_type; - if (i < FIRSTP || i > LASTP) - error("ILLEGAL PROC (%d)", i); - proc = proctab[i - FIRSTP]; - r = (*proc)(p); - if (r->c_type & (BRK|CNT|NXT|RTN)) - return r; - if (p->n_next != NULL) - c_free(r); -#ifdef DOS - kbhit(); /* needs in MS-DOS */ -#endif - } - return r; -} - -static CELL * -Arith(p) NODE *p; -{ - int op; - CELL *r, *u, *v, *execute(); - double x, y, fmod(), pow(); - - op = (int) p->n_arg[0]; - if (op == UMINUS) { - u = execute(p->n_arg[1]); - x = - getfval(u); - } - else if (op == INCDEC) { - u = execute(p->n_arg[1]); - x = getfval(u); - setfval(u, x + (int) p->n_arg[2]); - if ((int) p->n_arg[3] == PRE) - return u; - /* return dummy */ - } - else { - u = execute(p->n_arg[1]); - v = execute(p->n_arg[2]); - x = getfval(u); - y = getfval(v); - if (op == DIV || op == MOD) { - if (y == 0.0) - fprintf(stderr, "divid by 0\n"); - } - switch (op) { - case SUB: x -= y;break; - case ADD: x += y; break; - case MULT: x *= y; break; - case DIV: - if (y == 0.0) - error("division by zero in \"/\"", (char *)0); - x /= y; break; - case MOD: - if (y == 0.0) - error("division by zero in \"%%\"", (char *)0); - x = fmod(x, y); break; - case POWER: x = pow(x, y); break; - default: printf("UNSUPPORTED ARITH OPERATOR !\n"); break; - } - c_free(v); - } - c_free(u); - r = mktmp(NUM, NULL, x); - return r; -} - -static CELL * -Assign(p) NODE *p; -{ - CELL *u, *v, *execute(); - int op; - double x, y, fmod(), pow(); - - op = (int) p->n_arg[0]; - u = execute(p->n_arg[1]); - -#if 0 - if (u->c_type == UDF) /* fix up local var */ - u->c_type |= VAR|STR; -#endif - if (!(u->c_type & (VAR|FLD|REC)) && (u->c_type != UDF)) - fprintf(stderr, "ASSIGN TO NON VARIABLE (%d)\n", u->c_type); - v = execute(p->n_arg[2]); - - if (u == v) - goto rtn; /* same node */ - - if (op == ASSIGN) { - if (v->c_type & NUM/* || isnum(v->c_sval)*/) - setfval(u, getfval(v)); - else - setsval(u, getsval(v)); - } - else { - x = getfval(u); - y = getfval(v); - switch (op) { - case ADDEQ: x += y; break; - case SUBEQ: x -= y; break; - case MULTEQ: x *= y; break; - case DIVEQ: - if (y == 0.0) - error("division by zero in \"/=\"", (char *)0); - x /= y; break; - case MODEQ: - if (y == 0.0) - error("division by zero in \"%=\"", (char *)0); - x = fmod(x, y); break; - case POWEQ: x = pow(x, y); break; - default: - synerr("illegal assign op (%d)", op); - break; - } - setfval(u, x); - } -rtn: - c_free(v); - return u; -} - -static CELL * -Cat(p) NODE *p; -{ - CELL *u; - char *s, *t, str[BUFSIZ]; - - u = execute(p->n_arg[0]); - s = getsval(u); - for (t = str; *s; ) - *t++ = *s++; - c_free(u); - u = execute(p->n_arg[1]); - s = getsval(u); - while (*s) - *t++ = *s++; - c_free(u); - *t = '\0'; - return mktmp(STR, str, 0.0); -} - -static CELL * -Print(p) NODE *p; -{ - register int i, redir, typ; - CELL *u; - char *s, str[BUFSIZ]; - char *file; - FILE *fp; - - redir = (int) p->n_arg[0]; - if (typ = redir & PRMASK) { /* redirect */ - u = execute(p->n_arg[1]); - file = getsval(u); - if (typ == R_PIPE) - typ = R_POUT; - fp = getfp(file, typ); - c_free(u); - } - else - fp = stdout; - if (redir & FORMAT) /* format */ - format(str, p); - else { - *str = '\0'; - for (i = 2; p->n_arg[i] != NULL; i++) { - if (i > 2) - strcat(str, *OFS); - u = execute(p->n_arg[i]); - s = getsval(u); - strcat(str, s); - c_free(u); - } - strcat(str, *ORS); - } - if (redir & STROUT) /* sprintf */ - return mktmp(STR, str, 0.0); - fputs(str, fp); - fflush(fp); - return &truecell; -} - -static CELL * -Mathfun(p) NODE *p; -{ - CELL *u, *v; - double x, y; - double atan2(), cos(), exp(), log(), sin(), sqrt(), modf(); - - if ((int) p->n_arg[1] == 0) { - u = NULL; - x = 0.0; - } - else { - u = execute(p->n_arg[2]); - x = getfval(u); - } - switch ((int) p->n_arg[0]) { - case ATAN2: - if ((int) p->n_arg[1] == 2) { - v = execute(p->n_arg[3]); - y = getfval(v); - x = atan2(x, y); - c_free(v); - } - else - x = 0.0; - break; - case COS: x = cos(x); break; - case EXP: x = exp(x); break; - case INT: y = modf(x, &x); break; - case LOG: x = log(x); break; - case SIN: x = sin(x); break; - case SQRT: x = sqrt(x); break; - case RAND: x = (double) rand() / 32768.0; break; - case SRAND: if (x == 0.0) - x = (double) time(0); - x = (double) srand((int) x); - break; - default: - fprintf(stderr, "unknown math function (%d)\n", p->n_arg[2]); - break; - } - if (u != NULL) - c_free(u); - return mktmp(NUM, NULL, x); -} - -static CELL * -Strfun(p) NODE *p; -{ - CELL *u, *v, *r; - char *s, *t, str[BUFSIZ]; - int i, m, n; - double x; - regexp *pat, *getpat(); - - n = (int) p->n_arg[1]; - if (n > 0 && (int) p->n_arg[0] != SPLIT) { - u = execute(p->n_arg[2]); - s = getsval(u); - } - else { - s = ""; - u = NULL; - } - switch ((int) p->n_arg[0]) { - case INDEX: - if (n > 1) { - v = execute(p->n_arg[3]); - t = getsval(v); - i = Index(s, t); - c_free(v); - } - else - i = 0; - r = mktmp(NUM, NULL, (double) i); - break; - case LENGTH: - i = (n > 0) ? jstrlen(s) : jstrlen(record); - r = mktmp(NUM, NULL, (double) i); - break; - case SPLIT: - r = Split(p); - break; - case SUBSTR: - if (n > 1) { - v = execute(p->n_arg[3]); - m = (int) getfval(v) - 1; - c_free(v); - } - else - m = 0; - if (n > 2) { - v = execute(p->n_arg[4]); - n = (int) getfval(v); - c_free(v); - } - else - n = jstrlen(s) - m; - for (t = str; *s && m-- > 0; s++) - if (isKanji(*s)) - s++; - while (*s && n-- > 0) { - if (isKanji(*s)) - *t++ = *s++; - *t++ = *s++; - } - *t = '\0'; - r = mktmp(STR, str, 0.0); - break; - case RMATCH: - if (n > 1) { - v = execute(p->n_arg[3]); - pat = getpat(v); - match(pat, s); - c_free(v); - if (r_start) { /* change only if match */ - *RSTART = (double) r_start; - *RLENGTH = (double) r_length; - } - r = mktmp(NUM, NULL, (double) r_start); - } - else - error("missing regexpr in match(str, regexpr)"); - break; - case CLOSE: - r = Close(s); - break; - case SYSTEM: - r = mktmp(NUM, NULL, system(s) == -1 ? 0.0 : 1.0); - break; - default: - fprintf(stderr, "unknown string function"); - break; - } - c_free(u); - return r; -} - -static regexp * -getpat(r) CELL *r; -{ - regexp *pat, *mkpat(); - - if (r->c_type & PAT) - pat = (regexp *) r->c_sval; - else { - if (r_str && strcmp(r_str, r->c_sval) == 0) - pat = r_pat; - else { - sfree(r_str); sfree(r_pat); - r_str = strsave(getsval(r)); - pat = r_pat = mkpat(r_str); - } - } - return pat; -} - -static CELL * -Subst(p) NODE *p; -{ - CELL *u, *v, *w; - char *s, *t, *r, str[BUFSIZ], *strcpy(); - int i, n; - - n = (int) p->n_arg[1]; - if (n > 1) { - u = execute(p->n_arg[3]); /* substitute string */ - s = getsval(u); - v = execute(p->n_arg[2]); /* expr */ - if (n > 2) { - w = execute(p->n_arg[4]); - t = getsval(w); - r = str; - } - else { - t = r = record; - w = NULL; - } - i = (int) p->n_arg[0] == RGSUB ? 0 : 1; - if (v->c_type & (PAT|STR)) - i = Sub(r, v->c_sval, (v->c_type & STR), s, t, i); - else - error("[g]sub(PAT, .. ) must be /../ or string (%d)", - w->c_type); - if (n > 2) { - if (w->c_type & REC) { - strcpy(record, str); - mkfld(record, *FS, field); - } - else - setsval(w, str); - } - else - mkfld(record, *FS, field); - c_free(u); - c_free(v); - c_free(w); - } - else - i = 0; - return mktmp(NUM, NULL, (double) i); -} - -static CELL * -Cond(p) NODE *p; -{ - CELL *u, *v; - double x, y; - int op, i, j; - char *s; - int save = pateval; - - op = (int) p->n_arg[0]; - u = execute(p->n_arg[1]); - x = getfval(u); -/* -printf("Cond(%d)(%s)\n", u->c_type, u->c_sval); -*/ - if (op == AND || op == OR || op == NOT) { - if (u->c_type & NUM) - i = (x != 0.0); - else { - s = getsval(u); - i = (s != (char *)NULL) && (*s != '\0'); - } - } - if (op == AND && !i) { - c_free(u); - return &falsecell; - } - if (op == OR && i) { - c_free(u); - return &truecell; - } - if (op == NOT) - i = i == 0 ? 1 : 0; - else { - if (op == MATCH || op == NOMATCH) - pateval = 0; - v = execute(p->n_arg[2]); - y = getfval(v); - if (op == AND || op == OR || op == BINAND || op == BINOR) { - if (v->c_type & NUM) - j = (y != 0.0); - else { - s = getsval(v); - j = (s != (char *)NULL) && (*s != '\0'); - } - switch (op) { - case AND: i = i && j; break; - case OR: i = i || j; break; - case BINAND: i = i & j; break; - case BINOR: i = i | j; break; - } - } - else if (op == MATCH || op == NOMATCH) { - char *s; - regexp *pat, *getpat(); - - s = getsval(u); - pat = getpat(v); - i = match(pat, s) == 0 ? 0 : 1; - if (op == NOMATCH) - i = i == 0 ? 1 : 0; - } - else { /* relative operator */ -/* -printf("Cond(%d)(%d)(%s)(%s)\n", u->c_type, v->c_type, u->c_sval, v->c_sval); -*/ - if ((u->c_type & NUM) && (v->c_type & NUM)) - i = x < y ? -1 : (x > y ? 1 : 0); - else - i = strcmp(getsval(u), getsval(v)); -/* -printf("Cond(%d)(%d)(%g)(%g)(%d)\n", u->c_type, v->c_type, x, y, i); -*/ - - switch (op) { - case LT: i = i < 0 ? 1 : 0; break; - case LE: i = i <= 0 ? 1 : 0; break; - case EQ: i = i == 0 ? 1 : 0; break; - case NE: i = i != 0 ? 1 : 0; break; - case GT: i = i > 0 ? 1 : 0; break; - case GE: i = i >= 0 ? 1 : 0; break; - default: - fprintf(stderr, "unknown relative operator (%d)\n", op); - break; - } - } - c_free(v); - } - c_free(u); - pateval = save; - return mktmp(NUM, NULL, (double) i); -} - -static CELL * -If(p) NODE *p; -{ - CELL *u; - int i; - char *s; - - u = execute(p->n_arg[0]); - if (u->c_type & NUM) - i = (getfval(u) != 0.0); - else { - s = getsval(u); - i = (s != (char *)NULL) && (*s != '\0'); - } - c_free(u); - if (i) - u = execute(p->n_arg[1]); - else if (p->n_arg[2]) - u = execute(p->n_arg[2]); - else - u = &truecell; - return u; -} - -static CELL * -While(p) NODE *p; -{ - CELL *u; - double x; - - for (;;) { - u = execute(p->n_arg[0]); - x = getfval(u); - if (x == 0.0) - break; - c_free(u); - u = execute(p->n_arg[1]); - switch (u->c_type) { - case BRK: - goto rtn; - case NXT: case EXT: case RTN: - return u; - } - c_free(u); - } -rtn: - c_free(u); - return &truecell; -} - -static CELL * -Do(p) NODE *p; -{ - CELL *u; - double x; - - for (;;) { - u = execute(p->n_arg[0]); - switch (u->c_type) { - case BRK: - goto rtn; - case NXT: case EXT: case RTN: - return u; - } - c_free(u); - u = execute(p->n_arg[1]); - if(getfval(u) == 0.0) - break; - c_free(u); - } -rtn: - c_free(u); - return &truecell; -} - -static CELL * -For(p) NODE *p; -{ - CELL *u; - double x; - - if (p->n_arg[0] != NULL) { - u = execute(p->n_arg[0]); - c_free(u); - } - for (;;) { - if (p->n_arg[1] != NULL) { - u = execute(p->n_arg[1]); - x = getfval(u); - c_free(u); - if (x == 0.0) - break; - } - u = execute(p->n_arg[3]); - switch (u->c_type) { - case BRK: - c_free(u); - goto rtn; - case NXT: case EXT: case RTN: - return u; - } - if (p->n_arg[2] != NULL) { - u = execute(p->n_arg[2]); - c_free(u); - } - } -rtn: - return &truecell; -} - -static CELL * -Jump(p) NODE *p; -{ - CELL *u; - int i; - - switch ((int) p->n_arg[0]) { - case BREAK: u = &breakcell; break; - case CONTIN: u = &contcell; break; - case EXIT: - if ((int) p->n_arg[1]) { - u = execute(p->n_arg[1]); - i = (int) getfval(u); - } - else - i = 0; - closeall(); - exit(i); - case RETURN: - Return(p); - u = &retcell; - break; - case NEXT: u = &nextcell; break; - } - return u; -} - -static -Return(p) NODE *p; -{ - CELL *u; - int i; - char *s, str[BUFSIZ]; - - c_free(retval); - if (p->n_arg[1] != NULL) { - if (p->n_arg[2] == NULL) { -/* -if (0) { -*/ - u = execute(p->n_arg[1]); - if (u->c_type == UDF) - retval = mktmp(STR, "", 0.0); - else - retval = mktmp(u->c_type, u->c_sval, u->c_fval); - c_free(u); - } - else { - for (i = 1; p->n_arg[i] != NULL; i++) { - if (i == 1) - *str = '\0'; - else - strcat(str, *OFS); - u = execute(p->n_arg[i]); - s = getsval(u); - strcat(str, s); - c_free(u); - } -/* -printf("Ret(%s)(%d)\n", str, isnum(str)); -*/ - if (isnum(str)) - retval = mktmp(STR|NUM, str, atof(str)); - else - retval = mktmp(STR, str, 0.0); - } - } - else - retval = &truecell; -} - -#define MAXFRAME 100 -CELL **frame[MAXFRAME]; -static int framep; - -static CELL * -Arg(p) NODE *p; -{ - CELL *u; - int i; - - u = (CELL *)p->n_arg[0]; - return _Arg((int)u->c_fval); -} - -CELL * -_Arg(i) -{ -/* -printf("Arg(%d)\n", i); -*/ - return frame[framep - 1][i]; -} - -static CELL * -Call(p) NODE *p; -{ - CELL *u, *v, *r, **arg; - NODE *q; - int i, j, k, n; - char *emalloc(); - - if (framep >= MAXFRAME - 2) - error("stack frame overflow", (char *)0); - retval = &truecell; - r = (CELL *) p->n_arg[0]; - if (r->c_type != FUN) - synerr("called function is not declared", (char *)0); - n = (int) r->c_fval; /* # of params */ - if (n > 0) { - arg = (CELL **) emalloc(sizeof(u) * n); - for (i = 2, j = 0, k = (int) p->n_arg[1]; j < k; i++) { - u = execute(p->n_arg[i]); -/* -printf("pass, j(%d)typ(%d)\n", j, u->c_type); -*/ - if (u->c_type & ARR) - v = u; /* pass by reference */ - else { /* pass by value */ - v = mkcell(UDF, u->c_sval, u->c_fval); - if (u->c_type != UDF) { -#if 0 - v->c_type = u->c_type; - if (v->c_type & (NUM|STR)) - v->c_type |= VAR; - v->c_type &= ~TMP; /* dont't free */ -#else - v->c_type |= (u->c_type & (NUM|STR))|VAR; - /*v->c_type &= ~TMP;*/ -#endif - /* Don't free original */ - } -/* -printf("pass1, j(%d)typ(%d)\n", j, v->c_type); -*/ - } - arg[j++] = v; - } - for ( ; j < n; ) /* local var */ - arg[j++] = mkcell(UDF, NULL, 0.0); - } - else - arg = NULL; - - frame[framep] = arg; - framep++; - - r = execute(r->c_sval); - c_free(r); - framep--; - if (n > 0) { - for (j = n - 1 ; j > k; j--) { /* local var */ - u = arg[j]; - if (u->c_type & ARR) - a_free(u); - else - c_free(u); - } - for ( ; j >= 0; j--) { - u = arg[j]; - if (!(u->c_type & ARR)) { -/* c_free(u);*/ - sfree(u->c_sval); - sfree(u); - } - else { - v = execute(p->n_arg[j + 2]); - if (v->c_type == UDF) { /* copy back */ -/* -printf("copy_back_UDF(%d)(%d)\n", j, u->c_type); -*/ - v->c_type = u->c_type; - sfree(v->c_sval); - v->c_sval = u->c_sval; - v->c_fval = u->c_fval; - sfree(u); - } - } - } - } - sfree(arg); -/* return retval;*/ - u = mktmp(retval->c_type, retval->c_sval, retval->c_fval); - return u; -} - -CELL *Nulproc() -{ - return &truecell; -} - -CELL * -Usrfun(p) NODE *p; -{ - CELL *u; - - u = execute(p); - return u; -} diff --git a/commands/awk.old/k.c b/commands/awk.old/k.c deleted file mode 100644 index 94f81e63d..000000000 --- a/commands/awk.old/k.c +++ /dev/null @@ -1,43 +0,0 @@ -/* - * a small awk clone - * - * (C) 1989 Saeko Hirabauashi & Kouichi Hirabayashi - * - * Absolutely no warranty. Use this software with your own risk. - * - * Permission to use, copy, modify and distribute this software for any - * purpose and without fee is hereby granted, provided that the above - * copyright and disclaimer notice. - * - * This program was written to fit into 64K+64K memory of the Minix 1.2. - */ - - -#include - -isKanji(c) -{ - c &= 0xff; - return (c > 0x80 && c < 0xa0 || c > 0xdf && c < 0xfd); -} - -jstrlen(s) char *s; -{ - int i; - - for (i = 0; *s; i++, s++) - if (isKanji(*s)) - s++; - return i; -} - -char * -jStrchr(s, c) char *s; -{ - for ( ; *s; s++) - if (isKanji(*s)) - s++; - else if (*s == c) - return s; - return NULL; -} diff --git a/commands/awk.old/l.c b/commands/awk.old/l.c deleted file mode 100644 index 8e86c50cc..000000000 --- a/commands/awk.old/l.c +++ /dev/null @@ -1,353 +0,0 @@ -/* - * a small awk clone - * - * (C) 1989 Saeko Hirabauashi & Kouichi Hirabayashi - * - * Absolutely no warranty. Use this software with your own risk. - * - * Permission to use, copy, modify and distribute this software for any - * purpose and without fee is hereby granted, provided that the above - * copyright and disclaimer notice. - * - * This program was written to fit into 64K+64K memory of the Minix 1.2. - */ - - -#include -#include -#include "awk.h" - -extern char *srcprg; /* inline program */ -extern FILE *pfp; /* program file */ - -int sym; /* lexical token */ -int sym1; /* auxiliary lexical token */ -int regexflg; /* set by parser (y.c) to indicate parsing REGEXPR */ -int funflg; /* set by parser (y.c) to indicate parsing FUNCTION */ -int printflg; /* set by parser (y.c) to indicate parsing PRINT */ -int getlineflg; /* set by parser (y.c) to indicate parsing GETLINE */ -char text[BUFSIZ]; /* lexical word */ -char line[BUFSIZ]; /* program line for error message (ring buffer) */ -char *linep = line; /* line pointer */ -char funnam[128]; /* function name for error message */ -int lineno = 1; - -lex() -{ - int c, d; - char *s; - - if (regexflg) - return sym = scanreg(); -next: - while ((c = Getc()) == ' ' || c == '\t') - ; - while (c == '#') - for (c = Getc(); c != '\n'; c = Getc()) - ; - switch (c) { - case '\\': - if ((c = Getc()) == '\n') { - lineno++; - goto next; - } - break; - case '\n': - lineno++; - break; - } - switch (c) { - case EOF: return sym = 0; - case '+': return sym = follow2('=', '+', ADDEQ, INC, ADD); - case '-': return sym = follow2('=', '-', SUBEQ, DEC, SUB); - case '*': return sym = follow('=', MULTEQ, MULT); - case '/': return sym = follow('=', DIVEQ, DIV); - case '%': return sym = follow('=', MODEQ, MOD); - case '^': return sym = follow('=', POWEQ, POWER); - case '=': return sym = follow('=', EQ, ASSIGN); - case '!': return sym = follow2('=', '~', NE, NOMATCH, NOT); - case '&': return sym = follow('&', AND, BINAND); - case '|': sym = follow('|', OR, BINOR); - if (printflg && sym == BINOR) - sym = R_POUT; - return sym; - case '<': sym = follow2('=', '<', LE, SHIFTL, LT); - if (getlineflg && sym == LT) - sym = R_IN; - return sym; - case '>': sym = follow2('=', '>', GE, SHIFTR, GT); - if (printflg) { - switch (sym) { - case GT: sym = R_OUT; break; - case SHIFTR: sym = R_APD; break; - } - } - return sym; - case '~': return sym = MATCH; break; - case ';': case '\n': return sym = EOL; - } - if (isalpha(c) || c == '_') { - for (s = text; isalnum(c) || c == '_'; ) { - *s++ = c; c = Getc(); - } - Ungetc(c); - *s = '\0'; - if ((d = iskeywd(text)) == 0 && - (d = isbuiltin(text, &sym1)) == 0) { - if (c == '(') - return sym = CALL; - else if (funflg) { - if ((sym1 = isarg(text)) != -1) - return sym = ARG; - } - } - return sym = d ? d : IDENT; - } - else if (c == '.' || (isdigit(c))) { - Ungetc(c); - return sym = scannum(text); /* NUMBER */ - } - else if (c == '"') - return sym = scanstr(text); /* STRING */ - return sym = c; -} - -static -follow(c1, r1, r2) -{ - register int c; - - if ((c = Getc()) == c1) - return r1; - else { - Ungetc(c); - return r2; - } -} - -static -follow2(c1, c2, r1, r2, r3) -{ - register int c; - - if ((c = Getc()) == c1) - return r1; - else if (c == c2) - return r2; - else { - Ungetc(c); - return r3; - } -} - -static -iskeywd(s) char *s; -{ - static struct { char *kw; int token; } tab[] = { - "BEGIN", BEGIN, - "END", END, - "break", BREAK, - "continue", CONTIN, - "delete", DELETE, - "do", DO, - "else", ELSE, - "exit", EXIT, - "for", FOR, - "func", FUNC, - "function", FUNC, - "getline", GETLINE, - "if", IF, - "in", IN, - "next", NEXT, - "print", PRINT, - "printf", PRINTF, - "return", RETURN, - "sprint", SPRINT, - "sprintf", SPRINTF, - "while", WHILE, - "", 0, 0 - }; - register int i; - - for (i = 0; tab[i].token; i++) - if (strcmp(tab[i].kw, s) == 0) - break; - return tab[i].token; -} - -static -isbuiltin(s, p) char *s; int *p; -{ - static struct { char *kw; int type; int token; } tab[] = { - "atan2", MATHFUN, ATAN2, - "close", STRFUN, CLOSE, - "cos", MATHFUN, COS, - "exp", MATHFUN, EXP, - "gsub", SUBST, RGSUB, - "index", STRFUN, INDEX, - "int", MATHFUN, INT, - "length", STRFUN, LENGTH, - "log", MATHFUN, LOG, - "match", STRFUN, RMATCH, - "sin", MATHFUN, SIN, - "sqrt", MATHFUN, SQRT, - "rand", MATHFUN, RAND, - "srand", MATHFUN, SRAND, - "split", STRFUN, SPLIT, - "sub", SUBST, RSUB, - "substr", STRFUN, SUBSTR, - "system", STRFUN, SYSTEM, - "", 0, 0 - }; - register int i; - - for (i = 0; tab[i].token; i++) - if (strcmp(tab[i].kw, s) == 0) - break; - *p = tab[i].token; - return tab[i].type; -} - -static -scannum(s) char *s; -{ - register int c; - char *strchr(); - - if ((c = Getc()) && strchr("+-", c) != NULL) { - *s++ = c; c = Getc(); - } - while (isdigit(c)) { - *s++ = c; c = Getc(); - } - if (c == '.') { - *s++ = c; c = Getc(); - while (isdigit(c)) { - *s++ = c; c = Getc(); - } - } - if (c && strchr("eE", c) != NULL) { - *s++ = c; c = Getc(); - if (c && strchr("+-", c) != NULL) { - *s++ = c; c = Getc(); - } - while (isdigit(c)) { - *s++ = c; c = Getc(); - } - } - *s = '\0'; - Ungetc(c); - return NUMBER; -} - -static -scanstr(s) char *s; -{ - register int c, i, j; - - for (c = Getc(); c != EOF & c != '"'; ) { - if (c == '\\') { - switch (c = Getc()) { - case 'b': c = '\b'; break; - case 'f': c = '\f'; break; - case 'n': c = '\n'; break; - case 'r': c = '\r'; break; - case 't': c = '\t'; break; - default: - if (isdigit(c)) { - for (i = j = 0; i < 3 && isdigit(c); c = Getc(), i++) - j = j * 8 + c - '0'; - Ungetc(c); - c = j; - } - break; - } - } - *s++ = c; - if (isKanji(c)) - *s++ = Getc(); - c = Getc(); - } - *s = '\0'; - return STRING; -} - -static -scanreg() -{ - register int c; - register char *s; - - for (s = text; (c = Getc()) != '/'; ) - if (c == '\n') - error("newline in regular expression"); - else { - if (isKanji(c) || c == '\\') { - *s++ = c; c = Getc(); - } - *s++ = c; - } - *s = '\0'; - return REGEXP; -} - -isarrayindex() -{ - int c, c2; - -next: - while ((c = Getc()) == ' ' || c == '\t') - ; - if (c == '\\') { - if ((c2 = Getc()) == '\n') { - lineno++; - goto next; - } - Ungetc(c2); - } - if (c != '[') Ungetc(c); - - return (c == '['); -} - -#define UNGET_DEPTH 2 -static int unget[UNGET_DEPTH], unget_depth; - -Ungetc(c) -{ - if (unget_depth == UNGET_DEPTH) error("unget buffer overflow"); - unget[unget_depth++] = c; - - if (linep > line) { - if (--linep < line) - linep == line + BUFSIZ - 1; - } -} - -Getc() -{ - register int c; - char *s, *t; - - if (unget_depth > 0) - c = unget[--unget_depth]; - else if (srcprg) - c = *srcprg ? *srcprg++ : EOF; - else - c = fgetc(pfp); - -#if 0 - if (linep - line == BUFSIZ) { -printf("!!!\n"); - for (s = line; *s != '\n' && ((s - line) -#include -#include -#include "awk.h" - -extern char **FS, **FILENAME; -extern char record[]; -extern FILE *ifp; - -NODE *parse(); -CELL *execute(); -FILE *efopen(), *fopen(); -char *strsave(); - -int xargc; -char **xargv; -char *srcprg; -FILE *pfp; -char *cmd; -#if 0 -int iflg; /* interactive mode */ -#endif - -main(argc, argv, envp) char **argv, *envp; -{ - char *s, *strpbrk(), *strchr(); - void onint(); - -#ifdef DOS - _sharg(&argc, &argv); -#endif - signal(SIGINT, onint); - signal(SIGFPE, onint); - cmd = argv[0]; - init(); - while (--argc > 0 && (*++argv)[0] == '-') - for (s = argv[0]+1; *s; s++) - if (strcmp(argv[0], "-") == 0) - break; - else - switch (*s) { -#if 0 - case 'i': - iflg++; - pfp = stdin; - interactive(); - /* no return */ -#endif - case 'F': - *FS = ++s; - break; - case 'f': - if (*(s+1)) - s++; - else { - argc--; s = *++argv; - } - if (s == NULL) usage(); - pfp = efopen(s, "r"); - s += strlen(s) - 1; - break; - } - xargc = argc; xargv = argv; - if (pfp == NULL && xargc > 0) { - srcprg = *xargv++; xargc--; - } -/* - if (pfp == NULL && xargc > 0) { - if (strpbrk(xargv[0], " !$^()={}[];<>,/~") != NULL) { - sprintf(record, "%s\n", xargv[0]); - srcprg = strsave(record); - } - else { - sprintf(record, "%s.awk", xargv[0]); - if ((pfp = fopen(record, "r")) == NULL) - error("can't open %s", record); - } - xargc--; xargv++; - } -*/ - - if (pfp == NULL && srcprg == NULL) usage(); - - while (*xargv != NULL && strchr(*xargv, '=') != NULL) { - setvar(*xargv++); - xargc--; - } - - initarg(cmd, xargc, xargv, envp); - if (xargc == 0) { - ifp = stdin; *FILENAME = "-"; - } - parse(); - closeall(); - exit(0); -} - -FILE * -efopen(file, mode) char *file, *mode; -{ - FILE *fp, *fopen(); - - if ((fp = fopen(file, mode)) == NULL) - error("cannot open %s", file); - return fp; -} - -error(s, t) char *s, *t; -{ - extern double *NR; - - fprintf(stderr, "awk: "); - fprintf(stderr, s, t); - fprintf(stderr, "\n"); - if (NR != NULL) { - fprintf(stderr, "record number %g\n", *NR); - } -#ifdef DOS - closeall(); -#endif - exit(1); -} - -void -onint(i) -{ - closeall(); - exit(0x80 | i); -} - -void -usage() -{ - fprintf(stderr, - "usage: %s [options] [-f | ] [inputfiles]\n", cmd); - closeall(); - exit(1); -} diff --git a/commands/awk.old/n.c b/commands/awk.old/n.c deleted file mode 100644 index 489d3e5b6..000000000 --- a/commands/awk.old/n.c +++ /dev/null @@ -1,149 +0,0 @@ -/* - * a small awk clone - * - * (C) 1989 Saeko Hirabauashi & Kouichi Hirabayashi - * - * Absolutely no warranty. Use this software with your own risk. - * - * Permission to use, copy, modify and distribute this software for any - * purpose and without fee is hereby granted, provided that the above - * copyright and disclaimer notice. - * - * This program was written to fit into 64K+64K memory of the Minix 1.2. - */ - - -#include -#include "awk.h" - -NODE * -node0(type) -{ - NODE *p; - char *emalloc(); - - p = (NODE *) emalloc(sizeof(*p) - sizeof(p)); - p->n_type = type; - p->n_next = NULL; - return p; -} - -NODE * -node1(type, arg0) NODE *arg0; -{ - NODE *p; - char *emalloc(); - - p = (NODE *) emalloc(sizeof(*p)); - p->n_type = type; - p->n_next = NULL; - p->n_arg[0] = (NODE *) arg0; - return p; -} - -NODE * -node2(type, arg0, arg1) NODE *arg0, *arg1; -{ - NODE *p; - char *emalloc(); - - p = (NODE *) emalloc(sizeof(*p) + sizeof(p) * 1); - p->n_type = type; - p->n_next = NULL; - p->n_arg[0] = (NODE *) arg0; - p->n_arg[1] = (NODE *) arg1; - return p; -} - -NODE * -node3(type, arg0, arg1, arg2) NODE *arg0, *arg1, *arg2; -{ - NODE *p; - char *emalloc(); - - p = (NODE *) emalloc(sizeof(*p) + sizeof(p) * 2); - p->n_type = type; - p->n_next = NULL; - p->n_arg[0] = (NODE *) arg0; - p->n_arg[1] = (NODE *) arg1; - p->n_arg[2] = (NODE *) arg2; - return p; -} - -NODE * -node4(type, arg0, arg1, arg2, arg3) NODE *arg0, *arg1, *arg2, *arg3; -{ - NODE *p; - char *emalloc(); - - p = (NODE *) emalloc(sizeof(*p) + sizeof(p) * 3); - p->n_type = type; - p->n_next = NULL; - p->n_arg[0] = (NODE *) arg0; - p->n_arg[1] = (NODE *) arg1; - p->n_arg[2] = (NODE *) arg2; - p->n_arg[3] = (NODE *) arg3; - return p; -} - -CELL * -mkcell(type, sval, fval) char *sval; double fval; -{ - CELL *p; - char *emalloc(), *strsave(); - - p = (CELL *) emalloc(sizeof(*p)); - p->c_type = type; - if (sval == NULL) - p->c_sval = NULL; - else - p->c_sval = strsave(sval); - p->c_fval = fval; - return p; -} - -#ifdef TMPCELL -#define MAXTMP 25 - -CELL tmpcell[MAXTMP]; -#endif - -CELL * -mktmp(type, sval, fval) char *sval; double fval; -{ - register int i; - char *strsave(); - -#ifdef TMPCELL - for (i = 0; i < MAXTMP; i++) - if (tmpcell[i].c_type == 0) { - tmpcell[i].c_type = type | TMP; - tmpcell[i].c_sval = strsave(sval); - tmpcell[i].c_fval = fval; - return &tmpcell[i]; - } - error("formula too complex", (char *) 0); -#else - return mkcell(type | TMP, sval, fval); -#endif -} - -c_free(p) CELL *p; -{ - if ((p != NULL) && (p->c_type & TMP)) { -#ifdef TMPCELL - p->c_type = 0; - sfree(p->c_sval); - p->c_sval = (char *)NULL; - p->c_fval = 0.0; -#else - if (p->c_sval != NULL) { - Free(p->c_sval); - p->c_sval = NULL; - } - p->c_type = 0; - Free(p); - p = NULL; -#endif - } -} diff --git a/commands/awk.old/r.c b/commands/awk.old/r.c deleted file mode 100644 index e9630252f..000000000 --- a/commands/awk.old/r.c +++ /dev/null @@ -1,627 +0,0 @@ -/* - * a small awk clone - * - * (C) 1989 Saeko Hirabauashi & Kouichi Hirabayashi - * - * Absolutely no warranty. Use this software with your own risk. - * - * Permission to use, copy, modify and distribute this software for any - * purpose and without fee is hereby granted, provided that the above - * copyright and disclaimer notice. - * - * This program was written to fit into 64K+64K memory of the Minix 1.2. - */ - - -#include -#include -#include -#include -#include -#ifdef DOS -#include -#endif -#include "awk.h" -#include "regexp.h" - -#define MAXFLD 100 - -extern char **FS, **RS, **OFS, **ORS, **FILENAME; -extern double *NF, *NR; -extern double *FNR; -extern double *ARGC; -extern SYMBOL *argtab[]; -extern CELL *getvar(); - -char *strsave(), *strcpy(), *getsval(), *jStrchr(), *strchr(); -double getfval(), atof(); -CELL *mkcell(), *mktmp(), *execute(), *patexec(); -FILE *efopen(); - -extern CELL truecell, falsecell; - -extern int pateval; - -int infileno = 1; -FILE *ifp; -char record[BUFSIZ]; -CELL *field[MAXFLD]; - -char *fs_str; -regexp *fs_pat; - -CELL * -Getline(p) NODE *p; -{ - CELL *u; - char *fnam, *s, str[BUFSIZ]; - int i; - FILE *fp, *getfp(); - - if ((int) p->n_arg[0]) /* read into var */ - s = str; - else - s = NULL; - if ((int) p->n_arg[1]) { /* file name */ - u = execute(p->n_arg[1]); - fnam = getsval(u); - fp = getfp(fnam, (int) p->n_arg[2]); - c_free(u); - i = get1rec(s, fp); - } - else - i = Getrec(s); - if (s == str) { - u = execute(p->n_arg[0]); - setsval(u, str); - } - return mktmp(NUM, NULL, (double) i); -} - -static -get1rec(buf, fp) char *buf; FILE *fp; -{ - register int c; - register char rs, *s; - int mflg; - - if (buf == NULL) - buf = record; - if ((rs = **RS) == '\0') { /* multi line record */ - mflg = 1; - rs = '\n'; - } - else - mflg = 0; - - if (feof(fp) || (c = getc(fp)) == EOF) - return 0; - for (s = buf; ; ) { - for ( ; c != rs && c != EOF; c = getc(fp)) { - if (isKanji(c)) { - *s++ = c; c = getc(fp); - } - *s++ = c; - } - if (mflg) { - if ((c = getc(fp)) == '\n' || c == EOF) - break; - *s++ = '\n'; - } - else - break; - } - *s = '\0'; -#if 1 - if (buf == record) { -#else - if (buf == record && c != EOF) { -#endif - mkfld(record, *FS, field); - (*NR)++; - (*FNR)++; - } - return s > buf || c != EOF ? 1 : 0; -} - -Getrec(s) char *s; -{ - CELL *u; - char *file, str[8]; - - while (ifp == stdin || infileno < (int)*ARGC) { - if (ifp == NULL) { - *FNR = 0.0; - if (infileno == (int)*ARGC) - break; - sprintf(str, "%d", infileno); - u = getvar(str, argtab); - file = getsval(u); - if (strchr(file, '=') != NULL) { - setvar(file); - infileno++; - continue; - } - else if (strcmp(file, "") == 0) { -/* -if (infileno == (int)*ARGC - 1) - ifp = stdin; -*/ - infileno++; - continue; - } - else { - if (strcmp(file, "-") == 0) - ifp = stdin; - else - ifp = efopen(file, "r"); - *FILENAME = file; - } - } - if (get1rec(s, ifp)) - return 1; - else { - if (ifp != stdin) - fclose(ifp); - ifp = NULL; - infileno++; - } - } - ifp = stdin; /* for further "getline" */ - *FILENAME = "-"; - return 0; /* EOF */ -} - -mkfld(rec, sep, fld) char *rec, *sep; CELL *fld[]; -{ - char *s, *t; - char str[BUFSIZ]; - int i, j, n; - int skip = 0; - - if (strlen(sep) > 1) - return r_mkfld(rec, sep, fld); - - if (*sep == ' ' || *sep == '\0') { - sep = " \t\n"; skip++; - } - for (i = 1, n = (int) *NF; i <= n; i++) { - sfree(fld[i]->c_sval); - sfree(fld[i]); - fld[i] = NULL; - } - for (i = 0, s = rec; ; ) { - t = str; - if (skip) { - while (*s && strchr(" \t\n", *s)) - s++; - if (*s == '\0') - break; - } - while (*s && !jStrchr(sep, *s)) { - if (isKanji(*s)) - *t++ = *s++; - *t++ = *s++; - } - *t = '\0'; - if (isnum(str)) - fld[++i] = mkcell(FLD|STR|NUM, str, atof(str)); - else - fld[++i] = mkcell(FLD|STR, str, 0.0); - if (*s) - s++; - else - break; - } - *NF = (double) i; - return i; -} - -static -r_mkfld(rec, sep, fld) char *rec, *sep; CELL *fld[]; -{ - char *s, *t; - char str[BUFSIZ]; - int i, n; - regexp *mkpat(); - extern int r_start, r_length; - - if (strcmp(*FS, fs_str) != 0) { - sfree(fs_str); sfree(fs_pat); - fs_str = strsave(*FS); - fs_pat = mkpat(fs_str); - } - for (i = 1, n = (int) *NF; i <= n; i++) { - sfree(fld[i]->c_sval); - sfree(fld[i]); - fld[i] = NULL; - } - for (i = 0, s = rec, t = str; *s; ) { - if (match(fs_pat, s)) { - for (n = r_start; --n > 0; ) - *t++ = *s++; - } - else { - while (*s) - *t++ = *s++; - } - *t = '\0'; - t = str; - fld[++i] = mkcell(FLD|STR, str, 0.0); - if (*s) - s += r_length; - } - *NF = (double) i; - return i; -} - -mkrec(u) CELL *u; -{ - register char *s, *t; - register int i, j; - - for (j = (int)*NF, i = 1; i <= j; i++) - if (field[i] == u) - break; - if (i > j) { - for ( ; i < MAXFLD; i++) - if (field[i] == u) - break; - if (i == MAXFLD) - error("too many field (%d)", i); - *NF = (double)i; - } - for (t = record, i = 1, j = (int) *NF; i <= j; i++) { - if (i > 1) - *t++ = **OFS; - for (s = getsval(field[i]); *s; ) - *t++ = *s++; - } - *t++ = '\0'; -} - -CELL * -Field(p) NODE *p; -{ - CELL *u; - int i, j; - - u = execute(p->n_arg[0]); - i = (int) getfval(u); - c_free(u); - j = (int)*NF; - if (i > j) - for (++j; j <= i; j++) { - if (field[j] == NULL) - field[j] = mkcell(FLD|STR, "", 0.0); - } - return field[i]; -} - -CELL * -P1stat(p) NODE *p; -{ - CELL *u; - double x; - - pateval++; - u = execute(p->n_arg[0]); - pateval = 0; - x = getfval(u); - c_free(u); - if (x != 0.0) - u = execute(p->n_arg[1]); - else - u = &truecell; - return u; -} - -CELL * -P2stat(p) NODE *p; -{ - static stat = 0; - CELL *u, *v; - double x; - - switch (stat) { - case 0: - pateval++; - u = execute(p->n_arg[0]); - pateval = 0; - x = getfval(u); - c_free(u); - if (x == 0.0) { - u = &truecell; break; - } - else - stat++; - /* fall through */ - case 1: - u = execute(p->n_arg[2]); - c_free(u); - pateval++; - u = execute(p->n_arg[1]); - pateval = 0; - x = getfval(u); - if (x != 0.0) - stat = 0; - break; - default: - u = &truecell; - break; - } - return u; -} - -CELL * -Print0() -{ -/* - int i, j; - char *s, str[BUFSIZ]; - - for (*str = '\0', i = 1, j = (int) *NF; i <= j; i++) { - if (i > 1) - strcat(str, *OFS); - s = getsval(field[i]); - strcat(str, s); - } - strcat(str, *ORS); - fputs(str, stdout); -*/ - fprintf(stdout, "%s%s", record, *ORS); - return &truecell; -} - -char * -format(t, p) char *t; NODE *p; -{ - CELL *u, *v; - char *r, *s, *s0, fmt[BUFSIZ]; - double x; - int i; - - u = execute(p->n_arg[2]); - s = s0 = getsval(u); -/* -printf("fmt(%s)\n", s); -*/ - for (i = 3; *s; s++) { - if (isKanji(*s)) { - *t++ = *s++; *t++ = *s; continue; - } - if (*s != '%') { - *t++ = *s; continue; - } - else if (*(s + 1) == '%') { - *t++ = *s++; continue; - } - for (r = fmt, *r++ = *s++; *r++ = *s; s++) { - if (strchr("%cdefgosux", *s)) - break; - } - *r = '\0'; - if (p->n_arg[i] == NULL) - error("not enough args in printf(%s)", s0); - v = execute(p->n_arg[i++]); - if (*s == 's') - r = getsval(v); - else - x = getfval(v); -/* -printf("val(%d)(%s)\n", v->c_type, v->c_sval); -*/ - switch (*s) { - case 'c': - sprintf(t, fmt, (int) x); - break; - case 'd': - if (*(s - 1) != 'l') { - *--r = 'l'; *++r = 'd'; *++r = '\0'; - } - sprintf(t, fmt, (long) x); - break; - case 'e': case 'f': case 'g': - sprintf(t, fmt, x); - break; - case 'o': case 'u': case 'x': - if (*(s - 1) == 'l') - sprintf(t, fmt, (long) x); - else - sprintf(t, fmt, (int) x); - break; - case 's': - /*r = getsval(v);*/ - sprintf(t, fmt, r); - break; - default: - strcpy(t, fmt); - break; - } - c_free(v); - t += strlen(t); - } - c_free(u); - *t = '\0'; -} - -#define MAXFILE 10 -struct { - char *f_name; /* file name */ - FILE *f_fp; - int f_type; -} filetab[MAXFILE]; - -FILE * -getfp(file, type) char *file; -{ - register int i; - register char *name, *mode; - char *awktmp(); - FILE *fp, *efopen(), *epopen(); - - for (i = 0; i < MAXFILE; i++) - if (filetab[i].f_name && strcmp(filetab[i].f_name, file) == 0) - return filetab[i].f_fp; - for (i = 0; i < MAXFILE; i++) - if (!filetab[i].f_fp) - break; - if (i == MAXFILE) - error("too many files to open"); - name = file; - switch (type) { - case R_OUT: mode = "w"; break; - case R_APD: mode = "a"; break; - case R_POUT: -#ifdef DOS - name = awktmp(i); mode = "w"; /* MS-DOS */ -#else - fp = epopen(file, "w"); - goto g1; -#endif - break; - case R_IN: mode = "r"; break; - case R_PIN: -#ifdef DOS - { - int savefd, fd, result; - - name = awktmp(i); - if ((fd = open(name, - O_WRONLY|O_TEXT|O_CREAT|O_TRUNC,S_IREAD|S_IWRITE)) == -1) - error("can't open %s", name); - savefd = dup(1); dup2(fd, 1); close(fd); - if ((result = - system(file)) == -1) - error("can't exec %s", file); - dup2(savefd, 1); close(savefd); close(fd); - mode = "r"; - } -#else - fp = epopen(file,"r"); - goto g1; -#endif - break; - } - fp = efopen(name, mode); -g1: - filetab[i].f_name = strsave(file); - filetab[i].f_type = type; - filetab[i].f_fp = fp; - return fp; -} - -closeall() -{ - register int i; - - for (i = 0; i < MAXFILE; i++) - close1(i); -} - -CELL * -Close(s) char *s; -{ - register int i; - - for (i = 0; i < MAXFILE; i++) - if (strcmp(s, filetab[i].f_name) == 0) { - close1(i); - break; - } - i = (i == MAXFILE) ? 0 : 1; - return mktmp(NUM, NULL, (double) i); -} - -static -close1(i) -{ - int fd, result, savefd; - char *awktmp(); - - if (filetab[i].f_fp == NULL) - return; - switch (filetab[i].f_type) { - case R_PIN: -#ifdef DOS - fclose(filetab[i].f_fp); - unlink(awktmp(i)); -#else - pclose(filetab[i].f_fp); -#endif - break; - case R_IN: case R_OUT: case R_APD: - fclose(filetab[i].f_fp); - break; - case R_POUT: -#ifdef DOS - fclose(filetab[i].f_fp); - if ((fd = open(awktmp(i), O_RDONLY)) == NULL) - error("can't open %s", awktmp(i)); - savefd = dup(0); - dup2(fd, 0); - close(fd); - if ((result = - system(filetab[i].f_name)) == -1) -/* - spawnl(P_WAIT, "/usr/bin/sh", "sh", "-c", filetab[i].f_name, (char *) 0)) == -1) - fprintf(stderr, "can't spawn /bin/sh\n"); -*/ - error("can't exec %s", filetab[i].f_name); - dup2(savefd, 0); - close(savefd); - unlink(awktmp(i)); -#else - pclose(filetab[i].f_fp); -#endif - break; - } - sfree(filetab[i].f_name); - filetab[i].f_type = 0; - filetab[i].f_name = NULL; - filetab[i].f_fp = NULL; -} - -#ifndef DOS -FILE * -epopen(file, mod) char *file, *mod; -{ - FILE *fp, *popen(); - - if ((fp = popen(file, mod)) == NULL) - error("can't poen %s", file); - return fp; -} -#endif - -static char * -awktmp(i) -{ - static char str[16]; - - sprintf(str, "awk000%02d.tmp", i); - return str; -} - -Index(s, t) char *s, *t; -{ - register char *u, *v; - register int i; - - for (i = 1; *s; s++, i++) { - for (u = s, v = t; *v; u++, v++) { - if (isKanji(*v)) { - if (*u != *v) - break; - u++; v++; - } - if (*u != *v) - break; - } - if (*v == '\0') - return i; - if (isKanji(*s)) - s++; - } - return 0; -} diff --git a/commands/awk.old/regexp.c b/commands/awk.old/regexp.c deleted file mode 100644 index 353960bdf..000000000 --- a/commands/awk.old/regexp.c +++ /dev/null @@ -1,1440 +0,0 @@ -/* - * regcomp and regexec -- regsub and regerror are elsewhere - * - * Copyright (c) 1986 by University of Toronto. - * Written by Henry Spencer. Not derived from licensed software. - * - * Permission is granted to anyone to use this software for any - * purpose on any computer system, and to redistribute it freely, - * subject to the following restrictions: - * - * 1. The author is not responsible for the consequences of use of - * this software, no matter how awful, even if they arise - * from defects in it. - * - * 2. The origin of this software must not be misrepresented, either - * by explicit claim or by omission. - * - * 3. Altered versions must be plainly marked as such, and must not - * be misrepresented as being the original software. - * - * Beware that some of this code is subtly aware of the way operator - * precedence is structured in regular expressions. Serious changes in - * regular-expression syntax might require a total rethink. - * - * Modified by K.Hirabayashi to accept KANJI code, memory allocation - * and to add following functions. - * isthere(), mkpat(), match(), regsub(), sjtok(), ktosj(), - * Strchr(), Strncmp(), Strlen() - */ - -#include -#include -#include "regexp.h" - -#define regerror(a) error("regular expression error: %s", a) - -int r_start, r_length; - -/* - * The first byte of the regexp internal "program" is actually this magic - * number; the start node begins in the second byte. - */ -#define MAGIC 0234 - -/* - * The "internal use only" fields in regexp.h are present to pass info from - * compile to execute that permits the execute phase to run lots faster on - * simple cases. They are: - * - * regstart char that must begin a match; '\0' if none obvious - * reganch is the match anchored (at beginning-of-line only)? - * regmust string (pointer into program) that match must include, or NULL - * regmlen length of regmust string - * - * Regstart and reganch permit very fast decisions on suitable starting points - * for a match, cutting down the work a lot. Regmust permits fast rejection - * of lines that cannot possibly match. The regmust tests are costly enough - * that regcomp() supplies a regmust only if the r.e. contains something - * potentially expensive (at present, the only such thing detected is * or + - * at the start of the r.e., which can involve a lot of backup). Regmlen is - * supplied because the test in regexec() needs it and regcomp() is computing - * it anyway. - */ - -/* - * Structure for regexp "program". This is essentially a linear encoding - * of a nondeterministic finite-state machine (aka syntax charts or - * "railroad normal form" in parsing technology). Each node is an opcode - * plus a "next" pointer, possibly plus an operand. "Next" pointers of - * all nodes except BRANCH implement concatenation; a "next" pointer with - * a BRANCH on both ends of it is connecting two alternatives. (Here we - * have one of the subtle syntax dependencies: an individual BRANCH (as - * opposed to a collection of them) is never concatenated with anything - * because of operator precedence.) The operand of some types of node is - * a literal string; for others, it is a node leading into a sub-FSM. In - * particular, the operand of a BRANCH node is the first node of the branch. - * (NB this is *not* a tree structure: the tail of the branch connects - * to the thing following the set of BRANCHes.) The opcodes are: - */ - -/* definition number opnd? meaning */ -#define END 0 /* no End of program. */ -#define BOL 1 /* no Match "" at beginning of line. */ -#define EOL 2 /* no Match "" at end of line. */ -#define ANY 3 /* no Match any one character. */ -#define ANYOF 4 /* str Match any character in this string. */ -#define ANYBUT 5 /* str Match any character not in this string. */ -#define BRANCH 6 /* node Match this alternative, or the next... */ -#define BACK 7 /* no Match "", "next" ptr points backward. */ -#define EXACTLY 8 /* str Match this string. */ -#define NOTHING 9 /* no Match empty string. */ -#define STAR 10 /* node Match this (simple) thing 0 or more times. */ -#define PLUS 11 /* node Match this (simple) thing 1 or more times. */ -#define OPEN 20 /* no Mark this point in input as start of #n. */ - /* OPEN+1 is number 1, etc. */ -#define CLOSE 30 /* no Analogous to OPEN. */ - -/* - * Opcode notes: - * - * BRANCH The set of branches constituting a single choice are hooked - * together with their "next" pointers, since precedence prevents - * anything being concatenated to any individual branch. The - * "next" pointer of the last BRANCH in a choice points to the - * thing following the whole choice. This is also where the - * final "next" pointer of each individual branch points; each - * branch starts with the operand node of a BRANCH node. - * - * BACK Normal "next" pointers all implicitly point forward; BACK - * exists to make loop structures possible. - * - * STAR,PLUS '?', and complex '*' and '+', are implemented as circular - * BRANCH structures using BACK. Simple cases (one character - * per match) are implemented with STAR and PLUS for speed - * and to minimize recursive plunges. - * - * OPEN,CLOSE ...are numbered at compile time. - */ - -/* - * A node is one char of opcode followed by two chars of "next" pointer. - * "Next" pointers are stored as two 8-bit pieces, high order first. The - * value is a positive offset from the opcode of the node containing it. - * An operand, if any, simply follows the node. (Note that much of the - * code generation knows about this implicit relationship.) - * - * Using two bytes for the "next" pointer is vast overkill for most things, - * but allows patterns to get big without disasters. - */ -#define OP(p) (*(p)) -#define NEXT(p) (((*((p)+1)&0377)<<8) + *((p)+2)&0377) -#define OPERAND(p) ((p) + 3) - - - -/* - * Utility definitions. - */ -#ifndef CHARBITS -#define UCHARAT(p) ((int)*(ushort *)(p)) -#else -#define UCHARAT(p) ((int)*(p)&CHARBITS) -#endif - -#define FAIL(m) { regerror(m); return(NULL); } -#define ISMULT(c) ((c) == '*' || (c) == '+' || (c) == '?') -#define META "^$.[()|?+*\\" - -/* - * Flags to be passed up and down. - */ -#define HASWIDTH 01 /* Known never to match null string. */ -#define SIMPLE 02 /* Simple enough to be STAR/PLUS operand. */ -#define SPSTART 04 /* Starts with * or +. */ -#define WORST 0 /* Worst case. */ - -/* - * Global work variables for regcomp(). - */ -static ushort *regparse; /* Input-scan pointer. */ -static int regnpar; /* () count. */ -static ushort regdummy; -static ushort *regcode; /* Code-emit pointer; ®dummy = don't. */ -static long regsize; /* Code size. */ - -/* - * Forward declarations for regcomp()'s friends. - */ -#ifndef STATIC -#define STATIC static -#endif -STATIC ushort *reg(); -STATIC ushort *regbranch(); -STATIC ushort *regpiece(); -STATIC ushort *regatom(); -STATIC ushort *regnode(); -STATIC ushort *regnext(); -STATIC void regc(); -STATIC void reginsert(); -STATIC void regtail(); -STATIC void regoptail(); -STATIC int Strcspn(); - -/* - - regcomp - compile a regular expression into internal code - * - * We can't allocate space until we know how big the compiled form will be, - * but we can't compile it (and thus know how big it is) until we've got a - * place to put the code. So we cheat: we compile it twice, once with code - * generation turned off and size counting turned on, and once "for real". - * This also means that we don't allocate space until we are sure that the - * thing really will compile successfully, and we never have to move the - * code and thus invalidate pointers into it. (Note that it has to be in - * one piece because free() must be able to free it all.) - * - * Beware that the optimization-preparation code in here knows about some - * of the structure of the compiled regexp. - */ -regexp * -regcomp(exp) -ushort *exp; -{ - register regexp *r; - register ushort *scan; - register ushort *longest; - register int len; - int flags; - extern char *emalloc(); - - if (exp == NULL) - FAIL("NULL argument"); - - /* First pass: determine size, legality. */ - regparse = exp; - regnpar = 1; - regsize = 0L; - regcode = ®dummy; - regc((ushort) MAGIC); - if (reg(0, &flags) == NULL) - return(NULL); - - /* Small enough for pointer-storage convention? */ - if (regsize >= 32767L) /* Probably could be 65535L. */ - FAIL("regexp too big"); - - /* Allocate space. */ - r = (regexp *)emalloc(sizeof(regexp) + (unsigned)regsize * sizeof(ushort)); - - /* Second pass: emit code. */ - regparse = exp; - regnpar = 1; - regcode = r->program; - regc((ushort) MAGIC); - if (reg(0, &flags) == NULL) - return(NULL); - - /* Dig out information for optimizations. */ - r->regstart = '\0'; /* Worst-case defaults. */ - r->reganch = 0; - r->regmust = NULL; - r->regmlen = 0; - scan = r->program+1; /* First BRANCH. */ - if (OP(regnext(scan)) == END) { /* Only one top-level choice. */ - scan = OPERAND(scan); - - /* Starting-point info. */ - if (OP(scan) == EXACTLY) - r->regstart = *OPERAND(scan); - else if (OP(scan) == BOL) - r->reganch++; - - /* - * If there's something expensive in the r.e., find the - * longest literal string that must appear and make it the - * regmust. Resolve ties in favor of later strings, since - * the regstart check works with the beginning of the r.e. - * and avoiding duplication strengthens checking. Not a - * strong reason, but sufficient in the absence of others. - */ - if (flags&SPSTART) { - longest = NULL; - len = 0; - for (; scan != NULL; scan = regnext(scan)) - if (OP(scan) == EXACTLY && Strlen(OPERAND(scan)) >= len) { - longest = OPERAND(scan); - len = Strlen(OPERAND(scan)); - } - r->regmust = longest; - r->regmlen = len; - } - } - - return(r); -} - -/* - - reg - regular expression, i.e. main body or parenthesized thing - * - * Caller must absorb opening parenthesis. - * - * Combining parenthesis handling with the base level of regular expression - * is a trifle forced, but the need to tie the tails of the branches to what - * follows makes it hard to avoid. - */ -static ushort * -reg(paren, flagp) -int paren; /* Parenthesized? */ -int *flagp; -{ - register ushort *ret; - register ushort *br; - register ushort *ender; - register int parno; - int flags; - - *flagp = HASWIDTH; /* Tentatively. */ - - /* Make an OPEN node, if parenthesized. */ - if (paren) { - if (regnpar >= NSUBEXP) - FAIL("too many ()"); - parno = regnpar; - regnpar++; - ret = regnode(OPEN+parno); - } else - ret = NULL; - - /* Pick up the branches, linking them together. */ - br = regbranch(&flags); - if (br == NULL) - return(NULL); - if (ret != NULL) - regtail(ret, br); /* OPEN -> first. */ - else - ret = br; - if (!(flags&HASWIDTH)) - *flagp &= ~HASWIDTH; - *flagp |= flags&SPSTART; - while (*regparse == '|') { - regparse++; - br = regbranch(&flags); - if (br == NULL) - return(NULL); - regtail(ret, br); /* BRANCH -> BRANCH. */ - if (!(flags&HASWIDTH)) - *flagp &= ~HASWIDTH; - *flagp |= flags&SPSTART; - } - - /* Make a closing node, and hook it on the end. */ - ender = regnode((paren) ? CLOSE+parno : END); - regtail(ret, ender); - - /* Hook the tails of the branches to the closing node. */ - for (br = ret; br != NULL; br = regnext(br)) - regoptail(br, ender); - - /* Check for proper termination. */ - if (paren && *regparse++ != ')') { - FAIL("unmatched ()"); - } else if (!paren && *regparse != '\0') { - if (*regparse == ')') { - FAIL("unmatched ()"); - } else - FAIL("junk on end"); /* "Can't happen". */ - /* NOTREACHED */ - } - - return(ret); -} - -/* - - regbranch - one alternative of an | operator - * - * Implements the concatenation operator. - */ -static ushort * -regbranch(flagp) -int *flagp; -{ - register ushort *ret; - register ushort *chain; - register ushort *latest; - int flags; - - *flagp = WORST; /* Tentatively. */ - - ret = regnode(BRANCH); - chain = NULL; - while (*regparse != '\0' && *regparse != '|' && *regparse != ')') { - latest = regpiece(&flags); - if (latest == NULL) - return(NULL); - *flagp |= flags&HASWIDTH; - if (chain == NULL) /* First piece. */ - *flagp |= flags&SPSTART; - else - regtail(chain, latest); - chain = latest; - } - if (chain == NULL) /* Loop ran zero times. */ - (void) regnode(NOTHING); - - return(ret); -} - -/* - - regpiece - something followed by possible [*+?] - * - * Note that the branching code sequences used for ? and the general cases - * of * and + are somewhat optimized: they use the same NOTHING node as - * both the endmarker for their branch list and the body of the last branch. - * It might seem that this node could be dispensed with entirely, but the - * endmarker role is not redundant. - */ -static ushort * -regpiece(flagp) -int *flagp; -{ - register ushort *ret; - register ushort op; - register ushort *next; - int flags; - - ret = regatom(&flags); - if (ret == NULL) - return(NULL); - - op = *regparse; - if (!ISMULT(op)) { - *flagp = flags; - return(ret); - } - - if (!(flags&HASWIDTH) && op != '?') - FAIL("*+ operand could be empty"); - *flagp = (op != '+') ? (WORST|SPSTART) : (WORST|HASWIDTH); - - if (op == '*' && (flags&SIMPLE)) - reginsert(STAR, ret); - else if (op == '*') { - /* Emit x* as (x&|), where & means "self". */ - reginsert(BRANCH, ret); /* Either x */ - regoptail(ret, regnode(BACK)); /* and loop */ - regoptail(ret, ret); /* back */ - regtail(ret, regnode(BRANCH)); /* or */ - regtail(ret, regnode(NOTHING)); /* null. */ - } else if (op == '+' && (flags&SIMPLE)) - reginsert(PLUS, ret); - else if (op == '+') { - /* Emit x+ as x(&|), where & means "self". */ - next = regnode(BRANCH); /* Either */ - regtail(ret, next); - regtail(regnode(BACK), ret); /* loop back */ - regtail(next, regnode(BRANCH)); /* or */ - regtail(ret, regnode(NOTHING)); /* null. */ - } else if (op == '?') { - /* Emit x? as (x|) */ - reginsert(BRANCH, ret); /* Either x */ - regtail(ret, regnode(BRANCH)); /* or */ - next = regnode(NOTHING); /* null. */ - regtail(ret, next); - regoptail(ret, next); - } - regparse++; - if (ISMULT(*regparse)) - FAIL("nested *?+"); - - return(ret); -} - -/* - - regatom - the lowest level - * - * Optimization: gobbles an entire sequence of ordinary characters so that - * it can turn them into a single node, which is smaller to store and - * faster to run. Backslashed characters are exceptions, each becoming a - * separate node; the code is simpler that way and it's not worth fixing. - */ -static ushort * -regatom(flagp) -int *flagp; -{ - register ushort *ret; - int flags; - ushort c, d; - - *flagp = WORST; /* Tentatively. */ - - switch ((int) *regparse++) { - case '^': - ret = regnode(BOL); - break; - case '$': - ret = regnode(EOL); - break; - case '.': - ret = regnode(ANY); - *flagp |= HASWIDTH|SIMPLE; - break; - case '[': { - register int class; - register int classend; - register int c; - - if (*regparse == '^') { /* Complement of range. */ - ret = regnode(ANYBUT); - regparse++; - } else - ret = regnode(ANYOF); - if (*regparse == ']' || *regparse == '-') - regc(*regparse++); - while (*regparse != '\0' && *regparse != ']') { - if (*regparse == '-') { - regparse++; - if (*regparse == ']' || *regparse == '\0') - regc((ushort) '-'); - else { - class = UCHARAT(regparse-2)+1; - classend = UCHARAT(regparse); - if (class > classend+1) - FAIL("invalid [] range"); - regc((ushort) 0xffff); - regc((ushort) class); - regc((ushort) classend); - regparse++; - } - } else { - if ((c = *regparse++) == '\\') { - if ((c = *regparse++) == 'n') - c = '\n'; - else if (c == 't') - c = '\t'; - } - regc(c); - } - } - regc((ushort) 0); - if (*regparse != ']') - FAIL("unmatched []"); - regparse++; - *flagp |= HASWIDTH|SIMPLE; - } - break; - case '(': - ret = reg(1, &flags); - if (ret == NULL) - return(NULL); - *flagp |= flags&(HASWIDTH|SPSTART); - break; - case '\0': - case '|': - case ')': - FAIL("internal urp"); /* Supposed to be caught earlier. */ - break; - case '?': - case '+': - case '*': - FAIL("?+* follows nothing"); - break; - case '\\': - if (*regparse == '\0') - FAIL("trailing \\"); - ret = regnode(EXACTLY); -/* - regc(*regparse++); -*/ - c = *regparse++; - if (c == 'n') - c = '\n'; - else if (c == 't') - c = '\t'; - else if (c == 'f') - c = '\f'; - else if (c == '\r') - c = '\r'; - else if (c == '\b') - c = '\b'; - else if (IsDigid(c)) { - d = c - '0'; - if (IsDigid(*regparse)) { - d = d * 8 + *regparse++ - '0'; - if (IsDigid(*regparse)) - d = d * 8 + *regparse++ - '0'; - } - c = d; - } - regc(c); - regc((ushort) 0); - *flagp |= HASWIDTH|SIMPLE; - break; - default: { - register int len; - register char ender; - - regparse--; - len = Strcspn(regparse, META); - if (len <= 0) - FAIL("internal disaster"); - ender = *(regparse+len); - if (len > 1 && ISMULT(ender)) - len--; /* Back off clear of ?+* operand. */ - *flagp |= HASWIDTH; - if (len == 1) - *flagp |= SIMPLE; - ret = regnode(EXACTLY); - while (len > 0) { - regc(*regparse++); - len--; - } - regc((ushort) 0); - } - break; - } - - return(ret); -} - -IsDigid(c) ushort c; -{ - return '0' <= c && c <= '9'; -} - -/* - - regnode - emit a node - */ -static ushort * /* Location. */ -regnode(op) -ushort op; -{ - register ushort *ret; - register ushort *ptr; - - ret = regcode; - if (ret == ®dummy) { - regsize += 3; - return(ret); - } - - ptr = ret; - *ptr++ = op; - *ptr++ = '\0'; /* Null "next" pointer. */ - *ptr++ = '\0'; - regcode = ptr; - - return(ret); -} - -/* - - regc - emit (if appropriate) a byte of code - */ -static void -regc(b) -ushort b; -{ - if (regcode != ®dummy) - *regcode++ = b; - else - regsize++; -} - -/* - - reginsert - insert an operator in front of already-emitted operand - * - * Means relocating the operand. - */ -static void -reginsert(op, opnd) -ushort op; -ushort *opnd; -{ - register ushort *src; - register ushort *dst; - register ushort *place; - - if (regcode == ®dummy) { - regsize += 3; - return; - } - - src = regcode; - regcode += 3; - dst = regcode; - while (src > opnd) - *--dst = *--src; - - place = opnd; /* Op node, where operand used to be. */ - *place++ = op; - *place++ = '\0'; - *place++ = '\0'; -} - -/* - - regtail - set the next-pointer at the end of a node chain - */ -static void -regtail(p, val) -ushort *p; -ushort *val; -{ - register ushort *scan; - register ushort *temp; - register int offset; - - if (p == ®dummy) - return; - - /* Find last node. */ - scan = p; - for (;;) { - temp = regnext(scan); - if (temp == NULL) - break; - scan = temp; - } - - if (OP(scan) == BACK) - offset = scan - val; - else - offset = val - scan; - *(scan+1) = (offset>>8)&0377; - *(scan+2) = offset&0377; -} - -/* - - regoptail - regtail on operand of first argument; nop if operandless - */ -static void -regoptail(p, val) -ushort *p; -ushort *val; -{ - /* "Operandless" and "op != BRANCH" are synonymous in practice. */ - if (p == NULL || p == ®dummy || OP(p) != BRANCH) - return; - regtail(OPERAND(p), val); -} - -/* - * regexec and friends - */ - -/* - * Global work variables for regexec(). - */ -static ushort *reginput; /* String-input pointer. */ -static ushort *regbol; /* Beginning of input, for ^ check. */ -static ushort **regstartp; /* Pointer to startp array. */ -static ushort **regendp; /* Ditto for endp. */ - -/* - * Forwards. - */ -STATIC int regtry(); -STATIC int regmatch(); -STATIC int regrepeat(); - -#ifdef DEBUG -int regnarrate = 0; -void regdump(); -STATIC char *regprop(); -#endif - -/* - - regexec - match a regexp against a string - */ -int -regexec(prog, string, bolflag) -register regexp *prog; -register ushort *string; -int bolflag; -{ - register ushort *s; - extern ushort *Strchr(); - - /* Be paranoid... */ - if (prog == NULL || string == NULL) { - regerror("NULL parameter"); - return(0); - } - - /* Check validity of program. */ - if (prog->program[0] != MAGIC) { - regerror("corrupted program"); - return(0); - } - - /* If there is a "must appear" string, look for it. */ - if (prog->regmust != NULL) { - s = string; - while ((s = Strchr(s, prog->regmust[0])) != NULL) { - if (Strncmp(s, prog->regmust, prog->regmlen) == 0) - break; /* Found it. */ - s++; - } - if (s == NULL) /* Not present. */ - return(0); - } - - /* Mark beginning of line for ^ . */ - if(bolflag) - regbol = string; - else - regbol = NULL; - - /* Simplest case: anchored match need be tried only once. */ - if (prog->reganch) - return(regtry(prog, string)); - - /* Messy cases: unanchored match. */ - s = string; - if (prog->regstart != '\0') { - /* We know what char it must start with. */ - while ((s = Strchr(s, prog->regstart)) != NULL) { - if (regtry(prog, s)) - return(1); - s++; - } -} - else - /* We don't -- general case. */ - do { - if (regtry(prog, s)) - return(1); - } while (*s++ != '\0'); - - /* Failure. */ - return(0); -} - -/* - - regtry - try match at specific point - */ -static int /* 0 failure, 1 success */ -regtry(prog, string) -regexp *prog; -ushort *string; -{ - register int i; - register ushort **sp; - register ushort **ep; - - reginput = string; - regstartp = prog->startp; - regendp = prog->endp; - - sp = prog->startp; - ep = prog->endp; - for (i = NSUBEXP; i > 0; i--) { - *sp++ = NULL; - *ep++ = NULL; - } - if (regmatch(prog->program + 1)) { - prog->startp[0] = string; - prog->endp[0] = reginput; - return(1); - } else - return(0); -} - -/* - - regmatch - main matching routine - * - * Conceptually the strategy is simple: check to see whether the current - * node matches, call self recursively to see whether the rest matches, - * and then act accordingly. In practice we make some effort to avoid - * recursion, in particular by going through "ordinary" nodes (that don't - * need to know whether the rest of the match failed) by a loop instead of - * by recursion. - */ -static int /* 0 failure, 1 success */ -regmatch(prog) -ushort *prog; -{ - register ushort *scan; /* Current node. */ - ushort *next; /* Next node. */ - extern ushort *Strchr(); - - scan = prog; -#ifdef DEBUG - if (scan != NULL && regnarrate) - fprintf(stderr, "%s(\n", regprop(scan)); -#endif - while (scan != NULL) { -#ifdef DEBUG - if (regnarrate) - fprintf(stderr, "%s...\n", regprop(scan)); -#endif - next = regnext(scan); - - switch ((int) OP(scan)) { - case BOL: - if (reginput != regbol) - return(0); - break; - case EOL: - if (*reginput != '\0') - return(0); - break; - case ANY: - if (*reginput == '\0') - return(0); - reginput++; - break; - case EXACTLY: { - register int len; - register ushort *opnd; - - opnd = OPERAND(scan); - /* Inline the first character, for speed. */ - if (*opnd != *reginput) - return(0); - len = Strlen(opnd); - if (len > 1 && Strncmp(opnd, reginput, len) != 0) - return(0); - reginput += len; - } - break; - case ANYOF: - if (*reginput == '\0' || isthere(OPERAND(scan), *reginput) == 0) - return(0); - reginput++; - break; - case ANYBUT: - if (*reginput == '\0' || isthere(OPERAND(scan), *reginput) != 0) - return(0); - reginput++; - break; - case NOTHING: - break; - case BACK: - break; - case OPEN+1: - case OPEN+2: - case OPEN+3: - case OPEN+4: - case OPEN+5: - case OPEN+6: - case OPEN+7: - case OPEN+8: - case OPEN+9: { - register int no; - register ushort *save; - - no = OP(scan) - OPEN; - save = reginput; - - if (regmatch(next)) { - /* - * Don't set startp if some later - * invocation of the same parentheses - * already has. - */ - if (regstartp[no] == NULL) - regstartp[no] = save; - return(1); - } else - return(0); - } - break; - case CLOSE+1: - case CLOSE+2: - case CLOSE+3: - case CLOSE+4: - case CLOSE+5: - case CLOSE+6: - case CLOSE+7: - case CLOSE+8: - case CLOSE+9: { - register int no; - register ushort *save; - - no = OP(scan) - CLOSE; - save = reginput; - - if (regmatch(next)) { - /* - * Don't set endp if some later - * invocation of the same parentheses - * already has. - */ - if (regendp[no] == NULL) - regendp[no] = save; - return(1); - } else - return(0); - } - break; - case BRANCH: { - register ushort *save; - - if (OP(next) != BRANCH) /* No choice. */ - next = OPERAND(scan); /* Avoid recursion. */ - else { - do { - save = reginput; - if (regmatch(OPERAND(scan))) - return(1); - reginput = save; - scan = regnext(scan); - } while (scan != NULL && OP(scan) == BRANCH); - return(0); - /* NOTREACHED */ - } - } - break; - case STAR: - case PLUS: { - register ushort nextch; - register int no; - register ushort *save; - register int min; - - /* - * Lookahead to avoid useless match attempts - * when we know what character comes next. - */ - nextch = '\0'; - if (OP(next) == EXACTLY) - nextch = *OPERAND(next); - min = (OP(scan) == STAR) ? 0 : 1; - save = reginput; - no = regrepeat(OPERAND(scan)); - while (no >= min) { - /* If it could work, try it. */ - if (nextch == '\0' || *reginput == nextch) - if (regmatch(next)) - return(1); - /* Couldn't or didn't -- back up. */ - no--; - reginput = save + no; - } - return(0); - } - break; - case END: - return(1); /* Success! */ - break; - default: - regerror("memory corruption"); - return(0); - break; - } - - scan = next; - } - - /* - * We get here only if there's trouble -- normally "case END" is - * the terminating point. - */ - regerror("corrupted pointers"); - return(0); -} - -/* - - regrepeat - repeatedly match something simple, report how many - */ -static int -regrepeat(p) -ushort *p; -{ - register int count = 0; - register ushort *scan; - register ushort *opnd; - - scan = reginput; - opnd = OPERAND(p); - switch (OP(p)) { - case ANY: - count = Strlen(scan); - scan += count; - break; - case EXACTLY: - while (*opnd == *scan) { - count++; - scan++; - } - break; - case ANYOF: - while (*scan != '\0' && isthere(opnd, *scan) != 0) { - count++; - scan++; - } - break; - case ANYBUT: - while (*scan != '\0' && isthere(opnd, *scan) == 0) { - count++; - scan++; - } - break; - default: /* Oh dear. Called inappropriately. */ - regerror("internal foulup"); - count = 0; /* Best compromise. */ - break; - } - reginput = scan; - - return(count); -} - -/* - - regnext - dig the "next" pointer out of a node - */ -static ushort * -regnext(p) -register ushort *p; -{ - register int offset; - - if (p == ®dummy) - return(NULL); - - offset = NEXT(p); - if (offset == 0) - return(NULL); - - if (OP(p) == BACK) - return(p-offset); - else - return(p+offset); -} - -#ifdef DEBUG - -STATIC char *regprop(); - -/* - - regdump - dump a regexp onto stdout in vaguely comprehensible form - */ -void -regdump(r) -regexp *r; -{ - register ushort *s; - register ushort op = EXACTLY; /* Arbitrary non-END op. */ - register ushort *next; - - - s = r->program + 1; - while (op != END) { /* While that wasn't END last time... */ - op = OP(s); - printf("%2d%s", s-r->program, regprop(s)); /* Where, what. */ - next = regnext(s); - if (next == NULL) /* Next ptr. */ - printf("(0)"); - else - printf("(%d)", (s-r->program)+(next-s)); - s += 3; - if (op == ANYOF || op == ANYBUT || op == EXACTLY) { - /* Literal string, where present. */ - while (*s != '\0') { - if (*s == 0xffff) { /* range */ - kputchar(*++s); putchar('-'); ++s; - } - kputchar(*s++); - } - s++; - } - putchar('\n'); - } - - /* Header fields of interest. */ - if (r->regstart != '\0') { - fputs("start `", stdout); kputchar(r->regstart); fputs("' ", stdout); - } - if (r->reganch) - printf("anchored "); - if (r->regmust != NULL) { - fputs("must have \"", stdout); kputs(r->regmust); putchar('"'); - } - printf("\n"); -} - -kputchar(c) ushort c; -{ - if (c & 0xff00) - putchar(c >> 8); - putchar(c & 0xff); -} - -kputs(s) ushort *s; -{ - while (*s) - kputchar(*s++); -} - -/* - - regprop - printable representation of opcode - */ -static char * -regprop(op) -ushort *op; -{ - register char *p; - static char buf[50]; - - (void) strcpy(buf, ":"); - - switch ((int) OP(op)) { - case BOL: - p = "BOL"; - break; - case EOL: - p = "EOL"; - break; - case ANY: - p = "ANY"; - break; - case ANYOF: - p = "ANYOF"; - break; - case ANYBUT: - p = "ANYBUT"; - break; - case BRANCH: - p = "BRANCH"; - break; - case EXACTLY: - p = "EXACTLY"; - break; - case NOTHING: - p = "NOTHING"; - break; - case BACK: - p = "BACK"; - break; - case END: - p = "END"; - break; - case OPEN+1: - case OPEN+2: - case OPEN+3: - case OPEN+4: - case OPEN+5: - case OPEN+6: - case OPEN+7: - case OPEN+8: - case OPEN+9: - sprintf(buf+strlen(buf), "OPEN%d", OP(op)-OPEN); - p = NULL; - break; - case CLOSE+1: - case CLOSE+2: - case CLOSE+3: - case CLOSE+4: - case CLOSE+5: - case CLOSE+6: - case CLOSE+7: - case CLOSE+8: - case CLOSE+9: - sprintf(buf+strlen(buf), "CLOSE%d", OP(op)-CLOSE); - p = NULL; - break; - case STAR: - p = "STAR"; - break; - case PLUS: - p = "PLUS"; - break; - default: - regerror("corrupted opcode"); - break; - } - if (p != NULL) - (void) strcat(buf, p); - return(buf); -} -#endif - -/* - * The following is provided for those people who do not have strcspn() in - * their C libraries. They should get off their butts and do something - * about it; at least one public-domain implementation of those (highly - * useful) string routines has been published on Usenet. - */ -/* - * strcspn - find length of initial segment of s1 consisting entirely - * of characters not from s2 - */ - -static int -Strcspn(s1, s2) -ushort *s1; -unsigned char *s2; -{ - register ushort *scan1; - register unsigned char *scan2; - register int count; - - count = 0; - for (scan1 = s1; *scan1 != '\0'; scan1++) { - for (scan2 = s2; *scan2 != '\0';) /* ++ moved down. */ - if (*scan1 == *scan2++) - return(count); - count++; - } - return(count); -} - -isthere(s, c) ushort *s, c; -{ - register unsigned int c1, c2; - - for ( ; *s; s++) { - if (*s == 0xffff) { /* range */ - c1 = *++s; c2 = *++s; - if (c1 <= c && c <= c2) - return 1; - } - else if (*s == c) - return 1; - } - return 0; -} - -ushort * -Strchr(s, c) ushort *s, c; -{ - for ( ; *s; s++) - if (*s == c) - return s; - return NULL; -} - -Strncmp(s, t, n) ushort *s, *t; -{ - for ( ; --n > 0 && *s == *t; s++, t++) - ; - return *s - *t; -} - -Strlen(s) ushort *s; -{ - int i; - - for (i = 0; *s; i++, s++) - ; - return i; -} - -ushort kbuf[BUFSIZ]; - -char * -mkpat(s) char *s; -{ - sjtok(kbuf, s); - return (char *) regcomp(kbuf); -} - -match(p, s) regexp *p; char *s; -{ - register int i; - - sjtok(kbuf, s); - if (i = regexec(p, kbuf, 1)) { - r_start = p->startp[0] - kbuf + 1; - r_length = p->endp[0] - p->startp[0]; - } - else - r_start = r_length = 0; - return i; -} - -sjtok(s, t) ushort *s; unsigned char *t; -{ - register c; - - for ( ; *t; t++) { - if (isKanji(c = *t)) - c = (c << 8) | (*++t & 0xff); - *s++ = c; - } - *s = 0; -} - -ktosj(s, t) unsigned char *s; ushort *t; -{ - register c; - - while (*t) { - if ((c = *t++) & 0xff00) - *s++ = c >> 8; - *s++ = c & 0xff; - } - *s = '\0'; -} - -regsub(dst, exp, src, pat, pos) ushort *dst, *src, *pat; regexp *exp; -{ /* dst <-- s/src/pat/pos global substitution for pos == 0 */ - register int c, i; - register ushort *loc1, *loc2, *s, *t, *u; - register int n = 0; - - if (exp->program[0] != MAGIC) { - regerror("damaged regexp fed to regsub"); - return 0; - } - while (*src) { -next: - if (regexec(exp, src, 1) == 0) - break; - loc1 = exp->startp[0]; loc2 = exp->endp[0]; - if (pos-- > 1) { - while (src < loc2) - *dst++ = *src++; - goto next; - } - while (src < loc1) - *dst++ = *src++; - for (s = pat; c = *s++; ) { - if (c == '&') - i = 0; - else if (c == '\\' && '0' <= *s && *s <= '9') - i = *s++ - '0'; - else { - if (c == '\\' && (*s == '\\' || *s == '&')) - c = *s++; - *dst++ = c; - continue; - } - if ((t = exp->startp[i]) != NULL - && (u = exp->endp[i]) != NULL) { - while (t < u) - *dst++ = *t++; - } - } - src = loc2; - n++; - if (pos == 0) - break; - } - while (*src) - *dst++ = *src++; - *dst++ = 0; - return n; -} - -static ushort kbuf1[BUFSIZ], kbuf2[BUFSIZ]; - -Sub(u, exp, str, s, t, pos) char *exp; char *s, *t, *u; -{ - register int i; - regexp *r; - - if (str) { - sjtok(kbuf, exp); - r = regcomp(kbuf); - } - else - r = (regexp *) exp; - sjtok(kbuf, s); - sjtok(kbuf1, t); - i = regsub(kbuf2, r, kbuf1, kbuf, pos); - ktosj(u, kbuf2); - if (str) - sfree(r); - - return i; -} diff --git a/commands/awk.old/regexp.h b/commands/awk.old/regexp.h deleted file mode 100644 index c5437a85d..000000000 --- a/commands/awk.old/regexp.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Definitions etc. for regexp(3) routines. - * - * Caveat: this is V8 regexp(3) [actually, a reimplementation thereof], - * not the System V one. - */ -#define ushort unsigned short -#define CHARBITS 0xffff -#define NSUBEXP 10 -typedef struct regexp { - ushort *startp[NSUBEXP]; - ushort *endp[NSUBEXP]; - ushort regstart; /* Internal use only. */ - ushort reganch; /* Internal use only. */ - ushort *regmust; /* Internal use only. */ - int regmlen; /* Internal use only. */ - ushort program[1]; /* Unwarranted chumminess with compiler. */ -} regexp; - -extern regexp *regcomp(); -extern int regexec(); -extern int regsub(); -extern int regerror(); diff --git a/commands/awk.old/v.c b/commands/awk.old/v.c deleted file mode 100644 index 072d5a61a..000000000 --- a/commands/awk.old/v.c +++ /dev/null @@ -1,703 +0,0 @@ -/* - * a small awk clone - * - * (C) 1989 Saeko Hirabauashi & Kouichi Hirabayashi - * - * Absolutely no warranty. Use this software with your own risk. - * - * Permission to use, copy, modify and distribute this software for any - * purpose and without fee is hereby granted, provided that the above - * copyright and disclaimer notice. - * - * This program was written to fit into 64K+64K memory of the Minix 1.2. - */ - - -#include -#include -#include "awk.h" -#include "regexp.h" - -#define PI 3.14159265358979323846 - -#define HASHSIZE 50 -#define MAXFIELD 100 - -double atof(); -char *getsval(), *jStrchar(); -extern CELL *execute(), *_Arg(); - -extern char record[]; -extern CELL *field[]; - -extern CELL truecell, falsecell; -extern prmflg; - -SYMBOL *hashtab[HASHSIZE]; -SYMBOL *funtab[HASHSIZE]; -SYMBOL *argtab[HASHSIZE]; -SYMBOL *envtab[HASHSIZE]; - -char *strsave(), *emalloc(), *strchr(); -CELL *lookup(), *install(), *_install(), *mkcell(), *mktmp(), *getvar(); - -char **FS, **RS, **OFS, **ORS, **OFMT, **FILENAME; -char **SUBSEP; -double *NR, *NF; -double *FNR, *ARGC, *RSTART, *RLENGTH; - -init() -{ - FS = &install("FS", VAR|STR, " ", 0.0, hashtab)->c_sval; - RS = &install("RS", VAR|STR, "\n", 0.0, hashtab)->c_sval; - OFS = &install("OFS", VAR|STR , " ", 0.0, hashtab)->c_sval; - ORS = &install("ORS", VAR|STR, "\n", 0.0, hashtab)->c_sval; - OFMT = &install("OFMT", VAR|STR, "%.6g", 0.0, hashtab)->c_sval; - NR = &install("NR", VAR|NUM, (char *)NULL, 0.0, hashtab)->c_fval; - NF = &install("NF", VAR|NUM, (char *)NULL, 0.0, hashtab)->c_fval; - FILENAME = &install("FILENAME", VAR|STR, (char *)NULL, 0.0, hashtab)->c_sval; - install("PI", VAR|NUM, (char *)NULL, PI, hashtab); - field[0] = mkcell(REC|STR, (char *)NULL, 0.0); /* $0 */ - field[0]->c_sval = record; - SUBSEP = &install("SUBSEP", VAR|STR, "\034", 0.0, hashtab)->c_sval; - FNR = &install("FNR", VAR|NUM, (char *)NULL, 0.0, hashtab)->c_fval; - RSTART = &install("RSTART", VAR|NUM, (char *)NULL, 0.0, hashtab)->c_fval; - RLENGTH = &install("RLENGTH", VAR|NUM, (char *)NULL, 0.0, hashtab)->c_fval; -} - -setvar(s) char *s; -{ - CELL *u; - char *t; - - for (t = s; *t && *t != '='; t++) - ; - *t++ = '\0'; - if ((u = lookup(s, hashtab)) == (CELL *)NULL) { - if (isnum(t)) - install(s, VAR|NUM|STR, t, atof(t), hashtab); - else - install(s, VAR|STR, t, 0.0, hashtab); - } - else { - if (isnum(t)) - setfval(u, atof(t)); - else - setsval(u, t); - } -} - -initarg(arg0, argc, argv, envp) char *arg0, **argv, **envp; -{ - CELL *u; - register int i; - register char str[4], *p; - - ARGC = &install("ARGC", VAR|NUM, (char *)NULL, (double)argc+1, hashtab)->c_fval; - u = install("ARGV", ARR, (char *)NULL, 0.0, hashtab); - u->c_sval = (char *) argtab; - install("0", VAR|STR, arg0, 0.0, argtab); - for (i = 0; i < argc; i++) { - sprintf(str, "%d", i+1); - if (isnum(argv[i])) - install(str, VAR|STR|NUM, argv[i], atof(argv[i]), argtab); - else - install(str, VAR|STR, argv[i], 0.0, argtab); - } - - u = install("ENVIRON", ARR, (char *)NULL, 0.0, hashtab); - u->c_sval = (char *) envtab; - for (i = 0; envp[i] && *envp[i]; i++) { - if ((p = strchr(envp[i], '=')) != NULL) { - *p = 0; - if (isnum(p+1)) - install(envp[i], VAR|STR|NUM, p+1, atof(p+1), envtab); - else - install(envp[i], VAR|STR, p+1, 0.0, envtab); - *p = '='; - } - } -} - -static -hash(s) unsigned char *s; -{ - register unsigned int h; - - for (h = 0; *s; ) - h += *s++; - return h % HASHSIZE; -} - -CELL * -lookup(s, h) char *s; SYMBOL *h[]; -{ - register SYMBOL *p; - - for (p = h[hash(s)]; p; p = p->s_next) - if (strcmp(s, p->s_name) == 0) - return p->s_val; - return (CELL *)NULL; -} - -static CELL * -install(name, type, sval, fval, h) char *name, *sval; double fval; SYMBOL *h[]; -{ - CELL *u; - - if ((u = lookup(name, h)) == (CELL *)NULL) - u = _install(name, type, sval, fval, h); - else - error("%s is doubly defined", name); - return u; -} - -static CELL * -_install(name, type, sval, fval, h) char *name, *sval; double fval; SYMBOL *h[];{ - register SYMBOL *p; - CELL *u; - int hval; - - p = (SYMBOL *) emalloc(sizeof(*p)); - u = (CELL *) emalloc(sizeof(*u)); - p->s_name = strsave(name); - p->s_val = u; - hval = hash(name); - p->s_next = h[hval]; - h[hval] = p; - u->c_type = type; - u->c_sval = strsave(sval); -#if 0 - if (!(type & NUM) && isnum(sval)) { - u->c_fval = atof(sval); - u->c_type |= NUM; - } - else -#endif - u->c_fval = fval; - return u; -} - -CELL * -getvar(s, h, typ) char *s; SYMBOL *h[]; -{ - CELL *u; - SYMBOL *p; - char *t; - int i, hval; - - if ((u = lookup(s, h)) == (CELL *)NULL) { - if (prmflg) { - u = _install(s, UDF, "", 0.0, h); - goto rtn; - } - else if (typ & ARR) { - t = emalloc(sizeof(SYMBOL *) * HASHSIZE); - for (i = 0; i < HASHSIZE; i++) - ((SYMBOL **) t)[i] = (SYMBOL *)NULL; - u = (CELL *) emalloc(sizeof(*u)); - u->c_type = typ; - u->c_sval = t; - u->c_fval = 0.0; - p = (SYMBOL *) emalloc(sizeof(*p)); - p->s_name = strsave(s); - p->s_val = u; - hval = hash(s); - p->s_next = h[hval]; - h[hval] = p; - } - else - u = _install(s, typ, "", 0.0, h); - } - else if (!prmflg && (u->c_type == UDF) && (typ != UDF)) { - /* fix up local_var/forward_function */ - if (typ == ARR) { -/* -printf("getvar_correct_to_array\n"); -*/ - u->c_type = typ; - sfree(u->c_sval); - u->c_sval = emalloc(sizeof(SYMBOL *) * HASHSIZE); - for (i = 0; i < HASHSIZE; i++) - ((SYMBOL **) u->c_sval)[i] = (SYMBOL *)NULL; - u->c_fval = 0.0; - } - else if (typ != UDF) { - u->c_type = typ; - } - } -rtn: - return u; -} - -fixarray(u) CELL *u; -{ - int i; - - if (u->c_type == UDF) { /* fix up local var */ -/* -printf("fixarray\n"); -*/ - u->c_type = ARR; - sfree(u->c_sval); - u->c_sval = emalloc(sizeof(SYMBOL *) * HASHSIZE); - for (i = 0; i < HASHSIZE; i++) - ((SYMBOL **) u->c_sval)[i] = (SYMBOL *)NULL; - u->c_fval = 0.0; - } -} - -a_free(u) CELL *u; -{ /* free local array */ - SYMBOL **h, *q, *r; - CELL *v; - int i; - - if (!(u->c_type & ARR)) - error("try to free non array variable", (char *)0); - h = (SYMBOL **) u->c_sval; - for (i = 0; i < HASHSIZE; i++) - for (q = h[i]; q; q = r) { - r = q->s_next; - sfree(q->s_name); - v = q->s_val; /* CELL */ - c_free(v); - sfree(q); /* SYMBOL */ - } - - sfree(u->c_sval); /* symbol table */ - c_free(u); -} - -CELL * -Array(p) NODE *p; -{ - CELL *u; - char str[BUFSIZ]; - int i, n; - - CELL *v; - - u = (CELL *) p->n_arg[0]; - if (u->c_type == POS) { - i = (int)u->c_fval; -/* -printf("**ARG_ARRAY(%d)*\n", i); -*/ - u = _Arg(i); - if (u->c_type == UDF) { /* fix up local array */ -/* -printf("local_var_to_array\n"); -*/ - fixarray(u); - } - } - else if (!(u->c_type & ARR)) - error("non array refference"); - arrayelm(p, str); - u = getvar(str, u->c_sval, VAR|NUM|STR); /* "rtsort in AWK book */ - return u; -} - -static -arrayelm(p, s) NODE *p; char *s; -{ - CELL *u; - int i, n; - char *t; - -/* -char *tt = s; -*/ - n = (int) p->n_arg[1] + 2; - for (i = 2; i < n; i++) { - if (i > 2) - *s++ = **SUBSEP; - u = execute(p->n_arg[i]); - for (t = getsval(u); *t; ) - *s++ = *t++; - c_free(u); - } - *s = '\0'; -/* -printf("array_elm(%s)\n", tt); -*/ -} - -CELL * -Element(p) NODE *p; -{ - char str[BUFSIZ]; - - arrayelm(p, str); - return mktmp(STR, str, 0.0); -} - -CELL * -Delete(p) NODE *p; -{ - CELL *u; - char str[BUFSIZ]; - int i; - SYMBOL *q, *r, **h; - - u = (CELL *) p->n_arg[0]; - if (!(u->c_type & ARR)) - error("can't delete non array variable"); - arrayelm(p, str); - h = (SYMBOL **) u->c_sval; - for (r = (SYMBOL *)NULL, i = hash(str), q = h[i]; q; r = q, q = q->s_next) - if (strcmp(str, q->s_name) == 0) - break; - if (q) { - sfree(q->s_val->c_sval); - sfree(q->s_name); - if (r) - r->s_next = q->s_next; - if (q == h[i]) - h[i] = (SYMBOL *)NULL; - } - return &truecell; -} - -CELL * -In(p) NODE *p; -{ - SYMBOL **h, *q; - CELL *u, *v; - char *s; - int i; - - u = (CELL *) p->n_arg[1]; /* array */ - if (!(u->c_type & ARR)) - error("%s is not an array", u->c_sval); - h = (SYMBOL **) u->c_sval; - if (u->c_sval != (char *)NULL) { - v = execute(p->n_arg[0]); /* var */ - s = getsval(v); - for (i = 0; i < HASHSIZE; i++) - for (q = h[i]; q; q = q->s_next) { - if (strcmp(s, q->s_name) == 0) { - c_free(v); - return &truecell; - } - } - c_free(v); - } - return &falsecell; -} - -CELL * -Split(p) NODE *p; -{ - CELL *u, *v, *w; - char *s, *t, *h, *name, *sep; - int i, n, skip; - char elm[8], str[BUFSIZ]; - static char *s_str; - static regexp *s_pat; - regexp *mkpat(); - extern int r_start, r_length; - - n = (int) p->n_arg[1]; - if (n > 1) { - u = execute(p->n_arg[2]); - s = getsval(u); /* str */ - v = execute(p->n_arg[3]); /* array */ - if (!(v->c_type & ARR)) { -/* -printf("Split fix_to_array(%d)\n", v->c_type); -*/ - if (v->c_type == UDF) /* fix up local array */ - fixarray(v); - else - error("split to non array variable", (char *)0); - } - h = v->c_sval; - c_free(v); - if (n > 2) { - v = execute(p->n_arg[4]); - sep = getsval(v); - } - else { - v = (CELL *)NULL; - sep = *FS; - } - if (strlen(sep) > 1) { /* reg_exp */ - if (strcmp(sep, s_str) != 0) { - sfree(s_str); sfree(s_pat); - s_str = strsave(sep); - s_pat = mkpat(s_str); - } - for (i = 0, t = str; *s; ) { - if (match(s_pat, s)) { - for (n = r_start; --n > 0; ) - *t++ = *s++; - } - else { - while(*s) - *t++ = *s++; - } - *t = '\0'; - t = str; - sprintf(elm, "%d", ++i); - w = getvar(elm, h, VAR); - if (isnum(str)) - setfval(w, atof(str)); - else - setsval(w, str); - if (*s) - s += r_length; - } - } - else { - skip = *sep == ' '; - for (i = 0; t = str, *s; ) { - if (skip) - while (jStrchr(" \t\n", *s)) - s++; - if (!(*s)) - break; - while (*s && !jStrchr(sep, *s)) { - if (isKanji(*s)) - *t++ = *s++; - *t++ = *s++; - } - *t = '\0'; - sprintf(elm, "%d", ++i); - w = getvar(elm, h, VAR); - if (isnum(str)) - setfval(w, atof(str)); - else - setsval(w, str); - if (*s && !skip) - s++; - } - } - c_free(v); /* sep */ - c_free(u); /* str may be CATed */ - } - else - i = 0; - return mktmp(NUM, (char *)NULL, (double) i); -} - -CELL * -Forin(p) NODE *p; -{ - CELL *u, *v; - SYMBOL **h, *q; - char *name; - int i; - - u = execute(p->n_arg[1]); - if (!(u->c_type & ARR)) - synerr( - "non array variable is specified in 'for (. in var)'", (char *)0); - h = (SYMBOL **) u->c_sval; - c_free(u); - u = execute(p->n_arg[0]); - if (u->c_type == UDF) { -/* -printf("Forin_fix_to_VAR|NUM\n"); -*/ - u->c_type = VAR|NUM; - } - if (!(u->c_type & VAR)) - error("'for (VAR in .)' is not variable (%d)", name, u->c_type); - for (i = 0; i < HASHSIZE; i++) { - for (q = h[i]; q; q = q->s_next) { - setsval(u, q->s_name); - v = execute(p->n_arg[2]); - c_free(v); - } - } - c_free(u); - return &truecell; -} - -char * -strsave(s) char *s; -{ - register int n; - char *emalloc(), *strcpy(); - - if (s == (char *)NULL) - return (char *)NULL; - n = strlen(s) + 1; - return strcpy(emalloc(n), s); -} - -sfree(p) char *p; -{ - if (p != (char *)NULL) - Free(p); -} - -isnum(s) char *s; -{ - char *strchr(); - - if (s == NULL || *s == '\0' || !strcmp(s, ".")) - return 0; - if (*s && strchr("+-", *s) != (char *)NULL) - s++; - if (*s == '\0') - return 0; - while (isdigit(*s)) - s++; - if (*s == '.') { - s++; - while (isdigit(*s)) - s++; - } - if (*s && strchr("eE", *s) != (char *)NULL) { - s++; - if (*s == '\0') - return 0; - if (*s && strchr("+-", *s) != (char *)NULL) - s++; - while (isdigit(*s)) - s++; - } - return *s == '\0'; -} - -setfval(u, f) CELL *u; double f; -{ - if (u->c_type == UDF) { /* fix up local var */ -/* -printf("setfval_fix_to_VAR\n"); -*/ - u->c_type |= VAR; - } - if (u->c_type & (VAR|FLD|REC|TMP)) { - u->c_type &= ~STR; - u->c_type |= NUM; - sfree(u->c_sval); - u->c_sval = (char *)NULL; - u->c_fval = f; - if (u->c_type & FLD) - mkrec(u); - } - else - fprintf(stderr, "assign to nonvariable (%d)\n", u->c_type); -} - -setsval(u, s) CELL *u; char *s; -{ - double atof(); - - if (u->c_type == UDF) { /* fix up local var */ -/* -printf("setsval_fix_to_VAR\n"); -*/ - u->c_type |= VAR; - } - if (u->c_type & (VAR|FLD|REC|TMP)) { - u->c_type &= ~NUM; - u->c_type |= STR; - sfree(u->c_sval); - u->c_sval = strsave(s); -#if 0 /* "table2" in AWK book */ - if (isnum(u->c_sval)) { - u->c_fval = atof(u->c_sval); - u->c_type |= NUM; - } - else -#endif - u->c_fval = 0.0; - if (u->c_type & FLD) - mkrec(u); - } - else - fprintf(stderr, "assign to constant (%d)\n", u->c_type); -} - -double -getfval(u) CELL *u; -{ - double x, atof(); - - if (u->c_type == UDF) { /* local var */ - u->c_type |= VAR|STR|NUM; - u->c_sval = strsave(""); - x = u->c_fval = 0.0; - } - else if (u->c_type & NUM) - x = u->c_fval; -#if 1 - else { - x = atof(u->c_sval); -#else - else { - if (isnum(u->c_sval)) - x = atof(u->c_sval); - else - x = 0.0; -#endif - } - return x; -} - -char * -getsval(u) CELL *u; -{ - char *s, str[80]; - - if (u->c_type & STR) - s = u->c_sval; - else if (u->c_type & NUM) { -/* if (u->c_fval >= -2147483648.0 && u->c_fval <= 2147483647.0)*/ - if ((long)u->c_fval == u->c_fval) - s = "%.16g"; - else - s = *OFMT; - sprintf(str, s, u->c_fval); - sfree(u->c_sval); - s = u->c_sval = strsave(str); - } -#if 1 - else if (u->c_type == UDF) { /* local var */ -/* -printf("getsval_fix_to_VAR|STR\n"); -*/ - u->c_type |= VAR|STR|NUM; - s = u->c_sval = strsave(""); - u->c_fval = 0.0; - } -#endif - else - fprintf(stderr, "abnormal value (STR|NUM == 0)(%d)\n", u->c_type); - return s; -} - -char * -emalloc(n) unsigned n; -{ - char *p; -#if 0 - char far *_fmalloc(); -#else - char *malloc(); -#endif - -#if 0 - if ((p = _fmalloc(n)) == (char *)NULL) -#else - if ((p = malloc(n)) == (char *)NULL) -#endif - error("memory over"); - return p; -} - -Free(s) char *s; -{ -#if DOS - void _ffree(); - - _ffree(s); -#else - free(s); -#endif -} diff --git a/commands/awk.old/y.c b/commands/awk.old/y.c deleted file mode 100644 index 6b5d8933d..000000000 --- a/commands/awk.old/y.c +++ /dev/null @@ -1,1086 +0,0 @@ -/* - * a small awk clone - * - * (C) 1989 Saeko Hirabauashi & Kouichi Hirabayashi - * - * Absolutely no warranty. Use this software with your own risk. - * - * Permission to use, copy, modify and distribute this software for any - * purpose and without fee is hereby granted, provided that the above - * copyright and disclaimer notice. - * - * This program was written to fit into 64K+64K memory of the Minix 1.2. - */ - - -#include -#include "awk.h" - -extern char *mkpat(); - -extern char *cmd; -extern char text[]; -extern char funnam[]; -extern int sym; -extern int sym1; -extern int regexflg; -extern int funflg; -extern int printflg; -extern int getlineflg; - -extern SYMBOL *hashtab[], *funtab[]; - -extern CELL *field[]; - -char *emalloc(), *strsave(); -NODE *node0(), *node1(), *node2(), *node3(), *node4(); -NODE *stat(), *pastat(); -NODE *expr(), *expr1(), *expr2(), *expr3(), *expr4(); -NODE *expr5(), *expr6(), *expr7(), *expr8(), *expr9(), *expr10(); -NODE *doprint(), *dofuncn(), *doif(), *dowhile(), *dofor(), *body(); -NODE *doassign(), *dodo(), *doarray(), *doreturn(), *doelement(); -CELL *mkcell(), *getvar(); -CELL *execute(), *lookup(); - -int forflg; /* parsing for(expr in array), inhibit 'expr in array' */ -int prmflg; /* parsing pass parameters */ -NODE *begin, *loop, *End; - -parse() -{ - NODE *p, *q, *r, *stat(); - CELL *u; - - lex(); - skipeol(); - while (sym) { - switch (sym) { - case BEGIN: - lex(); - begin = stat(); - break; - case END: - lex(); - if (End == NULL) - End = stat(); - else { - for (p = End; p; p = q) { - if ((q = p->n_next) == NULL) - p->n_next = stat(); - } - } - break; - case FUNC: - lex(); - dousrfun(); - break; - default: - q = loop = pastat(); - skipeol(); - while (sym && sym != BEGIN && sym != END && sym != FUNC) { - r = pastat(); - q->n_next = r; - q = r; - skipeol(); - } - break; - } - skipeol(); - } - if (begin) { - u = execute(begin); - c_free(u); - } - if (End || loop) - while (Getrec(NULL)) { - if (loop) { - u = execute(loop); - c_free(u); - } - } - if (End) { - u = execute(End); - c_free(u); - } -} - -#define MAXARG 100 -static char *argnam[MAXARG]; -static int narg; - -static -dousrfun() -{ - CELL *u; - - strcpy(funnam, text); - u = getvar(text, funtab, FUN); - lex(); - if (sym != '(') - synerr("'(' expected"); - for (lex(); sym != ')'; narg++) { - if (sym != IDENT) - synerr("argument expected"); - argnam[narg] = strsave(text); - lex(); - if (sym == ',') - lex(); - } - u->c_fval = (double) narg; - lex(); - skipeol(); - funflg++; - u->c_sval = (char *) stat(); - funflg--; - if (narg > 0) { - do { - sfree(argnam[--narg]); - } while (narg > 0); - } - skipeol(); -} - -isarg(s) char *s; -{ - int i; - - if (narg > 0) { - for (i = narg - 1; i >= 0; i--) - if (strcmp(s, argnam[i]) == 0) - break; - } - else - i = -1; - return i; -} - -/* -interactive() -{ - NODE *p, *q; - CELL *u; - - for (lex(); sym; lex()) { - p = stat(); - if (p->n_type != PRINT && !iscntl(p->n_type)) { - q = (NODE *) emalloc(sizeof(NODE) + sizeof(NODE *) * 4); - q->n_type = PRINT; - q->n_arg[0] = q->n_arg[1] = q->n_arg[3] = NULL; - q->n_arg[2] = p; - q->n_next = NULL; - p = q; - } - u = execute(p); - printf("[%g(%s)]\n", u->c_fval, u->c_sval); - c_free(u); - } - closeall(); - exit(0); -} -*/ - -static -iscntl(t) -{ - static int tab[] = { - IF, DO, WHILE, FOR, JUMP, GETLINE, 0 - }; - int i; - - for (i = 0; tab[i]; i++) - if (t == tab[i]) - break; - return tab[i]; -} - -static NODE * -pastat() -{ - NODE *p, *q, *r; - - if (sym == '{') /* action only */ - p = stat(); - else { /* exp [, expr] [{ .. }] */ - p = expr(); - if (sym == ',') { - lex(); - q = expr(); - } - else - q = NULL; - if (sym && sym != EOL) - r = stat(); - else - r = node0(PRINT0); - if (q) - p = node3(P2STAT, p, q, r); - else - p = node2(P1STAT, p, r); - } - return p; -} - -static NODE * -stat() -{ - NODE *p, *q, *r; - CELL *u, *v; - int op; - -/*printf("@stat(%d)(%s)\n", sym, text);*/ - while (sym == EOL) - lex(); - switch(sym) { - case PRINT: - p = doprint(0); - break; - case PRINTF: - p = doprint(FORMAT); - break; - case IF: - p = doif(); - break; - case WHILE: - p = dowhile(); - break; - case DO: - p = dodo(); - break; - case FOR: - p = dofor(); - break; - case RETURN: - p = doreturn(); - break; - case EXIT: - p = node2(JUMP, (NODE *)sym, (NODE *)NULL); - lex(); - if (sym == IDENT || sym == NUMBER || sym == ARG) - p->n_arg[1] = expr(); - break; - case BREAK: case CONTIN: case NEXT: - p = node1(JUMP, (NODE *)sym); - lex(); - break; - case DELETE: - lex(); - u = getvar(text, hashtab, ARR); - if (!isarrayindex()) - synerr("'[' expected"); - p = doarray(u); - p->n_type = DELETE; - lex(); /* ']' */ - break; - case '{': - lex(); - skipeol(); - if (sym == '}') - p = node0(NULPROC); - else - p = q = stat(); - skipeol(); - while (sym != '}') { - r = stat(); - q->n_next = r; - q = r; - skipeol(); - } - lex(); - break; - default: - p = expr(); -#if 0 - if (sym == BINOR) { /* expr | GETLINE */ - lex(); - if (sym != GETLINE) - synerr("'GETLINE' expected"); - lex(); - if (sym == IDENT || sym == STRING || sym == ARG) { - q = expr(); - } - else - q = NULL; - p = node3(GETLINE, q, p, (NODE *)R_PIN); - } -#endif - break; - } - if (p->n_type == VALUE) - synerr("statement expected"); - return p; -} - -static -skipeol() -{ - while (sym == EOL) - lex(); -} - -static NODE * -doprint(fmt) -{ - NODE *p, *q, *r; - CELL *u; - int i, op; - int n = 0; - - printflg++; - lex(); - if (sym == '(') - lex(); - if (sym != '}' && sym != ')' && sym != EOL && sym != R_OUT && sym != R_APD - && sym != R_POUT) { - p = q = expr(); n++; - while (sym == ',') { - lex(); - skipeol(); - r = expr(); n++; - q->n_next = r; - q = r; - } - } - if (sym == ')') - lex(); - if (sym == R_OUT || sym == R_APD || sym == R_POUT) { - op = sym; - lex(); -/* q = expr10();*/ - q = expr(); /* 94-04-02 */ - } - else - q = (NODE *) (op = 0); /* stdout */ - printflg = 0; - r = (NODE *) emalloc(sizeof(*r) + sizeof(r) * (n + 3)); - r->n_type = PRINT; /* convert list to arg */ - r->n_next = NULL; - r->n_arg[0] = (NODE *) (op | fmt); - r->n_arg[1] = q; - if (n == 0) { - p = node1(VALUE, (NODE *)field[0]); - } - for (i = 2; p != NULL; i++) { - r->n_arg[i] = p; - q = p->n_next; - p->n_next = NULL; - p = q; - } - r->n_arg[i] = NULL; - return r; -} - -static NODE * -doif() -{ - NODE *p, *q, *r; - - lex(); - if (sym != '(') - synerr("'(' expected"); - lex(); - p = expr(); - if (sym != ')') - synerr("')' expected"); - lex(); - skipeol(); - q = stat(); - skipeol(); - if (sym == ELSE) { - lex(); - skipeol(); - r = stat(); - } - else - r = NULL; - return node3(IF, p, q, r); -} - -static NODE * -dowhile() -{ - NODE *p, *q; - - lex(); - if (sym != '(') - synerr("'(' expected"); - lex(); - p = stat(); - if (sym != ')') - synerr("')' expected"); - q = body(); - return node2(WHILE, p, q); -} - -static NODE * -dofor() -{ - NODE *p, *q, *r, *s; - CELL *u; - int i; - - lex(); - if (sym != '(') - synerr("'(' expected"); - lex(); - if (sym != EOL) { - forflg++; /* inhibit parsing 'expr IN array' */ - p = expr(); - forflg = 0; - } - else - p = NULL; - if (sym == IN) { - lex(); - if (sym == ARG) { -/* -printf("***FOR_IN_ARG(%d)***\n", sym); -*/ - u = mkcell(POS, NULL, (double)sym1); - q = node1(ARG, u); - } - else { - u = getvar(text, hashtab, ARR); - q = node1(VALUE, u); - } - lex(); - if (sym != ')') - synerr("')' expected"); - lex(); - skipeol(); - s = stat(); - r = node3(FORIN, p, q, s); - } - else { - if (sym != EOL) - synerr("'in' or ';' expected"); - lex(); - if (sym != EOL) - q = expr(); - else - q = NULL; - if (sym != EOL) - synerr("';' expected"); - lex(); - if (sym != ')') - r = expr(); - else - r = NULL; - if (sym != ')') - synerr("')' expected"); - s = body(); - r = node4(FOR, p, q, r, s); - } - return r; -} - -static NODE * -body() -{ - NODE *r; - - while ((sym = Getc()) == '\n' || sym == ' ' || sym == '\t') - ; - if (sym == ';') { - r = node0(NULPROC); - lex(); - } - else { - Ungetc(sym); - lex(); - r = stat(); - } - return r; -} - -static NODE * -dodo() -{ - NODE *p, *q; - - lex(); - skipeol(); - p = stat(); - skipeol(); - if (sym != WHILE) - synerr("'while' expected"); - lex(); - if (sym != '(') - synerr("'(' expected"); - lex(); - q = stat(); - if (sym != ')') - synerr("')' expected"); - lex(); - return node2(DO, p, q); -} - -static NODE * -doreturn() -{ - NODE *p, *q, *r; - int i, n = 0; - - if (lex() != EOL) { - p = q = expr(); n++; - while (sym == ',') { - lex(); skipeol(); - r = expr(); n++; - q ->n_next = r; - q = r; - } - } - else - p = (NODE *)NULL; - - r = (NODE *) emalloc(sizeof(*r) + sizeof (r) * (n + 1)); - r->n_type = JUMP; - r->n_next = NULL; - r->n_arg[0] = (NODE *) RETURN; - for (i = 1; p != NULL; i++) { - r->n_arg[i] = p; - q = p->n_next; - p->n_next = NULL; - p = q; - } - r->n_arg[i] = NULL; - return r; -} - -static NODE * -expr() -{ - NODE *p; - - p = expr1(); - if (isassign(sym)) - p = doassign(sym, p); - return p; -} - -static isassign(sym) -{ - return (sym == ASSIGN || sym == ADDEQ || sym == SUBEQ || sym == MULTEQ - || sym == DIVEQ || sym == MODEQ || sym == POWEQ); -} - -static NODE * -doassign(op, p) NODE *p; -{ /* evaluate right to left */ - NODE *q; - - lex(); - q = expr(); - if (isassign(sym)) - q = doassign(sym, q); - return node3(ASSIGN, (NODE *)op, p, q); -} - -static NODE * -expr1() -{ - NODE *p, *q; - -/* -printf("expr1(%d)(%s)\n", sym, text); -*/ - p = expr2(); - if (sym == '?') { - lex(); -#if 0 - q = stat(); - if (sym != ':') - synerr("':' expected"); - lex(); - return node3(IF, p, q, stat()); -#else - q = expr(); - if (sym != ':') - synerr("':' expected"); - lex(); - return node3(IF, p, q, expr()); -#endif - } - return p; /* 930213 */ -} - -static NODE * -expr2() -{ - NODE *p; - -/* -printf("expr2(%d)(%s)\n", sym, text); -*/ - p = expr3(); - while (sym == OR) { - lex(); - skipeol(); - p = node3(COND, (NODE *)OR, p, expr3()); - } - return p; -} - -static NODE * -expr3() -{ - NODE *p; - -/* -printf("expr3(%d)(%s)\n", sym, text); -*/ - p = expr4(); - while (sym == AND) { - lex(); - skipeol(); - p = node3(COND, (NODE *)AND, p, expr4()); - } - return p; -} - -static NODE * -expr4() -{ - NODE *p; - CELL *q; - int op; - -/* -printf("expr4(%d)(%s)\n", sym, text); -*/ - p = expr5(); - if (!forflg && sym == IN) { - lex(); - q = getvar(text, hashtab, ARR); - lex(); - return node2(IN, p, q); - } - while (sym == EQ || sym == NE || sym == LT || sym == LE || sym == GT - || sym == GE || sym == MATCH || sym == NOMATCH) { - op = sym; - lex(); - p = node3(COND, (NODE *)op, p, expr5()); - } - return p; -} - -static NODE * -expr5() -{ - NODE *p, *q; - -/* -printf("expr5(%d)(%s)\n", sym, text); -*/ - p = expr6(); - while (iscat(sym)) { - q = expr6(); - p = node2(CAT, p, q); - } - return p; -} - -static iscat(sym) -{ - static int ctab[] = { - ADD, SUB, MULT, DIV, MOD, INC, DEC, STRING, NUMBER, IDENT, '(', - MATHFUN, STRFUN, SPRINTF, '$', SUBST, ARG, CALL, 0 - }; - register int i, j; - - for (i = 0; j = ctab[i]; i++) - if (sym == j) - break; - return j; -} - -static NODE * -expr6() -{ - register int sign = sym; - NODE *p, *q; - -/* -printf("expr6(%d)(%s)\n", sym, text); -*/ - if (sym == SUB || sym == ADD) - lex(); - p = expr7(); - if (sign == SUB) - p = node2(ARITH, (NODE *)UMINUS, p); - while (sym == ADD || sym == SUB) { - sign = sym; - lex(); - q = expr7(); - if (sign == ADD) { - p = node3(ARITH, (NODE *)ADD, p, q); - } - else if (sign == SUB) { - p = node3(ARITH, (NODE *)SUB, p, q); - } - else - synerr("'+' or '-' expected"); - } - return p; -} - -static NODE * -expr7() -{ - register int op; - NODE *p, *q; - -/* -printf("expr7(%d)(%s)\n", sym, text); -*/ - p = expr8(); - while (sym == MULT || sym == DIV || sym == MOD) { - op = sym; - lex(); - q = expr8(); - switch (op) { - case MULT: p = node3(ARITH, (NODE *)MULT, p, q); break; - case DIV: p = node3(ARITH, (NODE *)DIV, p, q); break; - case MOD: p = node3(ARITH, (NODE *)MOD, p, q); break; - default: synerr("'*', '/' or '%' expected"); break; - } - } - return p; -} - -static NODE * -expr8() -{ - NODE *p; - int op; - -/* -printf("expr8(%d)(%s)\n", sym, text); -*/ - if (sym == NOT) { - lex(); - p = node2(COND, (NODE *)NOT, expr9()); - } - else { - p = expr9(); - if (sym == POWER) { - lex(); - p = node3(ARITH, (NODE *)POWER, p, expr9()); - } - } - return p; -} - -static NODE * -expr9() -{ - NODE *p, *q; - int op, sym0; - -/* -printf("expr9(%d)(%s)\n", sym, text); -*/ - if (op = isincdec(sym)) { - lex(); - if (sym != IDENT && sym != ARG) - synerr("illegal '++/--' operator"); - p = expr10(); - p = node4(ARITH, (NODE *)INCDEC, p, (NODE *)op, (NODE *)PRE); - } - else { - sym0 = sym; - p = expr10(); - if (op = isincdec(sym)) { -/*printf("POST(%d)(%d)(%s)\n", sym, sym0, text);*/ - if (sym0 == IDENT || sym0 == ARG) { - p = node4(ARITH, (NODE *)INCDEC, p, (NODE *)op, - (NODE *)POST); - lex(); - } - } - if (sym == BINOR) { /* | getline */ - lex(); - if (sym != GETLINE) - synerr("'GETLINE' expected"); - lex(); - if (sym == IDENT || sym == STRING || sym == ARG) { - q = expr(); - } - else - q = NULL; - p = node3(GETLINE, q, p, (NODE *)R_PIN); - } - } - return p; -} - -static isincdec(sym) -{ - return sym == INC ? 1 : (sym == DEC ? -1 : 0); -} - -static NODE * -expr10() -{ - NODE *p, *q; - CELL *u, *v; - int op; - int c; -int gsave, psave; - double atof(); - -/* -printf("expr10(%d)(%s)\n", sym, text); -*/ - switch (sym) { - case STRING: - u = mkcell(STR, text, 0.0); - goto g1; - case NUMBER: - u = mkcell(NUM, NULL, atof(text)); -g1: - p = node1(VALUE, u); - lex(); - break; - case IDENT: case ARG: - if (isarrayindex()) { /* array */ - /* 940403 */ - if (sym == ARG) { - u = (CELL *)emalloc(sizeof(CELL)); - u = mkcell(POS, NULL, (double)sym1); - p = doarray(u); - } - else { - u = getvar(text, hashtab, ARR); - p = doarray(u); - } - } - else { - if (sym == ARG) { - u = mkcell(POS, NULL, (double)sym1); - p = node1(ARG, u); - } - else { /* symple variable */ - u = getvar(text, hashtab, VAR|STR|NUM); - p = node1(VALUE, u); - } - } - lex(); - break; - case '(': - /* print >(x ? y : z) needs this */ -gsave = getlineflg; psave = printflg; -getlineflg = printflg = 0; - lex(); - p = expr(); - if (sym == ',') /* (expr, expr, .. ) */ - p = doelement(p); - if (sym != ')') - synerr("')' expected"); -getlineflg = gsave; printflg = psave; - lex(); - break; - case CALL: - p = dofuncn(sym, getvar(text, funtab, UDF)); - break; - case MATHFUN: case STRFUN: case SUBST: - p = dofuncn(sym, (CELL *)sym1); - break; - case SPRINTF: - p = doprint(FORMAT|STROUT); - break; - case '$': - lex(); - switch (sym) { - case NUMBER: - u = mkcell(NUM, NULL, atof(text)); - p = node1(VALUE, u); - p = node1(FIELD, p); - lex(); - break; - case IDENT: case ARG: case '(': - p = node1(FIELD, expr10()); - break; - default: - synerr("number or identifier expected after '$'", (char *)0); - } - break; - case DIV: - regexflg++; - lex(); - regexflg = 0; - u = mkcell(PAT, NULL, 0.0); - u->c_sval = (char *) mkpat(text); - p = node1(VALUE, u); - lex(); - break; - case GETLINE: - getlineflg++; - lex(); - if (sym == IDENT || sym == STRING || sym == ARG) - q = expr10(); /* read into var */ - else - q = NULL; - getlineflg = 0; - if (sym == R_IN) { - op = R_IN; - lex(); - p = expr10(); - } - else - op = (int) (p = NULL); - p = node3(GETLINE, q, p, (NODE *)op); - break; - default: - synerr( - "identifier, number, string, argument, regexpr, call or '(' expected"); - break; - } - return p; -} - -static NODE * -dofuncn(fun, op) CELL *op; -{ - NODE *p; - int i, j; - int n = 0; - NODE *a[100]; - - if (lex() == '(') { - prmflg++; - for (lex(); sym && (sym != ')'); n++) { - if ((int)op == SPLIT && n == 1) { -/* -printf("sym(%d)sym1(%d)(%d)\n", sym, sym1, isarg(text)); -*/ - if (sym != ARG) { /*isarg(text) == -1*/ - /* make an array if not exist */ - prmflg = 0; - getvar(text, hashtab, ARR); - prmflg++; - } - } - a[n] = expr(); - if (sym == ',') - lex(); - else if (sym != ')') - synerr("',' or ')' expected"); - } - prmflg = 0; - - if (sym == ')') - lex(); - else - synerr("')' expected"); - } - p = (NODE *) emalloc(sizeof(*p) + sizeof(p) * (n + 2)); - p->n_type = fun; - p->n_next = NULL; - p->n_arg[0] = (NODE *) op; - p->n_arg[1] = (NODE *) n; - for (i = 0, j = 2; i < n; ) - p->n_arg[j++] = a[i++]; - p->n_arg[j] = NULL; - return p; -} - -static NODE * -doarray(u) CELL *u; -{ - NODE *p; - int i, j; - int n; - NODE *a[20]; - - for (lex(), n = 0; sym && sym != ']'; n++) { - a[n] = expr(); - if (sym == ',') - lex(); - } - if (sym != ']') - synerr("']' expected"); - /* left ']' for expr10() */ - p = (NODE *) emalloc(sizeof(*p) + sizeof(p) * (n + 1)); - p->n_type = ARRAY; - p->n_next = NULL; - p->n_arg[0] = (NODE *)u; - p->n_arg[1] = (NODE *) n; - for (i = 0, j = 2; i < n; ) - p->n_arg[j++] = a[i++]; - return p; -} - -static NODE * -doelement(q) NODE *q; -{ - NODE *p; - int i, j; - int n; - NODE *a[20]; - - a[0] = q; - for (lex(), n = 1; sym && sym != ')'; n++) { - a[n] = expr(); - if (sym == ',') - lex(); - else if (sym != ')') - synerr("',' or ')' expected"); - } - /* left ')' for expr10() */ - p = (NODE *) emalloc(sizeof(*p) + sizeof(p) * (n + 1)); - p->n_type = ELEMENT; - p->n_next = NULL; - p->n_arg[0] = NULL; - p->n_arg[1] = (NODE *) n; - for (i = 0, j = 2; i < n; ) - p->n_arg[j++] = a[i++]; - return p; -} - -synerr(s, t) char *s, *t; -{ - extern int lineno; - extern char line[], *linep; - int c, i; - char *u, *v; - - fprintf(stderr, "%s: Syntax error at line %d", cmd, lineno); - if (funflg) - fprintf(stderr, " in function %s", funnam); - fprintf(stderr, ":\n"); - if ((v = linep - 1) < line) - v = line + BUFSIZ - 1; - for (i = 0, u = v - 1; ; --u) { - if (u < line) { - if (line[BUFSIZ - 1] == '\0') - break; - u = line + BUFSIZ - 1; - } - if (*u == '\n' && ++i == 2) - break; - } - if (u != v) { - while (u != v) { - fputc(*u, stderr); - if ((++u - line) == BUFSIZ) - u = line; - } - if (*u != '\n') - fputc(*u, stderr); - fprintf(stderr, " <--\n\n"); -/* - fprintf(stderr, " <-- "); - while ((c = Getc()) != EOF && c != '\n') - fputc(c, stderr); - fprintf(stderr, "\n"); - if (c == EOF); - fprintf(stderr, "\n"); -*/ - } - fprintf(stderr, s, t); - fprintf(stderr, "\n"); -#ifdef DOS - closeall(); -#endif - exit(1); -}