Blame


1 76193d7c 2003-09-30 devnull #include "sam.h"
2 76193d7c 2003-09-30 devnull #include "parse.h"
3 76193d7c 2003-09-30 devnull
4 76193d7c 2003-09-30 devnull static char linex[]="\n";
5 76193d7c 2003-09-30 devnull static char wordx[]=" \t\n";
6 76193d7c 2003-09-30 devnull struct cmdtab cmdtab[]={
7 76193d7c 2003-09-30 devnull /* cmdc text regexp addr defcmd defaddr count token fn */
8 76193d7c 2003-09-30 devnull '\n', 0, 0, 0, 0, aDot, 0, 0, nl_cmd,
9 76193d7c 2003-09-30 devnull 'a', 1, 0, 0, 0, aDot, 0, 0, a_cmd,
10 76193d7c 2003-09-30 devnull 'b', 0, 0, 0, 0, aNo, 0, linex, b_cmd,
11 76193d7c 2003-09-30 devnull 'B', 0, 0, 0, 0, aNo, 0, linex, b_cmd,
12 76193d7c 2003-09-30 devnull 'c', 1, 0, 0, 0, aDot, 0, 0, c_cmd,
13 76193d7c 2003-09-30 devnull 'd', 0, 0, 0, 0, aDot, 0, 0, d_cmd,
14 76193d7c 2003-09-30 devnull 'D', 0, 0, 0, 0, aNo, 0, linex, D_cmd,
15 76193d7c 2003-09-30 devnull 'e', 0, 0, 0, 0, aNo, 0, wordx, e_cmd,
16 76193d7c 2003-09-30 devnull 'f', 0, 0, 0, 0, aNo, 0, wordx, f_cmd,
17 76193d7c 2003-09-30 devnull 'g', 0, 1, 0, 'p', aDot, 0, 0, g_cmd,
18 76193d7c 2003-09-30 devnull 'i', 1, 0, 0, 0, aDot, 0, 0, i_cmd,
19 76193d7c 2003-09-30 devnull 'k', 0, 0, 0, 0, aDot, 0, 0, k_cmd,
20 76193d7c 2003-09-30 devnull 'm', 0, 0, 1, 0, aDot, 0, 0, m_cmd,
21 76193d7c 2003-09-30 devnull 'n', 0, 0, 0, 0, aNo, 0, 0, n_cmd,
22 76193d7c 2003-09-30 devnull 'p', 0, 0, 0, 0, aDot, 0, 0, p_cmd,
23 76193d7c 2003-09-30 devnull 'q', 0, 0, 0, 0, aNo, 0, 0, q_cmd,
24 76193d7c 2003-09-30 devnull 'r', 0, 0, 0, 0, aDot, 0, wordx, e_cmd,
25 76193d7c 2003-09-30 devnull 's', 0, 1, 0, 0, aDot, 1, 0, s_cmd,
26 76193d7c 2003-09-30 devnull 't', 0, 0, 1, 0, aDot, 0, 0, m_cmd,
27 76193d7c 2003-09-30 devnull 'u', 0, 0, 0, 0, aNo, 2, 0, u_cmd,
28 76193d7c 2003-09-30 devnull 'v', 0, 1, 0, 'p', aDot, 0, 0, g_cmd,
29 76193d7c 2003-09-30 devnull 'w', 0, 0, 0, 0, aAll, 0, wordx, w_cmd,
30 76193d7c 2003-09-30 devnull 'x', 0, 1, 0, 'p', aDot, 0, 0, x_cmd,
31 76193d7c 2003-09-30 devnull 'y', 0, 1, 0, 'p', aDot, 0, 0, x_cmd,
32 76193d7c 2003-09-30 devnull 'X', 0, 1, 0, 'f', aNo, 0, 0, X_cmd,
33 76193d7c 2003-09-30 devnull 'Y', 0, 1, 0, 'f', aNo, 0, 0, X_cmd,
34 76193d7c 2003-09-30 devnull '!', 0, 0, 0, 0, aNo, 0, linex, plan9_cmd,
35 76193d7c 2003-09-30 devnull '>', 0, 0, 0, 0, aDot, 0, linex, plan9_cmd,
36 76193d7c 2003-09-30 devnull '<', 0, 0, 0, 0, aDot, 0, linex, plan9_cmd,
37 76193d7c 2003-09-30 devnull '|', 0, 0, 0, 0, aDot, 0, linex, plan9_cmd,
38 76193d7c 2003-09-30 devnull '=', 0, 0, 0, 0, aDot, 0, linex, eq_cmd,
39 76193d7c 2003-09-30 devnull 'c'|0x100,0, 0, 0, 0, aNo, 0, wordx, cd_cmd,
40 cbeb0b26 2006-04-01 devnull 0, 0, 0, 0, 0, 0, 0, 0
41 76193d7c 2003-09-30 devnull };
42 76193d7c 2003-09-30 devnull Cmd *parsecmd(int);
43 76193d7c 2003-09-30 devnull Addr *compoundaddr(void);
44 76193d7c 2003-09-30 devnull Addr *simpleaddr(void);
45 76193d7c 2003-09-30 devnull void freecmd(void);
46 76193d7c 2003-09-30 devnull void okdelim(int);
47 76193d7c 2003-09-30 devnull
48 76193d7c 2003-09-30 devnull Rune line[BLOCKSIZE];
49 76193d7c 2003-09-30 devnull Rune termline[BLOCKSIZE];
50 76193d7c 2003-09-30 devnull Rune *linep = line;
51 76193d7c 2003-09-30 devnull Rune *terminp = termline;
52 76193d7c 2003-09-30 devnull Rune *termoutp = termline;
53 2c0f3733 2006-04-20 devnull
54 2c0f3733 2006-04-20 devnull List cmdlist = { 'p' };
55 2c0f3733 2006-04-20 devnull List addrlist = { 'p' };
56 2c0f3733 2006-04-20 devnull List relist = { 'p' };
57 2c0f3733 2006-04-20 devnull List stringlist = { 'p' };
58 2c0f3733 2006-04-20 devnull
59 76193d7c 2003-09-30 devnull int eof;
60 76193d7c 2003-09-30 devnull
61 76193d7c 2003-09-30 devnull void
62 76193d7c 2003-09-30 devnull resetcmd(void)
63 76193d7c 2003-09-30 devnull {
64 76193d7c 2003-09-30 devnull linep = line;
65 76193d7c 2003-09-30 devnull *linep = 0;
66 76193d7c 2003-09-30 devnull terminp = termoutp = termline;
67 76193d7c 2003-09-30 devnull freecmd();
68 76193d7c 2003-09-30 devnull }
69 76193d7c 2003-09-30 devnull
70 76193d7c 2003-09-30 devnull int
71 76193d7c 2003-09-30 devnull inputc(void)
72 76193d7c 2003-09-30 devnull {
73 76193d7c 2003-09-30 devnull int n, nbuf;
74 0cadb430 2009-09-11 russcox char buf[UTFmax];
75 76193d7c 2003-09-30 devnull Rune r;
76 76193d7c 2003-09-30 devnull
77 76193d7c 2003-09-30 devnull Again:
78 76193d7c 2003-09-30 devnull nbuf = 0;
79 76193d7c 2003-09-30 devnull if(downloaded){
80 76193d7c 2003-09-30 devnull while(termoutp == terminp){
81 76193d7c 2003-09-30 devnull cmdupdate();
82 76193d7c 2003-09-30 devnull if(patset)
83 76193d7c 2003-09-30 devnull tellpat();
84 76193d7c 2003-09-30 devnull while(termlocked > 0){
85 76193d7c 2003-09-30 devnull outT0(Hunlock);
86 76193d7c 2003-09-30 devnull termlocked--;
87 76193d7c 2003-09-30 devnull }
88 76193d7c 2003-09-30 devnull if(rcv() == 0)
89 76193d7c 2003-09-30 devnull return -1;
90 76193d7c 2003-09-30 devnull }
91 76193d7c 2003-09-30 devnull r = *termoutp++;
92 76193d7c 2003-09-30 devnull if(termoutp == terminp)
93 76193d7c 2003-09-30 devnull terminp = termoutp = termline;
94 76193d7c 2003-09-30 devnull }else{
95 76193d7c 2003-09-30 devnull do{
96 76193d7c 2003-09-30 devnull n = read(0, buf+nbuf, 1);
97 76193d7c 2003-09-30 devnull if(n <= 0)
98 76193d7c 2003-09-30 devnull return -1;
99 76193d7c 2003-09-30 devnull nbuf += n;
100 76193d7c 2003-09-30 devnull }while(!fullrune(buf, nbuf));
101 76193d7c 2003-09-30 devnull chartorune(&r, buf);
102 76193d7c 2003-09-30 devnull }
103 76193d7c 2003-09-30 devnull if(r == 0){
104 76193d7c 2003-09-30 devnull warn(Wnulls);
105 76193d7c 2003-09-30 devnull goto Again;
106 76193d7c 2003-09-30 devnull }
107 76193d7c 2003-09-30 devnull return r;
108 76193d7c 2003-09-30 devnull }
109 76193d7c 2003-09-30 devnull
110 76193d7c 2003-09-30 devnull int
111 76193d7c 2003-09-30 devnull inputline(void)
112 76193d7c 2003-09-30 devnull {
113 2c0f3733 2006-04-20 devnull int i, c, start;
114 76193d7c 2003-09-30 devnull
115 2c0f3733 2006-04-20 devnull /*
116 2c0f3733 2006-04-20 devnull * Could set linep = line and i = 0 here and just
117 2c0f3733 2006-04-20 devnull * error(Etoolong) below, but this way we keep
118 2c0f3733 2006-04-20 devnull * old input buffer history around for a while.
119 2c0f3733 2006-04-20 devnull * This is useful only for debugging.
120 2c0f3733 2006-04-20 devnull */
121 2c0f3733 2006-04-20 devnull i = linep - line;
122 76193d7c 2003-09-30 devnull do{
123 76193d7c 2003-09-30 devnull if((c = inputc())<=0)
124 76193d7c 2003-09-30 devnull return -1;
125 2c0f3733 2006-04-20 devnull if(i == nelem(line)-1){
126 2c0f3733 2006-04-20 devnull if(linep == line)
127 2c0f3733 2006-04-20 devnull error(Etoolong);
128 2c0f3733 2006-04-20 devnull start = linep - line;
129 2c0f3733 2006-04-20 devnull runemove(line, linep, i-start);
130 2c0f3733 2006-04-20 devnull i -= start;
131 2c0f3733 2006-04-20 devnull linep = line;
132 2c0f3733 2006-04-20 devnull }
133 76193d7c 2003-09-30 devnull }while((line[i++]=c) != '\n');
134 76193d7c 2003-09-30 devnull line[i] = 0;
135 76193d7c 2003-09-30 devnull return 1;
136 76193d7c 2003-09-30 devnull }
137 76193d7c 2003-09-30 devnull
138 76193d7c 2003-09-30 devnull int
139 76193d7c 2003-09-30 devnull getch(void)
140 76193d7c 2003-09-30 devnull {
141 76193d7c 2003-09-30 devnull if(eof)
142 76193d7c 2003-09-30 devnull return -1;
143 76193d7c 2003-09-30 devnull if(*linep==0 && inputline()<0){
144 76193d7c 2003-09-30 devnull eof = TRUE;
145 76193d7c 2003-09-30 devnull return -1;
146 76193d7c 2003-09-30 devnull }
147 76193d7c 2003-09-30 devnull return *linep++;
148 76193d7c 2003-09-30 devnull }
149 76193d7c 2003-09-30 devnull
150 76193d7c 2003-09-30 devnull int
151 76193d7c 2003-09-30 devnull nextc(void)
152 76193d7c 2003-09-30 devnull {
153 76193d7c 2003-09-30 devnull if(*linep == 0)
154 76193d7c 2003-09-30 devnull return -1;
155 76193d7c 2003-09-30 devnull return *linep;
156 76193d7c 2003-09-30 devnull }
157 76193d7c 2003-09-30 devnull
158 76193d7c 2003-09-30 devnull void
159 76193d7c 2003-09-30 devnull ungetch(void)
160 76193d7c 2003-09-30 devnull {
161 76193d7c 2003-09-30 devnull if(--linep < line)
162 76193d7c 2003-09-30 devnull panic("ungetch");
163 76193d7c 2003-09-30 devnull }
164 76193d7c 2003-09-30 devnull
165 76193d7c 2003-09-30 devnull Posn
166 76193d7c 2003-09-30 devnull getnum(int signok)
167 76193d7c 2003-09-30 devnull {
168 76193d7c 2003-09-30 devnull Posn n=0;
169 76193d7c 2003-09-30 devnull int c, sign;
170 76193d7c 2003-09-30 devnull
171 76193d7c 2003-09-30 devnull sign = 1;
172 76193d7c 2003-09-30 devnull if(signok>1 && nextc()=='-'){
173 76193d7c 2003-09-30 devnull sign = -1;
174 76193d7c 2003-09-30 devnull getch();
175 76193d7c 2003-09-30 devnull }
176 76193d7c 2003-09-30 devnull if((c=nextc())<'0' || '9'<c) /* no number defaults to 1 */
177 76193d7c 2003-09-30 devnull return sign;
178 76193d7c 2003-09-30 devnull while('0'<=(c=getch()) && c<='9')
179 76193d7c 2003-09-30 devnull n = n*10 + (c-'0');
180 76193d7c 2003-09-30 devnull ungetch();
181 76193d7c 2003-09-30 devnull return sign*n;
182 76193d7c 2003-09-30 devnull }
183 76193d7c 2003-09-30 devnull
184 76193d7c 2003-09-30 devnull int
185 76193d7c 2003-09-30 devnull skipbl(void)
186 76193d7c 2003-09-30 devnull {
187 76193d7c 2003-09-30 devnull int c;
188 76193d7c 2003-09-30 devnull do
189 76193d7c 2003-09-30 devnull c = getch();
190 76193d7c 2003-09-30 devnull while(c==' ' || c=='\t');
191 76193d7c 2003-09-30 devnull if(c >= 0)
192 76193d7c 2003-09-30 devnull ungetch();
193 76193d7c 2003-09-30 devnull return c;
194 76193d7c 2003-09-30 devnull }
195 76193d7c 2003-09-30 devnull
196 76193d7c 2003-09-30 devnull void
197 76193d7c 2003-09-30 devnull termcommand(void)
198 76193d7c 2003-09-30 devnull {
199 76193d7c 2003-09-30 devnull Posn p;
200 76193d7c 2003-09-30 devnull
201 522b0689 2003-09-30 devnull for(p=cmdpt; p<cmd->b.nc; p++){
202 76193d7c 2003-09-30 devnull if(terminp >= &termline[BLOCKSIZE]){
203 522b0689 2003-09-30 devnull cmdpt = cmd->b.nc;
204 76193d7c 2003-09-30 devnull error(Etoolong);
205 76193d7c 2003-09-30 devnull }
206 76193d7c 2003-09-30 devnull *terminp++ = filereadc(cmd, p);
207 76193d7c 2003-09-30 devnull }
208 522b0689 2003-09-30 devnull cmdpt = cmd->b.nc;
209 76193d7c 2003-09-30 devnull }
210 76193d7c 2003-09-30 devnull
211 76193d7c 2003-09-30 devnull void
212 76193d7c 2003-09-30 devnull cmdloop(void)
213 76193d7c 2003-09-30 devnull {
214 76193d7c 2003-09-30 devnull Cmd *cmdp;
215 76193d7c 2003-09-30 devnull File *ocurfile;
216 76193d7c 2003-09-30 devnull int loaded;
217 76193d7c 2003-09-30 devnull
218 76193d7c 2003-09-30 devnull for(;;){
219 76193d7c 2003-09-30 devnull if(!downloaded && curfile && curfile->unread)
220 76193d7c 2003-09-30 devnull load(curfile);
221 76193d7c 2003-09-30 devnull if((cmdp = parsecmd(0))==0){
222 76193d7c 2003-09-30 devnull if(downloaded){
223 76193d7c 2003-09-30 devnull rescue();
224 76193d7c 2003-09-30 devnull exits("eof");
225 76193d7c 2003-09-30 devnull }
226 76193d7c 2003-09-30 devnull break;
227 76193d7c 2003-09-30 devnull }
228 76193d7c 2003-09-30 devnull ocurfile = curfile;
229 76193d7c 2003-09-30 devnull loaded = curfile && !curfile->unread;
230 76193d7c 2003-09-30 devnull if(cmdexec(curfile, cmdp) == 0)
231 76193d7c 2003-09-30 devnull break;
232 76193d7c 2003-09-30 devnull freecmd();
233 76193d7c 2003-09-30 devnull cmdupdate();
234 76193d7c 2003-09-30 devnull update();
235 76193d7c 2003-09-30 devnull if(downloaded && curfile &&
236 76193d7c 2003-09-30 devnull (ocurfile!=curfile || (!loaded && !curfile->unread)))
237 76193d7c 2003-09-30 devnull outTs(Hcurrent, curfile->tag);
238 76193d7c 2003-09-30 devnull /* don't allow type ahead on files that aren't bound */
239 76193d7c 2003-09-30 devnull if(downloaded && curfile && curfile->rasp == 0)
240 76193d7c 2003-09-30 devnull terminp = termoutp;
241 76193d7c 2003-09-30 devnull }
242 76193d7c 2003-09-30 devnull }
243 76193d7c 2003-09-30 devnull
244 76193d7c 2003-09-30 devnull Cmd *
245 76193d7c 2003-09-30 devnull newcmd(void){
246 76193d7c 2003-09-30 devnull Cmd *p;
247 76193d7c 2003-09-30 devnull
248 76193d7c 2003-09-30 devnull p = emalloc(sizeof(Cmd));
249 76193d7c 2003-09-30 devnull inslist(&cmdlist, cmdlist.nused, (long)p);
250 76193d7c 2003-09-30 devnull return p;
251 76193d7c 2003-09-30 devnull }
252 76193d7c 2003-09-30 devnull
253 76193d7c 2003-09-30 devnull Addr*
254 76193d7c 2003-09-30 devnull newaddr(void)
255 76193d7c 2003-09-30 devnull {
256 76193d7c 2003-09-30 devnull Addr *p;
257 76193d7c 2003-09-30 devnull
258 76193d7c 2003-09-30 devnull p = emalloc(sizeof(Addr));
259 76193d7c 2003-09-30 devnull inslist(&addrlist, addrlist.nused, (long)p);
260 76193d7c 2003-09-30 devnull return p;
261 76193d7c 2003-09-30 devnull }
262 76193d7c 2003-09-30 devnull
263 76193d7c 2003-09-30 devnull String*
264 76193d7c 2003-09-30 devnull newre(void)
265 76193d7c 2003-09-30 devnull {
266 76193d7c 2003-09-30 devnull String *p;
267 76193d7c 2003-09-30 devnull
268 76193d7c 2003-09-30 devnull p = emalloc(sizeof(String));
269 76193d7c 2003-09-30 devnull inslist(&relist, relist.nused, (long)p);
270 76193d7c 2003-09-30 devnull Strinit(p);
271 76193d7c 2003-09-30 devnull return p;
272 76193d7c 2003-09-30 devnull }
273 76193d7c 2003-09-30 devnull
274 76193d7c 2003-09-30 devnull String*
275 76193d7c 2003-09-30 devnull newstring(void)
276 76193d7c 2003-09-30 devnull {
277 76193d7c 2003-09-30 devnull String *p;
278 76193d7c 2003-09-30 devnull
279 76193d7c 2003-09-30 devnull p = emalloc(sizeof(String));
280 76193d7c 2003-09-30 devnull inslist(&stringlist, stringlist.nused, (long)p);
281 76193d7c 2003-09-30 devnull Strinit(p);
282 76193d7c 2003-09-30 devnull return p;
283 76193d7c 2003-09-30 devnull }
284 76193d7c 2003-09-30 devnull
285 76193d7c 2003-09-30 devnull void
286 76193d7c 2003-09-30 devnull freecmd(void)
287 76193d7c 2003-09-30 devnull {
288 76193d7c 2003-09-30 devnull int i;
289 76193d7c 2003-09-30 devnull
290 76193d7c 2003-09-30 devnull while(cmdlist.nused > 0)
291 2c0f3733 2006-04-20 devnull free(cmdlist.voidpptr[--cmdlist.nused]);
292 76193d7c 2003-09-30 devnull while(addrlist.nused > 0)
293 2c0f3733 2006-04-20 devnull free(addrlist.voidpptr[--addrlist.nused]);
294 76193d7c 2003-09-30 devnull while(relist.nused > 0){
295 76193d7c 2003-09-30 devnull i = --relist.nused;
296 76193d7c 2003-09-30 devnull Strclose(relist.stringpptr[i]);
297 76193d7c 2003-09-30 devnull free(relist.stringpptr[i]);
298 76193d7c 2003-09-30 devnull }
299 76193d7c 2003-09-30 devnull while(stringlist.nused>0){
300 76193d7c 2003-09-30 devnull i = --stringlist.nused;
301 76193d7c 2003-09-30 devnull Strclose(stringlist.stringpptr[i]);
302 76193d7c 2003-09-30 devnull free(stringlist.stringpptr[i]);
303 76193d7c 2003-09-30 devnull }
304 76193d7c 2003-09-30 devnull }
305 76193d7c 2003-09-30 devnull
306 76193d7c 2003-09-30 devnull int
307 76193d7c 2003-09-30 devnull lookup(int c)
308 76193d7c 2003-09-30 devnull {
309 76193d7c 2003-09-30 devnull int i;
310 76193d7c 2003-09-30 devnull
311 76193d7c 2003-09-30 devnull for(i=0; cmdtab[i].cmdc; i++)
312 76193d7c 2003-09-30 devnull if(cmdtab[i].cmdc == c)
313 76193d7c 2003-09-30 devnull return i;
314 76193d7c 2003-09-30 devnull return -1;
315 76193d7c 2003-09-30 devnull }
316 76193d7c 2003-09-30 devnull
317 76193d7c 2003-09-30 devnull void
318 76193d7c 2003-09-30 devnull okdelim(int c)
319 76193d7c 2003-09-30 devnull {
320 76193d7c 2003-09-30 devnull if(c=='\\' || ('a'<=c && c<='z')
321 76193d7c 2003-09-30 devnull || ('A'<=c && c<='Z') || ('0'<=c && c<='9'))
322 76193d7c 2003-09-30 devnull error_c(Edelim, c);
323 76193d7c 2003-09-30 devnull }
324 76193d7c 2003-09-30 devnull
325 76193d7c 2003-09-30 devnull void
326 76193d7c 2003-09-30 devnull atnl(void)
327 76193d7c 2003-09-30 devnull {
328 76193d7c 2003-09-30 devnull skipbl();
329 76193d7c 2003-09-30 devnull if(getch() != '\n')
330 76193d7c 2003-09-30 devnull error(Enewline);
331 76193d7c 2003-09-30 devnull }
332 76193d7c 2003-09-30 devnull
333 76193d7c 2003-09-30 devnull void
334 76193d7c 2003-09-30 devnull getrhs(String *s, int delim, int cmd)
335 76193d7c 2003-09-30 devnull {
336 76193d7c 2003-09-30 devnull int c;
337 76193d7c 2003-09-30 devnull
338 76193d7c 2003-09-30 devnull while((c = getch())>0 && c!=delim && c!='\n'){
339 76193d7c 2003-09-30 devnull if(c == '\\'){
340 76193d7c 2003-09-30 devnull if((c=getch()) <= 0)
341 76193d7c 2003-09-30 devnull error(Ebadrhs);
342 76193d7c 2003-09-30 devnull if(c == '\n'){
343 76193d7c 2003-09-30 devnull ungetch();
344 76193d7c 2003-09-30 devnull c='\\';
345 76193d7c 2003-09-30 devnull }else if(c == 'n')
346 76193d7c 2003-09-30 devnull c='\n';
347 76193d7c 2003-09-30 devnull else if(c!=delim && (cmd=='s' || c!='\\')) /* s does its own */
348 76193d7c 2003-09-30 devnull Straddc(s, '\\');
349 76193d7c 2003-09-30 devnull }
350 76193d7c 2003-09-30 devnull Straddc(s, c);
351 76193d7c 2003-09-30 devnull }
352 76193d7c 2003-09-30 devnull ungetch(); /* let client read whether delimeter, '\n' or whatever */
353 76193d7c 2003-09-30 devnull }
354 76193d7c 2003-09-30 devnull
355 76193d7c 2003-09-30 devnull String *
356 76193d7c 2003-09-30 devnull collecttoken(char *end)
357 76193d7c 2003-09-30 devnull {
358 76193d7c 2003-09-30 devnull String *s = newstring();
359 76193d7c 2003-09-30 devnull int c;
360 76193d7c 2003-09-30 devnull
361 76193d7c 2003-09-30 devnull while((c=nextc())==' ' || c=='\t')
362 76193d7c 2003-09-30 devnull Straddc(s, getch()); /* blanks significant for getname() */
363 76193d7c 2003-09-30 devnull while((c=getch())>0 && utfrune(end, c)==0)
364 76193d7c 2003-09-30 devnull Straddc(s, c);
365 76193d7c 2003-09-30 devnull Straddc(s, 0);
366 76193d7c 2003-09-30 devnull if(c != '\n')
367 76193d7c 2003-09-30 devnull atnl();
368 76193d7c 2003-09-30 devnull return s;
369 76193d7c 2003-09-30 devnull }
370 76193d7c 2003-09-30 devnull
371 76193d7c 2003-09-30 devnull String *
372 76193d7c 2003-09-30 devnull collecttext(void)
373 76193d7c 2003-09-30 devnull {
374 76193d7c 2003-09-30 devnull String *s = newstring();
375 76193d7c 2003-09-30 devnull int begline, i, c, delim;
376 76193d7c 2003-09-30 devnull
377 76193d7c 2003-09-30 devnull if(skipbl()=='\n'){
378 76193d7c 2003-09-30 devnull getch();
379 76193d7c 2003-09-30 devnull i = 0;
380 76193d7c 2003-09-30 devnull do{
381 76193d7c 2003-09-30 devnull begline = i;
382 76193d7c 2003-09-30 devnull while((c = getch())>0 && c!='\n')
383 76193d7c 2003-09-30 devnull i++, Straddc(s, c);
384 76193d7c 2003-09-30 devnull i++, Straddc(s, '\n');
385 76193d7c 2003-09-30 devnull if(c < 0)
386 76193d7c 2003-09-30 devnull goto Return;
387 76193d7c 2003-09-30 devnull }while(s->s[begline]!='.' || s->s[begline+1]!='\n');
388 76193d7c 2003-09-30 devnull Strdelete(s, s->n-2, s->n);
389 76193d7c 2003-09-30 devnull }else{
390 76193d7c 2003-09-30 devnull okdelim(delim = getch());
391 76193d7c 2003-09-30 devnull getrhs(s, delim, 'a');
392 76193d7c 2003-09-30 devnull if(nextc()==delim)
393 76193d7c 2003-09-30 devnull getch();
394 76193d7c 2003-09-30 devnull atnl();
395 76193d7c 2003-09-30 devnull }
396 76193d7c 2003-09-30 devnull Return:
397 76193d7c 2003-09-30 devnull Straddc(s, 0); /* JUST FOR CMDPRINT() */
398 76193d7c 2003-09-30 devnull return s;
399 76193d7c 2003-09-30 devnull }
400 76193d7c 2003-09-30 devnull
401 76193d7c 2003-09-30 devnull Cmd *
402 76193d7c 2003-09-30 devnull parsecmd(int nest)
403 76193d7c 2003-09-30 devnull {
404 76193d7c 2003-09-30 devnull int i, c;
405 76193d7c 2003-09-30 devnull struct cmdtab *ct;
406 76193d7c 2003-09-30 devnull Cmd *cp, *ncp;
407 76193d7c 2003-09-30 devnull Cmd cmd;
408 76193d7c 2003-09-30 devnull
409 76193d7c 2003-09-30 devnull cmd.next = cmd.ccmd = 0;
410 76193d7c 2003-09-30 devnull cmd.re = 0;
411 76193d7c 2003-09-30 devnull cmd.flag = cmd.num = 0;
412 76193d7c 2003-09-30 devnull cmd.addr = compoundaddr();
413 76193d7c 2003-09-30 devnull if(skipbl() == -1)
414 76193d7c 2003-09-30 devnull return 0;
415 76193d7c 2003-09-30 devnull if((c=getch())==-1)
416 76193d7c 2003-09-30 devnull return 0;
417 76193d7c 2003-09-30 devnull cmd.cmdc = c;
418 76193d7c 2003-09-30 devnull if(cmd.cmdc=='c' && nextc()=='d'){ /* sleazy two-character case */
419 76193d7c 2003-09-30 devnull getch(); /* the 'd' */
420 76193d7c 2003-09-30 devnull cmd.cmdc='c'|0x100;
421 76193d7c 2003-09-30 devnull }
422 76193d7c 2003-09-30 devnull i = lookup(cmd.cmdc);
423 76193d7c 2003-09-30 devnull if(i >= 0){
424 76193d7c 2003-09-30 devnull if(cmd.cmdc == '\n')
425 76193d7c 2003-09-30 devnull goto Return; /* let nl_cmd work it all out */
426 76193d7c 2003-09-30 devnull ct = &cmdtab[i];
427 76193d7c 2003-09-30 devnull if(ct->defaddr==aNo && cmd.addr)
428 76193d7c 2003-09-30 devnull error(Enoaddr);
429 76193d7c 2003-09-30 devnull if(ct->count)
430 76193d7c 2003-09-30 devnull cmd.num = getnum(ct->count);
431 76193d7c 2003-09-30 devnull if(ct->regexp){
432 76193d7c 2003-09-30 devnull /* x without pattern -> .*\n, indicated by cmd.re==0 */
433 76193d7c 2003-09-30 devnull /* X without pattern is all files */
434 76193d7c 2003-09-30 devnull if((ct->cmdc!='x' && ct->cmdc!='X') ||
435 76193d7c 2003-09-30 devnull ((c = nextc())!=' ' && c!='\t' && c!='\n')){
436 76193d7c 2003-09-30 devnull skipbl();
437 76193d7c 2003-09-30 devnull if((c = getch())=='\n' || c<0)
438 76193d7c 2003-09-30 devnull error(Enopattern);
439 76193d7c 2003-09-30 devnull okdelim(c);
440 76193d7c 2003-09-30 devnull cmd.re = getregexp(c);
441 76193d7c 2003-09-30 devnull if(ct->cmdc == 's'){
442 76193d7c 2003-09-30 devnull cmd.ctext = newstring();
443 76193d7c 2003-09-30 devnull getrhs(cmd.ctext, c, 's');
444 76193d7c 2003-09-30 devnull if(nextc() == c){
445 76193d7c 2003-09-30 devnull getch();
446 76193d7c 2003-09-30 devnull if(nextc() == 'g')
447 76193d7c 2003-09-30 devnull cmd.flag = getch();
448 76193d7c 2003-09-30 devnull }
449 76193d7c 2003-09-30 devnull
450 76193d7c 2003-09-30 devnull }
451 76193d7c 2003-09-30 devnull }
452 76193d7c 2003-09-30 devnull }
453 76193d7c 2003-09-30 devnull if(ct->addr && (cmd.caddr=simpleaddr())==0)
454 76193d7c 2003-09-30 devnull error(Eaddress);
455 76193d7c 2003-09-30 devnull if(ct->defcmd){
456 76193d7c 2003-09-30 devnull if(skipbl() == '\n'){
457 76193d7c 2003-09-30 devnull getch();
458 76193d7c 2003-09-30 devnull cmd.ccmd = newcmd();
459 76193d7c 2003-09-30 devnull cmd.ccmd->cmdc = ct->defcmd;
460 76193d7c 2003-09-30 devnull }else if((cmd.ccmd = parsecmd(nest))==0)
461 76193d7c 2003-09-30 devnull panic("defcmd");
462 76193d7c 2003-09-30 devnull }else if(ct->text)
463 76193d7c 2003-09-30 devnull cmd.ctext = collecttext();
464 76193d7c 2003-09-30 devnull else if(ct->token)
465 76193d7c 2003-09-30 devnull cmd.ctext = collecttoken(ct->token);
466 76193d7c 2003-09-30 devnull else
467 76193d7c 2003-09-30 devnull atnl();
468 76193d7c 2003-09-30 devnull }else
469 76193d7c 2003-09-30 devnull switch(cmd.cmdc){
470 76193d7c 2003-09-30 devnull case '{':
471 76193d7c 2003-09-30 devnull cp = 0;
472 76193d7c 2003-09-30 devnull do{
473 76193d7c 2003-09-30 devnull if(skipbl()=='\n')
474 76193d7c 2003-09-30 devnull getch();
475 76193d7c 2003-09-30 devnull ncp = parsecmd(nest+1);
476 76193d7c 2003-09-30 devnull if(cp)
477 76193d7c 2003-09-30 devnull cp->next = ncp;
478 76193d7c 2003-09-30 devnull else
479 76193d7c 2003-09-30 devnull cmd.ccmd = ncp;
480 76193d7c 2003-09-30 devnull }while(cp = ncp);
481 76193d7c 2003-09-30 devnull break;
482 76193d7c 2003-09-30 devnull case '}':
483 76193d7c 2003-09-30 devnull atnl();
484 76193d7c 2003-09-30 devnull if(nest==0)
485 76193d7c 2003-09-30 devnull error(Enolbrace);
486 76193d7c 2003-09-30 devnull return 0;
487 76193d7c 2003-09-30 devnull default:
488 76193d7c 2003-09-30 devnull error_c(Eunk, cmd.cmdc);
489 76193d7c 2003-09-30 devnull }
490 76193d7c 2003-09-30 devnull Return:
491 76193d7c 2003-09-30 devnull cp = newcmd();
492 76193d7c 2003-09-30 devnull *cp = cmd;
493 76193d7c 2003-09-30 devnull return cp;
494 76193d7c 2003-09-30 devnull }
495 76193d7c 2003-09-30 devnull
496 76193d7c 2003-09-30 devnull String* /* BUGGERED */
497 76193d7c 2003-09-30 devnull getregexp(int delim)
498 76193d7c 2003-09-30 devnull {
499 76193d7c 2003-09-30 devnull String *r = newre();
500 76193d7c 2003-09-30 devnull int c;
501 76193d7c 2003-09-30 devnull
502 76193d7c 2003-09-30 devnull for(Strzero(&genstr); ; Straddc(&genstr, c))
503 76193d7c 2003-09-30 devnull if((c = getch())=='\\'){
504 76193d7c 2003-09-30 devnull if(nextc()==delim)
505 76193d7c 2003-09-30 devnull c = getch();
506 76193d7c 2003-09-30 devnull else if(nextc()=='\\'){
507 76193d7c 2003-09-30 devnull Straddc(&genstr, c);
508 76193d7c 2003-09-30 devnull c = getch();
509 76193d7c 2003-09-30 devnull }
510 76193d7c 2003-09-30 devnull }else if(c==delim || c=='\n')
511 76193d7c 2003-09-30 devnull break;
512 76193d7c 2003-09-30 devnull if(c!=delim && c)
513 76193d7c 2003-09-30 devnull ungetch();
514 76193d7c 2003-09-30 devnull if(genstr.n > 0){
515 76193d7c 2003-09-30 devnull patset = TRUE;
516 76193d7c 2003-09-30 devnull Strduplstr(&lastpat, &genstr);
517 76193d7c 2003-09-30 devnull Straddc(&lastpat, '\0');
518 76193d7c 2003-09-30 devnull }
519 76193d7c 2003-09-30 devnull if(lastpat.n <= 1)
520 76193d7c 2003-09-30 devnull error(Epattern);
521 76193d7c 2003-09-30 devnull Strduplstr(r, &lastpat);
522 76193d7c 2003-09-30 devnull return r;
523 76193d7c 2003-09-30 devnull }
524 76193d7c 2003-09-30 devnull
525 76193d7c 2003-09-30 devnull Addr *
526 76193d7c 2003-09-30 devnull simpleaddr(void)
527 76193d7c 2003-09-30 devnull {
528 76193d7c 2003-09-30 devnull Addr addr;
529 76193d7c 2003-09-30 devnull Addr *ap, *nap;
530 76193d7c 2003-09-30 devnull
531 76193d7c 2003-09-30 devnull addr.next = 0;
532 76193d7c 2003-09-30 devnull addr.left = 0;
533 2e328464 2005-07-13 devnull addr.num = 0;
534 76193d7c 2003-09-30 devnull switch(skipbl()){
535 76193d7c 2003-09-30 devnull case '#':
536 76193d7c 2003-09-30 devnull addr.type = getch();
537 76193d7c 2003-09-30 devnull addr.num = getnum(1);
538 76193d7c 2003-09-30 devnull break;
539 76193d7c 2003-09-30 devnull case '0': case '1': case '2': case '3': case '4':
540 76193d7c 2003-09-30 devnull case '5': case '6': case '7': case '8': case '9':
541 76193d7c 2003-09-30 devnull addr.num = getnum(1);
542 76193d7c 2003-09-30 devnull addr.type='l';
543 76193d7c 2003-09-30 devnull break;
544 76193d7c 2003-09-30 devnull case '/': case '?': case '"':
545 76193d7c 2003-09-30 devnull addr.are = getregexp(addr.type = getch());
546 76193d7c 2003-09-30 devnull break;
547 76193d7c 2003-09-30 devnull case '.':
548 76193d7c 2003-09-30 devnull case '$':
549 76193d7c 2003-09-30 devnull case '+':
550 76193d7c 2003-09-30 devnull case '-':
551 76193d7c 2003-09-30 devnull case '\'':
552 76193d7c 2003-09-30 devnull addr.type = getch();
553 76193d7c 2003-09-30 devnull break;
554 76193d7c 2003-09-30 devnull default:
555 76193d7c 2003-09-30 devnull return 0;
556 76193d7c 2003-09-30 devnull }
557 76193d7c 2003-09-30 devnull if(addr.next = simpleaddr())
558 76193d7c 2003-09-30 devnull switch(addr.next->type){
559 76193d7c 2003-09-30 devnull case '.':
560 76193d7c 2003-09-30 devnull case '$':
561 76193d7c 2003-09-30 devnull case '\'':
562 76193d7c 2003-09-30 devnull if(addr.type!='"')
563 76193d7c 2003-09-30 devnull case '"':
564 76193d7c 2003-09-30 devnull error(Eaddress);
565 76193d7c 2003-09-30 devnull break;
566 76193d7c 2003-09-30 devnull case 'l':
567 76193d7c 2003-09-30 devnull case '#':
568 76193d7c 2003-09-30 devnull if(addr.type=='"')
569 76193d7c 2003-09-30 devnull break;
570 76193d7c 2003-09-30 devnull /* fall through */
571 76193d7c 2003-09-30 devnull case '/':
572 76193d7c 2003-09-30 devnull case '?':
573 76193d7c 2003-09-30 devnull if(addr.type!='+' && addr.type!='-'){
574 76193d7c 2003-09-30 devnull /* insert the missing '+' */
575 76193d7c 2003-09-30 devnull nap = newaddr();
576 76193d7c 2003-09-30 devnull nap->type='+';
577 76193d7c 2003-09-30 devnull nap->next = addr.next;
578 76193d7c 2003-09-30 devnull addr.next = nap;
579 76193d7c 2003-09-30 devnull }
580 76193d7c 2003-09-30 devnull break;
581 76193d7c 2003-09-30 devnull case '+':
582 76193d7c 2003-09-30 devnull case '-':
583 76193d7c 2003-09-30 devnull break;
584 76193d7c 2003-09-30 devnull default:
585 76193d7c 2003-09-30 devnull panic("simpleaddr");
586 76193d7c 2003-09-30 devnull }
587 76193d7c 2003-09-30 devnull ap = newaddr();
588 76193d7c 2003-09-30 devnull *ap = addr;
589 76193d7c 2003-09-30 devnull return ap;
590 76193d7c 2003-09-30 devnull }
591 76193d7c 2003-09-30 devnull
592 76193d7c 2003-09-30 devnull Addr *
593 76193d7c 2003-09-30 devnull compoundaddr(void)
594 76193d7c 2003-09-30 devnull {
595 76193d7c 2003-09-30 devnull Addr addr;
596 76193d7c 2003-09-30 devnull Addr *ap, *next;
597 76193d7c 2003-09-30 devnull
598 76193d7c 2003-09-30 devnull addr.left = simpleaddr();
599 76193d7c 2003-09-30 devnull if((addr.type = skipbl())!=',' && addr.type!=';')
600 76193d7c 2003-09-30 devnull return addr.left;
601 76193d7c 2003-09-30 devnull getch();
602 76193d7c 2003-09-30 devnull next = addr.next = compoundaddr();
603 76193d7c 2003-09-30 devnull if(next && (next->type==',' || next->type==';') && next->left==0)
604 76193d7c 2003-09-30 devnull error(Eaddress);
605 76193d7c 2003-09-30 devnull ap = newaddr();
606 76193d7c 2003-09-30 devnull *ap = addr;
607 76193d7c 2003-09-30 devnull return ap;
608 76193d7c 2003-09-30 devnull }