~ubuntu-branches/ubuntu/utopic/electric/utopic-proposed

« back to all changes in this revision

Viewing changes to src/io/io.c

  • Committer: Bazaar Package Importer
  • Author(s): Onkar Shinde
  • Date: 2008-07-23 02:09:53 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20080723020953-1gmnv7q2wpsdbnop
Tags: 8.07-0ubuntu1
* New Upstream version. Please check changelog for details. (LP: #242720)
* debian/control
  - Add build dependencies *-jdk, cdbs and bsh.
  - Remove build dependency dpatch. We will be using CDBS simple patchsys.
  - Refreshed runtime dependencies to default-jre | java2-runtime and bsh.
  - Added home page field.
  - Standard version 3.8.0.
  - Modify Maintainer value to match the DebianMaintainerField
    specification.
  - Changed email address for original maintainer to indicate who has
    refreshed the packaging.
* debian/rules
  - Revamped to use cdbs.
  - Added get-orig-source target.
* debian/patches
  - 00list, 02_sensible-browser.dpatch, 01_errors-numbers.dpatch,
    03_manpage.dpatch - Deleted, not relevant anymore.
  - 01_fix_build_xml.patch - Patch to fix the build.xml.
* debian/ant.properties
  - File to set various compilation properties.
* debian/electric.1
  - Remove the entry that causes lintian warning.
* debian/electric.desktop
  - Change as suggested by desktop-file-validate.
* debian/electric.docs
  - Updated as per changes in file names.
* debian/electric.svg
  - Name changed from electric_icon.svg.
* debian/install
  - Added appropriate locations for jar file, desktop file and wrapper shell
    script.
* debian/README.source
  - Added to comply with standards version 3.8.0.
* debian/TODO.Debian
  - Name changed form TODO.
* debain/wrapper/electric
  - Wrapper shell script to launch the application.
* debian/manpages
  - Added for installation of manpage.
* debian/watch
  - Updated to match jar files instead of older tar.gz files.
* debian/dirs
  - Removed, not needed anymore.
* debian/{electric.doc-base, electric.examples, substvars}
  - Removed, not relevant anymore.
* debian/*.debhelper
  - Removed auto generated files. Not relevant anymore.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * Electric(tm) VLSI Design System
3
 
 *
4
 
 * File: io.c
5
 
 * Input/output tool: controller module
6
 
 * Written by: Steven M. Rubin, Static Free Software
7
 
 *
8
 
 * Copyright (c) 2000 Static Free Software.
9
 
 *
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.
14
 
 *
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.
19
 
 *
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.
24
 
 *
25
 
 * Static Free Software
26
 
 * 4119 Alpine Road
27
 
 * Portola Valley, California 94028
28
 
 * info@staticfreesoft.com
29
 
 */
30
 
 
31
 
#include "global.h"
32
 
#include "database.h"
33
 
#include "conlay.h"
34
 
#include "egraphics.h"
35
 
#include "efunction.h"
36
 
#include "dbcontour.h"
37
 
#include "eio.h"
38
 
#include "usr.h"
39
 
#include "drc.h"
40
 
#include "network.h"
41
 
#include "usredtec.h"
42
 
#include "edialogs.h"
43
 
#include "tecart.h"
44
 
#include "tecschem.h"
45
 
#include "tecgen.h"
46
 
#include "tecmocmos.h"
47
 
#include <math.h>
48
 
 
49
 
/* the command parsing table */
50
 
#if IOCIF
51
 
static KEYWORD iocifoopt[] =
52
 
{
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}},
66
 
        TERMKEY
67
 
};
68
 
COMCOMP io_cifop = {iocifoopt,NOTOPLIST,NONEXTLIST,NOPARAMS,NOBACKUP,
69
 
        INPUTOPT, " \t", M_("style of CIF output"), 0};
70
 
static KEYWORD iocifiopt[] =
71
 
{
72
 
        {"rounded-wires",    0,{NOKEY,NOKEY,NOKEY,NOKEY,NOKEY}},
73
 
        {"squared-wires",    0,{NOKEY,NOKEY,NOKEY,NOKEY,NOKEY}},
74
 
        TERMKEY
75
 
};
76
 
static COMCOMP iocifip = {iocifiopt,NOTOPLIST,NONEXTLIST,NOPARAMS,NOBACKUP,
77
 
        INPUTOPT, " \t", M_("style of CIF input"), 0};
78
 
static KEYWORD iocifopt[] =
79
 
{
80
 
        {"input",     1,{&iocifip,NOKEY,NOKEY,NOKEY,NOKEY}},
81
 
        {"output",    1,{&io_cifop,NOKEY,NOKEY,NOKEY,NOKEY}},
82
 
        TERMKEY
83
 
};
84
 
COMCOMP io_cifp = {iocifopt,NOTOPLIST,NONEXTLIST,NOPARAMS,NOBACKUP,
85
 
        INPUTOPT, " \t", M_("control of CIF"), 0};
86
 
#endif
87
 
 
88
 
#if IODXF
89
 
static KEYWORD iodxfaopt[] =
90
 
{
91
 
        {"all",                  0,{NOKEY,NOKEY,NOKEY,NOKEY,NOKEY}},
92
 
        {"restrict",             0,{NOKEY,NOKEY,NOKEY,NOKEY,NOKEY}},
93
 
        TERMKEY
94
 
};
95
 
static COMCOMP iodxfap = {iodxfaopt,NOTOPLIST,NONEXTLIST,NOPARAMS,NOBACKUP,
96
 
        INPUTOPT, " \t", M_("DXF layer restriction options"), 0};
97
 
static KEYWORD iodxfopt[] =
98
 
{
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}},
102
 
        TERMKEY
103
 
};
104
 
COMCOMP io_dxfp = {iodxfopt,NOTOPLIST,NONEXTLIST,NOPARAMS,NOBACKUP,
105
 
        INPUTOPT, " \t", M_("DXF options"), 0};
106
 
#endif
107
 
 
108
 
#if IOGDS
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[] =
114
 
{
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}},
121
 
        TERMKEY
122
 
};
123
 
static COMCOMP iogdsop = {iogdsoopt,NOTOPLIST,NONEXTLIST,NOPARAMS,NOBACKUP,
124
 
        INPUTOPT, " \t", M_("style of GDS output"), 0};
125
 
static KEYWORD iogdsiopt[] =
126
 
{
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}},
135
 
        TERMKEY
136
 
};
137
 
static COMCOMP iogdsiop = {iogdsiopt,NOTOPLIST,NONEXTLIST,NOPARAMS,NOBACKUP,
138
 
        INPUTOPT, " \t", M_("style of GDS input"), 0};
139
 
static KEYWORD iogdsopt[] =
140
 
{
141
 
        {"output",   1,{&iogdsop,NOKEY,NOKEY,NOKEY,NOKEY}},
142
 
        {"input",    1,{&iogdsiop,NOKEY,NOKEY,NOKEY,NOKEY}},
143
 
        TERMKEY
144
 
};
145
 
COMCOMP io_gdsp = {iogdsopt,NOTOPLIST,NONEXTLIST,NOPARAMS,NOBACKUP,
146
 
        INPUTOPT, " \t", M_("control of GDS"), 0};
147
 
#endif
148
 
 
149
 
#if IOEDIF
150
 
static KEYWORD ioedifopt[] =
151
 
{
152
 
        {"schematic",         0,{NOKEY,NOKEY,NOKEY,NOKEY,NOKEY}},
153
 
        {"netlist",           0,{NOKEY,NOKEY,NOKEY,NOKEY,NOKEY}},
154
 
        TERMKEY
155
 
};
156
 
COMCOMP io_edifp = {ioedifopt,NOTOPLIST,NONEXTLIST,NOPARAMS,NOBACKUP,
157
 
        INPUTOPT, " \t", M_("EDIF output option"), 0};
158
 
#endif
159
 
 
160
 
static KEYWORD ioplotnopt[] =
161
 
{
162
 
        {"focus",       0,{NOKEY,NOKEY,NOKEY,NOKEY,NOKEY}},
163
 
        {"include-date",0,{NOKEY,NOKEY,NOKEY,NOKEY,NOKEY}},
164
 
        TERMKEY
165
 
};
166
 
static COMCOMP ioplotnp = {ioplotnopt,NOTOPLIST,NONEXTLIST,NOPARAMS,NOBACKUP,
167
 
        INPUTOPT, " \t", M_("negating control of plot output"), 0};
168
 
static KEYWORD ioplotopt[] =
169
 
{
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}},
174
 
        TERMKEY
175
 
};
176
 
static COMCOMP ioplotp = {ioplotopt,NOTOPLIST,NONEXTLIST,NOPARAMS,NOBACKUP,
177
 
        INPUTOPT, " \t", M_("control of plot output"), 0};
178
 
 
179
 
static KEYWORD ioveropt[] =
180
 
{
181
 
        {"off",              0,{NOKEY,NOKEY,NOKEY,NOKEY,NOKEY}},
182
 
        {"on",               0,{NOKEY,NOKEY,NOKEY,NOKEY,NOKEY}},
183
 
        {"graphical",        0,{NOKEY,NOKEY,NOKEY,NOKEY,NOKEY}},
184
 
        TERMKEY
185
 
};
186
 
static COMCOMP ioverp = {ioveropt,NOTOPLIST,NONEXTLIST,NOPARAMS,NOBACKUP,
187
 
        INPUTOPT, " \t", M_("verbose option"), 0};
188
 
 
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[] =
200
 
{
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}},
215
 
        TERMKEY
216
 
};
217
 
static COMCOMP iopostp = {iopostopt,NOTOPLIST,NONEXTLIST,NOPARAMS,NOBACKUP,
218
 
        INPUTOPT, " \t", M_("control of PostScript format"), 0};
219
 
 
220
 
static COMCOMP iohpgl2sp = {NOKEYWORD,NOTOPLIST,NONEXTLIST,NOPARAMS,NOBACKUP,
221
 
        INPUTOPT, " \t", M_("internal units per pixel"), 0};
222
 
static KEYWORD iohpgl2opt[] =
223
 
{
224
 
        {"scale",           1,{&iohpgl2sp,NOKEY,NOKEY,NOKEY,NOKEY}},
225
 
        TERMKEY
226
 
};
227
 
static COMCOMP iohpgl2p = {iohpgl2opt,NOTOPLIST,NONEXTLIST,NOPARAMS,NOBACKUP,
228
 
        INPUTOPT, " \t", M_("HPGL/2 scaling option"), 0};
229
 
static KEYWORD iohpglopt[] =
230
 
{
231
 
        {"1",               0,{NOKEY,NOKEY,NOKEY,NOKEY,NOKEY}},
232
 
        {"2",               1,{&iohpgl2p,NOKEY,NOKEY,NOKEY,NOKEY}},
233
 
        TERMKEY
234
 
};
235
 
static COMCOMP iohpglp = {iohpglopt,NOTOPLIST,NONEXTLIST,NOPARAMS,NOBACKUP,
236
 
        INPUTOPT, " \t", M_("HPGL version"), 0};
237
 
 
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};
242
 
 
243
 
static KEYWORD iobinopt[] =
244
 
{
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}},
250
 
        TERMKEY
251
 
};
252
 
static COMCOMP iobinp = {iobinopt,NOTOPLIST,NONEXTLIST,NOPARAMS,NOBACKUP,
253
 
        INPUTOPT, " \t", M_("Binary options"), 0};
254
 
 
255
 
static KEYWORD ioopt[] =
256
 
{
257
 
#if IOCIF
258
 
        {"cif",            1,{&io_cifp,NOKEY,NOKEY,NOKEY,NOKEY}},
259
 
#endif
260
 
#if IODXF
261
 
        {"dxf",            1,{&io_dxfp,NOKEY,NOKEY,NOKEY,NOKEY}},
262
 
#endif
263
 
#if IOGDS
264
 
        {"gds",            1,{&io_gdsp,NOKEY,NOKEY,NOKEY,NOKEY}},
265
 
#endif
266
 
#if IOEDIF
267
 
        {"edif",           1,{&io_edifp,NOKEY,NOKEY,NOKEY,NOKEY}},
268
 
#endif
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}},
275
 
        TERMKEY
276
 
};
277
 
COMCOMP io_iop = {ioopt, NOTOPLIST, NONEXTLIST, NOPARAMS, NOBACKUP,
278
 
                0, " \t", M_("Input/Output action"), 0};
279
 
 
280
 
static struct
281
 
{
282
 
        char *name;
283
 
        INTBIG required, bits;
284
 
} io_formatlist[] =
285
 
{
286
 
        {"binary",             1, FBINARY},
287
 
        {"nobackupbinary",     1, FBINARYNOBACKUP},
288
 
#if IOCIF
289
 
        {"cif",                1, FCIF},
290
 
#endif
291
 
#if IODEF
292
 
        {"def",                2, FDEF},
293
 
#endif
294
 
#if IODXF
295
 
        {"dxf",                2, FDXF},
296
 
#endif
297
 
#if IOEAGLE
298
 
        {"eagle",              2, FEAGLE},
299
 
#endif
300
 
#if IOECAD
301
 
        {"ecad",               2, FECAD},
302
 
#endif
303
 
#if IOEDIF
304
 
        {"edif",               2, FEDIF},
305
 
#endif
306
 
#if IOGDS
307
 
        {"gds",                1, FGDS},
308
 
#endif
309
 
        {"hpgl",               1, FHPGL},
310
 
#if IOL
311
 
        {"l",                  1, FL},
312
 
#endif
313
 
#if IOLEF
314
 
        {"lef",                2, FLEF},
315
 
#endif
316
 
#if IOPADS
317
 
        {"pads",               2, FPADS},
318
 
#endif
319
 
        {"postscript",         2, FPOSTSCRIPT},
320
 
        {"printed-postscript", 2, FPRINTEDPOSTSCRIPT},
321
 
#ifdef MACOS
322
 
        {"quickdraw",          1, FQUICKDRAW},
323
 
#endif
324
 
#if IOSDF
325
 
        {"sdf",                2, FSDF},
326
 
#endif
327
 
#if IOSKILL
328
 
        {"skill",              2, FSKILL},
329
 
#endif
330
 
#if IOSUE
331
 
        {"sue",                2, FSUE},
332
 
#endif
333
 
        {"text",               1, FTEXT},
334
 
#if VHDLTOOL
335
 
        {"vhdl",               1, FVHDL},
336
 
#endif
337
 
        {NULL, 0, 0}
338
 
};
339
 
 
340
 
#define NOBLOAT ((BLOAT *)-1)
341
 
 
342
 
typedef struct Ibloat
343
 
{
344
 
        char  *layer;
345
 
        INTBIG  amount;
346
 
        struct Ibloat *nextbloat;
347
 
} BLOAT;
348
 
 
349
 
static BLOAT *io_curbloat = NOBLOAT;
350
 
 
351
 
/* working memory for "io_setuptechorder()" */
352
 
static INTBIG      io_maxlayers;
353
 
static INTBIG      io_mostlayers = 0;
354
 
static INTBIG     *io_overlaporder;
355
 
 
356
 
/* miscellaneous */
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" */
386
 
 
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);
390
 
 
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);
405
 
 
406
 
INTBIG *io_getstatebits(void)
407
 
{
408
 
        REGISTER VARIABLE *var;
409
 
        REGISTER INTBIG i, len;
410
 
        static INTBIG mybits[NUMIOSTATEBITWORDS];
411
 
 
412
 
        var = getvalkey((INTBIG)io_tool, VTOOL, -1, io_state_key);
413
 
        if (var == NOVARIABLE)
414
 
        {
415
 
                for(i=1; i<NUMIOSTATEBITWORDS; i++) mybits[i] = 0;
416
 
                mybits[0] = DXFFLATTENINPUT|GDSINARRAYS;
417
 
                return(mybits);
418
 
        }
419
 
        if ((var->type&VISARRAY) != 0)
420
 
        {
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];
424
 
                return(mybits);
425
 
        }
426
 
        for(i=1; i<NUMIOSTATEBITWORDS; i++) mybits[i] = 0;
427
 
        mybits[0] = var->addr;
428
 
        return(mybits);
429
 
}
430
 
 
431
 
void io_setstatebits(INTBIG *bits)
432
 
{
433
 
        (void)setvalkey((INTBIG)io_tool, VTOOL, io_state_key, (INTBIG)bits,
434
 
                VINTEGER|VISARRAY|(NUMIOSTATEBITWORDS<<VLENGTHSH));
435
 
}
436
 
 
437
 
void io_init(INTBIG  *argc, char *argv[], TOOL *thistool)
438
 
