Blob
1 #include "rc.h"2 #include "exec.h"3 #include "io.h"4 #include "fns.h"5 struct here *here, **ehere;6 int ser=0;7 char tmp[]="/tmp/here0000.0000";8 char hex[]="0123456789abcdef";9 void psubst(io*, char*);10 void pstrs(io*, word*);11 void hexnum(char *p, int n)12 {13 *p++=hex[(n>>12)&0xF];14 *p++=hex[(n>>8)&0xF];15 *p++=hex[(n>>4)&0xF];16 *p=hex[n&0xF];17 }18 tree *heredoc(tree *tag)19 {20 struct here *h=new(struct here);21 if(tag->type!=WORD) yyerror("Bad here tag");22 h->next=0;23 if(here)24 *ehere=h;25 else26 here=h;27 ehere=&h->next;28 h->tag=tag;29 hexnum(&tmp[9], getpid());30 hexnum(&tmp[14], ser++);31 h->name=strdup(tmp);32 return token(tmp, WORD);33 }34 /*35 * bug: lines longer than NLINE get split -- this can cause spurious36 * missubstitution, or a misrecognized EOF marker.37 */38 #define NLINE 409639 void readhere(void){40 struct here *h, *nexth;41 io *f;42 char *s, *tag;43 int c, subst;44 char line[NLINE+1];45 for(h=here;h;h=nexth){46 subst=!h->tag->quoted;47 tag=h->tag->str;48 c=Creat(h->name);49 if(c<0) yyerror("can't create here document");50 f=openfd(c);51 s=line;52 pprompt();53 while((c=rchr(runq->cmdfd))!=EOF){54 if(c=='\n' || s==&line[NLINE]){55 *s='\0';56 if(strcmp(line, tag)==0) break;57 if(subst) psubst(f, line);58 else pstr(f, line);59 s=line;60 if(c=='\n'){61 pprompt();62 pchr(f, c);63 }64 else *s++=c;65 }66 else *s++=c;67 }68 flush(f);69 closeio(f);70 cleanhere(h->name);71 nexth=h->next;72 efree((char *)h);73 }74 here=0;75 doprompt=1;76 }77 void psubst(io *f, char *s)78 {79 char *t, *u;80 int savec, n;81 word *star;82 while(*s){83 if(*s!='$'){84 if(0xa0<=(*s&0xff) && (*s&0xff)<=0xf5){85 pchr(f, *s++);86 if(*s=='\0') break;87 }88 else if(0xf6<=(*s&0xff) && (*s&0xff)<=0xf7){89 pchr(f, *s++);90 if(*s=='\0') break;91 pchr(f, *s++);92 if(*s=='\0') break;93 }94 pchr(f, *s++);95 }96 else{97 t=++s;98 if(*t=='$') pchr(f, *t++);99 else{100 while(*t && idchr(*t)) t++;101 savec=*t;102 *t='\0';103 n=0;104 for(u=s;*u && '0'<=*u && *u<='9';u++) n=n*10+*u-'0';105 if(n && *u=='\0'){106 star=vlook("*")->val;107 if(star && 1<=n && n<=count(star)){108 while(--n) star=star->next;109 pstr(f, star->word);110 }111 }112 else113 pstrs(f, vlook(s)->val);114 *t=savec;115 if(savec=='^') t++;116 }117 s=t;118 }119 }120 }121 void pstrs(io *f, word *a)122 {123 if(a){124 while(a->next && a->next->word){125 pstr(f, a->word);126 pchr(f, ' ');127 a=a->next;128 }129 pstr(f, a->word);130 }131 }