140 lines · 2.3 KB · C
RawDownload
#include "rc.h"#include "exec.h"#include "io.h"#include "fns.h"struct here *here, **ehere;int ser = 0;char tmp[]="/tmp/here0000.0000";char hex[]="0123456789abcdef"; void psubst(io*, char*);void pstrs(io*, word*); voidhexnum(char *p, int n){	*p++=hex[(n>>12)&0xF];	*p++=hex[(n>>8)&0xF];	*p++=hex[(n>>4)&0xF];	*p = hex[n&0xF];} tree*heredoc(tree *tag){	struct here *h = new(struct here);	if(tag->type!=WORD)		yyerror("Bad here tag");	h->next = 0;	if(here)		*ehere = h;	else		here = h;	ehere=&h->next;	h->tag = tag;	hexnum(&tmp[9], getpid());	hexnum(&tmp[14], ser++);	h->name = strdup(tmp);	return token(tmp, WORD);}/* * bug: lines longer than NLINE get split -- this can cause spurious * missubstitution, or a misrecognized EOF marker. */#define	NLINE	4096 voidreadhere(void){	struct here *h, *nexth;	io *f;	char *s, *tag;	int n, subst;	char line[NLINE+1];	Rune r;	for(h = here;h;h = nexth){		subst=!h->tag->quoted;		tag = h->tag->str;		n = Creat(h->name);		if(n<0)			yyerror("can't create here document");		f = openfd(n);		s = line;		pprompt();		while((n = rutf(s, &r, runq->cmdfd))!=EOF){			if(r=='\n' || s>=&line[NLINE-UTFmax-1]){				if(r == '\n')					s--;				s[n]='\0';				if(tag && strcmp(line, tag)==0) break;				if(subst)					psubst(f, line);				else					pstr(f, line);				s = line;				if(r=='\n'){					pprompt();					pchr(f, r);				}			}			else s += n;		}		flush(f);		closeio(f);		cleanhere(h->name);		nexth = h->next;		efree((char *)h);	}	here = 0;	doprompt = 1;} voidpsubst(io *f, char *s){	int savec, n;	char *t, *u;	word *star;	while(*s){		if(*s!='$')			pchr(f, *s++);		/* we've already got good runes */		else{			t=++s;			if(*t=='$')				pchr(f, *t++);			else{				while(*t && idchr(*t)) t++;				savec=*t;				*t='\0';				n = 0;				for(u = s;*u && '0'<=*u && *u<='9';u++) n = n*10+*u-'0';				if(n && *u=='\0'){					star = vlook("*")->val;					if(star && 1<=n && n<=count(star)){						while(--n) star = star->next;						pstr(f, star->word);					}				}				else					pstrs(f, vlook((char *)s)->val);				*t = savec;				if(savec=='^')					t++;			}			s = t;		}	}} voidpstrs(io *f, word *a){	if(a){		while(a->next && a->next->word){			pstr(f, a->word);			pchr(f, ' ');			a = a->next;		}		pstr(f, a->word);	}}