{
439
 
        INTBIG statebits[NUMIOSTATEBITWORDS], i;
440
 
 
441
 
        /* nothing for pass 2 or 3 initialization */
442
 
        if (thistool == NOTOOL || thistool == 0) return;
443
 
 
444
 
        /* pass 1 initialization */
445
 
        io_tool = thistool;
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");
450
 
        nextchangequiet();
451
 
        for(i=1; i<NUMIOSTATEBITWORDS; i++) statebits[i] = 0;
452
 
        statebits[0] = DXFFLATTENINPUT|GDSINARRAYS;
453
 
        io_setstatebits(statebits);
454
 
        io_verbose = 0;
455
 
 
456
 
        DiaDeclareHook("libopt", &ioverp, io_libraryoptiondlog);
457
 
        DiaDeclareHook("cdlopt", &iobloatlp, io_cdloptionsdialog);
458
 
 
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"));
478
 
 
479
 
#if IOCIF
480
 
        io_initcif();
481
 
#endif
482
 
#if IODEF
483
 
        io_initdef();
484
 
#endif
485
 
#if IODXF
486
 
        io_initdxf();
487
 
#endif
488
 
#if IOEDIF
489
 
        io_initedif();
490
 
#endif
491
 
#if IOGDS
492
 
        io_initgds();
493
 
#endif
494
 
#if IOSKILL
495
 
        io_initskill();
496
 
#endif
497
 
}
498
 
 
499
 
void io_done(void)
500
 
{
501
 
#ifdef DEBUGMEMORY
502
 
        if (io_mostlayers > 0) efree((char *)io_overlaporder);
503
 
        io_freebininmemory();
504
 
        io_freebinoutmemory();
505
 
        io_freepostscriptmemory();
506
 
        io_freetextinmemory();
507
 
#  if IOCIF
508
 
        io_freecifinmemory();
509
 
        io_freecifparsmemory();
510
 
        io_freecifoutmemory();
511
 
#  endif
512
 
#  if IODEF
513
 
        io_freedefimemory();
514
 
#  endif
515
 
#  if IODXF
516
 
        io_freedxfmemory();
517
 
#  endif
518
 
#  if IOEDIF
519
 
        io_freeedifinmemory();
520
 
#  endif
521
 
#  if IOGDS
522
 
        io_freegdsoutmemory();
523
 
#  endif
524
 
#  if IOLEF
525
 
        io_freelefimemory();
526
 
#  endif
527
 
#  if IOSDF
528
 
        io_freesdfimemory();
529
 
#  endif
530
 
#  if IOSUE
531
 
        io_freesuememory();
532
 
#  endif
533
 
#endif
534
 
}
535
 
 
536
 
void io_slice(void)
537
 
{
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);
541
 
}
542
 
 
543
 
void io_set(INTBIG count, char *par[])
544
 
{
545
 
        REGISTER INTBIG l;
546
 
        REGISTER INTBIG *curstate, scale, wid, hei;
547
 
        REGISTER NODEPROTO *np;
548
 
        REGISTER char *pp;
549
 
        REGISTER VARIABLE *var;
550
 
        INTBIG arcres, arcsag;
551
 
 
552
 
        if (count == 0)
553
 
        {
554
 
                count = ttygetparam(M_("IO option:"), &io_iop, MAXPARS, par);
555
 
                if (count == 0)
556
 
                {
557
 
                        ttyputerr(M_("Aborted"));
558
 
                        return;
559
 
                }
560
 
        }
561
 
        l = strlen(pp = par[0]);
562
 
 
563
 
        /* get current state of I/O tool */
564
 
        curstate = io_getstatebits();
565
 
 
566
 
        /* check for bloating specifications */
567
 
        if (namesamen(pp, "bloat-output", l) == 0)
568
 
        {
569
 
                if (count <= 1)
570
 
                {
571
 
                        io_setoutputbloat("", 0);
572
 
                        return;
573
 
                }
574
 
                if (count < 3)
575
 
                {
576
 
                        ttyputusage("telltool io bloat-output LAYER AMOUNT");
577
 
                        return;
578
 
                }
579
 
                io_setoutputbloat(par[1], myatoi(par[2]));
580
 
                return;
581
 
        }
582
 
 
583
 
        /* check for format specifications */
584
 
        if (namesamen(pp, "plot", l) == 0)
585
 
        {
586
 
                if (count <= 1)
587
 
                {
588
 
                        if ((curstate[0]&PLOTFOCUS) != 0)
589
 
                        {
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"));
597
 
                        return;
598
 
                }
599
 
 
600
 
                l = strlen(pp = par[1]);
601
 
                if (namesamen(pp, "not", l) == 0)
602
 
                {
603
 
                        if (count <= 2)
604
 
                        {
605
 
                                ttyputusage("telltool io plot not OPTION");
606
 
                                return;
607
 
                        }
608
 
                        l = strlen(pp = par[2]);
609
 
                        if (namesamen(pp, "focus", l) == 0)
610
 
                        {
611
 
                                curstate[0] &= ~(PLOTFOCUS|PLOTFOCUSDPY);
612
 
                                io_setstatebits(curstate);
613
 
                                ttyputverbose(M_("Plot output will display entire facet"));
614
 
                                return;
615
 
                        }
616
 
                        if (namesamen(pp, "include-date", l) == 0)
617
 
                        {
618
 
                                curstate[0] &= ~PLOTDATES;
619
 
                                io_setstatebits(curstate);
620
 
                                ttyputverbose(M_("Plot output will not include dates"));
621
 
                                return;
622
 
                        }
623
 
                        ttyputbadusage("telltool io plot not");
624
 
                        return;
625
 
                }
626
 
                if (namesamen(pp, "focus-highlighted", l) == 0 && l >= 7)
627
 
                {
628
 
                        curstate[0] = (curstate[0] & ~PLOTFOCUSDPY) | PLOTFOCUS;
629
 
                        io_setstatebits(curstate);
630
 
                        ttyputverbose(M_("Plot output will focus on highlighted area"));
631
 
                        return;
632
 
                }
633
 
                if (namesamen(pp, "focus-window", l) == 0 && l >= 7)
634
 
                {
635
 
                        curstate[0] |= (PLOTFOCUSDPY|PLOTFOCUS);
636
 
                        io_setstatebits(curstate);
637
 
                        ttyputverbose(M_("Plot output will focus on highlighted area"));
638
 
                        return;
639
 
                }
640
 
                if (namesamen(pp, "include-date", l) == 0)
641
 
                {
642
 
                        curstate[0] |= PLOTDATES;
643
 
                        io_setstatebits(curstate);
644
 
                        ttyputverbose(M_("Plot output will include dates"));
645
 
                        return;
646
 
                }
647
 
                ttyputusage("telltool io plot [not] (focus | include-dates)");
648
 
                return;
649
 
        }
650
 
 
651
 
        /* check for binary specifications */
652
 
        if (namesamen(pp, "binary", l) == 0)
653
 
        {
654
 
                l = strlen(pp = par[1]);
655
 
                if (namesamen(pp, "no-backup", l) == 0 && l >= 4)
656
 
                {
657
 
                        curstate[0] = (curstate[0] & ~BINOUTBACKUP) | BINOUTNOBACK;
658
 
                        io_setstatebits(curstate);
659
 
                        ttyputverbose(M_("Binary output will not keep backups"));
660
 
                        return;
661
 
                }
662
 
                if (namesamen(pp, "one-level-backup", l) == 0)
663
 
                {
664
 
                        curstate[0] = (curstate[0] & ~BINOUTBACKUP) | BINOUTONEBACK;
665
 
                        io_setstatebits(curstate);
666
 
                        ttyputverbose(M_("Binary output will keep one backup"));
667
 
                        return;
668
 
                }
669
 
                if (namesamen(pp, "many-level-backup", l) == 0)
670
 
                {
671
 
                        curstate[0] = (curstate[0] & ~BINOUTBACKUP) | BINOUTFULLBACK;
672
 
                        io_setstatebits(curstate);
673
 
                        ttyputverbose(M_("Binary output will keep full backups"));
674
 
                        return;
675
 
                }
676
 
 
677
 
                if (namesamen(pp, "no-check", l) == 0 && l >= 4)
678
 
                {
679
 
                        curstate[0] &= ~CHECKATWRITE;
680
 
                        io_setstatebits(curstate);
681
 
                        ttyputverbose(M_("Binary output will not check the database"));
682
 
                        return;
683
 
                }
684
 
                if (namesamen(pp, "check", l) == 0)
685
 
                {
686
 
                        curstate[0] |= CHECKATWRITE;
687
 
                        io_setstatebits(curstate);
688
 
                        ttyputverbose(M_("Binary output will check the database"));
689
 
                        return;
690
 
                }
691
 
                ttyputusage("telltool io binary (no-backup | one-level-backup | many-level-backup | no-check | check)");
692
 
                return;
693
 
        }
694
 
 
695
 
#if IOCIF
696
 
        if (namesamen(pp, "cif", l) == 0)
697
 
        {
698
 
                if (count <= 1)
699
 
                {
700
 
                        ttyputbadusage("telltool io cif (input|output)");
701
 
                        return;
702
 
                }
703
 
                l = strlen(pp = par[1]);
704
 
                if (namesamen(pp, "input", l) == 0)
705
 
                {
706
 
                        if (count <= 2)
707
 
                        {
708
 
                                ttyputbadusage("telltool io cif input OPTIONS");
709
 
                                return;
710
 
                        }
711
 
                        l = strlen(pp = par[2]);
712
 
                        switch (*pp)
713
 
                        {
714
 
                                case 'r':
715
 
                                        curstate[0] &= ~CIFINSQUARE;
716
 
                                        io_setstatebits(curstate);
717
 
                                        ttyputverbose(M_("CIF wires will have rounded ends"));
718
 
                                        break;
719
 
                                case 's':
720
 
                                        curstate[0] |= CIFINSQUARE;
721
 
                                        io_setstatebits(curstate);
722
 
                                        ttyputverbose(M_("CIF wires will have squared ends"));
723
 
                                        break;
724
 
                                default:
725
 
                                        ttyputbadusage("telltool io cif input");
726
 
                        }
727
 
                        return;
728
 
                }
729
 
                if (namesamen(pp, "output", l) == 0)
730
 
                {
731
 
                        if (count <= 2)
732
 
                        {
733
 
                                ttyputbadusage("telltool io cif output OPTIONS");
734
 
                                return;
735
 
                        }
736
 
 
737
 
                        l = strlen(pp = par[2]);
738
 
                        if (namesamen(pp, "fully-instantiated", l) == 0)
739
 
                        {
740
 
                                curstate[0] &= ~CIFOUTEXACT;
741
 
                                io_setstatebits(curstate);
742
 
                                ttyputverbose(M_("CIF generation will include all facets"));
743
 
                                return;
744
 
                        }
745
 
                        if (namesamen(pp, "exactly-as-displayed", l) == 0)
746
 
                        {
747
 
                                curstate[0] |= CIFOUTEXACT;
748
 
                                io_setstatebits(curstate);
749
 
                                ttyputverbose(M_("CIF generation will duplicate screen"));
750
 
                                return;
751
 
                        }
752
 
                        if (namesamen(pp, "merge-boxes", l) == 0)
753
 
                        {
754
 
                                curstate[0] |= CIFOUTMERGE;
755
 
                                io_setstatebits(curstate);
756
 
                                ttyputverbose(M_("CIF generation will merge boxes"));
757
 
                                return;
758
 
                        }
759
 
                        if (namesamen(pp, "individual-boxes", l) == 0 && l >= 3)
760
 
                        {
761
 
                                curstate[0] &= ~CIFOUTMERGE;
762
 
                                io_setstatebits(curstate);
763
 
                                ttyputverbose(M_("CIF generation will list individual boxes"));
764
 
                                return;
765
 
                        }
766
 
                        if (namesamen(pp, "include-cloak-layer", l) == 0 && l >= 3)
767
 
                        {
768
 
                                curstate[0] |= CIFOUTADDDRC;
769
 
                                io_setstatebits(curstate);
770
 
                                ttyputverbose(M_("CIF generation will include DRC cloak layer"));
771
 
                                return;
772
 
                        }
773
 
                        if (namesamen(pp, "ignore-cloak-layer", l) == 0 && l >= 2)
774
 
                        {
775
 
                                curstate[0] &= ~CIFOUTADDDRC;
776
 
                                io_setstatebits(curstate);
777
 
                                ttyputverbose(M_("CIF generation will ignore DRC cloak layer"));
778
 
                                return;
779
 
                        }
780
 
                        if (namesamen(pp, "normalized", l) == 0 && l >= 3)
781
 
                        {
782
 
                                curstate[0] |= CIFOUTNORMALIZE;
783
 
                                io_setstatebits(curstate);
784
 
                                ttyputverbose(M_("CIF generation will normalize coordinates"));
785
 
                                return;
786
 
                        }
787
 
                        if (namesamen(pp, "not-normalized", l) == 0 && l >= 3)
788
 
                        {
789
 
                                curstate[0] &= ~CIFOUTNORMALIZE;
790
 
                                io_setstatebits(curstate);
791
 
                                ttyputverbose(M_("CIF generation will use facet coordinates"));
792
 
                                return;
793
 
                        }
794
 
                        if (namesamen(pp, "instantiate-top", l) == 0 && l >= 3)
795
 
                        {
796
 
                                curstate[0] &= ~CIFOUTNOTOPCALL;
797
 
                                io_setstatebits(curstate);
798
 
                                ttyputverbose(M_("CIF generation will instantiate top-level cell"));
799
 
                                return;
800
 
                        }
801
 
                        if (namesamen(pp, "dont-instantiate-top", l) == 0 && l >= 3)
802
 
                        {
803
 
                                curstate[0] |= CIFOUTNOTOPCALL;
804
 
                                io_setstatebits(curstate);
805
 
                                ttyputverbose(M_("CIF generation will not instantiate top-level cell"));
806
 
                                return;
807
 
                        }
808
 
                        if (namesamen(pp, "highlight-resolution", l) == 0 && l >= 3)
809
 
                        {
810
 
                                curstate[1] |= CIFRESHIGH;
811
 
                                io_setstatebits(curstate);
812
 
                                ttyputverbose(M_("CIF generation will highlight resolution errors"));
813
 
                                return;
814
 
                        }
815
 
                        if (namesamen(pp, "hide-resolution", l) == 0 && l >= 3)
816
 
                        {
817
 
                                curstate[1] &= ~CIFRESHIGH;
818
 
                                io_setstatebits(curstate);
819
 
                                ttyputverbose(M_("CIF generation will not highlight resolution errors"));
820
 
                                return;
821
 
                        }
822
 
                }
823
 
                ttyputusage("telltool io cif input|output OPTION");
824
 
                return;
825
 
        }
826
 
#endif
827
 
 
828
 
#if IOGDS
829
 
        if (namesamen(pp, "gds", l) == 0)
830
 
        {
831
 
                if (count <= 1)
832
 
                {
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"));
848
 
                        return;
849
 
                }
850
 
                l = strlen(pp = par[1]);
851
 
                if (namesamen(pp, "input", l) == 0)
852
 
                {
853
 
                        if (count <= 2)
854
 
                        {
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"));
864
 
                                return;
865
 
                        }
866
 
                        l = strlen(pp = par[2]);
867
 
                        if (namesamen(pp, "text", l) == 0)
868
 
                        {
869
 
                                curstate[0] |= GDSINTEXT;
870
 
                                io_setstatebits(curstate);
871
 
                                ttyputverbose(M_("GDS input includes text"));
872
 
                                return;
873
 
                        }
874
 
                        if (namesamen(pp, "no-text", l) == 0 && l >= 4)
875
 
                        {
876
 
                                curstate[0] &= ~GDSINTEXT;
877
 
                                io_setstatebits(curstate);
878
 
                                ttyputverbose(M_("GDS input ignores text"));
879
 
                                return;
880
 
                        }
881
 
                        if (namesamen(pp, "expand", l) == 0)
882
 
                        {
883
 
                                curstate[0] |= GDSINEXPAND;
884
 
                                io_setstatebits(curstate);
885
 
                                ttyputverbose(M_("GDS input expands instances"));
886
 
                                return;
887
 
                        }
888
 
                        if (namesamen(pp, "no-expand", l) == 0 && l >= 4)
889
 
                        {
890
 
                                curstate[0] &= ~GDSINEXPAND;
891
 
                                io_setstatebits(curstate);
892
 
                                ttyputverbose(M_("GDS input does not expand instances"));
893
 
                                return;
894
 
                        }
895
 
                        if (namesamen(pp, "arrays", l) == 0)
896
 
                        {
897
 
                                curstate[0] |= GDSINARRAYS;
898
 
                                io_setstatebits(curstate);
899
 
                                ttyputverbose(M_("GDS input instantiates arrays"));
900
 
                                return;
901
 
                        }
902
 
                        if (namesamen(pp, "no-arrays", l) == 0 && l >= 4)
903
 
                        {
904
 
                                curstate[0] &= ~GDSINARRAYS;
905
 
                                io_setstatebits(curstate);
906
 
                                ttyputverbose(M_("GDS input does not instantiate arrays"));
907
 
                                return;
908
 
                        }
909
 
                        if (namesamen(pp, "unknown-layers", l) == 0)
910
 
                        {
911
 
                                curstate[0] |= GDSINIGNOREUKN;
912
 
                                io_setstatebits(curstate);
913
 
                                ttyputverbose(M_("GDS input includes unknown layers"));
914
 
                                return;
915
 
                        }
916
 
                        if (namesamen(pp, "no-unknown-layers", l) == 0 && l >= 4)
917
 
                        {
918
 
                                curstate[0] &= ~GDSINIGNOREUKN;
919
 
                                io_setstatebits(curstate);
920
 
                                ttyputverbose(M_("GDS input ignores unknown layers"));
921
 
                                return;
922
 
                        }
923
 
                        ttyputbadusage("telltool io gds input");
924
 
                        return;
925
 
                }
926
 
                if (namesamen(pp, "output", l) == 0)
927
 
                {
928
 
                        if (count <= 2)
929
 
                        {
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"));
936
 
                                return;
937
 
                        }
938
 
                        l = strlen(pp = par[2]);
939
 
                        if (namesamen(pp, "merge-boxes", l) == 0)
940
 
                        {
941
 
                                curstate[0] |= GDSOUTMERGE;
942
 
                                io_setstatebits(curstate);
943
 
                                ttyputverbose(M_("GDS generation will merge boxes"));
944
 
                                return;
945
 
                        }
946
 
                        if (namesamen(pp, "individual-boxes", l) == 0 && l >= 3)
947
 
                        {
948
 
                                curstate[0] &= ~GDSOUTMERGE;
949
 
                                io_setstatebits(curstate);
950
 
                                ttyputverbose(M_("GDS generation will list individual boxes"));
951
 
                                return;
952
 
                        }
953
 
                        if (namesamen(pp, "include-cloak-layer", l) == 0 && l >= 3)
954
 
                        {
955
 
                                curstate[0] |= GDSOUTADDDRC;
956
 
                                io_setstatebits(curstate);
957
 
                                ttyputverbose(M_("GDS generation will include DRC cloak layer"));
958
 
                                return;
959
 
                        }
960
 
                        if (namesamen(pp, "ignore-cloak-layer", l) == 0 && l >= 2)
961
 
                        {
962
 
                                curstate[0] &= ~GDSOUTADDDRC;
963
 
                                io_setstatebits(curstate);
964
 
                                ttyputverbose(M_("GDS generation will ignore DRC cloak layer"));
965
 
                                return;
966
 
                        }
967
 
                        if (namesamen(pp, "arc-resolution", l) == 0 && l >= 5)
968
 
                        {
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);
974
 
                                return;
975
 
                        }
976
 
                        if (namesamen(pp, "arc-sag", l) == 0 && l >= 5)
977
 
                        {
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);
982
 
                                return;
983
 
                        }
984
 
                        ttyputbadusage("telltool io gds output");
985
 
                        return;
986
 
                }
987
 
                ttyputbadusage("telltool io gds");
988
 
                return;
989
 
        }
