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