/* * This file is part of the UCB release of Plan 9. It is subject to the license * terms in the LICENSE file found in the top-level directory of this * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No * part of the UCB release of Plan 9, including this file, may be copied, * modified, propagated, or distributed except according to the terms contained * in the LICENSE file. */ /* Portions of this file are Copyright (C) 9front's team. * See /doc/license/9front-mit for details about the licensing. * See http://git.9front.org/plan9front/plan9front/HEAD/info.html for a list of authors. */ #include "rc.h" #include "exec.h" #include "io.h" #include "fns.h" struct here *here, **ehere; int ser = 0; char tmp[]="/tmp/here0000.0000"; char hex[]="0123456789abcdef"; void psubst(io*, uint8_t*); void pstrs(io*, word*); void hexnum(char *p, int n) { *p++ = hex[(n>>12)&0xF]; *p++ = hex[(n>>8)&0xF]; *p++ = hex[(n>>4)&0xF]; *p = hex[n&0xF]; } tree* heredoc(tree *tag) { struct here *h; if(tag->type != WORD){ yyerror("Bad here tag"); return nil; } h = new(struct here); h->next = 0; if(here) *ehere = h; else here = h; ehere = &h->next; h->tag = tag; hexnum(&tmp[9], getpid()); hexnum(&tmp[14], ser++); h->name = estrdup(tmp); return token(tmp, WORD); } /* * bug: lines longer than NLINE get split -- this can cause spurious * missubstitution, or a misrecognized EOF marker. */ #define NLINE 4096 void readhere(void) { struct here *h, *nexth; io *f; char *s, *tag; int c, subst; char line[NLINE+1]; for(h = here;h;h = nexth){ subst=!h->tag->quoted; tag = h->tag->str; c = Creat(h->name); if(c<0) yyerror("can't create here document"); f = openfd(c); s = line; pprompt(); while((c = rchr(runq->cmdfd)) != EOF){ if(c == '\n' || s == &line[NLINE]){ *s='\0'; if(tag && strcmp(line, tag)==0) break; if(subst) psubst(f, (uint8_t *)line); else pstr(f, line); s = line; if(c == '\n'){ pprompt(); pchr(f, c); }else *s++ = c; }else *s++ = c; } flush(f); closeio(f); cleanhere(h->name); nexth = h->next; free(h); } here = 0; doprompt = 1; } void psubst(io *f, uint8_t *s) { int savec, n; uint8_t *t, *u; word *star; while(*s){ if(*s != '$'){ if(0xa0 <= *s && *s <= 0xf5){ pchr(f, *s++); if(*s == '\0') break; } else if(0xf6 <= *s && *s <= 0xf7){ pchr(f, *s++); if(*s == '\0') break; pchr(f, *s++); if(*s == '\0') break; } pchr(f, *s++); } else{ t = ++s; if(*t == '$') pchr(f, *t++); else{ while(*t && idchr(*t)) t++; savec = *t; *t = '\0'; n = 0; for(u = s; *u && '0' <= *u && *u <= '9'; u++) n = n*10 + *u - '0'; if(n && *u=='\0'){ star = vlook(ENV_RCARGLIST)->val; if(star && 1 <= n && n <= count(star)){ while(--n) star = star->next; pstr(f, star->word); } } else pstrs(f, vlook((char *)s)->val); *t = savec; if(savec == '^') t++; } s = t; } } } void pstrs(io *f, word *a) { if(a){ while(a->next && a->next->word){ pstr(f, a->word); pchr(f, ' '); a = a->next; } pstr(f, a->word); } }