990
 
#endif
991
 
 
992
 
#if IODXF
993
 
        if (namesamen(pp, "dxf", l) == 0)
994
 
        {
995
 
                if (count <= 1)
996
 
                {
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"));
1000
 
                        return;
1001
 
                }
1002
 
                l = strlen(pp = par[1]);
1003
 
                if (namesamen(pp, "acceptable-layers", l) == 0)
1004
 
                {
1005
 
                        if (count <= 2)
1006
 
                        {
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"));
1010
 
                                return;
1011
 
                        }
1012
 
                        l = strlen(pp = par[2]);
1013
 
                        if (namesamen(pp, "all", l) == 0)
1014
 
                        {
1015
 
                                curstate[0] |= DXFALLLAYERS;
1016
 
                                io_setstatebits(curstate);
1017
 
                                ttyputverbose(M_("DXF input will accept all layers"));
1018
 
                                return;
1019
 
                        }
1020
 
                        if (namesamen(pp, "restrict", l) == 0)
1021
 
                        {
1022
 
                                curstate[0] &= ~DXFALLLAYERS;
1023
 
                                io_setstatebits(curstate);
1024
 
                                ttyputverbose(M_("DXF input will accept only layers listed by technology"));
1025
 
                                return;
1026
 
                        }
1027
 
                }
1028
 
                if (namesamen(pp, "flatten-input", l) == 0)
1029
 
                {
1030
 
                        curstate[0] |= DXFFLATTENINPUT;
1031
 
                        io_setstatebits(curstate);
1032
 
                        ttyputverbose(M_("DXF input will flatten input blocks"));
1033
 
                        return;
1034
 
                }
1035
 
                if (namesamen(pp, "not-flatten-input", l) == 0)
1036
 
                {
1037
 
                        curstate[0] &= ~DXFFLATTENINPUT;
1038
 
                        io_setstatebits(curstate);
1039
 
                        ttyputverbose(M_("DXF input will retain input hierarchy"));
1040
 
                        return;
1041
 
                }
1042
 
                ttyputbadusage("telltool io dxf");
1043
 
                return;
1044
 
        }
1045
 
#endif
1046
 
 
1047
 
        if (namesamen(pp, "postscript", l) == 0)
1048
 
        {
1049
 
                if (count <= 1)
1050
 
                {
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)
1068
 
                        {
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);
1073
 
                        }
1074
 
                        return;
1075
 
                }
1076
 
                l = strlen(pp = par[1]);
1077
 
                if (namesamen(pp, "flat", l) == 0)
1078
 
                {
1079
 
                        curstate[0] &= ~PSHIERARCHICAL;
1080
 
                        io_setstatebits(curstate);
1081
 
                        ttyputverbose(M_("PostScript output will be flat"));
1082
 
                        return;
1083
 
                }
1084
 
                if (namesamen(pp, "hierarchical", l) == 0 && l >= 2)
1085
 
                {
1086
 
                        curstate[0] |= PSHIERARCHICAL;
1087
 
                        io_setstatebits(curstate);
1088
 
                        ttyputverbose(M_("PostScript output will be hierarchical"));
1089
 
                        return;
1090
 
                }
1091
 
                if (namesamen(pp, "encapsulated", l) == 0)
1092
 
                {
1093
 
                        curstate[0] |= EPSPSCRIPT;
1094
 
                        io_setstatebits(curstate);
1095
 
                        ttyputverbose(M_("PostScript output will be encapsulated format"));
1096
 
                        return;
1097
 
                }
1098
 
                if (namesamen(pp, "plain", l) == 0 && l >= 2)
1099
 
                {
1100
 
                        curstate[0] &= ~EPSPSCRIPT;
1101
 
                        io_setstatebits(curstate);
1102
 
                        ttyputverbose(M_("PostScript output will be plain format"));
1103
 
                        return;
1104
 
                }
1105
 
                if (namesamen(pp, "color", l) == 0)
1106
 
                {
1107
 
                        curstate[0] = (curstate[0] & ~PSCOLORSTIP) | PSCOLOR;
1108
 
                        io_setstatebits(curstate);
1109
 
                        ttyputverbose(M_("PostScript output will use color"));
1110
 
                        return;
1111
 
                }
1112
 
                if (namesamen(pp, "stippled-color", l) == 0 && l >= 2)
1113
 
                {
1114
 
                        curstate[0] |= PSCOLOR | PSCOLORSTIP;
1115
 
                        io_setstatebits(curstate);
1116
 
                        ttyputverbose(M_("PostScript output will use color"));
1117
 
                        return;
1118
 
                }
1119
 
                if (namesamen(pp, "gray-scale", l) == 0)
1120
 
                {
1121
 
                        curstate[0] &= ~PSCOLOR;
1122
 
                        io_setstatebits(curstate);
1123
 
                        ttyputverbose(M_("PostScript output will be gray-scale"));
1124
 
                        return;
1125
 
                }
1126
 
                if (namesamen(pp, "rotate", l) == 0)
1127
 
                {
1128
 
                        curstate[0] |= PSROTATE;
1129
 
                        io_setstatebits(curstate);
1130
 
                        ttyputverbose(M_("PostScript output will be rotated 90 degrees"));
1131
 
                        return;
1132
 
                }
1133
 
                if (namesamen(pp, "no-rotate", l) == 0)
1134
 
                {
1135
 
                        curstate[0] &= ~PSROTATE;
1136
 
                        io_setstatebits(curstate);
1137
 
                        ttyputverbose(M_("PostScript output will appear unrotated"));
1138
 
                        return;
1139
 
                }
1140
 
                if (namesamen(pp, "margin", l) == 0)
1141
 
                {
1142
 
                        if (count == 3)
1143
 
                        {
1144
 
                                wid = atofr(par[2]);
1145
 
                                (void)setval((INTBIG)io_tool, VTOOL, "IO_postscript_margin", wid, VFRACT);
1146
 
                        } else
1147
 
                        {
1148
 
                                var = getval((INTBIG)io_tool, VTOOL, VFRACT, "IO_postscript_margin");
1149
 
                                if (var == NOVARIABLE) wid = muldiv(DEFAULTPSMARGIN, WHOLE, 75); else
1150
 
                                        wid = var->addr;
1151
 
                        }
1152
 
                        ttyputverbose(M_("PostScript output will use a %s-wide margin"), frtoa(wid));
1153
 
                        return;
1154
 
                }
1155
 
                if (namesamen(pp, "plotter", l) == 0 && l >= 2)
1156
 
                {
1157
 
                        curstate[0] |= PSPLOTTER;
1158
 
                        io_setstatebits(curstate);
1159
 
                        if (count == 3)
1160
 
                        {
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));
1164
 
                        } else
1165
 
                                ttyputverbose(M_("PostScript output will assume a continuous-roll plotter"));
1166
 
                        return;
1167
 
                }
1168
 
                if (namesamen(pp, "printer", l) == 0 && l >= 2)
1169
 
                {
1170
 
                        curstate[0] &= ~PSPLOTTER;
1171
 
                        io_setstatebits(curstate);
1172
 
                        if (count == 4)
1173
 
                        {
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));
1180
 
                        } else
1181
 
                                ttyputverbose(M_("PostScript output will be assume a fixed-size sheet"));
1182
 
                        return;
1183
 
                }
1184
 
                if (namesamen(pp, "unsynchronize", l) == 0)
1185
 
                {
1186
 
                        np = el_curlib->curnodeproto;
1187
 
                        if (np == NONODEPROTO)
1188
 
                        {
1189
 
                                ttyputerr(M_("Edit a facet before removing synchronization"));
1190
 
                                return;
1191
 
                        }
1192
 
                        if (getvalkey((INTBIG)np, VNODEPROTO, VSTRING, io_postscriptfilenamekey) != NOVARIABLE)
1193
 
                        {
1194
 
                                (void)delvalkey((INTBIG)np, VNODEPROTO, io_postscriptfilenamekey);
1195
 
                                ttyputverbose(M_("Facet %s no longer synchronized to PostScript disk file"),
1196
 
                                        describenodeproto(np));
1197
 
                        }
1198
 
                        return;
1199
 
                }
1200
 
                if (namesamen(pp, "synchronize", l) == 0 && l >= 2)
1201
 
                {
1202
 
                        if (count <= 2)
1203
 
                        {
1204
 
                                ttyputusage("telltool io postscript synchronize FILENAME");
1205
 
                                return;
1206
 
                        }
1207
 
                        np = el_curlib->curnodeproto;
1208
 
                        if (np == NONODEPROTO)
1209
 
                        {
1210
 
                                ttyputerr(M_("Edit a facet to synchronize it to a PostScript file"));
1211
 
                                return;
1212
 
                        }
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]);
1217
 
                        return;
1218
 
                }
1219
 
                ttyputusage("telltool io postscript OPTION");
1220
 
                return;
1221
 
        }
1222
 
 
1223
 
        if (namesamen(pp, "hpgl", l) == 0)
1224
 
        {
1225
 
                if (count <= 1)
1226
 
                {
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"));
1230
 
                        return;
1231
 
                }
1232
 
                l = strlen(pp = par[1]);
1233
 
                if (namesamen(pp, "1", l) == 0)
1234
 
                {
1235
 
                        curstate[0] &= ~HPGL2;
1236
 
                        io_setstatebits(curstate);
1237
 
                        ttyputmsg(M_("HPGL output will use older (version 1) format"));
1238
 
                        return;
1239
 
                }
1240
 
                if (namesamen(pp, "2", l) == 0)
1241
 
                {
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)
1246
 
                        {
1247
 
                                scale = myatoi(par[3]);
1248
 
                                (void)setval((INTBIG)io_tool, VTOOL, "IO_hpgl2_scale",
1249
 
                                        scale, VINTEGER);
1250
 
                                ttyputverbose(M_("HPGL/2 plots will scale at %ld %ss per pixel"),
1251
 
                                        scale, unitsname(el_units));
1252
 
                        }
1253
 
                        return;
1254
 
                }
1255
 
                ttyputusage("telltool io hpgl [1|2]");
1256
 
                return;
1257
 
        }
1258
 
 
1259
 
#if IOEDIF
1260
 
        if (namesamen(pp, "edif", l) == 0)
1261
 
        {
1262
 
                if (count <= 1)
1263
 
                {
1264
 
                        if ((curstate[0]&EDIFSCHEMATIC) == 0)
1265
 
                                ttyputmsg(M_("EDIF output writes schematics")); else
1266
 
                                        ttyputmsg(M_("EDIF output writes netlists"));
1267
 
                        return;
1268
 
                }
1269
 
                l = strlen(pp = par[1]);
1270
 
                if (namesamen(pp, "schematic", l) == 0)
1271
 
                {
1272
 
                        curstate[0] |= EDIFSCHEMATIC;
1273
 
                        io_setstatebits(curstate);
1274
 
                        ttyputverbose(M_("EDIF output will write schematics"));
1275
 
                        return;
1276
 
                }
1277
 
                if (namesamen(pp, "netlist", l) == 0)
1278
 
                {
1279
 
                        curstate[0] &= ~EDIFSCHEMATIC;
1280
 
                        io_setstatebits(curstate);
1281
 
                        ttyputverbose(M_("EDIF output will write netlists"));
1282
 
                        return;
1283
 
                }
1284
 
                ttyputusage("telltool io edif [schematic|netlist]");
1285
 
                return;
1286
 
        }
1287
 
#endif
1288
 
 
1289
 
        if (namesamen(pp, "verbose", l) == 0)
1290
 
        {
1291
 
                if (count <= 1)
1292
 
                {
1293
 
                        ttyputusage("telltool io verbose OPTION");
1294
 
                        return;
1295
 
                }
1296
 
                l = strlen(pp = par[1]);
1297
 
                if (namesamen(pp, "off", l) == 0 && l >= 2)
1298
 
                {
1299
 
                        io_verbose = 0;
1300
 
                        ttyputverbose(M_("I/O done silently"));
1301
 
                        return;
1302
 
                }
1303
 
                if (namesamen(pp, "on", l) == 0 && l >= 2)
1304
 
                {
1305
 
                        io_verbose = 1;
1306
 
                        ttyputverbose(M_("I/O prints status"));
1307
 
                        return;
1308
 
                }
1309
 
                if (namesamen(pp, "graphical", l) == 0 && l >= 1)
1310
 
                {
1311
 
                        io_verbose = -1;
1312
 
                        ttyputverbose(M_("I/O shows graphical progress"));
1313
 
                        return;
1314
 
                }
1315
 
                ttyputbadusage("telltool io verbose");
1316
 
                return;
1317
 
        }
1318
 
 
1319
 
        ttyputbadusage("telltool io");
1320
 
}
1321
 
 
1322
 
/*
1323
 
 * make I/O requests of this tool:
1324
 
 *
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
1328
 
 */
1329
 
INTBIG io_request(char *command, va_list ap)
1330
 
