var_t interpretexp(char** line) { var_t exp; while (isspace(**line) != 0) ++(*line); if (**line == '"') { ++(*line); exp.any.s = readtoken(line, isqmark, 1); exp.tag = STRING; } else if (isdigit(**line)) { char* str = readtoken(line, isdigit, 0); exp.any.i = atoi(str); exp.tag = INT; free(str); } else if (isalpha(**line)) { char* id = readtoken(line, isalpha, 0); exp = *find_var(id); free(id); } else { printf("Error at:\n %s ", *line); exit(EXIT_FAILURE); } while (isspace(**line) != 0) ++(*line); /*if + return add_var(exp, interpretexp(line)) else if - return sub_var(exp, interpretexp(line))*/ return exp; }
STATIC union node * pipeline() { union node *n1, *pipenode; struct nodelist *lp, *prev; n1 = command(); if (readtoken() == TPIPE) { pipenode = (union node *)stalloc(sizeof (struct npipe)); pipenode->type = NPIPE; pipenode->npipe.backgnd = 0; lp = (struct nodelist *)stalloc(sizeof (struct nodelist)); pipenode->npipe.cmdlist = lp; lp->n = n1; do { prev = lp; lp = (struct nodelist *)stalloc(sizeof (struct nodelist)); lp->n = command(); prev->next = lp; } while (readtoken() == TPIPE); lp->next = NULL; n1 = pipenode; } tokpushback++; return n1; }
STATIC union node * list(nlflag) { union node *n1, *n2, *n3; checkkwd(); if (nlflag == 0 && tokendlist[lasttoken]) return NULL; n1 = andor(); for (;;) { switch (readtoken()) { case TBACKGND: if (n1->type == NCMD || n1->type == NPIPE) { n1->ncmd.backgnd = 1; } else if (n1->type == NREDIR) { n1->type = NBACKGND; } else { n3 = (union node *)stalloc(sizeof (struct nredir)); n3->type = NBACKGND; n3->nredir.n = n1; n3->nredir.redirect = NULL; n1 = n3; } goto tsemi; case TNL: tokpushback++; /* fall through */ tsemi: case TSEMI: if (readtoken() == TNL) { parseheredoc(); if (nlflag) return n1; } else { tokpushback++; } checkkwd(); if (tokendlist[lasttoken]) return n1; n2 = andor(); n3 = (union node *)stalloc(sizeof (struct nbinary)); n3->type = NSEMI; n3->nbinary.ch1 = n1; n3->nbinary.ch2 = n2; n1 = n3; break; case TEOF: if (heredoclist) parseheredoc(); else pungetc(); /* push back EOF on input */ return n1; default: if (nlflag) synexpect(-1); tokpushback++; return n1; } } }
STATIC union node * simplecmd() { union node *args, **app; union node *redir, **rpp; union node *n; args = NULL; app = &args; rpp = &redir; for (;;) { if (readtoken() == TWORD) { n = (union node *)stalloc(sizeof (struct narg)); n->type = NARG; n->narg.text = wordtext; n->narg.backquote = backquotelist; *app = n; app = &n->narg.next; } else if (lasttoken == TREDIR) { *rpp = n = redirnode; rpp = &n->nfile.next; parsefname(); /* read name of redirection file */ } else if (lasttoken == TLP && app == &args->narg.next && rpp == &redir) { /* We have a function */ if (readtoken() != TRP) synexpect(TRP); if (! goodname(n->narg.text)) synerror("Bad function name"); n->type = NDEFUN; n->narg.next = command(); return n; } else { tokpushback++; break; } } *app = NULL; *rpp = NULL; n = (union node *)stalloc(sizeof (struct ncmd)); n->type = NCMD; n->ncmd.backgnd = 0; n->ncmd.args = args; n->ncmd.redirect = redir; return n; }
STATIC int peektoken(void) { int t; t = readtoken(); tokpushback++; return (t); }
size_t readtokens (FILE *stream, size_t projected_n_tokens, const char *delim, size_t n_delim, char ***tokens_out, size_t **token_lengths) { token_buffer tb, *token = &tb; char **tokens; size_t *lengths; size_t sz; size_t n_tokens; if (projected_n_tokens == 0) projected_n_tokens = 64; else projected_n_tokens++; /* add one for trailing NULL pointer */ sz = projected_n_tokens; tokens = xnmalloc (sz, sizeof *tokens); lengths = xnmalloc (sz, sizeof *lengths); n_tokens = 0; init_tokenbuffer (token); for (;;) { char *tmp; size_t token_length = readtoken (stream, delim, n_delim, token); if (n_tokens >= sz) { tokens = x2nrealloc (tokens, &sz, sizeof *tokens); lengths = xnrealloc (lengths, sz, sizeof *lengths); } if (token_length == (size_t) -1) { /* don't increment n_tokens for NULL entry */ tokens[n_tokens] = NULL; lengths[n_tokens] = 0; break; } tmp = xnmalloc (token_length + 1, sizeof *tmp); lengths[n_tokens] = token_length; tokens[n_tokens] = memcpy (tmp, token->buffer, token_length + 1); n_tokens++; } free (token->buffer); *tokens_out = tokens; if (token_lengths != NULL) *token_lengths = lengths; else free (lengths); return n_tokens; }
static int read_comment(struct input *input) { char separator[128]; char *line = input_line(input); line = readtoken(separator, line, " \n"); input_next(input); while ((line = input_line(input)) && !startswith(line, separator)) input_next(input); return 0; }
STATIC union node * pipeline(void) { union node *n1, *n2, *pipenode; struct nodelist *lp, *prev; int negate; negate = 0; TRACE(("pipeline: entered\n")); while (readtoken() == TNOT) negate = !negate; tokpushback++; n1 = command(); if (readtoken() == TPIPE) { pipenode = (union node *)stalloc(sizeof (struct npipe)); pipenode->type = NPIPE; pipenode->npipe.backgnd = 0; lp = (struct nodelist *)stalloc(sizeof (struct nodelist)); pipenode->npipe.cmdlist = lp; lp->n = n1; do { prev = lp; lp = (struct nodelist *)stalloc(sizeof (struct nodelist)); lp->n = command(); prev->next = lp; } while (readtoken() == TPIPE); lp->next = NULL; n1 = pipenode; } tokpushback++; if (negate) { n2 = (union node *)stalloc(sizeof (struct nnot)); n2->type = NNOT; n2->nnot.com = n1; return n2; } else return n1; }
STATIC void parsefname() { union node *n = redirnode; if (readtoken() != TWORD) synexpect(-1); if (n->type == NHERE) { struct heredoc *here = heredoc; struct heredoc *p; int i; if (quoteflag == 0) n->type = NXHERE; TRACE(("Here document %d\n", n->type)); if (here->striptabs) { while (*wordtext == '\t') wordtext++; } if (! noexpand(wordtext) || (i = strlen(wordtext)) == 0 || i > EOFMARKLEN) synerror("Illegal eof marker for << redirection"); rmescapes(wordtext); here->eofmark = wordtext; here->next = NULL; if (heredoclist == NULL) heredoclist = here; else { for (p = heredoclist ; p->next ; p = p->next); p->next = here; } } else if (n->type == NTOFD || n->type == NFROMFD) { if (is_digit(wordtext[0])) n->ndup.dupfd = digit_val(wordtext[0]); else if (wordtext[0] == '-') n->ndup.dupfd = -1; else goto bad; if (wordtext[1] != '\0') { bad: synerror("Bad fd number"); } } else { n->nfile.fname = (union node *)stalloc(sizeof (struct narg)); n = n->nfile.fname; n->type = NARG; n->narg.next = NULL; n->narg.text = wordtext; n->narg.backquote = backquotelist; } }
union node * parsecmd(interact) { int t; doprompt = interact; if (doprompt) putprompt(ps1val()); needprompt = 0; if ((t = readtoken()) == TEOF) return NEOF; if (t == TNL) return NULL; tokpushback++; return list(1); }
static void basic (void) { char const *filename = "in.827"; int fd = open (filename, O_CREAT | O_WRONLY, 0600); ASSERT (fd >= 0); ASSERT (write (fd, "a|b;c+d", 7) == 7); ASSERT (close (fd) == 0); { token_buffer tb; FILE *fp = fopen (filename, "r"); ASSERT (fp); init_tokenbuffer (&tb); ASSERT (readtoken (fp, "|;", 2, &tb) == 1 && tb.buffer[0] == 'a'); ASSERT (readtoken (fp, "|;", 2, &tb) == 1 && tb.buffer[0] == 'b'); ASSERT (readtoken (fp, "+", 1, &tb) == 1 && tb.buffer[0] == 'c'); ASSERT (readtoken (fp, "-", 1, &tb) == 1 && tb.buffer[0] == 'd'); ASSERT (readtoken (fp, "%", 0, &tb) == (size_t) -1); ASSERT ( ! ferror (fp)); ASSERT (fclose (fp) == 0); } }
STATIC void checkkwd() { register char *const *pp; int t; while ((t = readtoken()) == TNL) parseheredoc(); if (t == TWORD && quoteflag == 0) { for (pp = parsekwd ; *pp ; pp++) { if (**pp == *wordtext && equal(*pp, wordtext)) { lasttoken = pp - parsekwd + KWDOFFSET; break; } } } tokpushback++; }
void interpretline(char* line) { char* name; do { name = readtoken(&line, isalpha, 0); printf(">%s<\n", name); switch (*line) { case '(': interpretfunc(name, ++line); break; case '=': interpretvar(name, ++line); break; default: printf("compile error at: %s\n", line); abort(); } /*free(name);*/ } while (*line != '\0'); }
int main (int argc, char **argv) { token_buffer tb; char const *delim; size_t delim_len; atexit (close_stdout); if (argc == 1) { basic (); return 0; } init_tokenbuffer (&tb); if (argc != 2) return 99; delim = argv[1]; delim_len = strlen (delim); if (STREQ (delim, "\\0")) { delim = ""; delim_len = 1; } while (1) { size_t token_length = readtoken (stdin, delim, delim_len, &tb); if (token_length == (size_t) -1) break; fwrite (tb.buffer, 1, token_length, stdout); putchar (':'); } putchar ('\n'); free (tb.buffer); ASSERT ( ! ferror (stdin)); return 0; }
union node * parsecmd(int interact) { int t; extern int exitstatus; tokpushback = 0; doprompt = interact; if (doprompt) setprompt(exitstatus == 0 || (vpse.flags & VUNSET) ? 1 : -1); else setprompt(0); needprompt = 0; t = readtoken(); if (t == TEOF) return NEOF; if (t == TNL) return NULL; tokpushback++; return list(1); }
static int exec_ironout(struct input *input, char *ironout) { char token[128]; char command[MAXPATHLEN]; FILE *output; char *line = input_line(input); int result; char *cur = command; line = nthtoken(token, line, " \n", 2); strcpy(cur, ironout); cur += strlen(cur); while (*line) { line = readtoken(token, line, " \n"); cur += sprintf(cur, " %s", token); } if (!(output = popen(command, "r"))) return 1; result = match_files(input, output); if (pclose(output)) return 1; return result; }
STATIC union node * andor() { union node *n1, *n2, *n3; int t; n1 = pipeline(); for (;;) { if ((t = readtoken()) == TAND) { t = NAND; } else if (t == TOR) { t = NOR; } else { tokpushback++; return n1; } n2 = pipeline(); n3 = (union node *)stalloc(sizeof (struct nbinary)); n3->type = t; n3->nbinary.ch1 = n1; n3->nbinary.ch2 = n2; n1 = n3; } }
STATIC void parsefname(void) { union node *n = redirnode; if (readtoken() != TWORD) synexpect(-1); if (n->type == NHERE) { struct heredoc *here = heredoc; struct heredoc *p; int i; if (quoteflag == 0) n->type = NXHERE; TRACE(("Here document %d\n", n->type)); if (here->striptabs) { while (*wordtext == '\t') wordtext++; } if (! noexpand(wordtext) || (i = strlen(wordtext)) == 0 || i > EOFMARKLEN) synerror("Illegal eof marker for << redirection"); rmescapes(wordtext); here->eofmark = wordtext; here->next = NULL; if (heredoclist == NULL) heredoclist = here; else { for (p = heredoclist ; p->next ; p = p->next); p->next = here; } } else if (n->type == NTOFD || n->type == NFROMFD) { fixredir(n, wordtext, 0); } else { n->nfile.fname = makename(); } }
void readancestry(char *ancestryname) /* These occur at the following braceindent levels: * 1: trio, genotyped, owned, split, active, segments. Ignored. * 2: north_european, eana, and other ethnic categories. They occur in no particular order and must be sorted later. * 3: hap1 and hap2, which designate which chromosome of a pair. * 4. chr1 through chr22 and chrX-npar. chrY and mt do not occur. */ { token tok; int braceindent=0,bracketindent=0,i; string ethnicity; interval intvl; int hap,chr,startend=0; int64_t index; ancestryfile=fopen(ancestryname,"r"); if (ancestryfile) { while (tok.ch!=EOF) { tok=readtoken(); switch (tok.ch) { case '{': braceindent++; break; case '}': braceindent--; break; case '[': bracketindent++; startend=0; break; case ']': bracketindent--; if (startend) { intvl.ethnicity[0]=find_ethnic(ethnicity); intvl.chromosome=chr; index=intvl.index(); if (haploid[hap][index].ethnicity[0]<=intvl.ethnicity[0]) haploid[hap][index]=intvl; //printf("%d %016lx [%d,%d] %s\n",hap,index,intvl.start,intvl.end,ethnicity.c_str()); intvl.clear(); startend=0; } break; case ',': startend++; break; case '"': switch (braceindent) { case 2: ethnicity=tok.str; break; case 3: hap=tok.str[3]-'1'; break; case 4: chr=chromosomenumber(tok.str); break; } /*for (i=0;i<braceindent;i++) printf("{ "); for (i=0;i<bracketindent;i++) printf("[ "); printf("%s\n",tok.str.c_str());*/ break; case '0': if (startend) intvl.end=tok.n; else intvl.start=tok.n; /*for (i=0;i<braceindent;i++) printf("{ "); for (i=0;i<bracketindent;i++) printf("[ "); printf("%d\n",tok.n);*/ break; } } fclose(ancestryfile); } else fprintf(stderr,"%s: could not open file\n",ancestryname); }
STATIC int readtoken1(int firstc, char const *syntax, char *eofmark, int striptabs) { int c = firstc; char *out; int len; char line[EOFMARKLEN + 1]; struct nodelist *bqlist; int quotef; int dblquote; int varnest; /* levels of variables expansion */ int arinest; /* levels of arithmetic expansion */ int parenlevel; /* levels of parens in arithmetic */ int oldstyle; char const *prevsyntax; /* syntax before arithmetic */ int synentry; #if __GNUC__ /* Avoid longjmp clobbering */ (void) &out; (void) "ef; (void) &dblquote; (void) &varnest; (void) &arinest; (void) &parenlevel; (void) &oldstyle; (void) &prevsyntax; (void) &syntax; (void) &synentry; #endif startlinno = plinno; dblquote = 0; if (syntax == DQSYNTAX) dblquote = 1; quotef = 0; bqlist = NULL; varnest = 0; arinest = 0; parenlevel = 0; STARTSTACKSTR(out); loop: { /* for each line, until end of word */ CHECKEND(); /* set c to PEOF if at end of here document */ for (;;) { /* until end of line or end of word */ CHECKSTRSPACE(3, out); /* permit 3 calls to USTPUTC */ synentry = syntax[c]; switch(synentry) { case CNL: /* '\n' */ if (syntax == BASESYNTAX) goto endword; /* exit outer loop */ USTPUTC(c, out); plinno++; if (doprompt) setprompt(2); else setprompt(0); c = pgetc(); goto loop; /* continue outer loop */ case CWORD: USTPUTC(c, out); break; case CCTL: if (eofmark == NULL || dblquote) USTPUTC(CTLESC, out); USTPUTC(c, out); break; case CBACK: /* backslash */ c = pgetc(); if (c == PEOF) { USTPUTC('\\', out); pungetc(); } else if (c == '\n') { if (doprompt) setprompt(2); else setprompt(0); } else { if (dblquote && c != '\\' && c != '`' && c != '$' && (c != '"' || eofmark != NULL)) USTPUTC('\\', out); if (SQSYNTAX[c] == CCTL) USTPUTC(CTLESC, out); else if (eofmark == NULL) USTPUTC(CTLQUOTEMARK, out); USTPUTC(c, out); quotef++; } break; case CSQUOTE: if (eofmark == NULL) USTPUTC(CTLQUOTEMARK, out); syntax = SQSYNTAX; break; case CDQUOTE: if (eofmark == NULL) USTPUTC(CTLQUOTEMARK, out); syntax = DQSYNTAX; dblquote = 1; break; case CENDQUOTE: if (eofmark != NULL && arinest == 0 && varnest == 0) { USTPUTC(c, out); } else { if (arinest) { syntax = ARISYNTAX; dblquote = 0; } else if (eofmark == NULL) { syntax = BASESYNTAX; dblquote = 0; } quotef++; } break; case CVAR: /* '$' */ PARSESUB(); /* parse substitution */ break; case CENDVAR: /* '}' */ if (varnest > 0) { varnest--; USTPUTC(CTLENDVAR, out); } else { USTPUTC(c, out); } break; case CLP: /* '(' in arithmetic */ parenlevel++; USTPUTC(c, out); break; case CRP: /* ')' in arithmetic */ if (parenlevel > 0) { USTPUTC(c, out); --parenlevel; } else { if (pgetc() == ')') { if (--arinest == 0) { USTPUTC(CTLENDARI, out); syntax = prevsyntax; if (syntax == DQSYNTAX) dblquote = 1; else dblquote = 0; } else USTPUTC(')', out); } else { /* * unbalanced parens * (don't 2nd guess - no error) */ pungetc(); USTPUTC(')', out); } } break; case CBQUOTE: /* '`' */ PARSEBACKQOLD(); break; case CEOF: goto endword; /* exit outer loop */ default: if (varnest == 0) goto endword; /* exit outer loop */ USTPUTC(c, out); } c = pgetc_macro(); } } endword: if (syntax == ARISYNTAX) synerror("Missing '))'"); if (syntax != BASESYNTAX && ! parsebackquote && eofmark == NULL) synerror("Unterminated quoted string"); if (varnest != 0) { startlinno = plinno; synerror("Missing '}'"); } USTPUTC('\0', out); len = out - stackblock(); out = stackblock(); if (eofmark == NULL) { if ((c == '>' || c == '<') && quotef == 0 && len <= 2 && (*out == '\0' || is_digit(*out))) { PARSEREDIR(); return lasttoken = TREDIR; } else { pungetc(); } } quoteflag = quotef; backquotelist = bqlist; grabstackblock(len); wordtext = out; return lasttoken = TWORD; /* end of readtoken routine */ /* * Check to see whether we are at the end of the here document. When this * is called, c is set to the first character of the next input line. If * we are at the end of the here document, this routine sets the c to PEOF. */ checkend: { if (eofmark) { if (striptabs) { while (c == '\t') c = pgetc(); } if (c == *eofmark) { if (pfgets(line, sizeof line) != NULL) { char *p, *q; p = line; for (q = eofmark + 1 ; *q && *p == *q ; p++, q++); if (*p == '\n' && *q == '\0') { c = PEOF; plinno++; needprompt = doprompt; } else { pushstring(line, strlen(line), NULL); } } } } goto checkend_return; } /* * Parse a redirection operator. The variable "out" points to a string * specifying the fd to be redirected. The variable "c" contains the * first character of the redirection operator. */ parseredir: { char fd = *out; union node *np; np = (union node *)stalloc(sizeof (struct nfile)); if (c == '>') { np->nfile.fd = 1; c = pgetc(); if (c == '>') np->type = NAPPEND; else if (c == '&') np->type = NTOFD; else if (c == '|') np->type = NCLOBBER; else { np->type = NTO; pungetc(); } } else { /* c == '<' */ np->nfile.fd = 0; c = pgetc(); if (c == '<') { if (sizeof (struct nfile) != sizeof (struct nhere)) { np = (union node *)stalloc(sizeof (struct nhere)); np->nfile.fd = 0; } np->type = NHERE; heredoc = (struct heredoc *)stalloc(sizeof (struct heredoc)); heredoc->here = np; if ((c = pgetc()) == '-') { heredoc->striptabs = 1; } else { heredoc->striptabs = 0; pungetc(); } } else if (c == '&') np->type = NFROMFD; else if (c == '>') np->type = NFROMTO; else { np->type = NFROM; pungetc(); } } if (fd != '\0') np->nfile.fd = digit_val(fd); redirnode = np; goto parseredir_return; } /* * Parse a substitution. At this point, we have read the dollar sign * and nothing else. */ parsesub: { int subtype; int typeloc; int flags; char *p; #ifndef GDB_HACK static const char types[] = "}-+?="; #endif int bracketed_name = 0; /* used to handle ${[0-9]*} variables */ c = pgetc(); if (c != '(' && c != '{' && !is_name(c) && !is_special(c)) { USTPUTC('$', out); pungetc(); } else if (c == '(') { /* $(command) or $((arith)) */ if (pgetc() == '(') { PARSEARITH(); } else { pungetc(); PARSEBACKQNEW(); } } else { USTPUTC(CTLVAR, out); typeloc = out - stackblock(); USTPUTC(VSNORMAL, out); subtype = VSNORMAL; if (c == '{') { bracketed_name = 1; c = pgetc(); if (c == '#') { if ((c = pgetc()) == '}') c = '#'; else subtype = VSLENGTH; } else subtype = 0; } if (is_name(c)) { do { STPUTC(c, out); c = pgetc(); } while (is_in_name(c)); } else if (is_digit(c)) { if (bracketed_name) { do { STPUTC(c, out); c = pgetc(); } while (is_digit(c)); } else { STPUTC(c, out); c = pgetc(); } } else { if (! is_special(c)) badsub: synerror("Bad substitution"); USTPUTC(c, out); c = pgetc(); } STPUTC('=', out); flags = 0; if (subtype == 0) { switch (c) { case ':': flags = VSNUL; c = pgetc(); /*FALLTHROUGH*/ default: p = strchr(types, c); if (p == NULL) goto badsub; subtype = p - types + VSNORMAL; break; case '%': case '#': { int cc = c; subtype = c == '#' ? VSTRIMLEFT : VSTRIMRIGHT; c = pgetc(); if (c == cc) subtype++; else pungetc(); break; } } } else { pungetc(); } if (subtype != VSLENGTH && (dblquote || arinest)) flags |= VSQUOTE; *(stackblock() + typeloc) = subtype | flags; if (subtype != VSNORMAL) varnest++; } goto parsesub_return; } /* * Called to parse command substitutions. Newstyle is set if the command * is enclosed inside $(...); nlpp is a pointer to the head of the linked * list of commands (passed by reference), and savelen is the number of * characters on the top of the stack which must be preserved. */ parsebackq: { struct nodelist **nlpp; int savepbq; union node *n; char *volatile str; struct jmploc jmploc; struct jmploc *volatile savehandler; int savelen; int saveprompt; #if __GNUC__ /* Avoid longjmp clobbering */ (void) &saveprompt; #endif savepbq = parsebackquote; if (setjmp(jmploc.loc)) { if (str) ckfree(str); parsebackquote = 0; handler = savehandler; longjmp(handler->loc, 1); } INTOFF; str = NULL; savelen = out - stackblock(); if (savelen > 0) { str = ckmalloc(savelen); memcpy(str, stackblock(), savelen); } savehandler = handler; handler = &jmploc; INTON; if (oldstyle) { /* We must read until the closing backquote, giving special treatment to some slashes, and then push the string and reread it as input, interpreting it normally. */ char *out; int c; int savelen; char *str; STARTSTACKSTR(out); for (;;) { if (needprompt) { setprompt(2); needprompt = 0; } switch (c = pgetc()) { case '`': goto done; case '\\': if ((c = pgetc()) == '\n') { plinno++; if (doprompt) setprompt(2); else setprompt(0); /* * If eating a newline, avoid putting * the newline into the new character * stream (via the STPUTC after the * switch). */ continue; } if (c != '\\' && c != '`' && c != '$' && (!dblquote || c != '"')) STPUTC('\\', out); break; case '\n': plinno++; needprompt = doprompt; break; case PEOF: startlinno = plinno; synerror("EOF in backquote substitution"); break; default: break; } STPUTC(c, out); } done: STPUTC('\0', out); savelen = out - stackblock(); if (savelen > 0) { str = ckmalloc(savelen); memcpy(str, stackblock(), savelen); setinputstring(str, 1); } } nlpp = &bqlist; while (*nlpp) nlpp = &(*nlpp)->next; *nlpp = (struct nodelist *)stalloc(sizeof (struct nodelist)); (*nlpp)->next = NULL; parsebackquote = oldstyle; if (oldstyle) { saveprompt = doprompt; doprompt = 0; } n = list(0); if (oldstyle) doprompt = saveprompt; else { if (readtoken() != TRP) synexpect(TRP); } (*nlpp)->n = n; if (oldstyle) { /* * Start reading from old file again, ignoring any pushed back * tokens left from the backquote parsing */ popfile(); tokpushback = 0; } while (stackblocksize() <= savelen) growstackblock(); STARTSTACKSTR(out); if (str) { memcpy(out, str, savelen); STADJUST(savelen, out); INTOFF; ckfree(str); str = NULL; INTON; } parsebackquote = savepbq; handler = savehandler; if (arinest || dblquote) USTPUTC(CTLBACKQ | CTLQUOTE, out); else USTPUTC(CTLBACKQ, out); if (oldstyle) goto parsebackq_oldreturn; else goto parsebackq_newreturn; } /* * Parse an arithmetic expansion (indicate start of one and set state) */ parsearith: { if (++arinest == 1) { prevsyntax = syntax; syntax = ARISYNTAX; USTPUTC(CTLARI, out); if (dblquote) USTPUTC('"',out); else USTPUTC(' ',out); } else { /* * we collapse embedded arithmetic expansion to * parenthesis, which should be equivalent */ USTPUTC('(', out); } goto parsearith_return; } } /* end of readtoken */
STATIC union node * simplecmd(union node **rpp, union node *redir) { union node *args, **app; union node **orig_rpp = rpp; union node *n = NULL, *n2; int negate = 0; /* If we don't have any redirections already, then we must reset */ /* rpp to be the address of the local redir variable. */ if (redir == 0) rpp = &redir; args = NULL; app = &args; /* * We save the incoming value, because we need this for shell * functions. There can not be a redirect or an argument between * the function name and the open parenthesis. */ orig_rpp = rpp; while (readtoken() == TNOT) { TRACE(("command: TNOT recognized\n")); negate = !negate; } tokpushback++; for (;;) { if (readtoken() == TWORD) { n = (union node *)stalloc(sizeof (struct narg)); n->type = NARG; n->narg.text = wordtext; n->narg.backquote = backquotelist; *app = n; app = &n->narg.next; } else if (lasttoken == TREDIR) { *rpp = n = redirnode; rpp = &n->nfile.next; parsefname(); /* read name of redirection file */ } else if (lasttoken == TLP && app == &args->narg.next && rpp == orig_rpp) { /* We have a function */ if (readtoken() != TRP) synexpect(TRP); #ifdef notdef if (! goodname(n->narg.text)) synerror("Bad function name"); #endif n->type = NDEFUN; n->narg.next = command(); goto checkneg; } else { tokpushback++; break; } } *app = NULL; *rpp = NULL; n = (union node *)stalloc(sizeof (struct ncmd)); n->type = NCMD; n->ncmd.backgnd = 0; n->ncmd.args = args; n->ncmd.redirect = redir; checkneg: if (negate) { n2 = (union node *)stalloc(sizeof (struct nnot)); n2->type = NNOT; n2->nnot.com = n; return n2; } else return n; }
STATIC union node * command(void) { union node *n1, *n2; union node *ap, **app; union node *cp, **cpp; union node *redir, **rpp; int t, negate = 0; checkkwd = 2; redir = NULL; n1 = NULL; rpp = &redir; /* Check for redirection which may precede command */ while (readtoken() == TREDIR) { *rpp = n2 = redirnode; rpp = &n2->nfile.next; parsefname(); } tokpushback++; while (readtoken() == TNOT) { TRACE(("command: TNOT recognized\n")); negate = !negate; } tokpushback++; switch (readtoken()) { case TIF: n1 = (union node *)stalloc(sizeof (struct nif)); n1->type = NIF; if ((n1->nif.test = list(0)) == NULL) synexpect(-1); if (readtoken() != TTHEN) synexpect(TTHEN); n1->nif.ifpart = list(0); n2 = n1; while (readtoken() == TELIF) { n2->nif.elsepart = (union node *)stalloc(sizeof (struct nif)); n2 = n2->nif.elsepart; n2->type = NIF; if ((n2->nif.test = list(0)) == NULL) synexpect(-1); if (readtoken() != TTHEN) synexpect(TTHEN); n2->nif.ifpart = list(0); } if (lasttoken == TELSE) n2->nif.elsepart = list(0); else { n2->nif.elsepart = NULL; tokpushback++; } if (readtoken() != TFI) synexpect(TFI); checkkwd = 1; break; case TWHILE: case TUNTIL: { int got; n1 = (union node *)stalloc(sizeof (struct nbinary)); n1->type = (lasttoken == TWHILE)? NWHILE : NUNTIL; if ((n1->nbinary.ch1 = list(0)) == NULL) synexpect(-1); if ((got=readtoken()) != TDO) { TRACE(("expecting DO got %s %s\n", tokname[got], got == TWORD ? wordtext : "")); synexpect(TDO); } n1->nbinary.ch2 = list(0); if (readtoken() != TDONE) synexpect(TDONE); checkkwd = 1; break; } case TFOR: if (readtoken() != TWORD || quoteflag || ! goodname(wordtext)) synerror("Bad for loop variable"); n1 = (union node *)stalloc(sizeof (struct nfor)); n1->type = NFOR; n1->nfor.var = wordtext; if (readtoken() == TWORD && ! quoteflag && equal(wordtext, "in")) { app = ≈ while (readtoken() == TWORD) { n2 = (union node *)stalloc(sizeof (struct narg)); n2->type = NARG; n2->narg.text = wordtext; n2->narg.backquote = backquotelist; *app = n2; app = &n2->narg.next; } *app = NULL; n1->nfor.args = ap; if (lasttoken != TNL && lasttoken != TSEMI) synexpect(-1); } else { #ifndef GDB_HACK static const char argvars[5] = {CTLVAR, VSNORMAL|VSQUOTE, '@', '=', '\0'}; #endif n2 = (union node *)stalloc(sizeof (struct narg)); n2->type = NARG; n2->narg.text = (char *)argvars; n2->narg.backquote = NULL; n2->narg.next = NULL; n1->nfor.args = n2; /* * Newline or semicolon here is optional (but note * that the original Bourne shell only allowed NL). */ if (lasttoken != TNL && lasttoken != TSEMI) tokpushback++; } checkkwd = 2; if ((t = readtoken()) == TDO) t = TDONE; else if (t == TBEGIN) t = TEND; else synexpect(-1); n1->nfor.body = list(0); if (readtoken() != t) synexpect(t); checkkwd = 1; break; case TCASE: n1 = (union node *)stalloc(sizeof (struct ncase)); n1->type = NCASE; if (readtoken() != TWORD) synexpect(TWORD); n1->ncase.expr = n2 = (union node *)stalloc(sizeof (struct narg)); n2->type = NARG; n2->narg.text = wordtext; n2->narg.backquote = backquotelist; n2->narg.next = NULL; while (readtoken() == TNL); if (lasttoken != TWORD || ! equal(wordtext, "in")) synerror("expecting \"in\""); cpp = &n1->ncase.cases; noaliases = 1; /* turn off alias expansion */ checkkwd = 2, readtoken(); while (lasttoken != TESAC) { *cpp = cp = (union node *)stalloc(sizeof (struct nclist)); cp->type = NCLIST; app = &cp->nclist.pattern; if (lasttoken == TLP) readtoken(); for (;;) { *app = ap = (union node *)stalloc(sizeof (struct narg)); ap->type = NARG; ap->narg.text = wordtext; ap->narg.backquote = backquotelist; if (checkkwd = 2, readtoken() != TPIPE) break; app = &ap->narg.next; readtoken(); } ap->narg.next = NULL; if (lasttoken != TRP) noaliases = 0, synexpect(TRP); cp->nclist.body = list(0); checkkwd = 2; if ((t = readtoken()) != TESAC) { if (t != TENDCASE) noaliases = 0, synexpect(TENDCASE); else checkkwd = 2, readtoken(); } cpp = &cp->nclist.next; } noaliases = 0; /* reset alias expansion */ *cpp = NULL; checkkwd = 1; break; case TLP: n1 = (union node *)stalloc(sizeof (struct nredir)); n1->type = NSUBSHELL; n1->nredir.n = list(0); n1->nredir.redirect = NULL; if (readtoken() != TRP) synexpect(TRP); checkkwd = 1; break; case TBEGIN: n1 = list(0); if (readtoken() != TEND) synexpect(TEND); checkkwd = 1; break; /* Handle an empty command like other simple commands. */ case TSEMI: case TAND: case TOR: /* * An empty command before a ; doesn't make much sense, and * should certainly be disallowed in the case of `if ;'. */ if (!redir) synexpect(-1); case TNL: case TEOF: case TWORD: case TRP: tokpushback++; n1 = simplecmd(rpp, redir); goto checkneg; default: synexpect(-1); } /* Now check for redirection which may follow command */ while (readtoken() == TREDIR) { *rpp = n2 = redirnode; rpp = &n2->nfile.next; parsefname(); } tokpushback++; *rpp = NULL; if (redir) { if (n1->type != NSUBSHELL) { n2 = (union node *)stalloc(sizeof (struct nredir)); n2->type = NREDIR; n2->nredir.n = n1; n1 = n2; } n1->nredir.redirect = redir; } checkneg: if (negate) { n2 = (union node *)stalloc(sizeof (struct nnot)); n2->type = NNOT; n2->nnot.com = n1; return n2; } else return n1; }
STATIC union node * list(int nlflag) { union node *n1, *n2, *n3; int tok; checkkwd = 2; if (nlflag == 0 && tokendlist[peektoken()]) return NULL; n1 = NULL; for (;;) { n2 = andor(); tok = readtoken(); if (tok == TBACKGND) { if (n2->type == NCMD || n2->type == NPIPE) { n2->ncmd.backgnd = 1; } else if (n2->type == NREDIR) { n2->type = NBACKGND; } else { n3 = (union node *)stalloc(sizeof (struct nredir)); n3->type = NBACKGND; n3->nredir.n = n2; n3->nredir.redirect = NULL; n2 = n3; } } if (n1 == NULL) { n1 = n2; } else { n3 = (union node *)stalloc(sizeof (struct nbinary)); n3->type = NSEMI; n3->nbinary.ch1 = n1; n3->nbinary.ch2 = n2; n1 = n3; } switch (tok) { case TBACKGND: case TSEMI: tok = readtoken(); /* FALLTHROUGH */ case TNL: if (tok == TNL) { parseheredoc(); if (nlflag) return n1; } else { tokpushback++; } checkkwd = 2; if (tokendlist[peektoken()]) return n1; break; case TEOF: if (heredoclist) parseheredoc(); else pungetc(); /* push back EOF on input */ return n1; default: if (nlflag) synexpect(-1); tokpushback++; return n1; } } }
char * _iodbcdm_getkeyvalinstr ( char *cnstr, int cnlen, char *keywd, char *value, int size) { char token[1024] = {'\0'}; int flag = 0; if (cnstr == NULL || value == NULL || keywd == NULL || size < 1) { return NULL; } if (cnlen == SQL_NTS) { cnlen = STRLEN (cnstr); } if (cnlen <= 0) { return NULL; } for (;;) { cnstr = readtoken (cnstr, token); if (*token == '\0') { break; } if (STREQ (token, ";")) { flag = 0; continue; } switch (flag) { case 0: if (upper_strneq (token, keywd, strlen (keywd))) { flag = 1; } break; case 1: if (STREQ (token, "=")) { flag = 2; } break; case 2: if (size < strlen (token) + 1) { return NULL; } STRNCPY (value, token, size); return value; default: break; } } return NULL; }
/* * read odbc init file to resolve the value of specified * key from named or defaulted dsn section */ char * _iodbcdm_getkeyvalbydsn ( char *dsn, int dsnlen, char *keywd, char *value, int size) { char buf[1024]; char dsntk[SQL_MAX_DSN_LENGTH + 3] = {'[', '\0'}; char token[1024]; /* large enough */ FILE *file; char pathbuf[1024]; char *path; #define DSN_NOMATCH 0 #define DSN_NAMED 1 #define DSN_DEFAULT 2 int dsnid = DSN_NOMATCH; int defaultdsn = DSN_NOMATCH; if (dsn == NULL || *dsn == 0) { dsn = "default"; dsnlen = STRLEN (dsn); } if (dsnlen == SQL_NTS) { dsnlen = STRLEN (dsn); } if (dsnlen <= 0 || keywd == NULL || buf == 0 || size <= 0) { return NULL; } if (dsnlen > sizeof (dsntk) - 2) { return NULL; } value[0] = '\0'; STRNCAT (dsntk, dsn, dsnlen); STRCAT (dsntk, "]"); dsnlen = dsnlen + 2; path = _iodbcdm_getinifile (pathbuf, sizeof (pathbuf)); if (path == NULL) { return NULL; } file = (FILE *) fopen (path, "r"); if (file == NULL) { return NULL; } for (;;) { char *str; str = fgets (buf, sizeof (buf), file); if (str == NULL) { break; } if (*str == '[') { if (upper_strneq (str, "[default]", STRLEN ("[default]"))) { /* we only read first dsn default dsn * section (as well as named dsn). */ if (defaultdsn == DSN_NOMATCH) { dsnid = DSN_DEFAULT; defaultdsn = DSN_DEFAULT; } else { dsnid = DSN_NOMATCH; } continue; } else if (upper_strneq (str, dsntk, dsnlen)) { dsnid = DSN_NAMED; } else { dsnid = DSN_NOMATCH; } continue; } else if (dsnid == DSN_NOMATCH) { continue; } str = readtoken (str, token); if (upper_strneq (keywd, token, STRLEN (keywd))) { str = readtoken (str, token); if (!STREQ (token, "=")) /* something other than = */ { continue; } str = readtoken (str, token); if (STRLEN (token) > size - 1) { break; } STRNCPY (value, token, size); /* copy the value(i.e. next token) to buf */ if (dsnid != DSN_DEFAULT) { break; } } } fclose (file); return (*value) ? value : NULL; }
struct imaptoken *nexttoken(void) { return (readtoken(1)); }
struct imaptoken *nexttoken_nouc(void) { return (readtoken(0)); }
STATIC union node * command() { union node *n1, *n2; union node *ap, **app; union node *cp, **cpp; union node *redir, **rpp; int t; checkkwd(); switch (readtoken()) { case TIF: n1 = (union node *)stalloc(sizeof (struct nif)); n1->type = NIF; n1->nif.test = list(0); if (readtoken() != TTHEN) synexpect(TTHEN); n1->nif.ifpart = list(0); n2 = n1; while (readtoken() == TELIF) { n2->nif.elsepart = (union node *)stalloc(sizeof (struct nif)); n2 = n2->nif.elsepart; n2->type = NIF; n2->nif.test = list(0); if (readtoken() != TTHEN) synexpect(TTHEN); n2->nif.ifpart = list(0); } if (lasttoken == TELSE) n2->nif.elsepart = list(0); else { n2->nif.elsepart = NULL; tokpushback++; } if (readtoken() != TFI) synexpect(TFI); break; case TWHILE: case TUNTIL: n1 = (union node *)stalloc(sizeof (struct nbinary)); n1->type = (lasttoken == TWHILE)? NWHILE : NUNTIL; n1->nbinary.ch1 = list(0); if (readtoken() != TDO) synexpect(TDO); n1->nbinary.ch2 = list(0); if (readtoken() != TDONE) synexpect(TDONE); break; case TFOR: if (readtoken() != TWORD || quoteflag || ! goodname(wordtext)) synerror("Bad for loop variable"); n1 = (union node *)stalloc(sizeof (struct nfor)); n1->type = NFOR; n1->nfor.var = wordtext; if (readtoken() == TWORD && ! quoteflag && equal(wordtext, "in")) { app = ≈ while (readtoken() == TWORD) { n2 = (union node *)stalloc(sizeof (struct narg)); n2->type = NARG; n2->narg.text = wordtext; n2->narg.backquote = backquotelist; *app = n2; app = &n2->narg.next; } *app = NULL; n1->nfor.args = ap; } else { #ifndef GDB_HACK static const char argvars[5] = {CTLVAR, VSNORMAL|VSQUOTE, '@', '=', '\0'}; #endif n2 = (union node *)stalloc(sizeof (struct narg)); n2->type = NARG; n2->narg.text = (char *)argvars; n2->narg.backquote = NULL; n2->narg.next = NULL; n1->nfor.args = n2; } if (lasttoken != TNL && lasttoken != TSEMI) synexpect(-1); checkkwd(); if ((t = readtoken()) == TDO) t = TDONE; else if (t == TBEGIN) t = TEND; else synexpect(-1); n1->nfor.body = list(0); if (readtoken() != t) synexpect(t); break; case TCASE: n1 = (union node *)stalloc(sizeof (struct ncase)); n1->type = NCASE; if (readtoken() != TWORD) synexpect(TWORD); n1->ncase.expr = n2 = (union node *)stalloc(sizeof (struct narg)); n2->type = NARG; n2->narg.text = wordtext; n2->narg.backquote = backquotelist; n2->narg.next = NULL; while (readtoken() == TNL); if (lasttoken != TWORD || ! equal(wordtext, "in")) synerror("expecting \"in\""); cpp = &n1->ncase.cases; while (checkkwd(), readtoken() == TWORD) { *cpp = cp = (union node *)stalloc(sizeof (struct nclist)); cp->type = NCLIST; app = &cp->nclist.pattern; for (;;) { *app = ap = (union node *)stalloc(sizeof (struct narg)); ap->type = NARG; ap->narg.text = wordtext; ap->narg.backquote = backquotelist; if (readtoken() != TPIPE) break; app = &ap->narg.next; if (readtoken() != TWORD) synexpect(TWORD); } ap->narg.next = NULL; if (lasttoken != TRP) synexpect(TRP); cp->nclist.body = list(0); if ((t = readtoken()) == TESAC) tokpushback++; else if (t != TENDCASE) synexpect(TENDCASE); cpp = &cp->nclist.next; } *cpp = NULL; if (lasttoken != TESAC) synexpect(TESAC); break; case TLP: n1 = (union node *)stalloc(sizeof (struct nredir)); n1->type = NSUBSHELL; n1->nredir.n = list(0); n1->nredir.redirect = NULL; if (readtoken() != TRP) synexpect(TRP); break; case TBEGIN: n1 = list(0); if (readtoken() != TEND) synexpect(TEND); break; case TWORD: case TREDIR: tokpushback++; return simplecmd(); default: synexpect(-1); } /* Now check for redirection which may follow command */ rpp = &redir; while (readtoken() == TREDIR) { *rpp = n2 = redirnode; rpp = &n2->nfile.next; parsefname(); } tokpushback++; *rpp = NULL; if (redir) { if (n1->type != NSUBSHELL) { n2 = (union node *)stalloc(sizeof (struct nredir)); n2->type = NREDIR; n2->nredir.n = n1; n1 = n2; } n1->nredir.redirect = redir; } return n1; }