void yylex(void) { if (tok == LEXERR) return; do tok = gettok(); while (tok != ENDINPUT && exalias()); if (tok == NEWLIN || tok == ENDINPUT) { while (hdocs) { struct heredocs *next = hdocs->next; char *name; hwbegin(0); cmdpush(hdocs->type == REDIR_HEREDOC ? CS_HEREDOC : CS_HEREDOCD); STOPHIST name = gethere(hdocs->str, hdocs->type); ALLOWHIST cmdpop(); hwend(); setheredoc(hdocs->pc, REDIR_HERESTR, name); zfree(hdocs, sizeof(struct heredocs)); hdocs = next; } } if (tok != NEWLIN) isnewlin = 0; else isnewlin = (inbufct) ? -1 : 1; if (tok == SEMI || tok == NEWLIN) tok = SEPER; }
void zshlex(void) { if (tok == LEXERR) return; do { if (inrepeat_) ++inrepeat_; if (inrepeat_ == 3 && isset(SHORTLOOPS)) incmdpos = 1; tok = gettok(); } while (tok != ENDINPUT && exalias()); nocorrect &= 1; if (tok == NEWLIN || tok == ENDINPUT) { while (hdocs) { struct heredocs *next = hdocs->next; char *doc, *munged_term; hwbegin(0); cmdpush(hdocs->type == REDIR_HEREDOC ? CS_HEREDOC : CS_HEREDOCD); munged_term = dupstring(hdocs->str); STOPHIST doc = gethere(&munged_term, hdocs->type); ALLOWHIST cmdpop(); hwend(); if (!doc) { zerr("here document too large"); while (hdocs) { next = hdocs->next; zfree(hdocs, sizeof(struct heredocs)); hdocs = next; } tok = LEXERR; break; } setheredoc(hdocs->pc, REDIR_HERESTR, doc, hdocs->str, munged_term); zfree(hdocs, sizeof(struct heredocs)); hdocs = next; } } if (tok != NEWLIN) isnewlin = 0; else isnewlin = (inbufct) ? -1 : 1; if (tok == SEMI || (tok == NEWLIN && !(lexflags & LEXFLAGS_NEWLINE))) tok = SEPER; }
static enum lextok gettok(void) { int c, d; int peekfd = -1; enum lextok peek; beginning: tokstr = NULL; while (iblank(c = hgetc()) && !lexstop); toklineno = lineno; if (lexstop) return (errflag) ? LEXERR : ENDINPUT; isfirstln = 0; if ((lexflags & LEXFLAGS_ZLE)) wordbeg = inbufct - (qbang && c == bangchar); hwbegin(-1-(qbang && c == bangchar)); /* word includes the last character read and possibly \ before ! */ if (dbparens) { lexbuf.len = 0; lexbuf.ptr = tokstr = (char *) hcalloc(lexbuf.siz = LEX_HEAP_SIZE); hungetc(c); cmdpush(CS_MATH); c = dquote_parse(infor ? ';' : ')', 0); cmdpop(); *lexbuf.ptr = '\0'; if (!c && infor) { infor--; return DINPAR; } if (c || (c = hgetc()) != ')') { hungetc(c); return LEXERR; } dbparens = 0; return DOUTPAR; } else if (idigit(c)) { /* handle 1< foo */ d = hgetc(); if(d == '&') { d = hgetc(); if(d == '>') { peekfd = c - '0'; hungetc('>'); c = '&'; } else { hungetc(d); lexstop = 0; hungetc('&'); } } else if (d == '>' || d == '<') { peekfd = c - '0'; c = d; } else { hungetc(d); lexstop = 0; } } /* chars in initial position in word */ /* * Handle comments. There are some special cases when this * is not normal command input: lexflags implies we are examining * a line lexically without it being used for normal command input. */ if (c == hashchar && !nocomments && (isset(INTERACTIVECOMMENTS) || ((!lexflags || (lexflags & LEXFLAGS_COMMENTS)) && !expanding && (!interact || unset(SHINSTDIN) || strin)))) { /* History is handled here to prevent extra * * newlines being inserted into the history. */ if (lexflags & LEXFLAGS_COMMENTS_KEEP) { lexbuf.len = 0; lexbuf.ptr = tokstr = (char *)hcalloc(lexbuf.siz = LEX_HEAP_SIZE); add(c); } hwend(); while ((c = ingetc()) != '\n' && !lexstop) { hwaddc(c); addtoline(c); if (lexflags & LEXFLAGS_COMMENTS_KEEP) add(c); } if (errflag) peek = LEXERR; else { if (lexflags & LEXFLAGS_COMMENTS_KEEP) { *lexbuf.ptr = '\0'; if (!lexstop) hungetc(c); peek = STRING; } else { hwend(); hwbegin(0); hwaddc('\n'); addtoline('\n'); /* * If splitting a line and removing comments, * we don't want a newline token since it's * treated specially. */ if ((lexflags & LEXFLAGS_COMMENTS_STRIP) && lexstop) peek = ENDINPUT; else peek = NEWLIN; } } return peek; } switch (lexact1[STOUC(c)]) { case LX1_BKSLASH: d = hgetc(); if (d == '\n') goto beginning; hungetc(d); lexstop = 0; break; case LX1_NEWLIN: return NEWLIN; case LX1_SEMI: d = hgetc(); if(d == ';') return DSEMI; else if(d == '&') return SEMIAMP; else if (d == '|') return SEMIBAR; hungetc(d); lexstop = 0; return SEMI; case LX1_AMPER: d = hgetc(); if (d == '&') return DAMPER; else if (d == '!' || d == '|') return AMPERBANG; else if (d == '>') { tokfd = peekfd; d = hgetc(); if (d == '!' || d == '|') return OUTANGAMPBANG; else if (d == '>') { d = hgetc(); if (d == '!' || d == '|') return DOUTANGAMPBANG; hungetc(d); lexstop = 0; return DOUTANGAMP; } hungetc(d); lexstop = 0; return AMPOUTANG; } hungetc(d); lexstop = 0; return AMPER; case LX1_BAR: d = hgetc(); if (d == '|') return DBAR; else if (d == '&') return BARAMP; hungetc(d); lexstop = 0; return BAR; case LX1_INPAR: d = hgetc(); if (d == '(') { if (infor) { dbparens = 1; return DINPAR; } if (incmdpos || (isset(SHGLOB) && !isset(KSHGLOB))) { lexbuf.len = 0; lexbuf.ptr = tokstr = (char *) hcalloc(lexbuf.siz = LEX_HEAP_SIZE); switch (cmd_or_math(CS_MATH)) { case CMD_OR_MATH_MATH: return DINPAR; case CMD_OR_MATH_CMD: /* * Not math, so we don't return the contents * as a string in this case. */ tokstr = NULL; return INPAR; case CMD_OR_MATH_ERR: /* * LEXFLAGS_ACTIVE means we came from bufferwords(), * so we treat as an incomplete math expression */ if (lexflags & LEXFLAGS_ACTIVE) tokstr = dyncat("((", tokstr ? tokstr : ""); /* fall through */ default: return LEXERR; } } } else if (d == ')') return INOUTPAR; hungetc(d); lexstop = 0; if (!(isset(SHGLOB) || incond == 1 || incmdpos)) break; return INPAR; case LX1_OUTPAR: return OUTPAR; case LX1_INANG: d = hgetc(); if (d == '(') { hungetc(d); lexstop = 0; unpeekfd: if(peekfd != -1) { hungetc(c); c = '0' + peekfd; } break; } if (d == '>') { peek = INOUTANG; } else if (d == '<') { int e = hgetc(); if (e == '(') { hungetc(e); hungetc(d); peek = INANG; } else if (e == '<') peek = TRINANG; else if (e == '-') peek = DINANGDASH; else { hungetc(e); lexstop = 0; peek = DINANG; } } else if (d == '&') { peek = INANGAMP; } else { hungetc(d); if(isnumglob()) goto unpeekfd; peek = INANG; } tokfd = peekfd; return peek; case LX1_OUTANG: d = hgetc(); if (d == '(') { hungetc(d); goto unpeekfd; } else if (d == '&') { d = hgetc(); if (d == '!' || d == '|') peek = OUTANGAMPBANG; else { hungetc(d); lexstop = 0; peek = OUTANGAMP; } } else if (d == '!' || d == '|') peek = OUTANGBANG; else if (d == '>') { d = hgetc(); if (d == '&') { d = hgetc(); if (d == '!' || d == '|') peek = DOUTANGAMPBANG; else { hungetc(d); lexstop = 0; peek = DOUTANGAMP; } } else if (d == '!' || d == '|') peek = DOUTANGBANG; else if (d == '(') { hungetc(d); hungetc('>'); peek = OUTANG; } else { hungetc(d); lexstop = 0; peek = DOUTANG; if (isset(HISTALLOWCLOBBER)) hwaddc('|'); } } else { hungetc(d); lexstop = 0; peek = OUTANG; if (!incond && isset(HISTALLOWCLOBBER)) hwaddc('|'); } tokfd = peekfd; return peek; } /* we've started a string, now get the * * rest of it, performing tokenization */ return gettokstr(c, 0); }
int exalias(void) { Reswd rw; hwend(); if (interact && isset(SHINSTDIN) && !strin && !incasepat && tok == STRING && !nocorrect && !(inbufflags & INP_ALIAS) && (isset(CORRECTALL) || (isset(CORRECT) && incmdpos))) spckword(&tokstr, 1, incmdpos, 1); if (!tokstr) { zshlextext = tokstrings[tok]; if (tok == NEWLIN) return 0; return checkalias(); } else { VARARR(char, copy, (strlen(tokstr) + 1)); if (has_token(tokstr)) { char *p, *t; zshlextext = p = copy; for (t = tokstr; (*p++ = itok(*t) ? ztokens[*t++ - Pound] : *t++);); } else zshlextext = tokstr; if ((lexflags & LEXFLAGS_ZLE) && !(inbufflags & INP_ALIAS)) { int zp = lexflags; gotword(); if ((zp & LEXFLAGS_ZLE) && !lexflags) { if (zshlextext == copy) zshlextext = tokstr; return 0; } } if (tok == STRING) { /* Check for an alias */ if ((zshlextext != copy || !isset(POSIXALIASES)) && checkalias()) { if (zshlextext == copy) zshlextext = tokstr; return 1; } /* Then check for a reserved word */ if ((incmdpos || (unset(IGNOREBRACES) && unset(IGNORECLOSEBRACES) && zshlextext[0] == '}' && !zshlextext[1])) && (rw = (Reswd) reswdtab->getnode(reswdtab, zshlextext))) { tok = rw->token; inrepeat_ = (tok == REPEAT); if (tok == DINBRACK) incond = 1; } else if (incond && !strcmp(zshlextext, "]]")) { tok = DOUTBRACK; incond = 0; } else if (incond == 1 && zshlextext[0] == '!' && !zshlextext[1]) tok = BANG; } inalmore = 0; if (zshlextext == copy) zshlextext = tokstr; } return 0; }
int gettok(void) { int c, d; int peekfd = -1, peek; beginning: tokstr = NULL; while (iblank(c = hgetc()) && !lexstop); if (lexstop) return (errflag) ? LEXERR : ENDINPUT; isfirstln = 0; wordbeg = inbufct - (qbang && c == bangchar); hwbegin(-1-(qbang && c == bangchar)); /* word includes the last character read and possibly \ before ! */ if (dbparens) { len = 0; bptr = tokstr = (char *) hcalloc(bsiz = 32); hungetc(c); cmdpush(CS_MATH); c = dquote_parse(infor ? ';' : ')', 0); cmdpop(); *bptr = '\0'; if (!c && infor) { infor--; return DINPAR; } if (c || (c = hgetc()) != ')') { hungetc(c); return LEXERR; } dbparens = 0; return DOUTPAR; } else if (idigit(c)) { /* handle 1< foo */ d = hgetc(); if(d == '&') { d = hgetc(); if(d == '>') { peekfd = c - '0'; hungetc('>'); c = '&'; } else { hungetc(d); lexstop = 0; hungetc('&'); } } else if (d == '>' || d == '<') { peekfd = c - '0'; c = d; } else { hungetc(d); lexstop = 0; } } /* chars in initial position in word */ if (c == hashchar && !nocomments && (isset(INTERACTIVECOMMENTS) || (!zleparse && !expanding && (!interact || unset(SHINSTDIN) || strin)))) { /* History is handled here to prevent extra * * newlines being inserted into the history. */ while ((c = ingetc()) != '\n' && !lexstop) { hwaddc(c); addtoline(c); } if (errflag) peek = LEXERR; else { hwend(); hwbegin(0); hwaddc('\n'); addtoline('\n'); peek = NEWLIN; } return peek; } switch (lexact1[STOUC(c)]) { case LX1_BKSLASH: d = hgetc(); if (d == '\n') goto beginning; hungetc(d); lexstop = 0; break; case LX1_NEWLIN: return NEWLIN; case LX1_SEMI: d = hgetc(); if(d == ';') return DSEMI; else if(d == '&') return SEMIAMP; hungetc(d); lexstop = 0; return SEMI; case LX1_AMPER: d = hgetc(); if (d == '&') return DAMPER; else if (d == '!' || d == '|') return AMPERBANG; else if (d == '>') { tokfd = peekfd; d = hgetc(); if (d == '!' || d == '|') return OUTANGAMPBANG; else if (d == '>') { d = hgetc(); if (d == '!' || d == '|') return DOUTANGAMPBANG; hungetc(d); lexstop = 0; return DOUTANGAMP; } hungetc(d); lexstop = 0; return AMPOUTANG; } hungetc(d); lexstop = 0; return AMPER; case LX1_BAR: d = hgetc(); if (d == '|') return DBAR; else if (d == '&') return BARAMP; hungetc(d); lexstop = 0; return BAR; case LX1_INPAR: d = hgetc(); if (d == '(') { if (infor) { dbparens = 1; return DINPAR; } if (incmdpos) { len = 0; bptr = tokstr = (char *) hcalloc(bsiz = 32); return cmd_or_math(CS_MATH) ? DINPAR : INPAR; } } else if (d == ')') return INOUTPAR; hungetc(d); lexstop = 0; if (!(incond == 1 || incmdpos)) break; return INPAR; case LX1_OUTPAR: return OUTPAR; case LX1_INANG: d = hgetc(); if (!incmdpos && d == '(') { hungetc(d); lexstop = 0; unpeekfd: if(peekfd != -1) { hungetc(c); c = '0' + peekfd; } break; } if (d == '>') { peek = INOUTANG; } else if (d == '<') { int e = hgetc(); if (e == '(') { hungetc(e); hungetc(d); peek = INANG; } else if (e == '<') peek = TRINANG; else if (e == '-') peek = DINANGDASH; else { hungetc(e); lexstop = 0; peek = DINANG; } } else if (d == '&') { peek = INANGAMP; } else { hungetc(d); if(isnumglob()) goto unpeekfd; peek = INANG; } tokfd = peekfd; return peek; case LX1_OUTANG: d = hgetc(); if (d == '(') { hungetc(d); goto unpeekfd; } else if (d == '&') { d = hgetc(); if (d == '!' || d == '|') peek = OUTANGAMPBANG; else { hungetc(d); lexstop = 0; peek = OUTANGAMP; } } else if (d == '!' || d == '|') peek = OUTANGBANG; else if (d == '>') { d = hgetc(); if (d == '&') { d = hgetc(); if (d == '!' || d == '|') peek = DOUTANGAMPBANG; else { hungetc(d); lexstop = 0; peek = DOUTANGAMP; } } else if (d == '!' || d == '|') peek = DOUTANGBANG; else if (d == '(') { hungetc(d); hungetc('>'); peek = OUTANG; } else { hungetc(d); lexstop = 0; peek = DOUTANG; if (isset(HISTALLOWCLOBBER)) hwaddc('|'); } } else { hungetc(d); lexstop = 0; peek = OUTANG; if (!incond && isset(HISTALLOWCLOBBER)) hwaddc('|'); } tokfd = peekfd; return peek; } /* we've started a string, now get the * * rest of it, performing tokenization */ return gettokstr(c, 0); }
int exalias(void) { Alias an; Reswd rw; hwend(); if (interact && isset(SHINSTDIN) && !strin && !incasepat && tok == STRING && !nocorrect && !(inbufflags & INP_ALIAS) && (isset(CORRECTALL) || (isset(CORRECT) && incmdpos))) spckword(&tokstr, 1, incmdpos, 1); if (!tokstr) { yytext = tokstrings[tok]; return 0; } else { VARARR(char, copy, (strlen(tokstr) + 1)); if (has_token(tokstr)) { char *p, *t; yytext = p = copy; for (t = tokstr; (*p++ = itok(*t) ? ztokens[*t++ - Pound] : *t++);); } else yytext = tokstr; if (zleparse && !(inbufflags & INP_ALIAS)) { int zp = zleparse; gotword(); if (zp == 1 && !zleparse) { if (yytext == copy) yytext = tokstr; return 0; } } if (tok == STRING) { /* Check for an alias */ if (!noaliases && isset(ALIASESOPT)) { char *suf; an = (Alias) aliastab->getnode(aliastab, yytext); if (an && !an->inuse && ((an->flags & ALIAS_GLOBAL) || incmdpos || inalmore)) { inpush(an->text, INP_ALIAS, an); if (an->text[0] == ' ') aliasspaceflag = 1; lexstop = 0; if (yytext == copy) yytext = tokstr; return 1; } if ((suf = strrchr(yytext, '.')) && suf[1] && suf > yytext && suf[-1] != Meta && (an = (Alias)sufaliastab->getnode(sufaliastab, suf+1)) && !an->inuse && incmdpos) { inpush(dupstring(yytext), INP_ALIAS, NULL); inpush(" ", INP_ALIAS, NULL); inpush(an->text, INP_ALIAS, an); lexstop = 0; if (yytext == copy) yytext = tokstr; return 1; } } /* Then check for a reserved word */ if ((incmdpos || (unset(IGNOREBRACES) && yytext[0] == '}' && !yytext[1])) && (rw = (Reswd) reswdtab->getnode(reswdtab, yytext))) { tok = rw->token; if (tok == DINBRACK) incond = 1; } else if (incond && !strcmp(yytext, "]]")) { tok = DOUTBRACK; incond = 0; } else if (incond == 1 && yytext[0] == '!' && !yytext[1]) tok = BANG; } inalmore = 0; if (yytext == copy) yytext = tokstr; } return 0; }