{
1331
 
        REGISTER LIBRARY *lib;
1332
 
        REGISTER INTBIG i, len, format;
1333
 
        REGISTER BOOLEAN err;
1334
 
        REGISTER INTBIG arg1, arg3;
1335
 
        char *arg2;
1336
 
 
1337
 
        if (namesame(command, "verbose") == 0)
1338
 
        {
1339
 
                i = io_verbose;
1340
 
                io_verbose = va_arg(ap, INTBIG);
1341
 
                return(i);
1342
 
        }
1343
 
 
1344
 
        /* get the arguments */
1345
 
        arg1 = va_arg(ap, INTBIG);
1346
 
        arg2 = va_arg(ap, char*);
1347
 
 
1348
 
        /* find desired library and format */
1349
 
        lib = (LIBRARY *)arg1;
1350
 
        format = -1;
1351
 
        len = strlen(arg2);
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)
1354
 
        {
1355
 
                format = io_formatlist[i].bits;
1356
 
                break;
1357
 
        }
1358
 
        if (format < 0)
1359
 
        {
1360
 
                ttyputerr(M_("Unknown I/O format: %s"), arg2);
1361
 
                return(1);
1362
 
        }
1363
 
 
1364
 
        if (namesame(command, "write") == 0)
1365
 
        {
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);
1370
 
 
1371
 
                switch (format)
1372
 
                {
1373
 
                        case FBINARY:
1374
 
                                err = io_writebinlibrary(lib, FALSE);
1375
 
                                break;
1376
 
                        case FBINARYNOBACKUP:
1377
 
                                err = io_writebinlibrary(lib, TRUE);
1378
 
                                break;
1379
 
 
1380
 
#if IOCIF
1381
 
                        case FCIF:
1382
 
                                err = io_writeciflibrary(lib);
1383
 
                                break;
1384
 
#endif
1385
 
 
1386
 
#if IODXF
1387
 
                        case FDXF:
1388
 
                                err = io_writedxflibrary(lib);
1389
 
                                break;
1390
 
#endif
1391
 
 
1392
 
#if IOEAGLE
1393
 
                        case FEAGLE:
1394
 
                                err = io_writeeaglelibrary(lib);
1395
 
                                break;
1396
 
#endif
1397
 
 
1398
 
#if IOECAD
1399
 
                        case FECAD:
1400
 
                                err = io_writeecadlibrary(lib);
1401
 
                                break;
1402
 
#endif
1403
 
 
1404
 
#if IOEDIF
1405
 
                        case FEDIF:
1406
 
                                err = io_writeediflibrary(lib);
1407
 
                                break;
1408
 
#endif
1409
 
 
1410
 
#if IOGDS
1411
 
                        case FGDS:
1412
 
                                err = io_writegdslibrary(lib);
1413
 
                                break;
1414
 
#endif
1415
 
 
1416
 
                        case FHPGL:
1417
 
                                err = io_writehpgllibrary(lib);
1418
 
                                break;
1419
 
 
1420
 
#if IOL
1421
 
                        case FL:
1422
 
                                err = io_writellibrary(lib);
1423
 
                                break;
1424
 
#endif
1425
 
 
1426
 
#if IOLEF
1427
 
                        case FLEF:
1428
 
                                err = io_writeleflibrary(lib);
1429
 
                                break;
1430
 
#endif
1431
 
 
1432
 
#if IOPADS
1433
 
                        case FPADS:
1434
 
                                err = io_writepadslibrary(lib);
1435
 
                                break;
1436
 
#endif
1437
 
 
1438
 
                        case FPOSTSCRIPT:
1439
 
                        case FPRINTEDPOSTSCRIPT:
1440
 
                                err = io_writepostscriptlibrary(lib, (format == FPOSTSCRIPT ? 0 : 1));
1441
 
                                break;
1442
 
 
1443
 
#ifdef MACOS
1444
 
                        case FQUICKDRAW:
1445
 
                                err = io_writequickdrawlibrary(lib);
1446
 
                                break;
1447
 
#endif
1448
 
 
1449
 
#if IOSKILL
1450
 
                        case FSKILL:
1451
 
                                err = io_writeskilllibrary(lib);
1452
 
                                break;
1453
 
#endif
1454
 
 
1455
 
                        case FTEXT:
1456
 
                                err = io_writetextlibrary(lib);
1457
 
                                break;
1458
 
 
1459
 
                        default:
1460
 
                                for(i=0; io_formatlist[i].name != 0; i++)
1461
 
                                        if (io_formatlist[i].bits == format)
1462
 
                                {
1463
 
                                        ttyputerr(M_("Cannot write %s files"), io_formatlist[i].name);
1464
 
                                        return(1);
1465
 
                                }
1466
 
                }
1467
 
 
1468
 
                /* announce the ending of library output */
1469
 
                if (err) return(1);
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);
1474
 
                return(0);
1475
 
        }
1476
 
 
1477
 
        if (namesame(command, "read") == 0)
1478
 
        {
1479
 
                arg3 = va_arg(ap, INTBIG);
1480
 
                io_libinputrecursivedepth = io_libinputreadmany = 0;
1481
 
                switch (format)
1482
 
                {
1483
 
                        case FBINARY:
1484
 
                                err = io_readbinlibrary(lib);
1485
 
                                /* make sure that the lambda values are consistent */
1486
 
                                if (!err) io_unifylambdavalues(lib);
1487
 
                                break;
1488
 
 
1489
 
#if IOCIF
1490
 
                        case FCIF:
1491
 
                                err = io_readciflibrary(lib);
1492
 
                                break;
1493
 
#endif
1494
 
 
1495
 
#if IODEF
1496
 
                        case FDEF:
1497
 
                                err = io_readdeflibrary(lib);
1498
 
                                break;
1499
 
#endif
1500
 
 
1501
 
#if IODXF
1502
 
                        case FDXF:
1503
 
                                err = io_readdxflibrary(lib);
1504
 
                                break;
1505
 
#endif
1506
 
 
1507
 
#if IOEDIF
1508
 
                        case FEDIF:
1509
 
                                err = io_readediflibrary(lib);
1510
 
                                break;
1511
 
#endif
1512
 
 
1513
 
#if IOGDS
1514
 
                        case FGDS:
1515
 
                                err = io_readgdslibrary(lib, arg3);
1516
 
                                break;
1517
 
#endif
1518
 
 
1519
 
#if IOLEF
1520
 
                        case FLEF:
1521
 
                                err = io_readleflibrary(lib);
1522
 
                                break;
1523
 
#endif
1524
 
 
1525
 
#if IOSDF
1526
 
                        case FSDF:
1527
 
                                err = io_readsdflibrary(lib);
1528
 
                                break;
1529
 
#endif
1530
 
 
1531
 
#if IOSUE
1532
 
                        case FSUE:
1533
 
                                err = io_readsuelibrary(lib);
1534
 
                                break;
1535
 
#endif
1536
 
 
1537
 
                        case FTEXT:
1538
 
                                err = io_readtextlibrary(lib);
1539
 
                                /* make sure that the lambda values are consistent */
1540
 
                                if (!err) io_unifylambdavalues(lib);
1541
 
                                break;
1542
 
 
1543
 
#if VHDLTOOL
1544
 
                        case FVHDL:
1545
 
                                err = io_readvhdllibrary(lib);
1546
 
                                break;
1547
 
#endif
1548
 
 
1549
 
                        default:
1550
 
                                for(i=0; io_formatlist[i].name != 0; i++)
1551
 
                                        if (io_formatlist[i].bits == format)
1552
 
                                {
1553
 
                                        ttyputerr(M_("Cannot read %s files"), io_formatlist[i].name);
1554
 
                                        return(1);
1555
 
                                }
1556
 
                }
1557
 
 
1558
 
                /* announce the completion of library input */
1559
 
                if (err) return(1);
1560
 
                for(i=0; i<el_maxtools; i++)
1561
 
                        if (el_tools[i].readlibrary != 0)
1562
 
                                (*el_tools[i].readlibrary)(lib);
1563
 
                return(0);
1564
 
        }
1565
 
        return(-1);
1566
 
}
1567
 
 
1568
 
/******************************* BLOATING *******************************/
1569
 
 
1570
 
/*
1571
 
 * routine to indicate that CIF layer "layer" is to be bloated by "amount"
1572
 
 */
1573
 
void io_setoutputbloat(char *layer, INTBIG amount)
1574
 
{
1575
 
        REGISTER BLOAT *bl;
1576
 
 
1577
 
        /* special case when bloating the null layer */
1578
 
        if (*layer == 0)
1579
 
        {
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));
1582
 
                return;
1583
 
        }
1584
 
 
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)
1588
 
        {
1589
 
                if (bl->amount == amount)
1590
 
                {
1591
 
                        ttyputmsg(M_("Layer %s is already being bloated by %ld %ss"),
1592
 
                                bl->layer, amount, unitsname(el_units));
1593
 
                        return;
1594
 
                }
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;
1598
 
                return;
1599
 
        }
1600
 
 
1601
 
        bl = (BLOAT *)emalloc(sizeof (BLOAT), io_tool->cluster);
1602
 
        if (bl == 0)
1603
 
        {
1604
 
                ttyputnomemory();
1605
 
                return;
1606
 
        }
1607
 
        (void)allocstring(&bl->layer, layer, io_tool->cluster);
1608
 
        bl->amount = amount;
1609
 
        bl->nextbloat = io_curbloat;
1610
 
        io_curbloat = bl;
1611
 
        ttyputmsg(M_("Layer %s will be bloated by %ld %ss"), layer, amount, unitsname(el_units));
1612
 
}
1613
 
 
1614
 
/*
1615
 
 * routine to tell the amount to bloat layer "lay"
1616
 
 */
1617
 
INTBIG io_getoutputbloat(char *layer)
1618
 
{
1619
 
        REGISTER BLOAT *bl;
1620
 
 
1621
 
        for(bl = io_curbloat; bl != NOBLOAT; bl = bl->nextbloat)
1622
 
                if (namesame(bl->layer, layer) == 0) return(bl->amount);
1623
 
        return(0);
1624
 
}
1625
 
 
1626
 
/******************************* LIBRARY REPAIR *******************************/
1627
 
 
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 */
1638
 
 
1639
 
/*
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.
1642
 
 */
1643
 
void io_fixnewlib(LIBRARY *lib, INTBIG statusitem)
1644
 
{
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,
1653
 
                shiftx, shifty;
1654
 
        UINTBIG olddescript[TEXTDESCRIPTSIZE];
1655
 
        REGISTER char *str, *pt, **newlist;
1656
 
        XARRAY trans;
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;
1671
 
 
1672
 
        /* make sure units are correct */
1673
 
        libunits = ((lib->userbits & LIBUNITS) >> LIBUNITSSH) << INTERNALUNITSSH;
1674
 
        if ((libunits & INTERNALUNITS) != (el_units & INTERNALUNITS))
1675
 
        {
1676
 
                ttyputmsg(_("Converting library from %s units to %s units"), unitsname(libunits),
1677
 
                        unitsname(el_units));
1678
 
                changeinternalunits(lib, libunits, el_units);
1679
 
        }
1680
 
 
1681
 
        /* check validity of instances */
1682
 
        for(np = lib->firstnodeproto; np != NONODEPROTO; np = np->nextnodeproto)
1683
 
        {
1684
 
                for(olib = el_curlib; olib != NOLIBRARY; olib = olib->nextlibrary)
1685
 
                        if (olib == np->cell->lib) break;
1686
 
                if (olib == NOLIBRARY)
1687
 
                {
1688
 
                        ttyputerr(_("ERROR: Facet %s: has invalid cell structure"), describenodeproto(np));
1689
 
                        continue;
1690
 
                }
1691
 
                for(ni = np->firstnodeinst; ni != NONODEINST; ni = ni->nextnodeinst)
1692
 
                {
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)
1699
 
                        {
1700
 
                                ttyputerr(_("ERROR: Facet %s: has instance from invalid library"), describenodeproto(np));
1701
 
                                ni->proto = gen_univpinprim;
1702
 
                                continue;
1703
 
                        }
1704
 
                        for(onp = olib->firstnodeproto; onp != NONODEPROTO; onp = onp->nextnodeproto)
1705
 
                                if (onp == ni->proto) break;
1706
 
                        if (onp == NONODEPROTO)
1707
 
                        {
1708
 
                                ttyputerr(_("ERROR: Facet %s: has instance with invalid prototype"), describenodeproto(np));
1709
 
                                ni->proto = gen_univpinprim;
1710
 
                                continue;
1711
 
                        }
1712
 
                }
1713
 
        }
1714
 
 
1715
 
        /* create cell name hash table */
1716
 
        db_buildcellhashtable(lib);
1717
 
 
1718
 
        /* adjust every facet in the library */
1719
 
        for(np = lib->firstnodeproto; np != NONODEPROTO; np = np->nextnodeproto)
1720
 
        {
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)
1724
 
                {
1725
 
                        pp->subportexpinst = pe;  break;
1726
 
                }
1727
 
#ifdef MACOS
1728
 
                /*
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.
1732
 
                 *
1733
 
                 * The Macintosh epoch is 1904, but every other machine uses 1970.
1734
 
                 * Therefore, the Macintosh numbers are 66 years larger.
1735
 
                 *
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.
1742
 
                 */
1743
 
                if (np->creationdate > 0x9FE3EB1F) np->creationdate -= 0x7C254E10;
1744
 
                if (np->revisiondate > 0x9FE3EB1F) np->revisiondate -= 0x7C254E10;
1745
 
#endif
1746
 
        }
1747
 
 
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)
1751
 
        {
1752
 
                inpp = pp;
1753
 
                while (inpp != NOPORTPROTO && inpp->parent->primindex == 0)
1754
 
                {
1755
 
                        inpp = inpp->subportproto;
1756
 
                }
1757
 
                if (inpp != NOPORTPROTO)
1758
 
                        pp->connects = inpp->connects;
1759
 
                if (pp->connects == 0)
1760
 
                {
1761
 
                        if (gen_upconn[0] != 0) pp->connects = gen_upconn; else
1762
 
                                pp->connects = &gen_upconn[1];
1763
 
                        pp->subportproto = pp->subnodeinst->proto->firstportproto;
1764
 
                }
1765
 
        }
1766
 
 
1767
 
        /* look for arrayed node specifications */
1768
 
        for(np = lib->firstnodeproto; np != NONODEPROTO; np = np->nextnodeproto)
1769
 
        {
1770
 
                if (!isschematicview(np)) continue;
1771
 
                for(ni = np->firstnodeinst; ni != NONODEINST; ni = ni->nextnodeinst)
1772
 
                {
1773
 
                        net_setnodewidth(ni);
1774
 
                }
1775
 
        }
1776
 
 
1777
 
        /*
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.
1783
 
         */
1784
 
        io_getversion(lib, &major, &minor, &detail);
1785
 
 
1786
 
        /* this is only done after all libraries are read */
1787
 
        if (io_libinputrecursivedepth == 0)
1788
 
        {
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)
1798
 
                {
1799
 
                        /* examine every nodeinst in the facet */
1800
 
                        for(ni = np->firstnodeinst; ni != NONODEINST; ni = ni->nextnodeinst)
1801
 
                        {
1802
 
                                /* compute linked list of node instances */
1803
 
                                pnt = ni->proto;
1804
 
                                if (pnt == NONODEPROTO)
1805
 
                                {
1806
 
                                        ttyputerr(_("Facet %s: has a node without a prototype"), describenodeproto(np));
1807
 
                                        ni->proto = gen_univpinprim;
1808
 
                                }
1809
 
                                if (pnt->firstinst != NONODEINST) pnt->firstinst->lastinst = ni;
1810
 
                                ni->nextinst = pnt->firstinst;
1811
 
                                ni->lastinst = NONODEINST;
1812
 
                                pnt->firstinst = ni;
1813
 
                        }
1814
 
                }
1815
 
 
1816
 
                /* for versions before 6.05bc, look for icon facets that are wrong */
1817
 
                if (major < 6 ||
1818
 
                        (major == 6 && minor < 5) ||
1819
 
                        (major == 6 && minor == 5 && detail < 55))
