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