1 |
/* |
2 |
* base/generic/compiler/qlfdid.c created from tcltk/generic/interface/Qlfdid.c |
3 |
* Created: 1/94 |
4 |
* Version: $Revision: 1.22 $ |
5 |
* Version control file: $RCSfile: Qlfdid.c,v $ |
6 |
* Date last modified: $Date: 2003/08/23 18:43:07 $ |
7 |
* Last modified by: $Author: ballan $ |
8 |
* |
9 |
* This file is part of ASCEND. |
10 |
* |
11 |
* Copyright 1997, Carnegie Mellon University |
12 |
* |
13 |
* ASCEND is free software; you can redistribute |
14 |
* it and/or modify it under the terms of the GNU General Public License as |
15 |
* published by the Free Software Foundation; either version 2 of the |
16 |
* License, or (at your option) any later version. |
17 |
* |
18 |
* ASCEND is distributed in hope that it will be |
19 |
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty of |
20 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
21 |
* General Public License for more details. |
22 |
* |
23 |
* You should have received a copy of the GNU General Public License |
24 |
* along with the program; if not, write to the Free Software Foundation, |
25 |
* Inc., 675 Mass Ave, Cambridge, MA 02139 USA. Check the file named |
26 |
* COPYING. COPYING is found in ../compiler. |
27 |
*/ |
28 |
|
29 |
#include "qlfdid.h" |
30 |
|
31 |
#include <utilities/ascConfig.h> |
32 |
#include <utilities/ascPanic.h> |
33 |
#include <utilities/ascMalloc.h> |
34 |
#include <general/list.h> |
35 |
#include <general/dstring.h> |
36 |
#include "compiler.h" |
37 |
#include "instance_enum.h" |
38 |
#include "symtab.h" |
39 |
#include "simlist.h" |
40 |
#include "instance_io.h" |
41 |
#include "instance_name.h" |
42 |
#include "instquery.h" |
43 |
#include "parentchild.h" |
44 |
#include "fractions.h" |
45 |
#include "dimen.h" |
46 |
#include "types.h" |
47 |
#include "stattypes.h" |
48 |
#include "instantiate.h" |
49 |
#include <solver/slv_types.h> |
50 |
|
51 |
#ifndef lint |
52 |
static CONST char QlfdidID[] = "$Id: Qlfdid.c,v 1.22 2003/08/23 18:43:07 ballan Exp $"; |
53 |
#endif |
54 |
|
55 |
|
56 |
#ifndef MAXIMUM_STRING_LENGTH |
57 |
#define MAXIMUM_STRING_LENGTH 1024 |
58 |
#endif |
59 |
#define QLFDIDMALLOC \ |
60 |
(struct SearchEntry *)ascmalloc(sizeof(struct SearchEntry)); |
61 |
|
62 |
|
63 |
/* used for searching */ |
64 |
struct Instance *g_search_inst = NULL; |
65 |
struct Instance *g_relative_inst = NULL; |
66 |
|
67 |
|
68 |
|
69 |
char *Asc_MakeInitString(int len) |
70 |
{ |
71 |
char *result; |
72 |
int defaultlen = 40; |
73 |
if (len<=0) { |
74 |
FPRINTF(stderr, |
75 |
"Setting length to %d due to invalid length given\n",defaultlen); |
76 |
len = defaultlen; |
77 |
} |
78 |
result = (char *)ascmalloc((len + 1)*sizeof(char)); |
79 |
assert(result!=NULL); |
80 |
sprintf(result,"%s","\0"); |
81 |
return result; |
82 |
} |
83 |
|
84 |
void Asc_ReInitString(char *str) |
85 |
{ |
86 |
if ((str)&&(strlen(str))) { |
87 |
strcpy(str,""); |
88 |
} |
89 |
} |
90 |
|
91 |
/* |
92 |
* Create a search entry node with a simple name |
93 |
* such as : a. |
94 |
*/ |
95 |
struct SearchEntry *Asc_SearchEntryCreate(char *name,struct Instance *i) |
96 |
{ |
97 |
struct SearchEntry *result; |
98 |
result = QLFDIDMALLOC; |
99 |
assert(result!=NULL); |
100 |
result->name = (char *)ascmalloc((strlen(name)+1)*sizeof(char)); |
101 |
strcpy(result->name,name); |
102 |
result->i = i; |
103 |
return result; |
104 |
} |
105 |
|
106 |
/* |
107 |
* Create a search entry node with a name that |
108 |
* is formatted like a integer array. such as: |
109 |
* [14]. |
110 |
*/ |
111 |
static |
112 |
struct SearchEntry *SearchEntryCreateIntArray(char *name,struct Instance *i) |
113 |
{ |
114 |
struct SearchEntry *result; |
115 |
result = QLFDIDMALLOC; |
116 |
assert(result!=NULL); |
117 |
result->name = (char *)ascmalloc((strlen(name)+8)*sizeof(char)); |
118 |
sprintf(result->name,"[%s]",name); |
119 |
result->i = i; |
120 |
return result; |
121 |
} |
122 |
|
123 |
/* |
124 |
* Create a search entry node with a name that |
125 |
* is formatted like a string array. such as: |
126 |
* ['benzene.flow']. |
127 |
*/ |
128 |
static |
129 |
struct SearchEntry *SearchEntryCreateStrArray(char *name,struct Instance *i) |
130 |
{ |
131 |
struct SearchEntry *result; |
132 |
result = QLFDIDMALLOC; |
133 |
assert(result!=NULL); |
134 |
result->name = (char *)ascmalloc((strlen(name)+8)*sizeof(char)); |
135 |
sprintf(result->name,"[\'%s\']",name); |
136 |
result->i = i; |
137 |
return result; |
138 |
} |
139 |
|
140 |
struct Instance *Asc_SearchEntryInstance(struct SearchEntry *se) |
141 |
{ |
142 |
assert(se!=NULL); |
143 |
return (se->i); |
144 |
} |
145 |
|
146 |
char *Asc_SearchEntryName(struct SearchEntry *se) |
147 |
{ |
148 |
assert(se!=NULL); |
149 |
return (se->name); |
150 |
} |
151 |
|
152 |
void Asc_SearchEntryDestroy(struct SearchEntry *se) |
153 |
{ |
154 |
if (!se) { |
155 |
return; |
156 |
} |
157 |
ascfree(se->name); |
158 |
se->name = NULL; |
159 |
se->i = NULL; |
160 |
ascfree(se); |
161 |
} |
162 |
|
163 |
void Asc_SearchListDestroy(struct gl_list_t *search_list) |
164 |
{ |
165 |
struct SearchEntry *se; |
166 |
unsigned long len,c; |
167 |
if (!search_list) { |
168 |
return; |
169 |
} |
170 |
len = gl_length(search_list); |
171 |
for(c=1;c<=len;c++) { |
172 |
se = (struct SearchEntry *)gl_fetch(search_list,c); |
173 |
Asc_SearchEntryDestroy(se); |
174 |
} |
175 |
gl_destroy(search_list); |
176 |
} |
177 |
|
178 |
static |
179 |
int CheckChildExist(struct InstanceName name) |
180 |
{ |
181 |
unsigned long ndx,nch; |
182 |
symchar *tablename; /* hacky, but centralized slop avoidance */ |
183 |
/* remember that a struct passed by value can be overwritten safely. */ |
184 |
nch = NumberChildren(g_search_inst); |
185 |
if (!nch) { |
186 |
g_search_inst = NULL; |
187 |
return 0; |
188 |
} |
189 |
switch (InstanceNameType(name)) { |
190 |
case IntArrayIndex: |
191 |
break; |
192 |
case StrName: |
193 |
tablename = InstanceNameStr(name); |
194 |
SetInstanceNameStrPtr(name,tablename); |
195 |
break; |
196 |
case StrArrayIndex: |
197 |
tablename = InstanceStrIndex(name); |
198 |
SetInstanceNameStrIndex(name,tablename); |
199 |
break; |
200 |
default: |
201 |
Asc_Panic(2,"%s: CheckChildExist called with bad arguments.",__FILE__); |
202 |
break; |
203 |
} |
204 |
ndx = ChildSearch(g_search_inst,&name); /* symchar safe */ |
205 |
if (ndx) { |
206 |
g_search_inst = InstanceChild(g_search_inst,ndx); |
207 |
return ndx; |
208 |
} else { |
209 |
g_search_inst = NULL; |
210 |
return 0; |
211 |
} |
212 |
} |
213 |
|
214 |
static void HandleLastPart(char *temp) |
215 |
{ |
216 |
struct InstanceName name; |
217 |
if (g_search_inst) { |
218 |
SetInstanceNameType(name,StrName); |
219 |
SetInstanceNameStrPtr(name,AddSymbol(temp)); |
220 |
CheckChildExist(name); /* sets g_search_inst regardless */ |
221 |
return; |
222 |
} else { |
223 |
g_search_inst = Asc_FindSimulationRoot(AddSymbol(temp)); |
224 |
} |
225 |
} |
226 |
|
227 |
struct gl_list_t *Asc_BrowQlfdidSearch(char *str, char *temp) |
228 |
{ |
229 |
register char *ptr, *org; |
230 |
struct InstanceName name; |
231 |
struct gl_list_t *search_list = NULL; |
232 |
struct SearchEntry *se; |
233 |
int ndx = 0; |
234 |
int open_bracket = 0; |
235 |
int open_quote = 0; |
236 |
|
237 |
g_search_inst = NULL; /* always start searches from the top */ |
238 |
if (!str) { |
239 |
return NULL; |
240 |
} |
241 |
search_list = gl_create(8L); |
242 |
ptr = temp; |
243 |
org = str; |
244 |
while(*str != '\0') { |
245 |
switch(*str) { |
246 |
case '.': |
247 |
if (*(str-1) != ']') { |
248 |
if (open_quote) { /* to deal b['funny.name'] */ |
249 |
*(ptr++) = *(str++); /* ---^--- */ |
250 |
break; |
251 |
} |
252 |
*ptr = '\0'; |
253 |
if (g_search_inst) { |
254 |
SetInstanceNameType(name,StrName); |
255 |
SetInstanceNameStrPtr(name,AddSymbol(temp)); |
256 |
if(0 == (ndx=CheckChildExist(name))) { |
257 |
Asc_SearchListDestroy(search_list); |
258 |
return NULL; |
259 |
} |
260 |
} else { |
261 |
g_search_inst = Asc_FindSimulationRoot(AddSymbol(temp)); |
262 |
if (!g_search_inst) { |
263 |
Asc_SearchListDestroy(search_list); |
264 |
return NULL; |
265 |
} |
266 |
} |
267 |
se = Asc_SearchEntryCreate(temp,g_search_inst); |
268 |
gl_append_ptr(search_list,se); |
269 |
} |
270 |
str++; |
271 |
ptr = temp; |
272 |
break; |
273 |
case '\'': |
274 |
str++; |
275 |
if (open_quote) { |
276 |
open_quote--; |
277 |
} else { |
278 |
open_quote++; |
279 |
} |
280 |
break; |
281 |
case '[': |
282 |
if (*(str-1) != ']') { |
283 |
*ptr = '\0'; |
284 |
if (g_search_inst) { |
285 |
SetInstanceNameType(name,StrName); |
286 |
SetInstanceNameStrPtr(name,AddSymbol(temp)); |
287 |
if(0 == (ndx=CheckChildExist(name))) { |
288 |
Asc_SearchListDestroy(search_list); |
289 |
return NULL; |
290 |
} |
291 |
} else { |
292 |
g_search_inst = Asc_FindSimulationRoot(AddSymbol(temp)); |
293 |
if (!g_search_inst) { |
294 |
Asc_SearchListDestroy(search_list); |
295 |
return NULL; |
296 |
} |
297 |
} |
298 |
se = Asc_SearchEntryCreate(temp,g_search_inst); |
299 |
gl_append_ptr(search_list,se); |
300 |
} |
301 |
ptr = temp; |
302 |
open_bracket++; |
303 |
str++; |
304 |
break; |
305 |
case ']': |
306 |
open_bracket--; |
307 |
*ptr = '\0'; |
308 |
str++; |
309 |
switch(InstanceKind(g_search_inst)) { |
310 |
case ARRAY_INT_INST: |
311 |
SetInstanceNameType(name,IntArrayIndex); |
312 |
SetInstanceNameIntIndex(name,atol(temp)); |
313 |
if(0 == (ndx=CheckChildExist(name))) { |
314 |
Asc_SearchListDestroy(search_list); |
315 |
return NULL; |
316 |
} |
317 |
ptr = temp; |
318 |
se = SearchEntryCreateIntArray(temp,g_search_inst); |
319 |
gl_append_ptr(search_list,se); |
320 |
break; |
321 |
case ARRAY_ENUM_INST: |
322 |
SetInstanceNameType(name,StrArrayIndex); |
323 |
SetInstanceNameStrIndex(name,AddSymbol(temp)); |
324 |
if(0 == (ndx=CheckChildExist(name))) { /* sets g_search_inst */ |
325 |
Asc_SearchListDestroy(search_list); |
326 |
return NULL; |
327 |
} |
328 |
ptr = temp; |
329 |
se = SearchEntryCreateStrArray(temp,g_search_inst); |
330 |
gl_append_ptr(search_list,se); |
331 |
break; |
332 |
default: |
333 |
FPRINTF(stderr,"Mismatch in qlfdid (%s) and simulation.\n",org); |
334 |
break; |
335 |
} |
336 |
break; |
337 |
default: |
338 |
*(ptr++) = *(str++); |
339 |
break; |
340 |
} |
341 |
} |
342 |
*ptr = '\0'; |
343 |
if (*temp == '\0') { |
344 |
return search_list; |
345 |
} |
346 |
HandleLastPart(temp); |
347 |
if (g_search_inst) { |
348 |
se = Asc_SearchEntryCreate(temp,g_search_inst); |
349 |
gl_append_ptr(search_list,se); |
350 |
return search_list; |
351 |
} else { |
352 |
Asc_SearchListDestroy(search_list); |
353 |
return NULL; |
354 |
} |
355 |
} |
356 |
|
357 |
int Asc_QlfdidSearch2(char *str) |
358 |
{ |
359 |
char temp[MAXIMUM_ID_LENGTH]; |
360 |
struct gl_list_t *search_list; |
361 |
|
362 |
search_list = Asc_BrowQlfdidSearch(str,temp); |
363 |
if ((g_search_inst==NULL) || (search_list==NULL)) { |
364 |
return 1; |
365 |
} else { |
366 |
Asc_SearchListDestroy(search_list); |
367 |
return 0; |
368 |
} |
369 |
} |
370 |
|
371 |
/* |
372 |
********************************************************************* |
373 |
* This is the version of the function that should be used purely |
374 |
* for the effect of leaving the g_search_inst looking at the result |
375 |
* of a qualified id search. |
376 |
********************************************************************* |
377 |
*/ |
378 |
|
379 |
static |
380 |
void HandleLastPart3(char *temp) |
381 |
{ |
382 |
struct InstanceName name; |
383 |
if (g_search_inst) { |
384 |
SetInstanceNameType(name,StrName); |
385 |
SetInstanceNameStrPtr(name,AddSymbol(temp)); |
386 |
CheckChildExist(name); /* sets g_search_inst regardless */ |
387 |
return; |
388 |
} else { |
389 |
g_search_inst = Asc_FindSimulationRoot(AddSymbol(temp)); |
390 |
} |
391 |
} |
392 |
|
393 |
static |
394 |
struct Instance *BrowQlfdidSearch3(CONST char *str, char *temp,int relative) |
395 |
{ |
396 |
register char *ptr; |
397 |
struct InstanceName name; |
398 |
int ndx = 0; |
399 |
int open_bracket = 0; |
400 |
int open_quote = 0; |
401 |
CONST char *org; |
402 |
|
403 |
if (relative == 1) { |
404 |
g_search_inst = g_relative_inst; /* could be NULL */ |
405 |
} else { |
406 |
g_search_inst = NULL; /* start search from the top */ |
407 |
} |
408 |
if (str == NULL) { |
409 |
return NULL; |
410 |
} |
411 |
org = str; |
412 |
ptr = temp; |
413 |
while(*str != '\0') { |
414 |
switch(*str) { |
415 |
case '.': |
416 |
if (*(str-1) != ']') { |
417 |
if (open_quote) { /* to deal b['funny.name'] */ |
418 |
*(ptr++) = *(str++); /* ---^--- */ |
419 |
break; |
420 |
} |
421 |
*ptr = '\0'; |
422 |
if (g_search_inst) { |
423 |
SetInstanceNameType(name,StrName); |
424 |
SetInstanceNameStrPtr(name,AddSymbol(temp)); |
425 |
ndx=CheckChildExist(name); |
426 |
if(ndx==0) { |
427 |
return NULL; |
428 |
} |
429 |
} else { |
430 |
g_search_inst = Asc_FindSimulationRoot(AddSymbol(temp)); |
431 |
if (!g_search_inst) { |
432 |
return NULL; |
433 |
} |
434 |
} |
435 |
} |
436 |
str++; |
437 |
ptr = temp; |
438 |
break; |
439 |
case '\'': |
440 |
str++; |
441 |
if (open_quote) { |
442 |
open_quote--; |
443 |
} else { |
444 |
open_quote++; |
445 |
} |
446 |
break; |
447 |
case '[': |
448 |
if (*(str-1) != ']') { |
449 |
*ptr = '\0'; |
450 |
if (g_search_inst) { |
451 |
SetInstanceNameType(name,StrName); |
452 |
SetInstanceNameStrPtr(name,AddSymbol(temp)); |
453 |
ndx=CheckChildExist(name); |
454 |
if(ndx==0) { |
455 |
return NULL; |
456 |
} |
457 |
} else { |
458 |
g_search_inst = Asc_FindSimulationRoot(AddSymbol(temp)); |
459 |
if (!g_search_inst) { |
460 |
return NULL; |
461 |
} |
462 |
} |
463 |
} |
464 |
ptr = temp; |
465 |
open_bracket++; |
466 |
str++; |
467 |
break; |
468 |
case ']': |
469 |
open_bracket--; |
470 |
*ptr = '\0'; |
471 |
str++; |
472 |
switch(InstanceKind(g_search_inst)) { |
473 |
case ARRAY_INT_INST: |
474 |
SetInstanceNameType(name,IntArrayIndex); |
475 |
SetInstanceNameIntIndex(name,atol(temp)); |
476 |
ndx=CheckChildExist(name); |
477 |
if(ndx==0) { |
478 |
return NULL; |
479 |
} |
480 |
ptr = temp; |
481 |
break; |
482 |
case ARRAY_ENUM_INST: |
483 |
SetInstanceNameType(name,StrArrayIndex); |
484 |
SetInstanceNameStrIndex(name,AddSymbol(temp)); |
485 |
ndx=CheckChildExist(name); |
486 |
if(ndx==0) { /* sets g_search_inst */ |
487 |
return NULL; |
488 |
} |
489 |
ptr = temp; |
490 |
break; |
491 |
default: |
492 |
FPRINTF(stderr,"Mismatch in values file (%s) and simulation.\n",org); |
493 |
break; |
494 |
} |
495 |
break; |
496 |
default: |
497 |
*(ptr++) = *(str++); |
498 |
break; |
499 |
} |
500 |
} |
501 |
*ptr = '\0'; |
502 |
if (*temp == '\0') { |
503 |
return g_search_inst; |
504 |
} |
505 |
HandleLastPart3(temp); |
506 |
return g_search_inst; /* which may be NULL */ |
507 |
} |
508 |
|
509 |
int Asc_QlfdidSearch3(CONST char *str, int relative) |
510 |
{ |
511 |
char *temp; |
512 |
struct Instance *found; |
513 |
|
514 |
if (str==NULL) { |
515 |
return 1; |
516 |
} |
517 |
temp = ascstrdup((char *)str); |
518 |
if (temp==NULL) { |
519 |
return 1; |
520 |
} |
521 |
found = BrowQlfdidSearch3(str,temp,relative); |
522 |
ascfree(temp); |
523 |
if (found != NULL) { |
524 |
return 0; |
525 |
} else { |
526 |
return 1; |
527 |
} |
528 |
} |
529 |
|
530 |
|
531 |
|
532 |
|
533 |
|
534 |
|
535 |
|
536 |
|