Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
#include "rc.h"
2
#include "exec.h"
3
#include "io.h"
4
#include "fns.h"
5
 
6
struct here *here, **ehere;
7
int ser = 0;
8
char tmp[] = "/tmp/here0000.0000";
9
char hex[] = "0123456789abcdef";
10
 
11
void psubst(io*, uchar*);
12
void pstrs(io*, word*);
13
 
14
void
15
hexnum(char *p, int n)
16
{
17
	*p++ = hex[(n>>12)&0xF];
18
	*p++ = hex[(n>>8)&0xF];
19
	*p++ = hex[(n>>4)&0xF];
20
	*p = hex[n&0xF];
21
}
22
 
23
tree*
24
heredoc(tree *tag)
25
{
26
	struct here *h = new(struct here);
27
 
28
	if(tag->type != WORD)
29
		yyerror("Bad here tag");
30
	h->next = 0;
31
	if(here)
32
		*ehere = h;
33
	else
34
		here = h;
35
	ehere = &h->next;
36
	h->tag = tag;
37
	hexnum(&tmp[9], getpid());
38
	hexnum(&tmp[14], ser++);
39
	h->name = strdup(tmp);
40
	return token(tmp, WORD);
41
}
42
 
43
/*
44
 * bug: lines longer than NLINE get split -- this can cause spurious
45
 * missubstitution, or a misrecognized EOF marker.
46
 */
47
#define	NLINE	4096
48
 
49
void
50
readhere(void)
51
{
52
	int c, subst;
53
	char *s, *tag;
54
	char line[NLINE+1];
55
	io *f;
56
	struct here *h, *nexth;
57
 
58
	for(h = here; h; h = nexth){
59
		subst = !h->tag->quoted;
60
		tag = h->tag->str;
61
		c = Creat(h->name);
62
		if(c < 0)
63
			yyerror("can't create here document");
64
		f = openfd(c);
65
		s = line;
66
		pprompt();
67
		while((c = rchr(runq->cmdfd)) != EOF){
68
			if(c == '\n' || s == &line[NLINE]){
69
				*s = '\0';
70
				if(tag && strcmp(line, tag) == 0)
71
					break;
72
				if(subst)
73
					psubst(f, (uchar *)line);
74
				else
75
					pstr(f, line);
76
				s = line;
77
				if(c == '\n'){
78
					pprompt();
79
					pchr(f, c);
80
				}else
81
					*s++ = c;
82
			}else
83
				*s++ = c;
84
		}
85
		flush(f);
86
		closeio(f);
87
		cleanhere(h->name);
88
		nexth = h->next;
89
		efree((char *)h);
90
	}
91
	here = 0;
92
	doprompt = 1;
93
}
94
 
95
void
96
psubst(io *f, uchar *s)
97
{
98
	int savec, n;
99
	uchar *t, *u;
100
	Rune r;
101
	word *star;
102
 
103
	while(*s){
104
		if(*s != '$'){		/* copy plain text rune */
105
			if(*s < Runeself)
106
				pchr(f, *s++);
107
			else{
108
				n = chartorune(&r, (char *)s);
109
				while(n-- > 0)
110
					pchr(f, *s++);
111
			}
112
		}else{			/* $something -- perform substitution */
113
			t = ++s;
114
			if(*t == '$')
115
				pchr(f, *t++);
116
			else{
117
				while(*t && idchr(*t))
118
					t++;
119
				savec = *t;
120
				*t = '\0';
121
				n = 0;
122
				for(u = s; *u && '0' <= *u && *u <= '9'; u++)
123
					n = n*10 + *u - '0';
124
				if(n && *u == '\0'){
125
					star = vlook("*")->val;
126
					if(star && 1 <= n && n <= count(star)){
127
						while(--n)
128
							star = star->next;
129
						pstr(f, star->word);
130
					}
131
				}else
132
					pstrs(f, vlook((char *)s)->val);
133
				*t = savec;
134
				if(savec == '^')
135
					t++;
136
			}
137
			s = t;
138
		}
139
	}
140
}
141
 
142
void
143
pstrs(io *f, word *a)
144
{
145
	if(a){
146
		while(a->next && a->next->word){
147
			pstr(f, a->word);
148
			pchr(f, ' ');
149
			a = a->next;
150
		}
151
		pstr(f, a->word);
152
	}
153
}