xref: /plan9/sys/src/cmd/mk/rc.c (revision 7dd7cddf99dd7472612f1413b4da293630e6b1bc)
1*7dd7cddfSDavid du Colombier #include	"mk.h"
2*7dd7cddfSDavid du Colombier 
3*7dd7cddfSDavid du Colombier char	*termchars = "'= \t";	/*used in parse.c to isolate assignment attribute*/
4*7dd7cddfSDavid du Colombier char	*shflags = "-I";	/* rc flag to force non-interactive mode */
5*7dd7cddfSDavid du Colombier int	IWS = '\1';		/* inter-word separator in env - not used in plan 9 */
6*7dd7cddfSDavid du Colombier 
7*7dd7cddfSDavid du Colombier /*
8*7dd7cddfSDavid du Colombier  *	This file contains functions that depend on rc's syntax.  Most
9*7dd7cddfSDavid du Colombier  *	of the routines extract strings observing rc's escape conventions
10*7dd7cddfSDavid du Colombier  */
11*7dd7cddfSDavid du Colombier 
12*7dd7cddfSDavid du Colombier 
13*7dd7cddfSDavid du Colombier /*
14*7dd7cddfSDavid du Colombier  *	skip a token in single quotes.
15*7dd7cddfSDavid du Colombier  */
16*7dd7cddfSDavid du Colombier static char *
squote(char * cp)17*7dd7cddfSDavid du Colombier squote(char *cp)
18*7dd7cddfSDavid du Colombier {
19*7dd7cddfSDavid du Colombier 	Rune r;
20*7dd7cddfSDavid du Colombier 	int n;
21*7dd7cddfSDavid du Colombier 
22*7dd7cddfSDavid du Colombier 	while(*cp){
23*7dd7cddfSDavid du Colombier 		n = chartorune(&r, cp);
24*7dd7cddfSDavid du Colombier 		if(r == '\'') {
25*7dd7cddfSDavid du Colombier 			n += chartorune(&r, cp+n);
26*7dd7cddfSDavid du Colombier 			if(r != '\'')
27*7dd7cddfSDavid du Colombier 				return(cp);
28*7dd7cddfSDavid du Colombier 		}
29*7dd7cddfSDavid du Colombier 		cp += n;
30*7dd7cddfSDavid du Colombier 	}
31*7dd7cddfSDavid du Colombier 	SYNERR(-1);		/* should never occur */
32*7dd7cddfSDavid du Colombier 	fprint(2, "missing closing '\n");
33*7dd7cddfSDavid du Colombier 	return 0;
34*7dd7cddfSDavid du Colombier }
35*7dd7cddfSDavid du Colombier 
36*7dd7cddfSDavid du Colombier /*
37*7dd7cddfSDavid du Colombier  *	search a string for characters in a pattern set
38*7dd7cddfSDavid du Colombier  *	characters in quotes and variable generators are escaped
39*7dd7cddfSDavid du Colombier  */
40*7dd7cddfSDavid du Colombier char *
charin(char * cp,char * pat)41*7dd7cddfSDavid du Colombier charin(char *cp, char *pat)
42*7dd7cddfSDavid du Colombier {
43*7dd7cddfSDavid du Colombier 	Rune r;
44*7dd7cddfSDavid du Colombier 	int n, vargen;
45*7dd7cddfSDavid du Colombier 
46*7dd7cddfSDavid du Colombier 	vargen = 0;
47*7dd7cddfSDavid du Colombier 	while(*cp){
48*7dd7cddfSDavid du Colombier 		n = chartorune(&r, cp);
49*7dd7cddfSDavid du Colombier 		switch(r){
50*7dd7cddfSDavid du Colombier 		case '\'':			/* skip quoted string */
51*7dd7cddfSDavid du Colombier 			cp = squote(cp+1);	/* n must = 1 */
52*7dd7cddfSDavid du Colombier 			if(!cp)
53*7dd7cddfSDavid du Colombier 				return 0;
54*7dd7cddfSDavid du Colombier 			break;
55*7dd7cddfSDavid du Colombier 		case '$':
56*7dd7cddfSDavid du Colombier 			if(*(cp+1) == '{')
57*7dd7cddfSDavid du Colombier 				vargen = 1;
58*7dd7cddfSDavid du Colombier 			break;
59*7dd7cddfSDavid du Colombier 		case '}':
60*7dd7cddfSDavid du Colombier 			if(vargen)
61*7dd7cddfSDavid du Colombier 				vargen = 0;
62*7dd7cddfSDavid du Colombier 			else if(utfrune(pat, r))
63*7dd7cddfSDavid du Colombier 				return cp;
64*7dd7cddfSDavid du Colombier 			break;
65*7dd7cddfSDavid du Colombier 		default:
66*7dd7cddfSDavid du Colombier 			if(vargen == 0 && utfrune(pat, r))
67*7dd7cddfSDavid du Colombier 				return cp;
68*7dd7cddfSDavid du Colombier 			break;
69*7dd7cddfSDavid du Colombier 		}
70*7dd7cddfSDavid du Colombier 		cp += n;
71*7dd7cddfSDavid du Colombier 	}
72*7dd7cddfSDavid du Colombier 	if(vargen){
73*7dd7cddfSDavid du Colombier 		SYNERR(-1);
74*7dd7cddfSDavid du Colombier 		fprint(2, "missing closing } in pattern generator\n");
75*7dd7cddfSDavid du Colombier 	}
76*7dd7cddfSDavid du Colombier 	return 0;
77*7dd7cddfSDavid du Colombier }
78*7dd7cddfSDavid du Colombier 
79*7dd7cddfSDavid du Colombier /*
80*7dd7cddfSDavid du Colombier  *	extract an escaped token.  Possible escape chars are single-quote,
81*7dd7cddfSDavid du Colombier  *	double-quote,and backslash.  Only the first is valid for rc. the
82*7dd7cddfSDavid du Colombier  *	others are just inserted into the receiving buffer.
83*7dd7cddfSDavid du Colombier  */
84*7dd7cddfSDavid du Colombier char*
expandquote(char * s,Rune r,Bufblock * b)85*7dd7cddfSDavid du Colombier expandquote(char *s, Rune r, Bufblock *b)
86*7dd7cddfSDavid du Colombier {
87*7dd7cddfSDavid du Colombier 	if (r != '\'') {
88*7dd7cddfSDavid du Colombier 		rinsert(b, r);
89*7dd7cddfSDavid du Colombier 		return s;
90*7dd7cddfSDavid du Colombier 	}
91*7dd7cddfSDavid du Colombier 
92*7dd7cddfSDavid du Colombier 	while(*s){
93*7dd7cddfSDavid du Colombier 		s += chartorune(&r, s);
94*7dd7cddfSDavid du Colombier 		if(r == '\'') {
95*7dd7cddfSDavid du Colombier 			if(*s == '\'')
96*7dd7cddfSDavid du Colombier 				s++;
97*7dd7cddfSDavid du Colombier 			else
98*7dd7cddfSDavid du Colombier 				return s;
99*7dd7cddfSDavid du Colombier 		}
100*7dd7cddfSDavid du Colombier 		rinsert(b, r);
101*7dd7cddfSDavid du Colombier 	}
102*7dd7cddfSDavid du Colombier 	return 0;
103*7dd7cddfSDavid du Colombier }
104*7dd7cddfSDavid du Colombier 
105*7dd7cddfSDavid du Colombier /*
106*7dd7cddfSDavid du Colombier  *	Input an escaped token.  Possible escape chars are single-quote,
107*7dd7cddfSDavid du Colombier  *	double-quote and backslash.  Only the first is a valid escape for
108*7dd7cddfSDavid du Colombier  *	rc; the others are just inserted into the receiving buffer.
109*7dd7cddfSDavid du Colombier  */
110*7dd7cddfSDavid du Colombier int
escapetoken(Biobuf * bp,Bufblock * buf,int preserve,int esc)111*7dd7cddfSDavid du Colombier escapetoken(Biobuf *bp, Bufblock *buf, int preserve, int esc)
112*7dd7cddfSDavid du Colombier {
113*7dd7cddfSDavid du Colombier 	int c, line;
114*7dd7cddfSDavid du Colombier 
115*7dd7cddfSDavid du Colombier 	if(esc != '\'')
116*7dd7cddfSDavid du Colombier 		return 1;
117*7dd7cddfSDavid du Colombier 
118*7dd7cddfSDavid du Colombier 	line = mkinline;
119*7dd7cddfSDavid du Colombier 	while((c = nextrune(bp, 0)) > 0){
120*7dd7cddfSDavid du Colombier 		if(c == '\''){
121*7dd7cddfSDavid du Colombier 			if(preserve)
122*7dd7cddfSDavid du Colombier 				rinsert(buf, c);
123*7dd7cddfSDavid du Colombier 			c = Bgetrune(bp);
124*7dd7cddfSDavid du Colombier 			if (c < 0)
125*7dd7cddfSDavid du Colombier 				break;
126*7dd7cddfSDavid du Colombier 			if(c != '\''){
127*7dd7cddfSDavid du Colombier 				Bungetrune(bp);
128*7dd7cddfSDavid du Colombier 				return 1;
129*7dd7cddfSDavid du Colombier 			}
130*7dd7cddfSDavid du Colombier 		}
131*7dd7cddfSDavid du Colombier 		rinsert(buf, c);
132*7dd7cddfSDavid du Colombier 	}
133*7dd7cddfSDavid du Colombier 	SYNERR(line); fprint(2, "missing closing %c\n", esc);
134*7dd7cddfSDavid du Colombier 	return 0;
135*7dd7cddfSDavid du Colombier }
136*7dd7cddfSDavid du Colombier 
137*7dd7cddfSDavid du Colombier /*
138*7dd7cddfSDavid du Colombier  *	copy a single-quoted string; s points to char after opening quote
139*7dd7cddfSDavid du Colombier  */
140*7dd7cddfSDavid du Colombier static char *
copysingle(char * s,Bufblock * buf)141*7dd7cddfSDavid du Colombier copysingle(char *s, Bufblock *buf)
142*7dd7cddfSDavid du Colombier {
143*7dd7cddfSDavid du Colombier 	Rune r;
144*7dd7cddfSDavid du Colombier 
145*7dd7cddfSDavid du Colombier 	while(*s){
146*7dd7cddfSDavid du Colombier 		s += chartorune(&r, s);
147*7dd7cddfSDavid du Colombier 		rinsert(buf, r);
148*7dd7cddfSDavid du Colombier 		if(r == '\'')
149*7dd7cddfSDavid du Colombier 			break;
150*7dd7cddfSDavid du Colombier 	}
151*7dd7cddfSDavid du Colombier 	return s;
152*7dd7cddfSDavid du Colombier }
153*7dd7cddfSDavid du Colombier /*
154*7dd7cddfSDavid du Colombier  *	check for quoted strings.  backquotes are handled here; single quotes above.
155*7dd7cddfSDavid du Colombier  *	s points to char after opening quote, q.
156*7dd7cddfSDavid du Colombier  */
157*7dd7cddfSDavid du Colombier char *
copyq(char * s,Rune q,Bufblock * buf)158*7dd7cddfSDavid du Colombier copyq(char *s, Rune q, Bufblock *buf)
159*7dd7cddfSDavid du Colombier {
160*7dd7cddfSDavid du Colombier 	if(q == '\'')				/* copy quoted string */
161*7dd7cddfSDavid du Colombier 		return copysingle(s, buf);
162*7dd7cddfSDavid du Colombier 
163*7dd7cddfSDavid du Colombier 	if(q != '`')				/* not quoted */
164*7dd7cddfSDavid du Colombier 		return s;
165*7dd7cddfSDavid du Colombier 
166*7dd7cddfSDavid du Colombier 	while(*s){				/* copy backquoted string */
167*7dd7cddfSDavid du Colombier 		s += chartorune(&q, s);
168*7dd7cddfSDavid du Colombier 		rinsert(buf, q);
169*7dd7cddfSDavid du Colombier 		if(q == '}')
170*7dd7cddfSDavid du Colombier 			break;
171*7dd7cddfSDavid du Colombier 		if(q == '\'')
172*7dd7cddfSDavid du Colombier 			s = copysingle(s, buf);	/* copy quoted string */
173*7dd7cddfSDavid du Colombier 	}
174*7dd7cddfSDavid du Colombier 	return s;
175*7dd7cddfSDavid du Colombier }
176