1 #include "rc.h" 2 #include "y.tab.h" 3 4 Here *here, **ehere; 5 int ser; 6 7 char tmp[]="/tmp/here0000.0000"; 8 char hex[]="0123456789abcdef"; 9 10 void psubst(Io*, char*); 11 void pstrs(Io*, Word*); 12 13 void hexnum(char *p, int n) 14 { 15 *p++=hex[(n>>12)&0xF]; 16 *p++=hex[(n>>8)&0xF]; 17 *p++=hex[(n>>4)&0xF]; 18 *p=hex[n&0xF]; 19 } 20 21 Tree * 22 heredoc(Tree *tag) 23 { 24 Here *h=new(Here); 25 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 void 46 readhere(void) 47 { 48 Here *h, *nexth; 49 Io *f; 50 char *s, *tag; 51 int c, subst; 52 char line[NLINE+1]; 53 54 for(h=here;h;h=nexth){ 55 subst=!h->tag->quoted; 56 tag=h->tag->str; 57 c=create(h->name, 1, 0666); 58 if(c<0) yyerror("can't create here document"); 59 f=openfd(c); 60 s=line; 61 pprompt(); 62 while((c=rchr(runq->cmdfd))!=EOF){ 63 if(c=='\n' || s==&line[NLINE]){ 64 *s='\0'; 65 if(strcmp(line, tag)==0) break; 66 if(subst) psubst(f, line); 67 else pstr(f, line); 68 s=line; 69 if(c=='\n'){ 70 pprompt(); 71 pchr(f, c); 72 } 73 else *s++=c; 74 } 75 else *s++=c; 76 } 77 flush(f); 78 closeio(f); 79 cleanhere(h->name); 80 nexth=h->next; 81 free(h); 82 } 83 here=0; 84 doprompt=1; 85 } 86 87 void 88 psubst(Io *f, char *s) 89 { 90 char *t, *u; 91 int savec, n; 92 Word *star; 93 94 while(*s){ 95 if(*s!='$'){ 96 if(0xa0<=(*s&0xff) && (*s&0xff)<=0xf5){ 97 pchr(f, *s++); 98 if(*s=='\0') break; 99 } 100 else if(0xf6<=(*s&0xff) && (*s&0xff)<=0xf7){ 101 pchr(f, *s++); 102 if(*s=='\0') break; 103 pchr(f, *s++); 104 if(*s=='\0') break; 105 } 106 pchr(f, *s++); 107 } 108 else{ 109 t=++s; 110 if(*t=='$') pchr(f, *t++); 111 else{ 112 while(*t && idchr(*t)) t++; 113 savec=*t; 114 *t='\0'; 115 n=0; 116 for(u=s;*u && '0'<=*u && *u<='9';u++) n=n*10+*u-'0'; 117 if(n && *u=='\0'){ 118 star=vlook("*")->val; 119 if(star && 1<=n && n<=count(star)){ 120 while(--n) star=star->next; 121 pstr(f, star->word); 122 } 123 } 124 else 125 pstrs(f, vlook(s)->val); 126 *t=savec; 127 if(savec=='^') t++; 128 } 129 s=t; 130 } 131 } 132 } 133 134 void 135 pstrs(Io *f, Word *a) 136 { 137 if(a){ 138 while(a->next && a->next->word){ 139 pstr(f, a->word); 140 pchr(f, ' '); 141 a=a->next; 142 } 143 pstr(f, a->word); 144 } 145 } 146