1 /* -*- tab-width: 4 -*-
2 *
3 * Electric(tm) VLSI Design System
4 *
5 * File: dbvars.c
6 * Database object variables module
7 * Written by: Steven M. Rubin, Static Free Software
8 *
9 * Copyright (c) 2000 Static Free Software.
10 *
11 * Electric(tm) is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * Electric(tm) is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with Electric(tm); see the file COPYING. If not, write to
23 * the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
24 * Boston, Mass 02111-1307, USA.
25 *
26 * Static Free Software
27 * 4119 Alpine Road
28 * Portola Valley, California 94028
29 * info@staticfreesoft.com
30 */
31
32 #include "global.h"
33 #include "database.h"
34 #include "egraphics.h"
35 #include "edialogs.h"
36 #include "usr.h"
37 #include "drc.h"
38 #include "erc.h"
39 #include "rout.h"
40 #include "network.h"
41 #include "logeffort.h"
42 #include "sim.h"
43 #include "simirsim.h"
44 #include "eio.h"
45 #include "tecart.h"
46 #include "tecmocmos.h"
47 #include "tecmocmossub.h"
48 #include "tecschem.h"
49
50 /***** option saving structures *****/
51
52 /* this define should match the one in "usrdiacom.c" */
53 #define SAVEDBITWORDS 2
54
55 typedef struct
56 {
57 BOOLEAN dirty;
58 INTBIG saveflag;
59 INTBIG *addr;
60 INTBIG type;
61 INTBIG partial;
62 CHAR *variablename;
63 UINTBIG initialbits1, initialbits2;
64 UINTBIG maskbits1, maskbits2;
65 CHAR *meaning;
66 } OPTIONVARPROTO;
67
68 typedef struct
69 {
70 UINTBIG bits[SAVEDBITWORDS];
71 CHAR *command;
72 OPTIONVARPROTO *variables;
73 } OPTIONVARCOMS;
74
75 typedef struct
76 {
77 INTBIG addr;
78 INTBIG type;
79 CHAR *variablename;
80 INTBIG oldtype;
81 } OPTIONVARCACHE;
82
83 static OPTIONVARCACHE *db_optionvarcache;
84 static INTBIG db_optionvarcachecount = 0;
85
86 /***** for parameterized cells *****/
87
88 #define NOPARCELL ((PARCELL *)-1)
89
90 typedef struct Iparcell
91 {
92 NODEPROTO *cell;
93 CHAR *parname;
94 CHAR *shortname;
95 struct Iparcell *nextparcell;
96 } PARCELL;
97
98 static PARCELL *db_parcellfree = NOPARCELL;
99 static PARCELL *db_firstparcell = NOPARCELL;
100
101 BOOLEAN db_onanobject = FALSE; /* TRUE if code evaluation is "on an object" (getval, etc.) */
102 INTBIG db_onobjectaddr; /* the address of the first object that we are on */
103 INTBIG db_onobjecttype; /* the type of the first object that we are on */
104 WINDOWPART *db_onobjectwin; /* the window of the first object that we are on */
105 INTBIG db_lastonobjectaddr; /* the address of the last object that we were on */
106 INTBIG db_lastonobjecttype; /* the type of the last object that we were on */
107
108 /***** for finding variables on objects *****/
109
110 #define SPECNAME 0 /* look for special names in structure */
111 #define VARNAME 1 /* look for variable names in structure */
112 #define PORTCNAME 2 /* look for port names on nodeproto */
113 #define ARCINAME 3 /* look for nodeinst/arcinst names in cell */
114 #define NODEINAME 4 /* look for nodeinst/arcinst names in cell */
115 #define PORTANAME 5 /* look for port arc names on nodeinst */
116 #define PORTENAME 6 /* look for export names on nodeinst */
117 #define ARCNAME 7 /* look for arcproto names in technology */
118 #define NODENAME 8 /* look for nodeproto names in technology */
119 #define NULLNAME 9 /* no more names in structure */
120
121 typedef struct
122 {
123 CHAR *name;
124 UINTBIG type;
125 INTBIG *ptr;
126 } NAMEVARS;
127
128 #define MAXAPACK 5 /* maximum nested attribute searches */
129 static struct attrsearch
130 {
131 INTSML *numvar; /* address of object variable count */
132 VARIABLE **firstvar; /* address of object variable list */
133 NAMEVARS *vars; /* special names in this object */
134 INTBIG proto; /* address of object prototype */
135 INTBIG object; /* address of this object */
136 INTBIG state; /* current name type under test */
137 INTBIG varindex; /* current index for variable search */
138 INTBIG specindex; /* current index for name search */
139 NODEPROTO *nodeprotoname; /* current cell object */
140 ARCPROTO *arcprotoname; /* current arcproto object */
141 PORTARCINST *portarcinstname; /* current portarcinst object */
142 PORTEXPINST *portexpinstname; /* current portexpinst object */
143 PORTPROTO *portprotoname; /* current portproto object */
144 ARCINST *arciname; /* current arcinst object */
145 NODEINST *nodeiname; /* current nodeinst object */
146 } db_attrpacket[MAXAPACK];
147 static INTBIG db_apackindex = 0;
148 static struct attrsearch *db_thisapack;
149 static INTBIG db_realaddress;
150
151 /* prototypes for local routines */
152 static PARCELL *db_allocparcell(void);
153 static INTBIG db_assignvalue(void *loc, INTBIG datasize);
154 static INTBIG db_binarysearch(INTSML, VARIABLE*, INTBIG);
155 static BOOLEAN db_delindvar(INTBIG, INTBIG, VARIABLE*, INTBIG);
156 static CHAR *db_describetype(INTBIG type);
157 static void db_freeparcell(PARCELL *pc);
158 static INTBIG db_getdatasize(INTBIG);
159 static BOOLEAN db_getindvar(VARIABLE*, INTBIG, INTBIG*);
160 static INTBIG db_getkey(CHAR*);
161 static void db_initarcinstlist(ARCINST*);
162 static void db_initarcprotolist(ARCPROTO*);
163 static void db_initconstraintlist(CONSTRAINT*);
164 static void db_initgeomlist(GEOM*);
165 static void db_initgraphicslist(GRAPHICS*);
166 static void db_initliblist(LIBRARY*);
167 static void db_initnetworklist(NETWORK*);
168 static void db_initnodeinstlist(NODEINST*);
169 static void db_initnodeprotolist(NODEPROTO*);
170 static void db_initpolygonlist(POLYGON*);
171 static void db_initportarcinstlist(PORTARCINST*);
172 static void db_initportexpinstlist(PORTEXPINST*);
173 static void db_initportprotolist(PORTPROTO*);
174 static void db_initrtnodelist(RTNODE*);
175 static void db_inittechlist(TECHNOLOGY*);
176 static void db_inittoollist(TOOL*);
177 static void db_initviewlist(VIEW*);
178 static void db_initwindowframelist(WINDOWFRAME*);
179 static void db_initwindowlist(WINDOWPART*);
180 static BOOLEAN db_insindvar(INTBIG, INTBIG, VARIABLE*, INTBIG, INTBIG);
181 #ifdef DEBUGMEMORY
182 static BOOLEAN db_setindvar(INTBIG, INTBIG, VARIABLE*, INTBIG, INTBIG, CHAR*, INTBIG);
183 static BOOLEAN db_setval(UCHAR1*, UCHAR1*, INTBIG, CLUSTER*, CHAR*, INTBIG);
184 static BOOLEAN db_setvalkey(INTSML*, VARIABLE**, INTBIG, INTBIG, INTBIG, INTBIG, CLUSTER*, CHAR*, INTBIG);
185 static BOOLEAN db_setvalvar(VARIABLE*, INTBIG, INTBIG, CLUSTER*, CHAR*, INTBIG);
186 #else
187 static BOOLEAN db_setindvar(INTBIG, INTBIG, VARIABLE*, INTBIG, INTBIG);
188 static BOOLEAN db_setval(UCHAR1*, UCHAR1*, INTBIG, CLUSTER*);
189 static BOOLEAN db_setvalkey(INTSML*, VARIABLE**, INTBIG, INTBIG, INTBIG, INTBIG, CLUSTER*);
190 static BOOLEAN db_setvalvar(VARIABLE*, INTBIG, INTBIG, CLUSTER*);
191 #endif
192 static void db_makefontassociationdescript(UINTBIG *descript, INTBIG *fontusage, INTBIG numfonts);
193 static void db_makefontassociationvar(INTSML numvar, VARIABLE *firstvar, INTBIG *fontusage, INTBIG numfonts);
194 static void db_makefontassociations(LIBRARY *lib);
195 static void db_renamevar(INTSML, VARIABLE*, INTBIG, INTBIG);
196 static CLUSTER *db_whichcluster(INTBIG, INTBIG);
197
198 /*
199 * Routine to free all memory associated with this module.
200 */
db_freevariablememory(void)201 void db_freevariablememory(void)
202 {
203 REGISTER INTBIG i;
204 REGISTER PARCELL *pc;
205
206 for(i=0; i<el_numnames; i++) efree((CHAR *)el_namespace[i]);
207 if (el_numnames != 0) efree((CHAR *)el_namespace);
208 if (db_optionvarcachecount > 0) efree((CHAR *)db_optionvarcache);
209
210 while (db_firstparcell != NOPARCELL)
211 {
212 pc = db_firstparcell;
213 db_firstparcell = pc->nextparcell;
214 efree((CHAR *)pc->parname);
215 efree((CHAR *)pc->shortname);
216 db_freeparcell(pc);
217 }
218 while (db_parcellfree != NOPARCELL)
219 {
220 pc = db_parcellfree;
221 db_parcellfree = pc->nextparcell;
222 efree((CHAR *)pc);
223 }
224 }
225
226 /************************* ACCESSING VARIABLES *************************/
227
228 /*
229 * routine to find the variable with name "name", which must be of type
230 * "want", on the object whose address is "addr" and type is "type". If
231 * "want" is -1 then any type will do. If the variable does not exist or
232 * is the wrong type, NOVARIABLE is returned. If the variable is code, it
233 * will be evaluated and a pseudo-variable will be returned that holds the
234 * value.
235 */
getval(INTBIG addr,INTBIG type,INTBIG want,CHAR * name)236 VARIABLE *getval(INTBIG addr, INTBIG type, INTBIG want, CHAR *name)
237 {
238 VARIABLE *var;
239 REGISTER VARIABLE *retvar;
240 REGISTER CHAR *pp;
241 REGISTER INTBIG search;
242 REGISTER BOOLEAN oldonobjectstate;
243
244 /* accumulate the object that the "getval" is on (should use mutex) */
245 oldonobjectstate = db_onanobject;
246 if (!db_onanobject)
247 {
248 db_onanobject = TRUE;
249 db_onobjectaddr = addr;
250 db_onobjecttype = type;
251 }
252 db_lastonobjectaddr = addr;
253 db_lastonobjecttype = type;
254
255 retvar = NOVARIABLE;
256 search = initobjlist(addr, type, FALSE);
257 if (search != 0)
258 {
259 for(;;)
260 {
261 pp = nextobjectlist(&var, search);
262 if (pp == 0) break;
263 if (namesame(pp, name) == 0)
264 {
265 /* variable found: make sure it is right type */
266 if (want == -1 || ((INTBIG)(var->type & (VTYPE|VISARRAY))) == want)
267 {
268 retvar = evalvar(var, addr, type);
269 if (retvar != var && retvar != NOVARIABLE)
270 {
271 /* check the type again */
272 if (want != -1 && ((INTBIG)(retvar->type & (VTYPE|VISARRAY))) != want)
273 retvar = NOVARIABLE;
274 }
275 }
276 break;
277 }
278 }
279 }
280
281 /* complete the accumulation of the "getval" object (should use mutex) */
282 db_onanobject = oldonobjectstate;
283
284 /* return the result */
285 return(retvar);
286 }
287
288 /*
289 * routine to find the variable with name "name", which must be of type
290 * "want", on the object whose address is "addr" and type is "type". If
291 * "want" is -1 then any type will do. If the variable does not exist or
292 * is the wrong type, NOVARIABLE is returned. If the variable is code, it
293 * will not be evaluated.
294 */
getvalnoeval(INTBIG addr,INTBIG type,INTBIG want,CHAR * name)295 VARIABLE *getvalnoeval(INTBIG addr, INTBIG type, INTBIG want, CHAR *name)
296 {
297 VARIABLE *var;
298 REGISTER VARIABLE *retvar;
299 REGISTER CHAR *pp;
300 REGISTER INTBIG search;
301 REGISTER BOOLEAN oldonobjectstate;
302
303 /* accumulate the object that the "getval" is on (should use mutex) */
304 oldonobjectstate = db_onanobject;
305 if (!db_onanobject)
306 {
307 db_onanobject = TRUE;
308 db_onobjectaddr = addr;
309 db_onobjecttype = type;
310 }
311 db_lastonobjectaddr = addr;
312 db_lastonobjecttype = type;
313
314 retvar = NOVARIABLE;
315 search = initobjlist(addr, type, FALSE);
316 if (search != 0)
317 {
318 for(;;)
319 {
320 pp = nextobjectlist(&var, search);
321 if (pp == 0) break;
322 if (namesame(pp, name) == 0)
323 {
324 /* variable found: make sure it is right type */
325 if (want == -1 || ((INTBIG)(var->type & (VTYPE|VISARRAY))) == want)
326 retvar = var;
327 break;
328 }
329 }
330 }
331
332 /* complete the accumulation of the "getval" object (should use mutex) */
333 db_onanobject = oldonobjectstate;
334
335 /* return the result */
336 return(retvar);
337 }
338
339 /*
340 * routine to find the variable with key "key", which must be of type "want",
341 * on the object whose address is "addr" and type is "type". If the
342 * variable does not exist or is the wrong type, NOVARIABLE is returned.
343 * If the variable is code, it will be evaluated and a pseudo-variable
344 * will be returned that holds the value.
345 */
getvalkey(INTBIG addr,INTBIG type,INTBIG want,INTBIG key)346 VARIABLE *getvalkey(INTBIG addr, INTBIG type, INTBIG want, INTBIG key)
347 {
348 REGISTER INTBIG med;
349 INTSML *mynumvar;
350 REGISTER VARIABLE *var, *retvar;
351 VARIABLE **myfirstvar;
352 REGISTER BOOLEAN oldonobjectstate;
353
354 /* accumulate the object that the "getval" is on (should use mutex) */
355 oldonobjectstate = db_onanobject;
356 if (!db_onanobject)
357 {
358 db_onanobject = TRUE;
359 db_onobjectaddr = addr;
360 db_onobjecttype = type;
361 }
362 db_lastonobjectaddr = addr;
363 db_lastonobjecttype = type;
364
365 /* get the firstvar/numvar into the globals */
366 retvar = NOVARIABLE;
367 if (!db_getvarptr(addr, type, &myfirstvar, &mynumvar))
368 {
369 /* binary search variable space for the key */
370 med = db_binarysearch(*mynumvar, *myfirstvar, key);
371 if (med >= 0)
372 {
373 /* get the variable */
374 var = &(*myfirstvar)[med];
375
376 /* make sure it is right type if a type was specified */
377 if (want == -1 || ((INTBIG)(var->type & (VTYPE|VISARRAY))) == want)
378 {
379 retvar = evalvar(var, addr, type);
380 if (retvar != var && retvar != NOVARIABLE)
381 {
382 /* check the type again */
383 if (want != -1 && ((INTBIG)(retvar->type & (VTYPE|VISARRAY))) != want)
384 retvar = NOVARIABLE;
385 }
386 }
387 }
388 }
389
390 /* complete the accumulation of the "getval" object (should use mutex) */
391 db_onanobject = oldonobjectstate;
392
393 /* return the result */
394 return(retvar);
395 }
396
397 /*
398 * routine to find the variable with key "key", which must be of type "want",
399 * on the object whose address is "addr" and type is "type". If the
400 * variable does not exist or is the wrong type, NOVARIABLE is returned.
401 * If the variable is code, it will not be evaluated.
402 */
getvalkeynoeval(INTBIG addr,INTBIG type,INTBIG want,INTBIG key)403 VARIABLE *getvalkeynoeval(INTBIG addr, INTBIG type, INTBIG want, INTBIG key)
404 {
405 REGISTER INTBIG med;
406 INTSML *mynumvar;
407 REGISTER VARIABLE *var, *retvar;
408 VARIABLE **myfirstvar;
409 REGISTER BOOLEAN oldonobjectstate;
410
411 /* accumulate the object that the "getval" is on (should use mutex) */
412 oldonobjectstate = db_onanobject;
413 if (!db_onanobject)
414 {
415 db_onanobject = TRUE;
416 db_onobjectaddr = addr;
417 db_onobjecttype = type;
418 }
419 db_lastonobjectaddr = addr;
420 db_lastonobjecttype = type;
421
422 /* get the firstvar/numvar into the globals */
423 retvar = NOVARIABLE;
424 if (!db_getvarptr(addr, type, &myfirstvar, &mynumvar))
425 {
426 /* binary search variable space for the key */
427 med = db_binarysearch(*mynumvar, *myfirstvar, key);
428 if (med >= 0)
429 {
430 /* get the variable */
431 var = &(*myfirstvar)[med];
432
433 /* make sure it is right type if a type was specified */
434 if (want == -1 || ((INTBIG)(var->type & (VTYPE|VISARRAY))) == want)
435 retvar = var;
436 }
437 }
438
439 /* complete the accumulation of the "getval" object (should use mutex) */
440 db_onanobject = oldonobjectstate;
441
442 /* return the result */
443 return(retvar);
444 }
445
446 /*
447 * Routine to set the current window to use when examining the value of variables.
448 * Returns the previous value of the default window.
449 */
setvariablewindow(WINDOWPART * win)450 WINDOWPART *setvariablewindow(WINDOWPART *win)
451 {
452 REGISTER WINDOWPART *lastwin;
453
454 lastwin = db_onobjectwin;
455 db_onobjectwin = win;
456 return(lastwin);
457 }
458
459 /*
460 * Routine to return the address and type of the current object that is being querried with
461 * "getval()", "getvalkey()", "getvalnoeval()", or "getvalkeynoeval()".
462 * Returns TRUE if there is a valid object, FALSE if not.
463 */
getcurrentvariableenvironment(INTBIG * addr,INTBIG * type,WINDOWPART ** win)464 BOOLEAN getcurrentvariableenvironment(INTBIG *addr, INTBIG *type, WINDOWPART **win)
465 {
466 if (db_onanobject)
467 {
468 *addr = db_onobjectaddr;
469 *type = db_onobjecttype;
470 *win = db_onobjectwin;
471 return(db_onanobject);
472 }
473 return(FALSE);
474 }
475
476 /*
477 * Routine to return the last address and type of the object from which a "getval()",
478 * "getvalkey()", "getvalnoeval()", or "getvalkeynoeval()" was called.
479 * Returns TRUE if there is a valid object, FALSE if not.
480 */
getlastvariableobject(INTBIG * addr,INTBIG * type)481 BOOLEAN getlastvariableobject(INTBIG *addr, INTBIG *type)
482 {
483 if (db_onanobject)
484 {
485 *addr = db_lastonobjectaddr;
486 *type = db_lastonobjecttype;
487 return(db_onanobject);
488 }
489 return(FALSE);
490 }
491
492 #define NUMEVALS 100
493
494 /*
495 * Routine to return a VARIABLE that can be used as a placeholder for a real one.
496 * This is needed when a VARIABLE is code (a dummy one must be created to hold the
497 * evaluation). It is also needed when generating VARIABLEs for objects that are part
498 * of the fixed C structures.
499 */
db_dummyvariable(void)500 VARIABLE *db_dummyvariable(void)
501 {
502 REGISTER VARIABLE *var;
503 static INTBIG evalnum = 0;
504 static VARIABLE retvar[NUMEVALS];
505
506 /* code cannot be called by multiple procesors: uses globals */
507 NOT_REENTRANT;
508
509 /* prepare to evaluate the variable */
510 evalnum++;
511 if (evalnum >= NUMEVALS) evalnum = 0;
512 var = &retvar[evalnum];
513 return(var);
514 }
515
516 /*
517 * routine to evaluate variable "var" and replace it with its true value if it is code
518 */
evalvar(VARIABLE * var,INTBIG addr,INTBIG type)519 VARIABLE *evalvar(VARIABLE *var, INTBIG addr, INTBIG type)
520 {
521 REGISTER INTBIG language;
522 REGISTER VARIABLE *thevar;
523
524 /* if this isn't code or even a variable, just return the input */
525 if (var == NOVARIABLE) return(var);
526 language = var->type & (VCODE1|VCODE2);
527 if (language == 0) return(var);
528
529 /* set the environment */
530 if (addr == 0) db_onanobject = FALSE; else
531 {
532 db_onanobject = TRUE;
533 db_lastonobjectaddr = db_onobjectaddr = addr;
534 db_lastonobjecttype = db_onobjecttype = type;
535 }
536
537 /* evaluate the variable */
538 thevar = doquerry((CHAR *)var->addr, language, var->type & ~(VCODE1|VCODE2));
539
540 /* remove the environment */
541 db_onanobject = FALSE;
542
543 if (thevar == NOVARIABLE) return(var);
544 thevar->key = var->key;
545 TDCOPY(thevar->textdescript, var->textdescript);
546 return(thevar);
547 }
548
549 /*
550 * routine to get an entry in the array variable "name" in object "addr"
551 * which is of type "type". Entry "aindex" is placed into "value". Returns
552 * true on error.
553 */
getind(INTBIG addr,INTBIG type,CHAR * name,INTBIG aindex,INTBIG * value)554 BOOLEAN getind(INTBIG addr, INTBIG type, CHAR *name, INTBIG aindex, INTBIG *value)
555 {
556 VARIABLE *var;
557 REGISTER CHAR *pp;
558 REGISTER INTBIG search;
559
560 search = initobjlist(addr, type, FALSE);
561 if (search == 0) return(TRUE);
562 for(;;)
563 {
564 pp = nextobjectlist(&var, search);
565 if (pp == 0) break;
566 if (namesame(pp, name) == 0) break;
567 }
568
569 /* variable must exist */
570 if (pp == 0) return(TRUE);
571
572 if ((var->type&VCANTSET) != 0) return(TRUE);
573
574 return(db_getindvar(var, aindex, value));
575 }
576
577 /*
578 * routine to get an entry in the array variable whose key is "key" in object
579 * "addr" which is of type "type". Entry "aindex" is placed in "value".
580 * The routine returns true upon error.
581 */
getindkey(INTBIG addr,INTBIG type,INTBIG key,INTBIG aindex,INTBIG * value)582 BOOLEAN getindkey(INTBIG addr, INTBIG type, INTBIG key, INTBIG aindex, INTBIG *value)
583 {
584 VARIABLE **myfirstvar;
585 INTSML *mynumvar;
586 REGISTER INTBIG med;
587
588 /* get the attribute list into the globals */
589 if (db_getvarptr(addr, type, &myfirstvar, &mynumvar)) return(TRUE);
590
591 /* binary search variable space for the key */
592 med = db_binarysearch(*mynumvar, *myfirstvar, key);
593
594 /* variable must exist */
595 if (med < 0) return(TRUE);
596
597 if (((*myfirstvar)[med].type&VCANTSET) != 0) return(TRUE);
598
599 /* get the variable */
600 return(db_getindvar(&(*myfirstvar)[med], aindex, value));
601 }
602
603 BOOLEAN db_parentvaldefaulted = FALSE;
604
605 /*
606 * Routine to examine the hierarchy and find the variable "name".
607 * Looks as many as "height" levels up the hierarchy (arbitrary if zero).
608 * Returns the variable if found.
609 */
getparentval(CHAR * name,INTBIG height)610 VARIABLE *getparentval(CHAR *name, INTBIG height)
611 {
612 REGISTER INTBIG key;
613
614 key = makekey(name);
615 return(getparentvalkey(key, height));
616 }
617
618 /*
619 * Routine to examine the hierarchy and find the variable with key "key".
620 * Looks as many as "height" levels up the hierarchy (arbitrary if zero).
621 * Returns the variable if found.
622 */
getparentvalkey(INTBIG key,INTBIG height)623 VARIABLE *getparentvalkey(INTBIG key, INTBIG height)
624 {
625 NODEINST **localnilist;
626 INTBIG localdepth, *localindexlist, oldclimb;
627 REGISTER NODEINST *ni;
628 REGISTER INTBIG i, climbed;
629 REGISTER VARIABLE *var, *varne;
630
631 /* search hierarchical path */
632 gettraversalpath(el_curlib->curnodeproto, db_onobjectwin, &localnilist, &localindexlist, &localdepth, height);
633 climbed = 0;
634 oldclimb = getpopouthierarchy();
635
636 for(i = localdepth - 1; i >= 0; i--)
637 {
638 ni = localnilist[i];
639
640 /*
641 * because evaluation of this variable may involve examination of the
642 * hierarchy, the hierarchy stack must get shortened
643 */
644 climbed++;
645 popouthierarchy(oldclimb+climbed);
646
647 /* look for the variable on the instance up the hierarchy */
648 var = getvalkey((INTBIG)ni, VNODEINST, -1, key);
649
650 /* restore hierarchy stack */
651 popouthierarchy(oldclimb);
652
653 /* return value if found */
654 if (var != NOVARIABLE)
655 {
656 /* make sure the variable is of type "parameter" */
657 if (TDGETISPARAM(var->textdescript) == 0)
658 {
659 ttyputmsg(_("Warning: Cell %s, node %s has attribute %s used as a parameter"),
660 describenodeproto(ni->parent), describenodeinst(ni), truevariablename(var));
661
662 /* repair the bit */
663 popouthierarchy(climbed);
664 varne = getvalkeynoeval((INTBIG)ni, VNODEINST, -1, key);
665 popouthierarchy(0);
666 if (varne != NOVARIABLE)
667 {
668 TDSETISPARAM(varne->textdescript, VTISPARAMETER);
669 ni->parent->lib->userbits |= LIBCHANGEDMINOR;
670 }
671 }
672 return(var);
673 }
674
675 /* stop climbing hierarchy if limited */
676 if (height != 0)
677 {
678 height--;
679 if (height <= 0) break;
680 }
681 }
682 db_parentvaldefaulted = TRUE;
683 return(NOVARIABLE);
684 }
685
686 /*
687 * Routine to return TRUE if the any call to "getparentval()" or "getparentvalkey()" returned
688 * a default value. Resets the flag at each call.
689 */
parentvaldefaulted(void)690 BOOLEAN parentvaldefaulted(void)
691 {
692 REGISTER BOOLEAN retval;
693
694 retval = db_parentvaldefaulted;
695 db_parentvaldefaulted = FALSE;
696 return(retval);
697 }
698
699 /*
700 * routine to modify the text descriptor on variable "var", which resides on
701 * object "addr" of type "type". The new descriptor is set to "newdescript"
702 */
modifydescript(INTBIG addr,INTBIG type,VARIABLE * var,UINTBIG * newdescript)703 void modifydescript(INTBIG addr, INTBIG type, VARIABLE *var, UINTBIG *newdescript)
704 {
705 UINTBIG olddescript[TEXTDESCRIPTSIZE];
706
707 if (var != NOVARIABLE)
708 {
709 TDCOPY(olddescript, var->textdescript);
710 TDCOPY(var->textdescript, newdescript);
711 }
712
713 /* handle change control, constraint, and broadcast */
714 if (!db_donextchangequietly && !db_dochangesquietly)
715 {
716 /* tell constraint system about killed variable */
717 (*el_curconstraint->modifydescript)(addr, type, var->key, olddescript);
718
719 db_setchangecell(db_whichnodeproto(addr, type));
720
721 /* record the change */
722 (void)db_change(addr, DESCRIPTMOD, type, var->key, var->type, olddescript[0],
723 olddescript[1], 0);
724 }
725 db_donextchangequietly = FALSE;
726
727 /* mark a change to the database */
728 db_changetimestamp++;
729 }
730
731 /*
732 * routine to return the length of the array in variable "var". If it is not
733 * an array, the value -1 is returned.
734 */
getlength(VARIABLE * var)735 INTBIG getlength(VARIABLE *var)
736 {
737 REGISTER INTBIG len;
738
739 if ((var->type&VISARRAY) == 0) return(-1);
740 len = (var->type&VLENGTH) >> VLENGTHSH;
741 if (len != 0) return(len);
742
743 if ((var->type&VTYPE) == VCHAR)
744 {
745 for(len=0; ((((CHAR *)var->addr)[len])&0377) != 0377; len++) ;
746 } else if ((var->type&VTYPE) == VFLOAT)
747 {
748 for(len=0; ((float *)var->addr)[len] != -1; len++) ;
749 } else if ((var->type&VTYPE) == VDOUBLE)
750 {
751 for(len=0; ((double *)var->addr)[len] != -1; len++) ;
752 } else if ((var->type&VTYPE) == VSHORT)
753 {
754 for(len=0; ((INTSML *)var->addr)[len] != -1; len++) ;
755 } else
756 {
757 for(len=0; ((INTBIG *)var->addr)[len] != -1; len++) ;
758 }
759 return(len);
760 }
761
762 /*
763 * routine to convert a variable name in "name" to a key and return it.
764 * If an error is detected, the routine returns -1.
765 */
makekey(CHAR * name)766 INTBIG makekey(CHAR *name)
767 {
768 REGISTER CHAR **newname;
769 REGISTER INTBIG med, i;
770
771 /* search namespace for this name */
772 med = db_getkey(name);
773 if (med >= 0) return((INTBIG)el_namespace[med]);
774
775 /* convert return value to proper index for new name */
776 med = -med-1;
777
778 /* make sure the name is valid */
779 for(i=0; name[i] != 0; i++) if (name[i] == ' ' || name[i] == '\t')
780 return(db_error(DBBADNAME|DBMAKEKEY));
781
782 /* allocate space for new list */
783 newname = (CHAR **)emalloc(((el_numnames+1)*(sizeof (CHAR *))), db_cluster);
784 if (newname == 0) return(db_error(DBNOMEM|DBMAKEKEY));
785
786 /* copy old list up to the new entry */
787 for(i=0; i<med; i++) newname[i] = el_namespace[i];
788
789 /* add the new entry */
790 if (allocstring(&newname[med], name, db_cluster)) return(-1);
791
792 /* copy old list after the new entry */
793 for(i=med; i<el_numnames; i++) newname[i+1] = el_namespace[i];
794
795 /* clean-up */
796 if (el_numnames != 0) efree((CHAR *)el_namespace);
797 el_namespace = newname;
798 el_numnames++;
799 return((INTBIG)el_namespace[med]);
800 }
801
802 /*
803 * routine to convert a variable key in "key" to a name and return it.
804 * Because of the techniques used, this is trivial.
805 */
makename(INTBIG key)806 CHAR *makename(INTBIG key)
807 {
808 return((CHAR *)key);
809 }
810
811 /*
812 * routine to initialize a search of the variable names on object "addr"
813 * of type "type". Subsequent calls to "nextobjectlist" will return
814 * variable names and fill the parameter with the variable addresses.
815 * If "restrictdirect" is nonzero, only list those attributes directly on the
816 * object (and not those in linked lists). The routine returns zero upon
817 * error, and otherwise returns a value that must be passed to the subsequent
818 * "nextobjectlist" calls
819 */
initobjlist(INTBIG addr,INTBIG type,BOOLEAN restrictdirect)820 INTBIG initobjlist(INTBIG addr, INTBIG type, BOOLEAN restrictdirect)
821 {
822 /* code cannot be called by multiple procesors: uses globals */
823 NOT_REENTRANT;
824
825 db_thisapack = &db_attrpacket[db_apackindex++];
826 if (db_apackindex >= MAXAPACK) db_apackindex = 0;
827 switch (type&VTYPE)
828 {
829 case VNODEINST: db_initnodeinstlist((NODEINST *)addr); break;
830 case VNODEPROTO: db_initnodeprotolist((NODEPROTO *)addr); break;
831 case VPORTARCINST: db_initportarcinstlist((PORTARCINST *)addr); break;
832 case VPORTEXPINST: db_initportexpinstlist((PORTEXPINST *)addr); break;
833 case VPORTPROTO: db_initportprotolist((PORTPROTO *)addr); break;
834 case VARCINST: db_initarcinstlist((ARCINST *)addr); break;
835 case VARCPROTO: db_initarcprotolist((ARCPROTO *)addr); break;
836 case VGEOM: db_initgeomlist((GEOM *)addr); break;
837 case VLIBRARY: db_initliblist((LIBRARY *)addr); break;
838 case VTECHNOLOGY: db_inittechlist((TECHNOLOGY *)addr); break;
839 case VTOOL: db_inittoollist((TOOL *)addr); break;
840 case VRTNODE: db_initrtnodelist((RTNODE *)addr); break;
841 case VNETWORK: db_initnetworklist((NETWORK *)addr); break;
842 case VVIEW: db_initviewlist((VIEW *)addr); break;
843 case VWINDOWPART: db_initwindowlist((WINDOWPART *)addr); break;
844 case VGRAPHICS: db_initgraphicslist((GRAPHICS *)addr); break;
845 case VCONSTRAINT: db_initconstraintlist((CONSTRAINT *)addr); break;
846 case VWINDOWFRAME: db_initwindowframelist((WINDOWFRAME *)addr); break;
847 case VPOLYGON: db_initpolygonlist((POLYGON *)addr); break;
848 default:
849 (void)db_error(DBBADOBJECT|DBINITOBJLIST);
850 return(0);
851 }
852 if (restrictdirect)
853 if (db_thisapack->state != NULLNAME) db_thisapack->state = SPECNAME;
854 return((INTBIG)db_thisapack);
855 }
856
857 /*
858 * routine to return the next name in the list (and the associated variable)
859 */
nextobjectlist(VARIABLE ** actualvar,INTBIG ain)860 CHAR *nextobjectlist(VARIABLE **actualvar, INTBIG ain)
861 {
862 struct attrsearch *apack;
863 REGISTER INTBIG datasize;
864 REGISTER BOOLEAN indir;
865 REGISTER CHAR *retval;
866 REGISTER NODEINST *ni;
867 REGISTER ARCINST *ai;
868 static CHAR line[50];
869 REGISTER VARIABLE *var, *nvar;
870
871 apack = (struct attrsearch *)ain;
872 for(;;) switch (apack->state)
873 {
874 case SPECNAME: /* looking for special names in object structure */
875 if (apack->vars[apack->specindex].name != 0)
876 {
877 /* get next special name */
878 *actualvar = var = db_dummyvariable();
879 var->key = apack->specindex;
880 var->type = apack->vars[apack->specindex].type;
881 TDCLEAR(var->textdescript);
882 TDSETSIZE(var->textdescript, TXTSETQLAMBDA(4));
883 var->addr = (INTBIG)apack->vars[apack->specindex].ptr - apack->proto + apack->object;
884 db_realaddress = var->addr;
885 indir = FALSE;
886 if ((var->type&VISARRAY) == 0) indir = TRUE; else
887 if ((var->type&VCREF) == 0) indir = TRUE;
888 if (indir)
889 {
890 datasize = db_getdatasize(var->type);
891 var->addr = db_assignvalue((void *)var->addr, datasize);
892 }
893 var->type |= VCREF;
894 return(apack->vars[apack->specindex++].name);
895 }
896 /* no more special names, go to next case */
897 apack->state = VARNAME;
898 break;
899 case VARNAME: /* looking for variable names in object */
900 if (apack->varindex < *apack->numvar)
901 {
902 /* get next variable name */
903 *actualvar = &(*apack->firstvar)[apack->varindex];
904 return((CHAR *)(*apack->firstvar)[apack->varindex++].key);
905 }
906 /* no more variable names, go to terminal case */
907 apack->state = NULLNAME;
908 break;
909 case ARCINAME: /* looking for arcs in the nodeproto */
910 if (apack->arciname != NOARCINST)
911 {
912 /* get next arcinst name */
913 ai = apack->arciname;
914 apack->arciname = apack->arciname->nextarcinst;
915 *actualvar = var = db_dummyvariable();
916 var->key = -1;
917 var->type = VARCINST;
918 TDCLEAR(var->textdescript);
919 TDSETSIZE(var->textdescript, TXTSETQLAMBDA(4));
920 var->addr = (INTBIG)ai;
921 nvar = getvalkey((INTBIG)ai, VARCINST, VSTRING, el_arc_name_key);
922 if (nvar != NOVARIABLE) return((CHAR *)nvar->addr);
923 (void)esnprintf(line, 50, x_("arc%ld"), (INTBIG)ai);
924 return(line);
925 }
926 apack->state = NODEINAME;
927 break;
928 case NODEINAME: /* looking for nodes in the nodeproto */
929 if (apack->nodeiname != NONODEINST)
930 {
931 /* get next nodeinst name */
932 ni = apack->nodeiname;
933 apack->nodeiname = apack->nodeiname->nextnodeinst;
934 *actualvar = var = db_dummyvariable();
935 var->key = -1;
936 var->type = VNODEINST;
937 TDCLEAR(var->textdescript);
938 TDSETSIZE(var->textdescript, TXTSETQLAMBDA(4));
939 var->addr = (INTBIG)ni;
940 nvar = getvalkey((INTBIG)ni, VNODEINST, VSTRING, el_node_name_key);
941 if (nvar != NOVARIABLE) return((CHAR *)nvar->addr);
942 (void)esnprintf(line, 50, x_("node%ld"), (INTBIG)ni);
943 return(line);
944 }
945 /* no more nodeinst names, go to next case */
946 apack->state = PORTCNAME;
947 break;
948 case PORTCNAME: /* looking for port names on nodeproto */
949 if (apack->portprotoname != NOPORTPROTO)
950 {
951 /* get next port name */
952 *actualvar = var = db_dummyvariable();
953 var->key = -1;
954 TDCLEAR(var->textdescript);
955 TDSETSIZE(var->textdescript, TXTSETQLAMBDA(4));
956 var->type = VPORTPROTO; var->addr = (INTBIG)apack->portprotoname;
957 retval = apack->portprotoname->protoname;
958 apack->portprotoname = apack->portprotoname->nextportproto;
959 return(retval);
960 }
961 /* no more port names, go to next case */
962 apack->state = SPECNAME;
963 break;
964 case PORTANAME: /* looking for portarcinst names on nodeinst */
965 if (apack->portarcinstname != NOPORTARCINST)
966 {
967 /* get next portarcinst name */
968 *actualvar = var = db_dummyvariable();
969 var->key = -1;
970 var->type = VPORTARCINST;
971 TDCLEAR(var->textdescript);
972 TDSETSIZE(var->textdescript, TXTSETQLAMBDA(4));
973 var->addr = (INTBIG)apack->portarcinstname;
974 retval = apack->portarcinstname->proto->protoname;
975 apack->portarcinstname = apack->portarcinstname->nextportarcinst;
976 return(retval);
977 }
978 /* no more portarcinst names, go to next case */
979 apack->state = PORTENAME;
980 break;
981 case PORTENAME: /* looking for portexpinst names on nodeinst */
982 if (apack->portexpinstname != NOPORTEXPINST)
983 {
984 /* get next portexpinst name */
985 *actualvar = var = db_dummyvariable();
986 var->key = -1;
987 var->type = VPORTEXPINST;
988 TDCLEAR(var->textdescript);
989 TDSETSIZE(var->textdescript, TXTSETQLAMBDA(4));
990 var->addr = (INTBIG)apack->portexpinstname;
991 retval = apack->portexpinstname->proto->protoname;
992 apack->portexpinstname = apack->portexpinstname->nextportexpinst;
993 return(retval);
994 }
995 /* no more portexpinst names, go to next case */
996 apack->state = SPECNAME;
997 break;
998 case ARCNAME: /* looking for arcs in the technology */
999 if (apack->arcprotoname != NOARCPROTO)
1000 {
1001 /* get next arcproto name */
1002 *actualvar = var = db_dummyvariable();
1003 var->key = -1;
1004 TDCLEAR(var->textdescript);
1005 TDSETSIZE(var->textdescript, TXTSETQLAMBDA(4));
1006 var->type = VARCPROTO; var->addr = (INTBIG)apack->arcprotoname;
1007 retval = apack->arcprotoname->protoname;
1008 apack->arcprotoname = apack->arcprotoname->nextarcproto;
1009 return(retval);
1010 }
1011 /* no more arcproto names, go to next case */
1012 apack->state = NODENAME;
1013 break;
1014 case NODENAME: /* looking for cells in the tech/lib */
1015 if (apack->nodeprotoname != NONODEPROTO)
1016 {
1017 /* get next cell name */
1018 *actualvar = var = db_dummyvariable();
1019 var->key = -1;
1020 TDCLEAR(var->textdescript);
1021 TDSETSIZE(var->textdescript, TXTSETQLAMBDA(4));
1022 var->type = VNODEPROTO; var->addr = (INTBIG)apack->nodeprotoname;
1023 retval = describenodeproto(apack->nodeprotoname);
1024 apack->nodeprotoname = apack->nodeprotoname->nextnodeproto;
1025 return(retval);
1026 }
1027 /* no more nodeproto names, go to next case */
1028 apack->state = SPECNAME;
1029 break;
1030 case NULLNAME:
1031 *actualvar = NOVARIABLE;
1032 return(0);
1033 }
1034 }
1035
1036 /********************** DELETING AND RENAMING VARIABLES *********************/
1037
1038 /*
1039 * delete the variable "name" from object whose address is "addr" and type
1040 * is "type". Returns true if there is an error.
1041 */
delval(INTBIG addr,INTBIG type,CHAR * name)1042 BOOLEAN delval(INTBIG addr, INTBIG type, CHAR *name)
1043 {
1044 REGISTER INTBIG key;
1045
1046 key = makekey(name);
1047 if (key == -1)
1048 {
1049 db_donextchangequietly = FALSE;
1050 return(TRUE);
1051 }
1052
1053 return(delvalkey(addr, type, key));
1054 }
1055
1056 /*
1057 * delete the variable with the key "key" from object whose address is
1058 * "addr" and type is "type". Returns true if there is an error.
1059 */
delvalkey(INTBIG addr,INTBIG type,INTBIG key)1060 BOOLEAN delvalkey(INTBIG addr, INTBIG type, INTBIG key)
1061 {
1062 REGISTER VARIABLE *var;
1063 REGISTER CHAR *varname;
1064 VARIABLE **myfirstvar;
1065 INTSML *mynumvar;
1066 REGISTER INTSML i, j;
1067 REGISTER INTBIG oldaddr, oldtype;
1068 UINTBIG olddescript[TEXTDESCRIPTSIZE];
1069
1070 /* get the firstvar/numvar pointers */
1071 if (db_getvarptr(addr, type, &myfirstvar, &mynumvar))
1072 {
1073 db_donextchangequietly = FALSE;
1074 return(TRUE);
1075 }
1076
1077 /* search for the variable in the list */
1078 for(i=0; i<*mynumvar; i++)
1079 if ((*myfirstvar)[i].key == key) break;
1080 if (i >= *mynumvar)
1081 {
1082 if (key != -1) varname = makename(key); else
1083 varname = _("FIXED VARIABLE");
1084 ttyputmsg(_("Internal error: tried to delete %s on object of type %s. No worry."),
1085 varname, db_describetype(type));
1086 db_donextchangequietly = FALSE;
1087 (void)db_error(DBNOVAR|DBDELVALKEY);
1088 return(TRUE);
1089 }
1090
1091 /* delete the variable */
1092 var = &(*myfirstvar)[i];
1093 oldaddr = var->addr;
1094 oldtype = var->type;
1095 TDCOPY(olddescript, var->textdescript);
1096
1097 /* delete the entry in the variable list */
1098 (*mynumvar)--;
1099 for(j = i; j < *mynumvar; j++)
1100 {
1101 (*myfirstvar)[j].key = (*myfirstvar)[j+1].key;
1102 (*myfirstvar)[j].type = (*myfirstvar)[j+1].type;
1103 TDCOPY((*myfirstvar)[j].textdescript, (*myfirstvar)[j+1].textdescript);
1104 (*myfirstvar)[j].addr = (*myfirstvar)[j+1].addr;
1105 }
1106 if (*mynumvar == 0) efree((CHAR *)*myfirstvar);
1107
1108 /* handle change control, constraint, and broadcast */
1109 if (!db_donextchangequietly && !db_dochangesquietly)
1110 {
1111 /* tell constraint system about killed variable */
1112 (*el_curconstraint->killvariable)(addr, type, key, oldaddr, oldtype, olddescript);
1113
1114 /* record the change */
1115 (void)db_change((INTBIG)addr, VARIABLEKILL, type, key, oldaddr, oldtype, olddescript[0],
1116 olddescript[1]);
1117 } else
1118 {
1119 /* not going through change control, so delete the memory now */
1120 db_freevar(oldaddr, oldtype);
1121 }
1122 db_donextchangequietly = FALSE;
1123
1124 /* mark a change to the database */
1125 if (type != VTOOL || addr != (INTBIG)us_tool) db_changetimestamp++;
1126 return(FALSE);
1127 }
1128
1129 /*
1130 * routine to rename variable "oldname" to "newname" everywhere in the
1131 * database.
1132 * This routine does not delete the old name from the namespace but it does
1133 * rename the variable wherever it exists, so the old name is no longer
1134 * in use. NOTE: this does not check variables on R-tree nodes.
1135 */
renameval(CHAR * oldname,CHAR * newname)1136 void renameval(CHAR *oldname, CHAR *newname)
1137 {
1138 REGISTER INTBIG oldkey, newkey;
1139 REGISTER INTSML i;
1140 REGISTER NODEPROTO *np;
1141 REGISTER ARCPROTO *ap;
1142 REGISTER PORTPROTO *pp;
1143 REGISTER NETWORK *net;
1144 REGISTER VIEW *v;
1145 REGISTER NODEINST *ni;
1146 REGISTER ARCINST *ai;
1147 REGISTER LIBRARY *lib;
1148 REGISTER TECHNOLOGY *tech;
1149
1150 /* get key of old name */
1151 oldkey = db_getkey(oldname);
1152 if (oldkey < 0) return;
1153 oldkey = (INTBIG)el_namespace[oldkey];
1154
1155 /* make sure new name is different */
1156 if (namesame(oldname, newname) == 0) return;
1157
1158 /* make new name key */
1159 newkey = makekey(newname);
1160 if (newkey < 0) return;
1161
1162 /* search the libraries */
1163 for(lib = el_curlib; lib != NOLIBRARY; lib = lib->nextlibrary)
1164 {
1165 db_renamevar(lib->numvar, lib->firstvar, oldkey, newkey);
1166 for(np = lib->firstnodeproto; np != NONODEPROTO; np = np->nextnodeproto)
1167 {
1168 db_renamevar(np->numvar, np->firstvar, oldkey, newkey);
1169 for(pp = np->firstportproto; pp != NOPORTPROTO; pp = pp->nextportproto)
1170 {
1171 db_renamevar(pp->numvar, pp->firstvar, oldkey, newkey);
1172 db_renamevar(pp->subportexpinst->numvar,
1173 pp->subportexpinst->firstvar, oldkey, newkey);
1174 }
1175 for(ni = np->firstnodeinst; ni != NONODEINST; ni = ni->nextnodeinst)
1176 {
1177 db_renamevar(ni->numvar, ni->firstvar, oldkey, newkey);
1178 db_renamevar(ni->geom->numvar, ni->geom->firstvar, oldkey, newkey);
1179 }
1180 for(ai = np->firstarcinst; ai != NOARCINST; ai = ai->nextarcinst)
1181 {
1182 db_renamevar(ai->numvar, ai->firstvar, oldkey, newkey);
1183 db_renamevar(ai->geom->numvar, ai->geom->firstvar, oldkey, newkey);
1184 db_renamevar(ai->end[0].portarcinst->numvar,
1185 ai->end[0].portarcinst->firstvar, oldkey, newkey);
1186 db_renamevar(ai->end[1].portarcinst->numvar,
1187 ai->end[1].portarcinst->firstvar, oldkey, newkey);
1188 }
1189 for(net = np->firstnetwork; net != NONETWORK; net = net->nextnetwork)
1190 db_renamevar(net->numvar, net->firstvar, oldkey, newkey);
1191 }
1192 }
1193
1194 /* search the tools */
1195 for(i=0; i<el_maxtools; i++)
1196 db_renamevar(el_tools[i].numvar, el_tools[i].firstvar, oldkey, newkey);
1197
1198 /* search the views */
1199 for(v = el_views; v != NOVIEW; v = v->nextview)
1200 db_renamevar(v->numvar, v->firstvar, oldkey, newkey);
1201
1202 /* search the technologies */
1203 for(tech = el_technologies; tech != NOTECHNOLOGY; tech = tech->nexttechnology)
1204 {
1205 db_renamevar(tech->numvar, tech->firstvar, oldkey, newkey);
1206 for(ap = tech->firstarcproto; ap != NOARCPROTO; ap = ap->nextarcproto)
1207 db_renamevar(ap->numvar, ap->firstvar, oldkey, newkey);
1208 for(np = tech->firstnodeproto; np != NONODEPROTO; np = np->nextnodeproto)
1209 db_renamevar(np->numvar, np->firstvar, oldkey, newkey);
1210 }
1211
1212 /* mark a change to the database */
1213 db_changetimestamp++;
1214 }
1215
1216 /************************* SETTING ENTIRE VARIABLES *************************/
1217
1218 /*
1219 * routine to set the value of entry "name" in object "addr" which is of
1220 * type "type". The entry is set to "newaddr" which has type "newtype".
1221 * The routine returns the variable address (NOVARIABLE on error).
1222 */
1223 #ifdef DEBUGMEMORY
_setval(INTBIG addr,INTBIG type,CHAR * name,INTBIG newaddr,INTBIG newtype,CHAR * module,INTBIG line)1224 VARIABLE *_setval(INTBIG addr, INTBIG type, CHAR *name, INTBIG newaddr, INTBIG newtype,
1225 CHAR *module, INTBIG line)
1226 #else
1227 VARIABLE *setval(INTBIG addr, INTBIG type, CHAR *name, INTBIG newaddr, INTBIG newtype)
1228 #endif
1229 {
1230 VARIABLE *var;
1231 REGISTER CHAR *pp;
1232 REGISTER INTBIG key, search;
1233
1234 /* look for an attribute that already has this name */
1235 search = initobjlist(addr, type, FALSE);
1236 if (search == 0)
1237 {
1238 db_donextchangequietly = FALSE;
1239 return(NOVARIABLE);
1240 }
1241 for(;;)
1242 {
1243 pp = nextobjectlist(&var, search);
1244 if (pp == 0) break;
1245 if (namesame(pp, name) == 0) break;
1246 }
1247
1248 /* if the attribute exists, change its value */
1249 if (pp != 0)
1250 {
1251 if ((var->type&VCANTSET) != 0)
1252 {
1253 db_donextchangequietly = FALSE;
1254 return((VARIABLE *)db_error(DBVARFIXED|DBSETVAL));
1255 }
1256
1257 /* handle change control, constraint, and broadcast */
1258 if (!db_donextchangequietly && !db_dochangesquietly)
1259 {
1260 /* tell constraint system about killed variable */
1261 (*el_curconstraint->killvariable)(addr, type, var->key, var->addr, var->type, var->textdescript);
1262
1263 /* record a change for removal of the old variable */
1264 (void)db_change((INTBIG)addr, VARIABLEKILL, type, var->key,
1265 var->addr, var->type, var->textdescript[0], var->textdescript[1]);
1266 }
1267
1268 #ifdef DEBUGMEMORY
1269 if (db_setvalvar(var, newaddr, newtype, db_whichcluster(addr, type), module, line))
1270 #else
1271 if (db_setvalvar(var, newaddr, newtype, db_whichcluster(addr, type)))
1272 #endif
1273 {
1274 db_donextchangequietly = FALSE;
1275 return((VARIABLE *)db_error(DBNOMEM|DBSETVAL));
1276 }
1277
1278 /* handle change control, constraint, and broadcast */
1279 if (!db_donextchangequietly && !db_dochangesquietly)
1280 {
1281 /* tell constraint system about new variable */
1282 (*el_curconstraint->newvariable)(addr, type, var->key, var->type);
1283
1284 (void)db_change((INTBIG)addr, VARIABLENEW, type, var->key, var->type, 0, 0, 0);
1285 }
1286 db_donextchangequietly = FALSE;
1287
1288 /* if nodeproto name changed, rebuild hash table of nodeproto names */
1289 if (type == VNODEPROTO && namesame(name, x_("protoname")) == 0)
1290 db_buildnodeprotohashtable(((NODEPROTO *)addr)->lib);
1291
1292 /* if portproto name changed, rebuild hash table of portproto names */
1293 if (type == VPORTPROTO && namesame(name, x_("protoname")) == 0)
1294 db_buildportprotohashtable(((PORTPROTO *)addr)->parent);
1295
1296 /* mark a change to the database */
1297 if (type != VTOOL || addr != (INTBIG)us_tool) db_changetimestamp++;
1298 return(var);
1299 }
1300
1301 /* create new variable: first ensure the name starts with a letter */
1302 if (!isalpha(*name))
1303 {
1304 db_donextchangequietly = FALSE;
1305 return((VARIABLE *)db_error(DBBADNAME|DBSETVAL));
1306 }
1307
1308 /* get the key of the new name */
1309 key = makekey(name);
1310 if (key == -1)
1311 {
1312 db_donextchangequietly = FALSE;
1313 return(NOVARIABLE);
1314 }
1315
1316 /* set the variable by its key */
1317 #ifdef DEBUGMEMORY
1318 return(_setvalkey(addr, type, key, newaddr, newtype, module, line));
1319 #else
1320 return(setvalkey(addr, type, key, newaddr, newtype));
1321 #endif
1322 }
1323
1324 /*
1325 * routine to set the variable on the object whose address is "addr", type
1326 * is "type", and key is "key". The variable is set to "newaddr" with type
1327 * "newtype". The routine returns the variable address (NOVARIABLE on error).
1328 */
1329 #ifdef DEBUGMEMORY
_setvalkey(INTBIG addr,INTBIG type,INTBIG key,INTBIG newaddr,INTBIG newtype,CHAR * module,INTBIG line)1330 VARIABLE *_setvalkey(INTBIG addr, INTBIG type, INTBIG key, INTBIG newaddr,
1331 INTBIG newtype, CHAR *module, INTBIG line)
1332 #else
1333 VARIABLE *setvalkey(INTBIG addr, INTBIG type, INTBIG key, INTBIG newaddr,
1334 INTBIG newtype)
1335 #endif
1336 {
1337 REGISTER INTBIG med;
1338 VARIABLE **myfirstvar;
1339 INTSML *mynumvar;
1340
1341 /* get the attribute list pointers */
1342 if (db_getvarptr(addr, type, &myfirstvar, &mynumvar))
1343 {
1344 db_donextchangequietly = FALSE;
1345 return(NOVARIABLE);
1346 }
1347
1348 /* binary search variable space for the key */
1349 med = db_binarysearch(*mynumvar, *myfirstvar, key);
1350 if (med >= 0)
1351 {
1352 if (((*myfirstvar)[med].type&VCANTSET) != 0)
1353 {
1354 db_donextchangequietly = FALSE;
1355 return((VARIABLE *)db_error(DBVARFIXED|DBSETVALKEY));
1356 }
1357
1358 /* handle change control, constraint, and broadcast */
1359 if (!db_donextchangequietly && !db_dochangesquietly)
1360 {
1361 /* tell constraint system about killed variable */
1362 (*el_curconstraint->killvariable)(addr, type, key,
1363 (*myfirstvar)[med].addr, (*myfirstvar)[med].type, (*myfirstvar)[med].textdescript);
1364
1365 /* record a change for removal of the old variable */
1366 (void)db_change((INTBIG)addr, VARIABLEKILL, type, key,
1367 (*myfirstvar)[med].addr, (*myfirstvar)[med].type, (*myfirstvar)[med].textdescript[0],
1368 (*myfirstvar)[med].textdescript[1]);
1369 }
1370 }
1371
1372 /* set the new variable */
1373 #ifdef DEBUGMEMORY
1374 if (db_setvalkey(mynumvar, myfirstvar, med, key, newaddr, newtype, db_whichcluster(addr, type),
1375 module, line))
1376 #else
1377 if (db_setvalkey(mynumvar, myfirstvar, med, key, newaddr, newtype,
1378 db_whichcluster(addr, type)))
1379 #endif
1380 {
1381 db_donextchangequietly = FALSE;
1382 return((VARIABLE *)db_error(DBNOMEM|DBSETVALKEY));
1383 }
1384
1385 /* handle change control, constraint, and broadcast */
1386 if (!db_donextchangequietly && !db_dochangesquietly)
1387 {
1388 /* tell constraint system about new variable */
1389 (*el_curconstraint->newvariable)(addr, type, key, newtype);
1390
1391 /* record the change */
1392 (void)db_change((INTBIG)addr, VARIABLENEW, type, key, newtype, 0, 0, 0);
1393 }
1394 db_donextchangequietly = FALSE;
1395 if (med < 0) med = -1 - med;
1396
1397 /* mark a change to the database */
1398 if (type != VTOOL || addr != (INTBIG)us_tool) db_changetimestamp++;
1399 return(&(*myfirstvar)[med]);
1400 }
1401
1402 /*
1403 * routine to copy the variables from object "fromaddr" (which has type
1404 * "fromtype") to object "toaddr" (which has type "totype"). Returns true
1405 * on error. If "uniquenames" is true, make sure nodes and arcs have unique names.
1406 */
copyvars(INTBIG fromaddr,INTBIG fromtype,INTBIG toaddr,INTBIG totype,BOOLEAN uniquenames)1407 BOOLEAN copyvars(INTBIG fromaddr, INTBIG fromtype, INTBIG toaddr, INTBIG totype, BOOLEAN uniquenames)
1408 {
1409 REGISTER INTSML i;
1410 REGISTER INTBIG key, addr, type;
1411 INTBIG lx, hx, ly, hy;
1412 REGISTER CHAR *objname, *newname;
1413 REGISTER GEOM *geom;
1414 REGISTER NODEPROTO *np;
1415 REGISTER NODEINST *ni;
1416 REGISTER ARCINST *ai;
1417 INTSML *numvar;
1418 VARIABLE **firstvar;
1419 REGISTER VARIABLE *var;
1420
1421 if (db_getvarptr(fromaddr, fromtype, &firstvar, &numvar)) return(TRUE);
1422
1423 for(i=0; i<(*numvar); i++)
1424 {
1425 key = (*firstvar)[i].key;
1426 addr = (*firstvar)[i].addr;
1427 type = (*firstvar)[i].type;
1428 if (uniquenames)
1429 {
1430 if (totype == VNODEINST && key == el_node_name_key)
1431 {
1432 /* if the node name wasn't displayable, do not copy */
1433 if ((type&VDISPLAY) == 0) continue;
1434
1435 /* find a unique node name */
1436 ni = (NODEINST *)toaddr;
1437 objname = (CHAR *)addr;
1438 newname = us_uniqueobjectname(objname, ni->parent, VNODEINST, ni);
1439 if (namesame(newname, objname) != 0) addr = (INTBIG)newname;
1440 } else if (totype == VARCINST && key == el_arc_name_key)
1441 {
1442 /* if the arc name wasn't displayable, do not copy */
1443 if ((type&VDISPLAY) == 0) continue;
1444
1445 /* find a unique node name */
1446 ai = (ARCINST *)toaddr;
1447 objname = (CHAR *)addr;
1448 newname = us_uniqueobjectname(objname, ai->parent, VARCINST, ai);
1449 if (namesame(newname, objname) != 0) addr = (INTBIG)newname;
1450 }
1451 }
1452
1453 var = setvalkey(toaddr, totype, key, addr, type);
1454 if (var == NOVARIABLE) return(TRUE);
1455 TDCOPY(var->textdescript, (*firstvar)[i].textdescript);
1456 }
1457
1458 /* variables may affect geometry size */
1459 if (totype == VNODEINST || totype == VARCINST)
1460 {
1461 if (totype == VNODEINST)
1462 {
1463 ni = (NODEINST *)toaddr;
1464 geom = ni->geom;
1465 np = ni->parent;
1466 } else
1467 {
1468 ai = (ARCINST *)toaddr;
1469 geom = ai->geom;
1470 np = ai->parent;
1471 }
1472 boundobj(geom, &lx, &hx, &ly, &hy);
1473 if (lx != geom->lowx || hx != geom->highx ||
1474 ly != geom->lowy || hy != geom->highy)
1475 updategeom(geom, np);
1476 }
1477 return(FALSE);
1478 }
1479
1480 /*********************** SETTING ENTRIES IN VARIABLES ***********************/
1481
1482 /*
1483 * routine to set an entry in the array variable "name" in object "addr"
1484 * which is of type "type". Entry "aindex" is set to "newaddr".
1485 * The routine returns true upon error.
1486 */
1487 #ifdef DEBUGMEMORY
_setind(INTBIG addr,INTBIG type,CHAR * name,INTBIG aindex,INTBIG newaddr,CHAR * module,INTBIG line)1488 BOOLEAN _setind(INTBIG addr, INTBIG type, CHAR *name, INTBIG aindex, INTBIG newaddr,
1489 CHAR *module, INTBIG line)
1490 #else
1491 BOOLEAN setind(INTBIG addr, INTBIG type, CHAR *name, INTBIG aindex, INTBIG newaddr)
1492 #endif
1493 {
1494 VARIABLE *var;
1495 REGISTER CHAR *pp;
1496 REGISTER INTBIG search;
1497 REGISTER BOOLEAN retval;
1498
1499 search = initobjlist(addr, type, FALSE);
1500 if (search == 0)
1501 {
1502 db_donextchangequietly = FALSE;
1503 return(TRUE);
1504 }
1505 for(;;)
1506 {
1507 pp = nextobjectlist(&var, search);
1508 if (pp == 0) break;
1509 if (namesame(pp, name) == 0) break;
1510 }
1511
1512 /* variable must exist */
1513 if (pp == 0)
1514 {
1515 db_donextchangequietly = FALSE;
1516 (void)db_error(DBNOVAR|DBSETIND);
1517 return(TRUE);
1518 }
1519
1520 if ((var->type&VCANTSET) != 0)
1521 {
1522 db_donextchangequietly = FALSE;
1523 (void)db_error(DBVARFIXED|DBSETIND);
1524 return(TRUE);
1525 }
1526
1527 #ifdef DEBUGMEMORY
1528 retval = db_setindvar(addr, type, var, aindex, newaddr, module, line);
1529 #else
1530 retval = db_setindvar(addr, type, var, aindex, newaddr);
1531 #endif
1532 db_donextchangequietly = FALSE;
1533 if (retval)
1534 {
1535 (void)db_error(DBNOMEM|DBSETIND);
1536 return(TRUE);
1537 }
1538
1539 /* mark a change to the database */
1540 db_changetimestamp++;
1541 return(FALSE);
1542 }
1543
1544 /*
1545 * routine to set an entry in the array variable whose key is "key" in object
1546 * "addr" which is of type "type". Entry "aindex" is set to "newaddr".
1547 * The routine returns nonzero upon error.
1548 */
1549 #ifdef DEBUGMEMORY
_setindkey(INTBIG addr,INTBIG type,INTBIG key,INTBIG aindex,INTBIG newaddr,CHAR * module,INTBIG line)1550 BOOLEAN _setindkey(INTBIG addr, INTBIG type, INTBIG key, INTBIG aindex, INTBIG newaddr,
1551 CHAR *module, INTBIG line)
1552 #else
1553 BOOLEAN setindkey(INTBIG addr, INTBIG type, INTBIG key, INTBIG aindex, INTBIG newaddr)
1554 #endif
1555 {
1556 VARIABLE **myfirstvar;
1557 INTSML *mynumvar;
1558 REGISTER INTBIG med;
1559 REGISTER BOOLEAN retval;
1560
1561 /* get the attribute list into the globals */
1562 if (db_getvarptr(addr, type, &myfirstvar, &mynumvar))
1563 {
1564 db_donextchangequietly = FALSE;
1565 return(TRUE);
1566 }
1567
1568 /* binary search variable space for the key */
1569 med = db_binarysearch(*mynumvar, *myfirstvar, key);
1570
1571 /* variable must exist */
1572 if (med < 0)
1573 {
1574 db_donextchangequietly = FALSE;
1575 (void)db_error(DBNOVAR|DBSETINDKEY);
1576 return(TRUE);
1577 }
1578
1579 if (((*myfirstvar)[med].type&VCANTSET) != 0)
1580 {
1581 db_donextchangequietly = FALSE;
1582 (void)db_error(DBVARFIXED|DBSETINDKEY);
1583 return(TRUE);
1584 }
1585
1586 /* set the variable */
1587 #ifdef DEBUGMEMORY
1588 retval = db_setindvar(addr, type, &(*myfirstvar)[med], aindex, newaddr, module, line);
1589 #else
1590 retval = db_setindvar(addr, type, &(*myfirstvar)[med], aindex, newaddr);
1591 #endif
1592 db_donextchangequietly = FALSE;
1593 if (retval != 0)
1594 {
1595 (void)db_error(DBNOMEM|DBSETINDKEY);
1596 return(TRUE);
1597 }
1598
1599 /* mark a change to the database */
1600 db_changetimestamp++;
1601 return(FALSE);
1602 }
1603
1604 /*
1605 * routine to insert an entry in the array variable "name" in object "addr"
1606 * which is of type "type". Entry "aindex" is set to "newaddr" and all entries
1607 * equal to or greater than "aindex" are moved up (i.e. "newaddr" is inserted
1608 * before entry "aindex"). The routine returns true upon error.
1609 */
insind(INTBIG addr,INTBIG type,CHAR * name,INTBIG aindex,INTBIG newaddr)1610 BOOLEAN insind(INTBIG addr, INTBIG type, CHAR *name, INTBIG aindex, INTBIG newaddr)
1611 {
1612 VARIABLE *var;
1613 REGISTER CHAR *pp;
1614 REGISTER INTBIG search;
1615 REGISTER BOOLEAN retval;
1616
1617 search = initobjlist(addr, type, FALSE);
1618 if (search == 0)
1619 {
1620 db_donextchangequietly = FALSE;
1621 return(TRUE);
1622 }
1623 for(;;)
1624 {
1625 pp = nextobjectlist(&var, search);
1626 if (pp == 0) break;
1627 if (namesame(pp, name) == 0) break;
1628 }
1629
1630 /* variable must exist */
1631 if (pp == 0)
1632 {
1633 db_donextchangequietly = FALSE;
1634 (void)db_error(DBNOVAR|DBINSIND);
1635 return(TRUE);
1636 }
1637
1638 /* cannot insert if variable is frozen or is in C data structures */
1639 if ((var->type&VCANTSET) != 0 || (var->type&VCREF) != 0)
1640 {
1641 db_donextchangequietly = FALSE;
1642 (void)db_error(DBVARFIXED|DBINSIND);
1643 return(TRUE);
1644 }
1645
1646 retval = db_insindvar(addr, type, var, aindex, newaddr);
1647 db_donextchangequietly = FALSE;
1648 if (retval != 0)
1649 {
1650 (void)db_error(DBNOMEM|DBINSIND);
1651 return(TRUE);
1652 }
1653
1654 /* mark a change to the database */
1655 db_changetimestamp++;
1656 return(FALSE);
1657 }
1658
1659 /*
1660 * routine to insert an entry in the array variable whose key is "key" in object
1661 * "addr" which is of type "type". Entry "aindex" is set to "newaddr" and all entries
1662 * equal to or greater than "aindex" are moved up (i.e. "newaddr" is inserted
1663 * before entry "aindex"). The routine returns true upon error.
1664 */
insindkey(INTBIG addr,INTBIG type,INTBIG key,INTBIG aindex,INTBIG newaddr)1665 BOOLEAN insindkey(INTBIG addr, INTBIG type, INTBIG key, INTBIG aindex, INTBIG newaddr)
1666 {
1667 VARIABLE **myfirstvar;
1668 INTSML *mynumvar;
1669 REGISTER INTBIG med;
1670 REGISTER BOOLEAN retval;
1671
1672 /* get the attribute list into the globals */
1673 if (db_getvarptr(addr, type, &myfirstvar, &mynumvar))
1674 {
1675 db_donextchangequietly = FALSE;
1676 return(TRUE);
1677 }
1678
1679 /* binary search variable space for the key */
1680 med = db_binarysearch(*mynumvar, *myfirstvar, key);
1681
1682 /* variable must exist */
1683 if (med < 0)
1684 {
1685 db_donextchangequietly = FALSE;
1686 (void)db_error(DBNOVAR|DBINSINDKEY);
1687 return(TRUE);
1688 }
1689
1690 /* cannot insert if variable is frozen or is in C data structures */
1691 if (((*myfirstvar)[med].type&VCANTSET) != 0 || ((*myfirstvar)[med].type&VCREF) != 0)
1692 {
1693 db_donextchangequietly = FALSE;
1694 (void)db_error(DBVARFIXED|DBINSINDKEY);
1695 return(TRUE);
1696 }
1697
1698 /* set the variable */
1699 retval = db_insindvar(addr, type, &(*myfirstvar)[med], aindex, newaddr);
1700 db_donextchangequietly = FALSE;
1701 if (retval != 0)
1702 {
1703 (void)db_error(DBNOMEM|DBINSINDKEY);
1704 return(TRUE);
1705 }
1706
1707 /* mark a change to the database */
1708 db_changetimestamp++;
1709 return(FALSE);
1710 }
1711
1712 /*
1713 * routine to delete entry "aindex" in the array variable "name" in object "addr"
1714 * which is of type "type". The routine returns true upon error.
1715 */
delind(INTBIG addr,INTBIG type,CHAR * name,INTBIG aindex)1716 BOOLEAN delind(INTBIG addr, INTBIG type, CHAR *name, INTBIG aindex)
1717 {
1718 VARIABLE *var;
1719 REGISTER CHAR *pp;
1720 REGISTER INTBIG search;
1721 REGISTER BOOLEAN retval;
1722
1723 search = initobjlist(addr, type, FALSE);
1724 if (search == 0)
1725 {
1726 db_donextchangequietly = FALSE;
1727 return(TRUE);
1728 }
1729 for(;;)
1730 {
1731 pp = nextobjectlist(&var, search);
1732 if (pp == 0) break;
1733 if (namesame(pp, name) == 0) break;
1734 }
1735
1736 /* variable must exist */
1737 if (pp == 0)
1738 {
1739 db_donextchangequietly = FALSE;
1740 (void)db_error(DBNOVAR|DBDELIND);
1741 return(TRUE);
1742 }
1743
1744 if ((var->type&VCANTSET) != 0)
1745 {
1746 db_donextchangequietly = FALSE;
1747 (void)db_error(DBVARFIXED|DBDELIND);
1748 return(TRUE);
1749 }
1750
1751 retval = db_delindvar(addr, type, var, aindex);
1752 db_donextchangequietly = FALSE;
1753 if (retval)
1754 {
1755 (void)db_error(DBNOMEM|DBDELIND);
1756 return(TRUE);
1757 }
1758
1759 /* mark a change to the database */
1760 db_changetimestamp++;
1761 return(FALSE);
1762 }
1763
1764 /*
1765 * routine to delete entry "aindex" in the array variable whose key is "key" in object
1766 * "addr" which is of type "type". The routine returns true upon error.
1767 */
delindkey(INTBIG addr,INTBIG type,INTBIG key,INTBIG aindex)1768 BOOLEAN delindkey(INTBIG addr, INTBIG type, INTBIG key, INTBIG aindex)
1769 {
1770 VARIABLE **myfirstvar;
1771 INTSML *mynumvar;
1772 REGISTER INTBIG med;
1773 REGISTER BOOLEAN retval;
1774
1775 /* get the attribute list into the globals */
1776 if (db_getvarptr(addr, type, &myfirstvar, &mynumvar))
1777 {
1778 db_donextchangequietly = FALSE;
1779 return(TRUE);
1780 }
1781
1782 /* binary search variable space for the key */
1783 med = db_binarysearch(*mynumvar, *myfirstvar, key);
1784
1785 /* variable must exist */
1786 if (med < 0)
1787 {
1788 db_donextchangequietly = FALSE;
1789 (void)db_error(DBNOVAR|DBDELINDKEY);
1790 return(TRUE);
1791 }
1792
1793 if (((*myfirstvar)[med].type&VCANTSET) != 0)
1794 {
1795 db_donextchangequietly = FALSE;
1796 (void)db_error(DBVARFIXED|DBDELINDKEY);
1797 return(TRUE);
1798 }
1799
1800 /* set the variable */
1801 retval = db_delindvar(addr, type, &(*myfirstvar)[med], aindex);
1802 db_donextchangequietly = FALSE;
1803 if (retval != 0)
1804 {
1805 (void)db_error(DBNOMEM|DBDELINDKEY);
1806 return(TRUE);
1807 }
1808
1809 /* mark a change to the database */
1810 db_changetimestamp++;
1811 return(FALSE);
1812 }
1813
1814 /************************* OPTION VARIABLES *************************/
1815
1816 /*
1817 * Many user-settable options are stored in variables. When libraries are saved,
1818 * these variables are saved, unless they are marked "VDONTSAVE". To handle this
1819 * situation properly, the library "options" is saved with all option variables
1820 * intact, but all other libraries are saved with the option variables removed.
1821 * The routines below "remove" the option variables (by marking them VDONTSAVE)
1822 * and restore them after the library is written.
1823 */
1824
1825 #if COMTOOL
1826 extern TOOL *com_tool;
1827 #endif
1828 #if DRCTOOL
1829 extern TOOL *dr_tool;
1830 #endif
1831 #if ERCTOOL
1832 extern TOOL *erc_tool;
1833 #endif
1834 #if LOGEFFTOOL
1835 extern TOOL *le_tool;
1836 #endif
1837 #if ROUTTOOL
1838 extern TOOL *ro_tool;
1839 #endif
1840 #if SCTOOL
1841 extern TOOL *sc_tool;
1842 #endif
1843 #if SIMTOOL
1844 extern TOOL *sim_tool;
1845 #endif
1846 #if VHDLTOOL
1847 extern TOOL *vhdl_tool;
1848 #endif
1849
1850 static OPTIONVARPROTO db_ovpcopyright[] = /* FILE: IO Options: Library Options */
1851 {
1852 {0, 0, (INTBIG*)&us_tool, VTOOL, 0, x_("USER_copyright_file"), 0, 0, 0, 0, N_("Copyright file")},
1853 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, x_("")}
1854 };
1855 static OPTIONVARPROTO db_ovpforeignfilelibrary[] = /* FILE: IO Options: Copyright Options */
1856 {
1857 {0, 0, (INTBIG*)&io_tool, VTOOL, 0, x_("IO_state"), 0, 0, BINOUTBACKUP, 0, N_("Library file backup")},
1858 {0, 0, (INTBIG*)&io_tool, VTOOL, 0, x_("IO_state"), 0, 0, CHECKATWRITE, 0, N_("Check database after write")},
1859 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, x_("")}
1860 };
1861 static OPTIONVARPROTO db_ovpforeignfilecif[] = /* FILE: IO Options: CIF Options */
1862 {
1863 {0, 0, (INTBIG*)&io_tool, VTOOL, 0, x_("IO_state"), 0, 0, CIFOUTEXACT, 0, N_("Output mimics display")},
1864 {0, 0, (INTBIG*)&io_tool, VTOOL, 0, x_("IO_state"), 0, 0, CIFOUTMERGE, 0, N_("Output merges boxes")},
1865 {0, 0, (INTBIG*)&io_tool, VTOOL, 0, x_("IO_state"), 0, 0, CIFINSQUARE, 0, N_("Input squares wires")},
1866 {0, 0, (INTBIG*)&io_tool, VTOOL, 0, x_("IO_state"), 0, 0, CIFOUTNOTOPCALL, 0, N_("Output Instantiates top level")},
1867 {0, 0, (INTBIG*)&io_tool, VTOOL, 0, x_("IO_state"), 0, 0, CIFOUTNORMALIZE, 0, N_("Normalize coordinates")},
1868 {0, 0, (INTBIG*)&io_tool, VTOOL, 0, x_("IO_state"), 0, 0, 0, CIFRESHIGH, N_("Resolution check")},
1869 {0, 0, 0, VTECHNOLOGY, 0, x_("IO_cif_layer_names"), 0, 0, 0, 0, N_("CIF layers")},
1870 {0, 0, 0, VTECHNOLOGY, 0, x_("IO_cif_resolution"), 0, 0, 0, 0, N_("CIF resolution")},
1871 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, x_("")}
1872 };
1873 static OPTIONVARPROTO db_ovpforeignfilegds[] = /* FILE: IO Options: GDS Options */
1874 {
1875 {0, 0, (INTBIG*)&io_tool, VTOOL, 0, x_("IO_state"), 0, 0, GDSINTEXT, 0, N_("Input includes text")},
1876 {0, 0, (INTBIG*)&io_tool, VTOOL, 0, x_("IO_state"), 0, 0, GDSINEXPAND, 0, N_("Input expands cells")},
1877 {0, 0, (INTBIG*)&io_tool, VTOOL, 0, x_("IO_state"), 0, 0, GDSINARRAYS, 0, N_("Input instantiates arrays")},
1878 {0, 0, (INTBIG*)&io_tool, VTOOL, 0, x_("IO_state"), 0, 0, GDSOUTMERGE, 0, N_("Output merges boxes")},
1879 {0, 0, (INTBIG*)&io_tool, VTOOL, 0, x_("IO_state"), 0, 0, GDSINIGNOREUKN, 0, N_("Input ignores unknown layers")},
1880 {0, 0, (INTBIG*)&io_tool, VTOOL, 0, x_("IO_state"), 0, 0, 0, GDSOUTPINS, N_("Output generates pins at exports")},
1881 {0, 0, (INTBIG*)&io_tool, VTOOL, 0, x_("IO_state"), 0, 0, 0, GDSOUTUC, N_("Output All Upper Case")},
1882 {0, 0, 0, VTECHNOLOGY, 0, x_("IO_gds_layer_numbers"), 0, 0, 0, 0, N_("GDS layers")},
1883 {0, 0, 0, VTECHNOLOGY, 0, x_("IO_gds_export_layer"), 0, 0, 0, 0, N_("Output export layer")},
1884 {0, 0, (INTBIG*)&io_tool, VTOOL, 0, x_("IO_curve_resolution"), 0, 0, 0, 0, N_("Maximum arc angle")},
1885 {0, 0, (INTBIG*)&io_tool, VTOOL, 0, x_("IO_curve_sag"), 0, 0, 0, 0, N_("Maximum arc sag")},
1886 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, x_("")}
1887 };
1888 static OPTIONVARPROTO db_ovpforeignfiledxf[] = /* FILE: IO Options: DXF Options */
1889 {
1890 {0, 0, (INTBIG*)&io_tool, VTOOL, 0, x_("IO_state"), 0, 0, DXFFLATTENINPUT, 0, N_("Input flattens hierarchy")},
1891 {0, 0, (INTBIG*)&io_tool, VTOOL, 0, x_("IO_state"), 0, 0, DXFALLLAYERS, 0, N_("Input reads all layers")},
1892 {0, 0, (INTBIG*)&io_tool, VTOOL, 0, x_("IO_dxf_units"), 0, 0, 0, 0, N_("DXF scale")},
1893 {0, 0, 0, VTECHNOLOGY, 0, x_("IO_dxf_layer_names"), 0, 0, 0, 0, N_("DXF layers")},
1894 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, x_("")}
1895 };
1896 static OPTIONVARPROTO db_ovpforeignfileedif[] = /* FILE: IO Options: EDIF Options */
1897 {
1898 {0, 0, (INTBIG*)&io_tool, VTOOL, 0, x_("IO_state"), 0, 0, EDIFSCHEMATIC, 0, N_("Use schematic view")},
1899 {0, 0, (INTBIG*)&io_tool, VTOOL, 0, x_("IO_edif_input_scale"), 0, 0, 0, 0, N_("Input scale")},
1900 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, x_("")}
1901 };
1902 #ifdef FORCECADENCE
1903 static OPTIONVARPROTO db_ovpforeignfileskill[] = /* FILE: IO Options: SKILL Options */
1904 {
1905 {0, 0, (INTBIG*)&io_tool, VTOOL, 0, x_("IO_state"), 0, 0, SKILLNOHIER, 0, N_("Do not include subcells")},
1906 {0, 0, (INTBIG*)&io_tool, VTOOL, 0, x_("IO_state"), 0, 0, 0, SKILLFLATHIER, N_("Flatten hierarchy")},
1907 {0, 0, 0, VTECHNOLOGY, 0, x_("IO_skill_layer_names"), 0, 0, 0, 0, N_("SKILL layers")},
1908 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, x_("")}
1909 };
1910 #endif
1911 static OPTIONVARPROTO db_ovpforeignfilecdl[] = /* FILE: IO Options: CDL Options */
1912 {
1913 {0, 0, (INTBIG*)&io_tool, VTOOL, 0, x_("IO_cdl_library_name"), 0, 0, 0, 0, N_("Cadence Library Name")},
1914 {0, 0, (INTBIG*)&io_tool, VTOOL, 0, x_("IO_cdl_library_path"), 0, 0, 0, 0, N_("Cadence Library Path")},
1915 {0, 0, (INTBIG*)&io_tool, VTOOL, 0, x_("IO_state"), 0, 0, 0, CDLNOBRACKETS, N_("Convert brackets")},
1916 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, x_("")}
1917 };
1918 static OPTIONVARPROTO db_ovpforeignfiledef[] = /* FILE: IO Options: DEF Options */
1919 {
1920 {0, 0, (INTBIG*)&io_tool, VTOOL, 0, x_("IO_state"), 0, 0, DEFNOLOGICAL, 0, N_("Place logical interconnect")},
1921 {0, 0, (INTBIG*)&io_tool, VTOOL, 0, x_("IO_state"), 0, 0, DEFNOPHYSICAL, 0, N_("Place physical interconnect")},
1922 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, x_("")}
1923 };
1924 static OPTIONVARPROTO db_ovpforeignfilesue[] = /* FILE: IO Options: Sue Options */
1925 {
1926 {0, 0, (INTBIG*)&io_tool, VTOOL, 0, x_("IO_state"), 0, 0, 0, SUEUSE4PORTTRANS, N_("Make 4-port transistors")},
1927 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, x_("")}
1928 };
1929
1930 static OPTIONVARPROTO db_ovpprint[] = /* FILE: Print Options */
1931 {
1932 /* {0, 0, 0, VNODEPROTO, 0, "IO_postscript_EPS_scale", 0, 0, 0, 0, N_("")}, *** cell specific ***/
1933 /* {0, 0, 0, VNODEPROTO, 0, "IO_postscript_filename", 0, 0, 0, 0, N_("")}, *** cell specific ***/
1934 {0, 0, (INTBIG*)&io_tool, VTOOL, 0, x_("IO_state"), 0, 0, PLOTFOCUS|PLOTFOCUSDPY, 0, N_("Area to plot")},
1935 {0, 0, (INTBIG*)&io_tool, VTOOL, 0, x_("IO_state"), 0, 0, PLOTDATES, 0, N_("Plot date in corner")},
1936 {0, 0, (INTBIG*)&io_tool, VTOOL, 0, x_("IO_state"), 0, 0, EPSPSCRIPT, 0, N_("Encapsulated PostScript")},
1937 {0, 0, (INTBIG*)&io_tool, VTOOL, 0, x_("IO_state"), 0, 0, HPGL2, 0, N_("Write HPGL/2")},
1938 {0, 0, (INTBIG*)&io_tool, VTOOL, 0, x_("IO_state"), 0, 0, PSCOLOR1|PSCOLOR2, 0, N_("Color PostScript")},
1939 {0, 0, (INTBIG*)&io_tool, VTOOL, 0, x_("IO_state"), 0, 0, PSPLOTTER, 0, N_("Printer/plotter")},
1940 {0, 0, (INTBIG*)&io_tool, VTOOL, 0, x_("IO_state"), 0, 0, PSROTATE, 0, N_("Rotate plot 90 degrees")},
1941 {0, 0, (INTBIG*)&io_tool, VTOOL, 0, x_("IO_state"), 0, 0, 0, PSAUTOROTATE, N_("Auto-rotate plot to fit")},
1942 {0, 0, (INTBIG*)&io_tool, VTOOL, 0, x_("IO_postscript_width"), 0, 0, 0, 0, N_("Page width")},
1943 {0, 0, (INTBIG*)&io_tool, VTOOL, 0, x_("IO_postscript_height"), 0, 0, 0, 0, N_("Page height")},
1944 {0, 0, (INTBIG*)&io_tool, VTOOL, 0, x_("IO_postscript_margin"), 0, 0, 0, 0, N_("Page margin")},
1945 {0, 0, (INTBIG*)&io_tool, VTOOL, 0, x_("IO_print_resolution_scale"), 0, 0, 0, 0, N_("Print and Copy resolution factor")},
1946 {0, 0, (INTBIG*)&io_tool, VTOOL, 0, x_("IO_hpgl2_scale"), 0, 0, 0, 0, N_("HPGL/2 units per pixel")},
1947 {0, 0, (INTBIG*)&io_tool, VTOOL, 0, x_("IO_default_printer"), 0, 0, 0, 0, N_("Default printer")},
1948 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, x_("")}
1949 };
1950 static OPTIONVARPROTO db_ovpnewnode[] = /* EDIT: New Node Options */
1951 {
1952 /* {0, 0, 0, VNODEPROTO, 0, "userbits", 0, 0, 0, 0, N_("")}, *** cell specific ***/
1953 {0, 0, (INTBIG*)&us_tool, VTOOL, 0, x_("USER_optionflags"), 0, 0, NOPRIMCHANGES, 0, N_("Disallow modification of locked primitives")},
1954 {0, 0, (INTBIG*)&us_tool, VTOOL, 0, x_("USER_optionflags"), 0, 0, NOMOVEAFTERDUP, 0, N_("Move after duplicate")},
1955 {0, 0, (INTBIG*)&us_tool, VTOOL, 0, x_("USER_optionflags"), 0, 0, DUPCOPIESPORTS, 0, N_("Duplicate/array/extract copies exports")},
1956 {0, 0, 0, VNODEPROTO, 0, x_("NODE_size_default"), 0, 0, 0, 0, N_("Size of new primitives")},
1957 {0, 0, 0, VNODEPROTO, 0, x_("USER_placement_angle"), 0, 0, 0, 0, N_("Rotation of new nodes")},
1958 {0, 0, (INTBIG*)&us_tool, VTOOL, 0, x_("USER_placement_angle"), 0, 0, 0, 0, N_("Rotation of new nodes")},
1959 {0, 0, (INTBIG*)&net_tool, VTOOL, 0, x_("NET_node_abbreviations"), 0, 0, 0, 0, N_("Primitive function abbreviations")},
1960 {0, 0, (INTBIG*)&net_tool, VTOOL, 0, x_("NET_node_abbreviation_length"), 0, 0, 0, 0, N_("Length of cell abbreviations")},
1961 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, x_("")}
1962 };
1963 static OPTIONVARPROTO db_ovpselect[] = /* EDIT: Selection: Selection Options */
1964 {
1965 {0, 0, (INTBIG*)&us_tool, VTOOL, 0, x_("USER_optionflags"), 0, 0, NOINSTANCESELECT, 0, N_("Easy selection of cell instances")},
1966 {0, 0, (INTBIG*)&us_tool, VTOOL, 0, x_("USER_optionflags"), 0, 0, NOTEXTSELECT, 0, N_("Easy selection of annotation text")},
1967 {0, 0, (INTBIG*)&us_tool, VTOOL, 0, x_("USER_optionflags"), 0, 0, CENTEREDPRIMITIVES, 0, N_("Center-based primitives")},
1968 {0, 0, (INTBIG*)&us_tool, VTOOL, 0, x_("USER_optionflags"), 0, 0, MUSTENCLOSEALL, 0, N_("Dragging must enclose entire object")},
1969 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, x_("")}
1970 };
1971 static OPTIONVARPROTO db_ovpcell[] = /* CELLS: Cell Options */
1972 {
1973 /* {0, 0, 0, VNODEPROTO, 0, "userbits", 0, 0, 0, 0}, *** cell specific ***/
1974 {0, 0, (INTBIG*)&us_tool, VTOOL, 0, x_("USER_optionflags"), 0, 0, DRAWTINYCELLS, 0, N_("Tiny cell instances hashed out")},
1975 {0, 0, (INTBIG*)&us_tool, VTOOL, 0, x_("USER_optionflags"), 0, 0, CHECKDATE, 0, N_("Check cell dates during creation")},
1976 {0, 0, (INTBIG*)&us_tool, VTOOL, 0, x_("USER_optionflags"), 0, 0, AUTOSWITCHTECHNOLOGY, 0, N_("Switch technology to match current cell")},
1977 {0, 0, (INTBIG*)&us_tool, VTOOL, 0, x_("USER_optionflags"), 0, 0, CELLCENTERALWAYS, 0, N_("Place cell center in new cells")},
1978 {0, 0, (INTBIG*)&us_tool, VTOOL, 0, x_("USER_tiny_lambda_per_pixel"), 0, 0, 0, 0, N_("Hash out scale")},
1979 {0, 0, (INTBIG*)&us_tool, VTOOL, 0, x_("USER_facet_explorer_textsize"), 0, 0, 0, 0, N_("Cell explorer text size")},
1980 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, x_("")}
1981 };
1982 static OPTIONVARPROTO db_ovpframe[] = /* VIEW: Frame Options */
1983 {
1984 /* {0, 0, 0, VNODEPROTO, 0, "FACET_schematic_page_size", 0, 0, 0, 0, N_("")}, *** cell specific ***/
1985 {0, 0, (INTBIG*)&us_tool, VTOOL, 0, x_("USER_drawing_company_name"), 0, 0, 0, 0, N_("Company name")},
1986 {0, 0, (INTBIG*)&us_tool, VTOOL, 0, x_("USER_drawing_designer_name"), 0, 0, 0, 0, N_("Designer name")},
1987 {0, 0, (INTBIG*)&us_tool, VTOOL, 0, x_("USER_drawing_project_name"), 0, 0, 0, 0, N_("Project name")},
1988 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, x_("")}
1989 };
1990 static OPTIONVARPROTO db_ovpicon[] = /* VIEW: Icon Options */
1991 {
1992 {0, 0, (INTBIG*)&us_tool, VTOOL, 0, x_("USER_icon_style"), 0, 0, ICONSTYLESIDEIN, 0, N_("Inputs on which side")},
1993 {0, 0, (INTBIG*)&us_tool, VTOOL, 0, x_("USER_icon_style"), 0, 0, ICONSTYLESIDEOUT, 0, N_("Outputs on which side")},
1994 {0, 0, (INTBIG*)&us_tool, VTOOL, 0, x_("USER_icon_style"), 0, 0, ICONSTYLESIDEBIDIR, 0, N_("Bidir. on which side")},
1995 {0, 0, (INTBIG*)&us_tool, VTOOL, 0, x_("USER_icon_style"), 0, 0, ICONSTYLESIDEPOWER, 0, N_("Power on which side")},
1996 {0, 0, (INTBIG*)&us_tool, VTOOL, 0, x_("USER_icon_style"), 0, 0, ICONSTYLESIDEGROUND, 0, N_("Ground on which side")},
1997 {0, 0, (INTBIG*)&us_tool, VTOOL, 0, x_("USER_icon_style"), 0, 0, ICONSTYLESIDECLOCK, 0, N_("Clock on which side")},
1998 {0, 0, (INTBIG*)&us_tool, VTOOL, 0, x_("USER_icon_style"), 0, 0, ICONSTYLEPORTLOC, 0, N_("Export location")},
1999 {0, 0, (INTBIG*)&us_tool, VTOOL, 0, x_("USER_icon_style"), 0, 0, ICONSTYLEPORTSTYLE, 0, N_("Export style")},
2000 {0, 0, (INTBIG*)&us_tool, VTOOL, 0, x_("USER_icon_style"), 0, 0, ICONSTYLETECH, 0, N_("Export technology")},
2001 {0, 0, (INTBIG*)&us_tool, VTOOL, 0, x_("USER_icon_style"), 0, 0, ICONSTYLEDRAWNOLEADS, 0, N_("Draw leads")},
2002 {0, 0, (INTBIG*)&us_tool, VTOOL, 0, x_("USER_icon_style"), 0, 0, ICONSTYLEDRAWNOBODY, 0, N_("Draw body")},
2003 {0, 0, (INTBIG*)&us_tool, VTOOL, 0, x_("USER_icon_style"), 0, 0, ICONSTYLEREVEXPORT, 0, N_("Reverse export order")},
2004 {0, 0, (INTBIG*)&us_tool, VTOOL, 0, x_("USER_icon_style"), 0, 0, ICONINSTLOC, 0, N_("Instance location")},
2005 {0, 0, (INTBIG*)&us_tool, VTOOL, 0, x_("USER_icon_lead_length"), 0, 0, 0, 0, N_("Lead length")},
2006 {0, 0, (INTBIG*)&us_tool, VTOOL, 0, x_("USER_icon_lead_spacing"), 0, 0, 0, 0, N_("Lead spacing")},
2007 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, x_("")}
2008 };
2009 static OPTIONVARPROTO db_ovpnewarc[] = /* ARC: New Arc Options */
2010 {
2011 {0, 0, 0, VARCPROTO, 0, x_("ARC_width_default"), 0, 0, 0, 0, N_("Width")},
2012 {0, 0, (INTBIG*)&us_tool, VTOOL, 0, x_("USER_arc_style"), 0, 0, WANTFIX, 0, N_("All rigid")},
2013 {0, 0, (INTBIG*)&us_tool, VTOOL, 0, x_("USER_arc_style"), 0, 0, WANTFIXANG, 0, N_("All fixed angle")},
2014 {0, 0, (INTBIG*)&us_tool, VTOOL, 0, x_("USER_arc_style"), 0, 0, WANTCANTSLIDE, 0, N_("All slidable")},
2015 {0, 0, (INTBIG*)&us_tool, VTOOL, 0, x_("USER_arc_style"), 0, 0, WANTNEGATED, 0, N_("All negated")},
2016 {0, 0, (INTBIG*)&us_tool, VTOOL, 0, x_("USER_arc_style"), 0, 0, WANTNOEXTEND, 0, N_("All ends extended")},
2017 {0, 0, (INTBIG*)&us_tool, VTOOL, 0, x_("USER_arc_style"), 0, 0, WANTDIRECTIONAL, 0, N_("All directional")},
2018 {0, 0, (INTBIG*)&us_tool, VTOOL, 0, x_("USER_arc_style"), 0, 0, AANGLEINC, 0, N_("All angle")},
2019 {0, 0, 0, VARCPROTO, 0, x_("USER_arc_style"), 0, 0, WANTFIX, 0, N_("Arc rigid")},
2020 {0, 0, 0, VARCPROTO, 0, x_("USER_arc_style"), 0, 0, WANTFIXANG, 0, N_("Arc fixed angle")},
2021 {0, 0, 0, VARCPROTO, 0, x_("USER_arc_style"), 0, 0, WANTCANTSLIDE, 0, N_("Arc slidable")},
2022 {0, 0, 0, VARCPROTO, 0, x_("USER_arc_style"), 0, 0, WANTNEGATED, 0, N_("Arc negated")},
2023 {0, 0, 0, VARCPROTO, 0, x_("USER_arc_style"), 0, 0, WANTNOEXTEND, 0, N_("Arc ends extended")},
2024 {0, 0, 0, VARCPROTO, 0, x_("USER_arc_style"), 0, 0, WANTDIRECTIONAL, 0, N_("Arc directional")},
2025 {0, 0, 0, VARCPROTO, 0, x_("USER_arc_style"), 0, 0, AANGLEINC, 0, N_("Arc angle")},
2026 {0, 0, 0, VARCPROTO, 0, x_("ARC_Default_Pin"), 0, 0, 0, 0, N_("Pin")},
2027 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, x_("")}
2028 };
2029
2030 static OPTIONVARPROTO db_ovpgrid[] = /* WINDOWS: Grid Options */
2031 {
2032 {0, 0, (INTBIG*)&us_tool, VTOOL, 0, x_("USER_default_grid"), 0, 0, 0, 0, N_("Default grid spacing")},
2033 {0, 0, (INTBIG*)&us_tool, VTOOL, 0, x_("USER_grid_bold_spacing"), 0, 0, 0, 0, N_("Distance between bold dots")},
2034 {0, 0, (INTBIG*)&us_tool, VTOOL, 0, x_("USER_grid_floats"), 0, 0, 0, 0, N_("Align grid with circuit")},
2035 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, x_("")}
2036 };
2037 static OPTIONVARPROTO db_ovpalign[] = /* WINDOWS: Alignment Options */
2038 {
2039 {0, 0, (INTBIG*)&us_tool, VTOOL, 0, x_("USER_alignment_ratio"), 0, 0, 0, 0, N_("Alignment of cursor to grid")},
2040 {0, 0, (INTBIG*)&us_tool, VTOOL, 0, x_("USER_alignment_edge_ratio"), 0, 0, 0, 0, N_("Alignment of edges to grid")},
2041 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, x_("")}
2042 };
2043 static OPTIONVARPROTO db_ovplayvis[] = /* WINDOWS: Layer Visibility Options */
2044 {
2045 {0, 0, (INTBIG*)&us_tool, VTOOL, 0, x_("USER_optionflags"), 0, 0, HIDETXTNODE, 0, N_("Node text")},
2046 {0, 0, (INTBIG*)&us_tool, VTOOL, 0, x_("USER_optionflags"), 0, 0, HIDETXTARC, 0, N_("Arc text")},
2047 {0, 0, (INTBIG*)&us_tool, VTOOL, 0, x_("USER_optionflags"), 0, 0, HIDETXTPORT, 0, N_("Port text")},
2048 {0, 0, (INTBIG*)&us_tool, VTOOL, 0, x_("USER_optionflags"), 0, 0, HIDETXTEXPORT, 0, N_("Export text")},
2049 {0, 0, (INTBIG*)&us_tool, VTOOL, 0, x_("USER_optionflags"), 0, 0, HIDETXTNONLAY, 0, N_("Nonlayout text")},
2050 {0, 0, (INTBIG*)&us_tool, VTOOL, 0, x_("USER_optionflags"), 0, 0, HIDETXTINSTNAME, 0, N_("Instance names")},
2051 {0, 0, (INTBIG*)&us_tool, VTOOL, 0, x_("USER_optionflags"), 0, 0, HIDETXTCELL, 0, N_("Cell text")},
2052 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, x_("")}
2053 };
2054 static OPTIONVARPROTO db_ovplaypat[] = /* WINDOWS: Layer Display Options */
2055 {
2056 {0, 0, 0, VTECHNOLOGY, 1, x_("TECH_layer_pattern_"), 0, 0, 0, 0, N_("Layer pattern/color")},
2057 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, x_("")}
2058 };
2059 static OPTIONVARPROTO db_ovpcolor[] = /* WINDOWS: Color Options */
2060 {
2061 {0, 0, 0, VTECHNOLOGY, 0, x_("USER_print_colors"), 0, 0, 0, 0, N_("Print colors")},
2062 {0, 0, (INTBIG*)&us_tool, VTOOL, 0, x_("USER_colormap_red"), 0, 0, 0, 0, N_("Red colormap")},
2063 {0, 0, (INTBIG*)&us_tool, VTOOL, 0, x_("USER_colormap_green"), 0, 0, 0, 0, N_("Green colormap")},
2064 {0, 0, (INTBIG*)&us_tool, VTOOL, 0, x_("USER_colormap_blue"), 0, 0, 0, 0, N_("Blue colormap")},
2065 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, x_("")}
2066 };
2067 static OPTIONVARPROTO db_ovpport[] = /* WINDOWS: Port and Export Options */
2068 {
2069 {0, 0, (INTBIG*)&us_tool, VTOOL, 0, x_("USER_optionflags"), 0, 0, PORTLABELS, 0, N_("Ports (on instances)")},
2070 {0, 0, (INTBIG*)&us_tool, VTOOL, 0, x_("USER_optionflags"), 0, 0, EXPORTLABELS, 0, N_("Exports (in cells)")},
2071 {0, 0, (INTBIG*)&us_tool, VTOOL, 0, x_("USER_optionflags"), 0, 0, MOVENODEWITHEXPORT, 0, N_("Move node with export name")},
2072 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, x_("")}
2073 };
2074 static OPTIONVARPROTO db_ovptext[] = /* WINDOWS: Text Options */
2075 {
2076 {0, 0, (INTBIG*)&us_tool, VTOOL, 0, x_("USER_default_text_style"), 0, 0, 0, 0, N_("Text corner")},
2077 {0, 0, (INTBIG*)&us_tool, VTOOL, 0, x_("USER_default_text_smart_style"), 0, 0, 0, 0, N_("Smart placement")},
2078 {0, 0, (INTBIG*)&us_tool, VTOOL, 0, x_("USER_default_node_text_size"), 0, 0, 0, 0, N_("Node style")},
2079 {0, 0, (INTBIG*)&us_tool, VTOOL, 0, x_("USER_default_arc_text_size"), 0, 0, 0, 0, N_("Arc style")},
2080 {0, 0, (INTBIG*)&us_tool, VTOOL, 0, x_("USER_default_export_text_size"), 0, 0, 0, 0, N_("Export style")},
2081 {0, 0, (INTBIG*)&us_tool, VTOOL, 0, x_("USER_default_nonlayout_text_size"), 0, 0, 0, 0, N_("Nonlayout style")},
2082 {0, 0, (INTBIG*)&us_tool, VTOOL, 0, x_("USER_default_instance_text_size"), 0, 0, 0, 0, N_("Instance style")},
2083 {0, 0, (INTBIG*)&us_tool, VTOOL, 0, x_("USER_default_facet_text_size"), 0, 0, 0, 0, N_("Cell style")},
2084 {0, 0, (INTBIG*)&us_tool, VTOOL, 0, x_("USER_text_editor"), 0, 0, 0, 0, N_("Text editor")},
2085 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, x_("")}
2086 };
2087 static OPTIONVARPROTO db_ovp3d[] = /* WINDOWS: 3D Options */
2088 {
2089 {0, 0, (INTBIG*)&us_tool, VTOOL, 0, x_("USER_optionflags"), 0, 0, NO3DPERSPECTIVE, 0, N_("Use perspective")},
2090 {0, 0, 0, VTECHNOLOGY, 0, x_("TECH_layer_3dheight"), 0, 0, 0, 0, N_("Height")},
2091 {0, 0, 0, VTECHNOLOGY, 0, x_("TECH_layer_3dthickness"), 0, 0, 0, 0, N_("Thickness")},
2092 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, x_("")}
2093 };
2094 static OPTIONVARPROTO db_ovpmsgloc[] = /* WINDOWS: Save Messages Location */
2095 {
2096 {0, 0, (INTBIG*)&us_tool, VTOOL, 0, x_("USER_messages_position"), 0, 0, 0, 0, N_("Messages window location")},
2097 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, x_("")}
2098 };
2099 static OPTIONVARPROTO db_ovpgeneral[] = /* INFO: General Options */
2100 {
2101 {0, 0, (INTBIG*)&us_tool, VTOOL, 0, x_("USER_optionflags"), 0, 0, NODATEORVERSION, 0, N_("Include date and version in output files")},
2102 {0, 0, (INTBIG*)&us_tool, VTOOL, 0, x_("USER_optionflags"), 0, 0, NOPROMPTBEFOREWRITE, 0, N_("Show file-selection dialog before writing netlists")},
2103 {0, 0, (INTBIG*)&us_tool, VTOOL, 0, x_("USER_optionflags"), 0, 0, BEEPAFTERLONGJOB, 0, N_("Beep after long jobs")},
2104 {0, 0, (INTBIG*)&us_tool, VTOOL, 0, x_("USER_optionflags"), 0, 0, EXPANDEDDIALOGSDEF, 0, N_("Expandable dialogs default to fullsize")},
2105 {0, 0, (INTBIG*)&us_tool, VTOOL, 0, x_("USER_optionflags"), 0, 0, NOEXTRASOUND, 0, N_("Click sounds when arcs are created")},
2106 {0, 0, (INTBIG*)&us_tool, VTOOL, 0, x_("USER_maximum_errors"), 0, 0, 0, 0, N_("Maximum errors to report")},
2107 {0, 0, (INTBIG*)&us_tool, VTOOL, 0, x_("USER_motion_delay"), 0, 0, 0, 0, N_("Motion delay after selection")},
2108 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, x_("")}
2109 };
2110 static OPTIONVARPROTO db_ovpquickkey[] = /* INFO: Quick Key Options */
2111 {
2112 {0, 0, (INTBIG*)&us_tool, VTOOL, 0, x_("USER_quick_keys"), 0, 0, 0, 0, N_("Quick keys")},
2113 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, x_("")}
2114 };
2115 static OPTIONVARPROTO db_ovptechopt[] = /* TECHNOLOGY: Technology Options */
2116 {
2117 {0, 0, (INTBIG*)&mocmossub_tech,VTECHNOLOGY, 0, x_("TECH_state"), 0, 0, MOCMOSSUBMETALS, 0, N_("mocmossub number of metal layers")},
2118 {0, 0, (INTBIG*)&mocmossub_tech,VTECHNOLOGY, 0, x_("TECH_state"), 0, 0, MOCMOSSUBNOCONV, 0, N_("mocmossub converts to mocmos")},
2119 {0, 0, (INTBIG*)&mocmos_tech,VTECHNOLOGY, 0, x_("TECH_state"), 0, 0, MOCMOSMETALS, 0, N_("mocmos number of metal layers")},
2120 {0, 0, (INTBIG*)&mocmos_tech,VTECHNOLOGY, 0, x_("TECH_state"), 0, 0, MOCMOSSTICKFIGURE, 0, N_("mocmos stick figure")},
2121 {0, 0, (INTBIG*)&mocmos_tech,VTECHNOLOGY, 0, x_("TECH_state"), 0, 0, MOCMOSNOSTACKEDVIAS, 0, N_("mocmos stacked vias")},
2122 {0, 0, (INTBIG*)&mocmos_tech,VTECHNOLOGY, 0, x_("TECH_state"), 0, 0, MOCMOSALTAPRULES, 0, N_("mocmos alternate contact rules")},
2123 {0, 0, (INTBIG*)&mocmos_tech,VTECHNOLOGY, 0, x_("TECH_state"), 0, 0, MOCMOSTWOPOLY, 0, N_("mocmos number of polysilicon layers")},
2124 {0, 0, (INTBIG*)&mocmos_tech,VTECHNOLOGY, 0, x_("TECH_state"), 0, 0, MOCMOSSPECIALTRAN, 0, N_("mocmos shows special transistors")},
2125 {0, 0, (INTBIG*)&mocmos_tech,VTECHNOLOGY, 0, x_("TECH_state"), 0, 0, MOCMOSRULESET, 0, N_("mocmos rule set")},
2126 {0, 0, (INTBIG*)&art_tech, VTECHNOLOGY, 0, x_("TECH_state"), 0, 0, ARTWORKFILLARROWHEADS, 0, N_("artwork fills arrowheads")},
2127 {0, 0, (INTBIG*)&sch_tech, VTECHNOLOGY, 0, x_("TECH_layout_technology"), 0, 0, 0, 0, N_("Technology to use for schematics")},
2128 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, x_("")}
2129 };
2130 static OPTIONVARPROTO db_ovptechunits[] = /* TECHNOLOGY: Units */
2131 {
2132 {0, 0, (INTBIG*)&us_tool, VTOOL, 0, x_("USER_display_units"), 0, 0, DISPLAYUNITS, 0, N_("Display units")},
2133 {0, 0, (INTBIG*)&us_tool, VTOOL, 0, x_("USER_display_units"), 0, 0, INTERNALUNITS, 0, N_("Internal units")},
2134 {0, 0, (INTBIG*)&us_tool, VTOOL, 0, x_("USER_electrical_units"), 0, 0, 0, 0, N_("Electrical units")},
2135 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, x_("")}
2136 };
2137 #if DRCTOOL
2138 static OPTIONVARPROTO db_ovpdrc[] = /* TOOLS: DRC: DRC Options */
2139 {
2140 {0, 0, (INTBIG*)&dr_tool, VTOOL, 0, x_("DRC_pointout"), 0, 0, 0, 0, N_("Incremental DRC highlights errors")},
2141 {0, 0, (INTBIG*)&dr_tool, VTOOL, 0, x_("DRC_options"), 0, 0, DRCFIRSTERROR, 0, N_("Just 1 error per cell")},
2142 {0, 0, (INTBIG*)&dr_tool, VTOOL, 0, x_("DRC_options"), 0, 0, DRCREASONABLE, 0, N_("Ignore center cuts in large contacts")},
2143 {0, 0, (INTBIG*)&dr_tool, VTOOL, 0, x_("DRC_options"), 0, 0, DRCMULTIPROC|DRCNUMPROC, 0, N_("Use multiple processors")},
2144 {0, 0, (INTBIG*)&dr_tool, VTOOL, 0, x_("DRC_incrementalon"), 0, 0, 0, 0, N_("Incremental DRC on")},
2145 {0, 0, 0, VTECHNOLOGY, 0, x_("DRC_ecad_deck"), 0, 0, 0, 0, N_("Dracula rules deck")},
2146 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, x_("")}
2147 };
2148 static OPTIONVARPROTO db_ovpdrcr[] = /* TOOLS: DRC: DRC Rules */
2149 {
2150 {0, 0, 0, VTECHNOLOGY, 0, x_("DRC_wide_limit"), 0, 0, 0, 0, N_("Wide rule size")},
2151 {0, 0, 0, VTECHNOLOGY, 0, x_("DRC_min_width"), 0, 0, 0, 0, N_("Minimum width distance")},
2152 {0, 0, 0, VTECHNOLOGY, 0, x_("DRC_min_width_rule"), 0, 0, 0, 0, N_("Minimum width rule")},
2153 {0, 0, 0, VTECHNOLOGY, 0, x_("DRC_min_connected_distances"), 0, 0, 0, 0, N_("Normal connected distance")},
2154 {0, 0, 0, VTECHNOLOGY, 0, x_("DRC_min_connected_distances_rule"), 0, 0, 0, 0, N_("Normal connected rule")},
2155 {0, 0, 0, VTECHNOLOGY, 0, x_("DRC_min_unconnected_distances"), 0, 0, 0, 0, N_("Normal not-connected distance")},
2156 {0, 0, 0, VTECHNOLOGY, 0, x_("DRC_min_unconnected_distances_rule"), 0, 0, 0, 0, N_("Normal not-connected rule")},
2157 {0, 0, 0, VTECHNOLOGY, 0, x_("DRC_min_connected_distances_wide"), 0, 0, 0, 0, N_("Wide connected distance")},
2158 {0, 0, 0, VTECHNOLOGY, 0, x_("DRC_min_connected_distances_wide_rule"), 0, 0, 0, 0, N_("Wide connected rule")},
2159 {0, 0, 0, VTECHNOLOGY, 0, x_("DRC_min_unconnected_distances_wide"), 0, 0, 0, 0, N_("Wide not-connected spacing")},
2160 {0, 0, 0, VTECHNOLOGY, 0, x_("DRC_min_unconnected_distances_wide_rule"), 0, 0, 0, 0, N_("Wide not-connected rule")},
2161 {0, 0, 0, VTECHNOLOGY, 0, x_("DRC_min_connected_distances_multi"), 0, 0, 0, 0, N_("Multiple cuts connected distance")},
2162 {0, 0, 0, VTECHNOLOGY, 0, x_("DRC_min_connected_distances_multi_rule"), 0, 0, 0, 0, N_("Multiple cuts connected rule")},
2163 {0, 0, 0, VTECHNOLOGY, 0, x_("DRC_min_unconnected_distances_multi"), 0, 0, 0, 0, N_("Multiple cuts not-connected distance")},
2164 {0, 0, 0, VTECHNOLOGY, 0, x_("DRC_min_unconnected_distances_multi_rule"), 0, 0, 0, 0, N_("Multiple cuts not-connected rule")},
2165 {0, 0, 0, VTECHNOLOGY, 0, x_("DRC_min_edge_distances"), 0, 0, 0, 0, N_("Edge distance")},
2166 {0, 0, 0, VTECHNOLOGY, 0, x_("DRC_min_edge_distances_rule"), 0, 0, 0, 0, N_("Edge rule")},
2167 {0, 0, 0, VTECHNOLOGY, 0, x_("DRC_min_node_size"), 0, 0, 0, 0, N_("Minimum node size")},
2168 {0, 0, 0, VTECHNOLOGY, 0, x_("DRC_min_node_size_rule"), 0, 0, 0, 0, N_("Minimum node size rule")},
2169 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, x_("")}
2170 };
2171 #endif
2172 #if SIMTOOL
2173 static OPTIONVARPROTO db_ovpsimulation[] = /* TOOLS: Simulation: Simulation Options */
2174 {
2175 {0, 0, (INTBIG*)&sim_tool, VTOOL, 0, x_("SIM_als_no_update"), 0, 0, 0, 0, N_("Resimulate each change")},
2176 {0, 0, (INTBIG*)&sim_tool, VTOOL, 0, x_("SIM_als_num_events"), 0, 0, 0, 0, N_("ALS: maximum events")},
2177 {0, 0, (INTBIG*)&sim_tool, VTOOL, 0, x_("SIM_window_state"), 0, 0, ADVANCETIME, 0, N_("Auto advance time")},
2178 {0, 0, (INTBIG*)&sim_tool, VTOOL, 0, x_("SIM_window_state"), 0, 0, BUSBASEBITS, 0, N_("Base for bus values")},
2179 {0, 0, (INTBIG*)&sim_tool, VTOOL, 0, x_("SIM_window_state"), 0, 0, SIMENGINE, 0, N_("Simulation engine")},
2180 {0, 0, (INTBIG*)&sim_tool, VTOOL, 0, x_("SIM_window_state"), 0, 0, SHOWWAVEFORM, 0, N_("Show waveform window")},
2181 {0, 0, (INTBIG*)&sim_tool, VTOOL, 0, x_("SIM_window_state"), 0, 0, WAVEPLACE, 0, N_("Place waveform window")},
2182 {0, 0, (INTBIG*)&sim_tool, VTOOL, 0, x_("SIM_window_state"), 0, 0, FULLSTATE, 0, N_("Multistate display")},
2183 {0, 0, (INTBIG*)&sim_tool, VTOOL, 0, x_("SIM_irsim_state"), 0, 0, IRSIMPARASITICS, 0, N_("IRSIM parasitics")},
2184 {0, 0, (INTBIG*)&sim_tool, VTOOL, 0, x_("SIM_irsim_state"), 0, 0, IRSIMSHOWCOMMANDS, 0, N_("IRSIM show commands")},
2185 {0, 0, (INTBIG*)&sim_tool, VTOOL, 0, x_("SIM_irsim_parameter_file"), 0, 0, 0, 0, N_("IRSIM parameter file")},
2186 {0, 0, (INTBIG*)&sim_tool, VTOOL, 0, x_("SIM_window_color_str0"), 0, 0, 0, 0, N_("Strength 0 (off) color")},
2187 {0, 0, (INTBIG*)&sim_tool, VTOOL, 0, x_("SIM_window_color_str1"), 0, 0, 0, 0, N_("Strength 1 (node) color")},
2188 {0, 0, (INTBIG*)&sim_tool, VTOOL, 0, x_("SIM_window_color_str2"), 0, 0, 0, 0, N_("Strength 2 (gate) color")},
2189 {0, 0, (INTBIG*)&sim_tool, VTOOL, 0, x_("SIM_window_color_str3"), 0, 0, 0, 0, N_("Strength 3 (power) color")},
2190 {0, 0, (INTBIG*)&sim_tool, VTOOL, 0, x_("SIM_window_color_low"), 0, 0, 0, 0, N_("Low color")},
2191 {0, 0, (INTBIG*)&sim_tool, VTOOL, 0, x_("SIM_window_color_high"), 0, 0, 0, 0, N_("High color")},
2192 {0, 0, (INTBIG*)&sim_tool, VTOOL, 0, x_("SIM_window_color_X"), 0, 0, 0, 0, N_("Undefined (X) color")},
2193 {0, 0, (INTBIG*)&sim_tool, VTOOL, 0, x_("SIM_window_color_Z"), 0, 0, 0, 0, N_("Floating (Z) color")},
2194 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, x_("")}
2195 };
2196 static OPTIONVARPROTO db_ovpsimspice[] = /* TOOLS: Simulation Interface: Spice Options */
2197 {
2198 /* {0, 0, 0, VNODEPROTO, 0, "SIM_spice_behave_file", 0, 0, 0, 0, N_("")}, *** cell specific ***/
2199 {0, 0, (INTBIG*)&sim_tool, VTOOL, 0, x_("SIM_dontrun"), 0, 0, 0, 0, N_("Running SPICE")},
2200 {0, 0, (INTBIG*)&sim_tool, VTOOL, 0, x_("SIM_spice_level"), 0, 0, 0, 0, N_("SPICE level")},
2201 {0, 0, (INTBIG*)&sim_tool, VTOOL, 0, x_("SIM_spice_state"), 0, 0, SPICETYPE, 0, N_("SPICE engine")},
2202 {0, 0, (INTBIG*)&sim_tool, VTOOL, 0, x_("SIM_spice_state"), 0, 0, SPICEOUTPUT, 0, N_("SPICE output format")},
2203 {0, 0, (INTBIG*)&sim_tool, VTOOL, 0, x_("SIM_spice_state"), 0, 0, SPICEGLOBALPG, 0, N_("Force global VDD/GND")},
2204 {0, 0, (INTBIG*)&sim_tool, VTOOL, 0, x_("SIM_spice_state"), 0, 0, SPICEUSELAMBDAS, 0, N_("Write sizes in lambda")},
2205 {0, 0, (INTBIG*)&sim_tool, VTOOL, 0, x_("SIM_spice_parts"), 0, 0, 0, 0, N_("SPICE primitive set")},
2206 {0, 0, (INTBIG*)&sim_tool, VTOOL, 0, x_("SIM_spice_runarguments"), 0, 0, 0, 0, N_("SPICE execution arguments")},
2207 {0, 0, 0, VTECHNOLOGY, 0, x_("SIM_spice_model_file"), 0, 0, 0, 0, N_("Use header cards from file")},
2208 {0, 0, 0, VTECHNOLOGY, 0, x_("SIM_spice_trailer_file"), 0, 0, 0, 0, N_("Use trailer cards from file")},
2209 {0, 0, 0, VTECHNOLOGY, 0, x_("SIM_spice_header_level1"), 0, 0, 0, 0, N_("Level 1 built-in header cards")},
2210 {0, 0, 0, VTECHNOLOGY, 0, x_("SIM_spice_header_level2"), 0, 0, 0, 0, N_("Level 2 built-in header cards")},
2211 {0, 0, 0, VTECHNOLOGY, 0, x_("SIM_spice_header_level3"), 0, 0, 0, 0, N_("Level 3 built-in header cards")},
2212 {0, 0, 0, VTECHNOLOGY, 0, x_("SIM_spice_resistance"), 0, 0, 0, 0, N_("Resistance")},
2213 {0, 0, 0, VTECHNOLOGY, 0, x_("SIM_spice_capacitance"), 0, 0, 0, 0, N_("Capacitance")},
2214 {0, 0, 0, VTECHNOLOGY, 0, x_("SIM_spice_edge_capacitance"), 0, 0, 0, 0, N_("Edge capacitance")},
2215 {0, 0, 0, VTECHNOLOGY, 0, x_("SIM_spice_min_resistance"), 0, 0, 0, 0, N_("Min. resistance")},
2216 {0, 0, 0, VTECHNOLOGY, 0, x_("SIM_spice_min_capacitance"), 0, 0, 0, 0, N_("Min. capacitance")},
2217 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, x_("")}
2218 };
2219 static OPTIONVARPROTO db_ovpsimverilog[] = /* TOOLS: Simulation Interface: Verilog Options */
2220 {
2221 /* {0, 0, 0, VNODEPROTO, 0, "SIM_verilog_behave_file", 0, 0, 0, 0, N_("")}, *** cell specific ***/
2222 {0, 0, (INTBIG*)&sim_tool, VTOOL, 0, x_("SIM_verilog_state"), 0, 0, VERILOGUSEASSIGN, 0, N_("Use assign construct")},
2223 {0, 0, (INTBIG*)&sim_tool, VTOOL, 0, x_("SIM_verilog_state"), 0, 0, VERILOGUSETRIREG, 0, N_("Default wire is trireg")},
2224 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, x_("")}
2225 };
2226 static OPTIONVARPROTO db_ovpsimfasthenry[] = /* TOOLS: Simulation Interface: FastHenry Options */
2227 {
2228 {0, 0, (INTBIG*)&sim_tool, VTOOL, 0, x_("SIM_fasthenry_state"), 0, 0, FHUSESINGLEFREQ, 0, N_("Use single frequency")},
2229 {0, 0, (INTBIG*)&sim_tool, VTOOL, 0, x_("SIM_fasthenry_state"), 0, 0, FHMAKEMULTIPOLECKT, 0, N_("Make multipole subcircuit")},
2230 {0, 0, (INTBIG*)&sim_tool, VTOOL, 0, x_("SIM_fasthenry_state"), 0, 0, FHMAKEPOSTSCRIPTVIEW, 0, N_("Make PostScript view")},
2231 {0, 0, (INTBIG*)&sim_tool, VTOOL, 0, x_("SIM_fasthenry_state"), 0, 0, FHMAKESPICESUBCKT, 0, N_("Make SPICE subcircuit")},
2232 {0, 0, (INTBIG*)&sim_tool, VTOOL, 0, x_("SIM_fasthenry_state"), 0, 0, FHEXECUTETYPE, 0, N_("Action after writing deck")},
2233 {0, 0, (INTBIG*)&sim_tool, VTOOL, 0, x_("SIM_fasthenry_freqstart"), 0, 0, 0, 0, N_("FastHenry start frequency")},
2234 {0, 0, (INTBIG*)&sim_tool, VTOOL, 0, x_("SIM_fasthenry_freqend"), 0, 0, 0, 0, N_("FastHenry end frequency")},
2235 {0, 0, (INTBIG*)&sim_tool, VTOOL, 0, x_("SIM_fasthenry_runsperdecade"), 0, 0, 0, 0, N_("FastHenry runs per decade")},
2236 {0, 0, (INTBIG*)&sim_tool, VTOOL, 0, x_("SIM_fasthenry_numpoles"), 0, 0, 0, 0, N_("FastHenry number of poles")},
2237 {0, 0, (INTBIG*)&sim_tool, VTOOL, 0, x_("SIM_fasthenry_seglimit"), 0, 0, 0, 0, N_("FastHenry segment limit")},
2238 {0, 0, (INTBIG*)&sim_tool, VTOOL, 0, x_("SIM_fasthenry_thickness"), 0, 0, 0, 0, N_("FastHenry thickness")},
2239 {0, 0, (INTBIG*)&sim_tool, VTOOL, 0, x_("SIM_fasthenry_width_subdivs"), 0, 0, 0, 0, N_("FastHenry width subdivisions")},
2240 {0, 0, (INTBIG*)&sim_tool, VTOOL, 0, x_("SIM_fasthenry_height_subdivs"), 0, 0, 0, 0, N_("FastHenry height subdivisions")},
2241 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, x_("")}
2242 };
2243 #endif
2244 #if ERCTOOL
2245 static OPTIONVARPROTO db_ovpercwell[] = /* TOOLS: ERC: Well Check Options */
2246 {
2247 {0, 0, (INTBIG*)&erc_tool, VTOOL, 0, x_("ERC_options"), 0, 0, PWELLCONOPTIONS, 0, N_("PWell contact checks")},
2248 {0, 0, (INTBIG*)&erc_tool, VTOOL, 0, x_("ERC_options"), 0, 0, NWELLCONOPTIONS, 0, N_("NWell contact checks")},
2249 {0, 0, (INTBIG*)&erc_tool, VTOOL, 0, x_("ERC_options"), 0, 0, PWELLONGROUND, 0, N_("Check PWell to ground")},
2250 {0, 0, (INTBIG*)&erc_tool, VTOOL, 0, x_("ERC_options"), 0, 0, NWELLONPOWER, 0, N_("Check NWell to power")},
2251 {0, 0, (INTBIG*)&erc_tool, VTOOL, 0, x_("ERC_options"), 0, 0, FINDEDGEDIST, 0, N_("Find farthest distance from contact to edge")},
2252 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, x_("")}
2253 };
2254 static OPTIONVARPROTO db_ovpercant[] = /* TOOLS: ERC: Antenna Rules Options */
2255 {
2256 {0, 0, 0, VTECHNOLOGY, 0, x_("ERC_antenna_arc_ratio"), 0, 0, 0, 0, N_("Maximum antenna ratio")},
2257 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, x_("")}
2258 };
2259 #endif
2260 static OPTIONVARPROTO db_ovpncc[] = /* TOOLS: Network: NCC Options */
2261 {
2262 {0, 0, (INTBIG*)&net_tool, VTOOL, 0, x_("NET_ncc_options"), 0, 0, NCCRECURSE, 0, N_("Recurse through hierarchy")},
2263 {0, 0, (INTBIG*)&net_tool, VTOOL, 0, x_("NET_ncc_options"), 0, 0, NCCHIERARCHICAL, 0, N_("Expand hierarchy")},
2264 {0, 0, (INTBIG*)&net_tool, VTOOL, 0, x_("NET_ncc_options"), 0, 0, NCCNOMERGEPARALLEL, 0, N_("Merge parallel components")},
2265 {0, 0, (INTBIG*)&net_tool, VTOOL, 0, x_("NET_ncc_options"), 0, 0, NCCMERGESERIES, 0, N_("Merge series transistors")},
2266 {0, 0, (INTBIG*)&net_tool, VTOOL, 0, x_("NET_ncc_options"), 0, 0, NCCIGNOREPWRGND, 0, N_("Ignore power and ground")},
2267 {0, 0, (INTBIG*)&net_tool, VTOOL, 0, x_("NET_ncc_options"), 0, 0, NCCCHECKEXPORTNAMES, 0, N_("Check export names")},
2268 {0, 0, (INTBIG*)&net_tool, VTOOL, 0, x_("NET_ncc_options"), 0, 0, NCCCHECKSIZE, 0, N_("Check component sizes")},
2269 {0, 0, (INTBIG*)&net_tool, VTOOL, 0, x_("NET_ncc_options"), 0, 0, NCCINCLUDENOCOMPNETS, 0, N_("Allow no-component nets")},
2270 {0, 0, (INTBIG*)&net_tool, VTOOL, 0, x_("NET_ncc_options"), 0, 0, NCCRESISTINCLUSION, 0, N_("NCC automatic resistor adjustment")},
2271 {0, 0, (INTBIG*)&net_tool, VTOOL, 0, x_("NET_ncc_options"), 0, 0, NCCDISLOCAFTERMATCH|NCCENAFOCSYMGRPFRE|NCCENAFOCSYMGRPPRO|NCCSUPALLAMBREP|NCCVERBOSETEXT|NCCVERBOSEGRAPHICS|NCCGRAPHICPROGRESS|NCCENASTATISTICS, 0, N_("NCC Debugging settings")},
2272 {0, 0, (INTBIG*)&net_tool, VTOOL, 0, x_("NET_ncc_component_tolerance"), 0, 0, 0, 0, N_("Size tolerance (%)")},
2273 {0, 0, (INTBIG*)&net_tool, VTOOL, 0, x_("NET_ncc_component_tolerance_amt"), 0, 0, 0, 0, N_("Size tolerance (amt)")},
2274 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, x_("")}
2275 };
2276 static OPTIONVARPROTO db_ovpnetwork[] = /* TOOLS: Network: Network Options */
2277 {
2278 {0, 0, (INTBIG*)&net_tool, VTOOL, 0, x_("NET_options"), 0, 0, NETCONPWRGND, 0, N_("Unify Power and Ground")},
2279 {0, 0, (INTBIG*)&net_tool, VTOOL, 0, x_("NET_options"), 0, 0, NETCONCOMMONNAME, 0, N_("Unify all like-named nets")},
2280 {0, 0, (INTBIG*)&net_tool, VTOOL, 0, x_("NET_options"), 0, 0, NETIGNORERESISTORS, 0, N_("Ignore Resistors")},
2281 {0, 0, (INTBIG*)&net_tool, VTOOL, 0, x_("NET_options"), 0, 0, NETDEFBUSBASE1, 0, N_("Bus starting index")},
2282 {0, 0, (INTBIG*)&net_tool, VTOOL, 0, x_("NET_options"), 0, 0, NETDEFBUSBASEDESC, 0, N_("Bus ascending/descending")},
2283 {0, 0, (INTBIG*)&net_tool, VTOOL, 0, x_("NET_unify_strings"), 0, 0, 0, 0, N_("Network unification prefix")},
2284 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, x_("")}
2285 };
2286 #if LOGEFFTOOL
2287 static OPTIONVARPROTO db_ovplogeffort[] = /* TOOLS: Logical Effort: Logical Effort Options */
2288 {
2289 {0, 0, (INTBIG*)&le_tool, VTOOL, 0, x_("LE_state"), 0, 0, DISPLAYCAPACITANCE, 0, N_("Display capacitance")},
2290 {0, 0, (INTBIG*)&le_tool, VTOOL, 0, x_("LE_state"), 0, 0, HIGHLIGHTCOMPONENTS, 0, N_("Highlight components")},
2291 {0, 0, (INTBIG*)&le_tool, VTOOL, 0, x_("LE_state"), 0, 0, LEUSELESETTINGS, 0, N_("Use Local LE Settings")},
2292 {0, 0, (INTBIG*)&le_tool, VTOOL, 0, x_("LE_maximum_stage_effort"), 0, 0, 0, 0, N_("Maximum stage gain")},
2293 {0, 0, (INTBIG*)&le_tool, VTOOL, 0, x_("LE_global_fanout_effort"), 0, 0, 0, 0, N_("Global fanout")},
2294 {0, 0, (INTBIG*)&le_tool, VTOOL, 0, x_("LE_convergence_epsilon"), 0, 0, 0, 0, N_("Convergence Epsilon")},
2295 {0, 0, (INTBIG*)&le_tool, VTOOL, 0, x_("LE_diff_ratio_nmos"), 0, 0, 0, 0, N_("NMOS Diffusion ratio")},
2296 {0, 0, (INTBIG*)&le_tool, VTOOL, 0, x_("LE_diff_ratio_pmos"), 0, 0, 0, 0, N_("PMOS Diffusion ratio")},
2297 {0, 0, (INTBIG*)&le_tool, VTOOL, 0, x_("LE_gate_cap"), 0, 0, 0, 0, N_("Gate capacitance ratio")},
2298 {0, 0, (INTBIG*)&le_tool, VTOOL, 0, x_("LE_def_wire_ratio"), 0, 0, 0, 0, N_("Default wire ratio")},
2299 {0, 0, (INTBIG*)&le_tool, VTOOL, 0, x_("LE_max_iterations"), 0, 0, 0, 0, N_("Maximum iterations")},
2300 {0, 0, (INTBIG*)&le_tool, VTOOL, 0, x_("LE_keeper_size_adj"), 0, 0, 0, 0, N_("Keeper size ratio")},
2301 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, x_("")}
2302 };
2303 #endif
2304 #if ROUTTOOL
2305 static OPTIONVARPROTO db_ovprouting[] = /* TOOLS: Routing: Routing Options */
2306 {
2307 {0, 0, (INTBIG*)&ro_tool, VTOOL, 0, x_("ROUT_prefered_arc"), 0, 0, 0, 0, N_("Prefered arc")},
2308 {0, 0, (INTBIG*)&ro_tool, VTOOL, 0, x_("ROUT_options"), 0, 0, MIMICUNROUTES, 0, N_("Mimic stitching can unstitch")},
2309 {0, 0, (INTBIG*)&ro_tool, VTOOL, 0, x_("ROUT_options"), 0, 0, MIMICIGNOREPORTS, 0, N_("Ports must match")},
2310 {0, 0, (INTBIG*)&ro_tool, VTOOL, 0, x_("ROUT_options"), 0, 0, MIMICONSIDERARCCOUNT, 0, N_("Number of existing arcs must match")},
2311 {0, 0, (INTBIG*)&ro_tool, VTOOL, 0, x_("ROUT_options"), 0, 0, MIMICIGNORENODETYPE, 0, N_("Node types must match")},
2312 {0, 0, (INTBIG*)&ro_tool, VTOOL, 0, x_("ROUT_options"), 0, 0, MIMICIGNORENODESIZE, 0, N_("Nodes sizes must match")},
2313 {0, 0, (INTBIG*)&ro_tool, VTOOL, 0, x_("ROUT_options"), 0, 0, MIMICINTERACTIVE, 0, N_("Mimic stitching runs interactively")},
2314 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, x_("")}
2315 };
2316 #endif
2317 #if VHDLTOOL
2318 static OPTIONVARPROTO db_ovpvhdl[] = /* TOOLS: VHDL: VHDL Options */
2319 {
2320 {0, 0, (INTBIG*)&vhdl_tool,VTOOL, 0, x_("VHDL_vhdl_on_disk"), 0, 0, 0, 0, N_("VHDL stored in cell")},
2321 {0, 0, (INTBIG*)&vhdl_tool,VTOOL, 0, x_("VHDL_netlist_on_disk"), 0, 0, 0, 0, N_("Netlist stored in cell")},
2322 {0, 0, 0, VTECHNOLOGY, 0, x_("TECH_vhdl_names"), 0, 0, 0, 0, N_("VHDL primitive names")},
2323 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, x_("")}
2324 };
2325 #endif
2326 #if SCTOOL
2327 static OPTIONVARPROTO db_ovpsilcomp[] = /* TOOLS: Silicon Compiler: Silicon Compiler Options */
2328 {
2329 {0, 0, (INTBIG*)&sc_tool, VTOOL, 0, x_("SC_horiz_arc"), 0, 0, 0, 0, N_("Horizontal routing arc")},
2330 {0, 0, (INTBIG*)&sc_tool, VTOOL, 0, x_("SC_vert_arc"), 0, 0, 0, 0, N_("Vertical routing arc")},
2331 {0, 0, (INTBIG*)&sc_tool, VTOOL, 0, x_("SC_l1_width"), 0, 0, 0, 0, N_("Horizontal wire width")},
2332 {0, 0, (INTBIG*)&sc_tool, VTOOL, 0, x_("SC_l2_width"), 0, 0, 0, 0, N_("Vertical wire width")},
2333 {0, 0, (INTBIG*)&sc_tool, VTOOL, 0, x_("SC_pwr_width"), 0, 0, 0, 0, N_("Power wire width")},
2334 {0, 0, (INTBIG*)&sc_tool, VTOOL, 0, x_("SC_main_pwr_width"), 0, 0, 0, 0, N_("Main power wire width")},
2335 {0, 0, (INTBIG*)&sc_tool, VTOOL, 0, x_("SC_main_pwr_rail"), 0, 0, 0, 0, N_("Main power arc")},
2336 {0, 0, (INTBIG*)&sc_tool, VTOOL, 0, x_("SC_pwell_size"), 0, 0, 0, 0, N_("P-Well height")},
2337 {0, 0, (INTBIG*)&sc_tool, VTOOL, 0, x_("SC_pwell_offset"), 0, 0, 0, 0, N_("P-Well offset from bottom")},
2338 {0, 0, (INTBIG*)&sc_tool, VTOOL, 0, x_("SC_nwell_size"), 0, 0, 0, 0, N_("N-Well height")},
2339 {0, 0, (INTBIG*)&sc_tool, VTOOL, 0, x_("SC_nwell_offset"), 0, 0, 0, 0, N_("N-Well offset from top")},
2340 {0, 0, (INTBIG*)&sc_tool, VTOOL, 0, x_("SC_via_size"), 0, 0, 0, 0, N_("Via size")},
2341 {0, 0, (INTBIG*)&sc_tool, VTOOL, 0, x_("SC_min_spacing"), 0, 0, 0, 0, N_("Minimum metal spacing")},
2342 {0, 0, (INTBIG*)&sc_tool, VTOOL, 0, x_("SC_feedthru_size"), 0, 0, 0, 0, N_("Feedthrough size")},
2343 {0, 0, (INTBIG*)&sc_tool, VTOOL, 0, x_("SC_port_x_min_dist"), 0, 0, 0, 0, N_("Minimum port distance")},
2344 {0, 0, (INTBIG*)&sc_tool, VTOOL, 0, x_("SC_active_dist"), 0, 0, 0, 0, N_("Minimum active distance")},
2345 {0, 0, (INTBIG*)&sc_tool, VTOOL, 0, x_("SC_num_rows"), 0, 0, 0, 0, N_("Number of rows of cells")},
2346 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, x_("")}
2347 };
2348 #endif
2349 #if COMTOOL
2350 static OPTIONVARPROTO db_ovpcompaction[] = /* TOOLS: Compaction: Compaction Options */
2351 {
2352 {0, 0, (INTBIG*)&com_tool, VTOOL, 0, x_("COM_spread"), 0, 0, 0, 0, N_("Spreads")},
2353 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, x_("")}
2354 };
2355 #endif
2356 #if LANGJAVA
2357 static OPTIONVARPROTO db_ovpjava[] = /* WINDOWS: Java Options */
2358 {
2359 {0, 0, (INTBIG*)&us_tool, VTOOL, 0, x_("JAVA_flags"), 0, 0, JAVANOCOMPILER, 0, N_("Disable compiler")},
2360 {0, 0, (INTBIG*)&us_tool, VTOOL, 0, x_("JAVA_flags"), 0, 0, JAVANOEVALUATE, 0, N_("Disable evaluation")},
2361 {0, 0, (INTBIG*)&us_tool, VTOOL, 0, x_("JAVA_flags"), 0, 0, JAVAUSEJOSE, 0, N_("Enable Jose")},
2362 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, x_("")}
2363 };
2364 #endif
2365
2366 #define OPTIONCIF 01 /* CIF Options */
2367 #define OPTIONGDS 02 /* GDS Options */
2368 #define OPTIONDXF 04 /* DXF Options */
2369 #define OPTIONEDIF 010 /* EDIF Options */
2370 #define OPTIONPRINT 020 /* Print Options */
2371 #define OPTIONFRAME 040 /* Frame Options */
2372 #define OPTIONALIGNMENT 0100 /* Alignment Options */
2373 #define OPTIONTEXT 0200 /* Text Options */
2374 #define OPTIONNEWNODE 0400 /* New Node Options */
2375 #define OPTIONNEWARC 01000 /* New Arc Options */
2376 #define OPTIONDRC 02000 /* DRC Options */
2377 #define OPTIONSIMULATION 04000 /* Simulation Options */
2378 #define OPTIONSPICE 010000 /* Spice Options */
2379 #define OPTIONVERILOG 020000 /* Verilog Options */
2380 #define OPTIONVHDL 040000 /* VHDL Options */
2381 #define OPTIONSILCOMP 0100000 /* Silicon Compiler Options */
2382 #define OPTIONNETWORK 0200000 /* Network Options */
2383 #define OPTIONROUTING 0400000 /* Routing Options */
2384 #define OPTIONCOMPACTION 01000000 /* Compaction Options */
2385 #define OPTIONGRID 02000000 /* Grid Options */
2386 #define OPTIONLOGEFFORT 04000000 /* Logical Effort Options */
2387 #define OPTIONPORT 010000000 /* Port Display Options */
2388 #define OPTIONCOLOR 020000000 /* Color Options */
2389 #define OPTIONQUICKKEY 040000000 /* Quick Key Options */
2390 #define OPTIONSKILL 0100000000 /* SKILL Options */
2391 #define OPTIONCELL 0200000000 /* Cell Options */
2392 #define OPTIONSELECT 0400000000 /* Selection Options */
2393 #define OPTION3D 01000000000 /* 3D Options */
2394 #define OPTIONTECH 02000000000 /* Technology Options */
2395 #define OPTIONERCWELL 04000000000 /* ERC Well Check Options */
2396 #define OPTIONLAYPAT 010000000000 /* Layer Display Options */
2397 #define OPTIONFASTHENRY 020000000000 /* FastHenry Options */
2398 #define OPTIONDEF 01 /* DEF Options */
2399 #define OPTIONUNITS 02 /* Technology Units */
2400 #define OPTIONICON 04 /* Icon Options */
2401 #define OPTIONLIBRARY 010 /* Library Options */
2402 #define OPTIONDRCR 0200 /* DRC Rules */
2403 #define OPTIONJAVA 0400 /* Java Options */
2404 #define OPTIONMSGLOC 01000 /* Save Messages Location */
2405 #define OPTIONGENERAL 02000 /* General Options */
2406 #define OPTIONLAYVIS 04000 /* Layer Visibility Options */
2407 #define OPTIONNCC 010000 /* NCC Options */
2408 #define OPTIONCDL 020000 /* CDL Options */
2409 #define OPTIONATTRIBUTES 040000 /* Attribute Options */
2410 #define OPTIONSUE 0100000 /* Sue Options */
2411 #define OPTIONCOPYRIGHT 0200000 /* Copyright Options */
2412 #define OPTIONERCANT 02000000 /* ERC Antenna Rules Options */
2413
2414 static OPTIONVARCOMS db_optionvarcoms[] =
2415 {
2416 {{0,OPTIONLIBRARY}, N_("File / IO Options / Library Options"), db_ovpforeignfilelibrary},
2417 {{0,OPTIONCOPYRIGHT}, N_("File / IO Options / Copyright Options"), db_ovpcopyright},
2418 {{OPTIONCIF,0}, N_("File / IO Options / CIF Options"), db_ovpforeignfilecif},
2419 {{OPTIONGDS,0}, N_("File / IO Options / GDS II Options"), db_ovpforeignfilegds},
2420 {{OPTIONEDIF,0}, N_("File / IO Options / EDIF Options"), db_ovpforeignfileedif},
2421 {{0,OPTIONDEF}, N_("File / IO Options / DEF Options"), db_ovpforeignfiledef},
2422 {{0,OPTIONCDL}, N_("File / IO Options / CDL Options"), db_ovpforeignfilecdl},
2423 {{OPTIONDXF,0}, N_("File / IO Options / DXF Options"), db_ovpforeignfiledxf},
2424 {{0,OPTIONSUE}, N_("File / IO Options / Sue Options"), db_ovpforeignfilesue},
2425 #ifdef FORCECADENCE
2426 {{OPTIONSKILL,0}, N_("File / IO Options / SKILL Options"), db_ovpforeignfileskill},
2427 #endif
2428 {{OPTIONPRINT,0}, N_("File / Print Options"), db_ovpprint},
2429 {{OPTIONNEWNODE,0}, N_("Edit / New Node Options"), db_ovpnewnode},
2430 {{OPTIONSELECT,0}, N_("Edit / Selection / Selection Options"), db_ovpselect},
2431 {{OPTIONCELL,0}, N_("Cell / Cell Options"), db_ovpcell},
2432 {{OPTIONNEWARC,0}, N_("Arc / New Arc Options"), db_ovpnewarc},
2433 {{OPTIONPORT,0}, N_("Export / Port and Export Options"), db_ovpport},
2434 {{OPTIONFRAME,0}, N_("View / Frame Options"), db_ovpframe},
2435 {{0,OPTIONICON}, N_("View / Icon Options"), db_ovpicon},
2436 {{OPTIONGRID,0}, N_("Windows / Grid Options"), db_ovpgrid},
2437 {{OPTIONALIGNMENT,0}, N_("Windows / Alignment Options"), db_ovpalign},
2438 {{0,OPTIONLAYVIS}, N_("Windows / Layer Visibility"), db_ovplayvis},
2439 {{OPTIONCOLOR,0}, N_("Windows / Color Options"), db_ovpcolor},
2440 {{OPTIONLAYPAT,0}, N_("Windows / Layer Display Options"), db_ovplaypat},
2441 {{OPTIONTEXT,0}, N_("Windows / Text Options"), db_ovptext},
2442 {{OPTION3D,0}, N_("Windows / 3D Display / 3D Options"), db_ovp3d},
2443 {{0,OPTIONMSGLOC}, N_("Windows / Messages Window / Save Window Location"), db_ovpmsgloc},
2444 {{0,OPTIONGENERAL}, N_("Info / User Interface / General Options"), db_ovpgeneral},
2445 {{OPTIONQUICKKEY,0}, N_("Info / User Interface / Quick Key Options"), db_ovpquickkey},
2446 {{OPTIONTECH,0}, N_("Technology / Technology Options"), db_ovptechopt},
2447 {{0,OPTIONUNITS}, N_("Technology / Change Units"), db_ovptechunits},
2448 #if DRCTOOL
2449 {{OPTIONDRC,0}, N_("Tools / DRC / DRC Options"), db_ovpdrc},
2450 {{OPTIONDRCR,1}, N_("Tools / DRC / DRC Rules"), db_ovpdrcr},
2451 #endif
2452 #if SIMTOOL
2453 {{OPTIONSIMULATION,0}, N_("Tools / Simulation (Built-in) / Simulation Options"), db_ovpsimulation},
2454 {{OPTIONSPICE,0}, N_("Tools / Simulation (SPICE) / Spice Options"), db_ovpsimspice},
2455 {{OPTIONVERILOG,0}, N_("Tools / Simulation (Verilog) / Verilog Options"), db_ovpsimverilog},
2456 {{OPTIONFASTHENRY,0}, N_("Tools / Simulation (Others) / FastHenry Options"), db_ovpsimfasthenry},
2457 #endif
2458 #if ERCTOOL
2459 {{OPTIONERCWELL,0}, N_("Tools / Electrical Rules / Well Check Options"), db_ovpercwell},
2460 {{0,OPTIONERCANT}, N_("Tools / Electrical Rules / Antenna Rules Options"), db_ovpercant},
2461 #endif
2462 {{0,OPTIONNCC}, N_("Tools / Network / NCC Control and Options"), db_ovpncc},
2463 {{OPTIONNETWORK,0}, N_("Tools / Network / Network Options"), db_ovpnetwork},
2464 #if LOGEFFTOOL
2465 {{OPTIONLOGEFFORT,0}, N_("Tools / Logical Effort / Logical Effort Options"), db_ovplogeffort},
2466 #endif
2467 #if ROUTTOOL
2468 {{OPTIONROUTING,0}, N_("Tools / Routing / Routing Options"), db_ovprouting},
2469 #endif
2470 #if VHDLTOOL
2471 {{OPTIONVHDL,0}, N_("Tools / VHDL Compiler / VHDL Options"), db_ovpvhdl},
2472 #endif
2473 #if SCTOOL
2474 {{OPTIONSILCOMP,0}, N_("Tools / Silicon Compiler / Silicon Compiler Options"), db_ovpsilcomp},
2475 #endif
2476 #if COMTOOL
2477 {{OPTIONCOMPACTION,0}, N_("Tools / Compaction / Compaction Options"), db_ovpcompaction},
2478 #endif
2479 #if LANGJAVA
2480 {{0,OPTIONJAVA}, N_("Tools / Language Interpreter / Java Options"), db_ovpjava}
2481 #endif
2482 };
2483
2484 /*
2485 * Routine to return the "name" of option "aindex" and its "bits".
2486 * Returns true if the aindex is out of range.
2487 */
describeoptions(INTBIG aindex,CHAR ** name,INTBIG * bits)2488 BOOLEAN describeoptions(INTBIG aindex, CHAR **name, INTBIG *bits)
2489 {
2490 REGISTER INTBIG optioncomcount, i;
2491
2492 optioncomcount = sizeof(db_optionvarcoms) / sizeof(OPTIONVARCOMS);
2493 if (aindex < 0 || aindex >= optioncomcount) return(TRUE);
2494 *name = TRANSLATE(db_optionvarcoms[aindex].command);
2495 for(i=0; i<SAVEDBITWORDS; i++)
2496 bits[i] = db_optionvarcoms[aindex].bits[i];
2497 return(FALSE);
2498 }
2499
2500 /*
2501 * Routine to cache the current value of all options so that it can be determined
2502 * later what has changed.
2503 */
cacheoptionbitvalues(void)2504 void cacheoptionbitvalues(void)
2505 {
2506 REGISTER INTBIG i, j, optioncomcount;
2507 REGISTER OPTIONVARPROTO *ovp;
2508 REGISTER VARIABLE *var;
2509
2510 optioncomcount = sizeof(db_optionvarcoms) / sizeof(OPTIONVARCOMS);
2511 for(i=0; i<optioncomcount; i++)
2512 {
2513 ovp = db_optionvarcoms[i].variables;
2514 for(j=0; ovp[j].variablename != 0; j++)
2515 {
2516 if (ovp[j].partial != 0) continue;
2517 if (ovp[j].addr == 0) continue;
2518 var = getval(*ovp[j].addr, ovp[j].type, -1, ovp[j].variablename);
2519 if (var == NOVARIABLE) continue;
2520 if ((var->type&VTYPE) != VINTEGER) continue;
2521 if ((var->type&VISARRAY) != 0)
2522 {
2523 ovp[j].initialbits1 = ((INTBIG *)var->addr)[0];
2524 ovp[j].initialbits2 = ((INTBIG *)var->addr)[1];
2525 } else
2526 {
2527 ovp[j].initialbits1 = var->addr;
2528 ovp[j].initialbits2 = 0;
2529 }
2530 }
2531 }
2532 }
2533
2534 /*
2535 * Routine to return true if variable "name" on object "addr" (type "type")
2536 * is an option variable.
2537 */
isoptionvariable(INTBIG addr,INTBIG type,CHAR * name)2538 BOOLEAN isoptionvariable(INTBIG addr, INTBIG type, CHAR *name)
2539 {
2540 REGISTER INTBIG i, j, len, optioncomcount;
2541 REGISTER BOOLEAN retval;
2542 REGISTER OPTIONVARPROTO *ovp;
2543 REGISTER VARIABLE *var;
2544 Q_UNUSED( addr );
2545
2546 retval = FALSE;
2547 optioncomcount = sizeof(db_optionvarcoms) / sizeof(OPTIONVARCOMS);
2548 for(i=0; i<optioncomcount; i++)
2549 {
2550 ovp = db_optionvarcoms[i].variables;
2551 for(j=0; ovp[j].variablename != 0; j++)
2552 {
2553 if (ovp[j].type != type) continue;
2554 if (ovp[j].partial != 0)
2555 {
2556 len = estrlen(ovp[j].variablename);
2557 if (namesamen(ovp[j].variablename, name, len) != 0) continue;
2558 } else
2559 {
2560 if (namesame(ovp[j].variablename, name) != 0) continue;
2561 }
2562
2563 /* see if option tracking has been disabled */
2564 var = getvalkey((INTBIG)us_tool, VTOOL, VINTEGER, us_ignoreoptionchangeskey);
2565 if (var != NOVARIABLE) continue;
2566 ovp[j].dirty = TRUE;
2567 retval = TRUE;
2568 }
2569 }
2570 return(retval);
2571 }
2572
2573 /*
2574 * Routine to list all options into item "item" of dialog "dia".
2575 */
listalloptions(INTBIG item,void * dia)2576 void listalloptions(INTBIG item, void *dia)
2577 {
2578 REGISTER INTBIG i, j, optioncomcount, namedoption;
2579 REGISTER OPTIONVARPROTO *ovp;
2580 REGISTER void *infstr;
2581
2582 optioncomcount = sizeof(db_optionvarcoms) / sizeof(OPTIONVARCOMS);
2583 for(i=0; i<optioncomcount; i++)
2584 {
2585 namedoption = 0;
2586 ovp = db_optionvarcoms[i].variables;
2587 for(j=0; ovp[j].variablename != 0; j++)
2588 {
2589 if (namedoption == 0)
2590 {
2591 infstr = initinfstr();
2592 formatinfstr(infstr, x_("%s:"), TRANSLATE(db_optionvarcoms[i].command));
2593 DiaStuffLine(dia, item, returninfstr(infstr));
2594 namedoption = 1;
2595 }
2596 infstr = initinfstr();
2597 formatinfstr(infstr, x_(" %s"), TRANSLATE(ovp[j].meaning));
2598 DiaStuffLine(dia, item, returninfstr(infstr));
2599 }
2600 }
2601 }
2602
2603 /*
2604 * Routine to display which options have changed.
2605 */
explainoptionchanges(INTBIG item,void * dia)2606 void explainoptionchanges(INTBIG item, void *dia)
2607 {
2608 REGISTER INTBIG i, j, k, optioncomcount, namedoption, val1, val2, len;
2609 REGISTER CHAR *name;
2610 REGISTER BOOLEAN same;
2611 REGISTER TECHNOLOGY *tech;
2612 REGISTER NODEPROTO *np;
2613 REGISTER ARCPROTO *ap;
2614 REGISTER OPTIONVARPROTO *ovp;
2615 REGISTER VARIABLE *var;
2616 REGISTER void *infstr;
2617
2618 optioncomcount = sizeof(db_optionvarcoms) / sizeof(OPTIONVARCOMS);
2619 for(i=0; i<optioncomcount; i++)
2620 {
2621 namedoption = 0;
2622 ovp = db_optionvarcoms[i].variables;
2623 for(j=0; ovp[j].variablename != 0; j++)
2624 {
2625 if (!ovp[j].dirty) continue;
2626 if (ovp[j].addr == 0)
2627 {
2628 same = TRUE;
2629 switch (ovp[j].type)
2630 {
2631 case VTECHNOLOGY:
2632 for(tech = el_technologies; tech != NOTECHNOLOGY; tech = tech->nexttechnology)
2633 {
2634 if (ovp[j].partial == 0)
2635 {
2636 var = getval((INTBIG)tech, ovp[j].type, -1, ovp[j].variablename);
2637 if (var != NOVARIABLE && (var->type&VDONTSAVE) == 0) same = FALSE;
2638 } else
2639 {
2640 len = estrlen(ovp[j].variablename);
2641 for(k=0; k<tech->numvar; k++)
2642 {
2643 var = &tech->firstvar[k];
2644 name = makename(var->key);
2645 if (namesamen(ovp[j].variablename, name, len) == 0)
2646 {
2647 if ((var->type&VDONTSAVE) == 0) same = FALSE;
2648 }
2649 }
2650 }
2651 }
2652 break;
2653 case VNODEPROTO:
2654 for(tech = el_technologies; tech != NOTECHNOLOGY; tech = tech->nexttechnology)
2655 {
2656 for(np = tech->firstnodeproto; np != NONODEPROTO; np = np->nextnodeproto)
2657 {
2658 var = getval((INTBIG)np, ovp[j].type, -1, ovp[j].variablename);
2659 if (var != NOVARIABLE && (var->type&VDONTSAVE) == 0) same = FALSE;
2660 }
2661 if (!same) break;
2662 }
2663 break;
2664 case VARCPROTO:
2665 for(tech = el_technologies; tech != NOTECHNOLOGY; tech = tech->nexttechnology)
2666 {
2667 for(ap = tech->firstarcproto; ap != NOARCPROTO; ap = ap->nextarcproto)
2668 {
2669 var = getval((INTBIG)ap, ovp[j].type, -1, ovp[j].variablename);
2670 if (var != NOVARIABLE && (var->type&VDONTSAVE) == 0) same = FALSE;
2671 }
2672 if (!same) break;
2673 }
2674 break;
2675 }
2676 if (same) continue;
2677 } else
2678 {
2679 if (ovp[j].maskbits1 != 0 || ovp[j].maskbits2 != 0)
2680 {
2681 var = getval(*ovp[j].addr, ovp[j].type, -1, ovp[j].variablename);
2682 if (var == NOVARIABLE) val1 = val2 = 0; else
2683 {
2684 if ((var->type&VTYPE) != VINTEGER) continue;
2685 if ((var->type&VISARRAY) != 0)
2686 {
2687 val1 = ((INTBIG *)var->addr)[0];
2688 val2 = ((INTBIG *)var->addr)[1];
2689 } else
2690 {
2691 val1 = var->addr;
2692 val2 = 0;
2693 }
2694 }
2695 same = TRUE;
2696 if (ovp[j].maskbits1 != 0)
2697 {
2698 if ((val1 & ovp[j].maskbits1) != (ovp[j].initialbits1&ovp[j].maskbits1)) same = FALSE;
2699 }
2700 if (ovp[j].maskbits2 != 0)
2701 {
2702 if ((val2 & ovp[j].maskbits2) != (ovp[j].initialbits2&ovp[j].maskbits2)) same = FALSE;
2703 }
2704 if (same) continue;
2705 }
2706 }
2707 if (namedoption == 0)
2708 {
2709 infstr = initinfstr();
2710 formatinfstr(infstr, x_("%s:"), TRANSLATE(db_optionvarcoms[i].command));
2711 if (item < 0) ttyputmsg(x_("%s"), returninfstr(infstr)); else
2712 DiaStuffLine(dia, item, returninfstr(infstr));
2713 namedoption = 1;
2714 }
2715 infstr = initinfstr();
2716 formatinfstr(infstr, x_(" %s"), TRANSLATE(ovp[j].meaning));
2717 if (item < 0) ttyputmsg(x_("%s"), returninfstr(infstr)); else
2718 DiaStuffLine(dia, item, returninfstr(infstr));
2719 }
2720 }
2721 }
2722
explainsavedoptions(INTBIG item,BOOLEAN onlychanged,void * dia)2723 void explainsavedoptions(INTBIG item, BOOLEAN onlychanged, void *dia)
2724 {
2725 REGISTER INTBIG i, j, k, optioncomcount, namedoption, val1, val2, len;
2726 REGISTER CHAR *name;
2727 REGISTER OPTIONVARPROTO *ovp;
2728 REGISTER BOOLEAN dirty, found;
2729 REGISTER VARIABLE *var;
2730 REGISTER TECHNOLOGY *tech;
2731 REGISTER NODEPROTO *np;
2732 REGISTER ARCPROTO *ap;
2733 REGISTER void *infstr;
2734
2735 optioncomcount = sizeof(db_optionvarcoms) / sizeof(OPTIONVARCOMS);
2736 for(i=0; i<optioncomcount; i++)
2737 {
2738 namedoption = 0;
2739 ovp = db_optionvarcoms[i].variables;
2740 for(j=0; ovp[j].variablename != 0; j++)
2741 {
2742 if (ovp[j].addr == 0)
2743 {
2744 found = FALSE;
2745 dirty = FALSE; /* must figure it out for real */
2746 switch (ovp[j].type)
2747 {
2748 case VTECHNOLOGY:
2749 for(tech = el_technologies; tech != NOTECHNOLOGY; tech = tech->nexttechnology)
2750 {
2751 if (ovp[j].partial == 0)
2752 {
2753 var = getval((INTBIG)tech, ovp[j].type, -1, ovp[j].variablename);
2754 if (var != NOVARIABLE && (var->type&VDONTSAVE) == 0) { found = TRUE; break; }
2755 } else
2756 {
2757 len = estrlen(ovp[j].variablename);
2758 for(k=0; k<tech->numvar; k++)
2759 {
2760 var = &tech->firstvar[k];
2761 name = makename(var->key);
2762 if (namesamen(ovp[j].variablename, name, len) == 0)
2763 {
2764 if ((var->type&VDONTSAVE) == 0) { found = TRUE; break; }
2765 }
2766 }
2767 if (found) break;
2768 }
2769 }
2770 break;
2771 case VNODEPROTO:
2772 for(tech = el_technologies; tech != NOTECHNOLOGY; tech = tech->nexttechnology)
2773 {
2774 for(np = tech->firstnodeproto; np != NONODEPROTO; np = np->nextnodeproto)
2775 {
2776 var = getval((INTBIG)np, ovp[j].type, -1, ovp[j].variablename);
2777 if (var != NOVARIABLE && (var->type&VDONTSAVE) == 0) { found = TRUE; break; }
2778 }
2779 if (found) break;
2780 }
2781 break;
2782 case VARCPROTO:
2783 for(tech = el_technologies; tech != NOTECHNOLOGY; tech = tech->nexttechnology)
2784 {
2785 for(ap = tech->firstarcproto; ap != NOARCPROTO; ap = ap->nextarcproto)
2786 {
2787 var = getval((INTBIG)ap, ovp[j].type, -1, ovp[j].variablename);
2788 if (var != NOVARIABLE && (var->type&VDONTSAVE) == 0) { found = TRUE; break; }
2789 }
2790 if (found) break;
2791 }
2792 break;
2793 }
2794 if (!found) continue;
2795 } else
2796 {
2797 var = getval(*ovp[j].addr, ovp[j].type, -1, ovp[j].variablename);
2798 if (var == NOVARIABLE || (var->type&VDONTSAVE) != 0) continue;
2799 dirty = FALSE;
2800 if ((ovp[j].maskbits1 != 0 || ovp[j].maskbits2 != 0) && (var->type&VTYPE) == VINTEGER)
2801 {
2802 if ((var->type&VISARRAY) != 0)
2803 {
2804 val1 = ((INTBIG *)var->addr)[0];
2805 val2 = ((INTBIG *)var->addr)[1];
2806 } else
2807 {
2808 val1 = var->addr;
2809 val2 = 0;
2810 }
2811 if (ovp[j].maskbits1 != 0)
2812 {
2813 if ((val1 & ovp[j].maskbits1) != (ovp[j].initialbits1&ovp[j].maskbits1)) dirty = TRUE;
2814 }
2815 if (ovp[j].maskbits2 != 0)
2816 {
2817 if ((val2 & ovp[j].maskbits2) != (ovp[j].initialbits2&ovp[j].maskbits2)) dirty = TRUE;
2818 }
2819 } else
2820 {
2821 if (ovp[j].dirty) dirty = TRUE;
2822 }
2823 }
2824 if (onlychanged && !dirty) continue;
2825 if (namedoption == 0)
2826 {
2827 infstr = initinfstr();
2828 formatinfstr(infstr, x_("%s:"), TRANSLATE(db_optionvarcoms[i].command));
2829 DiaStuffLine(dia, item, returninfstr(infstr));
2830 namedoption = 1;
2831 }
2832 infstr = initinfstr();
2833 if (!onlychanged && dirty) addstringtoinfstr(infstr, x_("*"));
2834 formatinfstr(infstr, x_(" %s"), TRANSLATE(ovp[j].meaning));
2835 DiaStuffLine(dia, item, returninfstr(infstr));
2836 }
2837 }
2838 }
2839
2840 /*
2841 * Routine to return true if options have really changed.
2842 */
optionshavechanged(void)2843 BOOLEAN optionshavechanged(void)
2844 {
2845 REGISTER INTBIG i, j, k, optioncomcount, val1, val2, same, len;
2846 REGISTER CHAR *name;
2847 REGISTER OPTIONVARPROTO *ovp;
2848 REGISTER TECHNOLOGY *tech;
2849 REGISTER NODEPROTO *np;
2850 REGISTER ARCPROTO *ap;
2851 REGISTER VARIABLE *var;
2852
2853 optioncomcount = sizeof(db_optionvarcoms) / sizeof(OPTIONVARCOMS);
2854 for(i=0; i<optioncomcount; i++)
2855 {
2856 ovp = db_optionvarcoms[i].variables;
2857 for(j=0; ovp[j].variablename != 0; j++)
2858 {
2859 if (!ovp[j].dirty) continue;
2860 if (ovp[j].addr == 0)
2861 {
2862 switch (ovp[j].type)
2863 {
2864 case VTECHNOLOGY:
2865 for(tech = el_technologies; tech != NOTECHNOLOGY; tech = tech->nexttechnology)
2866 {
2867 if (ovp[j].partial == 0)
2868 {
2869 var = getval((INTBIG)tech, ovp[j].type, -1, ovp[j].variablename);
2870 if (var != NOVARIABLE && (var->type&VDONTSAVE) == 0) return(TRUE);
2871 } else
2872 {
2873 len = estrlen(ovp[j].variablename);
2874 for(k=0; k<tech->numvar; k++)
2875 {
2876 var = &tech->firstvar[k];
2877 name = makename(var->key);
2878 if (namesamen(ovp[j].variablename, name, len) == 0)
2879 {
2880 if ((var->type&VDONTSAVE) == 0) return(TRUE);
2881 }
2882 }
2883 }
2884 }
2885 break;
2886 case VNODEPROTO:
2887 for(tech = el_technologies; tech != NOTECHNOLOGY; tech = tech->nexttechnology)
2888 {
2889 for(np = tech->firstnodeproto; np != NONODEPROTO; np = np->nextnodeproto)
2890 {
2891 var = getval((INTBIG)np, ovp[j].type, -1, ovp[j].variablename);
2892 if (var != NOVARIABLE && (var->type&VDONTSAVE) == 0) return(TRUE);
2893 }
2894 }
2895 break;
2896 case VARCPROTO:
2897 for(tech = el_technologies; tech != NOTECHNOLOGY; tech = tech->nexttechnology)
2898 {
2899 for(ap = tech->firstarcproto; ap != NOARCPROTO; ap = ap->nextarcproto)
2900 {
2901 var = getval((INTBIG)ap, ovp[j].type, -1, ovp[j].variablename);
2902 if (var != NOVARIABLE && (var->type&VDONTSAVE) == 0) return(TRUE);
2903 }
2904 }
2905 break;
2906 }
2907 continue;
2908 }
2909 if (ovp[j].maskbits1 != 0 || ovp[j].maskbits2 != 0)
2910 {
2911 var = getval(*ovp[j].addr, ovp[j].type, -1, ovp[j].variablename);
2912 if (var == NOVARIABLE) val1 = val2 = 0; else
2913 {
2914 if ((var->type&VTYPE) != VINTEGER) continue;
2915 if ((var->type&VISARRAY) != 0)
2916 {
2917 val1 = ((INTBIG *)var->addr)[0];
2918 val2 = ((INTBIG *)var->addr)[1];
2919 } else
2920 {
2921 val1 = var->addr;
2922 val2 = 0;
2923 }
2924 }
2925 same = 1;
2926 if (ovp[j].maskbits1 != 0)
2927 {
2928 if ((val1 & ovp[j].maskbits1) != (ovp[j].initialbits1&ovp[j].maskbits1)) same = 0;
2929 }
2930 if (ovp[j].maskbits2 != 0)
2931 {
2932 if ((val2 & ovp[j].maskbits2) != (ovp[j].initialbits2&ovp[j].maskbits2)) same = 0;
2933 }
2934 if (same != 0) continue;
2935 }
2936 return(TRUE);
2937 }
2938 }
2939 return(FALSE);
2940 }
2941
2942 /*
2943 * Routine to make all options "temporary" (set their "VDONTSAVE" bit so that they are
2944 * not saved to disk). Any exceptions to this may be specified in the
2945 * "LIB_save_options" variable of "lib". In addition, all such option variables are
2946 * remembered so that the "temporary" state can be restored later in
2947 * "us_restoreoptionstate()". This is done before saving a library so that the
2948 * options are *NOT* saved with the data. Only the "options" library has these
2949 * option variables saved with it.
2950 */
makeoptionstemporary(LIBRARY * lib)2951 void makeoptionstemporary(LIBRARY *lib)
2952 {
2953 REGISTER INTBIG teccount, arccount, nodecount, i, j, k, l, ind, optioncomcount,
2954 len;
2955 INTBIG savebits[SAVEDBITWORDS];
2956 REGISTER CHAR *name;
2957 REGISTER VARIABLE *var;
2958 REGISTER TECHNOLOGY *tech;
2959 REGISTER NODEPROTO *np;
2960 REGISTER ARCPROTO *ap;
2961 REGISTER OPTIONVARPROTO *ovp, *ovp2;
2962
2963 /* deallocate any former options variable cache */
2964 if (db_optionvarcachecount > 0) efree((CHAR *)db_optionvarcache);
2965 db_optionvarcachecount = 0;
2966
2967 /* see which options *SHOULD* be saved */
2968 for(i=0; i<SAVEDBITWORDS; i++) savebits[i] = 0;
2969 var = getval((INTBIG)lib, VLIBRARY, -1, x_("LIB_save_options"));
2970 if (var != NOVARIABLE)
2971 {
2972 if ((var->type&VISARRAY) == 0)
2973 {
2974 savebits[0] = var->addr;
2975 } else
2976 {
2977 len = getlength(var);
2978 for(i=0; i<len; i++) savebits[i] = ((INTBIG *)var->addr)[i];
2979 }
2980 }
2981
2982 /* clear flags of which options to save */
2983 optioncomcount = sizeof(db_optionvarcoms) / sizeof(OPTIONVARCOMS);
2984 for(i=0; i<optioncomcount; i++)
2985 {
2986 ovp = db_optionvarcoms[i].variables;
2987 for(j=0; ovp[j].variablename != 0; j++) ovp[j].saveflag = 0;
2988 }
2989
2990 /* set flags on options that should be saved */
2991 for(i=0; i<optioncomcount; i++)
2992 {
2993 /* see if this option package should be saved */
2994 for(j=0; j<SAVEDBITWORDS; j++)
2995 if ((db_optionvarcoms[i].bits[j]&savebits[j]) != 0) break;
2996 if (j >= SAVEDBITWORDS) continue;
2997
2998 ovp = db_optionvarcoms[i].variables;
2999 for(j=0; ovp[j].variablename != 0; j++)
3000 {
3001 ovp[j].saveflag = 1;
3002
3003 /* also save same option in other commands */
3004 for(k=0; k<optioncomcount; k++)
3005 {
3006 if (k == i) continue;
3007 ovp2 = db_optionvarcoms[k].variables;
3008 for(l=0; ovp2[l].variablename != 0; l++)
3009 {
3010 if (ovp[j].addr == ovp2[l].addr &&
3011 ovp[j].type == ovp2[l].type &&
3012 namesame(ovp[j].variablename, ovp2[l].variablename) == 0)
3013 ovp2[l].saveflag = 1;
3014 }
3015 }
3016 }
3017 }
3018
3019 /* determine the number of option variables */
3020 teccount = arccount = nodecount = 0;
3021 for(tech = el_technologies; tech != NOTECHNOLOGY; tech = tech->nexttechnology)
3022 {
3023 teccount++;
3024 for(np = tech->firstnodeproto; np != NONODEPROTO; np = np->nextnodeproto) nodecount++;
3025 for(ap = tech->firstarcproto; ap != NOARCPROTO; ap = ap->nextarcproto) arccount++;
3026 }
3027
3028 db_optionvarcachecount = 0;
3029 for(i=0; i<optioncomcount; i++)
3030 {
3031 ovp = db_optionvarcoms[i].variables;
3032 for(j=0; ovp[j].variablename != 0; j++)
3033 {
3034 if (ovp[j].saveflag != 0) continue;
3035 switch (ovp[j].type)
3036 {
3037 case VTECHNOLOGY:
3038 if (ovp[j].partial == 0) db_optionvarcachecount += teccount; else
3039 {
3040 len = estrlen(ovp[j].variablename);
3041 for(tech = el_technologies; tech != NOTECHNOLOGY; tech = tech->nexttechnology)
3042 {
3043 for(k=0; k<tech->numvar; k++)
3044 {
3045 var = &tech->firstvar[k];
3046 name = makename(var->key);
3047 if (namesamen(ovp[j].variablename, name, len) == 0)
3048 db_optionvarcachecount++;
3049 }
3050 }
3051 }
3052 break;
3053 case VNODEPROTO: db_optionvarcachecount += nodecount; break;
3054 case VARCPROTO: db_optionvarcachecount += arccount; break;
3055 default: db_optionvarcachecount++; break;
3056 }
3057 }
3058 }
3059
3060 /* allocate space for the option variable cache */
3061 db_optionvarcache = (OPTIONVARCACHE *)emalloc(db_optionvarcachecount * (sizeof (OPTIONVARCACHE)),
3062 us_tool->cluster);
3063 if (db_optionvarcache == 0)
3064 {
3065 db_optionvarcachecount = 0;
3066 return;
3067 }
3068
3069 /* load the option variable cache */
3070 ind = 0;
3071 for(i=0; i<optioncomcount; i++)
3072 {
3073 ovp = db_optionvarcoms[i].variables;
3074 for(j=0; ovp[j].variablename != 0; j++)
3075 {
3076 if (ovp[j].saveflag != 0) continue;
3077 switch (ovp[j].type)
3078 {
3079 case VTECHNOLOGY:
3080 if (ovp[j].partial == 0)
3081 {
3082 for(tech = el_technologies; tech != NOTECHNOLOGY; tech = tech->nexttechnology)
3083 {
3084 db_optionvarcache[ind].addr = (INTBIG)tech;
3085 db_optionvarcache[ind].type = VTECHNOLOGY;
3086 db_optionvarcache[ind].variablename = ovp[j].variablename;
3087 ind++;
3088 }
3089 } else
3090 {
3091 len = estrlen(ovp[j].variablename);
3092 for(tech = el_technologies; tech != NOTECHNOLOGY; tech = tech->nexttechnology)
3093 {
3094 for(k=0; k<tech->numvar; k++)
3095 {
3096 var = &tech->firstvar[k];
3097 name = makename(var->key);
3098 if (namesamen(ovp[j].variablename, name, len) != 0) continue;
3099 db_optionvarcache[ind].addr = (INTBIG)tech;
3100 db_optionvarcache[ind].type = VTECHNOLOGY;
3101 db_optionvarcache[ind].variablename = name;
3102 ind++;
3103 }
3104 }
3105 }
3106 break;
3107 case VNODEPROTO:
3108 for(tech = el_technologies; tech != NOTECHNOLOGY; tech = tech->nexttechnology)
3109 {
3110 for(np = tech->firstnodeproto; np != NONODEPROTO; np = np->nextnodeproto)
3111 {
3112 db_optionvarcache[ind].addr = (INTBIG)np;
3113 db_optionvarcache[ind].type = VNODEPROTO;
3114 db_optionvarcache[ind].variablename = ovp[j].variablename;
3115 ind++;
3116 }
3117 }
3118 break;
3119 case VARCPROTO:
3120 for(tech = el_technologies; tech != NOTECHNOLOGY; tech = tech->nexttechnology)
3121 {
3122 for(ap = tech->firstarcproto; ap != NOARCPROTO; ap = ap->nextarcproto)
3123 {
3124 db_optionvarcache[ind].addr = (INTBIG)ap;
3125 db_optionvarcache[ind].type = VARCPROTO;
3126 db_optionvarcache[ind].variablename = ovp[j].variablename;
3127 ind++;
3128 }
3129 }
3130 break;
3131 default:
3132 db_optionvarcache[ind].addr = *ovp[j].addr;
3133 db_optionvarcache[ind].type = ovp[j].type;
3134 db_optionvarcache[ind].variablename = ovp[j].variablename;
3135 ind++;
3136 break;
3137 }
3138 }
3139 }
3140
3141 /* now cache the parameter state and make them non-savable */
3142 for(i=0; i<db_optionvarcachecount; i++)
3143 {
3144 var = getval(db_optionvarcache[i].addr, db_optionvarcache[i].type, -1,
3145 db_optionvarcache[i].variablename);
3146 if (var == NOVARIABLE) continue;
3147 db_optionvarcache[i].oldtype = var->type;
3148 }
3149 for(i=0; i<db_optionvarcachecount; i++)
3150 {
3151 var = getval(db_optionvarcache[i].addr, db_optionvarcache[i].type, -1,
3152 db_optionvarcache[i].variablename);
3153 if (var == NOVARIABLE) continue;
3154 var->type |= VDONTSAVE;
3155 }
3156
3157 /* finally, cache the font association information */
3158 db_makefontassociations(lib);
3159 }
3160
3161 /*
3162 * Routine to look for non-default font usage and write the font name table.
3163 */
db_makefontassociations(LIBRARY * lib)3164 void db_makefontassociations(LIBRARY *lib)
3165 {
3166 REGISTER NODEPROTO *np;
3167 REGISTER NODEINST *ni;
3168 REGISTER ARCINST *ai;
3169 REGISTER PORTARCINST *pi;
3170 REGISTER PORTEXPINST *pe;
3171 REGISTER PORTPROTO *pp;
3172 REGISTER INTBIG *fontusage, numfonts, i, used;
3173 CHAR **list, **fontassociations;
3174 REGISTER void *infstr;
3175
3176 numfonts = screengetfacelist(&list, FALSE);
3177 fontusage = (INTBIG *)emalloc(numfonts * SIZEOFINTBIG, db_cluster);
3178 if (fontusage == 0) return;
3179 for(i=0; i<numfonts; i++) fontusage[i] = 0;
3180 for(np = lib->firstnodeproto; np != NONODEPROTO; np = np->nextnodeproto)
3181 {
3182 for(ni = np->firstnodeinst; ni != NONODEINST; ni = ni->nextnodeinst)
3183 {
3184 db_makefontassociationvar(ni->numvar, ni->firstvar, fontusage, numfonts);
3185 for(pi = ni->firstportarcinst; pi != NOPORTARCINST; pi = pi->nextportarcinst)
3186 db_makefontassociationvar(pi->numvar, pi->firstvar, fontusage, numfonts);
3187 for(pe = ni->firstportexpinst; pe != NOPORTEXPINST; pe = pe->nextportexpinst)
3188 db_makefontassociationvar(pe->numvar, pe->firstvar, fontusage, numfonts);
3189 if (ni->proto->primindex == 0)
3190 db_makefontassociationdescript(ni->textdescript, fontusage, numfonts);
3191 }
3192 for(ai = np->firstarcinst; ai != NOARCINST; ai = ai->nextarcinst)
3193 db_makefontassociationvar(ai->numvar, ai->firstvar, fontusage, numfonts);
3194 for(pp = np->firstportproto; pp != NOPORTPROTO; pp = pp->nextportproto)
3195 {
3196 db_makefontassociationvar(pp->numvar, pp->firstvar, fontusage, numfonts);
3197 db_makefontassociationdescript(pp->textdescript, fontusage, numfonts);
3198 }
3199 db_makefontassociationvar(np->numvar, np->firstvar, fontusage, numfonts);
3200 }
3201 db_makefontassociationvar(lib->numvar, lib->firstvar, fontusage, numfonts);
3202
3203 /* now look for fonts that are in use */
3204 used = 0;
3205 for(i=1; i<numfonts; i++)
3206 {
3207 if (fontusage[i] != 0) used++;
3208 }
3209 if (used > 0)
3210 {
3211 fontassociations = (CHAR **)emalloc(used * (sizeof (CHAR *)), db_cluster);
3212 if (fontassociations == 0) return;
3213 used = 0;
3214 for(i=1; i<numfonts; i++)
3215 {
3216 if (fontusage[i] == 0) continue;
3217 infstr = initinfstr();
3218 formatinfstr(infstr, x_("%ld/%s"), i, list[i]);
3219 (void)allocstring(&fontassociations[used], returninfstr(infstr), db_cluster);
3220 used++;
3221 }
3222 nextchangequiet();
3223 (void)setval((INTBIG)lib, VLIBRARY, x_("LIB_font_associations"),
3224 (INTBIG)fontassociations, VSTRING|VISARRAY|(used<<VLENGTHSH));
3225 efree((CHAR *)fontassociations);
3226 }
3227 efree((CHAR *)fontusage);
3228 }
3229
3230 /*
3231 * Helper routine for "db_makefontassociations"
3232 */
db_makefontassociationvar(INTSML numvar,VARIABLE * firstvar,INTBIG * fontusage,INTBIG numfonts)3233 void db_makefontassociationvar(INTSML numvar, VARIABLE *firstvar, INTBIG *fontusage, INTBIG numfonts)
3234 {
3235 REGISTER INTBIG i;
3236 REGISTER VARIABLE *var;
3237
3238 for(i=0; i<numvar; i++)
3239 {
3240 var = &firstvar[i];
3241 if ((var->type&VDISPLAY) != 0)
3242 db_makefontassociationdescript(var->textdescript, fontusage, numfonts);
3243 }
3244 }
3245
3246 /*
3247 * Helper routine for "db_makefontassociations"
3248 */
db_makefontassociationdescript(UINTBIG * descript,INTBIG * fontusage,INTBIG numfonts)3249 void db_makefontassociationdescript(UINTBIG *descript, INTBIG *fontusage, INTBIG numfonts)
3250 {
3251 REGISTER INTBIG face;
3252
3253 face = TDGETFACE(descript);
3254 if (face != 0)
3255 {
3256 if (face < numfonts)
3257 fontusage[face]++;
3258 }
3259 }
3260
3261 /*
3262 * Routine to restore the "temporary" state of all option variables (used after
3263 * the library has been written.
3264 */
restoreoptionstate(LIBRARY * lib)3265 void restoreoptionstate(LIBRARY *lib)
3266 {
3267 REGISTER INTBIG i;
3268 REGISTER VARIABLE *var;
3269
3270 /* restore the parameter state */
3271 for(i=0; i<db_optionvarcachecount; i++)
3272 {
3273 var = getval(db_optionvarcache[i].addr, db_optionvarcache[i].type, -1,
3274 db_optionvarcache[i].variablename);
3275 if (var == NOVARIABLE) continue;
3276 var->type = db_optionvarcache[i].oldtype;
3277 }
3278 if (getval((INTBIG)lib, VLIBRARY, VSTRING|VISARRAY, x_("LIB_font_associations")) != NOVARIABLE)
3279 {
3280 nextchangequiet();
3281 (void)delval((INTBIG)lib, VLIBRARY, x_("LIB_font_associations"));
3282 }
3283 }
3284
3285 /******************** PARAMETERIZED CELLS ********************/
3286
3287 /*
3288 * Routine to initialize the current list of parameterized cells.
3289 */
initparameterizedcells(void)3290 void initparameterizedcells(void)
3291 {
3292 REGISTER PARCELL *pc;
3293
3294 while (db_firstparcell != NOPARCELL)
3295 {
3296 pc = db_firstparcell;
3297 db_firstparcell = pc->nextparcell;
3298 efree((CHAR *)pc->parname);
3299 efree((CHAR *)pc->shortname);
3300 db_freeparcell(pc);
3301 }
3302 }
3303
3304 /*
3305 * Routine to check to see if parameterization "parname" of cell "np" is in the
3306 * list of parameterized cells. If found, returns pointer to the name (or
3307 * the short name if there is one). If not found, returns 0.
3308 */
inparameterizedcells(NODEPROTO * np,CHAR * parname)3309 CHAR *inparameterizedcells(NODEPROTO *np, CHAR *parname)
3310 {
3311 REGISTER PARCELL *pc;
3312 REGISTER NODEPROTO *onp;
3313
3314 for(pc = db_firstparcell; pc != NOPARCELL; pc = pc->nextparcell)
3315 {
3316 FOR_CELLGROUP(onp, np)
3317 if (pc->cell == onp) break;
3318 if (onp == NONODEPROTO) continue;
3319 if (namesame(pc->parname, parname) == 0)
3320 {
3321 if (pc->shortname != 0) return(pc->shortname);
3322 return(pc->parname);
3323 }
3324 }
3325 return(0);
3326 }
3327
3328 /*
3329 * Routine to add parameterization "parname" of cell "np" to the
3330 * list of parameterized cells.
3331 */
addtoparameterizedcells(NODEPROTO * np,CHAR * parname,CHAR * shortname)3332 void addtoparameterizedcells(NODEPROTO *np, CHAR *parname, CHAR *shortname)
3333 {
3334 REGISTER PARCELL *pc;
3335
3336 pc = db_allocparcell();
3337 if (pc == NOPARCELL) return;
3338 pc->cell = np;
3339 (void)allocstring(&pc->parname, parname, db_cluster);
3340 if (shortname == 0) pc->shortname = 0; else
3341 (void)allocstring(&pc->shortname, shortname, db_cluster);
3342 pc->nextparcell = db_firstparcell;
3343 db_firstparcell = pc;
3344 }
3345
3346 /*
3347 * Routine to create a parameterized name for node instance "ni".
3348 * If the node is not parameterized, returns zero.
3349 * If it returns a name, that name must be deallocated when done.
3350 */
parameterizedname(NODEINST * ni,CHAR * cellname)3351 CHAR *parameterizedname(NODEINST *ni, CHAR *cellname)
3352 {
3353 REGISTER INTBIG i;
3354 REGISTER VARIABLE *var, *evar;
3355 CHAR *name;
3356 REGISTER void *infstr;
3357 REGISTER BOOLEAN oldonobjectstate;
3358
3359 if (ni->proto->primindex != 0) return(0);
3360 for(i=0; i<ni->numvar; i++)
3361 {
3362 var = &ni->firstvar[i];
3363 if (TDGETISPARAM(var->textdescript) != 0) break;
3364 }
3365 if (i >= ni->numvar) return(0);
3366 infstr = initinfstr();
3367 addstringtoinfstr(infstr, cellname);
3368 for(i=0; i<ni->numvar; i++)
3369 {
3370 var = &ni->firstvar[i];
3371 if (TDGETISPARAM(var->textdescript) == 0) continue;
3372
3373 /* accumulate the object that we are on (should use mutex) */
3374 oldonobjectstate = db_onanobject;
3375 if (!db_onanobject)
3376 {
3377 db_onanobject = TRUE;
3378 db_onobjectaddr = (INTBIG)ni;
3379 db_onobjecttype = VNODEINST;
3380 }
3381 db_lastonobjectaddr = (INTBIG)ni;
3382 db_lastonobjecttype = VNODEINST;
3383 evar = evalvar(var, (INTBIG)ni, VNODEINST);
3384
3385 /* complete the accumulation of the "getval" object (should use mutex) */
3386 db_onanobject = oldonobjectstate;
3387 formatinfstr(infstr, x_("-%s-%s"), truevariablename(var),
3388 describevariable(evar, -1, -1));
3389 }
3390 (void)allocstring(&name, returninfstr(infstr), el_tempcluster);
3391 return(name);
3392 }
3393
3394 /*
3395 * Routine to implement a parameterized cell object. Returns
3396 * NOPARCELL on error.
3397 */
db_allocparcell(void)3398 PARCELL *db_allocparcell(void)
3399 {
3400 REGISTER PARCELL *pc;
3401
3402 if (db_parcellfree != NOPARCELL)
3403 {
3404 pc = db_parcellfree;
3405 db_parcellfree = pc->nextparcell;
3406 } else
3407 {
3408 pc = (PARCELL *)emalloc(sizeof (PARCELL), db_cluster);
3409 if (pc == 0) return(NOPARCELL);
3410 }
3411 return(pc);
3412 }
3413
3414 /*
3415 * Routine to return parameterized cell object "pc" to the free list.
3416 */
db_freeparcell(PARCELL * pc)3417 void db_freeparcell(PARCELL *pc)
3418 {
3419 pc->nextparcell = db_parcellfree;
3420 db_parcellfree = pc;
3421 }
3422
3423 /************************* DEPRECATED VARIABLES *************************/
3424
3425 CHAR *el_deprecatednodeprotovariables[] =
3426 {
3427 x_("NET_last_good_ncc"),
3428 x_("NET_last_good_ncc_facet"),
3429 x_("SIM_window_signal_order"),
3430 0
3431 };
3432
3433 struct
3434 {
3435 TOOL **tooladdr;
3436 CHAR *varname;
3437 } el_deprecatedtoolvariables[] =
3438 {
3439 {&net_tool, x_("NET_auto_name")},
3440 {&net_tool, x_("NET_use_port_names")},
3441 {&net_tool, x_("NET_compare_hierarchy")},
3442 {&net_tool, x_("D")},
3443 {&net_tool, x_("<")},
3444 {&net_tool, x_("\001")},
3445 {&us_tool, x_("USER_alignment_obj")},
3446 {&us_tool, x_("USER_alignment_edge")},
3447 {&sim_tool, x_("SIM_fasthenry_defthickness")},
3448 {&dr_tool, x_("DRC_pointout")},
3449 {0, 0}
3450 };
3451
isdeprecatedvariable(INTBIG addr,INTBIG type,CHAR * name)3452 BOOLEAN isdeprecatedvariable(INTBIG addr, INTBIG type, CHAR *name)
3453 {
3454 REGISTER INTBIG i;
3455
3456 if (type == VNODEPROTO)
3457 {
3458 for(i=0; el_deprecatednodeprotovariables[i] != 0; i++)
3459 if (namesame(name, el_deprecatednodeprotovariables[i]) == 0) return(TRUE);
3460 return(FALSE);
3461 }
3462 if (type == VTOOL)
3463 {
3464 for(i=0; el_deprecatedtoolvariables[i].tooladdr != 0; i++)
3465 {
3466 if (*el_deprecatedtoolvariables[i].tooladdr != (TOOL *)addr) continue;
3467 if (namesame(name, el_deprecatedtoolvariables[i].varname) == 0) return(TRUE);
3468 }
3469 return(FALSE);
3470 }
3471 return(FALSE);
3472 }
3473
3474 /************************* DATA FOR TYPES *************************/
3475
3476 /*
3477 * In the "type" field of a variable, the VCREF bit is typically set
3478 * to indicate that the variable points into the fixed C structures, and
3479 * is not part of the extendable attributes in "firstvar/numvar". However,
3480 * in the tables below, the VCREF bit is used to indicate dereferencing
3481 * in array attributes. Those arrays that are fixed in size or otherwise
3482 * part of the C structure need no dereferencing, and have the VCREF bit set
3483 * (see RTNODE->pointers, GRAPHICS->raster, NODEINST->textdescript, PORTPROTO->textdescript,
3484 * and POLYGON->textdescript). Those arrays that vary in length have only pointers in
3485 * their C structures, and need dereferencing (see PORTPROTO->connects, LIBRARY->lambda,
3486 * TECHNOLOGY->layers, NETWORK->arcaddr, and NETWORK->networklist). These
3487 * do not have the VCREF bit set.
3488 */
3489
3490 static NODEINST db_ptni;
3491 static NAMEVARS db_nodevars[] =
3492 {
3493 {x_("arraysize"), VINTEGER|VCANTSET, (INTBIG*)&db_ptni.arraysize},
3494 {x_("firstportarcinst"), VPORTARCINST|VCANTSET, (INTBIG*)&db_ptni.firstportarcinst},
3495 {x_("firstportexpinst"), VPORTEXPINST|VCANTSET, (INTBIG*)&db_ptni.firstportexpinst},
3496 {x_("geom"), VGEOM|VCANTSET, (INTBIG*)&db_ptni.geom},
3497 {x_("highx"), VINTEGER|VCANTSET, (INTBIG*)&db_ptni.highx},
3498 {x_("highy"), VINTEGER|VCANTSET, (INTBIG*)&db_ptni.highy},
3499 {x_("lowx"), VINTEGER|VCANTSET, (INTBIG*)&db_ptni.lowx},
3500 {x_("lowy"), VINTEGER|VCANTSET, (INTBIG*)&db_ptni.lowy},
3501 {x_("nextinst"), VNODEINST|VCANTSET, (INTBIG*)&db_ptni.nextinst},
3502 {x_("nextnodeinst"), VNODEINST|VCANTSET, (INTBIG*)&db_ptni.nextnodeinst},
3503 {x_("parent"), VNODEPROTO|VCANTSET, (INTBIG*)&db_ptni.parent},
3504 {x_("previnst"), VNODEINST|VCANTSET, (INTBIG*)&db_ptni.previnst},
3505 {x_("prevnodeinst"), VNODEINST|VCANTSET, (INTBIG*)&db_ptni.prevnodeinst},
3506 {x_("proto"), VNODEPROTO|VCANTSET, (INTBIG*)&db_ptni.proto},
3507 {x_("rotation"), VSHORT|VCANTSET, (INTBIG*)&db_ptni.rotation},
3508 {x_("temp1"), VINTEGER, (INTBIG*)&db_ptni.temp1},
3509 {x_("temp2"), VINTEGER, (INTBIG*)&db_ptni.temp2},
3510 {x_("textdescript"), VINTEGER|VISARRAY|(TEXTDESCRIPTSIZE<<VLENGTHSH)|VCREF, (INTBIG*)db_ptni.textdescript},
3511 {x_("transpose"), VSHORT|VCANTSET, (INTBIG*)&db_ptni.transpose},
3512 {x_("userbits"), VINTEGER, (INTBIG*)&db_ptni.userbits},
3513 {NULL, 0, NULL} /* 0 */
3514 };
3515
3516 /*
3517 * entry 9 of the table below ("globalnetchar") gets changed by "db_initnodeprotolist"
3518 * entry 10 of the table below ("globalnetworks") gets changed by "db_initnodeprotolist"
3519 */
3520 static NODEPROTO db_ptnp;
3521 static NAMEVARS db_nodeprotovars[] =
3522 {
3523 {x_("adirty"), VINTEGER|VCANTSET, (INTBIG*)&db_ptnp.adirty},
3524 {x_("cellview"), VVIEW, (INTBIG*)&db_ptnp.cellview},
3525 {x_("creationdate"), VINTEGER|VCANTSET, (INTBIG*)&db_ptnp.creationdate},
3526 {x_("firstarcinst"), VARCINST|VCANTSET, (INTBIG*)&db_ptnp.firstarcinst},
3527 {x_("firstinst"), VNODEINST|VCANTSET, (INTBIG*)&db_ptnp.firstinst},
3528 {x_("firstnetwork"), VNETWORK|VCANTSET, (INTBIG*)&db_ptnp.firstnetwork},
3529 {x_("firstnodeinst"), VNODEINST|VCANTSET, (INTBIG*)&db_ptnp.firstnodeinst},
3530 {x_("firstportproto"), VPORTPROTO|VCANTSET, (INTBIG*)&db_ptnp.firstportproto},
3531 {x_("globalnetcount"), VINTEGER|VCANTSET, (INTBIG*)&db_ptnp.globalnetcount},
3532 {x_("globalnetchar"), VINTEGER|VISARRAY|VCANTSET, (INTBIG*)&db_ptnp.globalnetchar},
3533 {x_("globalnetworks"), VNETWORK|VISARRAY|VCANTSET, (INTBIG*)&db_ptnp.globalnetworks},
3534 {x_("highx"), VINTEGER, (INTBIG*)&db_ptnp.highx},
3535 {x_("highy"), VINTEGER, (INTBIG*)&db_ptnp.highy},
3536 {x_("lib"), VLIBRARY|VCANTSET, (INTBIG*)&db_ptnp.lib},
3537 {x_("lowx"), VINTEGER, (INTBIG*)&db_ptnp.lowx},
3538 {x_("lowy"), VINTEGER, (INTBIG*)&db_ptnp.lowy},
3539 {x_("netd"), VUNKNOWN|VCANTSET, (INTBIG*)&db_ptnp.netd},
3540 {x_("newestversion"), VNODEPROTO|VCANTSET, (INTBIG*)&db_ptnp.newestversion},
3541 {x_("nextcellgrp"), VNODEPROTO|VCANTSET, (INTBIG*)&db_ptnp.nextcellgrp},
3542 {x_("nextcont"), VNODEPROTO|VCANTSET, (INTBIG*)&db_ptnp.nextcont},
3543 {x_("nextnodeproto"), VNODEPROTO|VCANTSET, (INTBIG*)&db_ptnp.nextnodeproto},
3544 {x_("numportprotos"), VINTEGER|VCANTSET, (INTBIG*)&db_ptnp.numportprotos},
3545 {x_("portprotohashtablesize"),VINTEGER|VCANTSET, (INTBIG*)&db_ptnp.portprotohashtablesize},
3546 {x_("prevnodeproto"), VNODEPROTO|VCANTSET, (INTBIG*)&db_ptnp.prevnodeproto},
3547 {x_("prevversion"), VNODEPROTO|VCANTSET, (INTBIG*)&db_ptnp.prevversion},
3548 {x_("primindex"), VINTEGER|VCANTSET, (INTBIG*)&db_ptnp.primindex},
3549 {x_("protoname"), VSTRING, (INTBIG*)&db_ptnp.protoname},
3550 {x_("revisiondate"), VINTEGER|VCANTSET, (INTBIG*)&db_ptnp.revisiondate},
3551 {x_("rtree"), VRTNODE|VCANTSET, (INTBIG*)&db_ptnp.rtree},
3552 {x_("tech"), VTECHNOLOGY|VCANTSET, (INTBIG*)&db_ptnp.tech},
3553 {x_("temp1"), VINTEGER, (INTBIG*)&db_ptnp.temp1},
3554 {x_("temp2"), VINTEGER, (INTBIG*)&db_ptnp.temp2},
3555 {x_("userbits"), VINTEGER, (INTBIG*)&db_ptnp.userbits},
3556 {x_("version"), VINTEGER|VCANTSET, (INTBIG*)&db_ptnp.version},
3557 {NULL, 0, NULL} /* 0 */
3558 };
3559
3560 static PORTARCINST db_ptpi;
3561 static NAMEVARS db_portavars[] =
3562 {
3563 {x_("conarcinst"), VARCINST|VCANTSET, (INTBIG*)&db_ptpi.conarcinst},
3564 {x_("nextportarcinst"), VPORTARCINST|VCANTSET, (INTBIG*)&db_ptpi.nextportarcinst},
3565 {x_("proto"), VPORTPROTO|VCANTSET, (INTBIG*)&db_ptpi.proto},
3566 {NULL, 0, NULL} /* 0 */
3567 };
3568
3569 static PORTEXPINST db_ptpe;
3570 static NAMEVARS db_portevars[] =
3571 {
3572 {x_("exportproto"), VPORTPROTO|VCANTSET, (INTBIG*)&db_ptpe.exportproto},
3573 {x_("nextportexpinst"), VPORTEXPINST|VCANTSET, (INTBIG*)&db_ptpe.nextportexpinst},
3574 {x_("proto"), VPORTPROTO|VCANTSET, (INTBIG*)&db_ptpe.proto},
3575 {NULL, 0, NULL} /* 0 */
3576 };
3577
3578 static PORTPROTO db_ptpp;
3579 static NAMEVARS db_portprotovars[] =
3580 {
3581 {x_("connects"), VARCPROTO|VISARRAY|VCANTSET,(INTBIG*)&db_ptpp.connects},
3582 {x_("network"), VNETWORK|VCANTSET, (INTBIG*)&db_ptpp.network},
3583 {x_("nextportproto"), VPORTPROTO|VCANTSET, (INTBIG*)&db_ptpp.nextportproto},
3584 {x_("parent"), VNODEPROTO|VCANTSET, (INTBIG*)&db_ptpp.parent},
3585 {x_("protoname"), VSTRING, (INTBIG*)&db_ptpp.protoname},
3586 {x_("subnodeinst"), VNODEINST|VCANTSET, (INTBIG*)&db_ptpp.subnodeinst},
3587 {x_("subportexpinst"), VPORTEXPINST|VCANTSET, (INTBIG*)&db_ptpp.subportexpinst},
3588 {x_("subportproto"), VPORTPROTO|VCANTSET, (INTBIG*)&db_ptpp.subportproto},
3589 {x_("temp1"), VINTEGER, (INTBIG*)&db_ptpp.temp1},
3590 {x_("temp2"), VINTEGER, (INTBIG*)&db_ptpp.temp2},
3591 {x_("textdescript"), VINTEGER|VISARRAY|(TEXTDESCRIPTSIZE<<VLENGTHSH)|VCREF,(INTBIG*)db_ptpp.textdescript},
3592 {x_("userbits"), VINTEGER, (INTBIG*)&db_ptpp.userbits},
3593 {NULL, 0, NULL} /* 0 */
3594 };
3595
3596 static ARCINST db_ptai;
3597 static NAMEVARS db_arcvars[] =
3598 {
3599 {x_("endshrink"), VINTEGER|VCANTSET, (INTBIG*)&db_ptai.endshrink},
3600 {x_("geom"), VGEOM|VCANTSET, (INTBIG*)&db_ptai.geom},
3601 {x_("length"), VINTEGER|VCANTSET, (INTBIG*)&db_ptai.length},
3602 {x_("network"), VNETWORK|VCANTSET, (INTBIG*)&db_ptai.network},
3603 {x_("nextarcinst"), VARCINST|VCANTSET, (INTBIG*)&db_ptai.nextarcinst},
3604 {x_("nodeinst1"), VNODEINST|VCANTSET, (INTBIG*)&db_ptai.end[0].nodeinst},
3605 {x_("nodeinst2"), VNODEINST|VCANTSET, (INTBIG*)&db_ptai.end[1].nodeinst},
3606 {x_("parent"), VNODEPROTO|VCANTSET, (INTBIG*)&db_ptai.parent},
3607 {x_("portarcinst1"), VPORTARCINST|VCANTSET, (INTBIG*)&db_ptai.end[0].portarcinst},
3608 {x_("portarcinst2"), VPORTARCINST|VCANTSET, (INTBIG*)&db_ptai.end[1].portarcinst},
3609 {x_("prevarcinst"), VARCINST|VCANTSET, (INTBIG*)&db_ptai.prevarcinst},
3610 {x_("proto"), VARCPROTO|VCANTSET, (INTBIG*)&db_ptai.proto},
3611 {x_("temp1"), VINTEGER, (INTBIG*)&db_ptai.temp1},
3612 {x_("temp2"), VINTEGER, (INTBIG*)&db_ptai.temp2},
3613 {x_("userbits"), VINTEGER, (INTBIG*)&db_ptai.userbits},
3614 {x_("width"), VINTEGER|VCANTSET, (INTBIG*)&db_ptai.width},
3615 {x_("xpos1"), VINTEGER|VCANTSET, (INTBIG*)&db_ptai.end[0].xpos},
3616 {x_("xpos2"), VINTEGER|VCANTSET, (INTBIG*)&db_ptai.end[1].xpos},
3617 {x_("ypos1"), VINTEGER|VCANTSET, (INTBIG*)&db_ptai.end[0].ypos},
3618 {x_("ypos2"), VINTEGER|VCANTSET, (INTBIG*)&db_ptai.end[1].ypos},
3619 {NULL, 0, NULL} /* 0 */
3620 };
3621
3622 static ARCPROTO db_ptap;
3623 static NAMEVARS db_arcprotovars[] =
3624 {
3625 {x_("arcindex"), VINTEGER|VCANTSET, (INTBIG*)&db_ptap.arcindex},
3626 {x_("nextarcproto"), VARCPROTO|VCANTSET, (INTBIG*)&db_ptap.nextarcproto},
3627 {x_("nominalwidth"), VINTEGER, (INTBIG*)&db_ptap.nominalwidth},
3628 {x_("protoname"), VSTRING, (INTBIG*)&db_ptap.protoname},
3629 {x_("tech"), VTECHNOLOGY|VCANTSET, (INTBIG*)&db_ptap.tech},
3630 {x_("temp1"), VINTEGER, (INTBIG*)&db_ptap.temp1},
3631 {x_("temp2"), VINTEGER, (INTBIG*)&db_ptap.temp2},
3632 {x_("userbits"), VINTEGER, (INTBIG*)&db_ptap.userbits},
3633 {NULL, 0, NULL} /* 0 */
3634 };
3635
3636 static GEOM db_ptgeom;
3637 static NAMEVARS db_geomvars[] =
3638 {
3639 {x_("entryisnode"), VBOOLEAN|VCANTSET, (INTBIG*)&db_ptgeom.entryisnode},
3640 {x_("entryaddr"), VINTEGER|VCANTSET, (INTBIG*)&db_ptgeom.entryaddr},
3641 {x_("highx"), VINTEGER|VCANTSET, (INTBIG*)&db_ptgeom.highx},
3642 {x_("highy"), VINTEGER|VCANTSET, (INTBIG*)&db_ptgeom.highy},
3643 {x_("lowx"), VINTEGER|VCANTSET, (INTBIG*)&db_ptgeom.lowx},
3644 {x_("lowy"), VINTEGER|VCANTSET, (INTBIG*)&db_ptgeom.lowy},
3645 {NULL, 0, NULL} /* 0 */
3646 };
3647
3648 static LIBRARY db_ptlib;
3649 static NAMEVARS db_libvars[] =
3650 {
3651 {x_("curnodeproto"), VNODEPROTO, (INTBIG*)&db_ptlib.curnodeproto},
3652 {x_("firstnodeproto"), VNODEPROTO|VCANTSET, (INTBIG*)&db_ptlib.firstnodeproto},
3653 {x_("lambda"), VINTEGER|VISARRAY|VCANTSET, (INTBIG*)&db_ptlib.lambda},
3654 {x_("libname"), VSTRING, (INTBIG*)&db_ptlib.libname},
3655 {x_("libfile"), VSTRING, (INTBIG*)&db_ptlib.libfile},
3656 {x_("nextlibrary"), VLIBRARY|VCANTSET, (INTBIG*)&db_ptlib.nextlibrary},
3657 {x_("nodeprotohashtablesize"),VINTEGER|VCANTSET, (INTBIG*)&db_ptlib.nodeprotohashtablesize},
3658 {x_("numnodeprotos"), VINTEGER|VCANTSET, (INTBIG*)&db_ptlib.numnodeprotos},
3659 {x_("tailnodeproto"), VNODEPROTO|VCANTSET, (INTBIG*)&db_ptlib.tailnodeproto},
3660 {x_("temp1"), VINTEGER, (INTBIG*)&db_ptlib.temp1},
3661 {x_("temp2"), VINTEGER, (INTBIG*)&db_ptlib.temp2},
3662 {x_("userbits"), VINTEGER, (INTBIG*)&db_ptlib.userbits},
3663 {NULL, 0, NULL} /* 0 */
3664 };
3665
3666 /*
3667 * entry 5 of the table below ("layers") gets changed by "db_inittechlist"
3668 */
3669 static TECHNOLOGY db_pttech;
3670 static NAMEVARS db_techvars[] =
3671 {
3672 {x_("arcprotocount"), VINTEGER|VCANTSET, (INTBIG*)&db_pttech.arcprotocount},
3673 {x_("deflambda"), VINTEGER|VCANTSET, (INTBIG*)&db_pttech.deflambda},
3674 {x_("firstarcproto"), VARCPROTO|VCANTSET, (INTBIG*)&db_pttech.firstarcproto},
3675 {x_("firstnodeproto"), VNODEPROTO|VCANTSET, (INTBIG*)&db_pttech.firstnodeproto},
3676 {x_("layercount"), VINTEGER|VCANTSET, (INTBIG*)&db_pttech.layercount},
3677 {x_("layers"), VGRAPHICS|VISARRAY|VCANTSET,(INTBIG*)&db_pttech.layers},
3678 {x_("nexttechnology"), VTECHNOLOGY|VCANTSET, (INTBIG*)&db_pttech.nexttechnology},
3679 {x_("nodeprotocount"), VINTEGER|VCANTSET, (INTBIG*)&db_pttech.nodeprotocount},
3680 {x_("techdescript"), VSTRING|VCANTSET, (INTBIG*)&db_pttech.techdescript},
3681 {x_("techindex"), VINTEGER|VCANTSET, (INTBIG*)&db_pttech.techindex},
3682 {x_("techname"), VSTRING, (INTBIG*)&db_pttech.techname},
3683 {x_("temp1"), VINTEGER, (INTBIG*)&db_pttech.temp1},
3684 {x_("temp2"), VINTEGER, (INTBIG*)&db_pttech.temp2},
3685 {x_("userbits"), VINTEGER, (INTBIG*)&db_pttech.userbits},
3686 {NULL, 0, NULL} /* 0 */
3687 };
3688
3689 static TOOL db_pttool;
3690 static NAMEVARS db_toolvars[] =
3691 {
3692 {x_("toolindex"), VINTEGER|VCANTSET, (INTBIG*)&db_pttool.toolindex},
3693 {x_("toolname"), VSTRING|VCANTSET, (INTBIG*)&db_pttool.toolname},
3694 {x_("toolstate"), VINTEGER, (INTBIG*)&db_pttool.toolstate},
3695 {NULL, 0, NULL} /* 0 */
3696 };
3697
3698 /*
3699 * entry 6 of the table below ("pointers") gets changed by "db_initrtnodelist"
3700 */
3701 static RTNODE db_ptrtn;
3702 static NAMEVARS db_rtnvars[] =
3703 {
3704 {x_("flag"), VSHORT|VCANTSET, (INTBIG*)&db_ptrtn.flag},
3705 {x_("highx"), VINTEGER|VCANTSET, (INTBIG*)&db_ptrtn.highx},
3706 {x_("highy"), VINTEGER|VCANTSET, (INTBIG*)&db_ptrtn.highy},
3707 {x_("lowx"), VINTEGER|VCANTSET, (INTBIG*)&db_ptrtn.lowx},
3708 {x_("lowy"), VINTEGER|VCANTSET, (INTBIG*)&db_ptrtn.lowy},
3709 {x_("parent"), VRTNODE|VCANTSET, (INTBIG*)&db_ptrtn.parent},
3710 {x_("pointers"), VRTNODE|VISARRAY|VCANTSET|VCREF, (INTBIG*)db_ptrtn.pointers},
3711 {x_("total"), VSHORT|VCANTSET, (INTBIG*)&db_ptrtn.total},
3712 {NULL, 0, NULL} /* 0 */
3713 };
3714
3715 /*
3716 * entry 0 of the table below ("arcaddr") gets changed by "db_initnetworklist"
3717 * entry 6 of the table below ("networklist") also gets changed
3718 */
3719 static NETWORK db_ptnet;
3720 static NAMEVARS db_netvars[] =
3721 {
3722 {x_("arcaddr"), VARCINST|VISARRAY|VCANTSET, (INTBIG*)&db_ptnet.arcaddr},
3723 {x_("arccount"), VSHORT|VCANTSET, (INTBIG*)&db_ptnet.arccount},
3724 {x_("arctotal"), VSHORT|VCANTSET, (INTBIG*)&db_ptnet.arctotal},
3725 {x_("buslinkcount"), VSHORT|VCANTSET, (INTBIG*)&db_ptnet.buslinkcount},
3726 {x_("globalnet"), VSHORT|VCANTSET, (INTBIG*)&db_ptnet.globalnet},
3727 {x_("namecount"), VSHORT|VCANTSET, (INTBIG*)&db_ptnet.namecount},
3728 {x_("netnameaddr"), VINTEGER|VCANTSET, (INTBIG*)&db_ptnet.netnameaddr},
3729 {x_("networklist"), VNETWORK|VISARRAY|VCANTSET, (INTBIG*)&db_ptnet.networklist},
3730 {x_("nextnetwork"), VNETWORK|VCANTSET, (INTBIG*)&db_ptnet.nextnetwork},
3731 {x_("parent"), VNODEPROTO|VCANTSET, (INTBIG*)&db_ptnet.parent},
3732 {x_("portcount"), VSHORT|VCANTSET, (INTBIG*)&db_ptnet.portcount},
3733 {x_("prevnetwork"), VNETWORK|VCANTSET, (INTBIG*)&db_ptnet.prevnetwork},
3734 {x_("refcount") , VSHORT|VCANTSET, (INTBIG*)&db_ptnet.refcount},
3735 {x_("buswidth"), VSHORT|VCANTSET, (INTBIG*)&db_ptnet.buswidth},
3736 {x_("temp1"), VINTEGER, (INTBIG*)&db_ptnet.temp1},
3737 {x_("temp2"), VINTEGER, (INTBIG*)&db_ptnet.temp2},
3738 {NULL, 0, NULL} /* 0 */
3739 };
3740
3741 static VIEW db_ptview;
3742 static NAMEVARS db_viewvars[] =
3743 {
3744 {x_("nextview"), VVIEW|VCANTSET, (INTBIG*)&db_ptview.nextview},
3745 {x_("sviewname"), VSTRING|VCANTSET, (INTBIG*)&db_ptview.sviewname},
3746 {x_("temp1"), VINTEGER, (INTBIG*)&db_ptview.temp1},
3747 {x_("temp2"), VINTEGER, (INTBIG*)&db_ptview.temp2},
3748 {x_("viewname"), VSTRING|VCANTSET, (INTBIG*)&db_ptview.viewname},
3749 {x_("viewstate"), VINTEGER|VCANTSET, (INTBIG*)&db_ptview.viewstate},
3750 {NULL, 0, NULL} /* 0 */
3751 };
3752
3753 static WINDOWPART db_ptwin;
3754 static NAMEVARS db_winvars[] =
3755 {
3756 {x_("buttonhandler"), VADDRESS, (INTBIG*)&db_ptwin.buttonhandler},
3757 {x_("changehandler"), VADDRESS, (INTBIG*)&db_ptwin.changehandler},
3758 {x_("charhandler"), VADDRESS, (INTBIG*)&db_ptwin.charhandler},
3759 {x_("curnodeproto"), VNODEPROTO, (INTBIG*)&db_ptwin.curnodeproto},
3760 {x_("editor"), VADDRESS, (INTBIG*)&db_ptwin.editor},
3761 {x_("expwindow"), VADDRESS, (INTBIG*)&db_ptwin.expwindow},
3762 {x_("frame"), VWINDOWFRAME|VCANTSET, (INTBIG*)&db_ptwin.frame},
3763 {x_("framehx"), VINTEGER, (INTBIG*)&db_ptwin.framehx},
3764 {x_("framehy"), VINTEGER, (INTBIG*)&db_ptwin.framehy},
3765 {x_("framelx"), VINTEGER, (INTBIG*)&db_ptwin.framelx},
3766 {x_("framely"), VINTEGER, (INTBIG*)&db_ptwin.framely},
3767 {x_("gridx"), VINTEGER, (INTBIG*)&db_ptwin.gridx},
3768 {x_("gridy"), VINTEGER, (INTBIG*)&db_ptwin.gridy},
3769 {x_("hratio"), VINTEGER, (INTBIG*)&db_ptwin.hratio},
3770 {x_("inplacedepth"), VINTEGER, (INTBIG*)&db_ptwin.inplacedepth},
3771 {x_("inplacestack"), VNODEINST|VISARRAY|(MAXINPLACEDEPTH<<VLENGTHSH)|VCREF,(INTBIG*)db_ptwin.inplacestack},
3772 {x_("intocell"), VINTEGER|VISARRAY|(9<<VLENGTHSH)|VCREF,(INTBIG*)db_ptwin.intocell},
3773 {x_("linkedwindowpart"), VWINDOWPART|VCANTSET, (INTBIG*)&db_ptwin.linkedwindowpart},
3774 {x_("location"), VSTRING|VCANTSET, (INTBIG*)&db_ptwin.location},
3775 {x_("nextwindowpart"), VWINDOWPART|VCANTSET, (INTBIG*)&db_ptwin.nextwindowpart},
3776 {x_("outofcell"), VINTEGER|VISARRAY|(9<<VLENGTHSH)|VCREF,(INTBIG*)db_ptwin.outofcell},
3777 {x_("prevwindowpart"), VWINDOWPART|VCANTSET, (INTBIG*)&db_ptwin.prevwindowpart},
3778 {x_("redisphandler"), VADDRESS, (INTBIG*)&db_ptwin.redisphandler},
3779 {x_("scalex"), VFLOAT, (INTBIG*)&db_ptwin.scalex},
3780 {x_("scaley"), VFLOAT, (INTBIG*)&db_ptwin.scaley},
3781 {x_("screenhx"), VINTEGER, (INTBIG*)&db_ptwin.screenhx},
3782 {x_("screenhy"), VINTEGER, (INTBIG*)&db_ptwin.screenhy},
3783 {x_("screenlx"), VINTEGER, (INTBIG*)&db_ptwin.screenlx},
3784 {x_("screenly"), VINTEGER, (INTBIG*)&db_ptwin.screenly},
3785 {x_("state"), VINTEGER, (INTBIG*)&db_ptwin.state},
3786 {x_("termhandler"), VADDRESS, (INTBIG*)&db_ptwin.termhandler},
3787 {x_("thumbhx"), VINTEGER, (INTBIG*)&db_ptwin.thumbhx},
3788 {x_("thumbhy"), VINTEGER, (INTBIG*)&db_ptwin.thumbhy},
3789 {x_("thumblx"), VINTEGER, (INTBIG*)&db_ptwin.thumblx},
3790 {x_("thumbly"), VINTEGER, (INTBIG*)&db_ptwin.thumbly},
3791 {x_("topnodeproto"), VNODEPROTO, (INTBIG*)&db_ptwin.topnodeproto},
3792 {x_("usehx"), VINTEGER, (INTBIG*)&db_ptwin.usehx},
3793 {x_("usehy"), VINTEGER, (INTBIG*)&db_ptwin.usehy},
3794 {x_("uselx"), VINTEGER, (INTBIG*)&db_ptwin.uselx},
3795 {x_("usely"), VINTEGER, (INTBIG*)&db_ptwin.usely},
3796 {x_("vratio"), VINTEGER, (INTBIG*)&db_ptwin.vratio},
3797 {NULL, 0, NULL} /* 0 */
3798 };
3799
3800 static GRAPHICS db_ptgra;
3801 static NAMEVARS db_gravars[] =
3802 {
3803 {x_("bits"), VINTEGER, (INTBIG*)&db_ptgra.bits},
3804 {x_("bwstyle"), VSHORT, (INTBIG*)&db_ptgra.bwstyle},
3805 {x_("col"), VINTEGER, (INTBIG*)&db_ptgra.col},
3806 {x_("colstyle"), VSHORT, (INTBIG*)&db_ptgra.colstyle},
3807 {x_("raster"), VSHORT|VISARRAY|(16<<VLENGTHSH)|VCREF, (INTBIG*)db_ptgra.raster},
3808 {NULL, 0, NULL} /* 0 */
3809 };
3810
3811 static CONSTRAINT db_ptcon;
3812 static NAMEVARS db_convars[] =
3813 {
3814 {x_("conname"), VSTRING|VCANTSET, (INTBIG*)&db_ptcon.conname},
3815 {NULL, 0, NULL} /* 0 */
3816 };
3817
3818 static WINDOWFRAME db_ptwf;
3819 static NAMEVARS db_wfvars[] =
3820 {
3821 {x_("floating"), VBOOLEAN, (INTBIG*)&db_ptwf.floating},
3822 {x_("width"), VINTEGER, (INTBIG*)&db_ptwf.swid},
3823 {x_("height"), VINTEGER, (INTBIG*)&db_ptwf.shei},
3824 {x_("yreverse"), VINTEGER, (INTBIG*)&db_ptwf.revy},
3825 {NULL, 0, NULL} /* 0 */
3826 };
3827
3828 /*
3829 * entry 0 of the table below ("xv") gets changed by "db_initpolygonlist"
3830 * entry 1 of the table below ("yv") also gets changed
3831 */
3832 static POLYGON db_ptpoly;
3833 static NAMEVARS db_polyvars[] =
3834 {
3835 /* the first two entries here cannot be moved (see "db_initpolygonlist()") */
3836 {x_("xv"), VINTEGER|VISARRAY|VCANTSET, (INTBIG*)&db_ptpoly.xv},
3837 {x_("yv"), VINTEGER|VISARRAY|VCANTSET, (INTBIG*)&db_ptpoly.yv},
3838 {x_("limit"), VINTEGER|VCANTSET, (INTBIG*)&db_ptpoly.limit},
3839 {x_("count"), VINTEGER|VCANTSET, (INTBIG*)&db_ptpoly.count},
3840 {x_("style"), VINTEGER, (INTBIG*)&db_ptpoly.style},
3841 {x_("string"), VSTRING|VCANTSET, (INTBIG*)&db_ptpoly.string},
3842 {x_("textdescript"), VINTEGER|VISARRAY|(TEXTDESCRIPTSIZE<<VLENGTHSH)|VCREF,(INTBIG*)db_ptpoly.textdescript},
3843 {x_("tech"), VTECHNOLOGY, (INTBIG*)&db_ptpoly.tech},
3844 {x_("desc"), VGRAPHICS|VCANTSET, (INTBIG*)&db_ptpoly.desc},
3845 {x_("layer"), VINTEGER, (INTBIG*)&db_ptpoly.layer},
3846 {x_("portproto"), VPORTPROTO, (INTBIG*)&db_ptpoly.portproto},
3847 {x_("nextpolygon"), VPOLYGON|VCANTSET, (INTBIG*)&db_ptpoly.nextpolygon},
3848 {NULL, 0, NULL} /* 0 */
3849 };
3850
3851 /************************* CODE FOR TYPES *************************/
3852
db_initnodeinstlist(NODEINST * ni)3853 void db_initnodeinstlist(NODEINST *ni)
3854 {
3855 if (ni == NONODEINST)
3856 {
3857 db_thisapack->state = NULLNAME;
3858 return;
3859 }
3860 db_thisapack->state = PORTANAME; /* then PORTENAME, SPECNAME, VARNAME */
3861 db_thisapack->portarcinstname = ni->firstportarcinst; /* PORTANAME */
3862 db_thisapack->portexpinstname = ni->firstportexpinst; /* PORTENAME */
3863 db_thisapack->vars = db_nodevars; /* SPECNAME */
3864 db_thisapack->proto = (INTBIG)&db_ptni; /* SPECNAME */
3865 db_thisapack->object = (INTBIG)ni; /* SPECNAME */
3866 db_thisapack->specindex = 0; /* SPECNAME */
3867 db_thisapack->numvar = &ni->numvar; /* VARNAME */
3868 db_thisapack->firstvar = &ni->firstvar; /* VARNAME */
3869 db_thisapack->varindex = 0; /* VARNAME */
3870 }
3871
db_initnodeprotolist(NODEPROTO * np)3872 void db_initnodeprotolist(NODEPROTO *np)
3873 {
3874 if (np == NONODEPROTO)
3875 {
3876 db_thisapack->state = NULLNAME;
3877 return;
3878 }
3879 if (np->primindex == 0)
3880 {
3881 db_thisapack->state = ARCINAME; /* then NODEINAME, PORTCNAME, SPECNAME, VARNAME */
3882 db_thisapack->arciname = np->firstarcinst; /* ARCINAME */
3883 db_thisapack->nodeiname = np->firstnodeinst; /* NODEINAME */
3884 } else db_thisapack->state = PORTCNAME; /* then SPECNAME, VARNAME */
3885 if (np->globalnetcount > 0)
3886 {
3887 db_nodeprotovars[9].type = VINTEGER|VISARRAY|(np->globalnetcount<<VLENGTHSH)|VCANTSET;
3888 db_nodeprotovars[10].type = VNETWORK|VISARRAY|(np->globalnetcount<<VLENGTHSH)|VCANTSET;
3889 } else
3890 {
3891 db_nodeprotovars[9].type = VINTEGER|VCANTSET;
3892 db_nodeprotovars[10].type = VINTEGER|VCANTSET;
3893 }
3894 db_thisapack->portprotoname = np->firstportproto; /* PORTCNAME */
3895 db_thisapack->vars = db_nodeprotovars; /* SPECNAME */
3896 db_thisapack->proto = (INTBIG)&db_ptnp; /* SPECNAME */
3897 db_thisapack->object = (INTBIG)np; /* SPECNAME */
3898 db_thisapack->specindex = 0; /* SPECNAME */
3899 db_thisapack->numvar = &np->numvar; /* VARNAME */
3900 db_thisapack->firstvar = &np->firstvar; /* VARNAME */
3901 db_thisapack->varindex = 0; /* VARNAME */
3902 }
3903
db_initportarcinstlist(PORTARCINST * pi)3904 void db_initportarcinstlist(PORTARCINST *pi)
3905 {
3906 if (pi == NOPORTARCINST)
3907 {
3908 db_thisapack->state = NULLNAME;
3909 return;
3910 }
3911 db_thisapack->state = SPECNAME; /* then VARNAME */
3912 db_thisapack->vars = db_portavars; /* SPECNAME */
3913 db_thisapack->proto = (INTBIG)&db_ptpi; /* SPECNAME */
3914 db_thisapack->object = (INTBIG)pi; /* SPECNAME */
3915 db_thisapack->specindex = 0; /* SPECNAME */
3916 db_thisapack->numvar = &pi->numvar; /* VARNAME */
3917 db_thisapack->firstvar = &pi->firstvar; /* VARNAME */
3918 db_thisapack->varindex = 0; /* VARNAME */
3919 }
3920
db_initportexpinstlist(PORTEXPINST * pe)3921 void db_initportexpinstlist(PORTEXPINST *pe)
3922 {
3923 if (pe == NOPORTEXPINST)
3924 {
3925 db_thisapack->state = NULLNAME;
3926 return;
3927 }
3928 db_thisapack->state = SPECNAME; /* then VARNAME */
3929 db_thisapack->vars = db_portevars; /* SPECNAME */
3930 db_thisapack->proto = (INTBIG)&db_ptpe; /* SPECNAME */
3931 db_thisapack->object = (INTBIG)pe; /* SPECNAME */
3932 db_thisapack->specindex = 0; /* SPECNAME */
3933 db_thisapack->numvar = &pe->numvar; /* VARNAME */
3934 db_thisapack->firstvar = &pe->firstvar; /* VARNAME */
3935 db_thisapack->varindex = 0; /* VARNAME */
3936 }
3937
db_initportprotolist(PORTPROTO * pp)3938 void db_initportprotolist(PORTPROTO *pp)
3939 {
3940 if (pp == NOPORTPROTO)
3941 {
3942 db_thisapack->state = NULLNAME;
3943 return;
3944 }
3945 db_thisapack->state = SPECNAME; /* then VARNAME */
3946 db_thisapack->vars = db_portprotovars; /* SPECNAME */
3947 db_thisapack->proto = (INTBIG)&db_ptpp; /* SPECNAME */
3948 db_thisapack->object = (INTBIG)pp; /* SPECNAME */
3949 db_thisapack->specindex = 0; /* SPECNAME */
3950 db_thisapack->numvar = &pp->numvar; /* VARNAME */
3951 db_thisapack->firstvar = &pp->firstvar; /* VARNAME */
3952 db_thisapack->varindex = 0; /* VARNAME */
3953 }
3954
db_initarcinstlist(ARCINST * ai)3955 void db_initarcinstlist(ARCINST *ai)
3956 {
3957 if (ai == NOARCINST)
3958 {
3959 db_thisapack->state = NULLNAME;
3960 return;
3961 }
3962 db_thisapack->state = SPECNAME; /* then VARNAME */
3963 db_thisapack->vars = db_arcvars; /* SPECNAME */
3964 db_thisapack->proto = (INTBIG)&db_ptai; /* SPECNAME */
3965 db_thisapack->object = (INTBIG)ai; /* SPECNAME */
3966 db_thisapack->specindex = 0; /* SPECNAME */
3967 db_thisapack->numvar = &ai->numvar; /* VARNAME */
3968 db_thisapack->firstvar = &ai->firstvar; /* VARNAME */
3969 db_thisapack->varindex = 0; /* VARNAME */
3970 }
3971
db_initarcprotolist(ARCPROTO * ap)3972 void db_initarcprotolist(ARCPROTO *ap)
3973 {
3974 if (ap == NOARCPROTO)
3975 {
3976 db_thisapack->state = NULLNAME;
3977 return;
3978 }
3979 db_thisapack->state = SPECNAME; /* then VARNAME */
3980 db_thisapack->vars = db_arcprotovars; /* SPECNAME */
3981 db_thisapack->proto = (INTBIG)&db_ptap; /* SPECNAME */
3982 db_thisapack->object = (INTBIG)ap; /* SPECNAME */
3983 db_thisapack->specindex = 0; /* SPECNAME */
3984 db_thisapack->numvar = &ap->numvar; /* VARNAME */
3985 db_thisapack->firstvar = &ap->firstvar; /* VARNAME */
3986 db_thisapack->varindex = 0; /* VARNAME */
3987 }
3988
db_initgeomlist(GEOM * geom)3989 void db_initgeomlist(GEOM *geom)
3990 {
3991 if (geom == NOGEOM)
3992 {
3993 db_thisapack->state = NULLNAME;
3994 return;
3995 }
3996 switch(geom->entryisnode)
3997 {
3998 case TRUE: db_geomvars[1].type = VNODEINST|VCANTSET; break;
3999 case FALSE: db_geomvars[1].type = VARCINST|VCANTSET; break;
4000 }
4001 db_thisapack->state = SPECNAME; /* then VARNAME */
4002 db_thisapack->vars = db_geomvars; /* SPECNAME */
4003 db_thisapack->proto = (INTBIG)&db_ptgeom; /* SPECNAME */
4004 db_thisapack->object = (INTBIG)geom; /* SPECNAME */
4005 db_thisapack->specindex = 0; /* SPECNAME */
4006 db_thisapack->numvar = &geom->numvar; /* VARNAME */
4007 db_thisapack->firstvar = &geom->firstvar; /* VARNAME */
4008 db_thisapack->varindex = 0; /* VARNAME */
4009 }
4010
db_initliblist(LIBRARY * lib)4011 void db_initliblist(LIBRARY *lib)
4012 {
4013 if (lib == NOLIBRARY)
4014 {
4015 db_thisapack->state = NULLNAME;
4016 return;
4017 }
4018 db_thisapack->state = NODENAME; /* then SPECNAME, VARNAME */
4019 db_thisapack->nodeprotoname = lib->firstnodeproto; /* NODENAME */
4020 db_thisapack->vars = db_libvars; /* SPECNAME */
4021 db_thisapack->proto = (INTBIG)&db_ptlib; /* SPECNAME */
4022 db_thisapack->object = (INTBIG)lib; /* SPECNAME */
4023 db_thisapack->specindex = 0; /* SPECNAME */
4024 db_thisapack->numvar = &lib->numvar; /* VARNAME */
4025 db_thisapack->firstvar = &lib->firstvar; /* VARNAME */
4026 db_thisapack->varindex = 0; /* VARNAME */
4027 }
4028
db_inittechlist(TECHNOLOGY * tech)4029 void db_inittechlist(TECHNOLOGY *tech)
4030 {
4031 if (tech == NOTECHNOLOGY)
4032 {
4033 db_thisapack->state = NULLNAME;
4034 return;
4035 }
4036 db_techvars[5].type = VGRAPHICS|VISARRAY|(tech->layercount<<VLENGTHSH)|VCANTSET;
4037 db_thisapack->state = ARCNAME; /* then NODENAME, SPECNAME, VARNAME */
4038 db_thisapack->arcprotoname = tech->firstarcproto; /* ARCNAME */
4039 db_thisapack->nodeprotoname = tech->firstnodeproto; /* NODENAME */
4040 db_thisapack->vars = db_techvars; /* SPECNAME */
4041 db_thisapack->proto = (INTBIG)&db_pttech; /* SPECNAME */
4042 db_thisapack->object = (INTBIG)tech; /* SPECNAME */
4043 db_thisapack->specindex = 0; /* SPECNAME */
4044 db_thisapack->numvar = &tech->numvar; /* VARNAME */
4045 db_thisapack->firstvar = &tech->firstvar; /* VARNAME */
4046 db_thisapack->varindex = 0; /* VARNAME */
4047 }
4048
db_inittoollist(TOOL * tool)4049 void db_inittoollist(TOOL *tool)
4050 {
4051 if (tool == NOTOOL)
4052 {
4053 db_thisapack->state = NULLNAME;
4054 return;
4055 }
4056 db_thisapack->state = SPECNAME; /* then VARNAME */
4057 db_thisapack->vars = db_toolvars; /* SPECNAME */
4058 db_thisapack->proto = (INTBIG)&db_pttool; /* SPECNAME */
4059 db_thisapack->object = (INTBIG)tool; /* SPECNAME */
4060 db_thisapack->specindex = 0; /* SPECNAME */
4061 db_thisapack->numvar = &tool->numvar; /* VARNAME */
4062 db_thisapack->firstvar = &tool->firstvar; /* VARNAME */
4063 db_thisapack->varindex = 0; /* VARNAME */
4064 }
4065
db_initrtnodelist(RTNODE * rtn)4066 void db_initrtnodelist(RTNODE *rtn)
4067 {
4068 if (rtn == NORTNODE)
4069 {
4070 db_thisapack->state = NULLNAME;
4071 return;
4072 }
4073 db_rtnvars[6].type = VISARRAY | (rtn->total<<VLENGTHSH) | VCANTSET | VCREF;
4074 if (rtn->flag == 0) db_rtnvars[6].type |= VRTNODE; else
4075 db_rtnvars[6].type |= VGEOM;
4076 db_thisapack->state = SPECNAME; /* then VARNAME */
4077 db_thisapack->vars = db_rtnvars; /* SPECNAME */
4078 db_thisapack->proto = (INTBIG)&db_ptrtn; /* SPECNAME */
4079 db_thisapack->object = (INTBIG)rtn; /* SPECNAME */
4080 db_thisapack->specindex = 0; /* SPECNAME */
4081 db_thisapack->numvar = &rtn->numvar; /* VARNAME */
4082 db_thisapack->firstvar = &rtn->firstvar; /* VARNAME */
4083 db_thisapack->varindex = 0; /* VARNAME */
4084 }
4085 /*
4086 * entry 6 of the table below ("layers") gets changed by "db_inittechlist"
4087 */
4088
db_initnetworklist(NETWORK * net)4089 void db_initnetworklist(NETWORK *net)
4090 {
4091 if (net == NONETWORK)
4092 {
4093 db_thisapack->state = NULLNAME;
4094 return;
4095 }
4096 if (net->arccount <= 0) db_netvars[0].type = VADDRESS|VCANTSET; else
4097 if (net->arctotal == 0) db_netvars[0].type = VARCINST|VCANTSET; else
4098 db_netvars[0].type = VARCINST|VISARRAY|(net->arccount<<VLENGTHSH)|VCANTSET;
4099 if (net->buswidth <= 1) db_netvars[6].type = VADDRESS|VCANTSET; else
4100 db_netvars[6].type = VNETWORK|VISARRAY|(net->buswidth<<VLENGTHSH)|VCANTSET;
4101 db_thisapack->state = SPECNAME; /* then VARNAME */
4102 db_thisapack->vars = db_netvars; /* SPECNAME */
4103 db_thisapack->proto = (INTBIG)&db_ptnet; /* SPECNAME */
4104 db_thisapack->object = (INTBIG)net; /* SPECNAME */
4105 db_thisapack->specindex = 0; /* SPECNAME */
4106 db_thisapack->numvar = &net->numvar; /* VARNAME */
4107 db_thisapack->firstvar = &net->firstvar; /* VARNAME */
4108 db_thisapack->varindex = 0; /* VARNAME */
4109 }
4110
db_initviewlist(VIEW * view)4111 void db_initviewlist(VIEW *view)
4112 {
4113 if (view == NOVIEW)
4114 {
4115 db_thisapack->state = NULLNAME;
4116 return;
4117 }
4118 db_thisapack->state = SPECNAME; /* then VARNAME */
4119 db_thisapack->vars = db_viewvars; /* SPECNAME */
4120 db_thisapack->proto = (INTBIG)&db_ptview; /* SPECNAME */
4121 db_thisapack->object = (INTBIG)view; /* SPECNAME */
4122 db_thisapack->specindex = 0; /* SPECNAME */
4123 db_thisapack->numvar = &view->numvar; /* VARNAME */
4124 db_thisapack->firstvar = &view->firstvar; /* VARNAME */
4125 db_thisapack->varindex = 0; /* VARNAME */
4126 }
4127
db_initwindowlist(WINDOWPART * win)4128 void db_initwindowlist(WINDOWPART *win)
4129 {
4130 if (win == NOWINDOWPART)
4131 {
4132 db_thisapack->state = NULLNAME;
4133 return;
4134 }
4135 db_thisapack->state = SPECNAME; /* then VARNAME */
4136 db_thisapack->vars = db_winvars; /* SPECNAME */
4137 db_thisapack->proto = (INTBIG)&db_ptwin; /* SPECNAME */
4138 db_thisapack->object = (INTBIG)win; /* SPECNAME */
4139 db_thisapack->specindex = 0; /* SPECNAME */
4140 db_thisapack->numvar = &win->numvar; /* VARNAME */
4141 db_thisapack->firstvar = &win->firstvar; /* VARNAME */
4142 db_thisapack->varindex = 0; /* VARNAME */
4143 }
4144
db_initgraphicslist(GRAPHICS * gra)4145 void db_initgraphicslist(GRAPHICS *gra)
4146 {
4147 if (gra == NOGRAPHICS)
4148 {
4149 db_thisapack->state = NULLNAME;
4150 return;
4151 }
4152 db_thisapack->state = SPECNAME; /* then VARNAME */
4153 db_thisapack->vars = db_gravars; /* SPECNAME */
4154 db_thisapack->proto = (INTBIG)&db_ptgra; /* SPECNAME */
4155 db_thisapack->object = (INTBIG)gra; /* SPECNAME */
4156 db_thisapack->specindex = 0; /* SPECNAME */
4157 db_thisapack->numvar = &gra->numvar; /* VARNAME */
4158 db_thisapack->firstvar = &gra->firstvar; /* VARNAME */
4159 db_thisapack->varindex = 0; /* VARNAME */
4160 }
4161
db_initconstraintlist(CONSTRAINT * con)4162 void db_initconstraintlist(CONSTRAINT *con)
4163 {
4164 if (con == NOCONSTRAINT)
4165 {
4166 db_thisapack->state = NULLNAME;
4167 return;
4168 }
4169 db_thisapack->state = SPECNAME; /* then VARNAME */
4170 db_thisapack->vars = db_convars; /* SPECNAME */
4171 db_thisapack->proto = (INTBIG)&db_ptcon; /* SPECNAME */
4172 db_thisapack->object = (INTBIG)con; /* SPECNAME */
4173 db_thisapack->specindex = 0; /* SPECNAME */
4174 db_thisapack->numvar = &con->numvar; /* VARNAME */
4175 db_thisapack->firstvar = &con->firstvar; /* VARNAME */
4176 db_thisapack->varindex = 0; /* VARNAME */
4177 }
4178
db_initwindowframelist(WINDOWFRAME * wf)4179 void db_initwindowframelist(WINDOWFRAME *wf)
4180 {
4181 if (wf == NOWINDOWFRAME)
4182 {
4183 db_thisapack->state = NULLNAME;
4184 return;
4185 }
4186 db_thisapack->state = SPECNAME; /* then VARNAME */
4187 db_thisapack->vars = db_wfvars; /* SPECNAME */
4188 db_thisapack->proto = (INTBIG)&db_ptwf; /* SPECNAME */
4189 db_thisapack->object = (INTBIG)wf; /* SPECNAME */
4190 db_thisapack->specindex = 0; /* SPECNAME */
4191 db_thisapack->numvar = &wf->numvar; /* VARNAME */
4192 db_thisapack->firstvar = &wf->firstvar; /* VARNAME */
4193 db_thisapack->varindex = 0; /* VARNAME */
4194 }
4195
db_initpolygonlist(POLYGON * poly)4196 void db_initpolygonlist(POLYGON *poly)
4197 {
4198 if (poly == NOPOLYGON)
4199 {
4200 db_thisapack->state = NULLNAME;
4201 return;
4202 }
4203 db_thisapack->state = SPECNAME; /* then VARNAME */
4204 db_thisapack->vars = db_polyvars; /* SPECNAME */
4205 db_thisapack->proto = (INTBIG)&db_ptpoly; /* SPECNAME */
4206 db_thisapack->object = (INTBIG)poly; /* SPECNAME */
4207 db_thisapack->specindex = 0; /* SPECNAME */
4208 db_thisapack->numvar = &poly->numvar; /* VARNAME */
4209 db_thisapack->firstvar = &poly->firstvar; /* VARNAME */
4210 db_thisapack->varindex = 0; /* VARNAME */
4211 db_polyvars[0].type = VINTEGER|VCANTSET|VISARRAY|(poly->count << VLENGTHSH);
4212 db_polyvars[1].type = VINTEGER|VCANTSET|VISARRAY|(poly->count << VLENGTHSH);
4213 }
4214
4215 /************************* DISPLAYABLE VARIABLE ROUTINES *************************/
4216
4217 /*
4218 * this routine is used to determine the screen location of
4219 * letters in displayable text. The displayable variable is
4220 * "var"; it resides on object "addr" of type "type"; uses technology
4221 * "tech"; and is being displayed in window "win". The routine
4222 * calculates the position of line "line" and returns it in (x, y).
4223 * If "lowleft" is true, the returned position is the lower-left
4224 * corner of the text, otherwise it is the position of the center of the text.
4225 */
getdisparrayvarlinepos(INTBIG addr,INTBIG type,TECHNOLOGY * tech,WINDOWPART * win,VARIABLE * var,INTBIG line,INTBIG * x,INTBIG * y,BOOLEAN lowleft)4226 void getdisparrayvarlinepos(INTBIG addr, INTBIG type, TECHNOLOGY *tech, WINDOWPART *win, VARIABLE *var,
4227 INTBIG line, INTBIG *x, INTBIG *y, BOOLEAN lowleft)
4228 {
4229 CHAR *string;
4230 INTBIG cx, cy, distx, disty;
4231 INTBIG tsx, tsy, style;
4232 REGISTER INTSML saverot, savetrn;
4233 REGISTER GEOM *geom;
4234 REGISTER NODEPROTO *np;
4235 REGISTER PORTPROTO *pp;
4236 REGISTER INTBIG screen, realscreen, len, lambda;
4237 REGISTER NODEINST *ni;
4238 REGISTER ARCINST *ai;
4239 REGISTER LIBRARY *lib;
4240 REGISTER TECHNOLOGY *lambdatech;
4241 XARRAY trans;
4242
4243 switch (type)
4244 {
4245 case VNODEINST:
4246 ni = (NODEINST *)addr;
4247 makerot(ni, trans);
4248 geom = ni->geom;
4249 lambdatech = ni->proto->tech;
4250 lib = ni->parent->lib;
4251 cx = (geom->lowx + geom->highx) / 2;
4252 cy = (geom->lowy + geom->highy) / 2;
4253 break;
4254 case VARCINST:
4255 ai = (ARCINST *)addr;
4256 geom = ai->geom;
4257 lambdatech = ai->proto->tech;
4258 lib = ai->parent->lib;
4259 cx = (geom->lowx + geom->highx) / 2;
4260 cy = (geom->lowy + geom->highy) / 2;
4261 break;
4262 case VPORTPROTO:
4263 pp = (PORTPROTO *)addr;
4264 ni = pp->subnodeinst;
4265 lambdatech = ni->proto->tech;
4266 lib = pp->parent->lib;
4267 saverot = ni->rotation; savetrn = ni->transpose;
4268 ni->rotation = ni->transpose = 0;
4269 portposition(pp->subnodeinst, pp->subportproto, &cx, &cy);
4270 ni->rotation = saverot; ni->transpose = savetrn;
4271 ni = pp->subnodeinst;
4272 makerot(ni, trans);
4273 break;
4274 case VNODEPROTO:
4275 np = (NODEPROTO *)addr;
4276 lambdatech = np->tech;
4277 lib = np->lib;
4278 cx = cy = 0; /* cell variables are offset from (0,0) */
4279 break;
4280 default:
4281 lambdatech = NOTECHNOLOGY;
4282 lib = NOLIBRARY;
4283 }
4284 lambdatech = tech;
4285 if (lowleft)
4286 {
4287 distx = TDGETXOFF(var->textdescript);
4288 lambda = lib->lambda[lambdatech->techindex];
4289 distx = distx * lambda / 4;
4290 disty = TDGETYOFF(var->textdescript);
4291 disty = disty * lambda / 4;
4292 cx += distx; cy += disty;
4293 if (type == VNODEINST || type == VPORTPROTO)
4294 xform(cx, cy, &cx, &cy, trans);
4295 }
4296
4297 /* add variable name if requested */
4298 string = describedisplayedvariable(var, line, -1);
4299 screensettextinfo(win, tech, var->textdescript);
4300 if (*string != 0) screengettextsize(win, string, &tsx, &tsy); else
4301 {
4302 screengettextsize(win, x_("Xy"), &tsx, &tsy);
4303 tsx = 0;
4304 }
4305
4306 switch (TDGETPOS(var->textdescript))
4307 {
4308 case VTPOSCENT: style = TEXTCENT; break;
4309 case VTPOSBOXED: style = TEXTBOX; break;
4310 case VTPOSUP: style = TEXTBOT; break;
4311 case VTPOSDOWN: style = TEXTTOP; break;
4312 case VTPOSLEFT: style = TEXTRIGHT; break;
4313 case VTPOSRIGHT: style = TEXTLEFT; break;
4314 case VTPOSUPLEFT: style = TEXTBOTRIGHT; break;
4315 case VTPOSUPRIGHT: style = TEXTBOTLEFT; break;
4316 case VTPOSDOWNLEFT: style = TEXTTOPRIGHT; break;
4317 case VTPOSDOWNRIGHT: style = TEXTTOPLEFT; break;
4318 }
4319 if (type == VNODEINST || type == VPORTPROTO)
4320 style = rotatelabel(style, TDGETROTATION(var->textdescript), trans);
4321
4322 realscreen = screen = applyyscale(win, cy - win->screenly) + win->usely;
4323 if ((var->type&VISARRAY) == 0) len = 1; else
4324 len = getlength(var);
4325 switch (style)
4326 {
4327 case TEXTBOX:
4328 case TEXTCENT: /* text is centered about grab point */
4329 case TEXTLEFT: /* text is to right of grab point */
4330 case TEXTRIGHT: /* text is to left of grab point */
4331 if (lowleft) realscreen = screen - ((line+1)*tsy - len*tsy/2); else
4332 realscreen = screen - (line*tsy - len*tsy/2) - tsy/2;
4333 break;
4334 case TEXTBOT: /* text is above grab point */
4335 case TEXTBOTRIGHT: /* text is to upper-left of grab point */
4336 case TEXTBOTLEFT: /* text is to upper-right of grab point */
4337 realscreen = screen + (len-line-1) * tsy;
4338 break;
4339 case TEXTTOP: /* text is below grab point */
4340 case TEXTTOPRIGHT: /* text is to lower-left of grab point */
4341 case TEXTTOPLEFT: /* text is to lower-right of grab point */
4342 if (lowleft) realscreen = screen - (line+1) * tsy; else
4343 realscreen = screen - line * tsy;
4344 break;
4345 }
4346 *y = (INTBIG)((realscreen - win->usely) / win->scaley) + win->screenly;
4347
4348 realscreen = screen = applyxscale(win, cx - win->screenlx) + win->uselx;
4349 switch (style)
4350 {
4351 case TEXTBOX:
4352 case TEXTCENT: /* text is centered about grab point */
4353 case TEXTBOT: /* text is above grab point */
4354 case TEXTTOP: /* text is below grab point */
4355 if (lowleft) realscreen = screen - tsx/2;
4356 break;
4357 case TEXTRIGHT: /* text is to left of grab point */
4358 case TEXTBOTRIGHT: /* text is to upper-left of grab point */
4359 case TEXTTOPRIGHT: /* text is to lower-left of grab point */
4360 if (lowleft) realscreen = screen - tsx;
4361 break;
4362 }
4363 *x = (INTBIG)((realscreen - win->uselx) / win->scalex) + win->screenlx;
4364 }
4365
4366 /*
4367 * this routine fills polygon poly with an outline of a displayable
4368 * variable's text. The displayable variable is "var", it resides
4369 * on object "geom", and is being displayed in window "win".
4370 * It is used to draw variable highlighting.
4371 */
makedisparrayvarpoly(GEOM * geom,WINDOWPART * win,VARIABLE * var,POLYGON * poly)4372 void makedisparrayvarpoly(GEOM *geom, WINDOWPART *win, VARIABLE *var, POLYGON *poly)
4373 {
4374 INTBIG centerobjx, centerobjy, realobjwidth, realobjheight, len, j,
4375 screenwidth, screenheight, lx, hx, ly, hy, sslx, sshx, ssly, sshy;
4376 float sscalex, sscaley;
4377 static BOOLEAN canscalefonts, fontscalingunknown = TRUE;
4378 REGISTER BOOLEAN reltext;
4379 REGISTER NODEINST *ni;
4380 REGISTER INTBIG distx, disty, lambda;
4381 REGISTER TECHNOLOGY *tech;
4382 REGISTER NODEPROTO *np;
4383 XARRAY trans;
4384 INTBIG tsx, tsy, lineheight, style;
4385 CHAR *string;
4386
4387 if (poly->limit < 4) (void)extendpolygon(poly, 4);
4388 if (geom == NOGEOM)
4389 {
4390 /* cell variables are offset from (0,0) */
4391 lx = hx = ly = hy = 0;
4392 tech = el_curtech;
4393 lambda = el_curlib->lambda[tech->techindex];
4394 } else
4395 {
4396 boundobj(geom, &lx, &hx, &ly, &hy);
4397 lambda = figurelambda(geom);
4398 np = geomparent(geom);
4399 if (np->tech == NOTECHNOLOGY)
4400 np->tech = whattech(np);
4401 tech = np->tech;
4402 }
4403 distx = TDGETXOFF(var->textdescript);
4404 distx = distx * lambda / 4;
4405 disty = TDGETYOFF(var->textdescript);
4406 disty = disty * lambda / 4;
4407 centerobjx = (lx + hx) / 2 + distx;
4408 centerobjy = (ly + hy) / 2 + disty;
4409
4410 /* rotate grab point if on a node */
4411 if (geom != NOGEOM && geom->entryisnode)
4412 {
4413 ni = geom->entryaddr.ni;
4414 centerobjx = (ni->lowx + ni->highx) / 2 + distx;
4415 centerobjy = (ni->lowy + ni->highy) / 2 + disty;
4416 makerot(ni, trans);
4417 xform(centerobjx, centerobjy, ¢erobjx, ¢erobjy, trans);
4418 }
4419
4420 if (fontscalingunknown)
4421 {
4422 fontscalingunknown = FALSE;
4423 canscalefonts = graphicshas(CANSCALEFONTS);
4424 }
4425 reltext = FALSE;
4426 if (canscalefonts)
4427 {
4428 if ((TDGETSIZE(var->textdescript)&TXTQLAMBDA) != 0) reltext = TRUE;
4429 }
4430 if (reltext)
4431 {
4432 /* set window to a sensible range */
4433 sslx = win->screenlx; win->screenlx = win->uselx * lambda / 12;
4434 sshx = win->screenhx; win->screenhx = win->usehx * lambda / 12;
4435 ssly = win->screenly; win->screenly = win->usely * lambda / 12;
4436 sshy = win->screenhy; win->screenhy = win->usehy * lambda / 12;
4437 sscalex = win->scalex; sscaley = win->scaley;
4438 computewindowscale(win);
4439 }
4440
4441 screensettextinfo(win, tech, var->textdescript);
4442 screengettextsize(win, x_("Xy"), &tsx, &lineheight);
4443 if ((var->type&VISARRAY) == 0) len = 1; else
4444 len = getlength(var);
4445 screenwidth = 0;
4446 for(j=0; j<len; j++)
4447 {
4448 string = describedisplayedvariable(var, j, -1);
4449 screengettextsize(win, string, &tsx, &tsy);
4450 if (tsx > screenwidth) screenwidth = tsx;
4451 }
4452
4453 screenheight = lineheight * len;
4454 realobjwidth = (INTBIG)(screenwidth / win->scalex);
4455 realobjheight = (INTBIG)(screenheight / win->scaley);
4456
4457 if (reltext)
4458 {
4459 /* restore window */
4460 win->screenlx = sslx; win->screenhx = sshx;
4461 win->screenly = ssly; win->screenhy = sshy;
4462 win->scalex = sscalex; win->scaley = sscaley;
4463 }
4464
4465 switch (TDGETPOS(var->textdescript))
4466 {
4467 case VTPOSCENT:
4468 case VTPOSBOXED: style = TEXTCENT; break;
4469 case VTPOSUP: style = TEXTBOT; break;
4470 case VTPOSDOWN: style = TEXTTOP; break;
4471 case VTPOSLEFT: style = TEXTRIGHT; break;
4472 case VTPOSRIGHT: style = TEXTLEFT; break;
4473 case VTPOSUPLEFT: style = TEXTBOTRIGHT; break;
4474 case VTPOSUPRIGHT: style = TEXTBOTLEFT; break;
4475 case VTPOSDOWNLEFT: style = TEXTTOPRIGHT; break;
4476 case VTPOSDOWNRIGHT: style = TEXTTOPLEFT; break;
4477 }
4478 if (geom != NOGEOM && geom->entryisnode)
4479 {
4480 makerot(geom->entryaddr.ni, trans);
4481 style = rotatelabel(style, TDGETROTATION(var->textdescript), trans);
4482 }
4483
4484 /* set X position */
4485 switch (style)
4486 {
4487 case TEXTCENT: /* text is centered about grab point */
4488 case TEXTBOT: /* text is above grab point */
4489 case TEXTTOP: /* text is below grab point */
4490 poly->xv[0] = poly->xv[1] = centerobjx - realobjwidth/2;
4491 poly->xv[2] = poly->xv[3] = centerobjx + realobjwidth/2;
4492 break;
4493 case TEXTLEFT: /* text is to right of grab point */
4494 case TEXTBOTLEFT: /* text is to upper-right of grab point */
4495 case TEXTTOPLEFT: /* text is to lower-right of grab point */
4496 poly->xv[0] = poly->xv[1] = centerobjx;
4497 poly->xv[2] = poly->xv[3] = centerobjx + realobjwidth;
4498 break;
4499 case TEXTRIGHT: /* text is to left of grab point */
4500 case TEXTBOTRIGHT: /* text is to upper-left of grab point */
4501 case TEXTTOPRIGHT: /* text is to lower-left of grab point */
4502 poly->xv[0] = poly->xv[1] = centerobjx - realobjwidth;
4503 poly->xv[2] = poly->xv[3] = centerobjx;
4504 break;
4505 }
4506
4507 /* set Y position */
4508 switch (style)
4509 {
4510 case TEXTCENT: /* text is centered about grab point */
4511 case TEXTLEFT: /* text is to right of grab point */
4512 case TEXTRIGHT: /* text is to left of grab point */
4513 poly->yv[0] = poly->yv[3] = centerobjy - realobjheight/2;
4514 poly->yv[1] = poly->yv[2] = centerobjy + realobjheight/2;
4515 break;
4516 case TEXTBOT: /* text is above grab point */
4517 case TEXTBOTRIGHT: /* text is to upper-left of grab point */
4518 case TEXTBOTLEFT: /* text is to upper-right of grab point */
4519 poly->yv[0] = poly->yv[3] = centerobjy;
4520 poly->yv[1] = poly->yv[2] = centerobjy + realobjheight;
4521 break;
4522 case TEXTTOP: /* text is below grab point */
4523 case TEXTTOPRIGHT: /* text is to lower-left of grab point */
4524 case TEXTTOPLEFT: /* text is to lower-right of grab point */
4525 poly->yv[0] = poly->yv[3] = centerobjy - realobjheight;
4526 poly->yv[1] = poly->yv[2] = centerobjy;
4527 break;
4528 }
4529 poly->count = 4;
4530 }
4531
4532 /*
4533 * routine to return the name of the variable whose key is "key" and whose
4534 * type is "type"
4535 */
changedvariablename(INTBIG type,INTBIG key,INTBIG subtype)4536 CHAR *changedvariablename(INTBIG type, INTBIG key, INTBIG subtype)
4537 {
4538 if ((subtype&VCREF) == 0)
4539 {
4540 if (key == -1) return(_("NULL"));
4541 return(makename(key));
4542 }
4543
4544 switch (type&VTYPE)
4545 {
4546 case VNODEINST: return(db_nodevars[key].name);
4547 case VNODEPROTO: return(db_nodeprotovars[key].name);
4548 case VPORTARCINST: return(db_portavars[key].name);
4549 case VPORTEXPINST: return(db_portevars[key].name);
4550 case VPORTPROTO: return(db_portprotovars[key].name);
4551 case VARCINST: return(db_arcvars[key].name);
4552 case VARCPROTO: return(db_arcprotovars[key].name);
4553 case VGEOM: return(db_geomvars[key].name);
4554 case VRTNODE: return(db_rtnvars[key].name);
4555 case VLIBRARY: return(db_libvars[key].name);
4556 case VTECHNOLOGY: return(db_techvars[key].name);
4557 case VTOOL: return(db_toolvars[key].name);
4558 case VVIEW: return(db_viewvars[key].name);
4559 case VNETWORK: return(db_netvars[key].name);
4560 case VWINDOWPART: return(db_winvars[key].name);
4561 case VGRAPHICS: return(db_gravars[key].name);
4562 case VCONSTRAINT: return(db_convars[key].name);
4563 case VWINDOWFRAME: return(db_wfvars[key].name);
4564 }
4565 return(_("NULL"));
4566 }
4567
4568 /*
4569 * routine to adjust the coordinate values in "poly" to account for the
4570 * display offset in the type field "textdescription". Assumes that the
4571 * initial values are the center of the object. The object on which this
4572 * text resides is in "geom". Routine also sets the style and the font of
4573 * text message to use with this coordinate.
4574 */
adjustdisoffset(INTBIG addr,INTBIG type,TECHNOLOGY * tech,POLYGON * poly,UINTBIG * textdescription)4575 void adjustdisoffset(INTBIG addr, INTBIG type, TECHNOLOGY *tech,
4576 POLYGON *poly, UINTBIG *textdescription)
4577 {
4578 REGISTER INTBIG lambda;
4579 INTBIG distx, disty, plx, phx, ply, phy;
4580 REGISTER INTBIG i;
4581 REGISTER NODEINST *ni;
4582 XARRAY trans;
4583
4584 lambda = el_curlib->lambda[tech->techindex];
4585 switch (type&VTYPE)
4586 {
4587 case VNODEINST: lambda = lambdaofnode((NODEINST *)addr); break;
4588 case VARCINST: lambda = lambdaofarc((ARCINST *)addr); break;
4589 }
4590 distx = TDGETXOFF(textdescription);
4591 distx = distx * lambda / 4;
4592 disty = TDGETYOFF(textdescription);
4593 disty = disty * lambda / 4;
4594 if (TDGETPOS(textdescription) == VTPOSBOXED)
4595 {
4596 getbbox(poly, &plx, &phx, &ply, &phy);
4597 if (distx > 0) plx += distx*2; else
4598 if (distx < 0) phx += distx*2;
4599 if (disty > 0) ply += disty*2; else
4600 if (disty < 0) phy += disty*2;
4601 makerectpoly(plx, phx, ply, phy, poly);
4602 } else
4603 {
4604 /* just shift the polygon */
4605 for(i=0; i<poly->count; i++)
4606 {
4607 poly->xv[i] += distx;
4608 poly->yv[i] += disty;
4609 }
4610 }
4611
4612 /* determine the text message style */
4613 switch (TDGETPOS(textdescription))
4614 {
4615 case VTPOSCENT: poly->style = TEXTCENT; break;
4616 case VTPOSBOXED: poly->style = TEXTBOX; break;
4617 case VTPOSUP: poly->style = TEXTBOT; break;
4618 case VTPOSDOWN: poly->style = TEXTTOP; break;
4619 case VTPOSLEFT: poly->style = TEXTRIGHT; break;
4620 case VTPOSRIGHT: poly->style = TEXTLEFT; break;
4621 case VTPOSUPLEFT: poly->style = TEXTBOTRIGHT; break;
4622 case VTPOSUPRIGHT: poly->style = TEXTBOTLEFT; break;
4623 case VTPOSDOWNLEFT: poly->style = TEXTTOPRIGHT; break;
4624 case VTPOSDOWNRIGHT: poly->style = TEXTTOPLEFT; break;
4625 }
4626 if (type == VNODEINST)
4627 {
4628 ni = (NODEINST *)addr;
4629 makeangle(ni->rotation, ni->transpose, trans);
4630 poly->style = rotatelabel(poly->style, TDGETROTATION(textdescription), trans);
4631 }
4632 if (type == VPORTPROTO)
4633 {
4634 ni = ((PORTPROTO *)addr)->subnodeinst;
4635 makeangle(ni->rotation, ni->transpose, trans);
4636 poly->style = rotatelabel(poly->style, TDGETROTATION(textdescription), trans);
4637 }
4638 TDCOPY(poly->textdescript, textdescription);
4639 poly->tech = tech;
4640 }
4641
4642 /************************* HELPER ROUTINES *************************/
4643
4644 /*
4645 * routine to convert a variable name in "name" to a key and return it.
4646 * If the name is not in the database, the routine returns a negative value
4647 * that is one less than the negative table index entry.
4648 */
db_getkey(CHAR * name)4649 INTBIG db_getkey(CHAR *name)
4650 {
4651 REGISTER INTBIG hi, lo, med, lastmed, i;
4652
4653 /* binary search name space for the variable name */
4654 i = lo = 0; hi = lastmed = el_numnames;
4655 for(;;)
4656 {
4657 /* find mid-point: quit if done */
4658 med = (hi + lo) / 2;
4659 if (med == lastmed) break;
4660 lastmed = med;
4661
4662 /* test the entry: return the key if a match */
4663 i = namesame(name, el_namespace[med]);
4664 if (i == 0) return(med);
4665
4666 /* decide which way to search in list */
4667 if (i < 0) hi = med; else lo = med;
4668 }
4669
4670 /* create a new position: adjust for position location */
4671 if (i > 0) med++;
4672 return(-med-1);
4673 }
4674
4675 /*
4676 * routine to determine the appropriate memory cluster to use for the
4677 * variable whose address is "addr" and type is "type".
4678 */
db_whichcluster(INTBIG addr,INTBIG type)4679 CLUSTER *db_whichcluster(INTBIG addr, INTBIG type)
4680 {
4681 REGISTER GEOM *geom;
4682 REGISTER NODEPROTO *np;
4683 REGISTER NODEINST *ni;
4684
4685 switch (type&VTYPE)
4686 {
4687 case VNODEINST:
4688 ni = (NODEINST *)addr;
4689 if (ni->parent == NONODEPROTO) return(db_cluster);
4690 return(ni->parent->lib->cluster);
4691 case VNODEPROTO:
4692 np = (NODEPROTO *)addr;
4693 if (np->primindex == 0) return(np->lib->cluster);
4694 return(np->tech->cluster);
4695 case VPORTARCINST:
4696 return(((PORTARCINST *)addr)->conarcinst->parent->lib->cluster);
4697 case VPORTEXPINST:
4698 return(((PORTEXPINST *)addr)->exportproto->parent->lib->cluster);
4699 case VPORTPROTO:
4700 np = ((PORTPROTO *)addr)->parent;
4701 if (np->primindex == 0) return(np->lib->cluster);
4702 return(np->tech->cluster);
4703 case VARCINST: return(((ARCINST *)addr)->parent->lib->cluster);
4704 case VARCPROTO: return(((ARCPROTO *)addr)->tech->cluster);
4705 case VGEOM: geom = (GEOM *)addr;
4706 if (geom->entryisnode)
4707 return(geom->entryaddr.ni->parent->lib->cluster);
4708 return(geom->entryaddr.ai->parent->lib->cluster);
4709 case VTECHNOLOGY: return(((TECHNOLOGY *)addr)->cluster);
4710 case VTOOL: return(((TOOL *)addr)->cluster);
4711 case VNETWORK: return(((NETWORK *)addr)->parent->lib->cluster);
4712 case VWINDOWPART: return(us_tool->cluster);
4713 case VWINDOWFRAME: return(us_tool->cluster);
4714 }
4715 return(db_cluster);
4716 }
4717
4718 /*
4719 * routine to determine the appropriate cell associated with the
4720 * variable whose address is "addr" and type is "type".
4721 */
db_whichnodeproto(INTBIG addr,INTBIG type)4722 NODEPROTO *db_whichnodeproto(INTBIG addr, INTBIG type)
4723 {
4724 REGISTER GEOM *geom;
4725 REGISTER NODEPROTO *np;
4726
4727 switch (type&VTYPE)
4728 {
4729 case VNODEINST: return(((NODEINST *)addr)->parent);
4730 case VNODEPROTO:
4731 np = (NODEPROTO *)addr;
4732 if (np->primindex == 0) return(np); else return(NONODEPROTO);
4733 case VPORTARCINST: return(((PORTARCINST *)addr)->conarcinst->parent);
4734 case VPORTEXPINST: return(((PORTEXPINST *)addr)->exportproto->parent);
4735 case VPORTPROTO: return(((PORTPROTO *)addr)->parent);
4736 case VARCINST: return(((ARCINST *)addr)->parent);
4737 case VGEOM: geom = (GEOM *)addr;
4738 if (geom->entryisnode) return(geom->entryaddr.ni->parent);
4739 return(geom->entryaddr.ai->parent);
4740 case VNETWORK: return(((NETWORK *)addr)->parent);
4741 }
4742 return(NONODEPROTO);
4743 }
4744
4745 /*
4746 * internal routine to set entry "med" in the list of variables at "*firstvar"
4747 * with "*numvar" entries (this entry has the key "key"). If "med" is negative
4748 * then the entry does not exist in the list and must be created. The entry is
4749 * set to the address "newaddr" and type "newtype". Memory is allocated from
4750 * cluster "cluster". Returns true if there is an error.
4751 */
4752 #ifdef DEBUGMEMORY
db_setvalkey(INTSML * numvar,VARIABLE ** firstvar,INTBIG med,INTBIG key,INTBIG newaddr,INTBIG newtype,CLUSTER * cluster,CHAR * module,INTBIG line)4753 BOOLEAN db_setvalkey(INTSML *numvar, VARIABLE **firstvar, INTBIG med, INTBIG key,
4754 INTBIG newaddr, INTBIG newtype, CLUSTER *cluster, CHAR *module, INTBIG line)
4755 #else
4756 BOOLEAN db_setvalkey(INTSML *numvar, VARIABLE **firstvar, INTBIG med, INTBIG key,
4757 INTBIG newaddr, INTBIG newtype, CLUSTER *cluster)
4758 #endif
4759 {
4760 REGISTER VARIABLE *newv, *var;
4761 REGISTER INTBIG i;
4762
4763 /* if there is no existing variable, create it */
4764 if (med < 0)
4765 {
4766 /* get the entry position in the list */
4767 med = -med - 1;
4768
4769 /* allocate space for new list */
4770 newv = (VARIABLE *)emalloc(((*numvar+1)*(sizeof (VARIABLE))), cluster);
4771 if (newv == 0) return(TRUE);
4772
4773 /* copy old list up to the new entry */
4774 for(i=0; i<med; i++)
4775 {
4776 newv[i].key = (*firstvar)[i].key;
4777 newv[i].type = (*firstvar)[i].type;
4778 TDCOPY(newv[i].textdescript, (*firstvar)[i].textdescript);
4779 newv[i].addr = (*firstvar)[i].addr;
4780 }
4781
4782 /* add the new entry */
4783 newv[med].key = key;
4784 newv[med].type = VUNKNOWN|VDONTSAVE;
4785 TDCLEAR(newv[med].textdescript);
4786 TDSETSIZE(newv[med].textdescript, TXTSETQLAMBDA(4));
4787 newv[med].addr = 0;
4788 var = &newv[med];
4789
4790 /* copy old list after the new entry */
4791 for(i = med; i < *numvar; i++)
4792 {
4793 newv[i+1].key = (*firstvar)[i].key;
4794 newv[i+1].type = (*firstvar)[i].type;
4795 TDCOPY(newv[i+1].textdescript, (*firstvar)[i].textdescript);
4796 newv[i+1].addr = (*firstvar)[i].addr;
4797 }
4798
4799 /* clean-up */
4800 if (*numvar != 0) efree((CHAR *)*firstvar);
4801 *firstvar = newv;
4802 (*numvar)++;
4803 } else var = &(*firstvar)[med];
4804
4805 /* set the variable */
4806 #ifdef DEBUGMEMORY
4807 if (db_setvalvar(var, newaddr, newtype, cluster, module, line) != 0) return(TRUE);
4808 #else
4809 if (db_setvalvar(var, newaddr, newtype, cluster) != 0) return(TRUE);
4810 #endif
4811
4812 return(FALSE);
4813 }
4814
4815 /*
4816 * routine to set the value of the variable "var" to the value "newaddr" and
4817 * type "newtype". Memory is allocated from cluster "cluster". Returns
4818 * true upon error.
4819 */
4820 #ifdef DEBUGMEMORY
db_setvalvar(VARIABLE * var,INTBIG newaddr,INTBIG newtype,CLUSTER * cluster,CHAR * module,INTBIG line)4821 BOOLEAN db_setvalvar(VARIABLE *var, INTBIG newaddr, INTBIG newtype,
4822 CLUSTER *cluster, CHAR *module, INTBIG line)
4823 #else
4824 BOOLEAN db_setvalvar(VARIABLE *var, INTBIG newaddr, INTBIG newtype,
4825 CLUSTER *cluster)
4826 #endif
4827 {
4828 REGISTER INTBIG i, len, datasize;
4829 INTBIG longval;
4830 REGISTER UCHAR1 *inaddr;
4831
4832 /* if the variable or key is not valid then ignore this */
4833 if (var == NOVARIABLE)
4834 {
4835 ttyputerr(_("No valid variable"));
4836 return(TRUE);
4837 }
4838 if ((var->type&VCREF) != 0)
4839 {
4840 /* setting a fixed attribute on an object */
4841 if ((newtype&VISARRAY) != 0)
4842 {
4843 ttyputmsg(_("Cannot set array in C structure"));
4844 return(FALSE);
4845 }
4846 if (((INTBIG)(var->type&(VTYPE|VISARRAY))) != (newtype&(VTYPE|VISARRAY)))
4847 {
4848 ttyputerr(_("Type mismatch"));
4849 return(TRUE);
4850 }
4851 #ifdef DEBUGMEMORY
4852 if (db_setval((UCHAR1 *)&newaddr, (UCHAR1 *)db_realaddress, newtype, cluster,
4853 module, line)) return(TRUE);
4854 #else
4855 if (db_setval((UCHAR1 *)&newaddr, (UCHAR1 *)db_realaddress, newtype, cluster))
4856 return(TRUE);
4857 #endif
4858 return(FALSE);
4859 }
4860
4861 /* if this change isn't subject to undo, free previous memory now */
4862 if (db_donextchangequietly || db_dochangesquietly)
4863 {
4864 db_freevar(var->addr, var->type);
4865 }
4866
4867 /* change the variable type */
4868 var->type = newtype;
4869
4870 /* allocate and fill space on the new variables */
4871 if ((newtype&(VCODE1|VCODE2)) != 0)
4872 {
4873 if (var->key == sch_globalnamekey || var->key == el_node_name_key || var->key == el_arc_name_key)
4874 {
4875 ttyputmsg(_("Language code forbidden for variable %s"), makename(var->key));
4876 var->type = VSTRING|newtype&(VDISPLAY|VDONTSAVE|VCANTSET);
4877 }
4878 #ifdef DEBUGMEMORY
4879 if (db_setval((UCHAR1 *)&newaddr, (UCHAR1 *)&var->addr, VSTRING, cluster,
4880 module, line)) return(TRUE);
4881 #else
4882 if (db_setval((UCHAR1 *)&newaddr, (UCHAR1 *)&var->addr, VSTRING, cluster))
4883 return(TRUE);
4884 #endif
4885 } else if ((newtype&VISARRAY) != 0)
4886 {
4887 var->addr = newaddr;
4888 len = getlength(var);
4889 datasize = db_getdatasize(newtype);
4890 if ((newtype&VLENGTH) == 0)
4891 {
4892 #ifdef DEBUGMEMORY
4893 var->addr = (INTBIG)_emalloc((len+1)*datasize, cluster, module, line);
4894 #else
4895 var->addr = (INTBIG)emalloc((len+1)*datasize, cluster);
4896 #endif
4897 if (var->addr == 0) return(TRUE);
4898 for(i=0; i<datasize; i++)
4899 ((UCHAR1 *)var->addr)[len*datasize+i] = 0xff;
4900 } else
4901 {
4902 #ifdef DEBUGMEMORY
4903 var->addr = (INTBIG)_emalloc(len*datasize, cluster, module, line);
4904 #else
4905 var->addr = (INTBIG)emalloc(len*datasize, cluster);
4906 #endif
4907 if (var->addr == 0) return(TRUE);
4908 }
4909 for(i=0; i<len; i++)
4910 {
4911 if ((newtype&VTYPE) == VSHORT)
4912 {
4913 longval = ((INTSML *)newaddr)[i];
4914 #ifdef DEBUGMEMORY
4915 if (db_setval((UCHAR1 *)&longval, &((UCHAR1 *)var->addr)[i*datasize], newtype,
4916 cluster, module, line)) return(TRUE);
4917 #else
4918 if (db_setval((UCHAR1 *)&longval, &((UCHAR1 *)var->addr)[i*datasize], newtype,
4919 cluster)) return(TRUE);
4920 #endif
4921 } else
4922 {
4923 inaddr = (UCHAR1 *)(newaddr + i*datasize);
4924 #ifdef DEBUGMEMORY
4925 if (db_setval(inaddr, &((UCHAR1 *)var->addr)[i*datasize], newtype,
4926 cluster, module, line)) return(TRUE);
4927 #else
4928 if (db_setval(inaddr, &((UCHAR1 *)var->addr)[i*datasize], newtype,
4929 cluster)) return(TRUE);
4930 #endif
4931 }
4932 }
4933 } else
4934 {
4935 #ifdef DEBUGMEMORY
4936 if (db_setval((UCHAR1 *)&newaddr, (UCHAR1 *)&var->addr, newtype, cluster,
4937 module, line)) return(TRUE);
4938 #else
4939 if (db_setval((UCHAR1 *)&newaddr, (UCHAR1 *)&var->addr, newtype, cluster))
4940 return(TRUE);
4941 #endif
4942 }
4943
4944 return(FALSE);
4945 }
4946
4947 /*
4948 * routine to get entry "aindex" of array variable "var" and place it in "value".
4949 * Returns true upon error.
4950 */
db_getindvar(VARIABLE * var,INTBIG aindex,INTBIG * value)4951 BOOLEAN db_getindvar(VARIABLE *var, INTBIG aindex, INTBIG *value)
4952 {
4953 INTBIG type, len;
4954 REGISTER INTBIG datasize;
4955 REGISTER void *loc;
4956
4957 /* if the variable or key is not valid then ignore this */
4958 if (var == NOVARIABLE) return(TRUE);
4959
4960 /* if the variable is not an array, quit now */
4961 type = var->type;
4962 if ((type&VISARRAY) == 0) return(TRUE);
4963
4964 /* ensure that the index is within the range of the array */
4965 len = getlength(var);
4966 if (aindex < 0) aindex = 0;
4967 if (aindex >= len) aindex = len - 1;
4968
4969 /* determine the size of the array entries */
4970 datasize = db_getdatasize(type);
4971
4972 /* set the entry */
4973 if ((type&VCREF) != 0)
4974 {
4975 /* get the address of the old array entry (fixed attributes) */
4976 loc = (void *)(db_realaddress + aindex*datasize);
4977 } else
4978 {
4979 /* get the address of the old array entry (variable attributes) */
4980 loc = &((CHAR *)var->addr)[aindex*datasize];
4981 }
4982
4983 /* set an arbitrary attribute on an object */
4984 *value = db_assignvalue(loc, datasize);
4985 return(FALSE);
4986 }
4987
4988 /*
4989 * routine to set entry "aindex" of array variable "var" (which is on object
4990 * "objaddr" of type "objtype") to the value "newaddr". Returns nonzero
4991 * upon error.
4992 */
4993 #ifdef DEBUGMEMORY
db_setindvar(INTBIG objaddr,INTBIG objtype,VARIABLE * var,INTBIG aindex,INTBIG newaddr,CHAR * module,INTBIG line)4994 BOOLEAN db_setindvar(INTBIG objaddr, INTBIG objtype, VARIABLE *var, INTBIG aindex,
4995 INTBIG newaddr, CHAR *module, INTBIG line)
4996 #else
4997 BOOLEAN db_setindvar(INTBIG objaddr, INTBIG objtype, VARIABLE *var, INTBIG aindex,
4998 INTBIG newaddr)
4999 #endif
5000 {
5001 REGISTER INTBIG datasize;
5002 REGISTER INTBIG len, oldvalue, type;
5003 REGISTER void *loc;
5004
5005 /* if the variable or key is not valid then ignore this */
5006 if (var == NOVARIABLE) return(TRUE);
5007
5008 /* if the variable is not an array, quit now */
5009 type = var->type;
5010 if ((type&VISARRAY) == 0) return(TRUE);
5011
5012 /* ensure that the index is within the range of the array */
5013 len = getlength(var);
5014 if (aindex < 0) aindex = 0;
5015 if (aindex >= len) aindex = len - 1;
5016
5017 /* determine the size of the array entries */
5018 datasize = db_getdatasize(type);
5019
5020 /* set the entry */
5021 if ((type&VCREF) != 0)
5022 {
5023 /* get the address of the old array entry (fixed attributes) */
5024 loc = (void *)(db_realaddress + aindex*datasize);
5025 } else
5026 {
5027 /* get the address of the old array entry (variable attributes) */
5028 loc = &((UCHAR1 *)var->addr)[aindex*datasize];
5029 }
5030
5031 /* set an arbitrary attribute on an object */
5032 oldvalue = db_assignvalue(loc, datasize);
5033 #ifdef DEBUGMEMORY
5034 if (db_setval((UCHAR1 *)&newaddr, (UCHAR1 *)loc, type,
5035 db_whichcluster(objaddr, objtype), module, line)) return(TRUE);
5036 #else
5037 if (db_setval((UCHAR1 *)&newaddr, (UCHAR1 *)loc, type,
5038 db_whichcluster(objaddr, objtype))) return(TRUE);
5039 #endif
5040
5041 /* handle change control, constraint, and broadcast */
5042 if (!db_donextchangequietly && !db_dochangesquietly)
5043 {
5044 /* tell constraint system about modified variable */
5045 (*el_curconstraint->modifyvariable)(objaddr, objtype, var->key, type,
5046 aindex, oldvalue);
5047
5048 /* mark a change */
5049 (void)db_change((INTBIG)objaddr, VARIABLEMOD, objtype, var->key, type,
5050 aindex, oldvalue, 0);
5051 } else
5052 {
5053 if ((type&(VCODE1|VCODE2)) != 0 || (type&VTYPE) == VSTRING)
5054 efree((CHAR *)oldvalue);
5055 }
5056
5057 return(FALSE);
5058 }
5059
5060 /*
5061 * routine to insert the value "newaddr" before entry "aindex" of array
5062 * variable "var" (which is on object "objaddr" of type "objtype").
5063 * Returns true upon error.
5064 */
db_insindvar(INTBIG objaddr,INTBIG objtype,VARIABLE * var,INTBIG aindex,INTBIG newaddr)5065 BOOLEAN db_insindvar(INTBIG objaddr, INTBIG objtype, VARIABLE *var, INTBIG aindex,
5066 INTBIG newaddr)
5067 {
5068 REGISTER INTBIG i, j, len, origlen, newsize, truelen, type, *newdata;
5069 REGISTER INTBIG datasize;
5070 CLUSTER *cluster;
5071
5072 /* if the variable or key is not valid then ignore this */
5073 if (var == NOVARIABLE) return(TRUE);
5074
5075 /* if the variable is not an array, quit now */
5076 type = var->type;
5077 if ((type&VISARRAY) == 0) return(TRUE);
5078 origlen = len = getlength(var);
5079
5080 /* ensure that the index is valid */
5081 if (aindex < 0) aindex = 0;
5082
5083 /* determine the size of the new array */
5084 newsize = len;
5085 if (aindex > newsize) newsize = aindex;
5086 newsize++;
5087 truelen = newsize;
5088
5089 /* if this is a variable-length array, include the terminator */
5090 if ((var->type&VLENGTH) == 0) { origlen++; newsize++; }
5091
5092 /* determine the size of the array entries */
5093 datasize = db_getdatasize(type);
5094
5095 /* allocate a new array */
5096 cluster = db_whichcluster(objaddr, objtype);
5097 newdata = (INTBIG *)emalloc(datasize * newsize, cluster);
5098 if (newdata == 0) return(TRUE);
5099
5100 /* copy and insert */
5101 j = 0;
5102 for(i=0; i<newsize; i++)
5103 {
5104 if (i == aindex)
5105 {
5106 #ifdef DEBUGMEMORY
5107 if (db_setval((UCHAR1 *)&newaddr, &((UCHAR1 *)newdata)[aindex*datasize], type,
5108 cluster, (CHAR *)__FILE__, (INTBIG)__LINE__)) return(TRUE);
5109 #else
5110 if (db_setval((UCHAR1 *)&newaddr, &((UCHAR1 *)newdata)[aindex*datasize], type,
5111 cluster)) return(TRUE);
5112 #endif
5113 continue;
5114 }
5115 if (j < origlen)
5116 {
5117 switch (type&VTYPE)
5118 {
5119 case VCHAR: ((CHAR *)newdata)[i] = ((CHAR *)var->addr)[j]; break;
5120 case VFLOAT: ((float *)newdata)[i] = ((float *)var->addr)[j]; break;
5121 case VDOUBLE: ((double *)newdata)[i] = ((double *)var->addr)[j]; break;
5122 case VSHORT: ((INTSML *)newdata)[i] = ((INTSML *)var->addr)[j]; break;
5123 default: ((INTBIG *)newdata)[i] = ((INTBIG *)var->addr)[j]; break;
5124 }
5125 j++;
5126 } else
5127 {
5128 if ((type&(VCODE1|VCODE2)) != 0 || (type&VTYPE) == VSTRING)
5129 {
5130 (void)allocstring(&((CHAR **)newdata)[i], x_(""), cluster);
5131 } else
5132 {
5133 switch (type&VTYPE)
5134 {
5135 case VCHAR: ((CHAR *)newdata)[i] = 0; break;
5136 case VFLOAT: ((float *)newdata)[i] = 0.0; break;
5137 case VDOUBLE: ((double *)newdata)[i] = 0.0; break;
5138 case VSHORT: ((INTSML *)newdata)[i] = 0; break;
5139 default: ((INTBIG *)newdata)[i] = 0; break;
5140 }
5141 }
5142 }
5143 }
5144 efree((CHAR *)var->addr);
5145 var->addr = (INTBIG)newdata;
5146
5147 /* bump the array size */
5148 if ((var->type&VLENGTH) != 0)
5149 var->type = (var->type & ~VLENGTH) | (truelen << VLENGTHSH);
5150
5151 /* handle change control, constraint, and broadcast */
5152 if (!db_donextchangequietly && !db_dochangesquietly)
5153 {
5154 /* tell constraint system about inserted variable */
5155 (*el_curconstraint->insertvariable)(objaddr, objtype, var->key, aindex);
5156
5157 /* mark a change */
5158 (void)db_change((INTBIG)objaddr, VARIABLEINS, objtype, var->key, type,
5159 aindex, 0, 0);
5160 }
5161
5162 return(FALSE);
5163 }
5164
5165 /*
5166 * routine to delete entry "aindex" of array variable "var" (which is on object
5167 * "objaddr" of type "objtype"). Returns true upon error.
5168 */
db_delindvar(INTBIG objaddr,INTBIG objtype,VARIABLE * var,INTBIG aindex)5169 BOOLEAN db_delindvar(INTBIG objaddr, INTBIG objtype, VARIABLE *var, INTBIG aindex)
5170 {
5171 REGISTER INTBIG i, len, truelen, oldvalue, type;
5172 REGISTER INTBIG datasize;
5173 REGISTER void *loc;
5174
5175 /* if the variable or key is not valid then ignore this */
5176 if (var == NOVARIABLE) return(TRUE);
5177
5178 /* if the variable is not an array, quit now */
5179 type = var->type;
5180 if ((type&VISARRAY) == 0) return(TRUE);
5181
5182 /* ensure that the index is within the range of the array */
5183 truelen = len = getlength(var);
5184
5185 /* can only delete valid line number */
5186 if (aindex < 0 || aindex >= len) return(TRUE);
5187
5188 /* cannot delete last entry */
5189 if (truelen == 1) return(TRUE);
5190
5191 /* if this is a variable-length array, include the terminator */
5192 if ((var->type&VLENGTH) == 0) len++;
5193
5194 /* determine the size of the array entries */
5195 datasize = db_getdatasize(type);
5196
5197 /* get the address of the old array entry */
5198 loc = &((CHAR *)var->addr)[aindex*datasize];
5199 oldvalue = db_assignvalue(loc, datasize);
5200
5201 /* shift the data */
5202 for(i=aindex; i<len-1; i++)
5203 {
5204 switch (type&VTYPE)
5205 {
5206 case VCHAR:
5207 ((CHAR *)var->addr)[i] = ((CHAR *)var->addr)[i+1];
5208 break;
5209 case VFLOAT:
5210 ((float *)var->addr)[i] = ((float *)var->addr)[i+1];
5211 break;
5212 case VDOUBLE:
5213 ((double *)var->addr)[i] = ((double *)var->addr)[i+1];
5214 break;
5215 case VSHORT:
5216 ((INTSML *)var->addr)[i] = ((INTSML *)var->addr)[i+1];
5217 break;
5218 default:
5219 ((INTBIG *)var->addr)[i] = ((INTBIG *)var->addr)[i+1];
5220 break;
5221 }
5222 }
5223
5224 /* decrement the array size */
5225 if ((var->type&VLENGTH) != 0)
5226 var->type = (var->type & ~VLENGTH) | ((truelen-1) << VLENGTHSH);
5227
5228 /* handle change control, constraint, and broadcast */
5229 if (!db_donextchangequietly && !db_dochangesquietly)
5230 {
5231 /* tell constraint system about deleted variable */
5232 (*el_curconstraint->deletevariable)(objaddr, objtype, var->key, aindex, oldvalue);
5233
5234 /* mark a change */
5235 (void)db_change((INTBIG)objaddr, VARIABLEDEL, objtype, var->key, type,
5236 aindex, oldvalue, 0);
5237 }
5238
5239 return(FALSE);
5240 }
5241
5242 /*
5243 * routine to set an individual variable entry at address "to" to the value
5244 * at address "from". This type is of type "type" and if allocatable, is
5245 * filled from cluster "cluster".
5246 */
5247 #ifdef DEBUGMEMORY
db_setval(UCHAR1 * from,UCHAR1 * to,INTBIG type,CLUSTER * cluster,CHAR * module,INTBIG line)5248 BOOLEAN db_setval(UCHAR1 *from, UCHAR1 *to, INTBIG type, CLUSTER *cluster,
5249 CHAR *module, INTBIG line)
5250 #else
5251 BOOLEAN db_setval(UCHAR1 *from, UCHAR1 *to, INTBIG type, CLUSTER *cluster)
5252 #endif
5253 {
5254 /* character sized variable */
5255 if ((type&VTYPE) == VCHAR || (type&VTYPE) == VBOOLEAN)
5256 {
5257 *to = *from;
5258 return(FALSE);
5259 }
5260
5261 /* double sized variable */
5262 if ((type&VTYPE) == VDOUBLE)
5263 {
5264 ((double *)to)[0] = ((double *)from)[0];
5265 return(FALSE);
5266 }
5267
5268 /* float sized variable */
5269 if ((type&VTYPE) == VFLOAT)
5270 {
5271 ((float *)to)[0] = ((float *)from)[0];
5272 return(FALSE);
5273 }
5274
5275 /* short sized variable */
5276 if ((type&VTYPE) == VSHORT)
5277 {
5278 ((INTSML *)to)[0] = (INTSML)(((INTBIG *)from)[0]);
5279 return(FALSE);
5280 }
5281
5282 /* integer sized variable */
5283 if ((type&(VCODE1|VCODE2)) == 0 && (type&VTYPE) != VSTRING)
5284 {
5285 ((INTBIG *)to)[0] = ((INTBIG *)from)[0];
5286 return(FALSE);
5287 }
5288
5289 /* string or code variable */
5290 #ifdef DEBUGMEMORY
5291 return(_allocstring((CHAR **)to, ((CHAR **)from)[0], cluster, module, line));
5292 #else
5293 return(allocstring((CHAR **)to, ((CHAR **)from)[0], cluster));
5294 #endif
5295 }
5296
5297 /*
5298 * routine to erase a list of variables when the object is deleted
5299 */
db_freevars(VARIABLE ** firstvar,INTSML * numvar)5300 void db_freevars(VARIABLE **firstvar, INTSML *numvar)
5301 {
5302 REGISTER INTBIG i;
5303 REGISTER VARIABLE *var;
5304 if (*numvar == 0) return;
5305 for(i = 0; i < *numvar; i++)
5306 {
5307 var = &(*firstvar)[i];
5308 db_freevar(var->addr, var->type);
5309 }
5310 efree((CHAR *)*firstvar);
5311 *numvar = 0;
5312 }
5313
5314 /*
5315 * routine to free any memory allocated to the variable whose address is "addr"
5316 * and whose type is "type"
5317 */
db_freevar(INTBIG addr,INTBIG type)5318 void db_freevar(INTBIG addr, INTBIG type)
5319 {
5320 REGISTER INTBIG i, len;
5321
5322 /* determine whether individual elements are allocated */
5323 if ((type&(VCODE1|VCODE2)) != 0 || (type&VTYPE) == VSTRING)
5324 {
5325 /* the old variable was allocated */
5326 if ((type&VISARRAY) != 0)
5327 {
5328 len = (type&VLENGTH) >> VLENGTHSH;
5329 if (len == 0)
5330 {
5331 for(i=0; ((INTBIG *)addr)[i] != -1; i++)
5332 efree((CHAR *)((INTBIG *)addr)[i]);
5333 } else for(i=0; i<len; i++) efree((CHAR *)((INTBIG *)addr)[i]);
5334 } else efree((CHAR *)addr);
5335 }
5336 if ((type&VISARRAY) != 0) efree((CHAR *)addr);
5337 }
5338
5339 /*
5340 * routine to do a binary search on the variables in "numvar" and "firstvar"
5341 * for an entry with the key "key". If found, its index is returned,
5342 * otherwise a negative value is returned that, when negated, is the position
5343 * in the list BEFORE which the key should be inserted (i.e. the value -1
5344 * means that the key belongs in the first entry and the value -3 means that
5345 * the key belongs after the second entry).
5346 */
db_binarysearch(INTSML numvar,VARIABLE * firstvar,INTBIG key)5347 INTBIG db_binarysearch(INTSML numvar, VARIABLE *firstvar, INTBIG key)
5348 {
5349 REGISTER INTBIG hi, lo, med, lastmed;
5350 REGISTER INTBIG i=key;
5351
5352 if (numvar == 0) return(-1);
5353 lo = 0; hi = lastmed = numvar;
5354 for(;;)
5355 {
5356 /* find mid-point: quit if done */
5357 med = (hi + lo) / 2;
5358 if (med == lastmed) break;
5359 lastmed = med;
5360
5361 /* test the entry: return the value if a match */
5362 i = firstvar[med].key;
5363 if (i == key) return(med);
5364
5365 /* decide which way to search in list */
5366 if (i > key) hi = med; else lo = med;
5367 }
5368 if (i < key) med++;
5369 return(-med-1);
5370 }
5371
db_renamevar(INTSML numvar,VARIABLE * firstvar,INTBIG oldkey,INTBIG newkey)5372 void db_renamevar(INTSML numvar, VARIABLE *firstvar, INTBIG oldkey,
5373 INTBIG newkey)
5374 {
5375 REGISTER INTBIG i, j, k;
5376 REGISTER INTBIG oldaddr, oldtype;
5377 UINTBIG olddescript[TEXTDESCRIPTSIZE];
5378 REGISTER VARIABLE *var;
5379
5380 if (numvar == 0) return;
5381
5382 for(i=0; i<numvar; i++)
5383 {
5384 var = &firstvar[i];
5385 if (var->key != oldkey) continue;
5386
5387 /* save the old information about this variable */
5388 oldtype = var->type;
5389 TDCOPY(olddescript, var->textdescript);
5390 oldaddr = var->addr;
5391
5392 /* compact out the old key */
5393 for(j=i+1; j<numvar; j++)
5394 {
5395 firstvar[j-1].key = firstvar[j].key;
5396 firstvar[j-1].type = firstvar[j].type;
5397 TDCOPY(firstvar[j-1].textdescript, firstvar[j].textdescript);
5398 firstvar[j-1].addr = firstvar[j].addr;
5399 }
5400
5401 /* now insert the new key */
5402 for(j=0; j<numvar-1; j++) if (newkey < firstvar[j].key) break;
5403 for(k=numvar-1; k>j; k--)
5404 {
5405 firstvar[k].key = firstvar[k-1].key;
5406 firstvar[k].type = firstvar[k-1].type;
5407 TDCOPY(firstvar[k].textdescript, firstvar[k-1].textdescript);
5408 firstvar[k].addr = firstvar[k-1].addr;
5409 }
5410
5411 /* insert the renamed variable in the right place */
5412 firstvar[j].key = newkey;
5413 firstvar[j].type = oldtype;
5414 TDCOPY(firstvar[j].textdescript, olddescript);
5415 firstvar[j].addr = oldaddr;
5416 }
5417 }
5418
5419 /*
5420 * routine to fill the parameters "fir" and "num" with the "firstvar" and
5421 * "numvar" attributes on object "addr", type "type". Returns false if
5422 * successful, true if the object has no "firstvar/numvar".
5423 */
db_getvarptr(INTBIG addr,INTBIG type,VARIABLE *** fir,INTSML ** num)5424 BOOLEAN db_getvarptr(INTBIG addr, INTBIG type, VARIABLE ***fir, INTSML **num)
5425 {
5426 REGISTER NODEINST *ni;
5427 REGISTER NODEPROTO *np;
5428 REGISTER PORTARCINST *pi;
5429 REGISTER PORTEXPINST *pe;
5430 REGISTER PORTPROTO *pp;
5431 REGISTER ARCINST *ai;
5432 REGISTER ARCPROTO *ap;
5433 REGISTER GEOM *g;
5434 REGISTER LIBRARY *lib;
5435 REGISTER TECHNOLOGY *tech;
5436 REGISTER TOOL *tool;
5437 REGISTER RTNODE *rtn;
5438 REGISTER NETWORK *net;
5439 REGISTER VIEW *v;
5440
5441 switch (type&VTYPE)
5442 {
5443 case VNODEINST:
5444 ni = (NODEINST *)addr;
5445 *fir = &ni->firstvar; *num = &ni->numvar; break;
5446 case VNODEPROTO:
5447 np = (NODEPROTO *)addr;
5448 *fir = &np->firstvar; *num = &np->numvar; break;
5449 case VPORTARCINST:
5450 pi = (PORTARCINST *)addr;
5451 *fir = &pi->firstvar; *num = &pi->numvar; break;
5452 case VPORTEXPINST:
5453 pe = (PORTEXPINST *)addr;
5454 *fir = &pe->firstvar; *num = &pe->numvar; break;
5455 case VPORTPROTO:
5456 pp = (PORTPROTO *)addr;
5457 *fir = &pp->firstvar; *num = &pp->numvar; break;
5458 case VARCINST:
5459 ai = (ARCINST *)addr;
5460 *fir = &ai->firstvar; *num = &ai->numvar; break;
5461 case VARCPROTO:
5462 ap = (ARCPROTO *)addr;
5463 *fir = &ap->firstvar; *num = &ap->numvar; break;
5464 case VGEOM:
5465 g = (GEOM *)addr;
5466 *fir = &g->firstvar; *num = &g->numvar; break;
5467 case VLIBRARY:
5468 lib = (LIBRARY *)addr;
5469 *fir = &lib->firstvar; *num = &lib->numvar; break;
5470 case VTECHNOLOGY:
5471 tech = (TECHNOLOGY *)addr;
5472 *fir = &tech->firstvar; *num = &tech->numvar; break;
5473 case VTOOL:
5474 tool = (TOOL *)addr;
5475 *fir = &tool->firstvar; *num = &tool->numvar; break;
5476 case VRTNODE:
5477 rtn = (RTNODE *)addr;
5478 *fir = &rtn->firstvar; *num = &rtn->numvar; break;
5479 case VNETWORK:
5480 net = (NETWORK *)addr;
5481 *fir = &net->firstvar; *num = &net->numvar; break;
5482 case VVIEW:
5483 v = (VIEW *)addr;
5484 *fir = &v->firstvar; *num = &v->numvar; break;
5485 default: return(TRUE);
5486 }
5487 return(FALSE);
5488 }
5489
db_getdatasize(INTBIG type)5490 INTBIG db_getdatasize(INTBIG type)
5491 {
5492 if ((type&VTYPE) == VCHAR || (type&VTYPE) == VBOOLEAN) return(SIZEOFCHAR);
5493 if ((type&VTYPE) == VSHORT) return(SIZEOFINTSML);
5494 if ((type&VTYPE) == VFLOAT) return(sizeof(float));
5495 if ((type&VTYPE) == VDOUBLE) return(sizeof(double));
5496 return(SIZEOFINTBIG);
5497 }
5498
db_assignvalue(void * loc,INTBIG datasize)5499 INTBIG db_assignvalue(void *loc, INTBIG datasize)
5500 {
5501 if (datasize == SIZEOFINTBIG) return(*((INTBIG *)loc));
5502 if (datasize == SIZEOFINTSML) return(*((INTSML *)loc));
5503 if (datasize == SIZEOFCHAR) return(*((CHAR *)loc));
5504 if (datasize == sizeof(float)) return(castint(*((float *)loc)));
5505 if (datasize == sizeof(double)) return(castint((float)(*((double *)loc))));
5506 return(*((INTBIG *)loc));
5507 }
5508
db_describetype(INTBIG type)5509 CHAR *db_describetype(INTBIG type)
5510 {
5511 REGISTER void *infstr;
5512
5513 infstr = initinfstr();
5514 switch (type&VTYPE)
5515 {
5516 case VINTEGER: addstringtoinfstr(infstr, _("Integer")); break;
5517 case VADDRESS: addstringtoinfstr(infstr, _("Address")); break;
5518 case VCHAR: addstringtoinfstr(infstr, _("Character")); break;
5519 case VSTRING: addstringtoinfstr(infstr, _("String")); break;
5520 case VFLOAT: addstringtoinfstr(infstr, _("Float")); break;
5521 case VDOUBLE: addstringtoinfstr(infstr, _("Double")); break;
5522 case VNODEINST: addstringtoinfstr(infstr, _("NodeInst")); break;
5523 case VNODEPROTO: addstringtoinfstr(infstr, _("NodeProto")); break;
5524 case VPORTARCINST: addstringtoinfstr(infstr, _("PortArcInst")); break;
5525 case VPORTEXPINST: addstringtoinfstr(infstr, _("PortExpInst")); break;
5526 case VPORTPROTO: addstringtoinfstr(infstr, _("PortProto")); break;
5527 case VARCINST: addstringtoinfstr(infstr, _("ArcInst")); break;
5528 case VARCPROTO: addstringtoinfstr(infstr, _("ArcProto")); break;
5529 case VGEOM: addstringtoinfstr(infstr, _("Geom")); break;
5530 case VLIBRARY: addstringtoinfstr(infstr, _("Library")); break;
5531 case VTECHNOLOGY: addstringtoinfstr(infstr, _("Technology")); break;
5532 case VTOOL: addstringtoinfstr(infstr, _("Tool")); break;
5533 case VRTNODE: addstringtoinfstr(infstr, _("RTNode")); break;
5534 case VFRACT: addstringtoinfstr(infstr, _("Fixed-Point")); break;
5535 case VNETWORK: addstringtoinfstr(infstr, _("Network")); break;
5536 case VVIEW: addstringtoinfstr(infstr, _("View")); break;
5537 case VWINDOWPART: addstringtoinfstr(infstr, _("Window")); break;
5538 case VGRAPHICS: addstringtoinfstr(infstr, _("Graphics")); break;
5539 case VSHORT: addstringtoinfstr(infstr, _("Short")); break;
5540 case VBOOLEAN: addstringtoinfstr(infstr, _("Boolean")); break;
5541 case VCONSTRAINT: addstringtoinfstr(infstr, _("Constraint")); break;
5542 case VWINDOWFRAME: addstringtoinfstr(infstr, _("WindowFrame")); break;
5543 case VGENERAL: addstringtoinfstr(infstr, _("General")); break;
5544 default: addstringtoinfstr(infstr, _("Unknown")); break;
5545 }
5546 if ((type&VISARRAY) != 0) addstringtoinfstr(infstr, _(" array"));
5547 return(returninfstr(infstr));
5548 }
5549