From 2ade60747db41771498ab2b85ce6e3c3389f2c26 Mon Sep 17 00:00:00 2001 From: Nicholas Noll Date: Wed, 13 Oct 2021 09:08:59 -0700 Subject: feat(rc): added unix port of rc with linenoise --- sys/cmd/rc/here.c | 150 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 150 insertions(+) create mode 100644 sys/cmd/rc/here.c (limited to 'sys/cmd/rc/here.c') diff --git a/sys/cmd/rc/here.c b/sys/cmd/rc/here.c new file mode 100644 index 0000000..17c6245 --- /dev/null +++ b/sys/cmd/rc/here.c @@ -0,0 +1,150 @@ +#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*); + +void +hexnum(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 + +void +readhere(void) +{ + struct here *h, *nexth; + io *f; + char *s, *tag; + int c, subst; + char line[NLINE+1]; + for(h = here;h;h = nexth){ + subst=!h->tag->quoted; + tag = h->tag->str; + c = Creat(h->name); + if(c<0) + yyerror("can't create here document"); + f = openfd(c); + s = line; + pprompt(); + while((c = rchr(runq->cmdfd))!=EOF){ + if(c=='\n' || s==&line[NLINE]){ + *s='\0'; + if(tag && strcmp(line, tag)==0) break; + if(subst) + psubst(f, line); + else pstr(f, line); + s = line; + if(c=='\n'){ + pprompt(); + pchr(f, c); + } + else *s++=c; + } + else *s++=c; + } + flush(f); + closeio(f); + cleanhere(h->name); + nexth = h->next; + efree((char *)h); + } + here = 0; + doprompt = 1; +} + +void +psubst(io *f, char *s) +{ + char *t, *u; + int savec, n; + word *star; + while(*s){ + if(*s!='$'){ + if(0xa0<=(*s&0xff) && (*s&0xff)<=0xf5){ + pchr(f, *s++); + if(*s=='\0') + break; + } + else if(0xf6<=(*s&0xff) && (*s&0xff)<=0xf7){ + pchr(f, *s++); + if(*s=='\0') + break; + pchr(f, *s++); + if(*s=='\0') + break; + } + pchr(f, *s++); + } + 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(s)->val); + *t = savec; + if(savec=='^') + t++; + } + s = t; + } + } +} + +void +pstrs(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); + } +} -- cgit v1.2.1