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