2016-11-25 17:18:40 +01:00
|
|
|
/*
|
|
|
|
* This file is part of the UCB release of Plan 9. It is subject to the license
|
|
|
|
* terms in the LICENSE file found in the top-level directory of this
|
|
|
|
* distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
|
|
|
|
* part of the UCB release of Plan 9, including this file, may be copied,
|
|
|
|
* modified, propagated, or distributed except according to the terms contained
|
|
|
|
* in the LICENSE file.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "rc.h"
|
|
|
|
#include "exec.h"
|
|
|
|
#include "io.h"
|
|
|
|
#include "fns.h"
|
|
|
|
|
|
|
|
struct here *here, **ehere;
|
|
|
|
int ser = 0;
|
2017-10-18 01:10:06 +02:00
|
|
|
char tmp[]="/tmp/here0000.0000";
|
|
|
|
char hex[]="0123456789abcdef";
|
2016-11-25 17:18:40 +01:00
|
|
|
|
|
|
|
void psubst(io*, uint8_t*);
|
|
|
|
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++);
|
2017-10-18 01:10:06 +02:00
|
|
|
h->name = estrdup(tmp);
|
2016-11-25 17:18:40 +01:00
|
|
|
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)
|
|
|
|
{
|
2017-10-18 01:10:06 +02:00
|
|
|
struct here *h, *nexth;
|
|
|
|
io *f;
|
2016-11-25 17:18:40 +01:00
|
|
|
char *s, *tag;
|
2017-10-18 01:10:06 +02:00
|
|
|
int c, subst;
|
2016-11-25 17:18:40 +01:00
|
|
|
char line[NLINE+1];
|
2017-10-18 01:10:06 +02:00
|
|
|
for(h = here;h;h = nexth){
|
|
|
|
subst=!h->tag->quoted;
|
2016-11-25 17:18:40 +01:00
|
|
|
tag = h->tag->str;
|
|
|
|
c = Creat(h->name);
|
2017-10-18 01:10:06 +02:00
|
|
|
if(c<0)
|
2016-11-25 17:18:40 +01:00
|
|
|
yyerror("can't create here document");
|
|
|
|
f = openfd(c);
|
|
|
|
s = line;
|
|
|
|
pprompt();
|
|
|
|
while((c = rchr(runq->cmdfd)) != EOF){
|
|
|
|
if(c == '\n' || s == &line[NLINE]){
|
2017-10-18 01:10:06 +02:00
|
|
|
*s='\0';
|
|
|
|
if(tag && strcmp(line, tag)==0)
|
2016-11-25 17:18:40 +01:00
|
|
|
break;
|
|
|
|
if(subst)
|
|
|
|
psubst(f, (uint8_t *)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;
|
2017-10-18 01:10:06 +02:00
|
|
|
free(h);
|
2016-11-25 17:18:40 +01:00
|
|
|
}
|
|
|
|
here = 0;
|
|
|
|
doprompt = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
psubst(io *f, uint8_t *s)
|
|
|
|
{
|
|
|
|
int savec, n;
|
|
|
|
uint8_t *t, *u;
|
|
|
|
word *star;
|
|
|
|
|
|
|
|
while(*s){
|
2017-10-18 01:10:06 +02:00
|
|
|
if(*s != '$'){
|
|
|
|
if(0xa0 <= *s && *s <= 0xf5){
|
2016-11-25 17:18:40 +01:00
|
|
|
pchr(f, *s++);
|
2017-10-18 01:10:06 +02:00
|
|
|
if(*s == '\0')
|
|
|
|
break;
|
2016-11-25 17:18:40 +01:00
|
|
|
}
|
2017-10-18 01:10:06 +02:00
|
|
|
else if(0xf6 <= *s && *s <= 0xf7){
|
|
|
|
pchr(f, *s++);
|
|
|
|
if(*s == '\0')
|
|
|
|
break;
|
|
|
|
pchr(f, *s++);
|
|
|
|
if(*s == '\0')
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
pchr(f, *s++);
|
|
|
|
}
|
|
|
|
else{
|
2016-11-25 17:18:40 +01:00
|
|
|
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';
|
2017-10-18 01:10:06 +02:00
|
|
|
if(n && *u=='\0'){
|
2017-10-18 22:38:30 +02:00
|
|
|
star = vlook(ENV_RCARGLIST)->val;
|
2016-11-25 17:18:40 +01:00
|
|
|
if(star && 1 <= n && n <= count(star)){
|
|
|
|
while(--n)
|
|
|
|
star = star->next;
|
|
|
|
pstr(f, star->word);
|
|
|
|
}
|
2017-10-18 01:10:06 +02:00
|
|
|
}
|
|
|
|
else
|
2016-11-25 17:18:40 +01:00
|
|
|
pstrs(f, vlook((char *)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);
|
|
|
|
}
|
|
|
|
}
|