123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152 |
- #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*, uchar*);
- 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)
- {
- 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, (uchar *)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, uchar *s)
- {
- int savec, n;
- uchar *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("*")->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);
- }
- }
|