2
* Electric(tm) VLSI Design System
5
* Input/output tool: controller module
6
* Written by: Steven M. Rubin, Static Free Software
8
* Copyright (c) 2000 Static Free Software.
10
* Electric(tm) is free software; you can redistribute it and/or modify
11
* it under the terms of the GNU General Public License as published by
12
* the Free Software Foundation; either version 2 of the License, or
13
* (at your option) any later version.
15
* Electric(tm) is distributed in the hope that it will be useful,
16
* but WITHOUT ANY WARRANTY; without even the implied warranty of
17
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18
* GNU General Public License for more details.
20
* You should have received a copy of the GNU General Public License
21
* along with Electric(tm); see the file COPYING. If not, write to
22
* the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
23
* Boston, Mass 02111-1307, USA.
25
* Static Free Software
27
* Portola Valley, California 94028
28
* info@staticfreesoft.com
34
#include "egraphics.h"
35
#include "efunction.h"
36
#include "dbcontour.h"
46
#include "tecmocmos.h"
49
/* the command parsing table */
51
static KEYWORD iocifoopt[] =
53
{"fully-instantiated", 0,{NOKEY,NOKEY,NOKEY,NOKEY,NOKEY}},
54
{"exactly-as-displayed", 0,{NOKEY,NOKEY,NOKEY,NOKEY,NOKEY}},
55
{"individual-boxes", 0,{NOKEY,NOKEY,NOKEY,NOKEY,NOKEY}},
56
{"merge-boxes", 0,{NOKEY,NOKEY,NOKEY,NOKEY,NOKEY}},
57
{"include-cloak-layer", 0,{NOKEY,NOKEY,NOKEY,NOKEY,NOKEY}},
58
{"ignore-cloak-layer", 0,{NOKEY,NOKEY,NOKEY,NOKEY,NOKEY}},
59
{"normalized", 0,{NOKEY,NOKEY,NOKEY,NOKEY,NOKEY}},
60
{"not-normalized", 0,{NOKEY,NOKEY,NOKEY,NOKEY,NOKEY}},
61
{"exactly-as-displayed", 0,{NOKEY,NOKEY,NOKEY,NOKEY,NOKEY}},
62
{"instantiate-top", 0,{NOKEY,NOKEY,NOKEY,NOKEY,NOKEY}},
63
{"dont-instantiate-top", 0,{NOKEY,NOKEY,NOKEY,NOKEY,NOKEY}},
64
{"highlight-resolution", 0,{NOKEY,NOKEY,NOKEY,NOKEY,NOKEY}},
65
{"hide-resolution", 0,{NOKEY,NOKEY,NOKEY,NOKEY,NOKEY}},
68
COMCOMP io_cifop = {iocifoopt,NOTOPLIST,NONEXTLIST,NOPARAMS,NOBACKUP,
69
INPUTOPT, " \t", M_("style of CIF output"), 0};
70
static KEYWORD iocifiopt[] =
72
{"rounded-wires", 0,{NOKEY,NOKEY,NOKEY,NOKEY,NOKEY}},
73
{"squared-wires", 0,{NOKEY,NOKEY,NOKEY,NOKEY,NOKEY}},
76
static COMCOMP iocifip = {iocifiopt,NOTOPLIST,NONEXTLIST,NOPARAMS,NOBACKUP,
77
INPUTOPT, " \t", M_("style of CIF input"), 0};
78
static KEYWORD iocifopt[] =
80
{"input", 1,{&iocifip,NOKEY,NOKEY,NOKEY,NOKEY}},
81
{"output", 1,{&io_cifop,NOKEY,NOKEY,NOKEY,NOKEY}},
84
COMCOMP io_cifp = {iocifopt,NOTOPLIST,NONEXTLIST,NOPARAMS,NOBACKUP,
85
INPUTOPT, " \t", M_("control of CIF"), 0};
89
static KEYWORD iodxfaopt[] =
91
{"all", 0,{NOKEY,NOKEY,NOKEY,NOKEY,NOKEY}},
92
{"restrict", 0,{NOKEY,NOKEY,NOKEY,NOKEY,NOKEY}},
95
static COMCOMP iodxfap = {iodxfaopt,NOTOPLIST,NONEXTLIST,NOPARAMS,NOBACKUP,
96
INPUTOPT, " \t", M_("DXF layer restriction options"), 0};
97
static KEYWORD iodxfopt[] =
99
{"acceptable-layers", 1,{&iodxfap,NOKEY,NOKEY,NOKEY,NOKEY}},
100
{"flatten-input", 0,{NOKEY,NOKEY,NOKEY,NOKEY,NOKEY}},
101
{"not-flatten-input", 0,{NOKEY,NOKEY,NOKEY,NOKEY,NOKEY}},
104
COMCOMP io_dxfp = {iodxfopt,NOTOPLIST,NONEXTLIST,NOPARAMS,NOBACKUP,
105
INPUTOPT, " \t", M_("DXF options"), 0};
109
static COMCOMP iogdsoarp = {NOKEYWORD,NOTOPLIST,NONEXTLIST,NOPARAMS,NOBACKUP,
110
INPUTOPT, " \t", M_("maximum number of degrees per arc segment"), 0};
111
static COMCOMP iogdsoasp = {NOKEYWORD,NOTOPLIST,NONEXTLIST,NOPARAMS,NOBACKUP,
112
INPUTOPT, " \t", M_("maximum sag distance for an arc segment"), 0};
113
static KEYWORD iogdsoopt[] =
115
{"individual-boxes", 0,{NOKEY,NOKEY,NOKEY,NOKEY,NOKEY}},
116
{"merge-boxes", 0,{NOKEY,NOKEY,NOKEY,NOKEY,NOKEY}},
117
{"include-cloak-layer", 0,{NOKEY,NOKEY,NOKEY,NOKEY,NOKEY}},
118
{"ignore-cloak-layer", 0,{NOKEY,NOKEY,NOKEY,NOKEY,NOKEY}},
119
{"arc-resolution", 1,{&iogdsoarp,NOKEY,NOKEY,NOKEY,NOKEY}},
120
{"arc-sag", 1,{&iogdsoasp,NOKEY,NOKEY,NOKEY,NOKEY}},
123
static COMCOMP iogdsop = {iogdsoopt,NOTOPLIST,NONEXTLIST,NOPARAMS,NOBACKUP,
124
INPUTOPT, " \t", M_("style of GDS output"), 0};
125
static KEYWORD iogdsiopt[] =
127
{"text", 0,{NOKEY,NOKEY,NOKEY,NOKEY,NOKEY}},
128
{"expand", 0,{NOKEY,NOKEY,NOKEY,NOKEY,NOKEY}},
129
{"arrays", 0,{NOKEY,NOKEY,NOKEY,NOKEY,NOKEY}},
130
{"unknown-layers", 0,{NOKEY,NOKEY,NOKEY,NOKEY,NOKEY}},
131
{"no-text", 0,{NOKEY,NOKEY,NOKEY,NOKEY,NOKEY}},
132
{"no-expand", 0,{NOKEY,NOKEY,NOKEY,NOKEY,NOKEY}},
133
{"no-arrays", 0,{NOKEY,NOKEY,NOKEY,NOKEY,NOKEY}},
134
{"no-unknown-layers", 0,{NOKEY,NOKEY,NOKEY,NOKEY,NOKEY}},
137
static COMCOMP iogdsiop = {iogdsiopt,NOTOPLIST,NONEXTLIST,NOPARAMS,NOBACKUP,
138
INPUTOPT, " \t", M_("style of GDS input"), 0};
139
static KEYWORD iogdsopt[] =
141
{"output", 1,{&iogdsop,NOKEY,NOKEY,NOKEY,NOKEY}},
142
{"input", 1,{&iogdsiop,NOKEY,NOKEY,NOKEY,NOKEY}},
145
COMCOMP io_gdsp = {iogdsopt,NOTOPLIST,NONEXTLIST,NOPARAMS,NOBACKUP,
146
INPUTOPT, " \t", M_("control of GDS"), 0};
150
static KEYWORD ioedifopt[] =
152
{"schematic", 0,{NOKEY,NOKEY,NOKEY,NOKEY,NOKEY}},
153
{"netlist", 0,{NOKEY,NOKEY,NOKEY,NOKEY,NOKEY}},
156
COMCOMP io_edifp = {ioedifopt,NOTOPLIST,NONEXTLIST,NOPARAMS,NOBACKUP,
157
INPUTOPT, " \t", M_("EDIF output option"), 0};
160
static KEYWORD ioplotnopt[] =
162
{"focus", 0,{NOKEY,NOKEY,NOKEY,NOKEY,NOKEY}},
163
{"include-date",0,{NOKEY,NOKEY,NOKEY,NOKEY,NOKEY}},
166
static COMCOMP ioplotnp = {ioplotnopt,NOTOPLIST,NONEXTLIST,NOPARAMS,NOBACKUP,
167
INPUTOPT, " \t", M_("negating control of plot output"), 0};
168
static KEYWORD ioplotopt[] =
170
{"not", 1,{&ioplotnp,NOKEY,NOKEY,NOKEY,NOKEY}},
171
{"focus-highlighted", 0,{NOKEY,NOKEY,NOKEY,NOKEY,NOKEY}},
172
{"focus-window", 0,{NOKEY,NOKEY,NOKEY,NOKEY,NOKEY}},
173
{"include-date", 0,{NOKEY,NOKEY,NOKEY,NOKEY,NOKEY}},
176
static COMCOMP ioplotp = {ioplotopt,NOTOPLIST,NONEXTLIST,NOPARAMS,NOBACKUP,
177
INPUTOPT, " \t", M_("control of plot output"), 0};
179
static KEYWORD ioveropt[] =
181
{"off", 0,{NOKEY,NOKEY,NOKEY,NOKEY,NOKEY}},
182
{"on", 0,{NOKEY,NOKEY,NOKEY,NOKEY,NOKEY}},
183
{"graphical", 0,{NOKEY,NOKEY,NOKEY,NOKEY,NOKEY}},
186
static COMCOMP ioverp = {ioveropt,NOTOPLIST,NONEXTLIST,NOPARAMS,NOBACKUP,
187
INPUTOPT, " \t", M_("verbose option"), 0};
189
static COMCOMP iopostsynch = {NOKEYWORD, topoffile, nextfile, NOPARAMS, NOBACKUP,
190
NOFILL|INPUTOPT, " \t", M_("PostScript synchronization file name"), 0};
191
static COMCOMP iopostplotwid = {NOKEYWORD,NOTOPLIST,NONEXTLIST,NOPARAMS,NOBACKUP,
192
INPUTOPT, " \t", M_("PostScript plotter width"), 0};
193
static COMCOMP iopostprintwid = {NOKEYWORD,NOTOPLIST,NONEXTLIST,NOPARAMS,NOBACKUP,
194
INPUTOPT, " \t", M_("PostScript printer width"), 0};
195
static COMCOMP iopostprinthei = {NOKEYWORD,NOTOPLIST,NONEXTLIST,NOPARAMS,NOBACKUP,
196
INPUTOPT, " \t", M_("PostScript printer height"), 0};
197
static COMCOMP iopostmargin = {NOKEYWORD,NOTOPLIST,NONEXTLIST,NOPARAMS,NOBACKUP,
198
INPUTOPT, " \t", M_("PostScript margin"), 0};
199
static KEYWORD iopostopt[] =
201
{"plain", 0,{NOKEY,NOKEY,NOKEY,NOKEY,NOKEY}},
202
{"encapsulated", 0,{NOKEY,NOKEY,NOKEY,NOKEY,NOKEY}},
203
{"rotate", 0,{NOKEY,NOKEY,NOKEY,NOKEY,NOKEY}},
204
{"no-rotate", 0,{NOKEY,NOKEY,NOKEY,NOKEY,NOKEY}},
205
{"color", 0,{NOKEY,NOKEY,NOKEY,NOKEY,NOKEY}},
206
{"stippled-color", 0,{NOKEY,NOKEY,NOKEY,NOKEY,NOKEY}},
207
{"gray-scale", 0,{NOKEY,NOKEY,NOKEY,NOKEY,NOKEY}},
208
{"printer", 2,{&iopostprintwid,&iopostprinthei,NOKEY,NOKEY,NOKEY}},
209
{"plotter", 1,{&iopostplotwid,NOKEY,NOKEY,NOKEY,NOKEY}},
210
{"margin", 1,{&iopostmargin,NOKEY,NOKEY,NOKEY,NOKEY}},
211
{"flat", 0,{NOKEY,NOKEY,NOKEY,NOKEY,NOKEY}},
212
{"hierarchical", 0,{NOKEY,NOKEY,NOKEY,NOKEY,NOKEY}},
213
{"unsynchronize", 0,{NOKEY,NOKEY,NOKEY,NOKEY,NOKEY}},
214
{"synchronize", 1,{&iopostsynch,NOKEY,NOKEY,NOKEY,NOKEY}},
217
static COMCOMP iopostp = {iopostopt,NOTOPLIST,NONEXTLIST,NOPARAMS,NOBACKUP,
218
INPUTOPT, " \t", M_("control of PostScript format"), 0};
220
static COMCOMP iohpgl2sp = {NOKEYWORD,NOTOPLIST,NONEXTLIST,NOPARAMS,NOBACKUP,
221
INPUTOPT, " \t", M_("internal units per pixel"), 0};
222
static KEYWORD iohpgl2opt[] =
224
{"scale", 1,{&iohpgl2sp,NOKEY,NOKEY,NOKEY,NOKEY}},
227
static COMCOMP iohpgl2p = {iohpgl2opt,NOTOPLIST,NONEXTLIST,NOPARAMS,NOBACKUP,
228
INPUTOPT, " \t", M_("HPGL/2 scaling option"), 0};
229
static KEYWORD iohpglopt[] =
231
{"1", 0,{NOKEY,NOKEY,NOKEY,NOKEY,NOKEY}},
232
{"2", 1,{&iohpgl2p,NOKEY,NOKEY,NOKEY,NOKEY}},
235
static COMCOMP iohpglp = {iohpglopt,NOTOPLIST,NONEXTLIST,NOPARAMS,NOBACKUP,
236
INPUTOPT, " \t", M_("HPGL version"), 0};
238
static COMCOMP iobloatlp = {NOKEYWORD,NOTOPLIST,NONEXTLIST,NOPARAMS,NOBACKUP,
239
INPUTOPT, " \t", M_("Layer name to bloat"), 0};
240
static COMCOMP iobloatap = {NOKEYWORD,NOTOPLIST,NONEXTLIST,NOPARAMS,NOBACKUP,
241
0, " \t", M_("amount to bloat layer (in internal units)"), 0};
243
static KEYWORD iobinopt[] =
245
{"no-backup", 0,{NOKEY,NOKEY,NOKEY,NOKEY,NOKEY}},
246
{"one-level-backup", 0,{NOKEY,NOKEY,NOKEY,NOKEY,NOKEY}},
247
{"many-level-backup", 0,{NOKEY,NOKEY,NOKEY,NOKEY,NOKEY}},
248
{"no-check", 0,{NOKEY,NOKEY,NOKEY,NOKEY,NOKEY}},
249
{"check", 0,{NOKEY,NOKEY,NOKEY,NOKEY,NOKEY}},
252
static COMCOMP iobinp = {iobinopt,NOTOPLIST,NONEXTLIST,NOPARAMS,NOBACKUP,
253
INPUTOPT, " \t", M_("Binary options"), 0};
255
static KEYWORD ioopt[] =
258
{"cif", 1,{&io_cifp,NOKEY,NOKEY,NOKEY,NOKEY}},
261
{"dxf", 1,{&io_dxfp,NOKEY,NOKEY,NOKEY,NOKEY}},
264
{"gds", 1,{&io_gdsp,NOKEY,NOKEY,NOKEY,NOKEY}},
267
{"edif", 1,{&io_edifp,NOKEY,NOKEY,NOKEY,NOKEY}},
269
{"binary", 1,{&iobinp,NOKEY,NOKEY,NOKEY,NOKEY}},
270
{"plot", 1,{&ioplotp,NOKEY,NOKEY,NOKEY,NOKEY}},
271
{"verbose", 1,{&ioverp,NOKEY,NOKEY,NOKEY,NOKEY}},
272
{"postscript", 1,{&iopostp,NOKEY,NOKEY,NOKEY,NOKEY}},
273
{"hpgl", 1,{&iohpglp,NOKEY,NOKEY,NOKEY,NOKEY}},
274
{"bloat-output", 2,{&iobloatlp,&iobloatap,NOKEY,NOKEY,NOKEY}},
277
COMCOMP io_iop = {ioopt, NOTOPLIST, NONEXTLIST, NOPARAMS, NOBACKUP,
278
0, " \t", M_("Input/Output action"), 0};
283
INTBIG required, bits;
286
{"binary", 1, FBINARY},
287
{"nobackupbinary", 1, FBINARYNOBACKUP},
298
{"eagle", 2, FEAGLE},
319
{"postscript", 2, FPOSTSCRIPT},
320
{"printed-postscript", 2, FPRINTEDPOSTSCRIPT},
322
{"quickdraw", 1, FQUICKDRAW},
328
{"skill", 2, FSKILL},
340
#define NOBLOAT ((BLOAT *)-1)
342
typedef struct Ibloat
346
struct Ibloat *nextbloat;
349
static BLOAT *io_curbloat = NOBLOAT;
351
/* working memory for "io_setuptechorder()" */
352
static INTBIG io_maxlayers;
353
static INTBIG io_mostlayers = 0;
354
static INTBIG *io_overlaporder;
357
FILE *io_fileout; /* channel for output */
358
jmp_buf io_filerror; /* nonlocal jump when I/O fails */
359
INTBIG io_cifbase; /* index used when writing CIF */
360
INTBIG io_postscriptfilenamekey; /* key for "IO_postscript_filename" */
361
INTBIG io_postscriptfiledatekey; /* key for "IO_postscript_filedate" */
362
INTBIG io_postscriptepsscalekey; /* key for "IO_postscript_EPS_scale" */
363
INTBIG io_verbose; /* 0: silent 1:chattier -1:graphical */
364
TOOL *io_tool; /* the I/O tool object */
365
INTBIG io_filetypeblib; /* Binary library disk file descriptor */
366
INTBIG io_filetypecif; /* CIF disk file descriptor */
367
INTBIG io_filetypedef; /* DEF disk file descriptor */
368
INTBIG io_filetypedxf; /* DXF disk file descriptor */
369
INTBIG io_filetypeeagle; /* EAGLE disk netlist file descriptor */
370
INTBIG io_filetypeecad; /* ECAD disk netlist file descriptor */
371
INTBIG io_filetypeedif; /* EDIF disk file descriptor */
372
INTBIG io_filetypegds; /* GDS disk file descriptor */
373
INTBIG io_filetypehpgl; /* HPGL disk file descriptor */
374
INTBIG io_filetypel; /* L disk file descriptor */
375
INTBIG io_filetypelef; /* LEF disk file descriptor */
376
INTBIG io_filetypepads; /* PADS netlist disk file descriptor */
377
INTBIG io_filetypeps; /* PostScript disk file descriptor */
378
INTBIG io_filetypesdf; /* SDF disk file descriptor */
379
INTBIG io_filetypeskill; /* SKILL commands disk file descriptor */
380
INTBIG io_filetypesue; /* SUE disk file descriptor */
381
INTBIG io_filetypetlib; /* Text library disk file descriptor */
382
INTBIG io_filetypevhdl; /* VHDL disk file descriptor */
383
INTBIG io_libinputrecursivedepth; /* for recursing when reading dependent libraries */
384
INTBIG io_libinputreadmany; /* nonzero if reading dependent libraries */
385
static INTBIG io_state_key; /* key for "IO_state" */
387
/* shared prototypes */
388
void io_compute_center(INTBIG xc, INTBIG yc, INTBIG x1, INTBIG y1,
389
INTBIG x2, INTBIG y2, INTBIG *cx, INTBIG *cy);
391
/* prototypes for local routines */
392
static double io_calc_angle(double r, double dx, double dy);
393
static void io_fixrtree(RTNODE*);
394
static void io_fixtechlayers(void);
395
static void io_unifylambdavalues(LIBRARY *lib);
396
static void io_libraryoptiondlog(void);
397
static void io_cdloptionsdialog(void);
398
static void io_getversion(LIBRARY *lib, INTBIG *major, INTBIG *minor, INTBIG *detail);
399
static void io_convertallrelativetext(INTSML numvar, VARIABLE *firstvar);
400
static void io_convertrelativetext(UINTBIG *descript);
401
static void io_fixupnodeinst(NODEINST *ni, INTBIG dlx, INTBIG dly, INTBIG dhx, INTBIG dhy);
402
static void io_convertalltextdescriptors(INTSML numvar, VARIABLE *firstvar);
403
static void io_converttextdescriptor(UINTBIG *descript);
404
static void io_setoutputbloat(char *layer, INTBIG amount);
406
INTBIG *io_getstatebits(void)
408
REGISTER VARIABLE *var;
409
REGISTER INTBIG i, len;
410
static INTBIG mybits[NUMIOSTATEBITWORDS];
412
var = getvalkey((INTBIG)io_tool, VTOOL, -1, io_state_key);
413
if (var == NOVARIABLE)
415
for(i=1; i<NUMIOSTATEBITWORDS; i++) mybits[i] = 0;
416
mybits[0] = DXFFLATTENINPUT|GDSINARRAYS;
419
if ((var->type&VISARRAY) != 0)
421
for(i=0; i<NUMIOSTATEBITWORDS; i++) mybits[i] = 0;
422
len = getlength(var);
423
for(i=0; i<len; i++) mybits[i] = ((INTBIG *)var->addr)[i];
426
for(i=1; i<NUMIOSTATEBITWORDS; i++) mybits[i] = 0;
427
mybits[0] = var->addr;
431
void io_setstatebits(INTBIG *bits)
433
(void)setvalkey((INTBIG)io_tool, VTOOL, io_state_key, (INTBIG)bits,
434
VINTEGER|VISARRAY|(NUMIOSTATEBITWORDS<<VLENGTHSH));
437
void io_init(INTBIG *argc, char *argv[], TOOL *thistool)
439
INTBIG statebits[NUMIOSTATEBITWORDS], i;
441
/* nothing for pass 2 or 3 initialization */
442
if (thistool == NOTOOL || thistool == 0) return;
444
/* pass 1 initialization */
446
io_state_key = makekey("IO_state");
447
io_postscriptfilenamekey = makekey("IO_postscript_filename");
448
io_postscriptfiledatekey = makekey("IO_postscript_filedate");
449
io_postscriptepsscalekey = makekey("IO_postscript_EPS_scale");
451
for(i=1; i<NUMIOSTATEBITWORDS; i++) statebits[i] = 0;
452
statebits[0] = DXFFLATTENINPUT|GDSINARRAYS;
453
io_setstatebits(statebits);
456
DiaDeclareHook("libopt", &ioverp, io_libraryoptiondlog);
457
DiaDeclareHook("cdlopt", &iobloatlp, io_cdloptionsdialog);
459
/* create disk file descriptors */
460
io_filetypeblib = setupfiletype("elib", "*.elib", MACFSTAG('Elec'), TRUE, "blib", _("Binary library"));
461
io_filetypecif = setupfiletype("cif", "*.cif", MACFSTAG('TEXT'), FALSE, "cif", _("CIF"));
462
io_filetypedef = setupfiletype("def", "*.def", MACFSTAG('TEXT'), FALSE, "def", _("DEF"));
463
io_filetypedxf = setupfiletype("dxf", "*.dxf", MACFSTAG('TEXT'), FALSE, "dxf", _("AutoCAD DXF"));
464
io_filetypeeagle = setupfiletype("txt", "*.txt", MACFSTAG('TEXT'), FALSE, "eagle", _("Eagle netlist"));
465
io_filetypeecad = setupfiletype("enl", "*.enl", MACFSTAG('TEXT'), FALSE, "ecad", _("ECAD netlist"));
466
io_filetypeedif = setupfiletype("edif", "*.edif;*.ed?", MACFSTAG('TEXT'), FALSE, "edif", _("EDIF"));
467
io_filetypegds = setupfiletype("gds", "*.gds", MACFSTAG('GDS '), TRUE, "gds", _("GDS II"));
468
io_filetypehpgl = setupfiletype("hpgl", "*.hpgl", MACFSTAG('TEXT'), FALSE, "hpgl", _("HPGL"));
469
io_filetypel = setupfiletype("l", "*.l", MACFSTAG('TEXT'), FALSE, "l", _("L"));
470
io_filetypelef = setupfiletype("lef", "*.lef", MACFSTAG('TEXT'), FALSE, "lef", _("LEF"));
471
io_filetypepads = setupfiletype("asc", "*.asc", MACFSTAG('TEXT'), FALSE, "pad", _("PADS netlist"));
472
io_filetypeps = setupfiletype("ps", "*.ps;*.eps", MACFSTAG('TEXT'), FALSE, "ps", _("PostScript"));
473
io_filetypesdf = setupfiletype("sdf", "*.sdf", MACFSTAG('TEXT'), FALSE, "sdf", _("SDF"));
474
io_filetypeskill = setupfiletype("il", "*.il", MACFSTAG('TEXT'), FALSE, "skill", _("SKILL commands"));
475
io_filetypesue = setupfiletype("sue", "*.sue", MACFSTAG('TEXT'), FALSE, "sue", _("SUE"));
476
io_filetypetlib = setupfiletype("txt", "*.txt", MACFSTAG('TEXT'), FALSE, "tlib", _("Text library"));
477
io_filetypevhdl = setupfiletype("vhdl", "*.vhdl;*.vhd", MACFSTAG('TEXT'), FALSE, "vhdl", _("VHDL"));
502
if (io_mostlayers > 0) efree((char *)io_overlaporder);
503
io_freebininmemory();
504
io_freebinoutmemory();
505
io_freepostscriptmemory();
506
io_freetextinmemory();
508
io_freecifinmemory();
509
io_freecifparsmemory();
510
io_freecifoutmemory();
519
io_freeedifinmemory();
522
io_freegdsoutmemory();
538
ttyputmsg(M_("Input and Output are performed with the 'library' command"));
539
ttyputmsg(M_("...I/O tool turned off"));
540
toolturnoff(io_tool, FALSE);
543
void io_set(INTBIG count, char *par[])
546
REGISTER INTBIG *curstate, scale, wid, hei;
547
REGISTER NODEPROTO *np;
549
REGISTER VARIABLE *var;
550
INTBIG arcres, arcsag;
554
count = ttygetparam(M_("IO option:"), &io_iop, MAXPARS, par);
557
ttyputerr(M_("Aborted"));
561
l = strlen(pp = par[0]);
563
/* get current state of I/O tool */
564
curstate = io_getstatebits();
566
/* check for bloating specifications */
567
if (namesamen(pp, "bloat-output", l) == 0)
571
io_setoutputbloat("", 0);
576
ttyputusage("telltool io bloat-output LAYER AMOUNT");
579
io_setoutputbloat(par[1], myatoi(par[2]));
583
/* check for format specifications */
584
if (namesamen(pp, "plot", l) == 0)
588
if ((curstate[0]&PLOTFOCUS) != 0)
590
if ((curstate[0]&PLOTFOCUSDPY) != 0)
591
ttyputmsg(M_("Plot output will focus on displayed window")); else
592
ttyputmsg(M_("Plot output will focus on highlighted area"));
593
} else ttyputmsg(M_("Plot output will display entire facet"));
594
if ((curstate[0]&PLOTDATES) != 0)
595
ttyputmsg(M_("Plot output will include dates")); else
596
ttyputmsg(M_("Plot output will not include dates"));
600
l = strlen(pp = par[1]);
601
if (namesamen(pp, "not", l) == 0)
605
ttyputusage("telltool io plot not OPTION");
608
l = strlen(pp = par[2]);
609
if (namesamen(pp, "focus", l) == 0)
611
curstate[0] &= ~(PLOTFOCUS|PLOTFOCUSDPY);
612
io_setstatebits(curstate);
613
ttyputverbose(M_("Plot output will display entire facet"));
616
if (namesamen(pp, "include-date", l) == 0)
618
curstate[0] &= ~PLOTDATES;
619
io_setstatebits(curstate);
620
ttyputverbose(M_("Plot output will not include dates"));
623
ttyputbadusage("telltool io plot not");
626
if (namesamen(pp, "focus-highlighted", l) == 0 && l >= 7)
628
curstate[0] = (curstate[0] & ~PLOTFOCUSDPY) | PLOTFOCUS;
629
io_setstatebits(curstate);
630
ttyputverbose(M_("Plot output will focus on highlighted area"));
633
if (namesamen(pp, "focus-window", l) == 0 && l >= 7)
635
curstate[0] |= (PLOTFOCUSDPY|PLOTFOCUS);
636
io_setstatebits(curstate);
637
ttyputverbose(M_("Plot output will focus on highlighted area"));
640
if (namesamen(pp, "include-date", l) == 0)
642
curstate[0] |= PLOTDATES;
643
io_setstatebits(curstate);
644
ttyputverbose(M_("Plot output will include dates"));
647
ttyputusage("telltool io plot [not] (focus | include-dates)");
651
/* check for binary specifications */
652
if (namesamen(pp, "binary", l) == 0)
654
l = strlen(pp = par[1]);
655
if (namesamen(pp, "no-backup", l) == 0 && l >= 4)
657
curstate[0] = (curstate[0] & ~BINOUTBACKUP) | BINOUTNOBACK;
658
io_setstatebits(curstate);
659
ttyputverbose(M_("Binary output will not keep backups"));
662
if (namesamen(pp, "one-level-backup", l) == 0)
664
curstate[0] = (curstate[0] & ~BINOUTBACKUP) | BINOUTONEBACK;
665
io_setstatebits(curstate);
666
ttyputverbose(M_("Binary output will keep one backup"));
669
if (namesamen(pp, "many-level-backup", l) == 0)
671
curstate[0] = (curstate[0] & ~BINOUTBACKUP) | BINOUTFULLBACK;
672
io_setstatebits(curstate);
673
ttyputverbose(M_("Binary output will keep full backups"));
677
if (namesamen(pp, "no-check", l) == 0 && l >= 4)
679
curstate[0] &= ~CHECKATWRITE;
680
io_setstatebits(curstate);
681
ttyputverbose(M_("Binary output will not check the database"));
684
if (namesamen(pp, "check", l) == 0)
686
curstate[0] |= CHECKATWRITE;
687
io_setstatebits(curstate);
688
ttyputverbose(M_("Binary output will check the database"));
691
ttyputusage("telltool io binary (no-backup | one-level-backup | many-level-backup | no-check | check)");
696
if (namesamen(pp, "cif", l) == 0)
700
ttyputbadusage("telltool io cif (input|output)");
703
l = strlen(pp = par[1]);
704
if (namesamen(pp, "input", l) == 0)
708
ttyputbadusage("telltool io cif input OPTIONS");
711
l = strlen(pp = par[2]);
715
curstate[0] &= ~CIFINSQUARE;
716
io_setstatebits(curstate);
717
ttyputverbose(M_("CIF wires will have rounded ends"));
720
curstate[0] |= CIFINSQUARE;
721
io_setstatebits(curstate);
722
ttyputverbose(M_("CIF wires will have squared ends"));
725
ttyputbadusage("telltool io cif input");
729
if (namesamen(pp, "output", l) == 0)
733
ttyputbadusage("telltool io cif output OPTIONS");
737
l = strlen(pp = par[2]);
738
if (namesamen(pp, "fully-instantiated", l) == 0)
740
curstate[0] &= ~CIFOUTEXACT;
741
io_setstatebits(curstate);
742
ttyputverbose(M_("CIF generation will include all facets"));
745
if (namesamen(pp, "exactly-as-displayed", l) == 0)
747
curstate[0] |= CIFOUTEXACT;
748
io_setstatebits(curstate);
749
ttyputverbose(M_("CIF generation will duplicate screen"));
752
if (namesamen(pp, "merge-boxes", l) == 0)
754
curstate[0] |= CIFOUTMERGE;
755
io_setstatebits(curstate);
756
ttyputverbose(M_("CIF generation will merge boxes"));
759
if (namesamen(pp, "individual-boxes", l) == 0 && l >= 3)
761
curstate[0] &= ~CIFOUTMERGE;
762
io_setstatebits(curstate);
763
ttyputverbose(M_("CIF generation will list individual boxes"));
766
if (namesamen(pp, "include-cloak-layer", l) == 0 && l >= 3)
768
curstate[0] |= CIFOUTADDDRC;
769
io_setstatebits(curstate);
770
ttyputverbose(M_("CIF generation will include DRC cloak layer"));
773
if (namesamen(pp, "ignore-cloak-layer", l) == 0 && l >= 2)
775
curstate[0] &= ~CIFOUTADDDRC;
776
io_setstatebits(curstate);
777
ttyputverbose(M_("CIF generation will ignore DRC cloak layer"));
780
if (namesamen(pp, "normalized", l) == 0 && l >= 3)
782
curstate[0] |= CIFOUTNORMALIZE;
783
io_setstatebits(curstate);
784
ttyputverbose(M_("CIF generation will normalize coordinates"));
787
if (namesamen(pp, "not-normalized", l) == 0 && l >= 3)
789
curstate[0] &= ~CIFOUTNORMALIZE;
790
io_setstatebits(curstate);
791
ttyputverbose(M_("CIF generation will use facet coordinates"));
794
if (namesamen(pp, "instantiate-top", l) == 0 && l >= 3)
796
curstate[0] &= ~CIFOUTNOTOPCALL;
797
io_setstatebits(curstate);
798
ttyputverbose(M_("CIF generation will instantiate top-level cell"));
801
if (namesamen(pp, "dont-instantiate-top", l) == 0 && l >= 3)
803
curstate[0] |= CIFOUTNOTOPCALL;
804
io_setstatebits(curstate);
805
ttyputverbose(M_("CIF generation will not instantiate top-level cell"));
808
if (namesamen(pp, "highlight-resolution", l) == 0 && l >= 3)
810
curstate[1] |= CIFRESHIGH;
811
io_setstatebits(curstate);
812
ttyputverbose(M_("CIF generation will highlight resolution errors"));
815
if (namesamen(pp, "hide-resolution", l) == 0 && l >= 3)
817
curstate[1] &= ~CIFRESHIGH;
818
io_setstatebits(curstate);
819
ttyputverbose(M_("CIF generation will not highlight resolution errors"));
823
ttyputusage("telltool io cif input|output OPTION");
829
if (namesamen(pp, "gds", l) == 0)
833
if ((curstate[0]&GDSOUTMERGE) == 0)
834
ttyputmsg(M_("GDS generation will list individual boxes")); else
835
ttyputmsg(M_("GDS generation will merge boxes"));
836
if ((curstate[0]&GDSOUTADDDRC) == 0)
837
ttyputmsg(M_("GDS generation will ignore DRC cloak layer")); else
838
ttyputmsg(M_("GDS generation will include DRC cloak layer"));
839
if ((curstate[0]&GDSINTEXT) == 0)
840
ttyputmsg(M_("GDS input ignores text")); else
841
ttyputmsg(M_("GDS input includes text"));
842
if ((curstate[0]&GDSINEXPAND) == 0)
843
ttyputmsg(M_("GDS input does not expand instances")); else
844
ttyputmsg(M_("GDS input expands instances"));
845
if ((curstate[0]&GDSINARRAYS) == 0)
846
ttyputmsg(M_("GDS input does not instantiate arrays")); else
847
ttyputmsg(M_("GDS input instantiates arrays"));
850
l = strlen(pp = par[1]);
851
if (namesamen(pp, "input", l) == 0)
855
if ((curstate[0]&GDSINTEXT) == 0)
856
ttyputmsg(M_("GDS input ignores text")); else
857
ttyputmsg(M_("GDS input includes text"));
858
if ((curstate[0]&GDSINEXPAND) == 0)
859
ttyputmsg(M_("GDS input does not expand instances")); else
860
ttyputmsg(M_("GDS input expands instances"));
861
if ((curstate[0]&GDSINARRAYS) == 0)
862
ttyputmsg(M_("GDS input does not instantiate arrays")); else
863
ttyputmsg(M_("GDS input instantiates arrays"));
866
l = strlen(pp = par[2]);
867
if (namesamen(pp, "text", l) == 0)
869
curstate[0] |= GDSINTEXT;
870
io_setstatebits(curstate);
871
ttyputverbose(M_("GDS input includes text"));
874
if (namesamen(pp, "no-text", l) == 0 && l >= 4)
876
curstate[0] &= ~GDSINTEXT;
877
io_setstatebits(curstate);
878
ttyputverbose(M_("GDS input ignores text"));
881
if (namesamen(pp, "expand", l) == 0)
883
curstate[0] |= GDSINEXPAND;
884
io_setstatebits(curstate);
885
ttyputverbose(M_("GDS input expands instances"));
888
if (namesamen(pp, "no-expand", l) == 0 && l >= 4)
890
curstate[0] &= ~GDSINEXPAND;
891
io_setstatebits(curstate);
892
ttyputverbose(M_("GDS input does not expand instances"));
895
if (namesamen(pp, "arrays", l) == 0)
897
curstate[0] |= GDSINARRAYS;
898
io_setstatebits(curstate);
899
ttyputverbose(M_("GDS input instantiates arrays"));
902
if (namesamen(pp, "no-arrays", l) == 0 && l >= 4)
904
curstate[0] &= ~GDSINARRAYS;
905
io_setstatebits(curstate);
906
ttyputverbose(M_("GDS input does not instantiate arrays"));
909
if (namesamen(pp, "unknown-layers", l) == 0)
911
curstate[0] |= GDSINIGNOREUKN;
912
io_setstatebits(curstate);
913
ttyputverbose(M_("GDS input includes unknown layers"));
916
if (namesamen(pp, "no-unknown-layers", l) == 0 && l >= 4)
918
curstate[0] &= ~GDSINIGNOREUKN;
919
io_setstatebits(curstate);
920
ttyputverbose(M_("GDS input ignores unknown layers"));
923
ttyputbadusage("telltool io gds input");
926
if (namesamen(pp, "output", l) == 0)
930
if ((curstate[0]&GDSOUTMERGE) == 0)
931
ttyputmsg(M_("GDS generation will list individual boxes")); else
932
ttyputmsg(M_("GDS generation will merge boxes"));
933
if ((curstate[0]&GDSOUTADDDRC) == 0)
934
ttyputmsg(M_("GDS generation will ignore DRC cloak layer")); else
935
ttyputmsg(M_("GDS generation will include DRC cloak layer"));
938
l = strlen(pp = par[2]);
939
if (namesamen(pp, "merge-boxes", l) == 0)
941
curstate[0] |= GDSOUTMERGE;
942
io_setstatebits(curstate);
943
ttyputverbose(M_("GDS generation will merge boxes"));
946
if (namesamen(pp, "individual-boxes", l) == 0 && l >= 3)
948
curstate[0] &= ~GDSOUTMERGE;
949
io_setstatebits(curstate);
950
ttyputverbose(M_("GDS generation will list individual boxes"));
953
if (namesamen(pp, "include-cloak-layer", l) == 0 && l >= 3)
955
curstate[0] |= GDSOUTADDDRC;
956
io_setstatebits(curstate);
957
ttyputverbose(M_("GDS generation will include DRC cloak layer"));
960
if (namesamen(pp, "ignore-cloak-layer", l) == 0 && l >= 2)
962
curstate[0] &= ~GDSOUTADDDRC;
963
io_setstatebits(curstate);
964
ttyputverbose(M_("GDS generation will ignore DRC cloak layer"));
967
if (namesamen(pp, "arc-resolution", l) == 0 && l >= 5)
969
getcontoursegmentparameters(&arcres, &arcsag);
970
if (count > 3) arcres = atofr(par[3]) * 10 / WHOLE;
971
ttyputverbose(M_("GDS arc generation will create a line every %s degrees"),
972
frtoa(arcres*WHOLE/10));
973
setcontoursegmentparameters(arcres, arcsag);
976
if (namesamen(pp, "arc-sag", l) == 0 && l >= 5)
978
getcontoursegmentparameters(&arcres, &arcsag);
979
if (count > 3) arcsag = atola(par[3]);
980
ttyputverbose(M_("GDS arc generation will sag no more than %s"), latoa(arcsag));
981
setcontoursegmentparameters(arcres, arcsag);
984
ttyputbadusage("telltool io gds output");
987
ttyputbadusage("telltool io gds");
993
if (namesamen(pp, "dxf", l) == 0)
997
if ((curstate[0]&DXFALLLAYERS) == 0)
998
ttyputmsg(M_("DXF input will accept only layers listed by technology")); else
999
ttyputmsg(M_("DXF input will accept all layers"));
1002
l = strlen(pp = par[1]);
1003
if (namesamen(pp, "acceptable-layers", l) == 0)
1007
if ((curstate[0]&DXFALLLAYERS) == 0)
1008
ttyputmsg(M_("DXF input will accept only layers listed by technology")); else
1009
ttyputmsg(M_("DXF input will accept all layers"));
1012
l = strlen(pp = par[2]);
1013
if (namesamen(pp, "all", l) == 0)
1015
curstate[0] |= DXFALLLAYERS;
1016
io_setstatebits(curstate);
1017
ttyputverbose(M_("DXF input will accept all layers"));
1020
if (namesamen(pp, "restrict", l) == 0)
1022
curstate[0] &= ~DXFALLLAYERS;
1023
io_setstatebits(curstate);
1024
ttyputverbose(M_("DXF input will accept only layers listed by technology"));
1028
if (namesamen(pp, "flatten-input", l) == 0)
1030
curstate[0] |= DXFFLATTENINPUT;
1031
io_setstatebits(curstate);
1032
ttyputverbose(M_("DXF input will flatten input blocks"));
1035
if (namesamen(pp, "not-flatten-input", l) == 0)
1037
curstate[0] &= ~DXFFLATTENINPUT;
1038
io_setstatebits(curstate);
1039
ttyputverbose(M_("DXF input will retain input hierarchy"));
1042
ttyputbadusage("telltool io dxf");
1047
if (namesamen(pp, "postscript", l) == 0)
1051
if ((curstate[0]&EPSPSCRIPT) == 0)
1052
ttyputmsg(M_("PostScript output is in plain format")); else
1053
ttyputmsg(M_("PostScript output is in encapsulated format"));
1054
if ((curstate[0]&PSCOLOR) == 0)
1055
ttyputmsg(M_("PostScript output is gray-scale")); else
1056
ttyputmsg(M_("PostScript output is in color"));
1057
if ((curstate[0]&PSROTATE) == 0)
1058
ttyputmsg(M_("PostScript output is unrotated")); else
1059
ttyputmsg(M_("PostScript output is rotated 90 degrees"));
1060
if ((curstate[0]&PSPLOTTER) == 0)
1061
ttyputmsg(M_("PostScript output is printed")); else
1062
ttyputmsg(M_("PostScript output is plotted"));
1063
if ((curstate[0]&PSHIERARCHICAL) == 0)
1064
ttyputmsg(M_("PostScript output is flat")); else
1065
ttyputmsg(M_("PostScript output is hierarchical"));
1066
np = el_curlib->curnodeproto;
1067
if (np != NONODEPROTO)
1069
var = getvalkey((INTBIG)np, VNODEPROTO, VSTRING, io_postscriptfilenamekey);
1070
if (var != NOVARIABLE)
1071
ttyputmsg(M_("Facet %s synchronized to PostScript file %s"),
1072
describenodeproto(np), (char *)var->addr);
1076
l = strlen(pp = par[1]);
1077
if (namesamen(pp, "flat", l) == 0)
1079
curstate[0] &= ~PSHIERARCHICAL;
1080
io_setstatebits(curstate);
1081
ttyputverbose(M_("PostScript output will be flat"));
1084
if (namesamen(pp, "hierarchical", l) == 0 && l >= 2)
1086
curstate[0] |= PSHIERARCHICAL;
1087
io_setstatebits(curstate);
1088
ttyputverbose(M_("PostScript output will be hierarchical"));
1091
if (namesamen(pp, "encapsulated", l) == 0)
1093
curstate[0] |= EPSPSCRIPT;
1094
io_setstatebits(curstate);
1095
ttyputverbose(M_("PostScript output will be encapsulated format"));
1098
if (namesamen(pp, "plain", l) == 0 && l >= 2)
1100
curstate[0] &= ~EPSPSCRIPT;
1101
io_setstatebits(curstate);
1102
ttyputverbose(M_("PostScript output will be plain format"));
1105
if (namesamen(pp, "color", l) == 0)
1107
curstate[0] = (curstate[0] & ~PSCOLORSTIP) | PSCOLOR;
1108
io_setstatebits(curstate);
1109
ttyputverbose(M_("PostScript output will use color"));
1112
if (namesamen(pp, "stippled-color", l) == 0 && l >= 2)
1114
curstate[0] |= PSCOLOR | PSCOLORSTIP;
1115
io_setstatebits(curstate);
1116
ttyputverbose(M_("PostScript output will use color"));
1119
if (namesamen(pp, "gray-scale", l) == 0)
1121
curstate[0] &= ~PSCOLOR;
1122
io_setstatebits(curstate);
1123
ttyputverbose(M_("PostScript output will be gray-scale"));
1126
if (namesamen(pp, "rotate", l) == 0)
1128
curstate[0] |= PSROTATE;
1129
io_setstatebits(curstate);
1130
ttyputverbose(M_("PostScript output will be rotated 90 degrees"));
1133
if (namesamen(pp, "no-rotate", l) == 0)
1135
curstate[0] &= ~PSROTATE;
1136
io_setstatebits(curstate);
1137
ttyputverbose(M_("PostScript output will appear unrotated"));
1140
if (namesamen(pp, "margin", l) == 0)
1144
wid = atofr(par[2]);
1145
(void)setval((INTBIG)io_tool, VTOOL, "IO_postscript_margin", wid, VFRACT);
1148
var = getval((INTBIG)io_tool, VTOOL, VFRACT, "IO_postscript_margin");
1149
if (var == NOVARIABLE) wid = muldiv(DEFAULTPSMARGIN, WHOLE, 75); else
1152
ttyputverbose(M_("PostScript output will use a %s-wide margin"), frtoa(wid));
1155
if (namesamen(pp, "plotter", l) == 0 && l >= 2)
1157
curstate[0] |= PSPLOTTER;
1158
io_setstatebits(curstate);
1161
wid = atofr(par[2]);
1162
(void)setval((INTBIG)io_tool, VTOOL, "IO_postscript_width", wid, VFRACT);
1163
ttyputverbose(M_("PostScript output will assume a %s-wide plotter"), frtoa(wid));
1165
ttyputverbose(M_("PostScript output will assume a continuous-roll plotter"));
1168
if (namesamen(pp, "printer", l) == 0 && l >= 2)
1170
curstate[0] &= ~PSPLOTTER;
1171
io_setstatebits(curstate);
1174
wid = atofr(par[2]);
1175
(void)setval((INTBIG)io_tool, VTOOL, "IO_postscript_width", wid, VFRACT);
1176
hei = atofr(par[3]);
1177
(void)setval((INTBIG)io_tool, VTOOL, "IO_postscript_height", hei, VFRACT);
1178
ttyputverbose(M_("PostScript output will assume a %s x %s page"),
1179
frtoa(wid), frtoa(hei));
1181
ttyputverbose(M_("PostScript output will be assume a fixed-size sheet"));
1184
if (namesamen(pp, "unsynchronize", l) == 0)
1186
np = el_curlib->curnodeproto;
1187
if (np == NONODEPROTO)
1189
ttyputerr(M_("Edit a facet before removing synchronization"));
1192
if (getvalkey((INTBIG)np, VNODEPROTO, VSTRING, io_postscriptfilenamekey) != NOVARIABLE)
1194
(void)delvalkey((INTBIG)np, VNODEPROTO, io_postscriptfilenamekey);
1195
ttyputverbose(M_("Facet %s no longer synchronized to PostScript disk file"),
1196
describenodeproto(np));
1200
if (namesamen(pp, "synchronize", l) == 0 && l >= 2)
1204
ttyputusage("telltool io postscript synchronize FILENAME");
1207
np = el_curlib->curnodeproto;
1208
if (np == NONODEPROTO)
1210
ttyputerr(M_("Edit a facet to synchronize it to a PostScript file"));
1213
(void)setvalkey((INTBIG)np, VNODEPROTO, io_postscriptfilenamekey,
1214
(INTBIG)par[1], VSTRING);
1215
ttyputverbose(M_("Facet %s synchronized to PostScript file %s"),
1216
describenodeproto(np), par[1]);
1219
ttyputusage("telltool io postscript OPTION");
1223
if (namesamen(pp, "hpgl", l) == 0)
1227
if ((curstate[0]&HPGL2) == 0)
1228
ttyputmsg(M_("HPGL output uses older (version 1) format")); else
1229
ttyputmsg(M_("HPGL output uses newer (HPGL/2) format"));
1232
l = strlen(pp = par[1]);
1233
if (namesamen(pp, "1", l) == 0)
1235
curstate[0] &= ~HPGL2;
1236
io_setstatebits(curstate);
1237
ttyputmsg(M_("HPGL output will use older (version 1) format"));
1240
if (namesamen(pp, "2", l) == 0)
1242
curstate[0] |= HPGL2;
1243
io_setstatebits(curstate);
1244
ttyputverbose(M_("HPGL output will use newer (HPGL/2) format"));
1245
if (count >= 4 && namesamen(par[2], "scale", strlen(par[2])) == 0)
1247
scale = myatoi(par[3]);
1248
(void)setval((INTBIG)io_tool, VTOOL, "IO_hpgl2_scale",
1250
ttyputverbose(M_("HPGL/2 plots will scale at %ld %ss per pixel"),
1251
scale, unitsname(el_units));
1255
ttyputusage("telltool io hpgl [1|2]");
1260
if (namesamen(pp, "edif", l) == 0)
1264
if ((curstate[0]&EDIFSCHEMATIC) == 0)
1265
ttyputmsg(M_("EDIF output writes schematics")); else
1266
ttyputmsg(M_("EDIF output writes netlists"));
1269
l = strlen(pp = par[1]);
1270
if (namesamen(pp, "schematic", l) == 0)
1272
curstate[0] |= EDIFSCHEMATIC;
1273
io_setstatebits(curstate);
1274
ttyputverbose(M_("EDIF output will write schematics"));
1277
if (namesamen(pp, "netlist", l) == 0)
1279
curstate[0] &= ~EDIFSCHEMATIC;
1280
io_setstatebits(curstate);
1281
ttyputverbose(M_("EDIF output will write netlists"));
1284
ttyputusage("telltool io edif [schematic|netlist]");
1289
if (namesamen(pp, "verbose", l) == 0)
1293
ttyputusage("telltool io verbose OPTION");
1296
l = strlen(pp = par[1]);
1297
if (namesamen(pp, "off", l) == 0 && l >= 2)
1300
ttyputverbose(M_("I/O done silently"));
1303
if (namesamen(pp, "on", l) == 0 && l >= 2)
1306
ttyputverbose(M_("I/O prints status"));
1309
if (namesamen(pp, "graphical", l) == 0 && l >= 1)
1312
ttyputverbose(M_("I/O shows graphical progress"));
1315
ttyputbadusage("telltool io verbose");
1319
ttyputbadusage("telltool io");
1323
* make I/O requests of this tool:
1325
* "read" TAKES: LIBRARY to read and string style
1326
* "write" TAKES: LIBRARY to write and string style
1327
* "verbose" TAKES: new verbose factor, RETURNS: old verbose factor
1329
INTBIG io_request(char *command, va_list ap)
1331
REGISTER LIBRARY *lib;
1332
REGISTER INTBIG i, len, format;
1333
REGISTER BOOLEAN err;
1334
REGISTER INTBIG arg1, arg3;
1337
if (namesame(command, "verbose") == 0)
1340
io_verbose = va_arg(ap, INTBIG);
1344
/* get the arguments */
1345
arg1 = va_arg(ap, INTBIG);
1346
arg2 = va_arg(ap, char*);
1348
/* find desired library and format */
1349
lib = (LIBRARY *)arg1;
1352
for(i=0; io_formatlist[i].name != 0; i++)
1353
if (namesamen(arg2, io_formatlist[i].name, len) == 0 && len >= io_formatlist[i].required)
1355
format = io_formatlist[i].bits;
1360
ttyputerr(M_("Unknown I/O format: %s"), arg2);
1364
if (namesame(command, "write") == 0)
1366
/* announce the beginning of library output */
1367
for(i=0; i<el_maxtools; i++)
1368
if (el_tools[i].writelibrary != 0)
1369
(*el_tools[i].writelibrary)(lib, FALSE);
1374
err = io_writebinlibrary(lib, FALSE);
1376
case FBINARYNOBACKUP:
1377
err = io_writebinlibrary(lib, TRUE);
1382
err = io_writeciflibrary(lib);
1388
err = io_writedxflibrary(lib);
1394
err = io_writeeaglelibrary(lib);
1400
err = io_writeecadlibrary(lib);
1406
err = io_writeediflibrary(lib);
1412
err = io_writegdslibrary(lib);
1417
err = io_writehpgllibrary(lib);
1422
err = io_writellibrary(lib);
1428
err = io_writeleflibrary(lib);
1434
err = io_writepadslibrary(lib);
1439
case FPRINTEDPOSTSCRIPT:
1440
err = io_writepostscriptlibrary(lib, (format == FPOSTSCRIPT ? 0 : 1));
1445
err = io_writequickdrawlibrary(lib);
1451
err = io_writeskilllibrary(lib);
1456
err = io_writetextlibrary(lib);
1460
for(i=0; io_formatlist[i].name != 0; i++)
1461
if (io_formatlist[i].bits == format)
1463
ttyputerr(M_("Cannot write %s files"), io_formatlist[i].name);
1468
/* announce the ending of library output */
1470
/* lib->userbits |= READFROMDISK; */
1471
for(i=0; i<el_maxtools; i++)
1472
if (el_tools[i].writelibrary != 0)
1473
(*el_tools[i].writelibrary)(lib, TRUE);
1477
if (namesame(command, "read") == 0)
1479
arg3 = va_arg(ap, INTBIG);
1480
io_libinputrecursivedepth = io_libinputreadmany = 0;
1484
err = io_readbinlibrary(lib);
1485
/* make sure that the lambda values are consistent */
1486
if (!err) io_unifylambdavalues(lib);
1491
err = io_readciflibrary(lib);
1497
err = io_readdeflibrary(lib);
1503
err = io_readdxflibrary(lib);
1509
err = io_readediflibrary(lib);
1515
err = io_readgdslibrary(lib, arg3);
1521
err = io_readleflibrary(lib);
1527
err = io_readsdflibrary(lib);
1533
err = io_readsuelibrary(lib);
1538
err = io_readtextlibrary(lib);
1539
/* make sure that the lambda values are consistent */
1540
if (!err) io_unifylambdavalues(lib);
1545
err = io_readvhdllibrary(lib);
1550
for(i=0; io_formatlist[i].name != 0; i++)
1551
if (io_formatlist[i].bits == format)
1553
ttyputerr(M_("Cannot read %s files"), io_formatlist[i].name);
1558
/* announce the completion of library input */
1560
for(i=0; i<el_maxtools; i++)
1561
if (el_tools[i].readlibrary != 0)
1562
(*el_tools[i].readlibrary)(lib);
1568
/******************************* BLOATING *******************************/
1571
* routine to indicate that CIF layer "layer" is to be bloated by "amount"
1573
void io_setoutputbloat(char *layer, INTBIG amount)
1577
/* special case when bloating the null layer */
1580
for(bl = io_curbloat; bl != NOBLOAT; bl = bl->nextbloat)
1581
ttyputmsg(M_("Bloating layer %s by %ld %ss"), bl->layer, bl->amount, unitsname(el_units));
1585
/* first see if this layer is already being bloated */
1586
for(bl = io_curbloat; bl != NOBLOAT; bl = bl->nextbloat)
1587
if (namesame(bl->layer, layer) == 0)
1589
if (bl->amount == amount)
1591
ttyputmsg(M_("Layer %s is already being bloated by %ld %ss"),
1592
bl->layer, amount, unitsname(el_units));
1595
ttyputmsg(M_("Layer %s was being bloated by %ld %ss, now by %ld"),
1596
bl->layer, bl->amount, unitsname(el_units), amount);
1597
bl->amount = amount;
1601
bl = (BLOAT *)emalloc(sizeof (BLOAT), io_tool->cluster);
1607
(void)allocstring(&bl->layer, layer, io_tool->cluster);
1608
bl->amount = amount;
1609
bl->nextbloat = io_curbloat;
1611
ttyputmsg(M_("Layer %s will be bloated by %ld %ss"), layer, amount, unitsname(el_units));
1615
* routine to tell the amount to bloat layer "lay"
1617
INTBIG io_getoutputbloat(char *layer)
1621
for(bl = io_curbloat; bl != NOBLOAT; bl = bl->nextbloat)
1622
if (namesame(bl->layer, layer) == 0) return(bl->amount);
1626
/******************************* LIBRARY REPAIR *******************************/
1628
#define OLDSOURCEDCV 0 /* Source is DC Voltage */
1629
#define OLDSOURCEAC 0400000 /* Source is AC analysis */
1630
#define OLDSOURCEBULK 01000000 /* Source is Bulk */
1631
#define OLDSOURCEDCC 01400000 /* Source is DC Current */
1632
#define OLDSOURCECURMTR 02000000 /* Source is Current meter */
1633
#define OLDSOURCENODE 02400000 /* Source is Nodeset */
1634
#define OLDSOURCESPEC 03000000 /* Source is Special */
1635
#define OLDSOURCETRAN 03400000 /* Source is Transient Analysis */
1636
#define OLDSOURCEDCAN 04000000 /* Source is DC Analysis */
1637
#define OLDSOURCEEXT 04400000 /* Source is Extension */
1640
* routine to complete formation of library "lib" that has just been read from
1641
* disk. Some data is not read, but computed from other data.
1643
void io_fixnewlib(LIBRARY *lib, INTBIG statusitem)
1645
REGISTER NODEPROTO *np, *pnt, *onp;
1646
REGISTER NODEINST *ni, *newni;
1647
REGISTER ARCINST *ai;
1648
REGISTER LIBRARY *olib;
1649
REGISTER BOOLEAN first, changed;
1650
REGISTER INTBIG libunits, i, j, lam, oldtype, size, len, lambda,
1651
totlx, tothx, totly, tothy, numchanged;
1652
INTBIG lx, ly, hx, hy, major, minor, detail, type, addr, xoff, yoff, growx, growy,
1654
UINTBIG olddescript[TEXTDESCRIPTSIZE];
1655
REGISTER char *str, *pt, **newlist;
1657
static POLYGON *poly = NOPOLYGON;
1658
static INTBIG sch_flipfloptypekey = 0;
1659
static INTBIG edtec_option_key = 0;
1660
static INTBIG sch_transistortypekey = 0;
1661
static INTBIG sch_sourcekey = 0;
1662
static INTBIG sch_twoportkey = 0;
1663
char line[200], *par[4];
1664
REGISTER VARIABLE *var, *newvar;
1665
REGISTER TECHNOLOGY *tech;
1666
REGISTER PORTPROTO *pp, *inpp;
1667
REGISTER PORTARCINST *pi;
1668
REGISTER PORTEXPINST *pe;
1669
REGISTER CELL *cell;
1670
extern ARCPROTO **gen_upconn;
1672
/* make sure units are correct */
1673
libunits = ((lib->userbits & LIBUNITS) >> LIBUNITSSH) << INTERNALUNITSSH;
1674
if ((libunits & INTERNALUNITS) != (el_units & INTERNALUNITS))
1676
ttyputmsg(_("Converting library from %s units to %s units"), unitsname(libunits),
1677
unitsname(el_units));
1678
changeinternalunits(lib, libunits, el_units);
1681
/* check validity of instances */
1682
for(np = lib->firstnodeproto; np != NONODEPROTO; np = np->nextnodeproto)
1684
for(olib = el_curlib; olib != NOLIBRARY; olib = olib->nextlibrary)
1685
if (olib == np->cell->lib) break;
1686
if (olib == NOLIBRARY)
1688
ttyputerr(_("ERROR: Facet %s: has invalid cell structure"), describenodeproto(np));
1691
for(ni = np->firstnodeinst; ni != NONODEINST; ni = ni->nextnodeinst)
1693
if (ni->proto->primindex != 0) continue;
1694
olib = ni->proto->cell->lib;
1695
if (olib == lib) continue;
1696
for(olib = el_curlib; olib != NOLIBRARY; olib = olib->nextlibrary)
1697
if (olib == ni->proto->cell->lib) break;
1698
if (olib == NOLIBRARY)
1700
ttyputerr(_("ERROR: Facet %s: has instance from invalid library"), describenodeproto(np));
1701
ni->proto = gen_univpinprim;
1704
for(onp = olib->firstnodeproto; onp != NONODEPROTO; onp = onp->nextnodeproto)
1705
if (onp == ni->proto) break;
1706
if (onp == NONODEPROTO)
1708
ttyputerr(_("ERROR: Facet %s: has instance with invalid prototype"), describenodeproto(np));
1709
ni->proto = gen_univpinprim;
1715
/* create cell name hash table */
1716
db_buildcellhashtable(lib);
1718
/* adjust every facet in the library */
1719
for(np = lib->firstnodeproto; np != NONODEPROTO; np = np->nextnodeproto)
1721
for(pp = np->firstportproto; pp != NOPORTPROTO; pp = pp->nextportproto)
1722
for(pe = pp->subnodeinst->firstportexpinst; pe != NOPORTEXPINST; pe = pe->nextportexpinst)
1723
if (pe->proto == pp->subportproto)
1725
pp->subportexpinst = pe; break;
1729
* The Macintosh uses a different date epoch than other machines, and this
1730
* is handled in "dbtext.c". However, the adjustment code is recent,
1731
* and some old Macintosh libraries may have incorrect date information.
1733
* The Macintosh epoch is 1904, but every other machine uses 1970.
1734
* Therefore, the Macintosh numbers are 66 years larger.
1736
* To check for bogus date information, see if the date is larger
1737
* than the constant 0x9FE3EB1F. This constant is 1989 in Mac time
1738
* but is 2055 elsewhere (1989 is the earliest possible incarnation
1739
* of Electric on the Mac). If the date is that large, then either it
1740
* is 2055 and Macs still exist (unlikely) or the date is bad and needs
1741
* to have 66 years (0x7C254E10) subtracted from it.
1743
if (np->creationdate > 0x9FE3EB1F) np->creationdate -= 0x7C254E10;
1744
if (np->revisiondate > 0x9FE3EB1F) np->revisiondate -= 0x7C254E10;
1748
/* now fill in the connection lists on the ports */
1749
for(np = lib->firstnodeproto; np != NONODEPROTO; np = np->nextnodeproto)
1750
for(pp = np->firstportproto; pp != NOPORTPROTO; pp = pp->nextportproto)
1753
while (inpp != NOPORTPROTO && inpp->parent->primindex == 0)
1755
inpp = inpp->subportproto;
1757
if (inpp != NOPORTPROTO)
1758
pp->connects = inpp->connects;
1759
if (pp->connects == 0)
1761
if (gen_upconn[0] != 0) pp->connects = gen_upconn; else
1762
pp->connects = &gen_upconn[1];
1763
pp->subportproto = pp->subnodeinst->proto->firstportproto;
1767
/* look for arrayed node specifications */
1768
for(np = lib->firstnodeproto; np != NONODEPROTO; np = np->nextnodeproto)
1770
if (!isschematicview(np)) continue;
1771
for(ni = np->firstnodeinst; ni != NONODEINST; ni = ni->nextnodeinst)
1773
net_setnodewidth(ni);
1778
* see if this is version 4 or earlier...
1779
* In version 4 and earlier, the basic unit was the centimicron and rotation
1780
* was specified in degrees. From version 5 and up, the basic unit is scaled
1781
* by 20 to the half-millimicron and the rotation fields are scaled by 10 to
1782
* tenth-degrees. Also, must convert some variable names.
1784
io_getversion(lib, &major, &minor, &detail);
1786
/* this is only done after all libraries are read */
1787
if (io_libinputrecursivedepth == 0)
1789
/* rebuild list of node instances */
1790
for(tech = el_technologies; tech != NOTECHNOLOGY; tech = tech->nexttechnology)
1791
for(np = tech->firstnodeproto; np != NONODEPROTO; np = np->nextnodeproto)
1792
np->firstinst = NONODEINST;
1793
for(olib = el_curlib; olib != NOLIBRARY; olib = olib->nextlibrary)
1794
for(np = olib->firstnodeproto; np != NONODEPROTO; np = np->nextnodeproto)
1795
np->firstinst = NONODEINST;
1796
for(olib = el_curlib; olib != NOLIBRARY; olib = olib->nextlibrary)
1797
for(np = olib->firstnodeproto; np != NONODEPROTO; np = np->nextnodeproto)
1799
/* examine every nodeinst in the facet */
1800
for(ni = np->firstnodeinst; ni != NONODEINST; ni = ni->nextnodeinst)
1802
/* compute linked list of node instances */
1804
if (pnt == NONODEPROTO)
1806
ttyputerr(_("Facet %s: has a node without a prototype"), describenodeproto(np));
1807
ni->proto = gen_univpinprim;
1809
if (pnt->firstinst != NONODEINST) pnt->firstinst->lastinst = ni;
1810
ni->nextinst = pnt->firstinst;
1811
ni->lastinst = NONODEINST;
1812
pnt->firstinst = ni;
1816
/* for versions before 6.05bc, look for icon facets that are wrong */
1818
(major == 6 && minor < 5) ||
1819
(major == 6 && minor == 5 && detail < 55))
1822
for(olib = el_curlib; olib != NOLIBRARY; olib = olib->nextlibrary)
1823
for(np = olib->firstnodeproto; np != NONODEPROTO; np = np->nextnodeproto)
1826
for(ni = np->firstnodeinst; ni != NONODEINST; ni = ni->nextnodeinst)
1828
boundobj(ni->geom, &lx, &hx, &ly, &hy);
1832
totlx = lx; tothx = hx;
1833
totly = ly; tothy = hy;
1836
if (lx < totlx) totlx = lx;
1837
if (hx > tothx) tothx = hx;
1838
if (ly < totly) totly = ly;
1839
if (hy > tothy) tothy = hy;
1842
for(ai = np->firstarcinst; ai != NOARCINST; ai = ai->nextarcinst)
1844
boundobj(ai->geom, &lx, &hx, &ly, &hy);
1845
if (lx < totlx) totlx = lx;
1846
if (hx > tothx) tothx = hx;
1847
if (ly < totly) totly = ly;
1848
if (hy > tothy) tothy = hy;
1850
if (first) continue;
1851
if (np->lowx == totlx && np->highx == tothx &&
1852
np->lowy == totly && np->highy == tothy) continue;
1854
for(ni = np->firstinst; ni != NONODEINST; ni = ni->nextinst)
1856
growx = ((tothx - np->highx) + (totlx - np->lowx)) / 2;
1857
growy = ((tothy - np->highy) + (totly - np->lowy)) / 2;
1858
if (ni->transpose != 0)
1860
makeangle(ni->rotation, ni->transpose, trans);
1863
makeangle((3600 - ni->rotation)%3600, 0, trans);
1865
xform(growx, growy, &shiftx, &shifty, trans);
1866
ni->lowx += totlx - np->lowx - growx + shiftx;
1867
ni->highx += tothx - np->highx - growx + shiftx;
1868
ni->lowy += totly - np->lowy - growy + shifty;
1869
ni->highy += tothy - np->highy - growy + shifty;
1870
updategeom(ni->geom, ni->parent);
1872
np->lowx = totlx; np->highx = tothx;
1873
np->lowy = totly; np->highy = tothy;
1876
if (numchanged != 0)
1878
ttyputmsg(_("WARNING: due to changes in bounds calculation, %ld facet sizes were adjusted"),
1880
ttyputmsg(_("...should do Check&Repair library"));
1884
/* create network information */
1885
if (statusitem > 0) DiaSetText(statusitem, _("Building network data..."));
1886
if (io_libinputreadmany > 0)
1888
/* many libraries read: renumber everything */
1889
(void)asktool(net_tool, "total-re-number");
1892
/* just 1 library read: renumber it */
1893
(void)asktool(net_tool, "library-re-number", (INTBIG)lib);
1897
/* set the facet's technology */
1898
for(np = lib->firstnodeproto; np != NONODEPROTO; np = np->nextnodeproto)
1899
np->tech = whattech(np);
1901
/* check for incorrect layer counts on stored variables */
1904
/* for versions 6.02 or earlier, convert text sizes */
1905
if (major < 6 || (major == 6 && minor <= 2))
1907
#ifdef REPORTCONVERSION
1908
ttyputmsg(" Converting text sizes");
1910
for(np = lib->firstnodeproto; np != NONODEPROTO; np = np->nextnodeproto)
1912
for(ni = np->firstnodeinst; ni != NONODEINST; ni = ni->nextnodeinst)
1914
io_convertallrelativetext(ni->numvar, ni->firstvar);
1915
for(pi = ni->firstportarcinst; pi != NOPORTARCINST; pi = pi->nextportarcinst)
1916
io_convertallrelativetext(pi->numvar, pi->firstvar);
1917
for(pe = ni->firstportexpinst; pe != NOPORTEXPINST; pe = pe->nextportexpinst)
1918
io_convertallrelativetext(pe->numvar, pe->firstvar);
1919
if (ni->proto->primindex == 0)
1920
io_convertrelativetext(ni->textdescript);
1922
for(ai = np->firstarcinst; ai != NOARCINST; ai = ai->nextarcinst)
1923
io_convertallrelativetext(ai->numvar, ai->firstvar);
1924
for(pp = np->firstportproto; pp != NOPORTPROTO; pp = pp->nextportproto)
1926
io_convertallrelativetext(pp->numvar, pp->firstvar);
1927
io_convertrelativetext(pp->textdescript);
1929
io_convertallrelativetext(np->numvar, np->firstvar);
1931
for(cell = lib->firstcell; cell != NOCELL; cell = cell->nextcell)
1932
io_convertallrelativetext(cell->numvar, cell->firstvar);
1933
io_convertallrelativetext(lib->numvar, lib->firstvar);
1936
/* for versions before 6.04c, convert text descriptor values */
1938
(major == 6 && minor < 4) ||
1939
(major == 6 && minor == 4 && detail < 3))
1941
#ifdef REPORTCONVERSION
1942
ttyputmsg(" Converting text descriptors");
1944
for(np = lib->firstnodeproto; np != NONODEPROTO; np = np->nextnodeproto)
1946
for(ni = np->firstnodeinst; ni != NONODEINST; ni = ni->nextnodeinst)
1948
io_convertalltextdescriptors(ni->numvar, ni->firstvar);
1949
for(pi = ni->firstportarcinst; pi != NOPORTARCINST; pi = pi->nextportarcinst)
1950
io_convertalltextdescriptors(pi->numvar, pi->firstvar);
1951
for(pe = ni->firstportexpinst; pe != NOPORTEXPINST; pe = pe->nextportexpinst)
1952
io_convertalltextdescriptors(pe->numvar, pe->firstvar);
1953
if (ni->proto->primindex == 0)
1954
io_converttextdescriptor(ni->textdescript);
1956
for(ai = np->firstarcinst; ai != NOARCINST; ai = ai->nextarcinst)
1957
io_convertalltextdescriptors(ai->numvar, ai->firstvar);
1958
for(pp = np->firstportproto; pp != NOPORTPROTO; pp = pp->nextportproto)
1960
io_convertalltextdescriptors(pp->numvar, pp->firstvar);
1961
io_converttextdescriptor(pp->textdescript);
1963
io_convertalltextdescriptors(np->numvar, np->firstvar);
1965
for(cell = lib->firstcell; cell != NOCELL; cell = cell->nextcell)
1966
io_convertalltextdescriptors(cell->numvar, cell->firstvar);
1967
io_convertalltextdescriptors(lib->numvar, lib->firstvar);
1970
/* for versions before 6.03r, convert variables on schematic primitives */
1972
(major == 6 && minor < 3) ||
1973
(major == 6 && minor == 3 && detail < 18))
1975
if (sch_transistortypekey == 0)
1976
sch_transistortypekey = makekey("SCHEM_transistor_type");
1977
if (sch_sourcekey == 0)
1978
sch_sourcekey = makekey("SCHEM_source");
1979
for(np = lib->firstnodeproto; np != NONODEPROTO; np = np->nextnodeproto)
1981
for(ni = np->firstnodeinst; ni != NONODEINST; ni = ni->nextnodeinst)
1983
if (ni->proto->primindex == 0) continue;
1984
if (ni->proto->tech == sch_tech)
1986
if (ni->proto == sch_transistorprim)
1988
var = getvalkey((INTBIG)ni, VNODEINST, VSTRING, sch_transistortypekey);
1989
if (var != NOVARIABLE)
1991
str = (char *)var->addr;
1992
if (namesamen(str, "nmos", 4) == 0)
1994
ni->userbits |= TRANNMOS; str += 4;
1995
} else if (namesamen(str, "dmos", 4) == 0)
1997
ni->userbits |= TRANDMOS; str += 4;
1998
} else if (namesamen(str, "pmos", 4) == 0)
2000
ni->userbits |= TRANPMOS; str += 4;
2001
} else if (namesamen(str, "npn", 3) == 0)
2003
ni->userbits |= TRANNPN; str += 3;
2004
} else if (namesamen(str, "pnp", 3) == 0)
2006
ni->userbits |= TRANPNP; str += 3;
2007
} else if (namesamen(str, "njfet", 5) == 0)
2009
ni->userbits |= TRANNJFET; str += 5;
2010
} else if (namesamen(str, "pjfet", 5) == 0)
2012
ni->userbits |= TRANPJFET; str += 5;
2013
} else if (namesamen(str, "dmes", 4) == 0)
2015
ni->userbits |= TRANDMES; str += 4;
2016
} else if (namesamen(str, "emes", 4) == 0)
2018
ni->userbits |= TRANEMES; str += 4;
2020
if (*str == 0) (void)delvalkey((INTBIG)ni, VNODEINST, sch_transistortypekey); else
2022
TDCOPY(olddescript, var->textdescript);
2024
(void)addstringtoinfstr(str);
2025
var = setvalkey((INTBIG)ni, VNODEINST, sch_transistortypekey,
2026
(INTBIG)returninfstr(), var->type);
2027
if (var != NOVARIABLE)
2028
TDCOPY(var->textdescript, olddescript);
2031
} else if (ni->proto == sch_sourceprim)
2033
var = getvalkey((INTBIG)ni, VNODEINST, VSTRING, sch_sourcekey);
2034
if (var != NOVARIABLE)
2036
str = (char *)var->addr;
2037
if (namesamen(str, "vd", 2) == 0)
2039
ni->userbits |= OLDSOURCEDCAN; str += 2;
2040
} else if (namesamen(str, "v", 1) == 0)
2042
ni->userbits |= OLDSOURCEDCV; str++;
2043
} else if (namesamen(str, "cm", 2) == 0)
2045
ni->userbits |= OLDSOURCECURMTR; str += 2;
2046
} else if (namesamen(str, "c", 1) == 0)
2048
ni->userbits |= OLDSOURCEDCC; str++;
2049
} else if (namesamen(str, "t", 1) == 0)
2051
ni->userbits |= OLDSOURCETRAN; str++;
2052
} else if (namesamen(str, "a", 1) == 0)
2054
ni->userbits |= OLDSOURCEAC; str++;
2055
} else if (namesamen(str, "n", 1) == 0)
2057
ni->userbits |= OLDSOURCENODE; str++;
2058
} else if (namesamen(str, "x", 1) == 0)
2060
ni->userbits |= OLDSOURCEEXT; str++;
2061
} else if (namesamen(str, "b", 1) == 0)
2063
ni->userbits |= OLDSOURCEBULK; str++;
2064
} else if (namesamen(str, "s", 1) == 0)
2066
ni->userbits |= OLDSOURCESPEC; str++;
2068
if (*str == '/') str++;
2069
if (*str == 0) (void)delvalkey((INTBIG)ni, VNODEINST, sch_sourcekey); else
2071
TDCOPY(olddescript, var->textdescript);
2073
(void)addstringtoinfstr(str);
2074
var = setvalkey((INTBIG)ni, VNODEINST, sch_sourcekey,
2075
(INTBIG)returninfstr(), var->type|VDISPLAY);
2076
if (var != NOVARIABLE)
2077
TDCOPY(var->textdescript, olddescript);
2080
} else if (ni->proto == sch_diodeprim)
2082
var = getvalkey((INTBIG)ni, VNODEINST, VSTRING, sch_diodekey);
2083
if (var != NOVARIABLE)
2085
str = (char *)var->addr;
2086
while (*str == ' ' || *str == '\t') str++;
2087
if (tolower(*str) == 'z')
2090
ni->userbits |= DIODEZENER;
2092
if (*str == 0) (void)delvalkey((INTBIG)ni, VNODEINST, sch_diodekey); else
2094
TDCOPY(olddescript, var->textdescript);
2096
(void)addstringtoinfstr(str);
2097
var = setvalkey((INTBIG)ni, VNODEINST, sch_diodekey,
2098
(INTBIG)returninfstr(), var->type|VDISPLAY);
2099
if (var != NOVARIABLE)
2100
TDCOPY(var->textdescript, olddescript);
2103
} else if (ni->proto == sch_capacitorprim)
2105
var = getvalkey((INTBIG)ni, VNODEINST, VSTRING, sch_capacitancekey);
2106
if (var != NOVARIABLE)
2108
str = (char *)var->addr;
2109
while (*str == ' ' || *str == '\t') str++;
2110
if (tolower(*str) == 'e')
2113
ni->userbits |= CAPACELEC;
2115
if (*str == 0) (void)delvalkey((INTBIG)ni, VNODEINST, sch_capacitancekey); else
2117
TDCOPY(olddescript, var->textdescript);
2119
(void)addstringtoinfstr(str);
2120
var = setvalkey((INTBIG)ni, VNODEINST, sch_capacitancekey,
2121
(INTBIG)returninfstr(), var->type|VDISPLAY);
2122
if (var != NOVARIABLE)
2123
TDCOPY(var->textdescript, olddescript);
2126
} else if (ni->proto == sch_twoportprim)
2128
if (sch_twoportkey == 0)
2129
sch_twoportkey = makekey("SCHEM_twoport_type");
2130
var = getvalkey((INTBIG)ni, VNODEINST, VSTRING, sch_twoportkey);
2131
if (var != NOVARIABLE)
2133
str = (char *)var->addr;
2134
while (*str == ' ') str++;
2135
switch (tolower(*str))
2137
case 'u': ni->userbits |= TWOPVCVS; str++; break;
2138
case 'g': ni->userbits |= TWOPVCCS; str++; break;
2139
case 'h': ni->userbits |= TWOPCCVS; str++; break;
2140
case 'f': ni->userbits |= TWOPCCCS; str++; break;
2141
case 'l': ni->userbits |= TWOPTLINE; str++; break;
2144
if (*str == 0) (void)delvalkey((INTBIG)ni, VNODEINST, sch_twoportkey); else
2146
TDCOPY(olddescript, var->textdescript);
2148
(void)addstringtoinfstr(str);
2149
var = setvalkey((INTBIG)ni, VNODEINST, sch_spicemodelkey,
2150
(INTBIG)returninfstr(), var->type|VDISPLAY);
2151
if (var != NOVARIABLE)
2152
TDCOPY(var->textdescript, olddescript);
2155
} else if (ni->proto == sch_ffprim)
2157
if (sch_flipfloptypekey == 0)
2158
sch_flipfloptypekey = makekey("SCHEM_flipflop_type");
2159
var = getvalkey((INTBIG)ni, VNODEINST, VSTRING, sch_flipfloptypekey);
2160
if (var != NOVARIABLE)
2162
for (str = (char *)var->addr; *str != 0; str++)
2164
if (namesamen(str, "rs", 2) == 0)
2166
ni->userbits |= FFTYPERS;
2170
if (namesamen(str, "jk", 2) == 0)
2172
ni->userbits |= FFTYPEJK;
2176
if (namesamen(str, "t", 1) == 0)
2178
ni->userbits |= FFTYPET;
2181
if (namesamen(str, "d", 1) == 0)
2183
ni->userbits |= FFTYPED;
2186
if (namesamen(str, "ms", 2) == 0)
2188
ni->userbits |= FFCLOCKMS;
2192
if (namesamen(str, "p", 1) == 0)
2194
ni->userbits |= FFCLOCKP;
2197
if (namesamen(str, "n", 1) == 0)
2199
ni->userbits |= FFCLOCKN;
2204
(void)delvalkey((INTBIG)ni, VNODEINST, sch_flipfloptypekey);
2212
/* for versions before 6.05bh, make sure that "far text" bit is set right */
2213
if (io_libinputrecursivedepth == 0)
2216
(major == 6 && minor < 5) ||
2217
(major == 6 && minor == 5 && detail < 60))
2219
for(olib = el_curlib; olib != NOLIBRARY; olib = olib->nextlibrary)
2220
for(np = olib->firstnodeproto; np != NONODEPROTO; np = np->nextnodeproto)
2222
for(ni = np->firstnodeinst; ni != NONODEINST; ni = ni->nextnodeinst)
2223
us_computenodefartextbit(ni);
2224
for(ai = np->firstarcinst; ai != NOARCINST; ai = ai->nextarcinst)
2225
us_computearcfartextbit(ai);
2230
/* for versions before 6.05bi, make all facet centers be "visible only inside facet" */
2232
(major == 6 && minor < 5) ||
2233
(major == 6 && minor == 5 && detail < 61))
2235
for(np = lib->firstnodeproto; np != NONODEPROTO; np = np->nextnodeproto)
2237
for(ni = np->firstnodeinst; ni != NONODEINST; ni = ni->nextnodeinst)
2239
if (ni->proto != gen_facetcenterprim) continue;
2240
ni->userbits |= NVISIBLEINSIDE;
2245
/* for versions before 6.05ba, convert source nodes */
2247
(major == 6 && minor < 5) ||
2248
(major == 6 && minor == 5 && detail < 53))
2250
/* change all Wire_Pins that are 1x1 to be 0.5x0.5 */
2252
for(np = lib->firstnodeproto; np != NONODEPROTO; np = np->nextnodeproto)
2254
for(ni = np->firstnodeinst; ni != NONODEINST; ni = ni->nextnodeinst)
2256
if (ni->proto->primindex == 0) continue;
2257
if (ni->proto->tech != sch_tech) continue;
2258
if (ni->proto != sch_wirepinprim) continue;
2259
lambda = lambdaofnode(ni);
2260
if (ni->highx - ni->lowx == lambda &&
2261
ni->highy - ni->lowy == lambda)
2263
modifynodeinst(ni, lambda/4, lambda/4, -lambda/4, -lambda/4, 0, 0);
2268
if (numchanged != 0)
2269
ttyputmsg(_("Note: reduced the size of %ld schematic wire pins from 1x1 to 0.5x0.5"),
2273
/* for versions before 6.05al, convert source nodes */
2275
(major == 6 && minor < 5) ||
2276
(major == 6 && minor == 5 && detail < 38))
2278
for(np = lib->firstnodeproto; np != NONODEPROTO; np = np->nextnodeproto)
2281
for(ni = np->firstnodeinst; ni != NONODEINST; ni = ni->nextnodeinst)
2283
if (ni->proto->primindex == 0) continue;
2284
if (ni->proto->tech != sch_tech) continue;
2285
if (ni->proto != sch_sourceprim) continue;
2287
switch (ni->userbits&NTECHBITS)
2289
case OLDSOURCEDCAN: str = "AnalysisDC"; break;
2290
case OLDSOURCEDCV: str = "DCVoltage"; break;
2291
case OLDSOURCEDCC: str = "DCCurrent"; break;
2292
case OLDSOURCETRAN: str = "AnalysisTransient"; break;
2293
case OLDSOURCEAC: str = "AnalysisAC"; break;
2294
case OLDSOURCENODE: str = "NodeSet"; break;
2295
case OLDSOURCEEXT: str = "Extension"; break;
2297
if (str == 0) continue;
2299
/* make sure the "spiceparts" library is read */
2300
olib = getlibrary("spiceparts");
2301
if (olib == NOLIBRARY)
2305
par[2] = "spiceparts.txt";
2307
telltool(us_tool, 4, par);
2308
olib = getlibrary("spiceparts");
2309
if (olib == NOLIBRARY)
2311
ttyputerr(_("Cannot find spice parts library for source conversion"));
2315
sprintf(line, "spiceparts:%s", str);
2316
onp = getnodeproto(line);
2317
if (onp == NONODEPROTO)
2319
ttyputerr(_("Cannot find '%s' for source conversion"), line);
2322
newni = replacenodeinst(ni, onp, TRUE, TRUE);
2323
if (newni != NONODEINST)
2324
newni->userbits |= NEXPAND;
2327
if (ni != NONODEINST) break;
2329
ttyputmsg(_("Warning: SPICE components converted in facet %s. Additional editing may be required."),
2330
describenodeproto(np));
2334
/* for versions before 6.04o, separate transistor size and SPICE info */
2336
(major == 6 && minor < 4) ||
2337
(major == 6 && minor == 4 && detail < 15))
2339
if (sch_transistortypekey == 0)
2340
sch_transistortypekey = makekey("SCHEM_transistor_type");
2341
if (sch_sourcekey == 0)
2342
sch_sourcekey = makekey("SCHEM_source");
2343
for(np = lib->firstnodeproto; np != NONODEPROTO; np = np->nextnodeproto)
2345
for(ni = np->firstnodeinst; ni != NONODEINST; ni = ni->nextnodeinst)
2347
if (ni->proto->primindex == 0) continue;
2348
if (ni->proto->tech != sch_tech) continue;
2350
/* convert "SCHEM_source" to "SIM_spice_model" */
2351
var = getvalkey((INTBIG)ni, VNODEINST, -1, sch_sourcekey);
2352
if (var != NOVARIABLE)
2354
TDCOPY(olddescript, var->textdescript);
2355
newvar = setvalkey((INTBIG)ni, VNODEINST, sch_spicemodelkey, var->addr,
2358
TDCOPY(newvar->textdescript, olddescript);
2359
(void)delvalkey((INTBIG)ni, VNODEINST, sch_sourcekey);
2362
if (ni->proto != sch_transistorprim &&
2363
ni->proto != sch_transistor4prim) continue;
2364
var = getvalkey((INTBIG)ni, VNODEINST, VSTRING, sch_transistortypekey);
2365
if (var == NOVARIABLE) continue;
2367
/* look for "/" and split into Width and Length */
2368
str = (char *)var->addr;
2369
oldtype = var->type;
2370
TDCOPY(olddescript, var->textdescript);
2371
#if 0 /* uncomment force "length=" and "width=" to be displayed */
2372
if ((oldtype&VDISPLAY) != 0 && TDGETDISPPART(olddescript) == VTDISPLAYVALUE)
2373
TDSETDISPPART(olddescript, VTDISPLAYNAMEVALUE);
2375
for(pt = str; *pt != 0; pt++) if (*pt == '/') break;
2380
/* determine separation of descriptors */
2381
us_getlenwidoffset(ni, olddescript, &xoff, &yoff);
2382
getsimpletype(str, &type, &addr);
2383
type |= oldtype & (VCODE1 | VCODE2 | VDISPLAY | VDONTSAVE);
2384
newvar = setvalkey((INTBIG)ni, VNODEINST, el_attrkey_width, addr, type);
2385
if (newvar != NOVARIABLE)
2387
TDCOPY(newvar->textdescript, olddescript);
2388
TDSETOFF(newvar->textdescript, TDGETXOFF(newvar->textdescript)+xoff,
2389
TDGETYOFF(newvar->textdescript)+yoff);
2393
for(pt = str; *pt != 0; pt++) if (*pt == '/') break;
2394
if (*pt == '/') *pt++ = 0;
2395
getsimpletype(str, &type, &addr);
2396
type |= oldtype & (VCODE1 | VCODE2 | VDISPLAY | VDONTSAVE);
2397
newvar = setvalkey((INTBIG)ni, VNODEINST, el_attrkey_length, addr, type);
2398
if (newvar != NOVARIABLE)
2400
TDCOPY(newvar->textdescript, olddescript);
2401
size = TDGETSIZE(newvar->textdescript);
2402
i = TXTGETPOINTS(size);
2403
if (i > 3) size = TXTSETPOINTS(i-2); else
2405
i = TXTGETQLAMBDA(size);
2406
if (i > 3) size = TXTSETQLAMBDA(i-2);
2408
TDSETSIZE(newvar->textdescript, size);
2409
TDSETOFF(newvar->textdescript, TDGETXOFF(newvar->textdescript)-xoff,
2410
TDGETYOFF(newvar->textdescript)-yoff);
2413
/* see if a SPICE model is at the end */
2416
type = VSTRING | (oldtype & (VCODE1 | VCODE2 | VDISPLAY | VDONTSAVE));
2417
newvar = setvalkey((INTBIG)ni, VNODEINST, sch_spicemodelkey,
2419
if (newvar != NOVARIABLE)
2420
TDCOPY(newvar->textdescript, olddescript);
2424
/* single number: just save Area */
2425
getsimpletype(str, &type, &addr);
2426
type |= oldtype & (VCODE1 | VCODE2 | VDISPLAY | VDONTSAVE);
2427
newvar = setvalkey((INTBIG)ni, VNODEINST, el_attrkey_area, addr, type);
2428
if (newvar != NOVARIABLE)
2429
TDCOPY(newvar->textdescript, olddescript);
2431
(void)delvalkey((INTBIG)ni, VNODEINST, sch_transistortypekey);
2436
/* for versions before 6.03g, convert schematic and mocmossub primitives */
2438
(major == 6 && minor < 3) ||
2439
(major == 6 && minor == 3 && detail < 7))
2441
#ifdef REPORTCONVERSION
2442
ttyputmsg(" Converting schematic and MOSIS CMOS primitives");
2444
for(np = lib->firstnodeproto; np != NONODEPROTO; np = np->nextnodeproto)
2446
for(ni = np->firstnodeinst; ni != NONODEINST; ni = ni->nextnodeinst)
2448
if (ni->proto->primindex == 0) continue;
2449
if (ni->proto->tech == sch_tech)
2451
if (ni->proto == sch_pwrprim)
2453
lam = lib->lambda[sch_tech->techindex];
2454
io_fixupnodeinst(ni, lam/2, lam/2, -lam/2, -lam/2);
2455
} else if (ni->proto == sch_gndprim)
2457
lam = lib->lambda[sch_tech->techindex];
2458
io_fixupnodeinst(ni, lam/2, 0, -lam/2, 0);
2459
} else if (ni->proto == sch_capacitorprim)
2461
lam = lib->lambda[sch_tech->techindex];
2462
io_fixupnodeinst(ni, lam/2, 0, -lam/2, 0);
2463
} else if (ni->proto == sch_resistorprim)
2465
lam = lib->lambda[sch_tech->techindex];
2466
io_fixupnodeinst(ni, 0, lam/2, 0, -lam/2);
2468
} else if (ni->proto->tech == mocmos_tech)
2470
if (ni->proto == mocmos_metal1metal2prim)
2472
lam = lib->lambda[mocmos_tech->techindex];
2473
io_fixupnodeinst(ni, -lam/2, -lam/2, lam/2, lam/2);
2474
} else if (ni->proto == mocmos_metal4metal5prim)
2476
lam = lib->lambda[mocmos_tech->techindex];
2477
io_fixupnodeinst(ni, -lam/2, -lam/2, lam/2, lam/2);
2478
} else if (ni->proto == mocmos_metal5metal6prim)
2480
lam = lib->lambda[mocmos_tech->techindex];
2481
io_fixupnodeinst(ni, -lam, -lam, lam, lam);
2482
} else if (ni->proto == mocmos_ptransistorprim)
2484
lam = lib->lambda[mocmos_tech->techindex];
2485
io_fixupnodeinst(ni, 0, -lam, 0, lam);
2486
} else if (ni->proto == mocmos_ntransistorprim)
2488
lam = lib->lambda[mocmos_tech->techindex];
2489
io_fixupnodeinst(ni, 0, -lam, 0, lam);
2490
} else if (ni->proto == mocmos_metal1poly2prim)
2492
lam = lib->lambda[mocmos_tech->techindex];
2493
io_fixupnodeinst(ni, -lam*3, -lam*3, lam*3, lam*3);
2494
} else if (ni->proto == mocmos_metal1poly12prim)
2496
lam = lib->lambda[mocmos_tech->techindex];
2497
io_fixupnodeinst(ni, -lam*4, -lam*4, lam*4, lam*4);
2504
/* for versions before 6.03l, convert mocmossub via4-via6 */
2506
(major == 6 && minor < 3) ||
2507
(major == 6 && minor == 3 && detail < 12))
2509
#ifdef REPORTCONVERSION
2510
ttyputmsg(" Converting MOSIS CMOS vias");
2512
for(np = lib->firstnodeproto; np != NONODEPROTO; np = np->nextnodeproto)
2514
for(ni = np->firstnodeinst; ni != NONODEINST; ni = ni->nextnodeinst)
2516
if (ni->proto->primindex == 0) continue;
2517
if (ni->proto->tech != mocmos_tech) continue;
2518
if (namesame(ni->proto->primname, "Metal-3-Metal-4-Con") == 0 ||
2519
namesame(ni->proto->primname, "Metal-4-Metal-5-Con") == 0 ||
2520
namesame(ni->proto->primname, "Metal-5-Metal-6-Con") == 0)
2522
lam = lib->lambda[mocmos_tech->techindex];
2523
io_fixupnodeinst(ni, -lam, -lam, lam, lam);
2529
/* for versions before 6.03aa, convert mocmossub well contacts */
2531
(major == 6 && minor < 3) ||
2532
(major == 6 && minor == 3 && detail < 27))
2534
for(np = lib->firstnodeproto; np != NONODEPROTO; np = np->nextnodeproto)
2536
for(ni = np->firstnodeinst; ni != NONODEINST; ni = ni->nextnodeinst)
2538
if (ni->proto->primindex == 0) continue;
2539
if (ni->proto->tech != mocmos_tech) continue;
2540
if (namesame(ni->proto->primname, "Metal-1-N-Well-Con") == 0 ||
2541
namesame(ni->proto->primname, "Metal-1-P-Well-Con") == 0)
2543
lam = lib->lambda[mocmos_tech->techindex];
2544
io_fixupnodeinst(ni, -lam-lam/2, -lam-lam/2, lam+lam/2, lam+lam/2);
2550
/* for versions before 6.05ab, derive "far text" bits */
2552
(major == 6 && minor < 5) ||
2553
(major == 6 && minor == 5 && detail < 28))
2555
for(np = lib->firstnodeproto; np != NONODEPROTO; np = np->nextnodeproto)
2557
for(ni = np->firstnodeinst; ni != NONODEINST; ni = ni->nextnodeinst)
2558
us_computenodefartextbit(ni);
2559
for(ai = np->firstarcinst; ai != NOARCINST; ai = ai->nextarcinst)
2560
us_computearcfartextbit(ai);
2564
/* for versions before 6.05ak, convert quick-key bindings */
2566
(major == 6 && minor < 5) ||
2567
(major == 6 && minor == 5 && detail < 37))
2569
var = getvalkey((INTBIG)us_tool, VTOOL, VSTRING|VISARRAY, us_quickkeyskey);
2570
if (var != NOVARIABLE)
2572
len = getlength(var);
2573
newlist = (char **)emalloc(len * (sizeof (char *)), el_tempcluster);
2575
for(i=0; i<len; i++)
2577
pt = ((char **)var->addr)[i];
2578
(void)allocstring(&newlist[i], pt, el_tempcluster);
2579
if (pt[1] != '/') continue;
2581
if (j >= 0216 && j <= 0231)
2583
/* convert former "function" key */
2584
sprintf(line, "F%ld%s", j - 0215, &pt[1]);
2585
(void)reallocstring(&newlist[i], line, el_tempcluster);
2592
setvalkey((INTBIG)us_tool, VTOOL, us_quickkeyskey, (INTBIG)newlist,
2593
VSTRING|VISARRAY|(len<<VLENGTHSH));
2595
for(i=0; i<len; i++) efree((char *)newlist[i]);
2596
efree((char *)newlist);
2600
/* the rest of the changes are just for version 4 or earlier */
2601
if (major >= 5) return;
2603
/* setup for units conversion */
2604
if (poly == NOPOLYGON) poly = allocstaticpolygon(4, io_tool->cluster);
2605
if (edtec_option_key == 0) edtec_option_key = makekey("EDTEC_option");
2607
/* must scale, first make sure the technologies agree with this library */
2608
if (lib != el_curlib)
2609
for(tech = el_technologies; tech != NOTECHNOLOGY; tech = tech->nexttechnology)
2610
changetechnologylambda(tech, lib->lambda[tech->techindex]);
2613
for(np = lib->firstnodeproto; np != NONODEPROTO; np = np->nextnodeproto)
2615
var = getvalkey((INTBIG)np, VNODEPROTO, VINTEGER|VISARRAY, el_prototype_center_key);
2616
if (var != NOVARIABLE)
2618
((INTBIG *)var->addr)[0] *= 20;
2619
((INTBIG *)var->addr)[1] *= 20;
2621
for(ni = np->firstnodeinst; ni != NONODEINST; ni = ni->nextnodeinst)
2623
ni->lowx *= 20; ni->highx *= 20;
2624
ni->lowy *= 20; ni->highy *= 20;
2626
var = getvalkey((INTBIG)ni, VNODEINST, VINTEGER, edtec_option_key);
2627
if (var != NOVARIABLE)
2629
if (var->addr == TECHLAMBDA)
2631
var = getvalkey((INTBIG)ni, VNODEINST, VSTRING, art_messagekey);
2632
if (var != NOVARIABLE)
2634
lam = myatoi(&((char *)var->addr)[8]);
2635
(void)sprintf(line, "Lambda: %ld", lam*20);
2637
(void)setvalkey((INTBIG)ni, VNODEINST, art_messagekey,
2638
(INTBIG)line, VSTRING|VDISPLAY);
2642
var = getvalkey((INTBIG)ni, VNODEINST, VINTEGER|VISARRAY, el_trace_key);
2643
if (var != NOVARIABLE)
2646
for(j=0; j<i; j++) ((INTBIG *)var->addr)[j] *= 20;
2648
var = getvalkey((INTBIG)ni, VNODEINST, VINTEGER, art_degreeskey);
2649
if (var != NOVARIABLE) var->addr *= 10;
2650
boundobj(ni->geom, &ni->geom->lowx, &ni->geom->highx, &ni->geom->lowy, &ni->geom->highy);
2654
for(np = lib->firstnodeproto; np != NONODEPROTO; np = np->nextnodeproto)
2656
for(ai = np->firstarcinst; ai != NOARCINST; ai = ai->nextarcinst)
2659
ai->end[0].xpos *= 20; ai->end[0].ypos *= 20;
2660
ai->end[1].xpos *= 20; ai->end[1].ypos *= 20;
2661
(void)setshrinkvalue(ai, FALSE);
2662
var = getvalkey((INTBIG)ai, VARCINST, VINTEGER, el_arc_radius_key);
2663
if (var != NOVARIABLE) var->addr *= 20;
2666
/* make sure arcinst connects in portinst area */
2667
shapeportpoly(ai->end[i].nodeinst, ai->end[i].portarcinst->proto, poly, FALSE);
2668
if (isinside(ai->end[i].xpos, ai->end[i].ypos, poly)) continue;
2669
portposition(ai->end[i].nodeinst, ai->end[i].portarcinst->proto, &lx, &ly);
2670
if (lx == ai->end[i].xpos && ly == ai->end[i].ypos) continue;
2672
/* try to make manhattan fix */
2673
if ((ai->end[0].xpos == ai->end[1].xpos) && isinside(ai->end[i].xpos, ly, poly))
2674
ai->end[i].ypos = ly; else
2675
if ((ai->end[0].ypos == ai->end[1].ypos) &&
2676
isinside(lx, ai->end[i].ypos, poly))
2677
ai->end[i].xpos = lx; else
2679
ai->end[i].xpos = lx; ai->end[i].ypos = ly;
2682
ai->length = computedistance(ai->end[0].xpos,ai->end[0].ypos,
2683
ai->end[1].xpos,ai->end[1].ypos);
2684
boundobj(ai->geom, &ai->geom->lowx, &ai->geom->highx, &ai->geom->lowy, &ai->geom->highy);
2686
db_boundfacet(np, &np->lowx, &np->highx, &np->lowy, &np->highy);
2687
io_fixrtree(np->rtree);
2690
/* now restore the technology lambda values */
2691
if (lib != el_curlib)
2692
for(tech = el_technologies; tech != NOTECHNOLOGY; tech = tech->nexttechnology)
2693
changetechnologylambda(tech, el_curlib->lambda[tech->techindex]);
2696
#define OLDSIZE 01700
2698
#define OLDTXT4P 0 /* 4 point text */
2699
#define OLDTXT6P 1 /* 6 point text */
2700
#define OLDTXT8P 2 /* 8 point text */
2701
#define OLDTXT10P 3 /* 10 point text */
2702
#define OLDTXT12P 4 /* 12 point text */
2703
#define OLDTXT14P 5 /* 14 point text */
2704
#define OLDTXT16P 6 /* 16 point text */
2705
#define OLDTXT18P 7 /* 18 point text */
2706
#define OLDTXT20P 8 /* 20 point text */
2707
#define OLDTXTHL 9 /* half-lambda text */
2708
#define OLDTXT1L 10 /* 1-lambda text */
2709
#define OLDTXT2L 11 /* 2-lambda text */
2710
#define OLDTXT3L 12 /* 3-lambda text */
2711
#define OLDTXT4L 13 /* 4-lambda text */
2712
#define OLDTXT5L 14 /* 5-lambda text */
2713
#define OLDTXT6L 15 /* 6-lambda text */
2715
void io_convertalltextdescriptors(INTSML numvar, VARIABLE *firstvar)
2718
REGISTER VARIABLE *var;
2720
for(i=0; i<numvar; i++)
2723
io_converttextdescriptor(var->textdescript);
2727
void io_converttextdescriptor(UINTBIG *descript)
2729
REGISTER INTBIG size;
2731
size = (descript[0]&OLDSIZE) >> OLDSIZESH;
2734
case OLDTXT4P: size = TXTSETPOINTS(4); break;
2735
case OLDTXT6P: size = TXTSETPOINTS(6); break;
2736
case OLDTXT8P: size = TXTSETPOINTS(8); break;
2737
case OLDTXT10P: size = TXTSETPOINTS(10); break;
2738
case OLDTXT12P: size = TXTSETPOINTS(12); break;
2739
case OLDTXT14P: size = TXTSETPOINTS(14); break;
2740
case OLDTXT16P: size = TXTSETPOINTS(16); break;
2741
case OLDTXT18P: size = TXTSETPOINTS(18); break;
2742
case OLDTXT20P: size = TXTSETPOINTS(20); break;
2743
case OLDTXTHL: size = TXTSETQLAMBDA(4/2); break;
2744
case OLDTXT1L: size = TXTSETQLAMBDA(1*4); break;
2745
case OLDTXT2L: size = TXTSETQLAMBDA(2*4); break;
2746
case OLDTXT3L: size = TXTSETQLAMBDA(3*4); break;
2747
case OLDTXT4L: size = TXTSETQLAMBDA(4*4); break;
2748
case OLDTXT5L: size = TXTSETQLAMBDA(5*4); break;
2749
case OLDTXT6L: size = TXTSETQLAMBDA(6*4); break;
2751
descript[0] &= ~OLDSIZE;
2752
descript[1] = size << VTSIZESH;
2755
void io_fixupnodeinst(NODEINST *ni, INTBIG dlx, INTBIG dly, INTBIG dhx, INTBIG dhy)
2757
REGISTER PORTARCINST *pi;
2758
REGISTER ARCINST *ai;
2760
for(pi = ni->firstportarcinst; pi != NOPORTARCINST; pi = pi->nextportarcinst)
2762
ai = pi->conarcinst;
2763
(void)(*el_curconstraint->setobject)((INTBIG)ai, VARCINST, CHANGETYPETEMPUNRIGID, 0);
2765
modifynodeinst(ni, dlx, dly, dhx, dhy, 0, 0);
2768
void io_convertallrelativetext(INTSML numvar, VARIABLE *firstvar)
2771
REGISTER VARIABLE *var;
2773
for(i=0; i<numvar; i++)
2776
io_convertrelativetext(var->textdescript);
2780
void io_convertrelativetext(UINTBIG *descript)
2782
REGISTER INTBIG size;
2784
size = (descript[0]&OLDSIZE) >> OLDSIZESH;
2785
if (size >= OLDTXT4P && size <= OLDTXT20P) return;
2790
descript[0] = (descript[0] & ~OLDSIZE) | (OLDTXT1L << OLDSIZESH);
2797
descript[0] = (descript[0] & ~OLDSIZE) | (OLDTXT2L << OLDSIZESH);
2802
descript[0] = (descript[0] & ~OLDSIZE) | (OLDTXT3L << OLDSIZESH);
2806
* Routine to convert old primitive names to their proper nodeprotos.
2808
NODEPROTO *io_convertoldprimitives(TECHNOLOGY *tech, char *name)
2810
if (namesame(name, "Cell-Center") == 0) return(gen_facetcenterprim);
2811
if (tech == art_tech)
2813
if (namesame(name, "Message") == 0 ||
2814
namesame(name, "Centered-Message") == 0 ||
2815
namesame(name, "Left-Message") == 0 ||
2816
namesame(name, "Right-Message") == 0) return(gen_invispinprim);
2817
if (namesame(name, "Opened-FarDotted-Polygon") == 0)
2818
return(art_openedthickerpolygonprim);
2820
if (tech == mocmos_tech)
2822
if (namesame(name, "Metal-1-Substrate-Con") == 0)
2823
return(mocmos_metal1nwellprim);
2824
if (namesame(name, "Metal-1-Well-Con") == 0)
2825
return(mocmos_metal1pwellprim);
2827
return(NONODEPROTO);
2831
* Routine to find the version of Electric that generated library "lib" and
2832
* parse it into three fields: the major version number, minor version, and
2833
* a detail version number.
2835
void io_getversion(LIBRARY *lib, INTBIG *major, INTBIG *minor, INTBIG *detail)
2837
REGISTER VARIABLE *var;
2838
INTBIG emajor, eminor, edetail;
2841
var = getval((INTBIG)lib, VLIBRARY, VSTRING, "LIB_former_version");
2842
if (var == NOVARIABLE)
2844
*major = *minor = *detail = 0;
2847
libversion = (char *)var->addr;
2848
parseelectricversion(libversion, major, minor, detail);
2850
/* see if this library is newer than the current version of Electric */
2851
parseelectricversion(el_version, &emajor, &eminor, &edetail);
2852
if (*major > emajor ||
2853
(*major == emajor && *minor > eminor) ||
2854
(*major == emajor && *minor == eminor && *detail > edetail))
2856
ttyputerr(_("Warning: library %s comes from a NEWER version of Electric (%s)"),
2857
lib->libname, libversion);
2861
/* Technology: Lambda Adjustment */
2862
static DIALOGITEM io_techadjlamdialogitems[] =
2864
/* 1 */ {0, {232,220,256,300}, BUTTON, N_("Done")},
2865
/* 2 */ {0, {204,264,220,512}, BUTTON, N_("Use New Size for all Technologies")},
2866
/* 3 */ {0, {204,8,220,256}, BUTTON, N_("Use Current Size for all Technologies")},
2867
/* 4 */ {0, {28,300,128,512}, SCROLL, ""},
2868
/* 5 */ {0, {148,8,164,164}, MESSAGE, N_("Current lambda size:")},
2869
/* 6 */ {0, {148,264,164,416}, MESSAGE, N_("New lambda size:")},
2870
/* 7 */ {0, {148,164,164,256}, MESSAGE, ""},
2871
/* 8 */ {0, {148,416,164,512}, MESSAGE, ""},
2872
/* 9 */ {0, {176,264,192,512}, BUTTON, N_("<< Use New Size in Current Library")},
2873
/* 10 */ {0, {176,8,192,256}, BUTTON, N_("Use Current Size in New Library >>")},
2874
/* 11 */ {0, {80,16,96,292}, MESSAGE, N_("and choose from the actions below.")},
2875
/* 12 */ {0, {8,8,24,508}, MESSAGE, N_("This new library uses different lambda values than existing libraries.")},
2876
/* 13 */ {0, {28,8,44,292}, MESSAGE, N_("You should unify the lambda values.")},
2877
/* 14 */ {0, {60,8,76,292}, MESSAGE, N_("Click on each technology in this list")},
2878
/* 15 */ {0, {136,8,137,512}, DIVIDELINE, ""},
2879
/* 16 */ {0, {112,8,128,284}, MESSAGE, N_("Use 'Check and Repair Libraries' when done.")}
2881
static DIALOG io_techadjlamdialog = {{75,75,340,596}, N_("Lambda Value Adjustment"), 0, 16, io_techadjlamdialogitems};
2883
/* special items for the "lambda adjustment" dialog: */
2884
#define DTLA_USENEWALWAYS 2 /* Use new unit always (button) */
2885
#define DTLA_USECURALWAYS 3 /* Use current unit always (button) */
2886
#define DTLA_TECHLIST 4 /* List of technologies (scroll) */
2887
#define DTLA_CURLAMBDA 7 /* Current lambda value (stat text) */
2888
#define DTLA_NEWLAMBDA 8 /* New lambda value (stat text) */
2889
#define DTLA_USENEW 9 /* Use new unit (button) */
2890
#define DTLA_USECUR 10 /* Use current unit (button) */
2893
* Routine to examine new library "lib" and make sure that the lambda values in it are
2894
* the same as existing libraries/technologies. Automatically adjusts values if possible,
2895
* and prompts the user to help out if necessary.
2897
void io_unifylambdavalues(LIBRARY *lib)
2899
REGISTER TECHNOLOGY *tech, *otech, **techarray;
2900
REGISTER LIBRARY *olib;
2901
REGISTER NODEPROTO *np;
2902
REGISTER NODEINST *ni;
2903
REGISTER ARCINST *ai;
2904
REGISTER INTBIG itemHit, i, count, recompute, newunit, curunit, *newlamarray,
2907
float lambdainmicrons;
2910
/* see if this library has incompatible lambda values */
2911
for(tech = el_technologies; tech != NOTECHNOLOGY; tech = tech->nexttechnology)
2913
if (tech == art_tech) continue;
2914
for(olib = el_curlib; olib != NOLIBRARY; olib = olib->nextlibrary)
2916
if (lib->lambda[tech->techindex] != olib->lambda[tech->techindex])
2919
if (olib != NOLIBRARY) break;
2921
if (tech == NOTECHNOLOGY) return;
2923
/* this library has different values: check usage in this and other libraries */
2924
for(olib = el_curlib; olib != NOLIBRARY; olib = olib->nextlibrary)
2926
olib->temp1 = (INTBIG)emalloc(el_maxtech * (sizeof (NODEPROTO *)), el_tempcluster);
2927
if (olib->temp1 == 0) return;
2928
for(i=0; i<el_maxtech; i++) ((NODEPROTO **)olib->temp1)[i] = NONODEPROTO;
2930
for(olib = el_curlib; olib != NOLIBRARY; olib = olib->nextlibrary)
2932
for(np = olib->firstnodeproto; np != NONODEPROTO; np = np->nextnodeproto)
2934
for(ni = np->firstnodeinst; ni != NONODEINST; ni = ni->nextnodeinst)
2936
if (ni->proto->primindex == 0) continue;
2937
tech = ni->proto->tech;
2938
((NODEPROTO **)olib->temp1)[tech->techindex] = np;
2940
for(ai = np->firstarcinst; ai != NOARCINST; ai = ai->nextarcinst)
2942
tech = ai->proto->tech;
2943
((NODEPROTO **)olib->temp1)[tech->techindex] = np;
2948
/* see if there are inconsistencies that cannot be automatically resolved */
2949
for(tech = el_technologies; tech != NOTECHNOLOGY; tech = tech->nexttechnology)
2951
if (tech == art_tech) continue;
2952
for(olib = el_curlib; olib != NOLIBRARY; olib = olib->nextlibrary)
2954
if (((NODEPROTO **)olib->temp1)[tech->techindex] == NONODEPROTO) continue;
2955
if (((NODEPROTO **)lib->temp1)[tech->techindex] == NONODEPROTO) continue;
2956
if (lib->lambda[tech->techindex] != olib->lambda[tech->techindex])
2959
if (olib != NOLIBRARY) break;
2961
if (tech != NOTECHNOLOGY)
2963
/* get the user to resolve the inconsistencies */
2964
(void)DiaInitDialog(&io_techadjlamdialog);
2965
DiaInitTextDialog(DTLA_TECHLIST, DiaNullDlogList, DiaNullDlogItem,
2966
DiaNullDlogDone, -1, SCSELMOUSE|SCREPORT);
2967
for(tech = el_technologies; tech != NOTECHNOLOGY; tech = tech->nexttechnology)
2969
if (tech == art_tech) continue;
2970
for(olib = el_curlib; olib != NOLIBRARY; olib = olib->nextlibrary)
2972
if (((NODEPROTO **)olib->temp1)[tech->techindex] == NONODEPROTO) continue;
2973
if (((NODEPROTO **)lib->temp1)[tech->techindex] == NONODEPROTO) continue;
2974
if (lib->lambda[tech->techindex] != olib->lambda[tech->techindex])
2977
if (olib == NOLIBRARY) continue;
2978
DiaStuffLine(DTLA_TECHLIST, tech->techname);
2980
DiaSelectLine(DTLA_TECHLIST, 0);
2982
tech = NOTECHNOLOGY;
2989
/* figure out which technology is selected */
2990
i = DiaGetCurLine(DTLA_TECHLIST);
2991
pt = DiaGetScrollLine(DTLA_TECHLIST, i);
2992
for(tech = el_technologies; tech != NOTECHNOLOGY; tech = tech->nexttechnology)
2993
if (namesame(pt, tech->techname) == 0) break;
2994
if (tech == NOTECHNOLOGY) continue;
2996
/* figure out which units are in force */
2997
curunit = newunit = lib->lambda[tech->techindex];
2998
for(olib = el_curlib; olib != NOLIBRARY; olib = olib->nextlibrary)
3000
if ((olib->userbits&HIDDENLIBRARY) != 0) continue;
3001
if (((NODEPROTO **)olib->temp1)[tech->techindex] == NONODEPROTO) continue;
3002
if (((NODEPROTO **)olib->temp1)[tech->techindex] == 0) continue;
3003
if (olib->lambda[tech->techindex] != lib->lambda[tech->techindex]) break;
3005
if (olib != NOLIBRARY) curunit = olib->lambda[tech->techindex];
3007
/* see if it has already been overridden */
3008
if (((INTBIG *)lib->temp1)[tech->techindex] == 0) newunit = curunit;
3010
/* set dialog values and offer choices */
3011
lambdainmicrons = scaletodispunit(curunit, DISPUNITMIC);
3012
sprintf(line, "%gu", lambdainmicrons);
3013
DiaSetText(DTLA_CURLAMBDA, line);
3014
lambdainmicrons = scaletodispunit(newunit, DISPUNITMIC);
3015
sprintf(line, "%gu", lambdainmicrons);
3016
DiaSetText(DTLA_NEWLAMBDA, line);
3017
if (newunit == curunit)
3019
DiaDimItem(DTLA_USENEW);
3020
DiaDimItem(DTLA_USECUR);
3023
DiaUnDimItem(DTLA_USENEW);
3024
DiaUnDimItem(DTLA_USECUR);
3027
itemHit = DiaNextHit();
3028
if (itemHit == OK) break;
3029
if (itemHit == DTLA_TECHLIST) recompute = 1;
3030
if (itemHit == DTLA_USENEW)
3033
if (tech != NOTECHNOLOGY)
3035
for(olib = el_curlib; olib != NOLIBRARY; olib = olib->nextlibrary)
3037
if ((olib->userbits&HIDDENLIBRARY) != 0) continue;
3038
if (((NODEPROTO **)olib->temp1)[tech->techindex] == NONODEPROTO) continue;
3039
((NODEPROTO **)olib->temp1)[tech->techindex] = 0;
3045
if (itemHit == DTLA_USENEWALWAYS)
3047
/* use new unit always */
3048
for(otech = el_technologies; otech != NOTECHNOLOGY; otech = otech->nexttechnology)
3050
for(olib = el_curlib; olib != NOLIBRARY; olib = olib->nextlibrary)
3052
if ((olib->userbits&HIDDENLIBRARY) != 0) continue;
3053
if (((NODEPROTO **)olib->temp1)[otech->techindex] == NONODEPROTO) continue;
3054
((NODEPROTO **)olib->temp1)[otech->techindex] = 0;
3058
DiaDimItem(DTLA_USECURALWAYS);
3059
DiaDimItem(DTLA_USENEWALWAYS);
3062
if (itemHit == DTLA_USECURALWAYS)
3064
/* use current unit always */
3065
for(otech = el_technologies; otech != NOTECHNOLOGY; otech = otech->nexttechnology)
3066
((NODEPROTO **)lib->temp1)[otech->techindex] = 0;
3068
DiaDimItem(DTLA_USECURALWAYS);
3069
DiaDimItem(DTLA_USENEWALWAYS);
3072
if (itemHit == DTLA_USECUR)
3074
/* use current unit */
3075
if (tech != NOTECHNOLOGY) ((NODEPROTO **)lib->temp1)[tech->techindex] = 0;
3083
/* adjust lambda values in old libraries to match this one */
3084
for(olib = el_curlib; olib != NOLIBRARY; olib = olib->nextlibrary)
3086
if (olib == lib) continue;
3088
/* see how many technologies are affected */
3090
for(tech = el_technologies; tech != NOTECHNOLOGY; tech = tech->nexttechnology)
3092
if (((NODEPROTO **)lib->temp1)[tech->techindex] == NONODEPROTO) continue;
3093
if (((NODEPROTO **)lib->temp1)[tech->techindex] == 0) continue;
3094
if (lib->lambda[tech->techindex] == olib->lambda[tech->techindex]) continue;
3097
if (count == 0) continue;
3099
/* adjust this library */
3100
techarray = (TECHNOLOGY **)emalloc(count * (sizeof (TECHNOLOGY *)), el_tempcluster);
3101
if (techarray == 0) return;
3102
newlamarray = (INTBIG *)emalloc(count * SIZEOFINTBIG, el_tempcluster);
3103
if (newlamarray == 0) return;
3105
for(tech = el_technologies; tech != NOTECHNOLOGY; tech = tech->nexttechnology)
3107
if (((NODEPROTO **)lib->temp1)[tech->techindex] == NONODEPROTO) continue;
3108
if (((NODEPROTO **)lib->temp1)[tech->techindex] == 0) continue;
3109
if (lib->lambda[tech->techindex] == olib->lambda[tech->techindex]) continue;
3110
techarray[count] = tech;
3111
newlamarray[count] = lib->lambda[tech->techindex];
3114
oldbits = olib->userbits;
3115
changelambda(count, techarray, newlamarray, olib, 1);
3116
olib->userbits = (olib->userbits & ~LIBCHANGEDMAJOR) |
3117
(oldbits & LIBCHANGEDMAJOR);
3118
efree((char *)techarray);
3119
efree((char *)newlamarray);
3122
/* change lambda values in this library to match old ones */
3124
for(tech = el_technologies; tech != NOTECHNOLOGY; tech = tech->nexttechnology)
3126
for(olib = el_curlib; olib != NOLIBRARY; olib = olib->nextlibrary)
3128
if (((NODEPROTO **)olib->temp1)[tech->techindex] == NONODEPROTO) continue;
3129
if (((NODEPROTO **)olib->temp1)[tech->techindex] == 0) continue;
3130
if (lib->lambda[tech->techindex] != olib->lambda[tech->techindex])
3133
if (olib == NOLIBRARY) continue;
3138
/* adjust new library */
3139
techarray = (TECHNOLOGY **)emalloc(count * (sizeof (TECHNOLOGY *)), el_tempcluster);
3140
if (techarray == 0) return;
3141
newlamarray = (INTBIG *)emalloc(count * SIZEOFINTBIG, el_tempcluster);
3142
if (newlamarray == 0) return;
3144
for(tech = el_technologies; tech != NOTECHNOLOGY; tech = tech->nexttechnology)
3146
for(olib = el_curlib; olib != NOLIBRARY; olib = olib->nextlibrary)
3148
if (((NODEPROTO **)olib->temp1)[tech->techindex] == NONODEPROTO) continue;
3149
if (((NODEPROTO **)olib->temp1)[tech->techindex] == 0) continue;
3150
if (lib->lambda[tech->techindex] != olib->lambda[tech->techindex])
3153
if (olib == NOLIBRARY) continue;
3154
techarray[count] = tech;
3155
newlamarray[count] = olib->lambda[tech->techindex];
3158
changelambda(count, techarray, newlamarray, lib, 1);
3159
efree((char *)techarray);
3160
efree((char *)newlamarray);
3163
/* free memory used here */
3164
for(olib = el_curlib; olib != NOLIBRARY; olib = olib->nextlibrary)
3165
efree((char *)olib->temp1);
3168
/****************************** LIBRARY OPTIONS DIALOG ******************************/
3170
/* Library: Options */
3171
static DIALOGITEM io_liboptdialogitems[] =
3173
/* 1 */ {0, {124,148,148,228}, BUTTON, N_("OK")},
3174
/* 2 */ {0, {124,16,148,96}, BUTTON, N_("Cancel")},
3175
/* 3 */ {0, {8,8,24,236}, RADIO, N_("No backup of library files")},
3176
/* 4 */ {0, {32,8,48,236}, RADIO, N_("Backup of last library file")},
3177
/* 5 */ {0, {56,8,72,236}, RADIO, N_("Backup history of library files")},
3178
/* 6 */ {0, {92,8,108,236}, CHECK, N_("Check database after write")}
3180
static DIALOG io_liboptdialog = {{75,75,232,320}, N_("Library Options"), 0, 6, io_liboptdialogitems};
3182
/* special items for the "library options" dialog: */
3183
#define DLBO_NOBACKUP 3 /* no backup (radio) */
3184
#define DLBO_ONEBACKUP 4 /* backup one level (radio) */
3185
#define DLBO_FULLBACKUP 5 /* backup history (radio) */
3186
#define DLBO_CHECKAFTERWRITE 6 /* check after write (check) */
3188
void io_libraryoptiondlog(void)
3190
INTBIG itemHit, i, *origstate, curstate[NUMIOSTATEBITWORDS];
3192
/* display the library paths dialog box */
3193
if (DiaInitDialog(&io_liboptdialog)) return;
3195
/* get current state of I/O tool */
3196
origstate = io_getstatebits();
3197
for(i=0; i<NUMIOSTATEBITWORDS; i++) curstate[i] = origstate[i];
3198
switch (curstate[0]&BINOUTBACKUP)
3200
case BINOUTNOBACK: DiaSetControl(DLBO_NOBACKUP, 1); break;
3201
case BINOUTONEBACK: DiaSetControl(DLBO_ONEBACKUP, 1); break;
3202
case BINOUTFULLBACK: DiaSetControl(DLBO_FULLBACKUP, 1); break;
3204
if ((curstate[0]&CHECKATWRITE) != 0) DiaSetControl(DLBO_CHECKAFTERWRITE, 1);
3206
/* loop until done */
3209
itemHit = DiaNextHit();
3210
if (itemHit == OK || itemHit == CANCEL) break;
3211
if (itemHit == DLBO_NOBACKUP || itemHit == DLBO_ONEBACKUP ||
3212
itemHit == DLBO_FULLBACKUP)
3214
DiaSetControl(DLBO_NOBACKUP, 0);
3215
DiaSetControl(DLBO_ONEBACKUP, 0);
3216
DiaSetControl(DLBO_FULLBACKUP, 0);
3217
DiaSetControl(itemHit, 1);
3220
if (itemHit == DLBO_CHECKAFTERWRITE)
3222
DiaSetControl(itemHit, 1 - DiaGetControl(itemHit));
3227
if (itemHit != CANCEL)
3229
curstate[0] &= ~(BINOUTBACKUP|CHECKATWRITE);
3230
if (DiaGetControl(DLBO_ONEBACKUP) != 0) curstate[0] |= BINOUTONEBACK; else
3231
if (DiaGetControl(DLBO_FULLBACKUP) != 0) curstate[0] |= BINOUTFULLBACK;
3232
if (DiaGetControl(DLBO_CHECKAFTERWRITE) != 0) curstate[0] |= CHECKATWRITE;
3233
for(i=0; i<NUMIOSTATEBITWORDS; i++)
3234
if (curstate[i] != origstate[i]) break;
3235
if (i < NUMIOSTATEBITWORDS)
3236
io_setstatebits(curstate);
3242
static DIALOGITEM io_cdloptdialogitems[] =
3244
/* 1 */ {0, {100,236,124,316}, BUTTON, N_("OK")},
3245
/* 2 */ {0, {100,64,124,144}, BUTTON, N_("Cancel")},
3246
/* 3 */ {0, {8,8,24,184}, MESSAGE, N_("Cadence Library Name:")},
3247
/* 4 */ {0, {8,187,24,363}, EDITTEXT, ""},
3248
/* 5 */ {0, {32,8,48,184}, MESSAGE, N_("Cadence Library Path:")},
3249
/* 6 */ {0, {32,187,64,363}, EDITTEXT, ""},
3250
/* 7 */ {0, {72,8,88,176}, CHECK, N_("Convert brackets")}
3252
static DIALOG io_cdloptdialog = {{75,75,208,447}, N_("CDL Options"), 0, 7, io_cdloptdialogitems};
3254
/* special items for the "CDL Options" dialog: */
3255
#define DCDL_LIBNAME 4 /* Cadence Library Name (edit text) */
3256
#define DCDL_LIBPATH 6 /* Cadence Library Path (edit text) */
3257
#define DCDL_CONVBRACKET 7 /* Convert brackets (check) */
3260
* Routine to run the CDL Options dialog.
3262
void io_cdloptionsdialog(void)
3264
INTBIG i, itemHit, *curstate, newstate[NUMIOSTATEBITWORDS];
3265
REGISTER VARIABLE *var;
3266
REGISTER char *inilibname, *inilibpath;
3267
BOOLEAN libnamechanged, libpathchanged;
3269
if (DiaInitDialog(&io_cdloptdialog)) return;
3270
var = getval((INTBIG)io_tool, VTOOL, VSTRING, "IO_cdl_library_name");
3271
if (var == NOVARIABLE) inilibname = ""; else
3272
inilibname = (char *)var->addr;
3273
DiaSetText(DCDL_LIBNAME, inilibname);
3274
var = getval((INTBIG)io_tool, VTOOL, VSTRING, "IO_cdl_library_path");
3275
if (var == NOVARIABLE) inilibpath = ""; else
3276
inilibpath = (char *)var->addr;
3277
DiaSetText(DCDL_LIBPATH, inilibpath);
3278
curstate = io_getstatebits();
3279
if ((curstate[1]&CDLNOBRACKETS) != 0) DiaSetControl(DCDL_CONVBRACKET, 1);
3281
libnamechanged = libpathchanged = FALSE;
3284
itemHit = DiaNextHit();
3285
if (itemHit == OK || itemHit == CANCEL) break;
3286
if (itemHit == DCDL_CONVBRACKET)
3288
DiaSetControl(itemHit, 1 - DiaGetControl(itemHit));
3291
if (itemHit == DCDL_LIBNAME)
3293
if (strcmp(inilibname, DiaGetText(DCDL_LIBNAME)) != 0)
3294
libnamechanged = TRUE;
3297
if (itemHit == DCDL_LIBPATH)
3299
if (strcmp(inilibpath, DiaGetText(DCDL_LIBPATH)) != 0)
3300
libpathchanged = TRUE;
3306
if (libnamechanged != 0)
3308
(void)setval((INTBIG)io_tool, VTOOL, "IO_cdl_library_name",
3309
(INTBIG)DiaGetText(DCDL_LIBNAME), VSTRING);
3311
if (libpathchanged != 0)
3313
(void)setval((INTBIG)io_tool, VTOOL, "IO_cdl_library_path",
3314
(INTBIG)DiaGetText(DCDL_LIBPATH), VSTRING);
3316
for(i=0; i<NUMIOSTATEBITWORDS; i++) newstate[i] = curstate[i];
3317
if (DiaGetControl(DCDL_CONVBRACKET) != 0) newstate[1] |= CDLNOBRACKETS; else
3318
newstate[1] &= ~CDLNOBRACKETS;
3319
for(i=0; i<NUMIOSTATEBITWORDS; i++) if (curstate[i] != newstate[i]) break;
3320
if (i < NUMIOSTATEBITWORDS) io_setstatebits(newstate);
3329
BOOLEAN uppertriangle;
3332
char *defaultstring;
3334
} io_techlayervariables[] =
3336
{"IO_cif_layer_names", N_("CIF Layer Names"), FALSE, 0, 0, "", 0.0},
3337
{"IO_dxf_layer_names", N_("DXF Layer Names"), FALSE, 0, 0, "", 0.0},
3338
{"IO_gds_layer_numbers", N_("GDS Layer Numbers"), FALSE, 0, -1, "", 0.0},
3339
{"IO_skill_layer_names", N_("SKILL Layer Names"), FALSE, 0, 0, "", 0.0},
3340
{"SIM_spice_resistance", N_("SPICE Layer Resistances"), FALSE, 0, 0, "", 0.0},
3341
{"SIM_spice_capacitance", N_("SPICE Layer Capacitances"), FALSE, 0, 0, "", 0.0},
3342
{"DRC_min_unconnected_distances", N_("Unconnected Design Rule spacings"), TRUE, 0, -WHOLE, "", 0.0},
3343
{"DRC_min_connected_distances", N_("Connected Design Rule spacings"), TRUE, 0, -WHOLE, "", 0.0},
3344
{"DRC_min_unconnected_distances_wide", N_("Wide Unconnected Design Rule spacings"), TRUE, 0, -WHOLE, "", 0.0},
3345
{"DRC_min_connected_distances_wide", N_("Wide Connected Design Rule spacings"), TRUE, 0, -WHOLE, "", 0.0},
3346
{0, 0, FALSE, 0, 0, "", 0.0}
3350
* this table rearranges the MOSIS CMOS Submicron layer tables from
3351
* their old 4-layer metal (34 layers) to 6-layer metal (40 layers)
3353
static INTBIG tech_mocmossubarrange[] =
3355
0, 1, 2, 3, 6, 7, 8, 9, 10, 11,
3356
12, 13, 14, 15, 16, 17, 18, 21, 22, 23,
3357
24, 25, 26, 27, 28, 31, 32, 33, 34, 35,
3364
INTBIG oldlayercount, newlayercount;
3365
INTBIG *arrangement;
3366
} io_techlayerfixes[] =
3368
"mocmossub", 34, 40, tech_mocmossubarrange,
3369
"mocmos", 34, 40, tech_mocmossubarrange,
3373
void io_fixtechlayers(void)
3375
REGISTER INTBIG i, j, k, l, l1, l2, oldpos, newpos, newl1, newl2, *newints;
3376
REGISTER float *newfloats;
3377
REGISTER char **newstrings;
3378
REGISTER TECHNOLOGY *tech;
3379
REGISTER VARIABLE *var;
3381
for(tech = el_technologies; tech != NOTECHNOLOGY; tech = tech->nexttechnology)
3383
for(i=0; io_techlayervariables[i].variable != 0; i++)
3385
if (io_techlayervariables[i].key == 0)
3386
io_techlayervariables[i].key = makekey(io_techlayervariables[i].variable);
3387
var = getvalkey((INTBIG)tech, VTECHNOLOGY, -1, io_techlayervariables[i].key);
3388
if (var == NOVARIABLE) continue;
3389
if (io_techlayervariables[i].uppertriangle)
3391
l = tech->layercount;
3392
if (getlength(var) == (l * l + l) / 2) continue;
3395
if (getlength(var) == tech->layercount) continue;
3398
/* layers are inconsistent: see if there are rules to fix it */
3399
for(j=0; io_techlayerfixes[j].techname != 0; j++)
3401
if (namesame(tech->techname, io_techlayerfixes[j].techname) != 0) continue;
3402
if (io_techlayervariables[i].uppertriangle)
3404
l = io_techlayerfixes[j].oldlayercount;
3405
if ((l*l+l)/2 != getlength(var)) continue;
3408
if (io_techlayerfixes[j].oldlayercount != getlength(var)) continue;
3410
if (io_techlayerfixes[j].newlayercount != tech->layercount) continue;
3413
if (io_techlayerfixes[j].techname != 0)
3415
if (io_techlayervariables[i].uppertriangle)
3417
k = tech->layercount;
3419
newints = (INTBIG *)emalloc(l * SIZEOFINTBIG, tech->cluster);
3421
newints[k] = io_techlayervariables[i].defaultint;
3422
for(l1=0; l1<io_techlayerfixes[j].oldlayercount; l1++)
3424
for(l2=l1; l2<io_techlayerfixes[j].oldlayercount; l2++)
3426
oldpos = (l1+1) * (l1/2) + (l1&1) * ((l1+1)/2);
3427
oldpos = l2 + io_techlayerfixes[j].oldlayercount * l1 - oldpos;
3428
newl1 = io_techlayerfixes[j].arrangement[l1];
3429
newl2 = io_techlayerfixes[j].arrangement[l2];
3430
newpos = (newl1+1) * (newl1/2) + (newl1&1) * ((newl1+1)/2);
3431
newpos = newl2 + tech->layercount * newl1 - newpos;
3432
newints[newpos] = ((INTBIG *)var->addr)[oldpos];
3435
(void)setvalkey((INTBIG)tech, VTECHNOLOGY, io_techlayervariables[i].key,
3436
(INTBIG)newints, (var->type&VTYPE)|VISARRAY|(l<<VLENGTHSH));
3437
efree((char *)newints);
3440
/* able to fix the ordering */
3441
if ((var->type&VTYPE) == VSTRING)
3443
newstrings = (char **)emalloc(tech->layercount * (sizeof (char *)),
3445
for(k=0; k<tech->layercount; k++)
3446
newstrings[k] = io_techlayervariables[i].defaultstring;
3447
for(k=0; k<getlength(var); k++)
3448
newstrings[io_techlayerfixes[j].arrangement[k]] =
3449
((char **)var->addr)[k];
3450
(void)setvalkey((INTBIG)tech, VTECHNOLOGY, io_techlayervariables[i].key,
3451
(INTBIG)newstrings, (var->type&VTYPE)|VISARRAY|(tech->layercount<<VLENGTHSH));
3452
efree((char *)newstrings);
3453
} else if ((var->type&VTYPE) == VFLOAT)
3455
newfloats = (float *)emalloc(tech->layercount * (sizeof (float)),
3457
for(k=0; k<tech->layercount; k++)
3458
newfloats[k] = io_techlayervariables[i].defaultfloat;
3459
for(k=0; k<getlength(var); k++)
3460
newfloats[io_techlayerfixes[j].arrangement[k]] =
3461
((float *)var->addr)[k];
3462
(void)setvalkey((INTBIG)tech, VTECHNOLOGY, io_techlayervariables[i].key,
3463
(INTBIG)newfloats, (var->type&VTYPE)|VISARRAY|(tech->layercount<<VLENGTHSH));
3464
efree((char *)newfloats);
3467
newints = (INTBIG *)emalloc(tech->layercount * SIZEOFINTBIG,
3469
for(k=0; k<tech->layercount; k++)
3470
newints[k] = io_techlayervariables[i].defaultint;
3471
for(k=0; k<getlength(var); k++)
3472
newints[io_techlayerfixes[j].arrangement[k]] =
3473
((INTBIG *)var->addr)[k];
3474
(void)setvalkey((INTBIG)tech, VTECHNOLOGY, io_techlayervariables[i].key,
3475
(INTBIG)newints, (var->type&VTYPE)|VISARRAY|(tech->layercount<<VLENGTHSH));
3476
efree((char *)newints);
3482
/* unable to fix: issue a warning */
3483
ttyputmsg(_("Warning: %s in technology %s are inconsistent"),
3484
_(io_techlayervariables[i].meaning), tech->techname);
3489
void io_fixrtree(RTNODE *rtree)
3492
REGISTER GEOM *geom;
3493
REGISTER RTNODE *subrt;
3495
if (rtree->total <= 0) return;
3496
if (rtree->flag != 0)
3498
geom = (GEOM *)rtree->pointers[0];
3499
rtree->lowx = geom->lowx; rtree->highx = geom->highx;
3500
rtree->lowy = geom->lowy; rtree->highy = geom->highy;
3501
for(i=1; i<rtree->total; i++)
3503
geom = (GEOM *)rtree->pointers[i];
3504
if (geom->lowx < rtree->lowx) rtree->lowx = geom->lowx;
3505
if (geom->highx > rtree->highx) rtree->highx = geom->highx;
3506
if (geom->lowy < rtree->lowy) rtree->lowy = geom->lowy;
3507
if (geom->highy > rtree->highy) rtree->highy = geom->highy;
3511
subrt = (RTNODE *)rtree->pointers[0];
3513
rtree->lowx = subrt->lowx; rtree->highx = subrt->highx;
3514
rtree->lowy = subrt->lowy; rtree->highy = subrt->highy;
3515
for(i=1; i<rtree->total; i++)
3517
subrt = (RTNODE *)rtree->pointers[i];
3519
if (subrt->lowx < rtree->lowx) rtree->lowx = subrt->lowx;
3520
if (subrt->highx > rtree->highx) rtree->highx = subrt->highx;
3521
if (subrt->lowy < rtree->lowy) rtree->lowy = subrt->lowy;
3522
if (subrt->highy > rtree->highy) rtree->highy = subrt->highy;
3528
* routine to convert port names that have changed (specifically those
3529
* in the Schematics technology). Given the port name on a node proto,
3530
* returns the correct port (or NOPORTPROTO if not known).
3532
PORTPROTO *io_convertoldportname(char *portname, NODEPROTO *np)
3534
if (np->primindex == 0) return(NOPORTPROTO);
3535
if (np == sch_sourceprim || np == sch_meterprim)
3537
if (namesame(portname, "top") == 0)
3538
return(np->firstportproto);
3539
if (namesame(portname, "bottom") == 0)
3540
return(np->firstportproto->nextportproto);
3542
if (np == sch_twoportprim)
3544
if (namesame(portname, "upperleft") == 0)
3545
return(np->firstportproto);
3546
if (namesame(portname, "lowerleft") == 0)
3547
return(np->firstportproto->nextportproto);
3548
if (namesame(portname, "upperright") == 0)
3549
return(np->firstportproto->nextportproto->nextportproto);
3550
if (namesame(portname, "lowerright") == 0)
3551
return(np->firstportproto->nextportproto->nextportproto->nextportproto);
3553
return(NOPORTPROTO);
3557
* Routine to determine the area of facet "np" that is to be printed.
3558
* Returns true if the area cannot be determined.
3560
BOOLEAN io_getareatoprint(NODEPROTO *np, INTBIG *lx, INTBIG *hx, INTBIG *ly, INTBIG *hy, BOOLEAN reduce)
3562
REGISTER INTBIG wid, hei, *curstate;
3563
INTBIG hlx, hhx, hly, hhy;
3564
REGISTER NODEPROTO *onp;
3566
curstate = io_getstatebits();
3567
us_fullview(np, lx, hx, ly, hy);
3569
/* extend it and make it square */
3574
*lx -= wid/8; *hx += wid/8;
3575
*ly -= hei/8; *hy += hei/8;
3576
us_squarescreen(el_curwindowpart, NOWINDOWPART, FALSE, lx, hx, ly, hy, 0);
3579
if ((curstate[0]&PLOTFOCUS) != 0)
3581
if ((curstate[0]&PLOTFOCUSDPY) != 0)
3583
*lx = el_curwindowpart->screenlx;
3584
*hx = el_curwindowpart->screenhx;
3585
*ly = el_curwindowpart->screenly;
3586
*hy = el_curwindowpart->screenhy;
3589
onp = (NODEPROTO *)asktool(us_tool, "get-highlighted-area",
3590
(INTBIG)&hlx, (INTBIG)&hhx, (INTBIG)&hly, (INTBIG)&hhy);
3591
if (onp == NONODEPROTO)
3592
ttyputerr(_("Warning: no highlighted area; printing entire facet")); else
3594
if (hhx == hlx || hhy == hly)
3596
ttyputerr(_("Warning: no highlighted area; highlight area and reissue command"));
3599
*lx = hlx; *hx = hhx;
3600
*ly = hly; *hy = hhy;
3607
/******************** LAYER ORDERING FOR GRAPHIC COPY/PRINT ********************/
3609
INTBIG io_setuptechorder(TECHNOLOGY *tech)
3611
REGISTER INTBIG i, j, k, l, m, *neworder, newamount;
3612
REGISTER INTBIG *layers;
3613
INTBIG order[LFNUMLAYERS];
3614
REGISTER VARIABLE *var;
3616
/* determine order of overlappable layers in current technology */
3618
i = tech->layercount;
3619
var = getval((INTBIG)tech, VTECHNOLOGY, VINTEGER|VISARRAY,
3620
"TECH_layer_function");
3621
if (var != NOVARIABLE)
3623
layers = (INTBIG *)var->addr;
3624
for(j=0; j<LFNUMLAYERS; j++)
3625
order[j] = layerfunctionheight(j);
3626
for(j=0; j<LFNUMLAYERS; j++)
3628
for(k=0; k<LFNUMLAYERS; k++)
3630
if (order[k] != j) continue;
3633
if ((layers[l]&LFTYPE) != k) continue;
3634
if (io_maxlayers >= io_mostlayers)
3636
newamount = io_mostlayers * 2;
3637
if (newamount <= 0) newamount = 10;
3638
if (newamount < io_maxlayers) newamount = io_maxlayers;
3639
neworder = (INTBIG *)emalloc(newamount * SIZEOFINTBIG, io_tool->cluster);
3640
if (neworder == 0) return(io_maxlayers);
3641
for(m=0; m<io_maxlayers; m++)
3642
neworder[m] = io_overlaporder[m];
3643
if (io_mostlayers > 0) efree((char *)io_overlaporder);
3644
io_overlaporder = neworder;
3645
io_mostlayers = newamount;
3647
io_overlaporder[io_maxlayers++] = l;
3653
return(io_maxlayers);
3657
* Routine to return the layer in plotting position "i" (from 0 to the value returned
3658
* by "io_setuptechorder" - 1).
3660
INTBIG io_nextplotlayer(INTBIG i)
3662
return(io_overlaporder[i]);
3665
/******************** MATH HELPERS ********************/
3668
* This routine is used by "ioedifo.c" and "routmaze.c".
3670
void io_compute_center(INTBIG xc, INTBIG yc, INTBIG x1, INTBIG y1,
3671
INTBIG x2, INTBIG y2, INTBIG *cx, INTBIG *cy)
3673
int r, dx, dy, a1, a2, a;
3674
double pie, theta, radius, Dx, Dy;
3676
/* reconstruct angles to p1 and p2 */
3679
radius = sqrt(Dx * Dx + Dy * Dy);
3680
r = rounddouble(radius);
3681
a1 = (int)io_calc_angle(r, (double)(x1 - xc), (double)(y1 - yc));
3682
a2 = (int)io_calc_angle(r, (double)(x2 - xc), (double)(y2 - yc));
3683
if (a1 < a2) a1 += 3600;
3686
theta = (double) a *pie / 1800.0; /* in radians */
3687
Dx = radius * cos(theta);
3688
Dy = radius * sin(theta);
3689
dx = rounddouble(Dx);
3690
dy = rounddouble(Dy);
3695
double io_calc_angle(double r, double dx, double dy)
3697
double ratio, a1, a2;
3699
ratio = 1800.0 / EPI;
3700
a1 = acos(dx/r) * ratio;
3701
a2 = asin(dy/r) * ratio;
3702
if (a2 < 0.0) return(3600.0 - a1);