diff options
author | rsc <devnull@localhost> | 2007-03-26 12:02:41 +0000 |
---|---|---|
committer | rsc <devnull@localhost> | 2007-03-26 12:02:41 +0000 |
commit | c8f538425f4e92e1e438b9bd25cb08e250a93d5b (patch) | |
tree | d701abbcd4973d5b6909d104eefe521de70a4e1c /src/cmd/rc/lex.c | |
parent | 79049567a0fac8707ea3f2927403445bdb2394fa (diff) | |
download | plan9port-c8f538425f4e92e1e438b9bd25cb08e250a93d5b.tar.gz plan9port-c8f538425f4e92e1e438b9bd25cb08e250a93d5b.tar.bz2 plan9port-c8f538425f4e92e1e438b9bd25cb08e250a93d5b.zip |
sync with plan 9
Diffstat (limited to 'src/cmd/rc/lex.c')
-rw-r--r-- | src/cmd/rc/lex.c | 278 |
1 files changed, 166 insertions, 112 deletions
diff --git a/src/cmd/rc/lex.c b/src/cmd/rc/lex.c index b0e27eb3..36934832 100644 --- a/src/cmd/rc/lex.c +++ b/src/cmd/rc/lex.c @@ -4,11 +4,15 @@ #include "getflags.h" #include "fns.h" int getnext(void); -int wordchr(int c) + +int +wordchr(int c) { return !strchr("\n \t#;&|^$=`'{}()<>", c) && c!=EOF; } -int idchr(int c) + +int +idchr(int c) { /* * Formerly: @@ -17,127 +21,170 @@ int idchr(int c) */ return c>' ' && !strchr("!\"#$%&'()+,-./:;<=>?@[\\]^`{|}~", c); } -int future=EOF; -int doprompt=1; +int future = EOF; +int doprompt = 1; int inquote; +int incomm; /* * Look ahead in the input stream */ -int nextc(void){ - if(future==EOF) future=getnext(); + +int +nextc(void) +{ + if(future==EOF) + future = getnext(); return future; } /* * Consume the lookahead character. */ -int advance(void){ - int c=nextc(); - lastc=future; - future=EOF; + +int +advance(void) +{ + int c = nextc(); + lastc = future; + future = EOF; return c; } /* * read a character from the input stream */ -int getnext(void){ - register int c; - static int peekc=EOF; + +int +getnext(void) +{ + int c; + static int peekc = EOF; if(peekc!=EOF){ - c=peekc; - peekc=EOF; + c = peekc; + peekc = EOF; return c; } - if(runq->eof) return EOF; - if(doprompt) pprompt(); - c=rchr(runq->cmdfd); + if(runq->eof) + return EOF; + if(doprompt) + pprompt(); + c = rchr(runq->cmdfd); if(!inquote && c=='\\'){ - c=rchr(runq->cmdfd); - if(c=='\n'){ - doprompt=1; + c = rchr(runq->cmdfd); + if(c=='\n' && !incomm){ /* don't continue a comment */ + doprompt = 1; c=' '; } else{ - peekc=c; + peekc = c; c='\\'; } } - doprompt=doprompt || c=='\n' || c==EOF; - if(c==EOF) runq->eof++; + doprompt = doprompt || c=='\n' || c==EOF; + if(c==EOF) + runq->eof++; else if(flag['V'] || ndot>=2 && flag['v']) pchr(err, c); return c; } -void pprompt(void){ + +void +pprompt(void) +{ var *prompt; if(runq->iflag){ pstr(err, promptstr); flush(err); - prompt=vlook("prompt"); + prompt = vlook("prompt"); if(prompt->val && prompt->val->next) - promptstr=prompt->val->next->word; + promptstr = prompt->val->next->word; else promptstr="\t"; } runq->lineno++; - doprompt=0; + doprompt = 0; } -void skipwhite(void){ + +void +skipwhite(void) +{ int c; for(;;){ - c=nextc(); - if(c=='#'){ /* Why did this used to be if(!inquote && c=='#') ?? */ + c = nextc(); + /* Why did this used to be if(!inquote && c=='#') ?? */ + if(c=='#'){ + incomm = 1; for(;;){ - c=nextc(); - if(c=='\n' || c==EOF) break; + c = nextc(); + if(c=='\n' || c==EOF) { + incomm = 0; + break; + } advance(); } } - if(c==' ' || c=='\t') advance(); + if(c==' ' || c=='\t') + advance(); else return; } } -void skipnl(void){ - register int c; + +void +skipnl(void) +{ + int c; for(;;){ skipwhite(); - c=nextc(); - if(c!='\n') return; + c = nextc(); + if(c!='\n') + return; advance(); } } -int nextis(int c){ + +int +nextis(int c) +{ if(nextc()==c){ advance(); return 1; } return 0; } -char *addtok(char *p, int val){ - if(p==0) return 0; + +char* +addtok(char *p, int val) +{ + if(p==0) + return 0; if(p==&tok[NTOK-1]){ - *p=0; + *p = 0; yyerror("token buffer too short"); return 0; } *p++=val; return p; } -char *addutf(char *p, int c){ - p=addtok(p, c); + +char* +addutf(char *p, int c) +{ + p = addtok(p, c); if(twobyte(c)) /* 2-byte escape */ return addtok(p, advance()); if(threebyte(c)){ /* 3-byte escape */ - p=addtok(p, advance()); + p = addtok(p, advance()); return addtok(p, advance()); } return p; } int lastdol; /* was the last token read '$' or '$#' or '"'? */ int lastword; /* was the last token read a word or compound word terminator? */ -int yylex(void){ - register int c, d=nextc(); - register char *w=tok; - register struct tree *t; - yylval.tree=0; + +int +yylex(void) +{ + int c, d = nextc(); + char *w = tok; + struct tree *t; + yylval.tree = 0; /* * Embarassing sneakiness: if the last token read was a quoted or unquoted * WORD then we alter the meaning of what follows. If the next character @@ -146,7 +193,7 @@ int yylex(void){ * we insert a `^' before it. */ if(lastword){ - lastword=0; + lastword = 0; if(d=='('){ advance(); strcpy(tok, "( [SUB]"); @@ -157,15 +204,15 @@ int yylex(void){ return '^'; } } - inquote=0; + inquote = 0; skipwhite(); - switch(c=advance()){ + switch(c = advance()){ case EOF: - lastdol=0; + lastdol = 0; strcpy(tok, "EOF"); return EOF; case '$': - lastdol=1; + lastdol = 1; if(nextis('#')){ strcpy(tok, "$#"); return COUNT; @@ -177,7 +224,7 @@ int yylex(void){ strcpy(tok, "$"); return '$'; case '&': - lastdol=0; + lastdol = 0; if(nextis('&')){ skipnl(); strcpy(tok, "&&"); @@ -186,7 +233,7 @@ int yylex(void){ strcpy(tok, "&"); return '&'; case '|': - lastdol=0; + lastdol = 0; if(nextis(c)){ skipnl(); strcpy(tok, "||"); @@ -194,7 +241,7 @@ int yylex(void){ } case '<': case '>': - lastdol=0; + lastdol = 0; /* * funny redirection tokens: * redir: arrow | arrow '[' fd ']' @@ -204,121 +251,128 @@ int yylex(void){ * some possibilities are nonsensical and get a message. */ *w++=c; - t=newtree(); + t = newtree(); switch(c){ case '|': - t->type=PIPE; - t->fd0=1; - t->fd1=0; + t->type = PIPE; + t->fd0 = 1; + t->fd1 = 0; break; case '>': - t->type=REDIR; + t->type = REDIR; if(nextis(c)){ - t->rtype=APPEND; + t->rtype = APPEND; *w++=c; } - else t->rtype=WRITE; - t->fd0=1; + else t->rtype = WRITE; + t->fd0 = 1; break; case '<': - t->type=REDIR; + t->type = REDIR; if(nextis(c)){ - t->rtype=HERE; + t->rtype = HERE; *w++=c; - } - else t->rtype=READ; - t->fd0=0; + } else if (nextis('>')){ + t->rtype = RDWR; + *w++=c; + } else t->rtype = READ; + t->fd0 = 0; break; } if(nextis('[')){ *w++='['; - c=advance(); + c = advance(); + *w++=c; if(c<'0' || '9'<c){ RedirErr: - *w++ = c; - *w=0; + *w = 0; yyerror(t->type==PIPE?"pipe syntax" :"redirection syntax"); return EOF; } - t->fd0=0; + t->fd0 = 0; do{ - t->fd0=t->fd0*10+c-'0'; + t->fd0 = t->fd0*10+c-'0'; *w++=c; - c=advance(); + c = advance(); }while('0'<=c && c<='9'); if(c=='='){ *w++='='; - if(t->type==REDIR) t->type=DUP; - c=advance(); + if(t->type==REDIR) + t->type = DUP; + c = advance(); if('0'<=c && c<='9'){ - t->rtype=DUPFD; - t->fd1=t->fd0; - t->fd0=0; + t->rtype = DUPFD; + t->fd1 = t->fd0; + t->fd0 = 0; do{ - t->fd0=t->fd0*10+c-'0'; + t->fd0 = t->fd0*10+c-'0'; *w++=c; - c=advance(); + c = advance(); }while('0'<=c && c<='9'); } else{ - if(t->type==PIPE) goto RedirErr; - t->rtype=CLOSE; + if(t->type==PIPE) + goto RedirErr; + t->rtype = CLOSE; } } - *w=0; if(c!=']' || t->type==DUP && (t->rtype==HERE || t->rtype==APPEND)) goto RedirErr; *w++=']'; } *w='\0'; - yylval.tree=t; - if(t->type==PIPE) skipnl(); + yylval.tree = t; + if(t->type==PIPE) + skipnl(); return t->type; case '\'': - lastdol=0; - lastword=1; - inquote=1; + lastdol = 0; + lastword = 1; + inquote = 1; for(;;){ - c=advance(); - if(c==EOF) break; + c = advance(); + if(c==EOF) + break; if(c=='\''){ if(nextc()!='\'') break; advance(); } - w=addutf(w, c); + w = addutf(w, c); } - if(w!=0) *w='\0'; - t=token(tok, WORD); - t->quoted=1; - yylval.tree=t; + if(w!=0) + *w='\0'; + t = token(tok, WORD); + t->quoted = 1; + yylval.tree = t; return t->type; } if(!wordchr(c)){ - lastdol=0; - tok[0]=c; + lastdol = 0; + tok[0] = c; tok[1]='\0'; return c; } for(;;){ /* next line should have (char)c==GLOB, but ken's compiler is broken */ if(c=='*' || c=='[' || c=='?' || c==(unsigned char)GLOB) - w=addtok(w, GLOB); - w=addutf(w, c); - c=nextc(); + w = addtok(w, GLOB); + w = addutf(w, c); + c = nextc(); if(lastdol?!idchr(c):!wordchr(c)) break; advance(); } - lastword=1; - lastdol=0; - if(w!=0) *w='\0'; - t=klook(tok); - if(t->type!=WORD) lastword=0; - t->quoted=0; - yylval.tree=t; + lastword = 1; + lastdol = 0; + if(w!=0) + *w='\0'; + t = klook(tok); + if(t->type!=WORD) + lastword = 0; + t->quoted = 0; + yylval.tree = t; return t->type; } - |