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 fa325e9b 2020-01-10 cross
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 47d4646e 2020-05-05 rsc argc = getflags(argc, argv, "DSYsrdiIlxepvVc: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 a3b799d9 2011-08-02 rsc return 0; /* not reached; silence OS X Lion gcc */
193 f08fdedc 2003-11-23 devnull }
194 f08fdedc 2003-11-23 devnull /*
195 f08fdedc 2003-11-23 devnull * Opcode routines
196 f08fdedc 2003-11-23 devnull * Arguments on stack (...)
197 f08fdedc 2003-11-23 devnull * Arguments in line [...]
198 f08fdedc 2003-11-23 devnull * Code in line with jump around {...}
199 f08fdedc 2003-11-23 devnull *
200 f08fdedc 2003-11-23 devnull * Xappend(file)[fd] open file to append
201 f08fdedc 2003-11-23 devnull * Xassign(name, val) assign val to name
202 f08fdedc 2003-11-23 devnull * Xasync{... Xexit} make thread for {}, no wait
203 f08fdedc 2003-11-23 devnull * Xbackq{... Xreturn} make thread for {}, push stdout
204 f08fdedc 2003-11-23 devnull * Xbang complement condition
205 f08fdedc 2003-11-23 devnull * Xcase(pat, value){...} exec code on match, leave (value) on
206 f08fdedc 2003-11-23 devnull * stack
207 f08fdedc 2003-11-23 devnull * Xclose[i] close file descriptor
208 f08fdedc 2003-11-23 devnull * Xconc(left, right) concatenate, push results
209 f08fdedc 2003-11-23 devnull * Xcount(name) push var count
210 f08fdedc 2003-11-23 devnull * Xdelfn(name) delete function definition
211 f08fdedc 2003-11-23 devnull * Xdeltraps(names) delete named traps
212 f08fdedc 2003-11-23 devnull * Xdol(name) get variable value
213 f08fdedc 2003-11-23 devnull * Xqdol(name) concatenate variable components
214 f08fdedc 2003-11-23 devnull * Xdup[i j] dup file descriptor
215 f08fdedc 2003-11-23 devnull * Xexit rc exits with status
216 f08fdedc 2003-11-23 devnull * Xfalse{...} execute {} if false
217 f08fdedc 2003-11-23 devnull * Xfn(name){... Xreturn} define function
218 f08fdedc 2003-11-23 devnull * Xfor(var, list){... Xreturn} for loop
219 f08fdedc 2003-11-23 devnull * Xjump[addr] goto
220 f08fdedc 2003-11-23 devnull * Xlocal(name, val) create local variable, assign value
221 f08fdedc 2003-11-23 devnull * Xmark mark stack
222 f08fdedc 2003-11-23 devnull * Xmatch(pat, str) match pattern, set status
223 f08fdedc 2003-11-23 devnull * Xpipe[i j]{... Xreturn}{... Xreturn} construct a pipe between 2 new threads,
224 f08fdedc 2003-11-23 devnull * wait for both
225 f08fdedc 2003-11-23 devnull * Xpipefd[type]{... Xreturn} connect {} to pipe (input or output,
226 f08fdedc 2003-11-23 devnull * depending on type), push /dev/fd/??
227 f08fdedc 2003-11-23 devnull * Xpopm(value) pop value from stack
228 c8f53842 2007-03-26 devnull * Xrdwr(file)[fd] open file for reading and writing
229 f08fdedc 2003-11-23 devnull * Xread(file)[fd] open file to read
230 f08fdedc 2003-11-23 devnull * Xsettraps(names){... Xreturn} define trap functions
231 f08fdedc 2003-11-23 devnull * Xshowtraps print trap list
232 f08fdedc 2003-11-23 devnull * Xsimple(args) run command and wait
233 f08fdedc 2003-11-23 devnull * Xreturn kill thread
234 f08fdedc 2003-11-23 devnull * Xsubshell{... Xexit} execute {} in a subshell and wait
235 f08fdedc 2003-11-23 devnull * Xtrue{...} execute {} if true
236 f08fdedc 2003-11-23 devnull * Xunlocal delete local variable
237 f08fdedc 2003-11-23 devnull * Xword[string] push string
238 f08fdedc 2003-11-23 devnull * Xwrite(file)[fd] open file to write
239 f08fdedc 2003-11-23 devnull */
240 c8f53842 2007-03-26 devnull
241 c8f53842 2007-03-26 devnull void
242 c8f53842 2007-03-26 devnull Xappend(void)
243 c8f53842 2007-03-26 devnull {
244 f08fdedc 2003-11-23 devnull char *file;
245 f08fdedc 2003-11-23 devnull int f;
246 f08fdedc 2003-11-23 devnull switch(count(runq->argv->words)){
247 c8f53842 2007-03-26 devnull default:
248 c8f53842 2007-03-26 devnull Xerror1(">> requires singleton");
249 c8f53842 2007-03-26 devnull return;
250 c8f53842 2007-03-26 devnull case 0:
251 c8f53842 2007-03-26 devnull Xerror1(">> requires file");
252 c8f53842 2007-03-26 devnull return;
253 c8f53842 2007-03-26 devnull case 1:
254 c8f53842 2007-03-26 devnull break;
255 f08fdedc 2003-11-23 devnull }
256 c8f53842 2007-03-26 devnull file = runq->argv->words->word;
257 c8f53842 2007-03-26 devnull if((f = open(file, 1))<0 && (f = Creat(file))<0){
258 f08fdedc 2003-11-23 devnull pfmt(err, "%s: ", file);
259 f08fdedc 2003-11-23 devnull Xerror("can't open");
260 f08fdedc 2003-11-23 devnull return;
261 f08fdedc 2003-11-23 devnull }
262 f08fdedc 2003-11-23 devnull Seek(f, 0L, 2);
263 f08fdedc 2003-11-23 devnull pushredir(ROPEN, f, runq->code[runq->pc].i);
264 f08fdedc 2003-11-23 devnull runq->pc++;
265 f08fdedc 2003-11-23 devnull poplist();
266 f08fdedc 2003-11-23 devnull }
267 c8f53842 2007-03-26 devnull
268 c8f53842 2007-03-26 devnull void
269 c8f53842 2007-03-26 devnull Xsettrue(void)
270 c8f53842 2007-03-26 devnull {
271 f08fdedc 2003-11-23 devnull setstatus("");
272 f08fdedc 2003-11-23 devnull }
273 c8f53842 2007-03-26 devnull
274 c8f53842 2007-03-26 devnull void
275 c8f53842 2007-03-26 devnull Xbang(void)
276 c8f53842 2007-03-26 devnull {
277 f08fdedc 2003-11-23 devnull setstatus(truestatus()?"false":"");
278 f08fdedc 2003-11-23 devnull }
279 c8f53842 2007-03-26 devnull
280 c8f53842 2007-03-26 devnull void
281 c8f53842 2007-03-26 devnull Xclose(void)
282 c8f53842 2007-03-26 devnull {
283 f08fdedc 2003-11-23 devnull pushredir(RCLOSE, runq->code[runq->pc].i, 0);
284 f08fdedc 2003-11-23 devnull runq->pc++;
285 f08fdedc 2003-11-23 devnull }
286 c8f53842 2007-03-26 devnull
287 c8f53842 2007-03-26 devnull void
288 c8f53842 2007-03-26 devnull Xdup(void)
289 c8f53842 2007-03-26 devnull {
290 f08fdedc 2003-11-23 devnull pushredir(RDUP, runq->code[runq->pc].i, runq->code[runq->pc+1].i);
291 f08fdedc 2003-11-23 devnull runq->pc+=2;
292 f08fdedc 2003-11-23 devnull }
293 c8f53842 2007-03-26 devnull
294 c8f53842 2007-03-26 devnull void
295 c8f53842 2007-03-26 devnull Xeflag(void)
296 c8f53842 2007-03-26 devnull {
297 f08fdedc 2003-11-23 devnull if(eflagok && !truestatus()) Xexit();
298 f08fdedc 2003-11-23 devnull }
299 c8f53842 2007-03-26 devnull
300 c8f53842 2007-03-26 devnull void
301 c8f53842 2007-03-26 devnull Xexit(void)
302 c8f53842 2007-03-26 devnull {
303 f08fdedc 2003-11-23 devnull struct var *trapreq;
304 f08fdedc 2003-11-23 devnull struct word *starval;
305 c8f53842 2007-03-26 devnull static int beenhere = 0;
306 f08fdedc 2003-11-23 devnull if(getpid()==mypid && !beenhere){
307 c8f53842 2007-03-26 devnull trapreq = vlook("sigexit");
308 f08fdedc 2003-11-23 devnull if(trapreq->fn){
309 c8f53842 2007-03-26 devnull beenhere = 1;
310 f08fdedc 2003-11-23 devnull --runq->pc;
311 c8f53842 2007-03-26 devnull starval = vlook("*")->val;
312 f08fdedc 2003-11-23 devnull start(trapreq->fn, trapreq->pc, (struct var *)0);
313 c8f53842 2007-03-26 devnull runq->local = newvar(strdup("*"), runq->local);
314 c8f53842 2007-03-26 devnull runq->local->val = copywords(starval, (struct word *)0);
315 c8f53842 2007-03-26 devnull runq->local->changed = 1;
316 c8f53842 2007-03-26 devnull runq->redir = runq->startredir = 0;
317 f08fdedc 2003-11-23 devnull return;
318 f08fdedc 2003-11-23 devnull }
319 f08fdedc 2003-11-23 devnull }
320 f08fdedc 2003-11-23 devnull Exit(getstatus());
321 f08fdedc 2003-11-23 devnull }
322 c8f53842 2007-03-26 devnull
323 c8f53842 2007-03-26 devnull void
324 c8f53842 2007-03-26 devnull Xfalse(void)
325 c8f53842 2007-03-26 devnull {
326 c8f53842 2007-03-26 devnull if(truestatus()) runq->pc = runq->code[runq->pc].i;
327 f08fdedc 2003-11-23 devnull else runq->pc++;
328 f08fdedc 2003-11-23 devnull }
329 f08fdedc 2003-11-23 devnull int ifnot; /* dynamic if not flag */
330 c8f53842 2007-03-26 devnull
331 c8f53842 2007-03-26 devnull void
332 c8f53842 2007-03-26 devnull Xifnot(void)
333 c8f53842 2007-03-26 devnull {
334 f08fdedc 2003-11-23 devnull if(ifnot)
335 f08fdedc 2003-11-23 devnull runq->pc++;
336 f08fdedc 2003-11-23 devnull else
337 c8f53842 2007-03-26 devnull runq->pc = runq->code[runq->pc].i;
338 f08fdedc 2003-11-23 devnull }
339 c8f53842 2007-03-26 devnull
340 c8f53842 2007-03-26 devnull void
341 c8f53842 2007-03-26 devnull Xjump(void)
342 c8f53842 2007-03-26 devnull {
343 c8f53842 2007-03-26 devnull runq->pc = runq->code[runq->pc].i;
344 f08fdedc 2003-11-23 devnull }
345 c8f53842 2007-03-26 devnull
346 c8f53842 2007-03-26 devnull void
347 c8f53842 2007-03-26 devnull Xmark(void)
348 c8f53842 2007-03-26 devnull {
349 f08fdedc 2003-11-23 devnull pushlist();
350 f08fdedc 2003-11-23 devnull }
351 c8f53842 2007-03-26 devnull
352 c8f53842 2007-03-26 devnull void
353 c8f53842 2007-03-26 devnull Xpopm(void)
354 c8f53842 2007-03-26 devnull {
355 f08fdedc 2003-11-23 devnull poplist();
356 f08fdedc 2003-11-23 devnull }
357 c8f53842 2007-03-26 devnull
358 c8f53842 2007-03-26 devnull void
359 c8f53842 2007-03-26 devnull Xread(void)
360 c8f53842 2007-03-26 devnull {
361 f08fdedc 2003-11-23 devnull char *file;
362 f08fdedc 2003-11-23 devnull int f;
363 f08fdedc 2003-11-23 devnull switch(count(runq->argv->words)){
364 c8f53842 2007-03-26 devnull default:
365 c8f53842 2007-03-26 devnull Xerror1("< requires singleton\n");
366 c8f53842 2007-03-26 devnull return;
367 c8f53842 2007-03-26 devnull case 0:
368 c8f53842 2007-03-26 devnull Xerror1("< requires file\n");
369 c8f53842 2007-03-26 devnull return;
370 c8f53842 2007-03-26 devnull case 1:
371 c8f53842 2007-03-26 devnull break;
372 f08fdedc 2003-11-23 devnull }
373 c8f53842 2007-03-26 devnull file = runq->argv->words->word;
374 c8f53842 2007-03-26 devnull if((f = open(file, 0))<0){
375 f08fdedc 2003-11-23 devnull pfmt(err, "%s: ", file);
376 f08fdedc 2003-11-23 devnull Xerror("can't open");
377 f08fdedc 2003-11-23 devnull return;
378 f08fdedc 2003-11-23 devnull }
379 f08fdedc 2003-11-23 devnull pushredir(ROPEN, f, runq->code[runq->pc].i);
380 f08fdedc 2003-11-23 devnull runq->pc++;
381 f08fdedc 2003-11-23 devnull poplist();
382 f08fdedc 2003-11-23 devnull }
383 c8f53842 2007-03-26 devnull
384 c8f53842 2007-03-26 devnull void
385 c8f53842 2007-03-26 devnull Xrdwr(void)
386 c8f53842 2007-03-26 devnull {
387 c8f53842 2007-03-26 devnull char *file;
388 c8f53842 2007-03-26 devnull int f;
389 c8f53842 2007-03-26 devnull
390 c8f53842 2007-03-26 devnull switch(count(runq->argv->words)){
391 c8f53842 2007-03-26 devnull default:
392 c8f53842 2007-03-26 devnull Xerror1("<> requires singleton\n");
393 c8f53842 2007-03-26 devnull return;
394 c8f53842 2007-03-26 devnull case 0:
395 c8f53842 2007-03-26 devnull Xerror1("<> requires file\n");
396 c8f53842 2007-03-26 devnull return;
397 c8f53842 2007-03-26 devnull case 1:
398 c8f53842 2007-03-26 devnull break;
399 c8f53842 2007-03-26 devnull }
400 c8f53842 2007-03-26 devnull file = runq->argv->words->word;
401 c8f53842 2007-03-26 devnull if((f = open(file, ORDWR))<0){
402 c8f53842 2007-03-26 devnull pfmt(err, "%s: ", file);
403 c8f53842 2007-03-26 devnull Xerror("can't open");
404 c8f53842 2007-03-26 devnull return;
405 c8f53842 2007-03-26 devnull }
406 c8f53842 2007-03-26 devnull pushredir(ROPEN, f, runq->code[runq->pc].i);
407 c8f53842 2007-03-26 devnull runq->pc++;
408 c8f53842 2007-03-26 devnull poplist();
409 c8f53842 2007-03-26 devnull }
410 c8f53842 2007-03-26 devnull
411 c8f53842 2007-03-26 devnull void
412 c8f53842 2007-03-26 devnull turfredir(void)
413 c8f53842 2007-03-26 devnull {
414 f08fdedc 2003-11-23 devnull while(runq->redir!=runq->startredir)
415 f08fdedc 2003-11-23 devnull Xpopredir();
416 f08fdedc 2003-11-23 devnull }
417 c8f53842 2007-03-26 devnull
418 c8f53842 2007-03-26 devnull void
419 c8f53842 2007-03-26 devnull Xpopredir(void)
420 c8f53842 2007-03-26 devnull {
421 c8f53842 2007-03-26 devnull struct redir *rp = runq->redir;
422 c8f53842 2007-03-26 devnull if(rp==0)
423 c8f53842 2007-03-26 devnull panic("turfredir null!", 0);
424 c8f53842 2007-03-26 devnull runq->redir = rp->next;
425 c8f53842 2007-03-26 devnull if(rp->type==ROPEN)
426 c8f53842 2007-03-26 devnull close(rp->from);
427 f08fdedc 2003-11-23 devnull efree((char *)rp);
428 f08fdedc 2003-11-23 devnull }
429 c8f53842 2007-03-26 devnull
430 c8f53842 2007-03-26 devnull void
431 c8f53842 2007-03-26 devnull Xreturn(void)
432 c8f53842 2007-03-26 devnull {
433 c8f53842 2007-03-26 devnull struct thread *p = runq;
434 f08fdedc 2003-11-23 devnull turfredir();
435 f08fdedc 2003-11-23 devnull while(p->argv) poplist();
436 f08fdedc 2003-11-23 devnull codefree(p->code);
437 c8f53842 2007-03-26 devnull runq = p->ret;
438 f08fdedc 2003-11-23 devnull efree((char *)p);
439 c8f53842 2007-03-26 devnull if(runq==0)
440 c8f53842 2007-03-26 devnull Exit(getstatus());
441 f08fdedc 2003-11-23 devnull }
442 c8f53842 2007-03-26 devnull
443 c8f53842 2007-03-26 devnull void
444 c8f53842 2007-03-26 devnull Xtrue(void)
445 c8f53842 2007-03-26 devnull {
446 f08fdedc 2003-11-23 devnull if(truestatus()) runq->pc++;
447 c8f53842 2007-03-26 devnull else runq->pc = runq->code[runq->pc].i;
448 f08fdedc 2003-11-23 devnull }
449 c8f53842 2007-03-26 devnull
450 c8f53842 2007-03-26 devnull void
451 c8f53842 2007-03-26 devnull Xif(void)
452 c8f53842 2007-03-26 devnull {
453 c8f53842 2007-03-26 devnull ifnot = 1;
454 f08fdedc 2003-11-23 devnull if(truestatus()) runq->pc++;
455 c8f53842 2007-03-26 devnull else runq->pc = runq->code[runq->pc].i;
456 f08fdedc 2003-11-23 devnull }
457 c8f53842 2007-03-26 devnull
458 c8f53842 2007-03-26 devnull void
459 c8f53842 2007-03-26 devnull Xwastrue(void)
460 c8f53842 2007-03-26 devnull {
461 c8f53842 2007-03-26 devnull ifnot = 0;
462 f08fdedc 2003-11-23 devnull }
463 c8f53842 2007-03-26 devnull
464 c8f53842 2007-03-26 devnull void
465 c8f53842 2007-03-26 devnull Xword(void)
466 c8f53842 2007-03-26 devnull {
467 f08fdedc 2003-11-23 devnull pushword(runq->code[runq->pc++].s);
468 f08fdedc 2003-11-23 devnull }
469 c8f53842 2007-03-26 devnull
470 c8f53842 2007-03-26 devnull void
471 c8f53842 2007-03-26 devnull Xwrite(void)
472 c8f53842 2007-03-26 devnull {
473 f08fdedc 2003-11-23 devnull char *file;
474 f08fdedc 2003-11-23 devnull int f;
475 f08fdedc 2003-11-23 devnull switch(count(runq->argv->words)){
476 c8f53842 2007-03-26 devnull default:
477 c8f53842 2007-03-26 devnull Xerror1("> requires singleton\n");
478 c8f53842 2007-03-26 devnull return;
479 c8f53842 2007-03-26 devnull case 0:
480 c8f53842 2007-03-26 devnull Xerror1("> requires file\n");
481 c8f53842 2007-03-26 devnull return;
482 c8f53842 2007-03-26 devnull case 1:
483 c8f53842 2007-03-26 devnull break;
484 f08fdedc 2003-11-23 devnull }
485 c8f53842 2007-03-26 devnull file = runq->argv->words->word;
486 c8f53842 2007-03-26 devnull if((f = Creat(file))<0){
487 f08fdedc 2003-11-23 devnull pfmt(err, "%s: ", file);
488 f08fdedc 2003-11-23 devnull Xerror("can't open");
489 f08fdedc 2003-11-23 devnull return;
490 f08fdedc 2003-11-23 devnull }
491 f08fdedc 2003-11-23 devnull pushredir(ROPEN, f, runq->code[runq->pc].i);
492 f08fdedc 2003-11-23 devnull runq->pc++;
493 f08fdedc 2003-11-23 devnull poplist();
494 f08fdedc 2003-11-23 devnull }
495 c8f53842 2007-03-26 devnull
496 c8f53842 2007-03-26 devnull char*
497 c8f53842 2007-03-26 devnull list2str(word *words)
498 c8f53842 2007-03-26 devnull {
499 f08fdedc 2003-11-23 devnull char *value, *s, *t;
500 c8f53842 2007-03-26 devnull int len = 0;
501 f08fdedc 2003-11-23 devnull word *ap;
502 c8f53842 2007-03-26 devnull for(ap = words;ap;ap = ap->next)
503 f08fdedc 2003-11-23 devnull len+=1+strlen(ap->word);
504 c8f53842 2007-03-26 devnull value = emalloc(len+1);
505 c8f53842 2007-03-26 devnull s = value;
506 c8f53842 2007-03-26 devnull for(ap = words;ap;ap = ap->next){
507 c8f53842 2007-03-26 devnull for(t = ap->word;*t;) *s++=*t++;
508 c8f53842 2007-03-26 devnull *s++=' ';
509 f08fdedc 2003-11-23 devnull }
510 c8f53842 2007-03-26 devnull if(s==value)
511 c8f53842 2007-03-26 devnull *s='\0';
512 f08fdedc 2003-11-23 devnull else s[-1]='\0';
513 f08fdedc 2003-11-23 devnull return value;
514 f08fdedc 2003-11-23 devnull }
515 c8f53842 2007-03-26 devnull
516 c8f53842 2007-03-26 devnull void
517 c8f53842 2007-03-26 devnull Xmatch(void)
518 c8f53842 2007-03-26 devnull {
519 f08fdedc 2003-11-23 devnull word *p;
520 f08fdedc 2003-11-23 devnull char *subject;
521 c8f53842 2007-03-26 devnull subject = list2str(runq->argv->words);
522 f08fdedc 2003-11-23 devnull setstatus("no match");
523 c8f53842 2007-03-26 devnull for(p = runq->argv->next->words;p;p = p->next)
524 f08fdedc 2003-11-23 devnull if(match(subject, p->word, '\0')){
525 f08fdedc 2003-11-23 devnull setstatus("");
526 f08fdedc 2003-11-23 devnull break;
527 f08fdedc 2003-11-23 devnull }
528 f08fdedc 2003-11-23 devnull efree(subject);
529 f08fdedc 2003-11-23 devnull poplist();
530 f08fdedc 2003-11-23 devnull poplist();
531 f08fdedc 2003-11-23 devnull }
532 c8f53842 2007-03-26 devnull
533 c8f53842 2007-03-26 devnull void
534 c8f53842 2007-03-26 devnull Xcase(void)
535 c8f53842 2007-03-26 devnull {
536 f08fdedc 2003-11-23 devnull word *p;
537 f08fdedc 2003-11-23 devnull char *s;
538 c8f53842 2007-03-26 devnull int ok = 0;
539 c8f53842 2007-03-26 devnull s = list2str(runq->argv->next->words);
540 c8f53842 2007-03-26 devnull for(p = runq->argv->words;p;p = p->next){
541 f08fdedc 2003-11-23 devnull if(match(s, p->word, '\0')){
542 c8f53842 2007-03-26 devnull ok = 1;
543 f08fdedc 2003-11-23 devnull break;
544 f08fdedc 2003-11-23 devnull }
545 f08fdedc 2003-11-23 devnull }
546 f08fdedc 2003-11-23 devnull efree(s);
547 f08fdedc 2003-11-23 devnull if(ok)
548 f08fdedc 2003-11-23 devnull runq->pc++;
549 f08fdedc 2003-11-23 devnull else
550 c8f53842 2007-03-26 devnull runq->pc = runq->code[runq->pc].i;
551 f08fdedc 2003-11-23 devnull poplist();
552 f08fdedc 2003-11-23 devnull }
553 c8f53842 2007-03-26 devnull
554 c8f53842 2007-03-26 devnull word*
555 c8f53842 2007-03-26 devnull conclist(word *lp, word *rp, word *tail)
556 f08fdedc 2003-11-23 devnull {
557 f08fdedc 2003-11-23 devnull char *buf;
558 f08fdedc 2003-11-23 devnull word *v;
559 f08fdedc 2003-11-23 devnull if(lp->next || rp->next)
560 c8f53842 2007-03-26 devnull tail = conclist(lp->next==0?lp:lp->next, rp->next==0?rp:rp->next,
561 f08fdedc 2003-11-23 devnull tail);
562 c8f53842 2007-03-26 devnull buf = emalloc(strlen(lp->word)+strlen(rp->word)+1);
563 f08fdedc 2003-11-23 devnull strcpy(buf, lp->word);
564 f08fdedc 2003-11-23 devnull strcat(buf, rp->word);
565 c8f53842 2007-03-26 devnull v = newword(buf, tail);
566 f08fdedc 2003-11-23 devnull efree(buf);
567 f08fdedc 2003-11-23 devnull return v;
568 f08fdedc 2003-11-23 devnull }
569 c8f53842 2007-03-26 devnull
570 c8f53842 2007-03-26 devnull void
571 c8f53842 2007-03-26 devnull Xconc(void)
572 c8f53842 2007-03-26 devnull {
573 c8f53842 2007-03-26 devnull word *lp = runq->argv->words;
574 c8f53842 2007-03-26 devnull word *rp = runq->argv->next->words;
575 c8f53842 2007-03-26 devnull word *vp = runq->argv->next->next->words;
576 c8f53842 2007-03-26 devnull int lc = count(lp), rc = count(rp);
577 f08fdedc 2003-11-23 devnull if(lc!=0 || rc!=0){
578 f08fdedc 2003-11-23 devnull if(lc==0 || rc==0){
579 f08fdedc 2003-11-23 devnull Xerror1("null list in concatenation");
580 f08fdedc 2003-11-23 devnull return;
581 f08fdedc 2003-11-23 devnull }
582 f08fdedc 2003-11-23 devnull if(lc!=1 && rc!=1 && lc!=rc){
583 f08fdedc 2003-11-23 devnull Xerror1("mismatched list lengths in concatenation");
584 f08fdedc 2003-11-23 devnull return;
585 f08fdedc 2003-11-23 devnull }
586 c8f53842 2007-03-26 devnull vp = conclist(lp, rp, vp);
587 f08fdedc 2003-11-23 devnull }
588 f08fdedc 2003-11-23 devnull poplist();
589 f08fdedc 2003-11-23 devnull poplist();
590 c8f53842 2007-03-26 devnull runq->argv->words = vp;
591 f08fdedc 2003-11-23 devnull }
592 c8f53842 2007-03-26 devnull
593 c8f53842 2007-03-26 devnull void
594 c8f53842 2007-03-26 devnull Xassign(void)
595 c8f53842 2007-03-26 devnull {
596 f08fdedc 2003-11-23 devnull var *v;
597 f08fdedc 2003-11-23 devnull if(count(runq->argv->words)!=1){
598 f08fdedc 2003-11-23 devnull Xerror1("variable name not singleton!");
599 f08fdedc 2003-11-23 devnull return;
600 f08fdedc 2003-11-23 devnull }
601 f08fdedc 2003-11-23 devnull deglob(runq->argv->words->word);
602 c8f53842 2007-03-26 devnull v = vlook(runq->argv->words->word);
603 f08fdedc 2003-11-23 devnull poplist();
604 f08fdedc 2003-11-23 devnull globlist();
605 f08fdedc 2003-11-23 devnull freewords(v->val);
606 c8f53842 2007-03-26 devnull v->val = runq->argv->words;
607 c8f53842 2007-03-26 devnull v->changed = 1;
608 fbc629a9 2007-03-28 devnull if(v->changefn)
609 fbc629a9 2007-03-28 devnull v->changefn(v);
610 c8f53842 2007-03-26 devnull runq->argv->words = 0;
611 f08fdedc 2003-11-23 devnull poplist();
612 f08fdedc 2003-11-23 devnull }
613 f08fdedc 2003-11-23 devnull /*
614 f08fdedc 2003-11-23 devnull * copy arglist a, adding the copy to the front of tail
615 f08fdedc 2003-11-23 devnull */
616 c8f53842 2007-03-26 devnull
617 c8f53842 2007-03-26 devnull word*
618 c8f53842 2007-03-26 devnull copywords(word *a, word *tail)
619 f08fdedc 2003-11-23 devnull {
620 c8f53842 2007-03-26 devnull word *v = 0, **end;
621 c8f53842 2007-03-26 devnull for(end=&v;a;a = a->next,end=&(*end)->next)
622 c8f53842 2007-03-26 devnull *end = newword(a->word, 0);
623 c8f53842 2007-03-26 devnull *end = tail;
624 f08fdedc 2003-11-23 devnull return v;
625 f08fdedc 2003-11-23 devnull }
626 c8f53842 2007-03-26 devnull
627 c8f53842 2007-03-26 devnull void
628 c8f53842 2007-03-26 devnull Xdol(void)
629 c8f53842 2007-03-26 devnull {
630 f08fdedc 2003-11-23 devnull word *a, *star;
631 f08fdedc 2003-11-23 devnull char *s, *t;
632 f08fdedc 2003-11-23 devnull int n;
633 f08fdedc 2003-11-23 devnull if(count(runq->argv->words)!=1){
634 f08fdedc 2003-11-23 devnull Xerror1("variable name not singleton!");
635 f08fdedc 2003-11-23 devnull return;
636 f08fdedc 2003-11-23 devnull }
637 c8f53842 2007-03-26 devnull s = runq->argv->words->word;
638 f08fdedc 2003-11-23 devnull deglob(s);
639 c8f53842 2007-03-26 devnull n = 0;
640 c8f53842 2007-03-26 devnull for(t = s;'0'<=*t && *t<='9';t++) n = n*10+*t-'0';
641 c8f53842 2007-03-26 devnull a = runq->argv->next->words;
642 f08fdedc 2003-11-23 devnull if(n==0 || *t)
643 c8f53842 2007-03-26 devnull a = copywords(vlook(s)->val, a);
644 f08fdedc 2003-11-23 devnull else{
645 c8f53842 2007-03-26 devnull star = vlook("*")->val;
646 f08fdedc 2003-11-23 devnull if(star && 1<=n && n<=count(star)){
647 c8f53842 2007-03-26 devnull while(--n) star = star->next;
648 c8f53842 2007-03-26 devnull a = newword(star->word, a);
649 f08fdedc 2003-11-23 devnull }
650 f08fdedc 2003-11-23 devnull }
651 f08fdedc 2003-11-23 devnull poplist();
652 c8f53842 2007-03-26 devnull runq->argv->words = a;
653 f08fdedc 2003-11-23 devnull }
654 c8f53842 2007-03-26 devnull
655 c8f53842 2007-03-26 devnull void
656 c8f53842 2007-03-26 devnull Xqdol(void)
657 c8f53842 2007-03-26 devnull {
658 f08fdedc 2003-11-23 devnull word *a, *p;
659 f08fdedc 2003-11-23 devnull char *s;
660 f08fdedc 2003-11-23 devnull int n;
661 f08fdedc 2003-11-23 devnull if(count(runq->argv->words)!=1){
662 f08fdedc 2003-11-23 devnull Xerror1("variable name not singleton!");
663 f08fdedc 2003-11-23 devnull return;
664 f08fdedc 2003-11-23 devnull }
665 c8f53842 2007-03-26 devnull s = runq->argv->words->word;
666 f08fdedc 2003-11-23 devnull deglob(s);
667 c8f53842 2007-03-26 devnull a = vlook(s)->val;
668 f08fdedc 2003-11-23 devnull poplist();
669 c8f53842 2007-03-26 devnull n = count(a);
670 f08fdedc 2003-11-23 devnull if(n==0){
671 f08fdedc 2003-11-23 devnull pushword("");
672 f08fdedc 2003-11-23 devnull return;
673 f08fdedc 2003-11-23 devnull }
674 c8f53842 2007-03-26 devnull for(p = a;p;p = p->next) n+=strlen(p->word);
675 c8f53842 2007-03-26 devnull s = emalloc(n);
676 f08fdedc 2003-11-23 devnull if(a){
677 f08fdedc 2003-11-23 devnull strcpy(s, a->word);
678 c8f53842 2007-03-26 devnull for(p = a->next;p;p = p->next){
679 f08fdedc 2003-11-23 devnull strcat(s, " ");
680 f08fdedc 2003-11-23 devnull strcat(s, p->word);
681 f08fdedc 2003-11-23 devnull }
682 f08fdedc 2003-11-23 devnull }
683 f08fdedc 2003-11-23 devnull else
684 f08fdedc 2003-11-23 devnull s[0]='\0';
685 f08fdedc 2003-11-23 devnull pushword(s);
686 f08fdedc 2003-11-23 devnull efree(s);
687 f08fdedc 2003-11-23 devnull }
688 c8f53842 2007-03-26 devnull
689 c8f53842 2007-03-26 devnull word*
690 94e1f2a4 2008-07-20 rsc copynwords(word *a, word *tail, int n)
691 94e1f2a4 2008-07-20 rsc {
692 94e1f2a4 2008-07-20 rsc word *v, **end;
693 fa325e9b 2020-01-10 cross
694 94e1f2a4 2008-07-20 rsc v = 0;
695 94e1f2a4 2008-07-20 rsc end = &v;
696 94e1f2a4 2008-07-20 rsc while(n-- > 0){
697 94e1f2a4 2008-07-20 rsc *end = newword(a->word, 0);
698 94e1f2a4 2008-07-20 rsc end = &(*end)->next;
699 94e1f2a4 2008-07-20 rsc a = a->next;
700 94e1f2a4 2008-07-20 rsc }
701 94e1f2a4 2008-07-20 rsc *end = tail;
702 94e1f2a4 2008-07-20 rsc return v;
703 94e1f2a4 2008-07-20 rsc }
704 94e1f2a4 2008-07-20 rsc
705 94e1f2a4 2008-07-20 rsc word*
706 c8f53842 2007-03-26 devnull subwords(word *val, int len, word *sub, word *a)
707 f08fdedc 2003-11-23 devnull {
708 94e1f2a4 2008-07-20 rsc int n, m;
709 f08fdedc 2003-11-23 devnull char *s;
710 c8f53842 2007-03-26 devnull if(!sub)
711 c8f53842 2007-03-26 devnull return a;
712 c8f53842 2007-03-26 devnull a = subwords(val, len, sub->next, a);
713 c8f53842 2007-03-26 devnull s = sub->word;
714 f08fdedc 2003-11-23 devnull deglob(s);
715 94e1f2a4 2008-07-20 rsc m = 0;
716 94e1f2a4 2008-07-20 rsc n = 0;
717 94e1f2a4 2008-07-20 rsc while('0'<=*s && *s<='9')
718 94e1f2a4 2008-07-20 rsc n = n*10+ *s++ -'0';
719 94e1f2a4 2008-07-20 rsc if(*s == '-'){
720 94e1f2a4 2008-07-20 rsc if(*++s == 0)
721 94e1f2a4 2008-07-20 rsc m = len - n;
722 94e1f2a4 2008-07-20 rsc else{
723 94e1f2a4 2008-07-20 rsc while('0'<=*s && *s<='9')
724 94e1f2a4 2008-07-20 rsc m = m*10+ *s++ -'0';
725 94e1f2a4 2008-07-20 rsc m -= n;
726 94e1f2a4 2008-07-20 rsc }
727 94e1f2a4 2008-07-20 rsc }
728 94e1f2a4 2008-07-20 rsc if(n<1 || n>len || m<0)
729 c8f53842 2007-03-26 devnull return a;
730 94e1f2a4 2008-07-20 rsc if(n+m>len)
731 94e1f2a4 2008-07-20 rsc m = len-n;
732 94e1f2a4 2008-07-20 rsc while(--n > 0)
733 94e1f2a4 2008-07-20 rsc val = val->next;
734 94e1f2a4 2008-07-20 rsc return copynwords(val, a, m+1);
735 f08fdedc 2003-11-23 devnull }
736 c8f53842 2007-03-26 devnull
737 c8f53842 2007-03-26 devnull void
738 c8f53842 2007-03-26 devnull Xsub(void)
739 c8f53842 2007-03-26 devnull {
740 f08fdedc 2003-11-23 devnull word *a, *v;
741 f08fdedc 2003-11-23 devnull char *s;
742 f08fdedc 2003-11-23 devnull if(count(runq->argv->next->words)!=1){
743 f08fdedc 2003-11-23 devnull Xerror1("variable name not singleton!");
744 f08fdedc 2003-11-23 devnull return;
745 f08fdedc 2003-11-23 devnull }
746 c8f53842 2007-03-26 devnull s = runq->argv->next->words->word;
747 f08fdedc 2003-11-23 devnull deglob(s);
748 c8f53842 2007-03-26 devnull a = runq->argv->next->next->words;
749 c8f53842 2007-03-26 devnull v = vlook(s)->val;
750 c8f53842 2007-03-26 devnull a = subwords(v, count(v), runq->argv->words, a);
751 f08fdedc 2003-11-23 devnull poplist();
752 f08fdedc 2003-11-23 devnull poplist();
753 c8f53842 2007-03-26 devnull runq->argv->words = a;
754 f08fdedc 2003-11-23 devnull }
755 c8f53842 2007-03-26 devnull
756 c8f53842 2007-03-26 devnull void
757 c8f53842 2007-03-26 devnull Xcount(void)
758 c8f53842 2007-03-26 devnull {
759 f08fdedc 2003-11-23 devnull word *a;
760 f08fdedc 2003-11-23 devnull char *s, *t;
761 f08fdedc 2003-11-23 devnull int n;
762 f08fdedc 2003-11-23 devnull char num[12];
763 f08fdedc 2003-11-23 devnull if(count(runq->argv->words)!=1){
764 f08fdedc 2003-11-23 devnull Xerror1("variable name not singleton!");
765 f08fdedc 2003-11-23 devnull return;
766 f08fdedc 2003-11-23 devnull }
767 c8f53842 2007-03-26 devnull s = runq->argv->words->word;
768 f08fdedc 2003-11-23 devnull deglob(s);
769 c8f53842 2007-03-26 devnull n = 0;
770 c8f53842 2007-03-26 devnull for(t = s;'0'<=*t && *t<='9';t++) n = n*10+*t-'0';
771 f08fdedc 2003-11-23 devnull if(n==0 || *t){
772 c8f53842 2007-03-26 devnull a = vlook(s)->val;
773 c8f53842 2007-03-26 devnull inttoascii(num, count(a));
774 f08fdedc 2003-11-23 devnull }
775 f08fdedc 2003-11-23 devnull else{
776 c8f53842 2007-03-26 devnull a = vlook("*")->val;
777 c8f53842 2007-03-26 devnull inttoascii(num, a && 1<=n && n<=count(a)?1:0);
778 f08fdedc 2003-11-23 devnull }
779 f08fdedc 2003-11-23 devnull poplist();
780 f08fdedc 2003-11-23 devnull pushword(num);
781 f08fdedc 2003-11-23 devnull }
782 c8f53842 2007-03-26 devnull
783 c8f53842 2007-03-26 devnull void
784 c8f53842 2007-03-26 devnull Xlocal(void)
785 c8f53842 2007-03-26 devnull {
786 f08fdedc 2003-11-23 devnull if(count(runq->argv->words)!=1){
787 f08fdedc 2003-11-23 devnull Xerror1("variable name must be singleton\n");
788 f08fdedc 2003-11-23 devnull return;
789 f08fdedc 2003-11-23 devnull }
790 f08fdedc 2003-11-23 devnull deglob(runq->argv->words->word);
791 c8f53842 2007-03-26 devnull runq->local = newvar(strdup(runq->argv->words->word), runq->local);
792 c8f53842 2007-03-26 devnull runq->local->val = copywords(runq->argv->next->words, (word *)0);
793 c8f53842 2007-03-26 devnull runq->local->changed = 1;
794 f08fdedc 2003-11-23 devnull poplist();
795 f08fdedc 2003-11-23 devnull poplist();
796 f08fdedc 2003-11-23 devnull }
797 c8f53842 2007-03-26 devnull
798 c8f53842 2007-03-26 devnull void
799 c8f53842 2007-03-26 devnull Xunlocal(void)
800 c8f53842 2007-03-26 devnull {
801 c8f53842 2007-03-26 devnull var *v = runq->local, *hid;
802 c8f53842 2007-03-26 devnull if(v==0)
803 c8f53842 2007-03-26 devnull panic("Xunlocal: no locals!", 0);
804 c8f53842 2007-03-26 devnull runq->local = v->next;
805 c8f53842 2007-03-26 devnull hid = vlook(v->name);
806 c8f53842 2007-03-26 devnull hid->changed = 1;
807 f08fdedc 2003-11-23 devnull efree(v->name);
808 f08fdedc 2003-11-23 devnull freewords(v->val);
809 f08fdedc 2003-11-23 devnull efree((char *)v);
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 freewords(word *w)
814 f08fdedc 2003-11-23 devnull {
815 f08fdedc 2003-11-23 devnull word *nw;
816 f08fdedc 2003-11-23 devnull while(w){
817 f08fdedc 2003-11-23 devnull efree(w->word);
818 c8f53842 2007-03-26 devnull nw = w->next;
819 f08fdedc 2003-11-23 devnull efree((char *)w);
820 c8f53842 2007-03-26 devnull w = nw;
821 f08fdedc 2003-11-23 devnull }
822 f08fdedc 2003-11-23 devnull }
823 c8f53842 2007-03-26 devnull
824 c8f53842 2007-03-26 devnull void
825 c8f53842 2007-03-26 devnull Xfn(void)
826 c8f53842 2007-03-26 devnull {
827 f08fdedc 2003-11-23 devnull var *v;
828 f08fdedc 2003-11-23 devnull word *a;
829 f08fdedc 2003-11-23 devnull int end;
830 c8f53842 2007-03-26 devnull end = runq->code[runq->pc].i;
831 c8f53842 2007-03-26 devnull for(a = runq->argv->words;a;a = a->next){
832 c8f53842 2007-03-26 devnull v = gvlook(a->word);
833 c8f53842 2007-03-26 devnull if(v->fn)
834 c8f53842 2007-03-26 devnull codefree(v->fn);
835 c8f53842 2007-03-26 devnull v->fn = codecopy(runq->code);
836 c8f53842 2007-03-26 devnull v->pc = runq->pc+2;
837 c8f53842 2007-03-26 devnull v->fnchanged = 1;
838 f08fdedc 2003-11-23 devnull }
839 c8f53842 2007-03-26 devnull runq->pc = end;
840 f08fdedc 2003-11-23 devnull poplist();
841 f08fdedc 2003-11-23 devnull }
842 c8f53842 2007-03-26 devnull
843 c8f53842 2007-03-26 devnull void
844 c8f53842 2007-03-26 devnull Xdelfn(void)
845 c8f53842 2007-03-26 devnull {
846 f08fdedc 2003-11-23 devnull var *v;
847 f08fdedc 2003-11-23 devnull word *a;
848 c8f53842 2007-03-26 devnull for(a = runq->argv->words;a;a = a->next){
849 c8f53842 2007-03-26 devnull v = gvlook(a->word);
850 c8f53842 2007-03-26 devnull if(v->fn)
851 c8f53842 2007-03-26 devnull codefree(v->fn);
852 c8f53842 2007-03-26 devnull v->fn = 0;
853 c8f53842 2007-03-26 devnull v->fnchanged = 1;
854 f08fdedc 2003-11-23 devnull }
855 f08fdedc 2003-11-23 devnull poplist();
856 f08fdedc 2003-11-23 devnull }
857 c8f53842 2007-03-26 devnull
858 c8f53842 2007-03-26 devnull char*
859 c8f53842 2007-03-26 devnull concstatus(char *s, char *t)
860 f08fdedc 2003-11-23 devnull {
861 f08fdedc 2003-11-23 devnull static char v[NSTATUS+1];
862 c8f53842 2007-03-26 devnull int n = strlen(s);
863 f08fdedc 2003-11-23 devnull strncpy(v, s, NSTATUS);
864 f08fdedc 2003-11-23 devnull if(n<NSTATUS){
865 f08fdedc 2003-11-23 devnull v[n]='|';
866 f08fdedc 2003-11-23 devnull strncpy(v+n+1, t, NSTATUS-n-1);
867 f08fdedc 2003-11-23 devnull }
868 f08fdedc 2003-11-23 devnull v[NSTATUS]='\0';
869 f08fdedc 2003-11-23 devnull return v;
870 f08fdedc 2003-11-23 devnull }
871 c8f53842 2007-03-26 devnull
872 c8f53842 2007-03-26 devnull void
873 c8f53842 2007-03-26 devnull Xpipewait(void)
874 c8f53842 2007-03-26 devnull {
875 f08fdedc 2003-11-23 devnull char status[NSTATUS+1];
876 f08fdedc 2003-11-23 devnull if(runq->pid==-1)
877 f08fdedc 2003-11-23 devnull setstatus(concstatus(runq->status, getstatus()));
878 f08fdedc 2003-11-23 devnull else{
879 f08fdedc 2003-11-23 devnull strncpy(status, getstatus(), NSTATUS);
880 f08fdedc 2003-11-23 devnull status[NSTATUS]='\0';
881 f08fdedc 2003-11-23 devnull Waitfor(runq->pid, 1);
882 f08fdedc 2003-11-23 devnull runq->pid=-1;
883 f08fdedc 2003-11-23 devnull setstatus(concstatus(getstatus(), status));
884 f08fdedc 2003-11-23 devnull }
885 f08fdedc 2003-11-23 devnull }
886 c8f53842 2007-03-26 devnull
887 c8f53842 2007-03-26 devnull void
888 c8f53842 2007-03-26 devnull Xrdcmds(void)
889 c8f53842 2007-03-26 devnull {
890 c8f53842 2007-03-26 devnull struct thread *p = runq;
891 f08fdedc 2003-11-23 devnull word *prompt;
892 f08fdedc 2003-11-23 devnull flush(err);
893 c8f53842 2007-03-26 devnull nerror = 0;
894 f08fdedc 2003-11-23 devnull if(flag['s'] && !truestatus())
895 f08fdedc 2003-11-23 devnull pfmt(err, "status=%v\n", vlook("status")->val);
896 f08fdedc 2003-11-23 devnull if(runq->iflag){
897 c8f53842 2007-03-26 devnull prompt = vlook("prompt")->val;
898 f08fdedc 2003-11-23 devnull if(prompt)
899 c8f53842 2007-03-26 devnull promptstr = prompt->word;
900 f08fdedc 2003-11-23 devnull else
901 f08fdedc 2003-11-23 devnull promptstr="% ";
902 f08fdedc 2003-11-23 devnull }
903 f08fdedc 2003-11-23 devnull Noerror();
904 47d4646e 2020-05-05 rsc if((flag['Y'] ? yyparse : parse)()){
905 f08fdedc 2003-11-23 devnull if(!p->iflag || p->eof && !Eintr()){
906 c8f53842 2007-03-26 devnull if(p->cmdfile)
907 c8f53842 2007-03-26 devnull efree(p->cmdfile);
908 f08fdedc 2003-11-23 devnull closeio(p->cmdfd);
909 f08fdedc 2003-11-23 devnull Xreturn(); /* should this be omitted? */
910 f08fdedc 2003-11-23 devnull }
911 f08fdedc 2003-11-23 devnull else{
912 f08fdedc 2003-11-23 devnull if(Eintr()){
913 f08fdedc 2003-11-23 devnull pchr(err, '\n');
914 c8f53842 2007-03-26 devnull p->eof = 0;
915 f08fdedc 2003-11-23 devnull }
916 f08fdedc 2003-11-23 devnull --p->pc; /* go back for next command */
917 f08fdedc 2003-11-23 devnull }
918 f08fdedc 2003-11-23 devnull }
919 f08fdedc 2003-11-23 devnull else{
920 f08fdedc 2003-11-23 devnull ntrap = 0; /* avoid double-interrupts during blocked writes */
921 f08fdedc 2003-11-23 devnull --p->pc; /* re-execute Xrdcmds after codebuf runs */
922 f08fdedc 2003-11-23 devnull start(codebuf, 1, runq->local);
923 f08fdedc 2003-11-23 devnull }
924 f08fdedc 2003-11-23 devnull freenodes();
925 f08fdedc 2003-11-23 devnull }
926 c8f53842 2007-03-26 devnull
927 c8f53842 2007-03-26 devnull void
928 c8f53842 2007-03-26 devnull Xerror(char *s)
929 f08fdedc 2003-11-23 devnull {
930 f08fdedc 2003-11-23 devnull if(strcmp(argv0, "rc")==0 || strcmp(argv0, "/bin/rc")==0)
931 f08fdedc 2003-11-23 devnull pfmt(err, "rc: %s: %r\n", s);
932 f08fdedc 2003-11-23 devnull else
933 f08fdedc 2003-11-23 devnull pfmt(err, "rc (%s): %s: %r\n", argv0, s);
934 f08fdedc 2003-11-23 devnull flush(err);
935 4ae2f414 2005-08-11 devnull setstatus("error");
936 f08fdedc 2003-11-23 devnull while(!runq->iflag) Xreturn();
937 f08fdedc 2003-11-23 devnull }
938 c8f53842 2007-03-26 devnull
939 c8f53842 2007-03-26 devnull void
940 c8f53842 2007-03-26 devnull Xerror1(char *s)
941 f08fdedc 2003-11-23 devnull {
942 f08fdedc 2003-11-23 devnull if(strcmp(argv0, "rc")==0 || strcmp(argv0, "/bin/rc")==0)
943 f08fdedc 2003-11-23 devnull pfmt(err, "rc: %s\n", s);
944 f08fdedc 2003-11-23 devnull else
945 f08fdedc 2003-11-23 devnull pfmt(err, "rc (%s): %s\n", argv0, s);
946 f08fdedc 2003-11-23 devnull flush(err);
947 4ae2f414 2005-08-11 devnull setstatus("error");
948 f08fdedc 2003-11-23 devnull while(!runq->iflag) Xreturn();
949 f08fdedc 2003-11-23 devnull }
950 c8f53842 2007-03-26 devnull
951 c8f53842 2007-03-26 devnull void
952 c8f53842 2007-03-26 devnull setstatus(char *s)
953 f08fdedc 2003-11-23 devnull {
954 f08fdedc 2003-11-23 devnull setvar("status", newword(s, (word *)0));
955 f08fdedc 2003-11-23 devnull }
956 c8f53842 2007-03-26 devnull
957 c8f53842 2007-03-26 devnull char*
958 c8f53842 2007-03-26 devnull getstatus(void)
959 c8f53842 2007-03-26 devnull {
960 c8f53842 2007-03-26 devnull var *status = vlook("status");
961 f08fdedc 2003-11-23 devnull return status->val?status->val->word:"";
962 f08fdedc 2003-11-23 devnull }
963 c8f53842 2007-03-26 devnull
964 c8f53842 2007-03-26 devnull int
965 c8f53842 2007-03-26 devnull truestatus(void)
966 c8f53842 2007-03-26 devnull {
967 f08fdedc 2003-11-23 devnull char *s;
968 c8f53842 2007-03-26 devnull for(s = getstatus();*s;s++)
969 c8f53842 2007-03-26 devnull if(*s!='|' && *s!='0')
970 c8f53842 2007-03-26 devnull return 0;
971 f08fdedc 2003-11-23 devnull return 1;
972 f08fdedc 2003-11-23 devnull }
973 c8f53842 2007-03-26 devnull
974 c8f53842 2007-03-26 devnull void
975 c8f53842 2007-03-26 devnull Xdelhere(void)
976 c8f53842 2007-03-26 devnull {
977 f08fdedc 2003-11-23 devnull Unlink(runq->code[runq->pc++].s);
978 f08fdedc 2003-11-23 devnull }
979 c8f53842 2007-03-26 devnull
980 c8f53842 2007-03-26 devnull void
981 c8f53842 2007-03-26 devnull Xfor(void)
982 c8f53842 2007-03-26 devnull {
983 f08fdedc 2003-11-23 devnull if(runq->argv->words==0){
984 f08fdedc 2003-11-23 devnull poplist();
985 c8f53842 2007-03-26 devnull runq->pc = runq->code[runq->pc].i;
986 f08fdedc 2003-11-23 devnull }
987 f08fdedc 2003-11-23 devnull else{
988 f08fdedc 2003-11-23 devnull freelist(runq->local->val);
989 c8f53842 2007-03-26 devnull runq->local->val = runq->argv->words;
990 c8f53842 2007-03-26 devnull runq->local->changed = 1;
991 c8f53842 2007-03-26 devnull runq->argv->words = runq->argv->words->next;
992 c8f53842 2007-03-26 devnull runq->local->val->next = 0;
993 f08fdedc 2003-11-23 devnull runq->pc++;
994 f08fdedc 2003-11-23 devnull }
995 f08fdedc 2003-11-23 devnull }
996 c8f53842 2007-03-26 devnull
997 c8f53842 2007-03-26 devnull void
998 c8f53842 2007-03-26 devnull Xglob(void)
999 c8f53842 2007-03-26 devnull {
1000 f08fdedc 2003-11-23 devnull globlist();
1001 f08fdedc 2003-11-23 devnull }