]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/rc/here.c
922911f80d7ae6fe5382052629996609b5a3b79a
[plan9front.git] / sys / src / cmd / rc / here.c
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 = estrdup(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                 free(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 }