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 void13 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 else31 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 spurious41 * missubstitution, or a misrecognized EOF marker.42 */43 #define NLINE 409645 void46 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 void89 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 else129 pstrs(f, vlook(s)->val);130 *t = savec;131 if(savec=='^')132 t++;133 }134 s = t;135 }136 }137 }139 void140 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 }