1 /*
2 * $Source: /home/nlfm/Working/CVS/frink/blocks.c,v $
3 * $Date: 2001/07/10 15:46:28 $
4 * $Revision: 2.2 $
5 *
6 *------------------------------------------------------------------------
7 * AUTHOR: Lindsay Marshall <lindsay.marshall@newcastle.ac.uk>
8 *------------------------------------------------------------------------
9 * Copyright 1994-2002 The University of Newcastle upon Tyne (see COPYRIGHT)
10 *========================================================================
11 *
12 */
13 #ifdef HAVE_CONFIG_H
14 #include <config.h>
15 #endif
16
17 #include <ctype.h>
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <string.h>
21
22 #include <frink.h>
23 #include <blocks.h>
24 #include <vars.h>
25
26 #ifdef HAVE_STDLIB_H
27 #include <stdlib.h>
28 #endif
29
30 #ifdef HAVE_MALLOC_H
31 #include <malloc.h>
32 #endif
33
34 extern List *blocks;
35
pushBlock(Token * cmd,int infl,int lvl,int cond)36 Blox *pushBlock(Token *cmd, int infl, int lvl, int cond)
37 {
38 Blox *blp = (Blox *) malloc(sizeof(Blox));
39
40 blp->name = cmd;
41 if (lvl < 0)
42 {
43 blp->level = ((Blox *) lpeek(blocks))->level + 1;
44 }
45 else
46 {
47 blp->level = lvl;
48 }
49 blp->unreachable = 0;
50 blp->result = 0;
51 blp->infloop = infl;
52 blp->returns = 0;
53 blp->breaks = 0;
54 blp->conditional = cond;
55 blp->continues = 0;
56 blp->vars = (List *) 0;
57 lpush(&blocks, blp);
58 return blp;
59 }
60
delBlock(Blox * blp)61 void delBlock(Blox *blp)
62 {
63 VarData *vp;
64
65 if (blp != (Blox *) 0)
66 {
67 while(blp->vars != noList)
68 {
69 vp = lpop(&blp->vars);
70 free(vp->name);
71 }
72 }
73 free(blp);
74 }
75
popBlock(int pcall)76 void popBlock(int pcall)
77 {
78 Blox *blp = (Blox *) lpop(&blocks);
79 List *lp, *arg = noList;
80 int def;
81 VarData *vp, *fvp;
82
83 if (pcall)
84 {
85 lp = blp->vars;
86 while (lp != noList)
87 {
88 vp = (VarData *) lpeek(lp);
89 if (vp->type == VARG)
90 {
91 lpush(&arg, vp);
92 }
93 lp = lp->next;
94 }
95 if (makespec) { fprintf(specfile, "%s {", blp->name->text); }
96 def = 0;
97 while (arg != noList)
98 {
99 vp = lpop(&arg);
100 if (strcmp("args", vp->name) == 0)
101 {
102 if (makespec) { fprintf(specfile, " args"); }
103 if (arg != (List *) 0)
104 {
105 warn(blp->name, "args not the final argument");
106 }
107 vp->used |= !fascist;
108 }
109 else
110 {
111 if (makespec) { fprintf(specfile, " any"); }
112 if (vp->dval)
113 {
114 def = 1;
115 if (makespec) { fprintf(specfile, "?"); }
116 }
117 else if (def)
118 {
119 warn(blp->name, "argument with no default follows argument with default");
120 }
121 }
122 }
123 if (makespec) { fprintf(specfile, "}\n"); }
124 lp = blp->vars;
125 while (lp != noList)
126 {
127 vp = (VarData *) lpeek(lp);
128 if (doTest(HUNUSED) && !vp->used)
129 {
130 if (fascist || strncmp(vp->name, "unused", 6) != 0)
131 {
132 warnFor(blp->name, vp->name, "variable \"%s\" may be unused");
133 }
134 }
135 lp = lp->next;
136 }
137 }
138 else if (blp->name == noToken && blp->level > 0)
139 { /* almagamate var lists */
140 while (blp->vars != noList)
141 {
142 vp = lpop(&blp->vars);
143 switch (vp->type)
144 {
145 case VARG:
146 case VGLOBAL:
147 break;
148
149 case VFOR:
150 if ((fvp = varKnown(vp->name)) != (VarData *) 0)
151 { /* we know about it already */
152 continue;
153 }
154 vp->type = VLOCAL;
155 break;
156
157 default: /* depends on loop type : bug!! */
158 if (blp->conditional) { vp->set = 0; }
159 break;
160 }
161 lpush(&(((Blox *) lpeek(blocks))->vars), vp);
162 }
163 }
164 delBlock(blp);
165 }
166
isUnreachable()167 int isUnreachable()
168 {
169 return ((Blox *) lpeek(blocks))->unreachable;
170 }
171
setUnreachable(int f)172 void setUnreachable(int f)
173 {
174 ((Blox *) lpeek(blocks))->unreachable = f;
175 }
176