Blame


1 f08fdedc 2003-11-23 devnull #include "rc.h"
2 f08fdedc 2003-11-23 devnull #include "getflags.h"
3 f08fdedc 2003-11-23 devnull #include "exec.h"
4 f08fdedc 2003-11-23 devnull #include "io.h"
5 f08fdedc 2003-11-23 devnull #include "fns.h"
6 f08fdedc 2003-11-23 devnull /*
7 f08fdedc 2003-11-23 devnull * Start executing the given code at the given pc with the given redirection
8 f08fdedc 2003-11-23 devnull */
9 f08fdedc 2003-11-23 devnull char *argv0="rc";
10 c8f53842 2007-03-26 devnull
11 c8f53842 2007-03-26 devnull void
12 c8f53842 2007-03-26 devnull start(code *c, int pc, var *local)
13 f08fdedc 2003-11-23 devnull {
14 c8f53842 2007-03-26 devnull struct thread *p = new(struct thread);
15 c8f53842 2007-03-26 devnull
16 c8f53842 2007-03-26 devnull p->code = codecopy(c);
17 c8f53842 2007-03-26 devnull p->pc = pc;
18 c8f53842 2007-03-26 devnull p->argv = 0;
19 c8f53842 2007-03-26 devnull p->redir = p->startredir = runq?runq->redir:0;
20 c8f53842 2007-03-26 devnull p->local = local;
21 c8f53842 2007-03-26 devnull p->cmdfile = 0;
22 c8f53842 2007-03-26 devnull p->cmdfd = 0;
23 c8f53842 2007-03-26 devnull p->eof = 0;
24 c8f53842 2007-03-26 devnull p->iflag = 0;
25 c8f53842 2007-03-26 devnull p->lineno = 1;
26 c8f53842 2007-03-26 devnull p->ret = runq;
27 c8f53842 2007-03-26 devnull runq = p;
28 f08fdedc 2003-11-23 devnull }
29 c8f53842 2007-03-26 devnull
30 c8f53842 2007-03-26 devnull word*
31 c8f53842 2007-03-26 devnull newword(char *wd, word *next)
32 f08fdedc 2003-11-23 devnull {
33 c8f53842 2007-03-26 devnull word *p = new(word);
34 c8f53842 2007-03-26 devnull p->word = strdup(wd);
35 c8f53842 2007-03-26 devnull p->next = next;
36 f08fdedc 2003-11-23 devnull return p;
37 f08fdedc 2003-11-23 devnull }
38 c8f53842 2007-03-26 devnull
39 c8f53842 2007-03-26 devnull void
40 c8f53842 2007-03-26 devnull pushword(char *wd)
41 f08fdedc 2003-11-23 devnull {
42 c8f53842 2007-03-26 devnull if(runq->argv==0)
43 c8f53842 2007-03-26 devnull panic("pushword but no argv!", 0);
44 c8f53842 2007-03-26 devnull runq->argv->words = newword(wd, runq->argv->words);
45 f08fdedc 2003-11-23 devnull }
46 c8f53842 2007-03-26 devnull
47 c8f53842 2007-03-26 devnull void
48 c8f53842 2007-03-26 devnull popword(void)
49 c8f53842 2007-03-26 devnull {
50 f08fdedc 2003-11-23 devnull word *p;
51 c8f53842 2007-03-26 devnull if(runq->argv==0)
52 c8f53842 2007-03-26 devnull panic("popword but no argv!", 0);
53 c8f53842 2007-03-26 devnull p = runq->argv->words;
54 c8f53842 2007-03-26 devnull if(p==0)
55 c8f53842 2007-03-26 devnull panic("popword but no word!", 0);
56 c8f53842 2007-03-26 devnull runq->argv->words = p->next;
57 f08fdedc 2003-11-23 devnull efree(p->word);
58 f08fdedc 2003-11-23 devnull efree((char *)p);
59 f08fdedc 2003-11-23 devnull }
60 c8f53842 2007-03-26 devnull
61 c8f53842 2007-03-26 devnull void
62 c8f53842 2007-03-26 devnull freelist(word *w)
63 f08fdedc 2003-11-23 devnull {
64 f08fdedc 2003-11-23 devnull word *nw;
65 f08fdedc 2003-11-23 devnull while(w){
66 c8f53842 2007-03-26 devnull nw = w->next;
67 f08fdedc 2003-11-23 devnull efree(w->word);
68 f08fdedc 2003-11-23 devnull efree((char *)w);
69 c8f53842 2007-03-26 devnull w = nw;
70 f08fdedc 2003-11-23 devnull }
71 f08fdedc 2003-11-23 devnull }
72 c8f53842 2007-03-26 devnull
73 c8f53842 2007-03-26 devnull void
74 c8f53842 2007-03-26 devnull pushlist(void)
75 c8f53842 2007-03-26 devnull {
76 c8f53842 2007-03-26 devnull list *p = new(list);
77 c8f53842 2007-03-26 devnull p->next = runq->argv;
78 c8f53842 2007-03-26 devnull p->words = 0;
79 c8f53842 2007-03-26 devnull runq->argv = p;
80 f08fdedc 2003-11-23 devnull }
81 c8f53842 2007-03-26 devnull
82 c8f53842 2007-03-26 devnull void
83 c8f53842 2007-03-26 devnull poplist(void)
84 c8f53842 2007-03-26 devnull {
85 c8f53842 2007-03-26 devnull list *p = runq->argv;
86 c8f53842 2007-03-26 devnull if(p==0)
87 c8f53842 2007-03-26 devnull panic("poplist but no argv", 0);
88 f08fdedc 2003-11-23 devnull freelist(p->words);
89 c8f53842 2007-03-26 devnull runq->argv = p->next;
90 f08fdedc 2003-11-23 devnull efree((char *)p);
91 f08fdedc 2003-11-23 devnull }
92 c8f53842 2007-03-26 devnull
93 c8f53842 2007-03-26 devnull int
94 c8f53842 2007-03-26 devnull count(word *w)
95 f08fdedc 2003-11-23 devnull {
96 f08fdedc 2003-11-23 devnull int n;
97 c8f53842 2007-03-26 devnull for(n = 0;w;n++) w = w->next;
98 f08fdedc 2003-11-23 devnull return n;
99 f08fdedc 2003-11-23 devnull }
100 c8f53842 2007-03-26 devnull
101 c8f53842 2007-03-26 devnull void
102 c8f53842 2007-03-26 devnull pushredir(int type, int from, int to)
103 c8f53842 2007-03-26 devnull {
104 c8f53842 2007-03-26 devnull redir * rp = new(redir);
105 c8f53842 2007-03-26 devnull rp->type = type;
106 c8f53842 2007-03-26 devnull rp->from = from;
107 c8f53842 2007-03-26 devnull rp->to = to;
108 c8f53842 2007-03-26 devnull rp->next = runq->redir;
109 c8f53842 2007-03-26 devnull runq->redir = rp;
110 f08fdedc 2003-11-23 devnull }
111 c8f53842 2007-03-26 devnull
112 c8f53842 2007-03-26 devnull var*
113 c8f53842 2007-03-26 devnull newvar(char *name, var *next)
114 f08fdedc 2003-11-23 devnull {
115 c8f53842 2007-03-26 devnull var *v = new(var);
116 c8f53842 2007-03-26 devnull v->name = name;
117 c8f53842 2007-03-26 devnull v->val = 0;
118 c8f53842 2007-03-26 devnull v->fn = 0;
119 c8f53842 2007-03-26 devnull v->changed = 0;
120 c8f53842 2007-03-26 devnull v->fnchanged = 0;
121 c8f53842 2007-03-26 devnull v->next = next;
122 bd1b0cc1 2007-03-26 devnull v->changefn = 0;
123 f08fdedc 2003-11-23 devnull return v;
124 f08fdedc 2003-11-23 devnull }
125 f08fdedc 2003-11-23 devnull /*
126 f08fdedc 2003-11-23 devnull * get command line flags, initialize keywords & traps.
127 f08fdedc 2003-11-23 devnull * get values from environment.
128 f08fdedc 2003-11-23 devnull * set $pid, $cflag, $*
129 f08fdedc 2003-11-23 devnull * fabricate bootstrap code and start it (*=(argv);. /usr/lib/rcmain $*)
130 f08fdedc 2003-11-23 devnull * start interpreting code
131 f08fdedc 2003-11-23 devnull */
132 f08fdedc 2003-11-23 devnull int
133 f08fdedc 2003-11-23 devnull main(int argc, char *argv[])
134 f08fdedc 2003-11-23 devnull {
135 f08fdedc 2003-11-23 devnull code bootstrap[32];
136 f08fdedc 2003-11-23 devnull char num[12], *rcmain;
137 f08fdedc 2003-11-23 devnull int i;
138 e3ffbf3b 2005-05-19 devnull
139 e3ffbf3b 2005-05-19 devnull /* needed for rcmain later */
140 0e4068e8 2005-07-26 devnull putenv("PLAN9", unsharp("#9"));
141 f08fdedc 2003-11-23 devnull
142 c8f53842 2007-03-26 devnull argc = getflags(argc, argv, "SsrdiIlxepvVc:1m:1[command]", 1);
143 c8f53842 2007-03-26 devnull if(argc==-1)
144 c8f53842 2007-03-26 devnull usage("[file [arg ...]]");
145 c8f53842 2007-03-26 devnull if(argv[0][0]=='-')
146 c8f53842 2007-03-26 devnull flag['l'] = flagset;
147 c8f53842 2007-03-26 devnull if(flag['I'])
148 c8f53842 2007-03-26 devnull flag['i'] = 0;
149 f08fdedc 2003-11-23 devnull else if(flag['i']==0 && argc==1 && Isatty(0)) flag['i'] = flagset;
150 c8f53842 2007-03-26 devnull rcmain = flag['m'] ? flag['m'][0] : Rcmain();
151 c8f53842 2007-03-26 devnull err = openfd(2);
152 f08fdedc 2003-11-23 devnull kinit();
153 f08fdedc 2003-11-23 devnull Trapinit();
154 f08fdedc 2003-11-23 devnull Vinit();
155 c8f53842 2007-03-26 devnull inttoascii(num, mypid = getpid());
156 a9eaaa03 2005-01-12 devnull pathinit();
157 f08fdedc 2003-11-23 devnull setvar("pid", newword(num, (word *)0));
158 f08fdedc 2003-11-23 devnull setvar("cflag", flag['c']?newword(flag['c'][0], (word *)0)
159 f08fdedc 2003-11-23 devnull :(word *)0);
160 f08fdedc 2003-11-23 devnull setvar("rcname", newword(argv[0], (word *)0));
161 c8f53842 2007-03-26 devnull i = 0;
162 c8f53842 2007-03-26 devnull bootstrap[i++].i = 1;
163 c8f53842 2007-03-26 devnull bootstrap[i++].f = Xmark;
164 c8f53842 2007-03-26 devnull bootstrap[i++].f = Xword;
165 f08fdedc 2003-11-23 devnull bootstrap[i++].s="*";
166 c8f53842 2007-03-26 devnull bootstrap[i++].f = Xassign;
167 c8f53842 2007-03-26 devnull bootstrap[i++].f = Xmark;
168 c8f53842 2007-03-26 devnull bootstrap[i++].f = Xmark;
169 c8f53842 2007-03-26 devnull bootstrap[i++].f = Xword;
170 f08fdedc 2003-11-23 devnull bootstrap[i++].s="*";
171 c8f53842 2007-03-26 devnull bootstrap[i++].f = Xdol;
172 c8f53842 2007-03-26 devnull bootstrap[i++].f = Xword;
173 c8f53842 2007-03-26 devnull bootstrap[i++].s = rcmain;
174 c8f53842 2007-03-26 devnull bootstrap[i++].f = Xword;
175 f08fdedc 2003-11-23 devnull bootstrap[i++].s=".";
176 c8f53842 2007-03-26 devnull bootstrap[i++].f = Xsimple;
177 c8f53842 2007-03-26 devnull bootstrap[i++].f = Xexit;
178 c8f53842 2007-03-26 devnull bootstrap[i].i = 0;
179 f08fdedc 2003-11-23 devnull start(bootstrap, 1, (var *)0);
180 f08fdedc 2003-11-23 devnull /* prime bootstrap argv */
181 f08fdedc 2003-11-23 devnull pushlist();
182 f08fdedc 2003-11-23 devnull argv0 = strdup(argv[0]);
183 c8f53842 2007-03-26 devnull for(i = argc-1;i!=0;--i) pushword(argv[i]);
184 f08fdedc 2003-11-23 devnull for(;;){
185 c8f53842 2007-03-26 devnull if(flag['r'])
186 c8f53842 2007-03-26 devnull pfnc(err, runq);
187 f08fdedc 2003-11-23 devnull runq->pc++;
188 f08fdedc 2003-11-23 devnull (*runq->code[runq->pc-1].f)();
189 c8f53842 2007-03-26 devnull if(ntrap)
190 c8f53842 2007-03-26 devnull dotrap();
191 f08fdedc 2003-11-23 devnull }
192 f08fdedc 2003-11-23 devnull }
193 f08fdedc 2003-11-23 devnull /*
194 f08fdedc 2003-11-23 devnull * Opcode routines
195 f08fdedc 2003-11-23 devnull * Arguments on stack (...)
196 f08fdedc 2003-11-23 devnull * Arguments in line [...]
197 f08fdedc 2003-11-23 devnull * Code in line with jump around {...}
198 f08fdedc 2003-11-23 devnull *
199 f08fdedc 2003-11-23 devnull * Xappend(file)[fd] open file to append
200 f08fdedc 2003-11-23 devnull * Xassign(name, val) assign val to name
201 f08fdedc 2003-11-23 devnull * Xasync{... Xexit} make thread for {}, no wait
202 f08fdedc 2003-11-23 devnull * Xbackq{... Xreturn} make thread for {}, push stdout
203 f08fdedc 2003-11-23 devnull * Xbang complement condition
204 f08fdedc 2003-11-23 devnull * Xcase(pat, value){...} exec code on match, leave (value) on
205 f08fdedc 2003-11-23 devnull * stack
206 f08fdedc 2003-11-23 devnull * Xclose[i] close file descriptor
207 f08fdedc 2003-11-23 devnull * Xconc(left, right) concatenate, push results
208 f08fdedc 2003-11-23 devnull * Xcount(name) push var count
209 f08fdedc 2003-11-23 devnull * Xdelfn(name) delete function definition
210 f08fdedc 2003-11-23 devnull * Xdeltraps(names) delete named traps
211 f08fdedc 2003-11-23 devnull * Xdol(name) get variable value
212 f08fdedc 2003-11-23 devnull * Xqdol(name) concatenate variable components
213 f08fdedc 2003-11-23 devnull * Xdup[i j] dup file descriptor
214 f08fdedc 2003-11-23 devnull * Xexit rc exits with status
215 f08fdedc 2003-11-23 devnull * Xfalse{...} execute {} if false
216 f08fdedc 2003-11-23 devnull * Xfn(name){... Xreturn} define function
217 f08fdedc 2003-11-23 devnull * Xfor(var, list){... Xreturn} for loop
218 f08fdedc 2003-11-23 devnull * Xjump[addr] goto
219 f08fdedc 2003-11-23 devnull * Xlocal(name, val) create local variable, assign value
220 f08fdedc 2003-11-23 devnull * Xmark mark stack
221 f08fdedc 2003-11-23 devnull * Xmatch(pat, str) match pattern, set status
222 f08fdedc 2003-11-23 devnull * Xpipe[i j]{... Xreturn}{... Xreturn} construct a pipe between 2 new threads,
223 f08fdedc 2003-11-23 devnull * wait for both
224 f08fdedc 2003-11-23 devnull * Xpipefd[type]{... Xreturn} connect {} to pipe (input or output,
225 f08fdedc 2003-11-23 devnull * depending on type), push /dev/fd/??
226 f08fdedc 2003-11-23 devnull * Xpopm(value) pop value from stack
227 c8f53842 2007-03-26 devnull * Xrdwr(file)[fd] open file for reading and writing
228 f08fdedc 2003-11-23 devnull * Xread(file)[fd] open file to read
229 f08fdedc 2003-11-23 devnull * Xsettraps(names){... Xreturn} define trap functions
230 f08fdedc 2003-11-23 devnull * Xshowtraps print trap list
231 f08fdedc 2003-11-23 devnull * Xsimple(args) run command and wait
232 f08fdedc 2003-11-23 devnull * Xreturn kill thread
233 f08fdedc 2003-11-23 devnull * Xsubshell{... Xexit} execute {} in a subshell and wait
234 f08fdedc 2003-11-23 devnull * Xtrue{...} execute {} if true
235 f08fdedc 2003-11-23 devnull * Xunlocal delete local variable
236 f08fdedc 2003-11-23 devnull * Xword[string] push string
237 f08fdedc 2003-11-23 devnull * Xwrite(file)[fd] open file to write
238 f08fdedc 2003-11-23 devnull */
239 c8f53842 2007-03-26 devnull
240 c8f53842 2007-03-26 devnull void
241 c8f53842 2007-03-26 devnull Xappend(void)
242 c8f53842 2007-03-26 devnull {
243 f08fdedc 2003-11-23 devnull char *file;
244 f08fdedc 2003-11-23 devnull int f;
245 f08fdedc 2003-11-23 devnull switch(count(runq->argv->words)){
246 c8f53842 2007-03-26 devnull default:
247 c8f53842 2007-03-26 devnull Xerror1(">> requires singleton");
248 c8f53842 2007-03-26 devnull return;
249 c8f53842 2007-03-26 devnull case 0:
250 c8f53842 2007-03-26 devnull Xerror1(">> requires file");
251 c8f53842 2007-03-26 devnull return;
252 c8f53842 2007-03-26 devnull case 1:
253 c8f53842 2007-03-26 devnull break;
254 f08fdedc 2003-11-23 devnull }
255 c8f53842 2007-03-26 devnull file = runq->argv->words->word;
256 c8f53842 2007-03-26 devnull if((f = open(file, 1))<0 && (f = Creat(file))<0){
257 f08fdedc 2003-11-23 devnull pfmt(err, "%s: ", file);
258 f08fdedc 2003-11-23 devnull Xerror("can't open");
259 f08fdedc 2003-11-23 devnull return;
260 f08fdedc 2003-11-23 devnull }
261 f08fdedc 2003-11-23 devnull Seek(f, 0L, 2);
262 f08fdedc 2003-11-23 devnull pushredir(ROPEN, f, runq->code[runq->pc].i);
263 f08fdedc 2003-11-23 devnull runq->pc++;
264 f08fdedc 2003-11-23 devnull poplist();
265 f08fdedc 2003-11-23 devnull }
266 c8f53842 2007-03-26 devnull
267 c8f53842 2007-03-26 devnull void
268 c8f53842 2007-03-26 devnull Xsettrue(void)
269 c8f53842 2007-03-26 devnull {
270 f08fdedc 2003-11-23 devnull setstatus("");
271 f08fdedc 2003-11-23 devnull }
272 c8f53842 2007-03-26 devnull
273 c8f53842 2007-03-26 devnull void
274 c8f53842 2007-03-26 devnull Xbang(void)
275 c8f53842 2007-03-26 devnull {
276 f08fdedc 2003-11-23 devnull setstatus(truestatus()?"false":"");
277 f08fdedc 2003-11-23 devnull }
278 c8f53842 2007-03-26 devnull
279 c8f53842 2007-03-26 devnull void
280 c8f53842 2007-03-26 devnull Xclose(void)
281 c8f53842 2007-03-26 devnull {
282 f08fdedc 2003-11-23 devnull pushredir(RCLOSE, runq->code[runq->pc].i, 0);
283 f08fdedc 2003-11-23 devnull runq->pc++;
284 f08fdedc 2003-11-23 devnull }
285 c8f53842 2007-03-26 devnull
286 c8f53842 2007-03-26 devnull void
287 c8f53842 2007-03-26 devnull Xdup(void)
288 c8f53842 2007-03-26 devnull {
289 f08fdedc 2003-11-23 devnull pushredir(RDUP, runq->code[runq->pc].i, runq->code[runq->pc+1].i);
290 f08fdedc 2003-11-23 devnull runq->pc+=2;
291 f08fdedc 2003-11-23 devnull }
292 c8f53842 2007-03-26 devnull
293 c8f53842 2007-03-26 devnull void
294 c8f53842 2007-03-26 devnull Xeflag(void)
295 c8f53842 2007-03-26 devnull {
296 f08fdedc 2003-11-23 devnull if(eflagok && !truestatus()) Xexit();
297 f08fdedc 2003-11-23 devnull }
298 c8f53842 2007-03-26 devnull
299 c8f53842 2007-03-26 devnull void
300 c8f53842 2007-03-26 devnull Xexit(void)
301 c8f53842 2007-03-26 devnull {
302 f08fdedc 2003-11-23 devnull struct var *trapreq;
303 f08fdedc 2003-11-23 devnull struct word *starval;
304 c8f53842 2007-03-26 devnull static int beenhere = 0;
305 f08fdedc 2003-11-23 devnull if(getpid()==mypid && !beenhere){
306 c8f53842 2007-03-26 devnull trapreq = vlook("sigexit");
307 f08fdedc 2003-11-23 devnull if(trapreq->fn){
308 c8f53842 2007-03-26 devnull beenhere = 1;
309 f08fdedc 2003-11-23 devnull --runq->pc;
310 c8f53842 2007-03-26 devnull starval = vlook("*")->val;
311 f08fdedc 2003-11-23 devnull start(trapreq->fn, trapreq->pc, (struct var *)0);
312 c8f53842 2007-03-26 devnull runq->local = newvar(strdup("*"), runq->local);
313 c8f53842 2007-03-26 devnull runq->local->val = copywords(starval, (struct word *)0);
314 c8f53842 2007-03-26 devnull runq->local->changed = 1;
315 c8f53842 2007-03-26 devnull runq->redir = runq->startredir = 0;
316 f08fdedc 2003-11-23 devnull return;
317 f08fdedc 2003-11-23 devnull }
318 f08fdedc 2003-11-23 devnull }
319 f08fdedc 2003-11-23 devnull Exit(getstatus());
320 f08fdedc 2003-11-23 devnull }
321 c8f53842 2007-03-26 devnull
322 c8f53842 2007-03-26 devnull void
323 c8f53842 2007-03-26 devnull Xfalse(void)
324 c8f53842 2007-03-26 devnull {
325 c8f53842 2007-03-26 devnull if(truestatus()) runq->pc = runq->code[runq->pc].i;
326 f08fdedc 2003-11-23 devnull else runq->pc++;
327 f08fdedc 2003-11-23 devnull }
328 f08fdedc 2003-11-23 devnull int ifnot; /* dynamic if not flag */
329 c8f53842 2007-03-26 devnull
330 c8f53842 2007-03-26 devnull void
331 c8f53842 2007-03-26 devnull Xifnot(void)
332 c8f53842 2007-03-26 devnull {
333 f08fdedc 2003-11-23 devnull if(ifnot)
334 f08fdedc 2003-11-23 devnull runq->pc++;
335 f08fdedc 2003-11-23 devnull else
336 c8f53842 2007-03-26 devnull runq->pc = runq->code[runq->pc].i;
337 f08fdedc 2003-11-23 devnull }
338 c8f53842 2007-03-26 devnull
339 c8f53842 2007-03-26 devnull void
340 c8f53842 2007-03-26 devnull Xjump(void)
341 c8f53842 2007-03-26 devnull {
342 c8f53842 2007-03-26 devnull runq->pc = runq->code[runq->pc].i;
343 f08fdedc 2003-11-23 devnull }
344 c8f53842 2007-03-26 devnull
345 c8f53842 2007-03-26 devnull void
346 c8f53842 2007-03-26 devnull Xmark(void)
347 c8f53842 2007-03-26 devnull {
348 f08fdedc 2003-11-23 devnull pushlist();
349 f08fdedc 2003-11-23 devnull }
350 c8f53842 2007-03-26 devnull
351 c8f53842 2007-03-26 devnull void
352 c8f53842 2007-03-26 devnull Xpopm(void)
353 c8f53842 2007-03-26 devnull {
354 f08fdedc 2003-11-23 devnull poplist();
355 f08fdedc 2003-11-23 devnull }
356 c8f53842 2007-03-26 devnull
357 c8f53842 2007-03-26 devnull void
358 c8f53842 2007-03-26 devnull Xread(void)
359 c8f53842 2007-03-26 devnull {
360 f08fdedc 2003-11-23 devnull char *file;
361 f08fdedc 2003-11-23 devnull int f;
362 f08fdedc 2003-11-23 devnull switch(count(runq->argv->words)){
363 c8f53842 2007-03-26 devnull default:
364 c8f53842 2007-03-26 devnull Xerror1("< requires singleton\n");
365 c8f53842 2007-03-26 devnull return;
366 c8f53842 2007-03-26 devnull case 0:
367 c8f53842 2007-03-26 devnull Xerror1("< requires file\n");
368 c8f53842 2007-03-26 devnull return;
369 c8f53842 2007-03-26 devnull case 1:
370 c8f53842 2007-03-26 devnull break;
371 f08fdedc 2003-11-23 devnull }
372 c8f53842 2007-03-26 devnull file = runq->argv->words->word;
373 c8f53842 2007-03-26 devnull if((f = open(file, 0))<0){
374 f08fdedc 2003-11-23 devnull pfmt(err, "%s: ", file);
375 f08fdedc 2003-11-23 devnull Xerror("can't open");
376 f08fdedc 2003-11-23 devnull return;
377 f08fdedc 2003-11-23 devnull }
378 f08fdedc 2003-11-23 devnull pushredir(ROPEN, f, runq->code[runq->pc].i);
379 f08fdedc 2003-11-23 devnull runq->pc++;
380 f08fdedc 2003-11-23 devnull poplist();
381 f08fdedc 2003-11-23 devnull }
382 c8f53842 2007-03-26 devnull
383 c8f53842 2007-03-26 devnull void
384 c8f53842 2007-03-26 devnull Xrdwr(void)
385 c8f53842 2007-03-26 devnull {
386 c8f53842 2007-03-26 devnull char *file;
387 c8f53842 2007-03-26 devnull int f;
388 c8f53842 2007-03-26 devnull
389 c8f53842 2007-03-26 devnull switch(count(runq->argv->words)){
390 c8f53842 2007-03-26 devnull default:
391 c8f53842 2007-03-26 devnull Xerror1("<> requires singleton\n");
392 c8f53842 2007-03-26 devnull return;
393 c8f53842 2007-03-26 devnull case 0:
394 c8f53842 2007-03-26 devnull Xerror1("<> requires file\n");
395 c8f53842 2007-03-26 devnull return;
396 c8f53842 2007-03-26 devnull case 1:
397 c8f53842 2007-03-26 devnull break;
398 c8f53842 2007-03-26 devnull }
399 c8f53842 2007-03-26 devnull file = runq->argv->words->word;
400 c8f53842 2007-03-26 devnull if((f = open(file, ORDWR))<0){
401 c8f53842 2007-03-26 devnull pfmt(err, "%s: ", file);
402 c8f53842 2007-03-26 devnull Xerror("can't open");
403 c8f53842 2007-03-26 devnull return;
404 c8f53842 2007-03-26 devnull }
405 c8f53842 2007-03-26 devnull pushredir(ROPEN, f, runq->code[runq->pc].i);
406 c8f53842 2007-03-26 devnull runq->pc++;
407 c8f53842 2007-03-26 devnull poplist();
408 c8f53842 2007-03-26 devnull }
409 c8f53842 2007-03-26 devnull
410 c8f53842 2007-03-26 devnull void
411 c8f53842 2007-03-26 devnull turfredir(void)
412 c8f53842 2007-03-26 devnull {
413 f08fdedc 2003-11-23 devnull while(runq->redir!=runq->startredir)
414 f08fdedc 2003-11-23 devnull Xpopredir();
415 f08fdedc 2003-11-23 devnull }
416 c8f53842 2007-03-26 devnull
417 c8f53842 2007-03-26 devnull void
418 c8f53842 2007-03-26 devnull Xpopredir(void)
419 c8f53842 2007-03-26 devnull {
420 c8f53842 2007-03-26 devnull struct redir *rp = runq->redir;
421 c8f53842 2007-03-26 devnull if(rp==0)
422 c8f53842 2007-03-26 devnull panic("turfredir null!", 0);
423 c8f53842 2007-03-26 devnull runq->redir = rp->next;
424 c8f53842 2007-03-26 devnull if(rp->type==ROPEN)
425 c8f53842 2007-03-26 devnull close(rp->from);
426 f08fdedc 2003-11-23 devnull efree((char *)rp);
427 f08fdedc 2003-11-23 devnull }
428 c8f53842 2007-03-26 devnull
429 c8f53842 2007-03-26 devnull void
430 c8f53842 2007-03-26 devnull Xreturn(void)
431 c8f53842 2007-03-26 devnull {
432 c8f53842 2007-03-26 devnull struct thread *p = runq;
433 f08fdedc 2003-11-23 devnull turfredir();
434 f08fdedc 2003-11-23 devnull while(p->argv) poplist();
435 f08fdedc 2003-11-23 devnull codefree(p->code);
436 c8f53842 2007-03-26 devnull runq = p->ret;
437 f08fdedc 2003-11-23 devnull efree((char *)p);
438 c8f53842 2007-03-26 devnull if(runq==0)
439 c8f53842 2007-03-26 devnull Exit(getstatus());
440 f08fdedc 2003-11-23 devnull }
441 c8f53842 2007-03-26 devnull
442 c8f53842 2007-03-26 devnull void
443 c8f53842 2007-03-26 devnull Xtrue(void)
444 c8f53842 2007-03-26 devnull {
445 f08fdedc 2003-11-23 devnull if(truestatus()) runq->pc++;
446 c8f53842 2007-03-26 devnull else runq->pc = runq->code[runq->pc].i;
447 f08fdedc 2003-11-23 devnull }
448 c8f53842 2007-03-26 devnull
449 c8f53842 2007-03-26 devnull void
450 c8f53842 2007-03-26 devnull Xif(void)
451 c8f53842 2007-03-26 devnull {
452 c8f53842 2007-03-26 devnull ifnot = 1;
453 f08fdedc 2003-11-23 devnull if(truestatus()) runq->pc++;
454 c8f53842 2007-03-26 devnull else runq->pc = runq->code[runq->pc].i;
455 f08fdedc 2003-11-23 devnull }
456 c8f53842 2007-03-26 devnull
457 c8f53842 2007-03-26 devnull void
458 c8f53842 2007-03-26 devnull Xwastrue(void)
459 c8f53842 2007-03-26 devnull {
460 c8f53842 2007-03-26 devnull ifnot = 0;
461 f08fdedc 2003-11-23 devnull }
462 c8f53842 2007-03-26 devnull
463 c8f53842 2007-03-26 devnull void
464 c8f53842 2007-03-26 devnull Xword(void)
465 c8f53842 2007-03-26 devnull {
466 f08fdedc 2003-11-23 devnull pushword(runq->code[runq->pc++].s);
467 f08fdedc 2003-11-23 devnull }
468 c8f53842 2007-03-26 devnull
469 c8f53842 2007-03-26 devnull void
470 c8f53842 2007-03-26 devnull Xwrite(void)
471 c8f53842 2007-03-26 devnull {
472 f08fdedc 2003-11-23 devnull char *file;
473 f08fdedc 2003-11-23 devnull int f;
474 f08fdedc 2003-11-23 devnull switch(count(runq->argv->words)){
475 c8f53842 2007-03-26 devnull default:
476 c8f53842 2007-03-26 devnull Xerror1("> requires singleton\n");
477 c8f53842 2007-03-26 devnull return;
478 c8f53842 2007-03-26 devnull case 0:
479 c8f53842 2007-03-26 devnull Xerror1("> requires file\n");
480 c8f53842 2007-03-26 devnull return;
481 c8f53842 2007-03-26 devnull case 1:
482 c8f53842 2007-03-26 devnull break;
483 f08fdedc 2003-11-23 devnull }
484 c8f53842 2007-03-26 devnull file = runq->argv->words->word;
485 c8f53842 2007-03-26 devnull if((f = Creat(file))<0){
486 f08fdedc 2003-11-23 devnull pfmt(err, "%s: ", file);
487 f08fdedc 2003-11-23 devnull Xerror("can't open");
488 f08fdedc 2003-11-23 devnull return;
489 f08fdedc 2003-11-23 devnull }
490 f08fdedc 2003-11-23 devnull pushredir(ROPEN, f, runq->code[runq->pc].i);
491 f08fdedc 2003-11-23 devnull runq->pc++;
492 f08fdedc 2003-11-23 devnull poplist();
493 f08fdedc 2003-11-23 devnull }
494 c8f53842 2007-03-26 devnull
495 c8f53842 2007-03-26 devnull char*
496 c8f53842 2007-03-26 devnull list2str(word *words)
497 c8f53842 2007-03-26 devnull {
498 f08fdedc 2003-11-23 devnull char *value, *s, *t;
499 c8f53842 2007-03-26 devnull int len = 0;
500 f08fdedc 2003-11-23 devnull word *ap;
501 c8f53842 2007-03-26 devnull for(ap = words;ap;ap = ap->next)
502 f08fdedc 2003-11-23 devnull len+=1+strlen(ap->word);
503 c8f53842 2007-03-26 devnull value = emalloc(len+1);
504 c8f53842 2007-03-26 devnull s = value;
505 c8f53842 2007-03-26 devnull for(ap = words;ap;ap = ap->next){
506 c8f53842 2007-03-26 devnull for(t = ap->word;*t;) *s++=*t++;
507 c8f53842 2007-03-26 devnull *s++=' ';
508 f08fdedc 2003-11-23 devnull }
509 c8f53842 2007-03-26 devnull if(s==value)
510 c8f53842 2007-03-26 devnull *s='\0';
511 f08fdedc 2003-11-23 devnull else s[-1]='\0';
512 f08fdedc 2003-11-23 devnull return value;
513 f08fdedc 2003-11-23 devnull }
514 c8f53842 2007-03-26 devnull
515 c8f53842 2007-03-26 devnull void
516 c8f53842 2007-03-26 devnull Xmatch(void)
517 c8f53842 2007-03-26 devnull {
518 f08fdedc 2003-11-23 devnull word *p;
519 f08fdedc 2003-11-23 devnull char *subject;
520 c8f53842 2007-03-26 devnull subject = list2str(runq->argv->words);
521 f08fdedc 2003-11-23 devnull setstatus("no match");
522 c8f53842 2007-03-26 devnull for(p = runq->argv->next->words;p;p = p->next)
523 f08fdedc 2003-11-23 devnull if(match(subject, p->word, '\0')){
524 f08fdedc 2003-11-23 devnull setstatus("");
525 f08fdedc 2003-11-23 devnull break;
526 f08fdedc 2003-11-23 devnull }
527 f08fdedc 2003-11-23 devnull efree(subject);
528 f08fdedc 2003-11-23 devnull poplist();
529 f08fdedc 2003-11-23 devnull poplist();
530 f08fdedc 2003-11-23 devnull }
531 c8f53842 2007-03-26 devnull
532 c8f53842 2007-03-26 devnull void
533 c8f53842 2007-03-26 devnull Xcase(void)
534 c8f53842 2007-03-26 devnull {
535 f08fdedc 2003-11-23 devnull word *p;
536 f08fdedc 2003-11-23 devnull char *s;
537 c8f53842 2007-03-26 devnull int ok = 0;
538 c8f53842 2007-03-26 devnull s = list2str(runq->argv->next->words);
539 c8f53842 2007-03-26 devnull for(p = runq->argv->words;p;p = p->next){
540 f08fdedc 2003-11-23 devnull if(match(s, p->word, '\0')){
541 c8f53842 2007-03-26 devnull ok = 1;
542 f08fdedc 2003-11-23 devnull break;
543 f08fdedc 2003-11-23 devnull }
544 f08fdedc 2003-11-23 devnull }
545 f08fdedc 2003-11-23 devnull efree(s);
546 f08fdedc 2003-11-23 devnull if(ok)
547 f08fdedc 2003-11-23 devnull runq->pc++;
548 f08fdedc 2003-11-23 devnull else
549 c8f53842 2007-03-26 devnull runq->pc = runq->code[runq->pc].i;
550 f08fdedc 2003-11-23 devnull poplist();
551 f08fdedc 2003-11-23 devnull }
552 c8f53842 2007-03-26 devnull
553 c8f53842 2007-03-26 devnull word*
554 c8f53842 2007-03-26 devnull conclist(word *lp, word *rp, word *tail)
555 f08fdedc 2003-11-23 devnull {
556 f08fdedc 2003-11-23 devnull char *buf;
557 f08fdedc 2003-11-23 devnull word *v;
558 f08fdedc 2003-11-23 devnull if(lp->next || rp->next)
559 c8f53842 2007-03-26 devnull tail = conclist(lp->next==0?lp:lp->next, rp->next==0?rp:rp->next,
560 f08fdedc 2003-11-23 devnull tail);
561 c8f53842 2007-03-26 devnull buf = emalloc(strlen(lp->word)+strlen(rp->word)+1);
562 f08fdedc 2003-11-23 devnull strcpy(buf, lp->word);
563 f08fdedc 2003-11-23 devnull strcat(buf, rp->word);
564 c8f53842 2007-03-26 devnull v = newword(buf, tail);
565 f08fdedc 2003-11-23 devnull efree(buf);
566 f08fdedc 2003-11-23 devnull return v;
567 f08fdedc 2003-11-23 devnull }
568 c8f53842 2007-03-26 devnull
569 c8f53842 2007-03-26 devnull void
570 c8f53842 2007-03-26 devnull Xconc(void)
571 c8f53842 2007-03-26 devnull {
572 c8f53842 2007-03-26 devnull word *lp = runq->argv->words;
573 c8f53842 2007-03-26 devnull word *rp = runq->argv->next->words;
574 c8f53842 2007-03-26 devnull word *vp = runq->argv->next->next->words;
575 c8f53842 2007-03-26 devnull int lc = count(lp), rc = count(rp);
576 f08fdedc 2003-11-23 devnull if(lc!=0 || rc!=0){
577 f08fdedc 2003-11-23 devnull if(lc==0 || rc==0){
578 f08fdedc 2003-11-23 devnull Xerror1("null list in concatenation");
579 f08fdedc 2003-11-23 devnull return;
580 f08fdedc 2003-11-23 devnull }
581 f08fdedc 2003-11-23 devnull if(lc!=1 && rc!=1 && lc!=rc){
582 f08fdedc 2003-11-23 devnull Xerror1("mismatched list lengths in concatenation");
583 f08fdedc 2003-11-23 devnull return;
584 f08fdedc 2003-11-23 devnull }
585 c8f53842 2007-03-26 devnull vp = conclist(lp, rp, vp);
586 f08fdedc 2003-11-23 devnull }
587 f08fdedc 2003-11-23 devnull poplist();
588 f08fdedc 2003-11-23 devnull poplist();
589 c8f53842 2007-03-26 devnull runq->argv->words = vp;
590 f08fdedc 2003-11-23 devnull }
591 c8f53842 2007-03-26 devnull
592 c8f53842 2007-03-26 devnull void
593 c8f53842 2007-03-26 devnull Xassign(void)
594 c8f53842 2007-03-26 devnull {
595 f08fdedc 2003-11-23 devnull var *v;
596 f08fdedc 2003-11-23 devnull if(count(runq->argv->words)!=1){
597 f08fdedc 2003-11-23 devnull Xerror1("variable name not singleton!");
598 f08fdedc 2003-11-23 devnull return;
599 f08fdedc 2003-11-23 devnull }
600 f08fdedc 2003-11-23 devnull deglob(runq->argv->words->word);
601 c8f53842 2007-03-26 devnull v = vlook(runq->argv->words->word);
602 f08fdedc 2003-11-23 devnull poplist();
603 f08fdedc 2003-11-23 devnull globlist();
604 f08fdedc 2003-11-23 devnull freewords(v->val);
605 c8f53842 2007-03-26 devnull v->val = runq->argv->words;
606 c8f53842 2007-03-26 devnull v->changed = 1;
607 fbc629a9 2007-03-28 devnull if(v->changefn)
608 fbc629a9 2007-03-28 devnull v->changefn(v);
609 c8f53842 2007-03-26 devnull runq->argv->words = 0;
610 f08fdedc 2003-11-23 devnull poplist();
611 f08fdedc 2003-11-23 devnull }
612 f08fdedc 2003-11-23 devnull /*
613 f08fdedc 2003-11-23 devnull * copy arglist a, adding the copy to the front of tail
614 f08fdedc 2003-11-23 devnull */
615 c8f53842 2007-03-26 devnull
616 c8f53842 2007-03-26 devnull word*
617 c8f53842 2007-03-26 devnull copywords(word *a, word *tail)
618 f08fdedc 2003-11-23 devnull {
619 c8f53842 2007-03-26 devnull word *v = 0, **end;
620 c8f53842 2007-03-26 devnull for(end=&v;a;a = a->next,end=&(*end)->next)
621 c8f53842 2007-03-26 devnull *end = newword(a->word, 0);
622 c8f53842 2007-03-26 devnull *end = tail;
623 f08fdedc 2003-11-23 devnull return v;
624 f08fdedc 2003-11-23 devnull }
625 c8f53842 2007-03-26 devnull
626 c8f53842 2007-03-26 devnull void
627 c8f53842 2007-03-26 devnull Xdol(void)
628 c8f53842 2007-03-26 devnull {
629 f08fdedc 2003-11-23 devnull word *a, *star;
630 f08fdedc 2003-11-23 devnull char *s, *t;
631 f08fdedc 2003-11-23 devnull int n;
632 f08fdedc 2003-11-23 devnull if(count(runq->argv->words)!=1){
633 f08fdedc 2003-11-23 devnull Xerror1("variable name not singleton!");
634 f08fdedc 2003-11-23 devnull return;
635 f08fdedc 2003-11-23 devnull }
636 c8f53842 2007-03-26 devnull s = runq->argv->words->word;
637 f08fdedc 2003-11-23 devnull deglob(s);
638 c8f53842 2007-03-26 devnull n = 0;
639 c8f53842 2007-03-26 devnull for(t = s;'0'<=*t && *t<='9';t++) n = n*10+*t-'0';
640 c8f53842 2007-03-26 devnull a = runq->argv->next->words;
641 f08fdedc 2003-11-23 devnull if(n==0 || *t)
642 c8f53842 2007-03-26 devnull a = copywords(vlook(s)->val, a);
643 f08fdedc 2003-11-23 devnull else{
644 c8f53842 2007-03-26 devnull star = vlook("*")->val;
645 f08fdedc 2003-11-23 devnull if(star && 1<=n && n<=count(star)){
646 c8f53842 2007-03-26 devnull while(--n) star = star->next;
647 c8f53842 2007-03-26 devnull a = newword(star->word, a);
648 f08fdedc 2003-11-23 devnull }
649 f08fdedc 2003-11-23 devnull }
650 f08fdedc 2003-11-23 devnull poplist();
651 c8f53842 2007-03-26 devnull runq->argv->words = a;
652 f08fdedc 2003-11-23 devnull }
653 c8f53842 2007-03-26 devnull
654 c8f53842 2007-03-26 devnull void
655 c8f53842 2007-03-26 devnull Xqdol(void)
656 c8f53842 2007-03-26 devnull {
657 f08fdedc 2003-11-23 devnull word *a, *p;
658 f08fdedc 2003-11-23 devnull char *s;
659 f08fdedc 2003-11-23 devnull int n;
660 f08fdedc 2003-11-23 devnull if(count(runq->argv->words)!=1){
661 f08fdedc 2003-11-23 devnull Xerror1("variable name not singleton!");
662 f08fdedc 2003-11-23 devnull return;
663 f08fdedc 2003-11-23 devnull }
664 c8f53842 2007-03-26 devnull s = runq->argv->words->word;
665 f08fdedc 2003-11-23 devnull deglob(s);
666 c8f53842 2007-03-26 devnull a = vlook(s)->val;
667 f08fdedc 2003-11-23 devnull poplist();
668 c8f53842 2007-03-26 devnull n = count(a);
669 f08fdedc 2003-11-23 devnull if(n==0){
670 f08fdedc 2003-11-23 devnull pushword("");
671 f08fdedc 2003-11-23 devnull return;
672 f08fdedc 2003-11-23 devnull }
673 c8f53842 2007-03-26 devnull for(p = a;p;p = p->next) n+=strlen(p->word);
674 c8f53842 2007-03-26 devnull s = emalloc(n);
675 f08fdedc 2003-11-23 devnull if(a){
676 f08fdedc 2003-11-23 devnull strcpy(s, a->word);
677 c8f53842 2007-03-26 devnull for(p = a->next;p;p = p->next){
678 f08fdedc 2003-11-23 devnull strcat(s, " ");
679 f08fdedc 2003-11-23 devnull strcat(s, p->word);
680 f08fdedc 2003-11-23 devnull }
681 f08fdedc 2003-11-23 devnull }
682 f08fdedc 2003-11-23 devnull else
683 f08fdedc 2003-11-23 devnull s[0]='\0';
684 f08fdedc 2003-11-23 devnull pushword(s);
685 f08fdedc 2003-11-23 devnull efree(s);
686 f08fdedc 2003-11-23 devnull }
687 c8f53842 2007-03-26 devnull
688 c8f53842 2007-03-26 devnull word*
689 c8f53842 2007-03-26 devnull subwords(word *val, int len, word *sub, word *a)
690 f08fdedc 2003-11-23 devnull {
691 f08fdedc 2003-11-23 devnull int n;
692 f08fdedc 2003-11-23 devnull char *s;
693 c8f53842 2007-03-26 devnull if(!sub)
694 c8f53842 2007-03-26 devnull return a;
695 c8f53842 2007-03-26 devnull a = subwords(val, len, sub->next, a);
696 c8f53842 2007-03-26 devnull s = sub->word;
697 f08fdedc 2003-11-23 devnull deglob(s);
698 c8f53842 2007-03-26 devnull n = 0;
699 c8f53842 2007-03-26 devnull while('0'<=*s && *s<='9') n = n*10+ *s++ -'0';
700 c8f53842 2007-03-26 devnull if(n<1 || len<n)
701 c8f53842 2007-03-26 devnull return a;
702 c8f53842 2007-03-26 devnull for(;n!=1;--n) val = val->next;
703 f08fdedc 2003-11-23 devnull return newword(val->word, a);
704 f08fdedc 2003-11-23 devnull }
705 c8f53842 2007-03-26 devnull
706 c8f53842 2007-03-26 devnull void
707 c8f53842 2007-03-26 devnull Xsub(void)
708 c8f53842 2007-03-26 devnull {
709 f08fdedc 2003-11-23 devnull word *a, *v;
710 f08fdedc 2003-11-23 devnull char *s;
711 f08fdedc 2003-11-23 devnull if(count(runq->argv->next->words)!=1){
712 f08fdedc 2003-11-23 devnull Xerror1("variable name not singleton!");
713 f08fdedc 2003-11-23 devnull return;
714 f08fdedc 2003-11-23 devnull }
715 c8f53842 2007-03-26 devnull s = runq->argv->next->words->word;
716 f08fdedc 2003-11-23 devnull deglob(s);
717 c8f53842 2007-03-26 devnull a = runq->argv->next->next->words;
718 c8f53842 2007-03-26 devnull v = vlook(s)->val;
719 c8f53842 2007-03-26 devnull a = subwords(v, count(v), runq->argv->words, a);
720 f08fdedc 2003-11-23 devnull poplist();
721 f08fdedc 2003-11-23 devnull poplist();
722 c8f53842 2007-03-26 devnull runq->argv->words = a;
723 f08fdedc 2003-11-23 devnull }
724 c8f53842 2007-03-26 devnull
725 c8f53842 2007-03-26 devnull void
726 c8f53842 2007-03-26 devnull Xcount(void)
727 c8f53842 2007-03-26 devnull {
728 f08fdedc 2003-11-23 devnull word *a;
729 f08fdedc 2003-11-23 devnull char *s, *t;
730 f08fdedc 2003-11-23 devnull int n;
731 f08fdedc 2003-11-23 devnull char num[12];
732 f08fdedc 2003-11-23 devnull if(count(runq->argv->words)!=1){
733 f08fdedc 2003-11-23 devnull Xerror1("variable name not singleton!");
734 f08fdedc 2003-11-23 devnull return;
735 f08fdedc 2003-11-23 devnull }
736 c8f53842 2007-03-26 devnull s = runq->argv->words->word;
737 f08fdedc 2003-11-23 devnull deglob(s);
738 c8f53842 2007-03-26 devnull n = 0;
739 c8f53842 2007-03-26 devnull for(t = s;'0'<=*t && *t<='9';t++) n = n*10+*t-'0';
740 f08fdedc 2003-11-23 devnull if(n==0 || *t){
741 c8f53842 2007-03-26 devnull a = vlook(s)->val;
742 c8f53842 2007-03-26 devnull inttoascii(num, count(a));
743 f08fdedc 2003-11-23 devnull }
744 f08fdedc 2003-11-23 devnull else{
745 c8f53842 2007-03-26 devnull a = vlook("*")->val;
746 c8f53842 2007-03-26 devnull inttoascii(num, a && 1<=n && n<=count(a)?1:0);
747 f08fdedc 2003-11-23 devnull }
748 f08fdedc 2003-11-23 devnull poplist();
749 f08fdedc 2003-11-23 devnull pushword(num);
750 f08fdedc 2003-11-23 devnull }
751 c8f53842 2007-03-26 devnull
752 c8f53842 2007-03-26 devnull void
753 c8f53842 2007-03-26 devnull Xlocal(void)
754 c8f53842 2007-03-26 devnull {
755 f08fdedc 2003-11-23 devnull if(count(runq->argv->words)!=1){
756 f08fdedc 2003-11-23 devnull Xerror1("variable name must be singleton\n");
757 f08fdedc 2003-11-23 devnull return;
758 f08fdedc 2003-11-23 devnull }
759 f08fdedc 2003-11-23 devnull deglob(runq->argv->words->word);
760 c8f53842 2007-03-26 devnull runq->local = newvar(strdup(runq->argv->words->word), runq->local);
761 c8f53842 2007-03-26 devnull runq->local->val = copywords(runq->argv->next->words, (word *)0);
762 c8f53842 2007-03-26 devnull runq->local->changed = 1;
763 f08fdedc 2003-11-23 devnull poplist();
764 f08fdedc 2003-11-23 devnull poplist();
765 f08fdedc 2003-11-23 devnull }
766 c8f53842 2007-03-26 devnull
767 c8f53842 2007-03-26 devnull void
768 c8f53842 2007-03-26 devnull Xunlocal(void)
769 c8f53842 2007-03-26 devnull {
770 c8f53842 2007-03-26 devnull var *v = runq->local, *hid;
771 c8f53842 2007-03-26 devnull if(v==0)
772 c8f53842 2007-03-26 devnull panic("Xunlocal: no locals!", 0);
773 c8f53842 2007-03-26 devnull runq->local = v->next;
774 c8f53842 2007-03-26 devnull hid = vlook(v->name);
775 c8f53842 2007-03-26 devnull hid->changed = 1;
776 f08fdedc 2003-11-23 devnull efree(v->name);
777 f08fdedc 2003-11-23 devnull freewords(v->val);
778 f08fdedc 2003-11-23 devnull efree((char *)v);
779 f08fdedc 2003-11-23 devnull }
780 c8f53842 2007-03-26 devnull
781 c8f53842 2007-03-26 devnull void
782 c8f53842 2007-03-26 devnull freewords(word *w)
783 f08fdedc 2003-11-23 devnull {
784 f08fdedc 2003-11-23 devnull word *nw;
785 f08fdedc 2003-11-23 devnull while(w){
786 f08fdedc 2003-11-23 devnull efree(w->word);
787 c8f53842 2007-03-26 devnull nw = w->next;
788 f08fdedc 2003-11-23 devnull efree((char *)w);
789 c8f53842 2007-03-26 devnull w = nw;
790 f08fdedc 2003-11-23 devnull }
791 f08fdedc 2003-11-23 devnull }
792 c8f53842 2007-03-26 devnull
793 c8f53842 2007-03-26 devnull void
794 c8f53842 2007-03-26 devnull Xfn(void)
795 c8f53842 2007-03-26 devnull {
796 f08fdedc 2003-11-23 devnull var *v;
797 f08fdedc 2003-11-23 devnull word *a;
798 f08fdedc 2003-11-23 devnull int end;
799 c8f53842 2007-03-26 devnull end = runq->code[runq->pc].i;
800 c8f53842 2007-03-26 devnull for(a = runq->argv->words;a;a = a->next){
801 c8f53842 2007-03-26 devnull v = gvlook(a->word);
802 c8f53842 2007-03-26 devnull if(v->fn)
803 c8f53842 2007-03-26 devnull codefree(v->fn);
804 c8f53842 2007-03-26 devnull v->fn = codecopy(runq->code);
805 c8f53842 2007-03-26 devnull v->pc = runq->pc+2;
806 c8f53842 2007-03-26 devnull v->fnchanged = 1;
807 f08fdedc 2003-11-23 devnull }
808 c8f53842 2007-03-26 devnull runq->pc = end;
809 f08fdedc 2003-11-23 devnull poplist();
810 f08fdedc 2003-11-23 devnull }
811 c8f53842 2007-03-26 devnull
812 c8f53842 2007-03-26 devnull void
813 c8f53842 2007-03-26 devnull Xdelfn(void)
814 c8f53842 2007-03-26 devnull {
815 f08fdedc 2003-11-23 devnull var *v;
816 f08fdedc 2003-11-23 devnull word *a;
817 c8f53842 2007-03-26 devnull for(a = runq->argv->words;a;a = a->next){
818 c8f53842 2007-03-26 devnull v = gvlook(a->word);
819 c8f53842 2007-03-26 devnull if(v->fn)
820 c8f53842 2007-03-26 devnull codefree(v->fn);
821 c8f53842 2007-03-26 devnull v->fn = 0;
822 c8f53842 2007-03-26 devnull v->fnchanged = 1;
823 f08fdedc 2003-11-23 devnull }
824 f08fdedc 2003-11-23 devnull poplist();
825 f08fdedc 2003-11-23 devnull }
826 c8f53842 2007-03-26 devnull
827 c8f53842 2007-03-26 devnull char*
828 c8f53842 2007-03-26 devnull concstatus(char *s, char *t)
829 f08fdedc 2003-11-23 devnull {
830 f08fdedc 2003-11-23 devnull static char v[NSTATUS+1];
831 c8f53842 2007-03-26 devnull int n = strlen(s);
832 f08fdedc 2003-11-23 devnull strncpy(v, s, NSTATUS);
833 f08fdedc 2003-11-23 devnull if(n<NSTATUS){
834 f08fdedc 2003-11-23 devnull v[n]='|';
835 f08fdedc 2003-11-23 devnull strncpy(v+n+1, t, NSTATUS-n-1);
836 f08fdedc 2003-11-23 devnull }
837 f08fdedc 2003-11-23 devnull v[NSTATUS]='\0';
838 f08fdedc 2003-11-23 devnull return v;
839 f08fdedc 2003-11-23 devnull }
840 c8f53842 2007-03-26 devnull
841 c8f53842 2007-03-26 devnull void
842 c8f53842 2007-03-26 devnull Xpipewait(void)
843 c8f53842 2007-03-26 devnull {
844 f08fdedc 2003-11-23 devnull char status[NSTATUS+1];
845 f08fdedc 2003-11-23 devnull if(runq->pid==-1)
846 f08fdedc 2003-11-23 devnull setstatus(concstatus(runq->status, getstatus()));
847 f08fdedc 2003-11-23 devnull else{
848 f08fdedc 2003-11-23 devnull strncpy(status, getstatus(), NSTATUS);
849 f08fdedc 2003-11-23 devnull status[NSTATUS]='\0';
850 f08fdedc 2003-11-23 devnull Waitfor(runq->pid, 1);
851 f08fdedc 2003-11-23 devnull runq->pid=-1;
852 f08fdedc 2003-11-23 devnull setstatus(concstatus(getstatus(), status));
853 f08fdedc 2003-11-23 devnull }
854 f08fdedc 2003-11-23 devnull }
855 c8f53842 2007-03-26 devnull
856 c8f53842 2007-03-26 devnull void
857 c8f53842 2007-03-26 devnull Xrdcmds(void)
858 c8f53842 2007-03-26 devnull {
859 c8f53842 2007-03-26 devnull struct thread *p = runq;
860 f08fdedc 2003-11-23 devnull word *prompt;
861 f08fdedc 2003-11-23 devnull flush(err);
862 c8f53842 2007-03-26 devnull nerror = 0;
863 f08fdedc 2003-11-23 devnull if(flag['s'] && !truestatus())
864 f08fdedc 2003-11-23 devnull pfmt(err, "status=%v\n", vlook("status")->val);
865 f08fdedc 2003-11-23 devnull if(runq->iflag){
866 c8f53842 2007-03-26 devnull prompt = vlook("prompt")->val;
867 f08fdedc 2003-11-23 devnull if(prompt)
868 c8f53842 2007-03-26 devnull promptstr = prompt->word;
869 f08fdedc 2003-11-23 devnull else
870 f08fdedc 2003-11-23 devnull promptstr="% ";
871 f08fdedc 2003-11-23 devnull }
872 f08fdedc 2003-11-23 devnull Noerror();
873 f08fdedc 2003-11-23 devnull if(yyparse()){
874 f08fdedc 2003-11-23 devnull if(!p->iflag || p->eof && !Eintr()){
875 c8f53842 2007-03-26 devnull if(p->cmdfile)
876 c8f53842 2007-03-26 devnull efree(p->cmdfile);
877 f08fdedc 2003-11-23 devnull closeio(p->cmdfd);
878 f08fdedc 2003-11-23 devnull Xreturn(); /* should this be omitted? */
879 f08fdedc 2003-11-23 devnull }
880 f08fdedc 2003-11-23 devnull else{
881 f08fdedc 2003-11-23 devnull if(Eintr()){
882 f08fdedc 2003-11-23 devnull pchr(err, '\n');
883 c8f53842 2007-03-26 devnull p->eof = 0;
884 f08fdedc 2003-11-23 devnull }
885 f08fdedc 2003-11-23 devnull --p->pc; /* go back for next command */
886 f08fdedc 2003-11-23 devnull }
887 f08fdedc 2003-11-23 devnull }
888 f08fdedc 2003-11-23 devnull else{
889 f08fdedc 2003-11-23 devnull ntrap = 0; /* avoid double-interrupts during blocked writes */
890 f08fdedc 2003-11-23 devnull --p->pc; /* re-execute Xrdcmds after codebuf runs */
891 f08fdedc 2003-11-23 devnull start(codebuf, 1, runq->local);
892 f08fdedc 2003-11-23 devnull }
893 f08fdedc 2003-11-23 devnull freenodes();
894 f08fdedc 2003-11-23 devnull }
895 c8f53842 2007-03-26 devnull
896 c8f53842 2007-03-26 devnull void
897 c8f53842 2007-03-26 devnull Xerror(char *s)
898 f08fdedc 2003-11-23 devnull {
899 f08fdedc 2003-11-23 devnull if(strcmp(argv0, "rc")==0 || strcmp(argv0, "/bin/rc")==0)
900 f08fdedc 2003-11-23 devnull pfmt(err, "rc: %s: %r\n", s);
901 f08fdedc 2003-11-23 devnull else
902 f08fdedc 2003-11-23 devnull pfmt(err, "rc (%s): %s: %r\n", argv0, s);
903 f08fdedc 2003-11-23 devnull flush(err);
904 4ae2f414 2005-08-11 devnull setstatus("error");
905 f08fdedc 2003-11-23 devnull while(!runq->iflag) Xreturn();
906 f08fdedc 2003-11-23 devnull }
907 c8f53842 2007-03-26 devnull
908 c8f53842 2007-03-26 devnull void
909 c8f53842 2007-03-26 devnull Xerror1(char *s)
910 f08fdedc 2003-11-23 devnull {
911 f08fdedc 2003-11-23 devnull if(strcmp(argv0, "rc")==0 || strcmp(argv0, "/bin/rc")==0)
912 f08fdedc 2003-11-23 devnull pfmt(err, "rc: %s\n", s);
913 f08fdedc 2003-11-23 devnull else
914 f08fdedc 2003-11-23 devnull pfmt(err, "rc (%s): %s\n", argv0, s);
915 f08fdedc 2003-11-23 devnull flush(err);
916 4ae2f414 2005-08-11 devnull setstatus("error");
917 f08fdedc 2003-11-23 devnull while(!runq->iflag) Xreturn();
918 f08fdedc 2003-11-23 devnull }
919 c8f53842 2007-03-26 devnull
920 c8f53842 2007-03-26 devnull void
921 c8f53842 2007-03-26 devnull setstatus(char *s)
922 f08fdedc 2003-11-23 devnull {
923 f08fdedc 2003-11-23 devnull setvar("status", newword(s, (word *)0));
924 f08fdedc 2003-11-23 devnull }
925 c8f53842 2007-03-26 devnull
926 c8f53842 2007-03-26 devnull char*
927 c8f53842 2007-03-26 devnull getstatus(void)
928 c8f53842 2007-03-26 devnull {
929 c8f53842 2007-03-26 devnull var *status = vlook("status");
930 f08fdedc 2003-11-23 devnull return status->val?status->val->word:"";
931 f08fdedc 2003-11-23 devnull }
932 c8f53842 2007-03-26 devnull
933 c8f53842 2007-03-26 devnull int
934 c8f53842 2007-03-26 devnull truestatus(void)
935 c8f53842 2007-03-26 devnull {
936 f08fdedc 2003-11-23 devnull char *s;
937 c8f53842 2007-03-26 devnull for(s = getstatus();*s;s++)
938 c8f53842 2007-03-26 devnull if(*s!='|' && *s!='0')
939 c8f53842 2007-03-26 devnull return 0;
940 f08fdedc 2003-11-23 devnull return 1;
941 f08fdedc 2003-11-23 devnull }
942 c8f53842 2007-03-26 devnull
943 c8f53842 2007-03-26 devnull void
944 c8f53842 2007-03-26 devnull Xdelhere(void)
945 c8f53842 2007-03-26 devnull {
946 f08fdedc 2003-11-23 devnull Unlink(runq->code[runq->pc++].s);
947 f08fdedc 2003-11-23 devnull }
948 c8f53842 2007-03-26 devnull
949 c8f53842 2007-03-26 devnull void
950 c8f53842 2007-03-26 devnull Xfor(void)
951 c8f53842 2007-03-26 devnull {
952 f08fdedc 2003-11-23 devnull if(runq->argv->words==0){
953 f08fdedc 2003-11-23 devnull poplist();
954 c8f53842 2007-03-26 devnull runq->pc = runq->code[runq->pc].i;
955 f08fdedc 2003-11-23 devnull }
956 f08fdedc 2003-11-23 devnull else{
957 f08fdedc 2003-11-23 devnull freelist(runq->local->val);
958 c8f53842 2007-03-26 devnull runq->local->val = runq->argv->words;
959 c8f53842 2007-03-26 devnull runq->local->changed = 1;
960 c8f53842 2007-03-26 devnull runq->argv->words = runq->argv->words->next;
961 c8f53842 2007-03-26 devnull runq->local->val->next = 0;
962 f08fdedc 2003-11-23 devnull runq->pc++;
963 f08fdedc 2003-11-23 devnull }
964 f08fdedc 2003-11-23 devnull }
965 c8f53842 2007-03-26 devnull
966 c8f53842 2007-03-26 devnull void
967 c8f53842 2007-03-26 devnull Xglob(void)
968 c8f53842 2007-03-26 devnull {
969 f08fdedc 2003-11-23 devnull globlist();
970 f08fdedc 2003-11-23 devnull }