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