123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162 |
- /*
- * 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.
- */
- #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 = new(struct here);
- if(tag->type != WORD)
- yyerror("Bad here tag");
- 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 = strdup(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)
- {
- int c, subst;
- char *s, *tag;
- char line[NLINE+1];
- io *f;
- struct here *h, *nexth;
- 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;
- efree((char *)h);
- }
- here = 0;
- doprompt = 1;
- }
- void
- psubst(io *f, uint8_t *s)
- {
- int savec, n;
- uint8_t *t, *u;
- Rune r;
- word *star;
- while(*s){
- if(*s != '$'){ /* copy plain text rune */
- if(*s < Runeself)
- pchr(f, *s++);
- else{
- n = chartorune(&r, (char *)s);
- while(n-- > 0)
- pchr(f, *s++);
- }
- }else{ /* $something -- perform substitution */
- 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("*")->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);
- }
- }
|