4 * (C) 1989 Saeko Hirabauashi & Kouichi Hirabayashi
6 * Absolutely no warranty. Use this software with your own risk.
8 * Permission to use, copy, modify and distribute this software for any
9 * purpose and without fee is hereby granted, provided that the above
10 * copyright and disclaimer notice.
12 * This program was written to fit into 64K+64K memory of the Minix 1.2.
21 #define PI 3.14159265358979323846
27 char *getsval(), *jStrchar();
28 extern CELL
*execute(), *_Arg();
33 extern CELL truecell
, falsecell
;
36 SYMBOL
*hashtab
[HASHSIZE
];
37 SYMBOL
*funtab
[HASHSIZE
];
38 SYMBOL
*argtab
[HASHSIZE
];
39 SYMBOL
*envtab
[HASHSIZE
];
41 char *strsave(), *emalloc(), *strchr();
42 CELL
*lookup(), *install(), *_install(), *mkcell(), *mktmp(), *getvar();
44 char **FS
, **RS
, **OFS
, **ORS
, **OFMT
, **FILENAME
;
47 double *FNR
, *ARGC
, *RSTART
, *RLENGTH
;
51 FS
= &install("FS", VAR
|STR
, " ", 0.0, hashtab
)->c_sval
;
52 RS
= &install("RS", VAR
|STR
, "\n", 0.0, hashtab
)->c_sval
;
53 OFS
= &install("OFS", VAR
|STR
, " ", 0.0, hashtab
)->c_sval
;
54 ORS
= &install("ORS", VAR
|STR
, "\n", 0.0, hashtab
)->c_sval
;
55 OFMT
= &install("OFMT", VAR
|STR
, "%.6g", 0.0, hashtab
)->c_sval
;
56 NR
= &install("NR", VAR
|NUM
, (char *)NULL
, 0.0, hashtab
)->c_fval
;
57 NF
= &install("NF", VAR
|NUM
, (char *)NULL
, 0.0, hashtab
)->c_fval
;
58 FILENAME
= &install("FILENAME", VAR
|STR
, (char *)NULL
, 0.0, hashtab
)->c_sval
;
59 install("PI", VAR
|NUM
, (char *)NULL
, PI
, hashtab
);
60 field
[0] = mkcell(REC
|STR
, (char *)NULL
, 0.0); /* $0 */
61 field
[0]->c_sval
= record
;
62 SUBSEP
= &install("SUBSEP", VAR
|STR
, "\034", 0.0, hashtab
)->c_sval
;
63 FNR
= &install("FNR", VAR
|NUM
, (char *)NULL
, 0.0, hashtab
)->c_fval
;
64 RSTART
= &install("RSTART", VAR
|NUM
, (char *)NULL
, 0.0, hashtab
)->c_fval
;
65 RLENGTH
= &install("RLENGTH", VAR
|NUM
, (char *)NULL
, 0.0, hashtab
)->c_fval
;
73 for (t
= s
; *t
&& *t
!= '='; t
++)
76 if ((u
= lookup(s
, hashtab
)) == (CELL
*)NULL
) {
78 install(s
, VAR
|NUM
|STR
, t
, atof(t
), hashtab
);
80 install(s
, VAR
|STR
, t
, 0.0, hashtab
);
90 initarg(arg0
, argc
, argv
, envp
) char *arg0
, **argv
, **envp
;
94 register char str
[4], *p
;
96 ARGC
= &install("ARGC", VAR
|NUM
, (char *)NULL
, (double)argc
+1, hashtab
)->c_fval
;
97 u
= install("ARGV", ARR
, (char *)NULL
, 0.0, hashtab
);
98 u
->c_sval
= (char *) argtab
;
99 install("0", VAR
|STR
, arg0
, 0.0, argtab
);
100 for (i
= 0; i
< argc
; i
++) {
101 sprintf(str
, "%d", i
+1);
103 install(str
, VAR
|STR
|NUM
, argv
[i
], atof(argv
[i
]), argtab
);
105 install(str
, VAR
|STR
, argv
[i
], 0.0, argtab
);
108 u
= install("ENVIRON", ARR
, (char *)NULL
, 0.0, hashtab
);
109 u
->c_sval
= (char *) envtab
;
110 for (i
= 0; envp
[i
] && *envp
[i
]; i
++) {
111 if ((p
= strchr(envp
[i
], '=')) != NULL
) {
114 install(envp
[i
], VAR
|STR
|NUM
, p
+1, atof(p
+1), envtab
);
116 install(envp
[i
], VAR
|STR
, p
+1, 0.0, envtab
);
123 hash(s
) unsigned char *s
;
125 register unsigned int h
;
133 lookup(s
, h
) char *s
; SYMBOL
*h
[];
137 for (p
= h
[hash(s
)]; p
; p
= p
->s_next
)
138 if (strcmp(s
, p
->s_name
) == 0)
144 install(name
, type
, sval
, fval
, h
) char *name
, *sval
; double fval
; SYMBOL
*h
[];
148 if ((u
= lookup(name
, h
)) == (CELL
*)NULL
)
149 u
= _install(name
, type
, sval
, fval
, h
);
151 error("%s is doubly defined", name
);
156 _install(name
, type
, sval
, fval
, h
) char *name
, *sval
; double fval
; SYMBOL
*h
[];{
161 p
= (SYMBOL
*) emalloc(sizeof(*p
));
162 u
= (CELL
*) emalloc(sizeof(*u
));
163 p
->s_name
= strsave(name
);
169 u
->c_sval
= strsave(sval
);
171 if (!(type
& NUM
) && isnum(sval
)) {
172 u
->c_fval
= atof(sval
);
182 getvar(s
, h
, typ
) char *s
; SYMBOL
*h
[];
189 if ((u
= lookup(s
, h
)) == (CELL
*)NULL
) {
191 u
= _install(s
, UDF
, "", 0.0, h
);
194 else if (typ
& ARR
) {
195 t
= emalloc(sizeof(SYMBOL
*) * HASHSIZE
);
196 for (i
= 0; i
< HASHSIZE
; i
++)
197 ((SYMBOL
**) t
)[i
] = (SYMBOL
*)NULL
;
198 u
= (CELL
*) emalloc(sizeof(*u
));
202 p
= (SYMBOL
*) emalloc(sizeof(*p
));
203 p
->s_name
= strsave(s
);
210 u
= _install(s
, typ
, "", 0.0, h
);
212 else if (!prmflg
&& (u
->c_type
== UDF
) && (typ
!= UDF
)) {
213 /* fix up local_var/forward_function */
216 printf("getvar_correct_to_array\n");
220 u
->c_sval
= emalloc(sizeof(SYMBOL
*) * HASHSIZE
);
221 for (i
= 0; i
< HASHSIZE
; i
++)
222 ((SYMBOL
**) u
->c_sval
)[i
] = (SYMBOL
*)NULL
;
225 else if (typ
!= UDF
) {
237 if (u
->c_type
== UDF
) { /* fix up local var */
239 printf("fixarray\n");
243 u
->c_sval
= emalloc(sizeof(SYMBOL
*) * HASHSIZE
);
244 for (i
= 0; i
< HASHSIZE
; i
++)
245 ((SYMBOL
**) u
->c_sval
)[i
] = (SYMBOL
*)NULL
;
251 { /* free local array */
256 if (!(u
->c_type
& ARR
))
257 error("try to free non array variable", (char *)0);
258 h
= (SYMBOL
**) u
->c_sval
;
259 for (i
= 0; i
< HASHSIZE
; i
++)
260 for (q
= h
[i
]; q
; q
= r
) {
263 v
= q
->s_val
; /* CELL */
265 sfree(q
); /* SYMBOL */
268 sfree(u
->c_sval
); /* symbol table */
281 u
= (CELL
*) p
->n_arg
[0];
282 if (u
->c_type
== POS
) {
285 printf("**ARG_ARRAY(%d)*\n", i);
288 if (u
->c_type
== UDF
) { /* fix up local array */
290 printf("local_var_to_array\n");
295 else if (!(u
->c_type
& ARR
))
296 error("non array refference");
298 u
= getvar(str
, u
->c_sval
, VAR
|NUM
|STR
); /* "rtsort in AWK book */
303 arrayelm(p
, s
) NODE
*p
; char *s
;
312 n
= (int) p
->n_arg
[1] + 2;
313 for (i
= 2; i
< n
; i
++) {
316 u
= execute(p
->n_arg
[i
]);
317 for (t
= getsval(u
); *t
; )
323 printf("array_elm(%s)\n", tt);
333 return mktmp(STR
, str
, 0.0);
344 u
= (CELL
*) p
->n_arg
[0];
345 if (!(u
->c_type
& ARR
))
346 error("can't delete non array variable");
348 h
= (SYMBOL
**) u
->c_sval
;
349 for (r
= (SYMBOL
*)NULL
, i
= hash(str
), q
= h
[i
]; q
; r
= q
, q
= q
->s_next
)
350 if (strcmp(str
, q
->s_name
) == 0)
353 sfree(q
->s_val
->c_sval
);
356 r
->s_next
= q
->s_next
;
358 h
[i
] = (SYMBOL
*)NULL
;
371 u
= (CELL
*) p
->n_arg
[1]; /* array */
372 if (!(u
->c_type
& ARR
))
373 error("%s is not an array", u
->c_sval
);
374 h
= (SYMBOL
**) u
->c_sval
;
375 if (u
->c_sval
!= (char *)NULL
) {
376 v
= execute(p
->n_arg
[0]); /* var */
378 for (i
= 0; i
< HASHSIZE
; i
++)
379 for (q
= h
[i
]; q
; q
= q
->s_next
) {
380 if (strcmp(s
, q
->s_name
) == 0) {
394 char *s
, *t
, *h
, *name
, *sep
;
396 char elm
[8], str
[BUFSIZ
];
398 static regexp
*s_pat
;
400 extern int r_start
, r_length
;
402 n
= (int) p
->n_arg
[1];
404 u
= execute(p
->n_arg
[2]);
405 s
= getsval(u
); /* str */
406 v
= execute(p
->n_arg
[3]); /* array */
407 if (!(v
->c_type
& ARR
)) {
409 printf("Split fix_to_array(%d)\n", v->c_type);
411 if (v
->c_type
== UDF
) /* fix up local array */
414 error("split to non array variable", (char *)0);
419 v
= execute(p
->n_arg
[4]);
426 if (strlen(sep
) > 1) { /* reg_exp */
427 if (strcmp(sep
, s_str
) != 0) {
428 sfree(s_str
); sfree(s_pat
);
429 s_str
= strsave(sep
);
430 s_pat
= mkpat(s_str
);
432 for (i
= 0, t
= str
; *s
; ) {
433 if (match(s_pat
, s
)) {
434 for (n
= r_start
; --n
> 0; )
443 sprintf(elm
, "%d", ++i
);
444 w
= getvar(elm
, h
, VAR
);
446 setfval(w
, atof(str
));
455 for (i
= 0; t
= str
, *s
; ) {
457 while (jStrchr(" \t\n", *s
))
461 while (*s
&& !jStrchr(sep
, *s
)) {
467 sprintf(elm
, "%d", ++i
);
468 w
= getvar(elm
, h
, VAR
);
470 setfval(w
, atof(str
));
478 c_free(u
); /* str may be CATed */
482 return mktmp(NUM
, (char *)NULL
, (double) i
);
493 u
= execute(p
->n_arg
[1]);
494 if (!(u
->c_type
& ARR
))
496 "non array variable is specified in 'for (. in var)'", (char *)0);
497 h
= (SYMBOL
**) u
->c_sval
;
499 u
= execute(p
->n_arg
[0]);
500 if (u
->c_type
== UDF
) {
502 printf("Forin_fix_to_VAR|NUM\n");
506 if (!(u
->c_type
& VAR
))
507 error("'for (VAR in .)' is not variable (%d)", name
, u
->c_type
);
508 for (i
= 0; i
< HASHSIZE
; i
++) {
509 for (q
= h
[i
]; q
; q
= q
->s_next
) {
510 setsval(u
, q
->s_name
);
511 v
= execute(p
->n_arg
[2]);
523 char *emalloc(), *strcpy();
525 if (s
== (char *)NULL
)
528 return strcpy(emalloc(n
), s
);
533 if (p
!= (char *)NULL
)
541 if (s
== NULL
|| *s
== '\0' || !strcmp(s
, "."))
543 if (*s
&& strchr("+-", *s
) != (char *)NULL
)
554 if (*s
&& strchr("eE", *s
) != (char *)NULL
) {
558 if (*s
&& strchr("+-", *s
) != (char *)NULL
)
566 setfval(u
, f
) CELL
*u
; double f
;
568 if (u
->c_type
== UDF
) { /* fix up local var */
570 printf("setfval_fix_to_VAR\n");
574 if (u
->c_type
& (VAR
|FLD
|REC
|TMP
)) {
578 u
->c_sval
= (char *)NULL
;
584 fprintf(stderr
, "assign to nonvariable (%d)\n", u
->c_type
);
587 setsval(u
, s
) CELL
*u
; char *s
;
591 if (u
->c_type
== UDF
) { /* fix up local var */
593 printf("setsval_fix_to_VAR\n");
597 if (u
->c_type
& (VAR
|FLD
|REC
|TMP
)) {
601 u
->c_sval
= strsave(s
);
602 #if 0 /* "table2" in AWK book */
603 if (isnum(u
->c_sval
)) {
604 u
->c_fval
= atof(u
->c_sval
);
614 fprintf(stderr
, "assign to constant (%d)\n", u
->c_type
);
622 if (u
->c_type
== UDF
) { /* local var */
623 u
->c_type
|= VAR
|STR
|NUM
;
624 u
->c_sval
= strsave("");
627 else if (u
->c_type
& NUM
)
634 if (isnum(u
->c_sval
))
650 else if (u
->c_type
& NUM
) {
651 /* if (u->c_fval >= -2147483648.0 && u->c_fval <= 2147483647.0)*/
652 if ((long)u
->c_fval
== u
->c_fval
)
656 sprintf(str
, s
, u
->c_fval
);
658 s
= u
->c_sval
= strsave(str
);
661 else if (u
->c_type
== UDF
) { /* local var */
663 printf("getsval_fix_to_VAR|STR\n");
665 u
->c_type
|= VAR
|STR
|NUM
;
666 s
= u
->c_sval
= strsave("");
671 fprintf(stderr
, "abnormal value (STR|NUM == 0)(%d)\n", u
->c_type
);
676 emalloc(n
) unsigned n
;
680 char far
*_fmalloc();
686 if ((p
= _fmalloc(n
)) == (char *)NULL
)
688 if ((p
= malloc(n
)) == (char *)NULL
)
690 error("memory over");