/* * Funzione di supporto per lo svuotamento. */ void emptynode(hpnode_t** hpb, hpnode_t* hpn) { if(hpn != 0) { emptynode(hpb, hpn->sup); emptynode(hpb, hpn->inf); hpn->sup = *hpb; *hpb = hpn; } }
/* * Build a regular expression NODE. * Argument is the string holding the expression. */ NODE * renode(wchar_t *s) { NODE *np; int n; np = emptynode(RE, 0); np->n_left = np->n_right = NNULL; if ((n = REGWCOMP(&np->n_regexp, s)) != REG_OK) { int m; char *p; m = REGWERROR(n, np->n_regexp, NULL, 0); p = (char *)emalloc(m); REGWERROR(n, np->n_regexp, p, m); awkerr("/%S/: %s", s, p); } return (np); }
/* * Read an identifier. * Input is first character of identifier. * Return VAR. */ static int lexid(wint_t c) { wchar_t *cp; size_t i; NODE *np; cp = linebuf; do { *cp++ = c; c = lexgetc(); } while (iswalpha(c) || iswdigit(c) || c == '_'); *cp = '\0'; lexungetc(c); yylval.node = np = vlook(linebuf); switch (np->n_type) { case KEYWORD: switch (np->n_keywtype) { case PRINT: case PRINTF: ++inprint; /* FALLTHROUGH */ default: return ((int)np->n_keywtype); } /* NOTREACHED */ case ARRAY: case VAR: /* * If reading the argument list, create a dummy node * for the duration of that function. These variables * can be removed from the symbol table at function end * but they must still exist because the execution tree * knows about them. */ if (funparm) { do_funparm: np = emptynode(PARM, i = (cp-linebuf)); np->n_flags = FSTRING; np->n_string = _null; np->n_strlen = 0; (void) memcpy(np->n_name, linebuf, (i+1) * sizeof (wchar_t)); addsymtab(np); yylval.node = np; } else if (np == varNF || (np == varFS && (!doing_begin || begin_getline))) { /* * If the user program references NF or sets * FS either outside of a begin block or * in a begin block after a getline then the * input line will be split immediately upon read * rather than when a field is first referenced. */ needsplit = 1; } else if (np == varENVIRON) needenviron = 1; /* FALLTHROUGH */ case PARM: return (VAR); case UFUNC: /* * It is ok to redefine functions as parameters */ if (funparm) goto do_funparm; /* FALLTHROUGH */ case FUNC: case GETLINE: /* * When a getline is encountered, clear the 'doing_begin' flag. * This will force the 'needsplit' flag to be set, even inside * a begin block, if FS is altered. (See VAR case above) */ if (doing_begin) begin_getline = 1; return (np->n_type); } /* NOTREACHED */ return (0); }
/* * Do initial setup of buffers, etc. * This must be called before most processing * and especially before lexical analysis. * Variables initialised here will be overruled by command * line parameter initialisation. */ static void awkvarinit() { NODE *np; (void) setvbuf(stderr, NULL, _IONBF, 0); if ((NIOSTREAM = sysconf(_SC_OPEN_MAX) - 4) <= 0) { (void) fprintf(stderr, gettext("not enough available file descriptors")); exit(1); } ofiles = (OFILE *)emalloc(sizeof (OFILE)*NIOSTREAM); #ifdef A_ZERO_POINTERS (void) memset((wchar_t *)ofiles, 0, sizeof (OFILE) * NIOSTREAM); #else { /* initialize file descriptor table */ OFILE *fp; for (fp = ofiles; fp < &ofiles[NIOSTREAM]; fp += 1) { fp->f_fp = FNULL; fp->f_mode = 0; fp->f_name = (char *)0; } } #endif constant = intnode((INT)0); const0 = intnode((INT)0); const1 = intnode((INT)1); constundef = emptynode(CONSTANT, 0); constundef->n_flags = FSTRING|FVINT; constundef->n_string = _null; constundef->n_strlen = 0; inc_oper = emptynode(ADD, 0); inc_oper->n_right = const1; asn_oper = emptynode(ADD, 0); field0 = node(FIELD, const0, NNULL); { RESFUNC near*rp; for (rp = &resfuncs[0]; rp->rf_name != (LOCCHARP)NULL; ++rp) { np = finstall(rp->rf_name, rp->rf_func, rp->rf_type); } } { RESERVED near*rp; for (rp = &reserved[0]; rp->r_name != (LOCCHARP)NULL; ++rp) { switch (rp->r_type) { case SVAR: case VAR: running = 1; np = vlook(rp->r_name); if (rp->r_type == SVAR) np->n_flags |= FSPECIAL; if (rp->r_svalue != NULL) strassign(np, rp->r_svalue, FSTATIC, (size_t)rp->r_ivalue); else { constant->n_int = rp->r_ivalue; (void) assign(np, constant); } running = 0; break; case KEYWORD: kinstall(rp->r_name, (int)rp->r_ivalue); break; } } } varNR = vlook(s_NR); varFNR = vlook(s_FNR); varNF = vlook(s_NF); varOFMT = vlook(s_OFMT); varCONVFMT = vlook(s_CONVFMT); varOFS = vlook(s_OFS); varORS = vlook(s_ORS); varRS = vlook(s_RS); varFS = vlook(s_FS); varARGC = vlook(s_ARGC); varSUBSEP = vlook(s_SUBSEP); varENVIRON = vlook(s_ENVIRON); varFILENAME = vlook(s_FILENAME); varSYMTAB = vlook(s_SYMTAB); incNR = node(ASG, varNR, node(ADD, varNR, const1)); incFNR = node(ASG, varFNR, node(ADD, varFNR, const1)); clrFNR = node(ASG, varFNR, const0); }
/* * Svuota la struttura heap. */ void emptyheap(heap_t* hp) { emptynode(&(hp->unused),hp->root); hp->root = 0; }