trc.c - plan9port - [fork] Plan 9 from user space | |
git clone git://src.adamsgaard.dk/plan9port | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
trc.c (3271B) | |
--- | |
1 #include "mk.h" | |
2 | |
3 /* | |
4 * This file contains functions that depend on rc's syntax. Most | |
5 * of the routines extract strings observing rc's escape conventi… | |
6 */ | |
7 | |
8 | |
9 /* | |
10 * skip a token in single quotes. | |
11 */ | |
12 static char * | |
13 squote(char *cp) | |
14 { | |
15 Rune r; | |
16 int n; | |
17 | |
18 while(*cp){ | |
19 n = chartorune(&r, cp); | |
20 if(r == '\'') { | |
21 n += chartorune(&r, cp+n); | |
22 if(r != '\'') | |
23 return(cp); | |
24 } | |
25 cp += n; | |
26 } | |
27 SYNERR(-1); /* should never occur */ | |
28 fprint(2, "missing closing '\n"); | |
29 return 0; | |
30 } | |
31 | |
32 /* | |
33 * search a string for characters in a pattern set | |
34 * characters in quotes and variable generators are escaped | |
35 */ | |
36 char * | |
37 rccharin(char *cp, char *pat) | |
38 { | |
39 Rune r; | |
40 int n, vargen; | |
41 | |
42 vargen = 0; | |
43 while(*cp){ | |
44 n = chartorune(&r, cp); | |
45 switch(r){ | |
46 case '\'': /* skip quoted string … | |
47 cp = squote(cp+1); /* n must = 1 */ | |
48 if(!cp) | |
49 return 0; | |
50 break; | |
51 case '$': | |
52 if(*(cp+1) == '{') | |
53 vargen = 1; | |
54 break; | |
55 case '}': | |
56 if(vargen) | |
57 vargen = 0; | |
58 else if(utfrune(pat, r)) | |
59 return cp; | |
60 break; | |
61 default: | |
62 if(vargen == 0 && utfrune(pat, r)) | |
63 return cp; | |
64 break; | |
65 } | |
66 cp += n; | |
67 } | |
68 if(vargen){ | |
69 SYNERR(-1); | |
70 fprint(2, "missing closing } in pattern generator\n"); | |
71 } | |
72 return 0; | |
73 } | |
74 | |
75 /* | |
76 * extract an escaped token. Possible escape chars are single-qu… | |
77 * double-quote,and backslash. Only the first is valid for rc. t… | |
78 * others are just inserted into the receiving buffer. | |
79 */ | |
80 char* | |
81 rcexpandquote(char *s, Rune r, Bufblock *b) | |
82 { | |
83 if (r != '\'') { | |
84 rinsert(b, r); | |
85 return s; | |
86 } | |
87 | |
88 while(*s){ | |
89 s += chartorune(&r, s); | |
90 if(r == '\'') { | |
91 if(*s == '\'') | |
92 s++; | |
93 else | |
94 return s; | |
95 } | |
96 rinsert(b, r); | |
97 } | |
98 return 0; | |
99 } | |
100 | |
101 /* | |
102 * Input an escaped token. Possible escape chars are single-quot… | |
103 * double-quote and backslash. Only the first is a valid escape … | |
104 * rc; the others are just inserted into the receiving buffer. | |
105 */ | |
106 int | |
107 rcescapetoken(Biobuf *bp, Bufblock *buf, int preserve, int esc) | |
108 { | |
109 int c, line; | |
110 | |
111 if(esc != '\'') | |
112 return 1; | |
113 | |
114 line = mkinline; | |
115 while((c = nextrune(bp, 0)) > 0){ | |
116 if(c == '\''){ | |
117 if(preserve) | |
118 rinsert(buf, c); | |
119 c = Bgetrune(bp); | |
120 if (c < 0) | |
121 break; | |
122 if(c != '\''){ | |
123 Bungetrune(bp); | |
124 return 1; | |
125 } | |
126 } | |
127 rinsert(buf, c); | |
128 } | |
129 SYNERR(line); fprint(2, "missing closing %c\n", esc); | |
130 return 0; | |
131 } | |
132 | |
133 /* | |
134 * copy a single-quoted string; s points to char after opening qu… | |
135 */ | |
136 static char * | |
137 copysingle(char *s, Bufblock *buf) | |
138 { | |
139 Rune r; | |
140 | |
141 while(*s){ | |
142 s += chartorune(&r, s); | |
143 rinsert(buf, r); | |
144 if(r == '\'') | |
145 break; | |
146 } | |
147 return s; | |
148 } | |
149 /* | |
150 * check for quoted strings. backquotes are handled here; single… | |
151 * s points to char after opening quote, q. | |
152 */ | |
153 char * | |
154 rccopyq(char *s, Rune q, Bufblock *buf) | |
155 { | |
156 if(q == '\'') /* copy quoted stri… | |
157 return copysingle(s, buf); | |
158 | |
159 if(q != '`') /* not quoted */ | |
160 return s; | |
161 | |
162 while(*s){ /* copy backquoted str… | |
163 s += chartorune(&q, s); | |
164 rinsert(buf, q); | |
165 if(q == '}') | |
166 break; | |
167 if(q == '\'') | |
168 s = copysingle(s, buf); /* copy quoted st… | |
169 } | |
170 return s; | |
171 } | |
172 | |
173 static int | |
174 rcmatchname(char *name) | |
175 { | |
176 char *p; | |
177 | |
178 if((p = strrchr(name, '/')) != nil) | |
179 name = p+1; | |
180 if(name[0] == 'r' && name[1] == 'c') | |
181 return 1; | |
182 return 0; | |
183 } | |
184 | |
185 Shell rcshell = { | |
186 "rc", | |
187 "'= \t", | |
188 '\1', | |
189 rccharin, | |
190 rcexpandquote, | |
191 rcescapetoken, | |
192 rccopyq, | |
193 rcmatchname | |
194 }; |