1820
 
                {
1821
 
                        numchanged = 0;
1822
 
                        for(olib = el_curlib; olib != NOLIBRARY; olib = olib->nextlibrary)
1823
 
                                for(np = olib->firstnodeproto; np != NONODEPROTO; np = np->nextnodeproto)
1824
 
                        {
1825
 
                                first = TRUE;
1826
 
                                for(ni = np->firstnodeinst; ni != NONODEINST; ni = ni->nextnodeinst)
1827
 
                                {
1828
 
                                        boundobj(ni->geom, &lx, &hx, &ly, &hy);
1829
 
                                        if (first)
1830
 
                                        {
1831
 
                                                first = FALSE;
1832
 
                                                totlx = lx;   tothx = hx;
1833
 
                                                totly = ly;   tothy = hy;
1834
 
                                        } else
1835
 
                                        {
1836
 
                                                if (lx < totlx) totlx = lx;
1837
 
                                                if (hx > tothx) tothx = hx;
1838
 
                                                if (ly < totly) totly = ly;
1839
 
                                                if (hy > tothy) tothy = hy;
1840
 
                                        }
1841
 
                                }
1842
 
                                for(ai = np->firstarcinst; ai != NOARCINST; ai = ai->nextarcinst)
1843
 
                                {
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;
1849
 
                                }
1850
 
                                if (first) continue;
1851
 
                                if (np->lowx == totlx && np->highx == tothx &&
1852
 
                                        np->lowy == totly && np->highy == tothy) continue;
1853
 
 
1854
 
                                for(ni = np->firstinst; ni != NONODEINST; ni = ni->nextinst)
1855
 
                                {
1856
 
                                        growx = ((tothx - np->highx) + (totlx - np->lowx)) / 2;
1857
 
                                        growy = ((tothy - np->highy) + (totly - np->lowy)) / 2;
1858
 
                                        if (ni->transpose != 0)
1859
 
                                        {
1860
 
                                                makeangle(ni->rotation, ni->transpose, trans);
1861
 
                                        } else
1862
 
                                        {
1863
 
                                                makeangle((3600 - ni->rotation)%3600, 0, trans);
1864
 
                                        }
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);
1871
 
                                }
1872
 
                                np->lowx = totlx;   np->highx = tothx;
1873
 
                                np->lowy = totly;   np->highy = tothy;
1874
 
                                numchanged++;
1875
 
                        }
1876
 
                        if (numchanged != 0)
1877
 
                        {
1878
 
                                ttyputmsg(_("WARNING: due to changes in bounds calculation, %ld facet sizes were adjusted"),
1879
 
                                        numchanged);
1880
 
                                ttyputmsg(_("...should do Check&Repair library"));
1881
 
                        }
1882
 
                }
1883
 
 
1884
 
                /* create network information */
1885
 
                if (statusitem > 0) DiaSetText(statusitem, _("Building network data..."));
1886
 
                if (io_libinputreadmany > 0)
1887
 
                {
1888
 
                        /* many libraries read: renumber everything */
1889
 
                        (void)asktool(net_tool, "total-re-number");
1890
 
                } else
1891
 
                {
1892
 
                        /* just 1 library read: renumber it */
1893
 
                        (void)asktool(net_tool, "library-re-number", (INTBIG)lib);
1894
 
                }
1895
 
        }
1896
 
 
1897
 
        /* set the facet's technology */
1898
 
        for(np = lib->firstnodeproto; np != NONODEPROTO; np = np->nextnodeproto)
1899
 
                np->tech = whattech(np);
1900
 
 
1901
 
        /* check for incorrect layer counts on stored variables */
1902
 
        io_fixtechlayers();
1903
 
 
1904
 
        /* for versions 6.02 or earlier, convert text sizes */
1905
 
        if (major < 6 || (major == 6 && minor <= 2))
1906
 
        {
1907
 
#ifdef REPORTCONVERSION
1908
 
                ttyputmsg("   Converting text sizes");
1909
 
#endif
1910
 
                for(np = lib->firstnodeproto; np != NONODEPROTO; np = np->nextnodeproto)
1911
 
                {
1912
 
                        for(ni = np->firstnodeinst; ni != NONODEINST; ni = ni->nextnodeinst)
1913
 
                        {
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);
1921
 
                        }
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)
1925
 
                        {
1926
 
                                io_convertallrelativetext(pp->numvar, pp->firstvar);
1927
 
                                io_convertrelativetext(pp->textdescript);
1928
 
                        }
1929
 
                        io_convertallrelativetext(np->numvar, np->firstvar);
1930
 
                }
1931
 
                for(cell = lib->firstcell; cell != NOCELL; cell = cell->nextcell)
1932
 
                        io_convertallrelativetext(cell->numvar, cell->firstvar);
1933
 
                io_convertallrelativetext(lib->numvar, lib->firstvar);
1934
 
        }
1935
 
 
1936
 
        /* for versions before 6.04c, convert text descriptor values */
1937
 
        if (major < 6 ||
1938
 
                (major == 6 && minor < 4) ||
1939
 
                (major == 6 && minor == 4 && detail < 3))
1940
 
        {
1941
 
#ifdef REPORTCONVERSION
1942
 
                ttyputmsg("   Converting text descriptors");
1943
 
#endif
1944
 
                for(np = lib->firstnodeproto; np != NONODEPROTO; np = np->nextnodeproto)
1945
 
                {
1946
 
                        for(ni = np->firstnodeinst; ni != NONODEINST; ni = ni->nextnodeinst)
1947
 
                        {
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);
1955
 
                        }
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)
1959
 
                        {
1960
 
                                io_convertalltextdescriptors(pp->numvar, pp->firstvar);
1961
 
                                io_converttextdescriptor(pp->textdescript);
1962
 
                        }
1963
 
                        io_convertalltextdescriptors(np->numvar, np->firstvar);
1964
 
                }
1965
 
                for(cell = lib->firstcell; cell != NOCELL; cell = cell->nextcell)
1966
 
                        io_convertalltextdescriptors(cell->numvar, cell->firstvar);
1967
 
                io_convertalltextdescriptors(lib->numvar, lib->firstvar);
1968
 
        }
1969
 
 
1970
 
        /* for versions before 6.03r, convert variables on schematic primitives */
1971
 
        if (major < 6 ||
1972
 
                (major == 6 && minor < 3) ||
1973
 
                (major == 6 && minor == 3 && detail < 18))
1974
 
        {
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)
1980
 
                {
1981
 
                        for(ni = np->firstnodeinst; ni != NONODEINST; ni = ni->nextnodeinst)
1982
 
                        {
1983
 
                                if (ni->proto->primindex == 0) continue;
1984
 
                                if (ni->proto->tech == sch_tech)
1985
 
                                {
1986
 
                                        if (ni->proto == sch_transistorprim)
1987
 
                                        {
1988
 
                                                var = getvalkey((INTBIG)ni, VNODEINST, VSTRING, sch_transistortypekey);
1989
 
                                                if (var != NOVARIABLE)
1990
 
                                                {
1991
 
                                                        str = (char *)var->addr;
1992
 
                                                        if (namesamen(str, "nmos", 4) == 0)
1993
 
                                                        {
1994
 
                                                                ni->userbits |= TRANNMOS;    str += 4;
1995
 
                                                        } else if (namesamen(str, "dmos", 4) == 0)
1996
 
                                                        {
1997
 
                                                                ni->userbits |= TRANDMOS;    str += 4;
1998
 
                                                        } else if (namesamen(str, "pmos", 4) == 0)
1999
 
                                                        {
2000
 
                                                                ni->userbits |= TRANPMOS;    str += 4;
2001
 
                                                        } else if (namesamen(str, "npn", 3) == 0)
2002
 
                                                        {
2003
 
                                                                ni->userbits |= TRANNPN;     str += 3;
2004
 
                                                        } else if (namesamen(str, "pnp", 3) == 0)
2005
 
                                                        {
2006
 
                                                                ni->userbits |= TRANPNP;     str += 3;
2007
 
                                                        } else if (namesamen(str, "njfet", 5) == 0)
2008
 
                                                        {
2009
 
                                                                ni->userbits |= TRANNJFET;   str += 5;
2010
 
                                                        } else if (namesamen(str, "pjfet", 5) == 0)
2011
 
                                                        {
2012
 
                                                                ni->userbits |= TRANPJFET;   str += 5;
2013
 
                                                        } else if (namesamen(str, "dmes", 4) == 0)
2014
 
                                                        {
2015
 
                                                                ni->userbits |= TRANDMES;    str += 4;
2016
 
                                                        } else if (namesamen(str, "emes", 4) == 0)
2017
 
                                                        {
2018
 
                                                                ni->userbits |= TRANEMES;    str += 4;
2019
 
                                                        }
2020
 
                                                        if (*str == 0) (void)delvalkey((INTBIG)ni, VNODEINST, sch_transistortypekey); else
2021
 
                                                        {
2022
 
                                                                TDCOPY(olddescript, var->textdescript);
2023
 
                                                                (void)initinfstr();
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);
2029
 
                                                        }
2030
 
                                                }
2031
 
                                        } else if (ni->proto == sch_sourceprim)
2032
 
                                        {
2033
 
                                                var = getvalkey((INTBIG)ni, VNODEINST, VSTRING, sch_sourcekey);
2034
 
                                                if (var != NOVARIABLE)
2035
 
                                                {
2036
 
                                                        str = (char *)var->addr;
2037
 
                                                        if (namesamen(str, "vd", 2) == 0)
2038
 
                                                        {
2039
 
                                                                ni->userbits |= OLDSOURCEDCAN;   str += 2;
2040
 
                                                        } else if (namesamen(str, "v", 1) == 0)
2041
 
                                                        {
2042
 
                                                                ni->userbits |= OLDSOURCEDCV;   str++;
2043
 
                                                        } else if (namesamen(str, "cm", 2) == 0)
2044
 
                                                        {
2045
 
                                                                ni->userbits |= OLDSOURCECURMTR;   str += 2;
2046
 
                                                        } else if (namesamen(str, "c", 1) == 0)
2047
 
                                                        {
2048
 
                                                                ni->userbits |= OLDSOURCEDCC;   str++;
2049
 
                                                        } else if (namesamen(str, "t", 1) == 0)
2050
 
                                                        {
2051
 
                                                                ni->userbits |= OLDSOURCETRAN;   str++;
2052
 
                                                        } else if (namesamen(str, "a", 1) == 0)
2053
 
                                                        {
2054
 
                                                                ni->userbits |= OLDSOURCEAC;   str++;
2055
 
                                                        } else if (namesamen(str, "n", 1) == 0)
2056
 
                                                        {
2057
 
                                                                ni->userbits |= OLDSOURCENODE;   str++;
2058
 
                                                        } else if (namesamen(str, "x", 1) == 0)
2059
 
                                                        {
2060
 
                                                                ni->userbits |= OLDSOURCEEXT;   str++;
2061
 
                                                        } else if (namesamen(str, "b", 1) == 0)
2062
 
                                                        {
2063
 
                                                                ni->userbits |= OLDSOURCEBULK;   str++;
2064
 
                                                        } else if (namesamen(str, "s", 1) == 0)
2065
 
                                                        {
2066
 
                                                                ni->userbits |= OLDSOURCESPEC;   str++;
2067
 
                                                        }
2068
 
                                                        if (*str == '/') str++;
2069
 
                                                        if (*str == 0) (void)delvalkey((INTBIG)ni, VNODEINST, sch_sourcekey); else
2070
 
                                                        {
2071
 
                                                                TDCOPY(olddescript, var->textdescript);
2072
 
                                                                (void)initinfstr();
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);
2078
 
                                                        }
2079
 
                                                }
2080
 
                                        } else if (ni->proto == sch_diodeprim)
2081
 
                                        {
2082
 
                                                var = getvalkey((INTBIG)ni, VNODEINST, VSTRING, sch_diodekey);
2083
 
                                                if (var != NOVARIABLE)
2084
 
                                                {
2085
 
                                                        str = (char *)var->addr;
2086
 
                                                        while (*str == ' ' || *str == '\t') str++;
2087
 
                                                        if (tolower(*str) == 'z')
2088
 
                                                        {
2089
 
                                                                str++;
2090
 
                                                                ni->userbits |= DIODEZENER;
2091
 
                                                        }
2092
 
                                                        if (*str == 0) (void)delvalkey((INTBIG)ni, VNODEINST, sch_diodekey); else
2093
 
                                                        {
2094
 
                                                                TDCOPY(olddescript, var->textdescript);
2095
 
                                                                (void)initinfstr();
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);
2101
 
                                                        }
2102
 
                                                }
2103
 
                                        } else if (ni->proto == sch_capacitorprim)
2104
 
                                        {
2105
 
                                                var = getvalkey((INTBIG)ni, VNODEINST, VSTRING, sch_capacitancekey);
2106
 
                                                if (var != NOVARIABLE)
2107
 
                                                {
2108
 
                                                        str = (char *)var->addr;
2109
 
                                                        while (*str == ' ' || *str == '\t') str++;
2110
 
                                                        if (tolower(*str) == 'e')
2111
 
                                                        {
2112
 
                                                                str++;
2113
 
                                                                ni->userbits |= CAPACELEC;
2114
 
                                                        }
2115
 
                                                        if (*str == 0) (void)delvalkey((INTBIG)ni, VNODEINST, sch_capacitancekey); else
2116
 
                                                        {
2117
 
                                                                TDCOPY(olddescript, var->textdescript);
2118
 
                                                                (void)initinfstr();
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);
2124
 
                                                        }
2125
 
                                                }
2126
 
                                        } else if (ni->proto == sch_twoportprim)
2127
 
                                        {
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)
2132
 
                                                {
2133
 
                                                        str = (char *)var->addr;
2134
 
                                                        while (*str == ' ') str++;
2135
 
                                                        switch (tolower(*str))
2136
 
                                                        {
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;
2142
 
                                                        }
2143
 
                                                        nextchangequiet();
2144
 
                                                        if (*str == 0) (void)delvalkey((INTBIG)ni, VNODEINST, sch_twoportkey); else
2145
 
                                                        {
2146
 
                                                                TDCOPY(olddescript, var->textdescript);
2147
 
                                                                (void)initinfstr();
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);
2153
 
                                                        }
2154
 
                                                }
2155
 
                                        } else if (ni->proto == sch_ffprim)
2156
 
                                        {
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)
2161
 
                                                {
2162
 
                                                        for (str = (char *)var->addr; *str != 0; str++)
2163
 
                                                        {
2164
 
                                                                if (namesamen(str, "rs", 2) == 0)
2165
 
                                                                {
2166
 
                                                                        ni->userbits |= FFTYPERS;
2167
 
                                                                        str++;
2168
 
                                                                        continue;
2169
 
                                                                }
2170
 
                                                                if (namesamen(str, "jk", 2) == 0)
2171
 
                                                                {
2172
 
                                                                        ni->userbits |= FFTYPEJK;
2173
 
                                                                        str++;
2174
 
                                                                        continue;
2175
 
                                                                }
2176
 
                                                                if (namesamen(str, "t", 1) == 0)
2177
 
                                                                {
2178
 
                                                                        ni->userbits |= FFTYPET;
2179
 
                                                                        continue;
2180
 
                                                                }
2181
 
                                                                if (namesamen(str, "d", 1) == 0)
2182
 
                                                                {
2183
 
                                                                        ni->userbits |= FFTYPED;
2184
 
                                                                        continue;
2185
 
                                                                }
2186
 
                                                                if (namesamen(str, "ms", 2) == 0)
2187
 
                                                                {
2188
 
                                                                        ni->userbits |= FFCLOCKMS;
2189
 
                                                                        str++;
2190
 
                                                                        continue;
2191
 
                                                                }
2192
 
                                                                if (namesamen(str, "p", 1) == 0)
2193
 
                                                                {
2194
 
                                                                        ni->userbits |= FFCLOCKP;
2195
 
                                                                        continue;
2196
 
                                                                }
2197
 
                                                                if (namesamen(str, "n", 1) == 0)
2198
 
                                                                {
2199
 
                                                                        ni->userbits |= FFCLOCKN;
2200
 
                                                                        continue;
2201
 
                                                                }
2202
 
                                                        }
2203
 
                                                        nextchangequiet();
2204
 
                                                        (void)delvalkey((INTBIG)ni, VNODEINST, sch_flipfloptypekey);
2205
 
                                                }
2206
 
                                        }
2207
 
                                }
2208
 
                        }
2209
 
                }
2210
 
        }
2211
 
 
2212
 
        /* for versions before 6.05bh, make sure that "far text" bit is set right */
2213
 
        if (io_libinputrecursivedepth == 0)
2214
 
        {
2215
 
                if (major < 6 ||
2216
 
                        (major == 6 && minor < 5) ||
2217
 
                        (major == 6 && minor == 5 && detail < 60))
2218
 
                {
2219
 
                        for(olib = el_curlib; olib != NOLIBRARY; olib = olib->nextlibrary)
2220
 
                                for(np = olib->firstnodeproto; np != NONODEPROTO; np = np->nextnodeproto)
2221
 
                        {
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);
2226
 
                        }
2227
 
                }
2228
 
        }
2229
 
 
2230
 
        /* for versions before 6.05bi, make all facet centers be "visible only inside facet" */
2231
 
        if (major < 6 ||
2232
 
                (major == 6 && minor < 5) ||
2233
 
                (major == 6 && minor == 5 && detail < 61))
