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