00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include <stdio.h>
00017 #include <ctype.h>
00018 #include "awk.h"
00019 #include "regexp.h"
00020
00021 #define PI 3.14159265358979323846
00022
00023 #define HASHSIZE 50
00024 #define MAXFIELD 100
00025
00026 double atof();
00027 char *getsval(), *jStrchar();
00028 extern CELL *execute(), *_Arg();
00029
00030 extern char record[];
00031 extern CELL *field[];
00032
00033 extern CELL truecell, falsecell;
00034 extern prmflg;
00035
00036 SYMBOL *hashtab[HASHSIZE];
00037 SYMBOL *funtab[HASHSIZE];
00038 SYMBOL *argtab[HASHSIZE];
00039 SYMBOL *envtab[HASHSIZE];
00040
00041 char *strsave(), *emalloc(), *strchr();
00042 CELL *lookup(), *install(), *_install(), *mkcell(), *mktmp(), *getvar();
00043
00044 char **FS, **RS, **OFS, **ORS, **OFMT, **FILENAME;
00045 char **SUBSEP;
00046 double *NR, *NF;
00047 double *FNR, *ARGC, *RSTART, *RLENGTH;
00048
00049 init()
00050 {
00051 FS = &install("FS", VAR|STR, " ", 0.0, hashtab)->c_sval;
00052 RS = &install("RS", VAR|STR, "\n", 0.0, hashtab)->c_sval;
00053 OFS = &install("OFS", VAR|STR , " ", 0.0, hashtab)->c_sval;
00054 ORS = &install("ORS", VAR|STR, "\n", 0.0, hashtab)->c_sval;
00055 OFMT = &install("OFMT", VAR|STR, "%.6g", 0.0, hashtab)->c_sval;
00056 NR = &install("NR", VAR|NUM, (char *)NULL, 0.0, hashtab)->c_fval;
00057 NF = &install("NF", VAR|NUM, (char *)NULL, 0.0, hashtab)->c_fval;
00058 FILENAME = &install("FILENAME", VAR|STR, (char *)NULL, 0.0, hashtab)->c_sval;
00059 install("PI", VAR|NUM, (char *)NULL, PI, hashtab);
00060 field[0] = mkcell(REC|STR, (char *)NULL, 0.0);
00061 field[0]->c_sval = record;
00062 SUBSEP = &install("SUBSEP", VAR|STR, "\034", 0.0, hashtab)->c_sval;
00063 FNR = &install("FNR", VAR|NUM, (char *)NULL, 0.0, hashtab)->c_fval;
00064 RSTART = &install("RSTART", VAR|NUM, (char *)NULL, 0.0, hashtab)->c_fval;
00065 RLENGTH = &install("RLENGTH", VAR|NUM, (char *)NULL, 0.0, hashtab)->c_fval;
00066 }
00067
00068 setvar(s) char *s;
00069 {
00070 CELL *u;
00071 char *t;
00072
00073 for (t = s; *t && *t != '='; t++)
00074 ;
00075 *t++ = '\0';
00076 if ((u = lookup(s, hashtab)) == (CELL *)NULL) {
00077 if (isnum(t))
00078 install(s, VAR|NUM|STR, t, atof(t), hashtab);
00079 else
00080 install(s, VAR|STR, t, 0.0, hashtab);
00081 }
00082 else {
00083 if (isnum(t))
00084 setfval(u, atof(t));
00085 else
00086 setsval(u, t);
00087 }
00088 }
00089
00090 initarg(arg0, argc, argv, envp) char *arg0, **argv, **envp;
00091 {
00092 CELL *u;
00093 register int i;
00094 register char str[4], *p;
00095
00096 ARGC = &install("ARGC", VAR|NUM, (char *)NULL, (double)argc+1, hashtab)->c_fval;
00097 u = install("ARGV", ARR, (char *)NULL, 0.0, hashtab);
00098 u->c_sval = (char *) argtab;
00099 install("0", VAR|STR, arg0, 0.0, argtab);
00100 for (i = 0; i < argc; i++) {
00101 sprintf(str, "%d", i+1);
00102 if (isnum(argv[i]))
00103 install(str, VAR|STR|NUM, argv[i], atof(argv[i]), argtab);
00104 else
00105 install(str, VAR|STR, argv[i], 0.0, argtab);
00106 }
00107
00108 u = install("ENVIRON", ARR, (char *)NULL, 0.0, hashtab);
00109 u->c_sval = (char *) envtab;
00110 for (i = 0; envp[i] && *envp[i]; i++) {
00111 if ((p = strchr(envp[i], '=')) != NULL) {
00112 *p = 0;
00113 if (isnum(p+1))
00114 install(envp[i], VAR|STR|NUM, p+1, atof(p+1), envtab);
00115 else
00116 install(envp[i], VAR|STR, p+1, 0.0, envtab);
00117 *p = '=';
00118 }
00119 }
00120 }
00121
00122 static
00123 hash(s) unsigned char *s;
00124 {
00125 register unsigned int h;
00126
00127 for (h = 0; *s; )
00128 h += *s++;
00129 return h % HASHSIZE;
00130 }
00131
00132 CELL *
00133 lookup(s, h) char *s; SYMBOL *h[];
00134 {
00135 register SYMBOL *p;
00136
00137 for (p = h[hash(s)]; p; p = p->s_next)
00138 if (strcmp(s, p->s_name) == 0)
00139 return p->s_val;
00140 return (CELL *)NULL;
00141 }
00142
00143 static CELL *
00144 install(name, type, sval, fval, h) char *name, *sval; double fval; SYMBOL *h[];
00145 {
00146 CELL *u;
00147
00148 if ((u = lookup(name, h)) == (CELL *)NULL)
00149 u = _install(name, type, sval, fval, h);
00150 else
00151 error("%s is doubly defined", name);
00152 return u;
00153 }
00154
00155 static CELL *
00156 _install(name, type, sval, fval, h) char *name, *sval; double fval; SYMBOL *h[];{
00157 register SYMBOL *p;
00158 CELL *u;
00159 int hval;
00160
00161 p = (SYMBOL *) emalloc(sizeof(*p));
00162 u = (CELL *) emalloc(sizeof(*u));
00163 p->s_name = strsave(name);
00164 p->s_val = u;
00165 hval = hash(name);
00166 p->s_next = h[hval];
00167 h[hval] = p;
00168 u->c_type = type;
00169 u->c_sval = strsave(sval);
00170 #if 0
00171 if (!(type & NUM) && isnum(sval)) {
00172 u->c_fval = atof(sval);
00173 u->c_type |= NUM;
00174 }
00175 else
00176 #endif
00177 u->c_fval = fval;
00178 return u;
00179 }
00180
00181 CELL *
00182 getvar(s, h, typ) char *s; SYMBOL *h[];
00183 {
00184 CELL *u;
00185 SYMBOL *p;
00186 char *t;
00187 int i, hval;
00188
00189 if ((u = lookup(s, h)) == (CELL *)NULL) {
00190 if (prmflg) {
00191 u = _install(s, UDF, "", 0.0, h);
00192 goto rtn;
00193 }
00194 else if (typ & ARR) {
00195 t = emalloc(sizeof(SYMBOL *) * HASHSIZE);
00196 for (i = 0; i < HASHSIZE; i++)
00197 ((SYMBOL **) t)[i] = (SYMBOL *)NULL;
00198 u = (CELL *) emalloc(sizeof(*u));
00199 u->c_type = typ;
00200 u->c_sval = t;
00201 u->c_fval = 0.0;
00202 p = (SYMBOL *) emalloc(sizeof(*p));
00203 p->s_name = strsave(s);
00204 p->s_val = u;
00205 hval = hash(s);
00206 p->s_next = h[hval];
00207 h[hval] = p;
00208 }
00209 else
00210 u = _install(s, typ, "", 0.0, h);
00211 }
00212 else if (!prmflg && (u->c_type == UDF) && (typ != UDF)) {
00213
00214 if (typ == ARR) {
00215
00216
00217
00218 u->c_type = typ;
00219 sfree(u->c_sval);
00220 u->c_sval = emalloc(sizeof(SYMBOL *) * HASHSIZE);
00221 for (i = 0; i < HASHSIZE; i++)
00222 ((SYMBOL **) u->c_sval)[i] = (SYMBOL *)NULL;
00223 u->c_fval = 0.0;
00224 }
00225 else if (typ != UDF) {
00226 u->c_type = typ;
00227 }
00228 }
00229 rtn:
00230 return u;
00231 }
00232
00233 fixarray(u) CELL *u;
00234 {
00235 int i;
00236
00237 if (u->c_type == UDF) {
00238
00239
00240
00241 u->c_type = ARR;
00242 sfree(u->c_sval);
00243 u->c_sval = emalloc(sizeof(SYMBOL *) * HASHSIZE);
00244 for (i = 0; i < HASHSIZE; i++)
00245 ((SYMBOL **) u->c_sval)[i] = (SYMBOL *)NULL;
00246 u->c_fval = 0.0;
00247 }
00248 }
00249
00250 a_free(u) CELL *u;
00251 {
00252 SYMBOL **h, *q, *r;
00253 CELL *v;
00254 int i;
00255
00256 if (!(u->c_type & ARR))
00257 error("try to free non array variable", (char *)0);
00258 h = (SYMBOL **) u->c_sval;
00259 for (i = 0; i < HASHSIZE; i++)
00260 for (q = h[i]; q; q = r) {
00261 r = q->s_next;
00262 sfree(q->s_name);
00263 v = q->s_val;
00264 c_free(v);
00265 sfree(q);
00266 }
00267
00268 sfree(u->c_sval);
00269 c_free(u);
00270 }
00271
00272 CELL *
00273 Array(p) NODE *p;
00274 {
00275 CELL *u;
00276 char str[BUFSIZ];
00277 int i, n;
00278
00279 CELL *v;
00280
00281 u = (CELL *) p->n_arg[0];
00282 if (u->c_type == POS) {
00283 i = (int)u->c_fval;
00284
00285
00286
00287 u = _Arg(i);
00288 if (u->c_type == UDF) {
00289
00290
00291
00292 fixarray(u);
00293 }
00294 }
00295 else if (!(u->c_type & ARR))
00296 error("non array refference");
00297 arrayelm(p, str);
00298 u = getvar(str, u->c_sval, VAR|NUM|STR);
00299 return u;
00300 }
00301
00302 static
00303 arrayelm(p, s) NODE *p; char *s;
00304 {
00305 CELL *u;
00306 int i, n;
00307 char *t;
00308
00309
00310
00311
00312 n = (int) p->n_arg[1] + 2;
00313 for (i = 2; i < n; i++) {
00314 if (i > 2)
00315 *s++ = **SUBSEP;
00316 u = execute(p->n_arg[i]);
00317 for (t = getsval(u); *t; )
00318 *s++ = *t++;
00319 c_free(u);
00320 }
00321 *s = '\0';
00322
00323
00324
00325 }
00326
00327 CELL *
00328 Element(p) NODE *p;
00329 {
00330 char str[BUFSIZ];
00331
00332 arrayelm(p, str);
00333 return mktmp(STR, str, 0.0);
00334 }
00335
00336 CELL *
00337 Delete(p) NODE *p;
00338 {
00339 CELL *u;
00340 char str[BUFSIZ];
00341 int i;
00342 SYMBOL *q, *r, **h;
00343
00344 u = (CELL *) p->n_arg[0];
00345 if (!(u->c_type & ARR))
00346 error("can't delete non array variable");
00347 arrayelm(p, str);
00348 h = (SYMBOL **) u->c_sval;
00349 for (r = (SYMBOL *)NULL, i = hash(str), q = h[i]; q; r = q, q = q->s_next)
00350 if (strcmp(str, q->s_name) == 0)
00351 break;
00352 if (q) {
00353 sfree(q->s_val->c_sval);
00354 sfree(q->s_name);
00355 if (r)
00356 r->s_next = q->s_next;
00357 if (q == h[i])
00358 h[i] = (SYMBOL *)NULL;
00359 }
00360 return &truecell;
00361 }
00362
00363 CELL *
00364 In(p) NODE *p;
00365 {
00366 SYMBOL **h, *q;
00367 CELL *u, *v;
00368 char *s;
00369 int i;
00370
00371 u = (CELL *) p->n_arg[1];
00372 if (!(u->c_type & ARR))
00373 error("%s is not an array", u->c_sval);
00374 h = (SYMBOL **) u->c_sval;
00375 if (u->c_sval != (char *)NULL) {
00376 v = execute(p->n_arg[0]);
00377 s = getsval(v);
00378 for (i = 0; i < HASHSIZE; i++)
00379 for (q = h[i]; q; q = q->s_next) {
00380 if (strcmp(s, q->s_name) == 0) {
00381 c_free(v);
00382 return &truecell;
00383 }
00384 }
00385 c_free(v);
00386 }
00387 return &falsecell;
00388 }
00389
00390 CELL *
00391 Split(p) NODE *p;
00392 {
00393 CELL *u, *v, *w;
00394 char *s, *t, *h, *name, *sep;
00395 int i, n, skip;
00396 char elm[8], str[BUFSIZ];
00397 static char *s_str;
00398 static regexp *s_pat;
00399 regexp *mkpat();
00400 extern int r_start, r_length;
00401
00402 n = (int) p->n_arg[1];
00403 if (n > 1) {
00404 u = execute(p->n_arg[2]);
00405 s = getsval(u);
00406 v = execute(p->n_arg[3]);
00407 if (!(v->c_type & ARR)) {
00408
00409
00410
00411 if (v->c_type == UDF)
00412 fixarray(v);
00413 else
00414 error("split to non array variable", (char *)0);
00415 }
00416 h = v->c_sval;
00417 c_free(v);
00418 if (n > 2) {
00419 v = execute(p->n_arg[4]);
00420 sep = getsval(v);
00421 }
00422 else {
00423 v = (CELL *)NULL;
00424 sep = *FS;
00425 }
00426 if (strlen(sep) > 1) {
00427 if (strcmp(sep, s_str) != 0) {
00428 sfree(s_str); sfree(s_pat);
00429 s_str = strsave(sep);
00430 s_pat = mkpat(s_str);
00431 }
00432 for (i = 0, t = str; *s; ) {
00433 if (match(s_pat, s)) {
00434 for (n = r_start; --n > 0; )
00435 *t++ = *s++;
00436 }
00437 else {
00438 while(*s)
00439 *t++ = *s++;
00440 }
00441 *t = '\0';
00442 t = str;
00443 sprintf(elm, "%d", ++i);
00444 w = getvar(elm, h, VAR);
00445 if (isnum(str))
00446 setfval(w, atof(str));
00447 else
00448 setsval(w, str);
00449 if (*s)
00450 s += r_length;
00451 }
00452 }
00453 else {
00454 skip = *sep == ' ';
00455 for (i = 0; t = str, *s; ) {
00456 if (skip)
00457 while (jStrchr(" \t\n", *s))
00458 s++;
00459 if (!(*s))
00460 break;
00461 while (*s && !jStrchr(sep, *s)) {
00462 if (isKanji(*s))
00463 *t++ = *s++;
00464 *t++ = *s++;
00465 }
00466 *t = '\0';
00467 sprintf(elm, "%d", ++i);
00468 w = getvar(elm, h, VAR);
00469 if (isnum(str))
00470 setfval(w, atof(str));
00471 else
00472 setsval(w, str);
00473 if (*s && !skip)
00474 s++;
00475 }
00476 }
00477 c_free(v);
00478 c_free(u);
00479 }
00480 else
00481 i = 0;
00482 return mktmp(NUM, (char *)NULL, (double) i);
00483 }
00484
00485 CELL *
00486 Forin(p) NODE *p;
00487 {
00488 CELL *u, *v;
00489 SYMBOL **h, *q;
00490 char *name;
00491 int i;
00492
00493 u = execute(p->n_arg[1]);
00494 if (!(u->c_type & ARR))
00495 synerr(
00496 "non array variable is specified in 'for (. in var)'", (char *)0);
00497 h = (SYMBOL **) u->c_sval;
00498 c_free(u);
00499 u = execute(p->n_arg[0]);
00500 if (u->c_type == UDF) {
00501
00502
00503
00504 u->c_type = VAR|NUM;
00505 }
00506 if (!(u->c_type & VAR))
00507 error("'for (VAR in .)' is not variable (%d)", name, u->c_type);
00508 for (i = 0; i < HASHSIZE; i++) {
00509 for (q = h[i]; q; q = q->s_next) {
00510 setsval(u, q->s_name);
00511 v = execute(p->n_arg[2]);
00512 c_free(v);
00513 }
00514 }
00515 c_free(u);
00516 return &truecell;
00517 }
00518
00519 char *
00520 strsave(s) char *s;
00521 {
00522 register int n;
00523 char *emalloc(), *strcpy();
00524
00525 if (s == (char *)NULL)
00526 return (char *)NULL;
00527 n = strlen(s) + 1;
00528 return strcpy(emalloc(n), s);
00529 }
00530
00531 sfree(p) char *p;
00532 {
00533 if (p != (char *)NULL)
00534 Free(p);
00535 }
00536
00537 isnum(s) char *s;
00538 {
00539 char *strchr();
00540
00541 if (s == NULL || *s == '\0' || !strcmp(s, "."))
00542 return 0;
00543 if (*s && strchr("+-", *s) != (char *)NULL)
00544 s++;
00545 if (*s == '\0')
00546 return 0;
00547 while (isdigit(*s))
00548 s++;
00549 if (*s == '.') {
00550 s++;
00551 while (isdigit(*s))
00552 s++;
00553 }
00554 if (*s && strchr("eE", *s) != (char *)NULL) {
00555 s++;
00556 if (*s == '\0')
00557 return 0;
00558 if (*s && strchr("+-", *s) != (char *)NULL)
00559 s++;
00560 while (isdigit(*s))
00561 s++;
00562 }
00563 return *s == '\0';
00564 }
00565
00566 setfval(u, f) CELL *u; double f;
00567 {
00568 if (u->c_type == UDF) {
00569
00570
00571
00572 u->c_type |= VAR;
00573 }
00574 if (u->c_type & (VAR|FLD|REC|TMP)) {
00575 u->c_type &= ~STR;
00576 u->c_type |= NUM;
00577 sfree(u->c_sval);
00578 u->c_sval = (char *)NULL;
00579 u->c_fval = f;
00580 if (u->c_type & FLD)
00581 mkrec(u);
00582 }
00583 else
00584 fprintf(stderr, "assign to nonvariable (%d)\n", u->c_type);
00585 }
00586
00587 setsval(u, s) CELL *u; char *s;
00588 {
00589 double atof();
00590
00591 if (u->c_type == UDF) {
00592
00593
00594
00595 u->c_type |= VAR;
00596 }
00597 if (u->c_type & (VAR|FLD|REC|TMP)) {
00598 u->c_type &= ~NUM;
00599 u->c_type |= STR;
00600 sfree(u->c_sval);
00601 u->c_sval = strsave(s);
00602 #if 0
00603 if (isnum(u->c_sval)) {
00604 u->c_fval = atof(u->c_sval);
00605 u->c_type |= NUM;
00606 }
00607 else
00608 #endif
00609 u->c_fval = 0.0;
00610 if (u->c_type & FLD)
00611 mkrec(u);
00612 }
00613 else
00614 fprintf(stderr, "assign to constant (%d)\n", u->c_type);
00615 }
00616
00617 double
00618 getfval(u) CELL *u;
00619 {
00620 double x, atof();
00621
00622 if (u->c_type == UDF) {
00623 u->c_type |= VAR|STR|NUM;
00624 u->c_sval = strsave("");
00625 x = u->c_fval = 0.0;
00626 }
00627 else if (u->c_type & NUM)
00628 x = u->c_fval;
00629 #if 1
00630 else {
00631 x = atof(u->c_sval);
00632 #else
00633 else {
00634 if (isnum(u->c_sval))
00635 x = atof(u->c_sval);
00636 else
00637 x = 0.0;
00638 #endif
00639 }
00640 return x;
00641 }
00642
00643 char *
00644 getsval(u) CELL *u;
00645 {
00646 char *s, str[80];
00647
00648 if (u->c_type & STR)
00649 s = u->c_sval;
00650 else if (u->c_type & NUM) {
00651
00652 if ((long)u->c_fval == u->c_fval)
00653 s = "%.16g";
00654 else
00655 s = *OFMT;
00656 sprintf(str, s, u->c_fval);
00657 sfree(u->c_sval);
00658 s = u->c_sval = strsave(str);
00659 }
00660 #if 1
00661 else if (u->c_type == UDF) {
00662
00663
00664
00665 u->c_type |= VAR|STR|NUM;
00666 s = u->c_sval = strsave("");
00667 u->c_fval = 0.0;
00668 }
00669 #endif
00670 else
00671 fprintf(stderr, "abnormal value (STR|NUM == 0)(%d)\n", u->c_type);
00672 return s;
00673 }
00674
00675 char *
00676 emalloc(n) unsigned n;
00677 {
00678 char *p;
00679 #if 0
00680 char far *_fmalloc();
00681 #else
00682 char *malloc();
00683 #endif
00684
00685 #if 0
00686 if ((p = _fmalloc(n)) == (char *)NULL)
00687 #else
00688 if ((p = malloc(n)) == (char *)NULL)
00689 #endif
00690 error("memory over");
00691 return p;
00692 }
00693
00694 Free(s) char *s;
00695 {
00696 #if DOS
00697 void _ffree();
00698
00699 _ffree(s);
00700 #else
00701 free(s);
00702 #endif
00703 }