2234
 
        {
2235
 
                for(np = lib->firstnodeproto; np != NONODEPROTO; np = np->nextnodeproto)
2236
 
                {
2237
 
                        for(ni = np->firstnodeinst; ni != NONODEINST; ni = ni->nextnodeinst)
2238
 
                        {
2239
 
                                if (ni->proto != gen_facetcenterprim) continue;
2240
 
                                ni->userbits |= NVISIBLEINSIDE;
2241
 
                        }
2242
 
                }
2243
 
        }
2244
 
 
2245
 
        /* for versions before 6.05ba, convert source nodes */
2246
 
        if (major < 6 ||
2247
 
                (major == 6 && minor < 5) ||
2248
 
                (major == 6 && minor == 5 && detail < 53))
2249
 
        {
2250
 
                /* change all Wire_Pins that are 1x1 to be 0.5x0.5 */
2251
 
                numchanged = 0;
2252
 
                for(np = lib->firstnodeproto; np != NONODEPROTO; np = np->nextnodeproto)
2253
 
                {
2254
 
                        for(ni = np->firstnodeinst; ni != NONODEINST; ni = ni->nextnodeinst)
2255
 
                        {
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)
2262
 
                                {
2263
 
                                        modifynodeinst(ni, lambda/4, lambda/4, -lambda/4, -lambda/4, 0, 0);
2264
 
                                        numchanged++;
2265
 
                                }
2266
 
                        }
2267
 
                }
2268
 
                if (numchanged != 0)
2269
 
                        ttyputmsg(_("Note: reduced the size of %ld schematic wire pins from 1x1 to 0.5x0.5"),
2270
 
                                numchanged);
2271
 
        }
2272
 
 
2273
 
        /* for versions before 6.05al, convert source nodes */
2274
 
        if (major < 6 ||
2275
 
                (major == 6 && minor < 5) ||
2276
 
                (major == 6 && minor == 5 && detail < 38))
2277
 
        {
2278
 
                for(np = lib->firstnodeproto; np != NONODEPROTO; np = np->nextnodeproto)
2279
 
                {
2280
 
                        changed = FALSE;
2281
 
                        for(ni = np->firstnodeinst; ni != NONODEINST; ni = ni->nextnodeinst)
2282
 
                        {
2283
 
                                if (ni->proto->primindex == 0) continue;
2284
 
                                if (ni->proto->tech != sch_tech) continue;
2285
 
                                if (ni->proto != sch_sourceprim) continue;
2286
 
                                str = 0;
2287
 
                                switch (ni->userbits&NTECHBITS)
2288
 
                                {
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;
2296
 
                                }
2297
 
                                if (str == 0) continue;
2298
 
 
2299
 
                                /* make sure the "spiceparts" library is read */
2300
 
                                olib = getlibrary("spiceparts");
2301
 
                                if (olib == NOLIBRARY)
2302
 
                                {
2303
 
                                        par[0] = "library";
2304
 
                                        par[1] = "read";
2305
 
                                        par[2] = "spiceparts.txt";
2306
 
                                        par[3] = "text";
2307
 
                                        telltool(us_tool, 4, par);
2308
 
                                        olib = getlibrary("spiceparts");
2309
 
                                        if (olib == NOLIBRARY)
2310
 
                                        {
2311
 
                                                ttyputerr(_("Cannot find spice parts library for source conversion"));
2312
 
                                                break;
2313
 
                                        }
2314
 
                                }
2315
 
                                sprintf(line, "spiceparts:%s", str);
2316
 
                                onp = getnodeproto(line);
2317
 
                                if (onp == NONODEPROTO)
2318
 
                                {
2319
 
                                        ttyputerr(_("Cannot find '%s' for source conversion"), line);
2320
 
                                        break;
2321
 
                                }
2322
 
                                newni = replacenodeinst(ni, onp, TRUE, TRUE);
2323
 
                                if (newni != NONODEINST)
2324
 
                                        newni->userbits |= NEXPAND;
2325
 
                                changed = TRUE;
2326
 
                        }
2327
 
                        if (ni != NONODEINST) break;
2328
 
                        if (changed)
2329
 
                                ttyputmsg(_("Warning: SPICE components converted in facet %s.  Additional editing may be required."),
2330
 
                                        describenodeproto(np));
2331
 
                }
2332
 
        }
2333
 
 
2334
 
        /* for versions before 6.04o, separate transistor size and SPICE info */
2335
 
        if (major < 6 ||
2336
 
                (major == 6 && minor < 4) ||
2337
 
                (major == 6 && minor == 4 && detail < 15))
2338
 
        {
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)
2344
 
                {
2345
 
                        for(ni = np->firstnodeinst; ni != NONODEINST; ni = ni->nextnodeinst)
2346
 
                        {
2347
 
                                if (ni->proto->primindex == 0) continue;
2348
 
                                if (ni->proto->tech != sch_tech) continue;
2349
 
 
2350
 
                                /* convert "SCHEM_source" to "SIM_spice_model" */
2351
 
                                var = getvalkey((INTBIG)ni, VNODEINST, -1, sch_sourcekey);
2352
 
                                if (var != NOVARIABLE)
2353
 
                                {
2354
 
                                        TDCOPY(olddescript, var->textdescript);
2355
 
                                        newvar = setvalkey((INTBIG)ni, VNODEINST, sch_spicemodelkey, var->addr,
2356
 
                                                var->type);
2357
 
                                        if (newvar != 0)
2358
 
                                                TDCOPY(newvar->textdescript, olddescript);
2359
 
                                        (void)delvalkey((INTBIG)ni, VNODEINST, sch_sourcekey);
2360
 
                                }
2361
 
 
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;
2366
 
 
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);
2374
 
#endif
2375
 
                                for(pt = str; *pt != 0; pt++) if (*pt == '/') break;
2376
 
                                if (*pt == '/')
2377
 
                                {
2378
 
                                        *pt++ = 0;
2379
 
 
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)
2386
 
                                        {
2387
 
                                                TDCOPY(newvar->textdescript, olddescript);
2388
 
                                                TDSETOFF(newvar->textdescript, TDGETXOFF(newvar->textdescript)+xoff,
2389
 
                                                        TDGETYOFF(newvar->textdescript)+yoff);
2390
 
                                        }
2391
 
 
2392
 
                                        str = pt;
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)
2399
 
                                        {
2400
 
                                                TDCOPY(newvar->textdescript, olddescript);
2401
 
                                                size = TDGETSIZE(newvar->textdescript);
2402
 
                                                i = TXTGETPOINTS(size);
2403
 
                                                if (i > 3) size = TXTSETPOINTS(i-2); else
2404
 
                                                {
2405
 
                                                        i = TXTGETQLAMBDA(size);
2406
 
                                                        if (i > 3) size = TXTSETQLAMBDA(i-2);
2407
 
                                                }
2408
 
                                                TDSETSIZE(newvar->textdescript, size);
2409
 
                                                TDSETOFF(newvar->textdescript, TDGETXOFF(newvar->textdescript)-xoff,
2410
 
                                                        TDGETYOFF(newvar->textdescript)-yoff);
2411
 
                                        }
2412
 
 
2413
 
                                        /* see if a SPICE model is at the end */
2414
 
                                        if (*pt != 0)
2415
 
                                        {
2416
 
                                                type = VSTRING | (oldtype & (VCODE1 | VCODE2 | VDISPLAY | VDONTSAVE));
2417
 
                                                newvar = setvalkey((INTBIG)ni, VNODEINST, sch_spicemodelkey,
2418
 
                                                        (INTBIG)pt, type);
2419
 
                                                if (newvar != NOVARIABLE)
2420
 
                                                        TDCOPY(newvar->textdescript, olddescript);
2421
 
                                        }
2422
 
                                } else
2423
 
                                {
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);
2430
 
                                }
2431
 
                                (void)delvalkey((INTBIG)ni, VNODEINST, sch_transistortypekey);
2432
 
                        }
2433
 
                }
2434
 
        }
2435
 
 
2436
 
        /* for versions before 6.03g, convert schematic and mocmossub primitives */
2437
 
        if (major < 6 ||
2438
 
                (major == 6 && minor < 3) ||
2439
 
                (major == 6 && minor == 3 && detail < 7))
2440
 
        {
2441
 
#ifdef REPORTCONVERSION
2442
 
                ttyputmsg("   Converting schematic and MOSIS CMOS primitives");
2443
 
#endif
2444
 
                for(np = lib->firstnodeproto; np != NONODEPROTO; np = np->nextnodeproto)
2445
 
                {
2446
 
                        for(ni = np->firstnodeinst; ni != NONODEINST; ni = ni->nextnodeinst)
2447
 
                        {
2448
 
                                if (ni->proto->primindex == 0) continue;
2449
 
                                if (ni->proto->tech == sch_tech)
2450
 
                                {
2451
 
                                        if (ni->proto == sch_pwrprim)
2452
 
                                        {
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)
2456
 
                                        {
2457
 
                                                lam = lib->lambda[sch_tech->techindex];
2458
 
                                                io_fixupnodeinst(ni, lam/2, 0, -lam/2, 0);
2459
 
                                        } else if (ni->proto == sch_capacitorprim)
2460
 
                                        {
2461
 
                                                lam = lib->lambda[sch_tech->techindex];
2462
 
                                                io_fixupnodeinst(ni, lam/2, 0, -lam/2, 0);
2463
 
                                        } else if (ni->proto == sch_resistorprim)
2464
 
                                        {
2465
 
                                                lam = lib->lambda[sch_tech->techindex];
2466
 
                                                io_fixupnodeinst(ni, 0, lam/2, 0, -lam/2);
2467
 
                                        }
2468
 
                                } else if (ni->proto->tech == mocmos_tech)
2469
 
                                {
2470
 
                                        if (ni->proto == mocmos_metal1metal2prim)
2471
 
                                        {
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)
2475
 
                                        {
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)
2479
 
                                        {
2480
 
                                                lam = lib->lambda[mocmos_tech->techindex];
2481
 
                                                io_fixupnodeinst(ni, -lam, -lam, lam, lam);
2482
 
                                        } else if (ni->proto == mocmos_ptransistorprim)
2483
 
                                        {
2484
 
                                                lam = lib->lambda[mocmos_tech->techindex];
2485
 
                                                io_fixupnodeinst(ni, 0, -lam, 0, lam);
2486
 
                                        } else if (ni->proto == mocmos_ntransistorprim)
2487
 
                                        {
2488
 
                                                lam = lib->lambda[mocmos_tech->techindex];
2489
 
                                                io_fixupnodeinst(ni, 0, -lam, 0, lam);
2490
 
                                        } else if (ni->proto == mocmos_metal1poly2prim)
2491
 
                                        {
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)
2495
 
                                        {
2496
 
                                                lam = lib->lambda[mocmos_tech->techindex];
2497
 
                                                io_fixupnodeinst(ni, -lam*4, -lam*4, lam*4, lam*4);
2498
 
                                        }
2499
 
                                }
2500
 
                        }
2501
 
                }
2502
 
        }
2503
 
 
2504
 
        /* for versions before 6.03l, convert mocmossub via4-via6 */
2505
 
        if (major < 6 ||
2506
 
                (major == 6 && minor < 3) ||
2507
 
                (major == 6 && minor == 3 && detail < 12))
2508
 
        {
2509
 
#ifdef REPORTCONVERSION
2510
 
                ttyputmsg("   Converting MOSIS CMOS vias");
2511
 
#endif
2512
 
                for(np = lib->firstnodeproto; np != NONODEPROTO; np = np->nextnodeproto)
2513
 
                {
2514
 
                        for(ni = np->firstnodeinst; ni != NONODEINST; ni = ni->nextnodeinst)
2515
 
                        {
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)
2521
 
                                {
2522
 
                                        lam = lib->lambda[mocmos_tech->techindex];
2523
 
                                        io_fixupnodeinst(ni, -lam, -lam, lam, lam);
2524
 
                                }
2525
 
                        }
2526
 
                }
2527
 
        }
2528
 
 
2529
 
        /* for versions before 6.03aa, convert mocmossub well contacts */
2530
 
        if (major < 6 ||
2531
 
                (major == 6 && minor < 3) ||
2532
 
                (major == 6 && minor == 3 && detail < 27))
2533
 
        {
2534
 
                for(np = lib->firstnodeproto; np != NONODEPROTO; np = np->nextnodeproto)
2535
 
                {
2536
 
                        for(ni = np->firstnodeinst; ni != NONODEINST; ni = ni->nextnodeinst)
2537
 
                        {
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)
2542
 
                                {
2543
 
                                        lam = lib->lambda[mocmos_tech->techindex];
2544
 
                                        io_fixupnodeinst(ni, -lam-lam/2, -lam-lam/2, lam+lam/2, lam+lam/2);
2545
 
                                }
2546
 
                        }
2547
 
                }
2548
 
        }
2549
 
 
2550
 
        /* for versions before 6.05ab, derive "far text" bits */
2551
 
        if (major < 6 ||
2552
 
                (major == 6 && minor < 5) ||
2553
 
                (major == 6 && minor == 5 && detail < 28))
2554
 
        {
2555
 
                for(np = lib->firstnodeproto; np != NONODEPROTO; np = np->nextnodeproto)
2556
 
                {
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);
2561
 
                }
2562
 
        }
2563
 
 
2564
 
        /* for versions before 6.05ak, convert quick-key bindings */
2565
 
        if (major < 6 ||
2566
 
                (major == 6 && minor < 5) ||
2567
 
                (major == 6 && minor == 5 && detail < 37))
2568
 
        {
2569
 
                var = getvalkey((INTBIG)us_tool, VTOOL, VSTRING|VISARRAY, us_quickkeyskey);
2570
 
                if (var != NOVARIABLE)
2571
 
                {
2572
 
                        len = getlength(var);
2573
 
                        newlist = (char **)emalloc(len * (sizeof (char *)), el_tempcluster);
2574
 
                        changed = FALSE;
2575
 
                        for(i=0; i<len; i++)
2576
 
                        {
2577
 
                                pt = ((char **)var->addr)[i];
2578
 
                                (void)allocstring(&newlist[i], pt, el_tempcluster);
2579
 
                                if (pt[1] != '/') continue;
2580
 
                                j = pt[0] & 0xFF;
2581
 
                                if (j >= 0216 && j <= 0231)
2582
 
                                {
2583
 
                                        /* convert former "function" key */
2584
 
                                        sprintf(line, "F%ld%s", j - 0215, &pt[1]);
2585
 
                                        (void)reallocstring(&newlist[i], line, el_tempcluster);
2586
 
                                        changed = TRUE;
2587
 
                                }
2588
 
                        }
2589
 
                        if (changed)
2590
 
                        {
2591
 
                                nextchangequiet();
2592
 
                                setvalkey((INTBIG)us_tool, VTOOL, us_quickkeyskey, (INTBIG)newlist,
2593
 
                                        VSTRING|VISARRAY|(len<<VLENGTHSH));
2594
 
                        }
2595
 
                        for(i=0; i<len; i++) efree((char *)newlist[i]);
2596
 
                        efree((char *)newlist);
2597
 
                }
2598
 
        }
2599
 
 
2600
 
        /* the rest of the changes are just for version 4 or earlier */
2601
 
        if (major >= 5) return;
2602
 
 
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");
2606
 
 
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]);
2611
 
 
2612
 
        /* now scale */
2613
 
        for(np = lib->firstnodeproto; np != NONODEPROTO; np = np->nextnodeproto)
2614
 
        {
2615
 
                var = getvalkey((INTBIG)np, VNODEPROTO, VINTEGER|VISARRAY, el_prototype_center_key);
2616
 
                if (var != NOVARIABLE)
2617
 
                {
2618
 
                        ((INTBIG *)var->addr)[0] *= 20;
2619
 
                        ((INTBIG *)var->addr)[1] *= 20;
2620
 
                }
2621
 
                for(ni = np->firstnodeinst; ni != NONODEINST; ni = ni->nextnodeinst)
2622
 
                {
2623
 
                        ni->lowx *= 20;   ni->highx *= 20;
2624
 
                        ni->lowy *= 20;   ni->highy *= 20;
2625
 
                        ni->rotation *= 10;
2626
 
                        var = getvalkey((INTBIG)ni, VNODEINST, VINTEGER, edtec_option_key);
2627
 
                        if (var != NOVARIABLE)
2628
 
                        {
2629
 
                                if (var->addr == TECHLAMBDA)
2630
 
                                {
2631
 
                                        var = getvalkey((INTBIG)ni, VNODEINST, VSTRING, art_messagekey);
2632
 
                                        if (var != NOVARIABLE)
2633
 
                                        {
2634
 
                                                lam = myatoi(&((char *)var->addr)[8]);
2635
 
                                                (void)sprintf(line, "Lambda: %ld", lam*20);
2636
 
                                                nextchangequiet();
2637
 
                                                (void)setvalkey((INTBIG)ni, VNODEINST, art_messagekey,
2638
 
                                                        (INTBIG)line, VSTRING|VDISPLAY);
2639
 
                                        }
2640
 
                                }
2641
 
                        }
2642
 
                        var = getvalkey((INTBIG)ni, VNODEINST, VINTEGER|VISARRAY, el_trace_key);
2643
 
                        if (var != NOVARIABLE)
2644
 
                        {
2645
 
                                i = getlength(var);
2646
 
                                for(j=0; j<i; j++) ((INTBIG *)var->addr)[j] *= 20;
2647
 
                        }
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);
2651
 
                }
