1 /***********************************************************************/
2 /* Open Visualization Data Explorer */
3 /* (C) Copyright IBM Corp. 1989,1999 */
4 /* ALL RIGHTS RESERVED */
5 /* This code licensed under the */
6 /* "IBM PUBLIC LICENSE - Open Visualization Data Explorer" */
7 /***********************************************************************/
8
9 #include <dxconfig.h>
10
11
12 #include <dx/dx.h>
13 #include "config.h"
14 #include "pmodflags.h"
15 #include "d.h"
16 #include "_macro.h"
17 #include "_variable.h"
18 #include "attribute.h"
19 #include "graph.h"
20 #include "parse.h"
21 #include "path.h"
22 #include "utils.h"
23 #include "log.h"
24 #include "graphIntr.h"
25
26 #define MACRO_DEPTH 512
27 #define MACRO_QUIT MACRO_DEPTH
28
29 /*
30 * These can be statics since graph construction takes place on a single
31 * processor.
32 *
33 * $$$$$ If we need to save some space we can dynamically allocate
34 * $$$$$ cells to hold the names etc. but at a performance penalty.
35 */
36
37 static char *_macro_stack[MACRO_DEPTH];
38 static int _macro_depth = 0;
39
40 static int _nocache_depth = 0;
41 static int _nocache_stack[MACRO_DEPTH];
42
43 int
_dxf_ExNoCachePush(int n)44 _dxf_ExNoCachePush (int n)
45 {
46 int nc = FALSE;
47
48 if (_nocache_depth > 0)
49 {
50 if (_nocache_depth < MACRO_DEPTH)
51 nc = _nocache_stack[_nocache_depth - 1];
52 else
53 nc = _nocache_stack[MACRO_DEPTH - 1];
54 }
55
56 nc = nc || n;
57
58 if (_nocache_depth < MACRO_DEPTH)
59 _nocache_stack[_nocache_depth++] = nc;
60 else
61 _nocache_depth++;
62
63 return (nc);
64 }
65
66
67 void
_dxf_ExNoCachePop()68 _dxf_ExNoCachePop ()
69 {
70 if (--_nocache_depth < 0)
71 _nocache_depth = 0;
72 }
73
74 /*
75 * Determines whether a recursive macro call has been made. If so
76 * generates an error message, if not pushes the macro name onto the
77 * stack.
78 */
79
80 #define ADVANCE(_bp) while (*(_bp)) (_bp)++
81 #define ADDARROW(_bp) {strcpy (_bp, " -> "); ADVANCE (_bp);}
82
_dxf_ExMacroRecursionCheck(char * name,_ntype type)83 int _dxf_ExMacroRecursionCheck (char *name, _ntype type)
84 {
85 int i;
86 int j;
87 char *warning = "Macro recursion: ";
88 char *message;
89 char *mptr;
90 int len;
91 int d;
92
93 if (type != NT_MACRO)
94 return (FALSE);
95
96 d = _macro_depth < MACRO_DEPTH ? _macro_depth : MACRO_DEPTH;
97
98 for (i = 0; i < d; i++)
99 {
100 if (name == _macro_stack[i] && ! strcmp (name, _macro_stack[i]))
101 {
102 /* Figure out how much space we need for the message */
103 for (j = 0, len = 0; j < d; j++)
104 len += strlen (_macro_stack[j]);
105
106 len += strlen (warning); /* for inital message */
107 len += 4 * _macro_depth; /* for ' -> ' */
108 len += strlen (name); /* for bad guy */
109 len++; /* for '\000' */
110
111 if ((mptr = message = DXAllocate (len)) == NULL)
112 DXUIMessage ("ERROR", "%s%s", warning, name);
113 else
114 {
115 strcpy (mptr, warning);
116 ADVANCE (mptr);
117
118 for (j = 0; j < d; j++)
119 {
120 strcpy (mptr, _macro_stack[j]);
121 ADVANCE (mptr);
122 ADDARROW (mptr);
123 }
124
125 strcpy (mptr, name);
126 ADVANCE (mptr);
127 *mptr = '\000';
128
129 DXUIMessage ("ERROR", message);
130 DXFree ((Pointer) message);
131 }
132
133 return (TRUE);
134 }
135 }
136
137 if (_macro_depth >= MACRO_QUIT)
138 {
139 DXUIMessage ("ERROR", "Macro depth = %d, assuming macro recursion", _macro_depth);
140 return (TRUE);
141 }
142
143 if (_macro_depth < MACRO_DEPTH)
144 _macro_stack[_macro_depth++] = name;
145 else
146 _macro_depth++;
147
148 return (FALSE);
149 }
150
151 /*
152 * Clears the macro recursion checking structure. Shouldn't be
153 * necessary but just in case something left us in a funky state.
154 */
155
_dxf_ExMacroRecursionInit()156 void _dxf_ExMacroRecursionInit ()
157 {
158 _macro_depth = 0;
159 _nocache_depth = 0;
160 }
161
162 /*
163 * Pops one level of macro call from the recursion check.
164 */
165
_dxf_ExMacroRecursionPop(char * name,_ntype type)166 void _dxf_ExMacroRecursionPop (char *name, _ntype type)
167 {
168 if (type != NT_MACRO)
169 return;
170
171 if (--_macro_depth < 0)
172 _macro_depth = 0;
173 }
174
175
176
177
_dxf_ExPrintNode(node * n)178 void _dxf_ExPrintNode(node*n)
179 {
180 node *sn;
181
182 if (n == NULL)
183 {
184 DXMessage("NULL");
185 return;
186 }
187 switch(n->type) {
188 case NT_MACRO:
189 DXMessage("macro");
190 _dxf_ExPrintNode(n->v.macro.id);
191 DXMessage("\t(");
192 for (sn = n->v.macro.in; sn; sn = sn->next)
193 _dxf_ExPrintNode(sn);
194 DXMessage("\t) -> (");
195 for (sn = n->v.macro.out; sn; sn = sn->next)
196 _dxf_ExPrintNode(sn);
197 DXMessage("\t)");
198 DXMessage("{");
199 for (sn = n->v.macro.def.stmt; sn; sn = sn->next)
200 {
201 _dxf_ExPrintNode(sn);
202 DXMessage(";");
203 }
204 DXMessage("}");
205 break;
206
207 case NT_MODULE:
208 for (sn = n->v.module.out; sn; sn = sn->next)
209 _dxf_ExPrintNode(sn);
210 DXMessage("=");
211 _dxf_ExPrintNode(n->v.module.id);
212 DXMessage("(");
213 for (sn = n->v.module.in; sn; sn = sn->next)
214 _dxf_ExPrintNode(sn);
215 DXMessage(")");
216 break;
217
218 case NT_ASSIGNMENT:
219 for (sn = n->v.assign.lval; sn; sn = sn->next)
220 _dxf_ExPrintNode(sn);
221 DXMessage("=");
222 for (sn = n->v.assign.rval; sn; sn = sn->next)
223 _dxf_ExPrintNode(sn);
224 break;
225
226 case NT_PRINT:
227 DXMessage("NT_PRINT");
228 break;
229
230 case NT_ATTRIBUTE:
231 DXMessage("NT_ATTRIBUTE");
232 break;
233
234 case NT_CALL:
235 _dxf_ExPrintNode(n->v.call.id);
236 DXMessage("(");
237 for (sn = n->v.call.arg; sn; sn = sn->next)
238 _dxf_ExPrintNode(sn);
239 DXMessage(")");
240 break;
241
242 case NT_ARGUMENT:
243 _dxf_ExPrintNode(n->v.arg.val);
244 break;
245
246 case NT_LOGICAL:
247 DXMessage("NT_LOGICAL");
248 break;
249
250 case NT_ARITHMETIC:
251 DXMessage("NT_ARITHMETIC");
252 break;
253
254 case NT_CONSTANT:
255 DXMessage("NT_CONSTANT");
256 break;
257
258 case NT_ID:
259 if (n->v.id.dflt != NULL)
260 {
261 DXMessage("%s = ", n->v.id.id);
262 _dxf_ExPrintNode(n->v.id.dflt);
263 }
264 else
265 {
266 DXMessage("%s", n->v.id.id);
267 }
268 break;
269
270 case NT_EXID:
271 DXMessage("NT_EXID");
272 break;
273
274 case NT_BACKGROUND:
275 DXMessage("NT_BACKGROUND");
276 break;
277
278 case NT_PACKET:
279 DXMessage("NT_PACKET");
280 break;
281
282 case NT_DATA:
283 DXMessage("NT_DATA");
284 break;
285
286 default:
287 DXMessage("Unknown type %d", n->type);
288 break;
289 }
290 }
291