Blob


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*);
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 }
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
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 }
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;
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;
109 pchr(f, *s++);
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);
128 else
129 pstrs(f, vlook(s)->val);
130 *t = savec;
131 if(savec=='^')
132 t++;
134 s = t;
139 void
140 pstrs(io *f, word *a)
142 if(a){
143 while(a->next && a->next->word){
144 pstr(f, a->word);
145 pchr(f, ' ');
146 a = a->next;
148 pstr(f, a->word);