2652
 
        }
2653
 
 
2654
 
        for(np = lib->firstnodeproto; np != NONODEPROTO; np = np->nextnodeproto)
2655
 
        {
2656
 
                for(ai = np->firstarcinst; ai != NOARCINST; ai = ai->nextarcinst)
2657
 
                {
2658
 
                        ai->width *= 20;
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;
2664
 
                        for(i=0; i<2; i++)
2665
 
                        {
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;
2671
 
 
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
2678
 
                                {
2679
 
                                        ai->end[i].xpos = lx;   ai->end[i].ypos = ly;
2680
 
                                }
2681
 
                        }
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);
2685
 
                }
2686
 
                db_boundfacet(np, &np->lowx, &np->highx, &np->lowy, &np->highy);
2687
 
                io_fixrtree(np->rtree);
2688
 
        }
2689
 
 
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]);
2694
 
}
2695
 
 
2696
 
#define OLDSIZE      01700
2697
 
#define OLDSIZESH        6
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    */
2714
 
 
2715
 
void io_convertalltextdescriptors(INTSML numvar, VARIABLE *firstvar)
2716
 
{
2717
 
        REGISTER INTBIG i;
2718
 
        REGISTER VARIABLE *var;
2719
 
 
2720
 
        for(i=0; i<numvar; i++)
2721
 
        {
2722
 
                var = &firstvar[i];
2723
 
                io_converttextdescriptor(var->textdescript);
2724
 
        }
2725
 
}
2726
 
 
2727
 
void io_converttextdescriptor(UINTBIG *descript)
2728
 
{
2729
 
        REGISTER INTBIG size;
2730
 
 
2731
 
        size = (descript[0]&OLDSIZE) >> OLDSIZESH;
2732
 
        switch (size)
2733
 
        {
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;
2750
 
        }
2751
 
        descript[0] &= ~OLDSIZE;
2752
 
        descript[1] = size << VTSIZESH;
2753
 
}
2754
 
 
2755
 
void io_fixupnodeinst(NODEINST *ni, INTBIG dlx, INTBIG dly, INTBIG dhx, INTBIG dhy)
2756
 
{
2757
 
        REGISTER PORTARCINST *pi;
2758
 
        REGISTER ARCINST *ai;
2759
 
 
2760
 
        for(pi = ni->firstportarcinst; pi != NOPORTARCINST; pi = pi->nextportarcinst)
2761
 
        {
2762
 
                ai = pi->conarcinst;
2763
 
                (void)(*el_curconstraint->setobject)((INTBIG)ai, VARCINST, CHANGETYPETEMPUNRIGID, 0);
2764
 
        }
2765
 
        modifynodeinst(ni, dlx, dly, dhx, dhy, 0, 0);
2766
 
}
2767
 
 
2768
 
void io_convertallrelativetext(INTSML numvar, VARIABLE *firstvar)
2769
 
{
2770
 
        REGISTER INTBIG i;
2771
 
        REGISTER VARIABLE *var;
2772
 
 
2773
 
        for(i=0; i<numvar; i++)
2774
 
        {
2775
 
                var = &firstvar[i];
2776
 
                io_convertrelativetext(var->textdescript);
2777
 
        }
2778
 
}
2779
 
 
2780
 
void io_convertrelativetext(UINTBIG *descript)
2781
 
{
2782
 
        REGISTER INTBIG size;
2783
 
 
2784
 
        size = (descript[0]&OLDSIZE) >> OLDSIZESH;
2785
 
        if (size >= OLDTXT4P && size <= OLDTXT20P) return;
2786
 
 
2787
 
        if (size <= 13)
2788
 
        {
2789
 
                /* TXTSMALL */
2790
 
                descript[0] = (descript[0] & ~OLDSIZE) | (OLDTXT1L << OLDSIZESH);
2791
 
                return;
2792
 
        }
2793
 
 
2794
 
        if (size == 14)
2795
 
        {
2796
 
                /* TXTMEDIUM */
2797
 
                descript[0] = (descript[0] & ~OLDSIZE) | (OLDTXT2L << OLDSIZESH);
2798
 
                return;
2799
 
        }
2800
 
 
2801
 
        /* TXTLARGE */
2802
 
        descript[0] = (descript[0] & ~OLDSIZE) | (OLDTXT3L << OLDSIZESH);
2803
 
}
2804
 
 
2805
 
/*
2806
 
 * Routine to convert old primitive names to their proper nodeprotos.
2807
 
 */
2808
 
NODEPROTO *io_convertoldprimitives(TECHNOLOGY *tech, char *name)
2809
 
{
2810
 
        if (namesame(name, "Cell-Center") == 0) return(gen_facetcenterprim);
2811
 
        if (tech == art_tech)
2812
 
        {
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);
2819
 
        }
2820
 
        if (tech == mocmos_tech)
2821
 
        {
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);
2826
 
        }
2827
 
        return(NONODEPROTO);
2828
 
}
2829
 
 
2830
 
/*
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.
2834
 
 */
2835
 
void io_getversion(LIBRARY *lib, INTBIG *major, INTBIG *minor, INTBIG *detail)
2836
 
{
2837
 
        REGISTER VARIABLE *var;
2838
 
        INTBIG emajor, eminor, edetail;
2839
 
        char *libversion;
2840
 
 
2841
 
        var = getval((INTBIG)lib, VLIBRARY, VSTRING, "LIB_former_version");
2842
 
        if (var == NOVARIABLE)
2843
 
        {
2844
 
                *major = *minor = *detail = 0;
2845
 
                return;
2846
 
        }
2847
 
        libversion = (char *)var->addr;
2848
 
        parseelectricversion(libversion, major, minor, detail);
2849
 
 
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))
2855
 
        {
2856
 
                ttyputerr(_("Warning: library %s comes from a NEWER version of Electric (%s)"),
2857
 
                        lib->libname, libversion);
2858
 
        }
2859
 
}
2860
 
 
2861
 
/* Technology: Lambda Adjustment */
2862
 
static DIALOGITEM io_techadjlamdialogitems[] =
2863
 
{
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.")}
2880
 
};
2881
 
static DIALOG io_techadjlamdialog = {{75,75,340,596}, N_("Lambda Value Adjustment"), 0, 16, io_techadjlamdialogitems};
2882
 
 
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) */
2891
 
 
2892
 
/*
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.
2896
 
 */
2897
 
void io_unifylambdavalues(LIBRARY *lib)
2898
 
{
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,
2905
 
                oldbits;
2906
 
        REGISTER char *pt;
2907
 
        float lambdainmicrons;
2908
 
        char line[50];
2909
 
 
2910
 
        /* see if this library has incompatible lambda values */
2911
 
        for(tech = el_technologies; tech != NOTECHNOLOGY; tech = tech->nexttechnology)
2912
 
        {
2913
 
                if (tech == art_tech) continue;
2914
 
                for(olib = el_curlib; olib != NOLIBRARY; olib = olib->nextlibrary)
2915
 
                {
2916
 
                        if (lib->lambda[tech->techindex] != olib->lambda[tech->techindex])
2917
 
                                break;
2918
 
                }
2919
 
                if (olib != NOLIBRARY) break;
2920
 
        }
2921
 
        if (tech == NOTECHNOLOGY) return;
2922
 
 
2923
 
        /* this library has different values: check usage in this and other libraries */
2924
 
        for(olib = el_curlib; olib != NOLIBRARY; olib = olib->nextlibrary)
2925
 
        {
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;
2929
 
        }
2930
 
        for(olib = el_curlib; olib != NOLIBRARY; olib = olib->nextlibrary)
2931
 
        {
2932
 
                for(np = olib->firstnodeproto; np != NONODEPROTO; np = np->nextnodeproto)
2933
 
                {
2934
 
                        for(ni = np->firstnodeinst; ni != NONODEINST; ni = ni->nextnodeinst)
2935
 
                        {
2936
 
                                if (ni->proto->primindex == 0) continue;
2937
 
                                tech = ni->proto->tech;
2938
 
                                ((NODEPROTO **)olib->temp1)[tech->techindex] = np;
2939
 
                        }
2940
 
                        for(ai = np->firstarcinst; ai != NOARCINST; ai = ai->nextarcinst)
2941
 
                        {
2942
 
                                tech = ai->proto->tech;
2943
 
                                ((NODEPROTO **)olib->temp1)[tech->techindex] = np;
2944
 
                        }
2945
 
                }
2946
 
        }
2947
 
 
2948
 
        /* see if there are inconsistencies that cannot be automatically resolved */
2949
 
        for(tech = el_technologies; tech != NOTECHNOLOGY; tech = tech->nexttechnology)
2950
 
        {
2951
 
                if (tech == art_tech) continue;
2952
 
                for(olib = el_curlib; olib != NOLIBRARY; olib = olib->nextlibrary)
2953
 
                {
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])
2957
 
                                break;
2958
 
                }
2959
 
                if (olib != NOLIBRARY) break;
2960
 
        }
2961
 
        if (tech != NOTECHNOLOGY)
2962
 
        {
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)
2968
 
                {
2969
 
                        if (tech == art_tech) continue;
2970
 
                        for(olib = el_curlib; olib != NOLIBRARY; olib = olib->nextlibrary)
2971
 
                        {
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])
2975
 
                                        break;
2976
 
                        }
2977
 
                        if (olib == NOLIBRARY) continue;
2978
 
                        DiaStuffLine(DTLA_TECHLIST, tech->techname);
2979
 
                }
2980
 
                DiaSelectLine(DTLA_TECHLIST, 0);
2981
 
                recompute = 1;
2982
 
                tech = NOTECHNOLOGY;
2983
 
                for(;;)
2984
 
                {
2985
 
                        if (recompute != 0)
2986
 
                        {
2987
 
                                recompute = 0;
2988
 
 
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;
2995
 
 
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)
2999
 
                                {
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;
3004
 
                                }
3005
 
                                if (olib != NOLIBRARY) curunit = olib->lambda[tech->techindex];
3006
 
 
3007
 
                                /* see if it has already been overridden */
3008
 
                                if (((INTBIG *)lib->temp1)[tech->techindex] == 0) newunit = curunit;
3009
 
 
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)
3018
 
                                {
3019
 
                                        DiaDimItem(DTLA_USENEW);
3020
 
                                        DiaDimItem(DTLA_USECUR);
3021
 
                                } else
3022
 
                                {
3023
 
                                        DiaUnDimItem(DTLA_USENEW);
3024
 
                                        DiaUnDimItem(DTLA_USECUR);
3025
 
                                }
3026
 
                        }
3027
 
                        itemHit = DiaNextHit();
3028
 
                        if (itemHit == OK) break;
3029
 
                        if (itemHit == DTLA_TECHLIST) recompute = 1;
3030
 
                        if (itemHit == DTLA_USENEW)
3031
 
                        {
3032
 
                                /* use new unit */
3033
 
                                if (tech != NOTECHNOLOGY)
3034
 
                                {
3035
 
                                        for(olib = el_curlib; olib != NOLIBRARY; olib = olib->nextlibrary)
3036
 
                                        {
3037
 
                                                if ((olib->userbits&HIDDENLIBRARY) != 0) continue;
3038
 
                                                if (((NODEPROTO **)olib->temp1)[tech->techindex] == NONODEPROTO) continue;
3039
 
                                                ((NODEPROTO **)olib->temp1)[tech->techindex] = 0;
3040
 
                                        }
3041
 
                                }
3042
 
                                recompute = 1;
3043
 
                                continue;
3044
 
                        }
3045
 
                        if (itemHit == DTLA_USENEWALWAYS)
3046
 
                        {
3047
 
                                /* use new unit always */
3048
 
                                for(otech = el_technologies; otech != NOTECHNOLOGY; otech = otech->nexttechnology)
3049
 
                                {
3050
 
                                        for(olib = el_curlib; olib != NOLIBRARY; olib = olib->nextlibrary)
3051
 
                                        {
3052
 
                                                if ((olib->userbits&HIDDENLIBRARY) != 0) continue;
3053
 
                                                if (((NODEPROTO **)olib->temp1)[otech->techindex] == NONODEPROTO) continue;
3054
 
                                                ((NODEPROTO **)olib->temp1)[otech->techindex] = 0;
3055
 
                                        }
3056
 
                                }
3057
 
                                recompute = 1;
3058
 
                                DiaDimItem(DTLA_USECURALWAYS);
3059
 
                                DiaDimItem(DTLA_USENEWALWAYS);
3060
 
                                continue;
3061
 
                        }
3062
 
                        if (itemHit == DTLA_USECURALWAYS)
3063
 
                        {
3064
 
                                /* use current unit always */
3065
 
                                for(otech = el_technologies; otech != NOTECHNOLOGY; otech = otech->nexttechnology)
3066
 
                                        ((NODEPROTO **)lib->temp1)[otech->techindex] = 0;
3067
 
                                recompute = 1;
3068
 
                                DiaDimItem(DTLA_USECURALWAYS);
3069
 
                                DiaDimItem(DTLA_USENEWALWAYS);
3070
 
                                continue;
3071
 
                        }
3072
 
                        if (itemHit == DTLA_USECUR)
3073
 
                        {
3074
 
                                /* use current unit */
3075
 
                                if (tech != NOTECHNOLOGY) ((NODEPROTO **)lib->temp1)[tech->techindex] = 0;
3076
 
                                recompute = 1;
3077
 
                                continue;
3078
 
                        }
3079
 
                }
3080
 
                DiaDoneDialog();
3081
 
        }
3082
 
 
3083
 
        /* adjust lambda values in old libraries to match this one */
3084
 
        for(olib = el_curlib; olib != NOLIBRARY; olib = olib->nextlibrary)
3085
 
        {
3086
 
                if (olib == lib) continue;
3087
 
 
3088
 
                /* see how many technologies are affected */
3089
 
                count = 0;
3090
 
                for(tech = el_technologies; tech != NOTECHNOLOGY; tech = tech->nexttechnology)
3091
 
                {
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;
3095
 
                        count++;
3096
 
                }
3097
 
                if (count == 0) continue;
3098
 
 
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;
3104
 
                count = 0;
3105
 
                for(tech = el_technologies; tech != NOTECHNOLOGY; tech = tech->nexttechnology)
3106
 
                {
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];
3112
 
                        count++;
3113
 
                }
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);
3120
 
        }
3121
 
 
3122
 
        /* change lambda values in this library to match old ones */
3123
 
        count = 0;
3124
 
        for(tech = el_technologies; tech != NOTECHNOLOGY; tech = tech->nexttechnology)
3125
 
        {
3126
 
                for(olib = el_curlib; olib != NOLIBRARY; olib = olib->nextlibrary)
3127
 
                {
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])
3131
 
                                break;
3132
 
                }
3133
 
                if (olib == NOLIBRARY) continue;
3134
 
                count++;
3135
 
        }
3136
 
        if (count != 0)
3137
 
        {
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;
3143
 
                count = 0;
3144
 
                for(tech = el_technologies; tech != NOTECHNOLOGY; tech = tech->nexttechnology)
3145
 
                {
3146
 
                        for(olib = el_curlib; olib != NOLIBRARY; olib = olib->nextlibrary)
3147
 
                        {
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])
3151
 
                                        break;
3152
 
                        }
3153
 
                        if (olib == NOLIBRARY) continue;
3154
 
                        techarray[count] = tech;
3155
 
                        newlamarray[count] = olib->lambda[tech->techindex];
3156
 
                        count++;
3157
 
                }
3158
 
                changelambda(count, techarray, newlamarray, lib, 1);
3159
 
                efree((char *)techarray);
3160
 
                efree((char *)newlamarray);
3161
 
        }
3162
 
 
3163
 
        /* free memory used here */
3164
 
        for(olib = el_curlib; olib != NOLIBRARY; olib = olib->nextlibrary)
3165
 
                efree((char *)olib->temp1);
3166
 
}
3167
 
 
3168
 
/****************************** LIBRARY OPTIONS DIALOG ******************************/
3169
 
 
3170
 
