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*);
11 void hexnum(char *p, int n)
12 {
13 *p++=hex[(n>>12)&0xF];
14 *p++=hex[(n>>8)&0xF];
15 *p++=hex[(n>>4)&0xF];
16 *p=hex[n&0xF];
17 }
18 tree *heredoc(tree *tag)
19 {
20 struct here *h=new(struct here);
21 if(tag->type!=WORD) yyerror("Bad here tag");
22 h->next=0;
23 if(here)
24 *ehere=h;
25 else
26 here=h;
27 ehere=&h->next;
28 h->tag=tag;
29 hexnum(&tmp[9], getpid());
30 hexnum(&tmp[14], ser++);
31 h->name=strdup(tmp);
32 return token(tmp, WORD);
33 }
34 /*
35 * bug: lines longer than NLINE get split -- this can cause spurious
36 * missubstitution, or a misrecognized EOF marker.
37 */
38 #define NLINE 4096
39 void readhere(void){
40 struct here *h, *nexth;
41 io *f;
42 char *s, *tag;
43 int c, subst;
44 char line[NLINE+1];
45 for(h=here;h;h=nexth){
46 subst=!h->tag->quoted;
47 tag=h->tag->str;
48 c=Creat(h->name);
49 if(c<0) yyerror("can't create here document");
50 f=openfd(c);
51 s=line;
52 pprompt();
53 while((c=rchr(runq->cmdfd))!=EOF){
54 if(c=='\n' || s==&line[NLINE]){
55 *s='\0';
56 if(strcmp(line, tag)==0) break;
57 if(subst) psubst(f, line);
58 else pstr(f, line);
59 s=line;
60 if(c=='\n'){
61 pprompt();
62 pchr(f, c);
63 }
64 else *s++=c;
65 }
66 else *s++=c;
67 }
68 flush(f);
69 closeio(f);
70 cleanhere(h->name);
71 nexth=h->next;
72 efree((char *)h);
73 }
74 here=0;
75 doprompt=1;
76 }
77 void psubst(io *f, char *s)
78 {
79 char *t, *u;
80 int savec, n;
81 word *star;
82 while(*s){
83 if(*s!='$'){
84 if(0xa0<=(*s&0xff) && (*s&0xff)<=0xf5){
85 pchr(f, *s++);
86 if(*s=='\0') break;
87 }
88 else if(0xf6<=(*s&0xff) && (*s&0xff)<=0xf7){
89 pchr(f, *s++);
90 if(*s=='\0') break;
91 pchr(f, *s++);
92 if(*s=='\0') break;
93 }
94 pchr(f, *s++);
95 }
96 else{
97 t=++s;
98 if(*t=='$') pchr(f, *t++);
99 else{
100 while(*t && idchr(*t)) t++;
101 savec=*t;
102 *t='\0';
103 n=0;
104 for(u=s;*u && '0'<=*u && *u<='9';u++) n=n*10+*u-'0';
105 if(n && *u=='\0'){
106 star=vlook("*")->val;
107 if(star && 1<=n && n<=count(star)){
108 while(--n) star=star->next;
109 pstr(f, star->word);
112 else
113 pstrs(f, vlook(s)->val);
114 *t=savec;
115 if(savec=='^') t++;
117 s=t;
121 void pstrs(io *f, word *a)
123 if(a){
124 while(a->next && a->next->word){
125 pstr(f, a->word);
126 pchr(f, ' ');
127 a=a->next;
129 pstr(f, a->word);