9base

revived minimalist port of Plan 9 userland to Unix
git clone git://git.suckless.org/9base
Log | Files | Refs | README | LICENSE

here.c (2504B)


      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 
     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 }
     20 
     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
     44 
     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 }
     87 
     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;
    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 				else
    129 					pstrs(f, vlook(s)->val);
    130 				*t = savec;
    131 				if(savec=='^')
    132 					t++;
    133 			}
    134 			s = t;
    135 		}
    136 	}
    137 }
    138 
    139 void
    140 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 }