1 /* -*- tab-width: 4 -*-
2 *
3 * Electric(tm) VLSI Design System
4 *
5 * File: iotexto.c
6 * Input/output tool: textual format output
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 "eio.h"
34
35 static INTBIG io_cellnumber, io_nodeinsterror, io_portarcinsterror, io_portexpinsterror,
36 io_portprotoerror, io_arcinsterror, io_geomerror, io_rtnodeerror, io_libraryerror;
37
38 /* prototypes for local routines */
39 static void io_textrecurse(NODEPROTO*);
40 static INTBIG io_countvars(INTBIG, VARIABLE*);
41 static void io_writevars(INTBIG, VARIABLE*, NODEPROTO*);
42 static CHAR *io_makestring(VARIABLE*, NODEPROTO*);
43 static void io_makestringvar(void*, INTBIG, INTBIG, NODEPROTO*);
44 static void io_addstring(void*, CHAR*);
45 static void io_printname(CHAR*, FILE*);
46
io_writetextlibrary(LIBRARY * lib)47 BOOLEAN io_writetextlibrary(LIBRARY *lib)
48 {
49 REGISTER CHAR *name;
50 CHAR file[256], *truename;
51 REGISTER INTBIG i, j, t, noc, arcinst, poc, cell, cellgroup;
52 REGISTER NODEPROTO *np, *onp;
53 REGISTER PORTPROTO *pp;
54 REGISTER LIBRARY *olib;
55 REGISTER NODEINST *ni;
56 REGISTER PORTARCINST *pi;
57 REGISTER PORTEXPINST *pe;
58 REGISTER ARCINST *ai;
59 REGISTER TECHNOLOGY *tech;
60 REGISTER VIEW *v;
61 REGISTER NODEPROTO **cells;
62
63 (void)estrcpy(file, lib->libfile);
64 name = &file[estrlen(file)-5];
65 if (estrcmp(name, x_(".elib")) == 0) *name = 0;
66 name = &file[estrlen(file)-4];
67 if (estrcmp(name, x_(".txt")) != 0) (void)estrcat(file, x_(".txt"));
68 name = truepath(file);
69 io_fileout = xcreate(name, io_filetypetlib, _("Readable Dump File"), &truename);
70 if (io_fileout == NULL)
71 {
72 if (truename != 0) ttyputerr(_("Cannot write %s"), truename);
73 return(TRUE);
74 }
75
76 /* clear error counters */
77 io_nodeinsterror = io_portarcinsterror = io_portexpinsterror = 0;
78 io_portprotoerror = io_arcinsterror = io_geomerror = io_libraryerror = 0;
79 io_rtnodeerror = 0;
80
81 /* determine proper library order */
82 for(olib = el_curlib; olib != NOLIBRARY; olib = olib->nextlibrary)
83 for(np = olib->firstnodeproto; np != NONODEPROTO; np = np->nextnodeproto)
84 np->temp1 = -1;
85 io_cellnumber = 0;
86 for(np = lib->firstnodeproto; np != NONODEPROTO; np = np->nextnodeproto)
87 if (np->firstinst == NONODEINST) io_textrecurse(np);
88 for(np = lib->firstnodeproto; np != NONODEPROTO; np = np->nextnodeproto)
89 if (np->temp1 < 0) io_textrecurse(np);
90 if (io_cellnumber > 0)
91 {
92 cells = (NODEPROTO **)emalloc((io_cellnumber * sizeof(NODEPROTO *)),
93 io_tool->cluster);
94 if (cells == 0)
95 {
96 ttyputnomemory();
97 return(TRUE);
98 }
99 for(olib = el_curlib; olib != NOLIBRARY; olib = olib->nextlibrary)
100 {
101 for(np = olib->firstnodeproto; np != NONODEPROTO; np = np->nextnodeproto)
102 {
103 if (np->temp1 >= 0 && np->temp1 < io_cellnumber)
104 cells[np->temp1] = np;
105 }
106 }
107 }
108
109 /* determine cell groupings */
110 for(np = lib->firstnodeproto; np != NONODEPROTO; np = np->nextnodeproto)
111 np->temp2 = 0;
112 cellgroup = 0;
113 for(np = lib->firstnodeproto; np != NONODEPROTO; np = np->nextnodeproto)
114 {
115 if (np->temp2 != 0) continue;
116 cellgroup++;
117 FOR_CELLGROUP(onp, np)
118 onp->temp2 = cellgroup;
119 }
120
121 /* write header information */
122 xprintf(io_fileout, x_("****library: \"%s\"\n"), lib->libname);
123 xprintf(io_fileout, x_("version: %s\n"), el_version);
124 xprintf(io_fileout, x_("aids: %ld\n"), el_maxtools);
125 for(i=0; i<el_maxtools; i++)
126 {
127 xprintf(io_fileout, x_("aidname: %s\n"), el_tools[i].toolname);
128 if (io_countvars(el_tools[i].numvar, el_tools[i].firstvar) != 0)
129 io_writevars(el_tools[i].numvar, el_tools[i].firstvar, NONODEPROTO);
130 }
131 xprintf(io_fileout, x_("userbits: %ld\n"), lib->userbits);
132 xprintf(io_fileout, x_("techcount: %ld\n"), el_maxtech);
133 for(tech = el_technologies; tech != NOTECHNOLOGY; tech = tech->nexttechnology)
134 {
135 xprintf(io_fileout, x_("techname: %s lambda: %ld\n"), tech->techname, lib->lambda[tech->techindex]);
136 io_writevars(tech->numvar, tech->firstvar, NONODEPROTO);
137 }
138 for(v = el_views; v != NOVIEW; v = v->nextview)
139 xprintf(io_fileout, x_("view: %s{%s}\n"), v->viewname, v->sviewname);
140 xprintf(io_fileout, x_("cellcount: %ld\n"), io_cellnumber);
141 if (lib->curnodeproto != NONODEPROTO)
142 xprintf(io_fileout, x_("maincell: %ld\n"), lib->curnodeproto->temp1);
143
144 /* write variables on the library */
145 io_writevars(lib->numvar, lib->firstvar, NONODEPROTO);
146
147 /* write the rest of the database */
148 for(cell = 0; cell < io_cellnumber; cell++)
149 {
150 /* write the nodeproto name */
151 np = cells[cell];
152 xprintf(io_fileout, x_("***cell: %ld/%ld\n"), np->temp1, np->temp2);
153 xprintf(io_fileout, x_("name: %s"), np->protoname);
154 if (*np->cellview->sviewname != 0)
155 xprintf(io_fileout, x_("{%s}"), np->cellview->sviewname);
156 xprintf(io_fileout, x_("\n"));
157 xprintf(io_fileout, x_("version: %ld\n"), np->version);
158 xprintf(io_fileout, x_("creationdate: %ld\n"), np->creationdate);
159 xprintf(io_fileout, x_("revisiondate: %ld\n"), np->revisiondate);
160
161 /* write the nodeproto bounding box */
162 xprintf(io_fileout, x_("lowx: %ld highx: %ld lowy: %ld highy: %ld\n"),
163 np->lowx, np->highx, np->lowy, np->highy);
164
165 /* cells in external libraries mention the library and stop */
166 if (np->lib != lib)
167 {
168 xprintf(io_fileout, x_("externallibrary: \"%s\"\n"),
169 np->lib->libfile);
170 continue;
171 }
172
173 /* write tool information */
174 xprintf(io_fileout, x_("aadirty: %ld\n"), np->adirty);
175 xprintf(io_fileout, x_("userbits: %ld\n"), np->userbits);
176
177 /* count and number the nodes, arcs, and ports */
178 noc = arcinst = poc = 0;
179 for(ni = np->firstnodeinst; ni != NONODEINST; ni = ni->nextnodeinst)
180 ni->temp1 = noc++;
181 for(ai = np->firstarcinst; ai != NOARCINST; ai = ai->nextarcinst)
182 ai->temp1 = arcinst++;
183 for(pp = np->firstportproto; pp != NOPORTPROTO; pp = pp->nextportproto)
184 pp->temp1 = poc++;
185 xprintf(io_fileout, x_("nodes: %ld arcs: %ld porttypes: %ld\n"), noc, arcinst, poc);
186
187 /* write variables on the cell */
188 io_writevars(np->numvar, np->firstvar, np);
189
190 /* write the nodes in this cell */
191 for(ni = np->firstnodeinst; ni != NONODEINST; ni = ni->nextnodeinst)
192 {
193 xprintf(io_fileout, x_("**node: %ld\n"), ni->temp1);
194 if (ni->proto->primindex == 0)
195 xprintf(io_fileout, x_("type: [%ld]\n"), ni->proto->temp1); else
196 xprintf(io_fileout, x_("type: %s:%s\n"),
197 ni->proto->tech->techname, ni->proto->protoname);
198 xprintf(io_fileout, x_("lowx: %ld highx: %ld lowy: %ld highy: %ld\n"), ni->lowx,
199 ni->highx, ni->lowy, ni->highy);
200 if (ni->transpose != 0) t = 1; else t = 0;
201 xprintf(io_fileout, x_("rotation: %d transpose: %d\n"), ni->rotation, t);
202 if (ni->proto->primindex == 0)
203 {
204 xprintf(io_fileout, x_("descript: %ld/%ld\n"), ni->textdescript[0],
205 ni->textdescript[1]);
206 }
207 xprintf(io_fileout, x_("userbits: %ld\n"), ni->userbits);
208 io_writevars(ni->numvar, ni->firstvar, np);
209
210 pi = ni->firstportarcinst; pe = ni->firstportexpinst;
211 for(pp = ni->proto->firstportproto, i=0; pp != NOPORTPROTO; pp = pp->nextportproto, i++)
212 {
213 j = 0;
214 while (pi != NOPORTARCINST && pi->proto == pp)
215 {
216 if (j == 0) xprintf(io_fileout, x_("*port: %s\n"), pp->protoname);
217 j++;
218 xprintf(io_fileout, x_("arc: %ld\n"), pi->conarcinst->temp1);
219 io_writevars(pi->numvar, pi->firstvar, np);
220 pi = pi->nextportarcinst;
221 }
222 while (pe != NOPORTEXPINST && pe->proto == pp)
223 {
224 if (j == 0) xprintf(io_fileout, x_("*port: %s\n"), pp->protoname);
225 j++;
226 xprintf(io_fileout, x_("exported: %ld\n"), pe->exportproto->temp1);
227 io_writevars(pe->numvar, pe->firstvar, np);
228 pe = pe->nextportexpinst;
229 }
230 }
231 }
232
233 /* write the portprotos in this cell */
234 poc = 0;
235 for(pp = np->firstportproto; pp != NOPORTPROTO; pp = pp->nextportproto)
236 {
237 xprintf(io_fileout, x_("**porttype: %ld\n"), poc++);
238 xprintf(io_fileout, x_("subnode: %ld\n"), pp->subnodeinst->temp1);
239 xprintf(io_fileout, x_("subport: %s\n"), pp->subportproto->protoname);
240 xprintf(io_fileout, x_("name: %s\n"), pp->protoname);
241
242 /* need to write both words */
243 xprintf(io_fileout, x_("descript: %ld/%ld\n"), pp->textdescript[0],
244 pp->textdescript[1]);
245 xprintf(io_fileout, x_("userbits: %ld\n"), pp->userbits);
246 io_writevars(pp->numvar, pp->firstvar, np);
247 }
248
249 /* write the arcs in this cell */
250 for(ai = np->firstarcinst; ai != NOARCINST; ai = ai->nextarcinst)
251 {
252 xprintf(io_fileout, x_("**arc: %ld\n"), ai->temp1);
253 xprintf(io_fileout, x_("type: %s:%s\n"), ai->proto->tech->techname, ai->proto->protoname);
254 xprintf(io_fileout, x_("width: %ld length: %ld\n"), ai->width, ai->length);
255 xprintf(io_fileout, x_("userbits: %ld\n"), ai->userbits);
256 for(i=0; i<2; i++)
257 {
258 xprintf(io_fileout, x_("*end: %ld\n"), i);
259 xprintf(io_fileout, x_("node: %ld\n"), ai->end[i].nodeinst->temp1);
260 xprintf(io_fileout, x_("nodeport: %s\n"), ai->end[i].portarcinst->proto->protoname);
261 xprintf(io_fileout, x_("xpos: %ld ypos: %ld\n"), ai->end[i].xpos, ai->end[i].ypos);
262 }
263 io_writevars(ai->numvar, ai->firstvar, np);
264 }
265 xprintf(io_fileout, x_("celldone: %s\n"), np->protoname);
266 }
267
268 /* print any variable-related error messages */
269 if (io_nodeinsterror != 0)
270 ttyputmsg(x_("Warning: %ld NODEINST pointers point outside cell: not saved"), io_nodeinsterror);
271 if (io_arcinsterror != 0)
272 ttyputmsg(x_("Warning: %ld ARCINST pointers point outside cell: not saved"), io_arcinsterror);
273 if (io_portprotoerror != 0)
274 ttyputmsg(x_("Warning: %ld PORTPROTO pointers point outside cell: not saved"), io_portprotoerror);
275 if (io_portarcinsterror != 0)
276 ttyputmsg(x_("Warning: %ld PORTARCINST pointers could not be saved"), io_portarcinsterror);
277 if (io_portexpinsterror != 0)
278 ttyputmsg(x_("Warning: %ld PORTEXPINST pointers could not be saved"), io_portexpinsterror);
279 if (io_geomerror != 0)
280 ttyputmsg(x_("Warning: %ld GEOM pointers could not be saved"), io_geomerror);
281 if (io_rtnodeerror != 0)
282 ttyputmsg(x_("Warning: %ld RTNODE pointers could not be saved"), io_rtnodeerror);
283 if (io_libraryerror != 0)
284 ttyputmsg(x_("Warning: LIBRARY pointers could not be saved"), io_libraryerror);
285
286 /* clean up and return */
287 xclose(io_fileout);
288 ttyputmsg(_("%s written"), truename);
289 lib->userbits &= ~(LIBCHANGEDMAJOR | LIBCHANGEDMINOR);
290 if (io_cellnumber > 0) efree((CHAR *)cells);
291 return(FALSE);
292 }
293
294 /*
295 * routine to help order the library for proper nonforward references
296 * in the outout
297 */
io_textrecurse(NODEPROTO * np)298 void io_textrecurse(NODEPROTO *np)
299 {
300 REGISTER NODEINST *ni;
301
302 for(ni = np->firstnodeinst; ni != NONODEINST; ni = ni->nextnodeinst)
303 {
304 if (ni->proto->primindex != 0) continue;
305 if (ni->proto->temp1 == -1) io_textrecurse(ni->proto);
306 }
307
308 /* add this cell to the list */
309 np->temp1 = io_cellnumber++;
310 }
311
312 /*
313 * routine to return the number of permanent variables on an object
314 */
io_countvars(INTBIG numvar,VARIABLE * firstvar)315 INTBIG io_countvars(INTBIG numvar, VARIABLE *firstvar)
316 {
317 REGISTER INTBIG i, j;
318
319 i = 0;
320 for(j=0; j<numvar; j++)
321 if ((firstvar[j].type & VDONTSAVE) == 0) i++;
322 return(i);
323 }
324
325 /*
326 * routine to write the variables on an object. The current cell is
327 * "curnodeproto" such that any references to objects in a cell must be in
328 * this cell.
329 */
io_writevars(INTBIG numvar,VARIABLE * firstvar,NODEPROTO * curnodeproto)330 void io_writevars(INTBIG numvar, VARIABLE *firstvar, NODEPROTO *curnodeproto)
331 {
332 REGISTER CHAR *pt;
333 REGISTER INTBIG i;
334 REGISTER VARIABLE *var;
335
336 i = io_countvars(numvar, firstvar);
337 if (i == 0) return;
338
339 xprintf(io_fileout, x_("variables: %ld\n"), i);
340 for(i=0; i<numvar; i++)
341 {
342 var = &firstvar[i];
343 if ((var->type & VDONTSAVE) != 0) continue;
344 pt = io_makestring(var, curnodeproto);
345 if (pt == 0) pt = x_("");
346 io_printname((CHAR *)var->key, io_fileout);
347 if ((var->type&(VLENGTH|VISARRAY)) != VISARRAY)
348 {
349 xprintf(io_fileout, x_("[0%o,0%o/0%o]: "), var->type, var->textdescript[0],
350 var->textdescript[1]);
351 } else
352 {
353 xprintf(io_fileout, x_("(%ld)[0%o,0%o/0%o]: "), getlength(var), var->type,
354 var->textdescript[0], var->textdescript[1]);
355 }
356 xprintf(io_fileout, x_("%s\n"), pt);
357 }
358 }
359
360 /*
361 * routine to convert variable "var" to a string for printing in the text file.
362 * returns zero on error
363 */
io_makestring(VARIABLE * var,NODEPROTO * curnodeproto)364 CHAR *io_makestring(VARIABLE *var, NODEPROTO *curnodeproto)
365 {
366 REGISTER INTBIG i, len;
367 CHAR line[50];
368 REGISTER CHAR *pt;
369 REGISTER void *infstr;
370
371 if (var == NOVARIABLE) return(0);
372
373 infstr = initinfstr();
374 if ((var->type&VISARRAY) != 0)
375 {
376 len = getlength(var);
377 for(i=0; i<len; i++)
378 {
379 if (i == 0) addtoinfstr(infstr, '['); else
380 addtoinfstr(infstr, ',');
381
382 if ((var->type&VTYPE) == VGENERAL)
383 {
384 if ((i&1) == 0)
385 {
386 (void)esnprintf(line, 50, x_("0%lo"), ((INTBIG *)var->addr)[i+1]);
387 addstringtoinfstr(infstr, line);
388 } else
389 {
390 io_makestringvar(infstr, ((INTBIG *)var->addr)[i], ((INTBIG *)var->addr)[i-1],
391 curnodeproto);
392 }
393 } else
394 {
395 switch ((var->type&VTYPE))
396 {
397 case VCHAR:
398 io_makestringvar(infstr, var->type, ((INTBIG)((CHAR *)var->addr)[i]),
399 curnodeproto);
400 break;
401
402 case VSHORT:
403 io_makestringvar(infstr, var->type, ((INTBIG)((INTSML *)var->addr)[i]),
404 curnodeproto);
405 break;
406
407 case VDOUBLE:
408 io_makestringvar(infstr, var->type, ((INTBIG)((double *)var->addr)[i]),
409 curnodeproto);
410 break;
411
412 default:
413 io_makestringvar(infstr, var->type, ((INTBIG *)var->addr)[i], curnodeproto);
414 break;
415 }
416 }
417 }
418 addtoinfstr(infstr, ']');
419 } else io_makestringvar(infstr, var->type, var->addr, curnodeproto);
420 pt = returninfstr(infstr);
421 return(pt);
422 }
423
424 /*
425 * routine to make a string from the value in "addr" which has a type in
426 * "type".
427 */
io_makestringvar(void * infstr,INTBIG type,INTBIG addr,NODEPROTO * curnodeproto)428 void io_makestringvar(void *infstr, INTBIG type, INTBIG addr, NODEPROTO *curnodeproto)
429 {
430 CHAR line[100];
431 REGISTER INTBIG cindex;
432 REGISTER NODEINST *ni;
433 REGISTER NODEPROTO *np;
434 REGISTER PORTARCINST *pi;
435 REGISTER PORTEXPINST *pe;
436 REGISTER PORTPROTO *pp;
437 REGISTER ARCINST *ai;
438 REGISTER ARCPROTO *ap;
439 REGISTER GEOM *geom;
440 REGISTER RTNODE *rtn;
441 REGISTER LIBRARY *lib;
442 REGISTER TECHNOLOGY *tech;
443 REGISTER TOOL *tool;
444
445 if ((type&(VCODE1|VCODE2)) != 0) type = VSTRING;
446 switch (type&VTYPE)
447 {
448 case VINTEGER:
449 case VSHORT:
450 case VBOOLEAN:
451 case VFRACT:
452 (void)esnprintf(line, 100, x_("%ld"), addr);
453 addstringtoinfstr(infstr, line);
454 break;
455 case VADDRESS:
456 (void)esnprintf(line, 100, x_("0%lo"), addr);
457 addstringtoinfstr(infstr, line);
458 break;
459 case VCHAR:
460 addtoinfstr(infstr, (CHAR)addr);
461 break;
462 case VSTRING:
463 addtoinfstr(infstr, '"');
464 io_addstring(infstr, (CHAR *)addr);
465 addtoinfstr(infstr, '"');
466 break;
467 case VFLOAT:
468 (void)esnprintf(line, 100, x_("%f"), castfloat(addr));
469 addstringtoinfstr(infstr, line);
470 break;
471 case VDOUBLE:
472 (void)esnprintf(line, 100, x_("%f"), castfloat(addr));
473 addstringtoinfstr(infstr, line);
474 break;
475 case VNODEINST:
476 ni = (NODEINST *)addr;
477 cindex = -1;
478 if (ni != NONODEINST)
479 {
480 if (ni->parent == curnodeproto) cindex = ni->temp1; else
481 io_nodeinsterror++;
482 }
483 (void)esnprintf(line, 100, x_("%ld"), cindex);
484 addstringtoinfstr(infstr, line);
485 break;
486 case VNODEPROTO:
487 np = (NODEPROTO *)addr;
488 if (np == NONODEPROTO)
489 {
490 addstringtoinfstr(infstr, x_("-1"));
491 break;
492 }
493 if (np->primindex == 0)
494 {
495 (void)esnprintf(line, 100, x_("%ld"), np->temp1);
496 addstringtoinfstr(infstr, line);
497 } else
498 {
499 io_addstring(infstr, np->tech->techname);
500 addtoinfstr(infstr, ':');
501 io_addstring(infstr, np->protoname);
502 }
503 break;
504 case VPORTARCINST:
505 io_portarcinsterror++;
506 pi = (PORTARCINST *)addr;
507 if (pi == NOPORTARCINST)
508 {
509 addstringtoinfstr(infstr, x_("NOPORTARCINST"));
510 break;
511 }
512 (void)esnprintf(line, 100, x_("portarc%ld"), (INTBIG)pi);
513 addstringtoinfstr(infstr, line);
514 break;
515 case VPORTEXPINST:
516 io_portexpinsterror++;
517 pe = (PORTEXPINST *)addr;
518 if (pe == NOPORTEXPINST)
519 {
520 addstringtoinfstr(infstr, x_("NOPORTEXPINST"));
521 break;
522 }
523 (void)esnprintf(line, 100, x_("portexp%ld"), (INTBIG)pe);
524 addstringtoinfstr(infstr, line);
525 break;
526 case VPORTPROTO:
527 pp = (PORTPROTO *)addr;
528 cindex = -1;
529 if (pp != NOPORTPROTO)
530 {
531 if (pp->parent == curnodeproto) cindex = pp->temp1; else
532 io_portprotoerror++;
533 }
534 (void)esnprintf(line, 100, x_("%ld"), cindex);
535 addstringtoinfstr(infstr, line);
536 break;
537 case VARCINST:
538 ai = (ARCINST *)addr;
539 cindex = -1;
540 if (ai != NOARCINST)
541 {
542 if (ai->parent == curnodeproto) cindex = ai->temp1; else
543 io_arcinsterror++;
544 }
545 (void)esnprintf(line, 100, x_("%ld"), cindex);
546 addstringtoinfstr(infstr, line);
547 break;
548 case VARCPROTO:
549 ap = (ARCPROTO *)addr;
550 if (ap == NOARCPROTO)
551 {
552 addstringtoinfstr(infstr, x_("NOARCPROTO"));
553 break;
554 }
555 io_addstring(infstr, ap->tech->techname);
556 addtoinfstr(infstr, ':');
557 io_addstring(infstr, ap->protoname);
558 break;
559 case VGEOM:
560 io_geomerror++;
561 geom = (GEOM *)addr;
562 if (geom == NOGEOM)
563 {
564 addstringtoinfstr(infstr, x_("NOGEOM"));
565 break;
566 }
567 (void)esnprintf(line, 100, x_("geom%ld"), (INTBIG)geom);
568 addstringtoinfstr(infstr, line);
569 break;
570 case VLIBRARY:
571 io_libraryerror++;
572 lib = (LIBRARY *)addr;
573 if (lib == NOLIBRARY)
574 {
575 addstringtoinfstr(infstr, x_("NOLIBRARY"));
576 break;
577 }
578 addtoinfstr(infstr, '"');
579 io_addstring(infstr, lib->libname);
580 addtoinfstr(infstr, '"');
581 break;
582 case VTECHNOLOGY:
583 tech = (TECHNOLOGY *)addr;
584 if (tech == NOTECHNOLOGY)
585 {
586 addstringtoinfstr(infstr, x_("NOTECHNOLOGY"));
587 break;
588 }
589 io_addstring(infstr, tech->techname);
590 break;
591 case VTOOL:
592 tool = (TOOL *)addr;
593 if (tool == NOTOOL)
594 {
595 addstringtoinfstr(infstr, x_("NOTOOL"));
596 break;
597 }
598 io_addstring(infstr, tool->toolname);
599 break;
600 case VRTNODE:
601 io_rtnodeerror++;
602 rtn = (RTNODE *)addr;
603 if (rtn == NORTNODE)
604 {
605 addstringtoinfstr(infstr, x_("NORTNODE"));
606 break;
607 }
608 (void)esnprintf(line, 100, x_("rtn%ld"), (INTBIG)rtn);
609 addstringtoinfstr(infstr, line);
610 break;
611 case VNETWORK:
612 case VVIEW:
613 case VWINDOWPART:
614 case VGRAPHICS:
615 case VCONSTRAINT:
616 case VGENERAL:
617 case VWINDOWFRAME:
618 case VPOLYGON:
619 break;
620 }
621 }
622
623 /*
624 * routine to add the string "str" to the infinite string and to quote the
625 * special characters '[', ']', '"', and '^'.
626 */
io_addstring(void * infstr,CHAR * str)627 void io_addstring(void *infstr, CHAR *str)
628 {
629
630 while (*str != 0)
631 {
632 if (*str == '[' || *str == ']' || *str == '"' || *str == '^')
633 addtoinfstr(infstr, '^');
634 addtoinfstr(infstr, *str++);
635 }
636 }
637
638 /*
639 * routine to print the variable name in "name" on file "file". The
640 * conversion performed is to quote with a backslash any of the characters
641 * '(', '[', or '^'.
642 */
io_printname(CHAR * name,FILE * file)643 void io_printname(CHAR *name, FILE *file)
644 {
645 REGISTER CHAR *pt;
646
647 for(pt = name; *pt != 0; pt++)
648 {
649 if (*pt == '^' || *pt == '[' || *pt == '(') xputc('^', file);
650 xputc(*pt, file);
651 }
652 }
653