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