/* Library: Options */
3171
 
static DIALOGITEM io_liboptdialogitems[] =
3172
 
{
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")}
3179
 
};
3180
 
static DIALOG io_liboptdialog = {{75,75,232,320}, N_("Library Options"), 0, 6, io_liboptdialogitems};
3181
 
 
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) */
3187
 
 
3188
 
void io_libraryoptiondlog(void)
3189
 
{
3190
 
        INTBIG itemHit, i, *origstate, curstate[NUMIOSTATEBITWORDS];
3191
 
 
3192
 
        /* display the library paths dialog box */
3193
 
        if (DiaInitDialog(&io_liboptdialog)) return;
3194
 
 
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)
3199
 
        {
3200
 
                case BINOUTNOBACK:   DiaSetControl(DLBO_NOBACKUP, 1);    break;
3201
 
                case BINOUTONEBACK:  DiaSetControl(DLBO_ONEBACKUP, 1);   break;
3202
 
                case BINOUTFULLBACK: DiaSetControl(DLBO_FULLBACKUP, 1);  break;
3203
 
        }
3204
 
        if ((curstate[0]&CHECKATWRITE) != 0) DiaSetControl(DLBO_CHECKAFTERWRITE, 1);
3205
 
 
3206
 
        /* loop until done */
3207
 
        for(;;)
3208
 
        {
3209
 
                itemHit = DiaNextHit();
3210
 
                if (itemHit == OK || itemHit == CANCEL) break;
3211
 
                if (itemHit == DLBO_NOBACKUP || itemHit == DLBO_ONEBACKUP ||
3212
 
                        itemHit == DLBO_FULLBACKUP)
3213
 
                {
3214
 
                        DiaSetControl(DLBO_NOBACKUP, 0);
3215
 
                        DiaSetControl(DLBO_ONEBACKUP, 0);
3216
 
                        DiaSetControl(DLBO_FULLBACKUP, 0);
3217
 
                        DiaSetControl(itemHit, 1);
3218
 
                        continue;
3219
 
                }
3220
 
                if (itemHit == DLBO_CHECKAFTERWRITE)
3221
 
                {
3222
 
                        DiaSetControl(itemHit, 1 - DiaGetControl(itemHit));
3223
 
                        continue;
3224
 
                }
3225
 
        }
3226
 
 
3227
 
        if (itemHit != CANCEL)
3228
 
        {
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);
3237
 
        }
3238
 
        DiaDoneDialog();
3239
 
}
3240
 
 
3241
 
/* CDL Options */
3242
 
static DIALOGITEM io_cdloptdialogitems[] =
3243
 
{
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")}
3251
 
};
3252
 
static DIALOG io_cdloptdialog = {{75,75,208,447}, N_("CDL Options"), 0, 7, io_cdloptdialogitems};
3253
 
 
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) */
3258
 
 
3259
 
/*
3260
 
 * Routine to run the CDL Options dialog.
3261
 
 */
3262
 
void io_cdloptionsdialog(void)
3263
 
{
3264
 
        INTBIG i, itemHit, *curstate, newstate[NUMIOSTATEBITWORDS];
3265
 
        REGISTER VARIABLE *var;
3266
 
        REGISTER char *inilibname, *inilibpath;
3267
 
        BOOLEAN libnamechanged, libpathchanged;
3268
 
 
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);
3280
 
 
3281
 
        libnamechanged = libpathchanged = FALSE;
3282
 
        for(;;)
3283
 
        {
3284
 
                itemHit = DiaNextHit();
3285
 
                if (itemHit == OK || itemHit == CANCEL) break;
3286
 
                if (itemHit == DCDL_CONVBRACKET)
3287
 
                {
3288
 
                        DiaSetControl(itemHit, 1 - DiaGetControl(itemHit));
3289
 
                        continue;
3290
 
                }
3291
 
                if (itemHit == DCDL_LIBNAME)
3292
 
                {
3293
 
                        if (strcmp(inilibname, DiaGetText(DCDL_LIBNAME)) != 0)
3294
 
                                libnamechanged = TRUE;
3295
 
                        continue;
3296
 
                }
3297
 
                if (itemHit == DCDL_LIBPATH)
3298
 
                {
3299
 
                        if (strcmp(inilibpath, DiaGetText(DCDL_LIBPATH)) != 0)
3300
 
                                libpathchanged = TRUE;
3301
 
                        continue;
3302
 
                }
3303
 
        }
3304
 
        if (itemHit == OK)
3305
 
        {
3306
 
                if (libnamechanged != 0)
3307
 
                {
3308
 
                        (void)setval((INTBIG)io_tool, VTOOL, "IO_cdl_library_name",
3309
 
                                (INTBIG)DiaGetText(DCDL_LIBNAME), VSTRING);
3310
 
                }
3311
 
                if (libpathchanged != 0)
3312
 
                {
3313
 
                        (void)setval((INTBIG)io_tool, VTOOL, "IO_cdl_library_path",
3314
 
                                (INTBIG)DiaGetText(DCDL_LIBPATH), VSTRING);
3315
 
                }
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);
3321
 
        }
3322
 
        DiaDoneDialog();
3323
 
}
3324
 
 
3325
 
static struct
3326
 
{
3327
 
        char   *variable;
3328
 
        char   *meaning;
3329
 
        BOOLEAN  uppertriangle;
3330
 
        INTBIG  key;
3331
 
        INTBIG  defaultint;
3332
 
        char   *defaultstring;
3333
 
        float   defaultfloat;
3334
 
} io_techlayervariables[] =
3335
 
{
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}
3347
 
};
3348
 
 
3349
 
/*
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)
3352
 
 */
3353
 
static INTBIG tech_mocmossubarrange[] =
3354
 
{
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,
3358
 
        36, 37, 38, 39
3359
 
};
3360
 
 
3361
 
static struct
3362
 
{
3363
 
        char *techname;
3364
 
        INTBIG oldlayercount, newlayercount;
3365
 
        INTBIG *arrangement;
3366
 
} io_techlayerfixes[] =
3367
 
{
3368
 
        "mocmossub", 34, 40, tech_mocmossubarrange,
3369
 
        "mocmos",    34, 40, tech_mocmossubarrange,
3370
 
        0, 0, 0, 0
3371
 
};
3372
 
 
3373
 
void io_fixtechlayers(void)
3374
 
{
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;
3380
 
 
3381
 
        for(tech = el_technologies; tech != NOTECHNOLOGY; tech = tech->nexttechnology)
3382
 
        {
3383
 
                for(i=0; io_techlayervariables[i].variable != 0; i++)
3384
 
                {
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)
3390
 
                        {
3391
 
                                l = tech->layercount;
3392
 
                                if (getlength(var) == (l * l + l) / 2) continue;
3393
 
                        } else
3394
 
                        {
3395
 
                                if (getlength(var) == tech->layercount) continue;
3396
 
                        }
3397
 
 
3398
 
                        /* layers are inconsistent: see if there are rules to fix it */
3399
 
                        for(j=0; io_techlayerfixes[j].techname != 0; j++)
3400
 
                        {
3401
 
                                if (namesame(tech->techname, io_techlayerfixes[j].techname) != 0) continue;
3402
 
                                if (io_techlayervariables[i].uppertriangle)
3403
 
                                {
3404
 
                                        l = io_techlayerfixes[j].oldlayercount;
3405
 
                                        if ((l*l+l)/2 != getlength(var)) continue;
3406
 
                                } else
3407
 
                                {
3408
 
                                        if (io_techlayerfixes[j].oldlayercount != getlength(var)) continue;
3409
 
                                }
3410
 
                                if (io_techlayerfixes[j].newlayercount != tech->layercount) continue;
3411
 
                                break;
3412
 
                        }
3413
 
                        if (io_techlayerfixes[j].techname != 0)
3414
 
                        {
3415
 
                                if (io_techlayervariables[i].uppertriangle)
3416
 
                                {
3417
 
                                        k = tech->layercount;
3418
 
                                        l = (k * k + k)/2;
3419
 
                                        newints = (INTBIG *)emalloc(l * SIZEOFINTBIG, tech->cluster);
3420
 
                                        for(k=0; k<l; k++)
3421
 
                                                newints[k] = io_techlayervariables[i].defaultint;
3422
 
                                        for(l1=0; l1<io_techlayerfixes[j].oldlayercount; l1++)
3423
 
                                        {
3424
 
                                                for(l2=l1; l2<io_techlayerfixes[j].oldlayercount; l2++)
3425
 
                                                {
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];
3433
 
                                                }
3434
 
                                        }
3435
 
                                        (void)setvalkey((INTBIG)tech, VTECHNOLOGY, io_techlayervariables[i].key,
3436
 
                                                (INTBIG)newints, (var->type&VTYPE)|VISARRAY|(l<<VLENGTHSH));
3437
 
                                        efree((char *)newints);
3438
 
                                } else
3439
 
                                {
3440
 
                                        /* able to fix the ordering */
3441
 
                                        if ((var->type&VTYPE) == VSTRING)
3442
 
                                        {
3443
 
                                                newstrings = (char **)emalloc(tech->layercount * (sizeof (char *)),
3444
 
                                                        tech->cluster);
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)
3454
 
                                        {
3455
 
                                                newfloats = (float *)emalloc(tech->layercount * (sizeof (float)),
3456
 
                                                        tech->cluster);
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);
3465
 
                                        } else
3466
 
                                        {
3467
 
                                                newints = (INTBIG *)emalloc(tech->layercount * SIZEOFINTBIG,
3468
 
                                                        tech->cluster);
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);
3477
 
                                        }
3478
 
                                }
3479
 
                                continue;
3480
 
                        }
3481
 
 
3482
 
                        /* unable to fix: issue a warning */
3483
 
                        ttyputmsg(_("Warning: %s in technology %s are inconsistent"),
3484
 
                                _(io_techlayervariables[i].meaning), tech->techname);
3485
 
                }
3486
 
        }
3487
 
}
3488
 
 
3489
 
void io_fixrtree(RTNODE *rtree)
3490
 
{
3491
 
        REGISTER INTBIG i;
3492
 
        REGISTER GEOM *geom;
3493
 
        REGISTER RTNODE *subrt;
3494
 
 
3495
 
        if (rtree->total <= 0) return;
3496
 
        if (rtree->flag != 0)
3497
 
        {
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++)
3502
 
                {
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;
3508
 
                }
3509
 
        } else
3510
 
        {
3511
 
                subrt = (RTNODE *)rtree->pointers[0];
3512
 
                io_fixrtree(subrt);
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++)
3516
 
                {
3517
 
                        subrt = (RTNODE *)rtree->pointers[i];
3518
 
                        io_fixrtree(subrt);
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;
3523
 
                }
3524
 
        }
3525
 
}
3526
 
 
3527
 
/*
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).
3531
 
 */
3532
 
PORTPROTO *io_convertoldportname(char *portname, NODEPROTO *np)
3533
 
{
3534
 
        if (np->primindex == 0) return(NOPORTPROTO);
3535
 
        if (np == sch_sourceprim || np == sch_meterprim)
3536
 
        {
3537
 
                if (namesame(portname, "top") == 0)
3538
 
                        return(np->firstportproto);
3539
 
                if (namesame(portname, "bottom") == 0)
3540
 
                        return(np->firstportproto->nextportproto);
3541
 
        }
3542
 
        if (np == sch_twoportprim)
3543
 
        {
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);
3552
 
        }
3553
 
        return(NOPORTPROTO);
3554
 
}
3555
 
 
3556
 
/*
3557
 
 * Routine to determine the area of facet "np" that is to be printed.
3558
 
 * Returns true if the area cannot be determined.
3559
 
 */
3560
 
BOOLEAN io_getareatoprint(NODEPROTO *np, INTBIG *lx, INTBIG *hx, INTBIG *ly, INTBIG *hy, BOOLEAN reduce)
3561
 
{
3562
 
        REGISTER INTBIG wid, hei, *curstate;
3563
 
        INTBIG hlx, hhx, hly, hhy;
3564
 
        REGISTER NODEPROTO *onp;
3565
 
 
3566
 
        curstate = io_getstatebits();
3567
 
        us_fullview(np, lx, hx, ly, hy);
3568
 
 
3569
 
        /* extend it and make it square */
3570
 
        wid = *hx - *lx;
3571
 
        hei = *hy - *ly;
3572
 
        if (reduce)
3573
 
        {
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);
3577
 
        }
3578
 
 
3579
 
        if ((curstate[0]&PLOTFOCUS) != 0)
3580
 
        {
3581
 
                if ((curstate[0]&PLOTFOCUSDPY) != 0)
3582
 
                {
3583
 
                        *lx = el_curwindowpart->screenlx;
3584
 
                        *hx = el_curwindowpart->screenhx;
3585
 
                        *ly = el_curwindowpart->screenly;
3586
 
                        *hy = el_curwindowpart->screenhy;
3587
 
                } else
3588
 
                {
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
3593
 
                        {
3594
 
                                if (hhx == hlx || hhy == hly)
3595
 
                                {
3596
 
                                        ttyputerr(_("Warning: no highlighted area; highlight area and reissue command"));
3597
 
                                        return(TRUE);
3598
 
                                }
3599
 
                                *lx = hlx;   *hx = hhx;
3600
 
                                *ly = hly;   *hy = hhy;
3601
 
                        }
3602
 
                }
3603
 
        }
3604
 
        return(FALSE);
3605
 
}
3606
 
 
3607
 
/******************** LAYER ORDERING FOR GRAPHIC COPY/PRINT ********************/
3608
 
 
3609
 
INTBIG io_setuptechorder(TECHNOLOGY *tech)
3610
 
{
3611
 
        REGISTER INTBIG i, j, k, l, m, *neworder, newamount;
3612
 
        REGISTER INTBIG *layers;
3613
 
        INTBIG order[LFNUMLAYERS];
3614
 
        REGISTER VARIABLE *var;
3615
 
 
3616
 
        /* determine order of overlappable layers in current technology */
3617
 
        io_maxlayers = 0;
3618
 
        i = tech->layercount;
3619
 
        var = getval((INTBIG)tech, VTECHNOLOGY, VINTEGER|VISARRAY,
3620
 
                "TECH_layer_function");
3621
 
        if (var != NOVARIABLE)
3622
 
        {
3623
 
                layers = (INTBIG *)var->addr;
3624
 
                for(j=0; j<LFNUMLAYERS; j++)
3625
 
                        order[j] = layerfunctionheight(j);
3626
 
                for(j=0; j<LFNUMLAYERS; j++)
3627
 
                {
3628
 
                        for(k=0; k<LFNUMLAYERS; k++)
3629
 
                        {
3630
 
                                if (order[k] != j) continue;
3631
 
                                for(l=0; l<i; l++)
3632
 
                                {
3633
 
                                        if ((layers[l]&LFTYPE) != k) continue;
3634
 
                                        if (io_maxlayers >= io_mostlayers)
3635
 
                                        {
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;
3646
 
                                        }
3647
 
                                        io_overlaporder[io_maxlayers++] = l;
3648
 
                                }
3649
 
                                break;
3650
 
                        }
3651
 
                }
3652
 
        }
3653
 
        return(io_maxlayers);
3654
 
}
3655
 
 
3656
 
/*
3657
 
 * Routine to return the layer in plotting position "i" (from 0 to the value returned
3658
 
 * by "io_setuptechorder" - 1).
3659
 
 */
3660
 
INTBIG io_nextplotlayer(INTBIG i)
3661
 
{
3662
 
        return(io_overlaporder[i]);
3663
 
}
3664
 
 
3665
 
/******************** MATH HELPERS ********************/
3666
 
 
3667
 
/*
3668
 
 * This routine is used by "ioedifo.c" and "routmaze.c".
3669
 
 */
3670
 
void io_compute_center(INTBIG xc, INTBIG yc, INTBIG x1, INTBIG y1,
3671
 
        INTBIG x2, INTBIG y2, INTBIG *cx, INTBIG *cy)
3672
 
{
3673
 
        int r, dx, dy, a1, a2, a;
3674
 
        double pie, theta, radius, Dx, Dy;
3675
 
 
3676
 
        /* reconstruct angles to p1 and p2 */
3677
 
        Dx = x1 - xc;
3678
 
        Dy = y1 - yc;
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;
3684
 
        a = (a1 + a2) >> 1;
3685
 
        pie = acos(-1.0);
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);
3691
 
        *cx = xc + dx;
3692
 
        *cy = yc + dy;
3693
 
}
3694
 
 
3695
 
double io_calc_angle(double r, double dx, double dy)
3696
 
{
3697
 
        double ratio, a1, a2;
3698
 
 
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);
3703
 
        return(a1);
3704
 
}