Cell *program(Node **a, int n) /* execute an awk program */ { /* a[0] = BEGIN, a[1] = body, a[2] = END */ Cell *x; if (setjmp(env) != 0) goto ex; if (a[0]) { /* BEGIN */ x = execute(a[0]); if (isexit(x)) return(true); if (isjump(x)) ERROR "illegal break, continue, next or nextfile from BEGIN" FATAL; tempfree(x); } if (a[1] || a[2]) while (getrec(record) > 0) { x = execute(a[1]); if (isexit(x)) break; tempfree(x); } ex: if (setjmp(env) != 0) /* handles exit within END */ goto ex1; if (a[2]) { /* END */ x = execute(a[2]); if (isbreak(x) || isnext(x) || iscont(x)) ERROR "illegal break, continue, next or nextfile from END" FATAL; tempfree(x); } ex1: return(true); }
Cell *instat(Node **a, int n) /* for (a[0] in a[1]) a[2] */ { Cell *x, *vp, *arrayp, *cp, *ncp; Array *tp; int i; vp = execute(a[0]); arrayp = execute(a[1]); if (!isarr(arrayp)) { return true; } tp = (Array *) arrayp->sval; tempfree(arrayp); for (i = 0; i < tp->size; i++) { /* this routine knows too much */ for (cp = tp->tab[i]; cp != NULL; cp = ncp) { setsval(vp, cp->nval); ncp = cp->cnext; x = execute(a[2]); if (isbreak(x)) { tempfree(vp); return true; } if (isnext(x) || isexit(x) || isret(x)) { tempfree(vp); return(x); } tempfree(x); } } return true; }
Cell *dostat(Node **a, int n) /* do a[0]; while(a[1]) */ { Cell *x; for (;;) { x = execute(a[0]); if (isbreak(x)) return true; if (isnext(x) || isnextfile(x) || isexit(x) || isret(x)) return(x); tempfree(x); x = execute(a[1]); if (!istrue(x)) return(x); tempfree(x); } }
Cell *whilestat(Node **a, int n) /* while (a[0]) a[1] */ { Cell *x; for (;;) { x = execute(a[0]); if (!istrue(x)) return(x); tempfree(x); x = execute(a[1]); if (isbreak(x)) { x = true; return(x); } if (isnext(x) || isexit(x) || isret(x)) return(x); tempfree(x); } }
Cell *forstat(Node **a, int n) /* for (a[0]; a[1]; a[2]) a[3] */ { Cell *x; x = execute(a[0]); tempfree(x); for (;;) { if (a[1]!=0) { x = execute(a[1]); if (!istrue(x)) return(x); else tempfree(x); } x = execute(a[3]); if (isbreak(x)) /* turn off break */ return true; if (isnext(x) || isexit(x) || isret(x)) return(x); tempfree(x); x = execute(a[2]); tempfree(x); } }
int findSubstringInWraproundString(string p) { int n = p.size(); vector<int> cnt(26, 0); //num of substrings from i vector<int> dp(n, 0); //num of valid substrings end at i for(int i = 0; i < n; ++i) { if(i != 0 && isnext(p[i], p[i - 1])) { dp[i] = dp[i - 1] + 1; for(int j = dp[i] - 1; j >= 0; --j) { cnt[p[i - j] - 'a'] = max(cnt[p[i - j] - 'a'], j + 1); } } else { dp[i] = 1; cnt[p[i] - 'a'] = max(cnt[p[i] - 'a'], 1); } } return accumulate(cnt.begin(), cnt.end(), 0); }
Cell *call(Node **a, int n) /* function call. very kludgy and fragile */ { static Cell newcopycell = { OCELL, CCOPY, 0, (char *) "", 0.0, NUM|STR|DONTFREE }; int i, ncall, ndef; Node *x; Cell *args[NARGS], *oargs[NARGS], *y, *z, *fcn; char *s; fcn = execute(a[0]); /* the function itself */ s = fcn->nval; if (!isfunc(fcn)) ERROR "calling undefined function %s", s FATAL; if (frame == NULL) { fp = frame = (struct Frame *) calloc(nframe += 100, sizeof(struct Frame)); if (frame == NULL) ERROR "out of space for stack frames calling %s", s FATAL; } for (ncall = 0, x = a[1]; x != NULL; x = x->nnext) /* args in call */ ncall++; ndef = (int) fcn->fval; /* args in defn */ dprintf( ("calling %s, %d args (%d in defn), fp=%d\n", s, ncall, ndef, fp-frame) ); if (ncall > ndef) ERROR "function %s called with %d args, uses only %d", s, ncall, ndef WARNING; if (ncall + ndef > NARGS) ERROR "function %s has %d arguments, limit %d", s, ncall+ndef, NARGS FATAL; for (i = 0, x = a[1]; x != NULL; i++, x = x->nnext) { /* get call args */ dprintf( ("evaluate args[%d], fp=%d:\n", i, fp-frame) ); y = execute(x); oargs[i] = y; dprintf( ("args[%d]: %s %f <%s>, t=%o\n", i, y->nval, y->fval, isarr(y) ? "(array)" : (char*) y->sval, y->tval) ); if (isfunc(y)) ERROR "can't use function %s as argument in %s", y->nval, s FATAL; if (isarr(y)) args[i] = y; /* arrays by ref */ else args[i] = copycell(y); tempfree(y); } for ( ; i < ndef; i++) { /* add null args for ones not provided */ args[i] = gettemp(); *args[i] = newcopycell; } fp++; /* now ok to up frame */ if (fp >= frame + nframe) { int dfp = fp - frame; /* old index */ frame = (struct Frame *) realloc((char *) frame, (nframe += 100) * sizeof(struct Frame)); if (frame == NULL) ERROR "out of space for stack frames in %s", s FATAL; fp = frame + dfp; } fp->fcncell = fcn; fp->args = args; fp->nargs = ndef; /* number defined with (excess are locals) */ fp->retval = gettemp(); dprintf( ("start exec of %s, fp=%d\n", s, fp-frame) ); y = execute((Node *)(fcn->sval)); /* execute body */ dprintf( ("finished exec of %s, fp=%d\n", s, fp-frame) ); for (i = 0; i < ndef; i++) { Cell *t = fp->args[i]; if (isarr(t)) { if (t->csub == CCOPY) { if (i >= ncall) { freesymtab(t); t->csub = CTEMP; } else { oargs[i]->tval = t->tval; oargs[i]->tval &= ~(STR|NUM|DONTFREE); oargs[i]->sval = t->sval; tempfree(t); } } } else if (t != y) { /* kludge to prevent freeing twice */ t->csub = CTEMP; tempfree(t); } } tempfree(fcn); if (isexit(y) || isnext(y) || isnextfile(y)) return y; tempfree(y); /* this can free twice! */ z = fp->retval; /* return value */ dprintf( ("%s returns %g |%s| %o\n", s, getfval(z), getsval(z), z->tval) ); fp--; return(z); }