]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/spin/vars.c
ip/ipconfig: use ewrite() to enable routing command for sendra
[plan9front.git] / sys / src / cmd / spin / vars.c
1 /***** spin: vars.c *****/
2
3 /*
4  * This file is part of the public release of Spin. It is subject to the
5  * terms in the LICENSE file that is included in this source directory.
6  * Tool documentation is available at http://spinroot.com
7  */
8
9 #include "spin.h"
10 #include "y.tab.h"
11
12 extern Ordered  *all_names;
13 extern RunList  *X, *LastX;
14 extern Symbol   *Fname;
15 extern char     Buf[];
16 extern int      lineno, depth, verbose, xspin, limited_vis;
17 extern int      analyze, jumpsteps, nproc, nstop, columns, old_priority_rules;
18 extern short    no_arrays, Have_claim;
19 extern void     sr_mesg(FILE *, int, int);
20 extern void     sr_buf(int, int);
21
22 static int      getglobal(Lextok *);
23 static int      setglobal(Lextok *, int);
24 static int      maxcolnr = 1;
25
26 int
27 getval(Lextok *sn)
28 {       Symbol *s = sn->sym;
29
30         if (strcmp(s->name, "_") == 0)
31         {       non_fatal("attempt to read value of '_'", 0);
32                 return 0;
33         }
34         if (strcmp(s->name, "_last") == 0)
35                 return (LastX)?LastX->pid:0;
36         if (strcmp(s->name, "_p") == 0)
37                 return (X && X->pc)?X->pc->seqno:0;
38         if (strcmp(s->name, "_pid") == 0)
39         {       if (!X) return 0;
40                 return X->pid - Have_claim;
41         }
42         if (strcmp(s->name, "_priority") == 0)
43         {       if (!X) return 0;
44
45                 if (old_priority_rules)
46                 {       non_fatal("cannot refer to _priority with -o6", (char *) 0);
47                         return 1;
48                 }
49                 return X->priority;
50         }
51
52         if (strcmp(s->name, "_nr_pr") == 0)
53         {       return nproc-nstop;     /* new 3.3.10 */
54         }
55
56         if (s->context && s->type)
57         {       return getlocal(sn);
58         }
59
60         if (!s->type)   /* not declared locally */
61         {       s = lookup(s->name); /* try global */
62                 sn->sym = s;    /* fix it */
63         }
64
65         return getglobal(sn);
66 }
67
68 int
69 setval(Lextok *v, int n)
70 {
71         if (strcmp(v->sym->name, "_last") == 0
72         ||  strcmp(v->sym->name, "_p") == 0
73         ||  strcmp(v->sym->name, "_pid") == 0
74         ||  strcmp(v->sym->name, "_nr_qs") == 0
75         ||  strcmp(v->sym->name, "_nr_pr") == 0)
76         {       non_fatal("illegal assignment to %s", v->sym->name);
77         }
78         if (strcmp(v->sym->name, "_priority") == 0)
79         {       if (old_priority_rules)
80                 {       non_fatal("cannot refer to _priority with -o6", (char *) 0);
81                         return 1;
82                 }
83                 if (!X)
84                 {       non_fatal("no context for _priority", (char *) 0);
85                         return 1;
86                 }
87                 X->priority = n;
88         }
89
90         if (v->sym->context && v->sym->type)
91                 return setlocal(v, n);
92         if (!v->sym->type)
93                 v->sym = lookup(v->sym->name);
94         return setglobal(v, n);
95 }
96
97 void
98 rm_selfrefs(Symbol *s, Lextok *i)
99 {
100         if (!i) return;
101
102         if (i->ntyp == NAME
103         &&  strcmp(i->sym->name, s->name) == 0
104         && (    (!i->sym->context && !s->context)
105            ||   ( i->sym->context &&  s->context
106                 && strcmp(i->sym->context->name, s->context->name) == 0)))
107         {       lineno  = i->ln;
108                 Fname   = i->fn;
109                 non_fatal("self-reference initializing '%s'", s->name);
110                 i->ntyp = CONST;
111                 i->val  = 0;
112         } else
113         {       rm_selfrefs(s, i->lft);
114                 rm_selfrefs(s, i->rgt);
115         }
116 }
117
118 int
119 checkvar(Symbol *s, int n)
120 {       int     i, oln = lineno;        /* calls on eval() change it */
121         Symbol  *ofnm = Fname;
122         Lextok  *z, *y;
123
124         if (!in_bound(s, n))
125                 return 0;
126
127         if (s->type == 0)
128         {       non_fatal("undecl var %s (assuming int)", s->name);
129                 s->type = INT;
130         }
131         /* not a STRUCT */
132         if (s->val == (int *) 0)        /* uninitialized */
133         {       s->val = (int *) emalloc(s->nel*sizeof(int));
134                 z = s->ini;
135                 for (i = 0; i < s->nel; i++)
136                 {       if (z && z->ntyp == ',')
137                         {       y = z->lft;
138                                 z = z->rgt;
139                         } else
140                         {       y = z;
141                         }
142                         if (s->type != CHAN)
143                         {       rm_selfrefs(s, y);
144                                 s->val[i] = eval(y);
145                         } else if (!analyze)
146                         {       s->val[i] = qmake(s);
147         }       }       }
148         lineno = oln;
149         Fname  = ofnm;
150
151         return 1;
152 }
153
154 static int
155 getglobal(Lextok *sn)
156 {       Symbol *s = sn->sym;
157         int i, n = eval(sn->lft);
158
159         if (s->type == 0 && X && (i = find_lab(s, X->n, 0)))    /* getglobal */
160         {       printf("findlab through getglobal on %s\n", s->name);
161                 return i;       /* can this happen? */
162         }
163         if (s->type == STRUCT)
164         {       return Rval_struct(sn, s, 1); /* 1 = check init */
165         }
166         if (checkvar(s, n))
167         {       return cast_val(s->type, s->val[n], s->nbits);
168         }
169         return 0;
170 }
171
172 int
173 cast_val(int t, int v, int w)
174 {       int i=0; short s=0; unsigned int u=0;
175
176         if (t == PREDEF || t == INT || t == CHAN) i = v;        /* predef means _ */
177         else if (t == SHORT) s = (short) v;
178         else if (t == BYTE || t == MTYPE)  u = (unsigned char)v;
179         else if (t == BIT)   u = (unsigned char)(v&1);
180         else if (t == UNSIGNED)
181         {       if (w == 0)
182                         fatal("cannot happen, cast_val", (char *)0);
183         /*      u = (unsigned)(v& ((1<<w)-1));          problem when w=32       */
184                 u = (unsigned)(v& (~0u>>(8*sizeof(unsigned)-w)));       /* doug */
185         }
186
187         if (v != i+s+ (int) u)
188         {       char buf[64]; sprintf(buf, "%d->%d (%d)", v, i+s+(int)u, t);
189                 non_fatal("value (%s) truncated in assignment", buf);
190         }
191         return (int)(i+s+(int)u);
192 }
193
194 static int
195 setglobal(Lextok *v, int m)
196 {
197         if (v->sym->type == STRUCT)
198         {       (void) Lval_struct(v, v->sym, 1, m);
199         } else
200         {       int n = eval(v->lft);
201                 if (checkvar(v->sym, n))
202                 {       int oval = v->sym->val[n];
203                         int nval = cast_val(v->sym->type, m, v->sym->nbits);
204                         v->sym->val[n] = nval;
205                         if (oval != nval)
206                         {       v->sym->setat = depth;
207         }       }       }
208         return 1;
209 }
210
211 void
212 dumpclaims(FILE *fd, int pid, char *s)
213 {       extern Lextok *Xu_List; extern int Pid;
214         extern short terse;
215         Lextok *m; int cnt = 0; int oPid = Pid;
216
217         for (m = Xu_List; m; m = m->rgt)
218                 if (strcmp(m->sym->name, s) == 0)
219                 {       cnt=1;
220                         break;
221                 }
222         if (cnt == 0) return;
223
224         Pid = pid;
225         fprintf(fd, "#ifndef XUSAFE\n");
226         for (m = Xu_List; m; m = m->rgt)
227         {       if (strcmp(m->sym->name, s) != 0)
228                         continue;
229                 no_arrays = 1;
230                 putname(fd, "\t\tsetq_claim(", m->lft, 0, "");
231                 no_arrays = 0;
232                 fprintf(fd, ", %d, ", m->val);
233                 terse = 1;
234                 putname(fd, "\"", m->lft, 0, "\", h, ");
235                 terse = 0;
236                 fprintf(fd, "\"%s\");\n", s);
237         }
238         fprintf(fd, "#endif\n");
239         Pid = oPid;
240 }
241
242 void
243 dumpglobals(void)
244 {       Ordered *walk;
245         static Lextok *dummy = ZN;
246         Symbol *sp;
247         int j;
248
249         if (!dummy)
250                 dummy = nn(ZN, NAME, nn(ZN,CONST,ZN,ZN), ZN);
251
252         for (walk = all_names; walk; walk = walk->next)
253         {       sp = walk->entry;
254                 if (!sp->type || sp->context || sp->owner
255                 ||  sp->type == PROCTYPE  || sp->type == PREDEF
256                 ||  sp->type == CODE_FRAG || sp->type == CODE_DECL
257                 ||  (sp->type == MTYPE && ismtype(sp->name)))
258                         continue;
259
260                 if (sp->type == STRUCT)
261                 {       if ((verbose&4) && !(verbose&64)
262                         &&  (sp->setat < depth
263                         &&   jumpsteps != depth))
264                         {       continue;
265                         }
266                         dump_struct(sp, sp->name, 0);
267                         continue;
268                 }
269                 for (j = 0; j < sp->nel; j++)
270                 {       int prefetch;
271                         if (sp->type == CHAN)
272                         {       doq(sp, j, 0);
273                                 continue;
274                         }
275                         if ((verbose&4) && !(verbose&64)
276                         &&  (sp->setat < depth
277                         &&   jumpsteps != depth))
278                         {       continue;
279                         }
280
281                         dummy->sym = sp;
282                         dummy->lft->val = j;
283                         /* in case of cast_val warnings, do this first: */
284                         prefetch = getglobal(dummy);
285                         printf("\t\t%s", sp->name);
286                         if (sp->nel > 1 || sp->isarray) printf("[%d]", j);
287                         printf(" = ");
288                         sr_mesg(stdout, prefetch,
289                                 sp->type == MTYPE);
290                         printf("\n");
291                         if (limited_vis && (sp->hidden&2))
292                         {       int colpos;
293                                 Buf[0] = '\0';
294                                 if (!xspin)
295                                 {       if (columns == 2)
296                                         sprintf(Buf, "~G%s = ", sp->name);
297                                         else
298                                         sprintf(Buf, "%s = ", sp->name);
299                                 }
300                                 sr_buf(prefetch, sp->type == MTYPE);
301                                 if (sp->colnr == 0)
302                                 {       sp->colnr = (unsigned char) maxcolnr;
303                                         maxcolnr = 1+(maxcolnr%10);
304                                 }
305                                 colpos = nproc+sp->colnr-1;
306                                 if (columns == 2)
307                                 {       pstext(colpos, Buf);
308                                         continue;
309                                 }
310                                 if (!xspin)
311                                 {       printf("\t\t%s\n", Buf);
312                                         continue;
313                                 }
314                                 printf("MSC: ~G %s %s\n", sp->name, Buf);
315                                 printf("%3d:\tproc %3d (TRACK) line   1 \"var\" ",
316                                         depth, colpos);
317                                 printf("(state 0)\t[printf('MSC: globvar\\\\n')]\n");
318                                 printf("\t\t%s", sp->name);
319                                 if (sp->nel > 1 || sp->isarray) printf("[%d]", j);
320                                 printf(" = %s\n", Buf);
321         }       }       }
322 }
323
324 void
325 dumplocal(RunList *r)
326 {       static Lextok *dummy = ZN;
327         Symbol *z, *s;
328         int i;
329
330         if (!r) return;
331
332         s = r->symtab;
333
334         if (!dummy)
335                 dummy = nn(ZN, NAME, nn(ZN,CONST,ZN,ZN), ZN);
336
337         for (z = s; z; z = z->next)
338         {       if (z->type == STRUCT)
339                 {       dump_struct(z, z->name, r);
340                         continue;
341                 }
342                 for (i = 0; i < z->nel; i++)
343                 {       if (z->type == CHAN)
344                         {       doq(z, i, r);
345                                 continue;
346                         }
347                         if ((verbose&4) && !(verbose&64)
348                         &&  (z->setat < depth
349                         &&   jumpsteps != depth))
350                                 continue;
351
352                         dummy->sym = z;
353                         dummy->lft->val = i;
354
355                         printf("\t\t%s(%d):%s",
356                                 r->n->name, r->pid - Have_claim, z->name);
357                         if (z->nel > 1 || z->isarray) printf("[%d]", i);
358                         printf(" = ");
359                         sr_mesg(stdout, getval(dummy), z->type == MTYPE);
360                         printf("\n");
361                         if (limited_vis && (z->hidden&2))
362                         {       int colpos;
363                                 Buf[0] = '\0';
364                                 if (!xspin)
365                                 {       if (columns == 2)
366                                         sprintf(Buf, "~G%s(%d):%s = ",
367                                         r->n->name, r->pid, z->name);
368                                         else
369                                         sprintf(Buf, "%s(%d):%s = ",
370                                         r->n->name, r->pid, z->name);
371                                 }
372                                 sr_buf(getval(dummy), z->type==MTYPE);
373                                 if (z->colnr == 0)
374                                 {       z->colnr = (unsigned char) maxcolnr;
375                                         maxcolnr = 1+(maxcolnr%10);
376                                 }
377                                 colpos = nproc+z->colnr-1;
378                                 if (columns == 2)
379                                 {       pstext(colpos, Buf);
380                                         continue;
381                                 }
382                                 if (!xspin)
383                                 {       printf("\t\t%s\n", Buf);
384                                         continue;
385                                 }
386                                 printf("MSC: ~G %s(%d):%s %s\n",
387                                         r->n->name, r->pid, z->name, Buf);
388
389                                 printf("%3d:\tproc %3d (TRACK) line   1 \"var\" ",
390                                         depth, colpos);
391                                 printf("(state 0)\t[printf('MSC: locvar\\\\n')]\n");
392                                 printf("\t\t%s(%d):%s",
393                                         r->n->name, r->pid, z->name);
394                                 if (z->nel > 1 || z->isarray) printf("[%d]", i);
395                                 printf(" = %s\n", Buf);
396         }       }       }
397 }