Plan 9 from Bell Labs’s /usr/web/sources/contrib/quanstro/root/sys/src/cmd/rc/here.c

Copyright © 2021 Plan 9 Foundation.
Distributed under the MIT License.
Download the Plan 9 distribution.


#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 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;
}

void
psubst(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;
		}
	}
}

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);
	}
}

Bell Labs OSI certified Powered by Plan 9

(Return to Plan 9 Home Page)

Copyright © 2021 Plan 9 Foundation. All Rights Reserved.
Comments to webmaster@9p.io.