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 else 26 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 spurious 36 * missubstitution, or a misrecognized EOF marker. 37 */ 38 #define NLINE 4096 39 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, c; 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 else 113 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 } 132