1 /* -*- tab-width: 4 -*-
2 *
3 * Electric(tm) VLSI Design System
4 *
5 * File: usrcomtz.c
6 * User interface tool: command handler for T through V
7 * Written by: Steven M. Rubin, Static Free Software
8 *
9 * Copyright (c) 2000 Static Free Software.
10 *
11 * Electric(tm) is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * Electric(tm) is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with Electric(tm); see the file COPYING. If not, write to
23 * the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
24 * Boston, Mass 02111-1307, USA.
25 *
26 * Static Free Software
27 * 4119 Alpine Road
28 * Portola Valley, California 94028
29 * info@staticfreesoft.com
30 */
31
32 #include "global.h"
33 #include "egraphics.h"
34 #include "edialogs.h"
35 #include "usr.h"
36 #include "usrtrack.h"
37 #include "tecgen.h"
38 #include "efunction.h"
39
40 /* working memory for "us_var()" */
41 static INTBIG *us_varaddr1, *us_vartype1, us_varlimit1=0;
42 static INTBIG *us_varaddr2, *us_vartype2, us_varlimit2=0;
43 static INTBIG *us_varaddr3, *us_vartype3, us_varlimit3=0;
44 static CHAR *us_varqualsave = 0;
45
46 static WINDOWPART *us_wpop; /* editor window part */
47 static BOOLEAN us_wpopcharhandler(INTSML chr, INTBIG special);
48 static BOOLEAN us_wpopbuttonhandler(INTBIG x, INTBIG y, INTBIG but);
49
50 /*
51 * Routine to free all memory associated with this module.
52 */
us_freecomtvmemory(void)53 void us_freecomtvmemory(void)
54 {
55 if (us_varqualsave != 0) efree((CHAR *)us_varqualsave);
56 if (us_varlimit1 > 0)
57 {
58 efree((CHAR *)us_vartype1);
59 efree((CHAR *)us_varaddr1);
60 }
61 if (us_varlimit2 > 0)
62 {
63 efree((CHAR *)us_vartype2);
64 efree((CHAR *)us_varaddr2);
65 }
66 if (us_varlimit3 > 0)
67 {
68 efree((CHAR *)us_vartype3);
69 efree((CHAR *)us_varaddr3);
70 }
71 }
72
us_technology(INTBIG count,CHAR * par[])73 void us_technology(INTBIG count, CHAR *par[])
74 {
75 REGISTER INTBIG l, oldlam;
76 REGISTER CHAR *pp;
77 CHAR *newpar[3];
78 extern COMCOMP us_technologyp;
79 REGISTER TECHNOLOGY *tech, *newtech;
80 REGISTER NODEPROTO *np, *newnp;
81 REGISTER NODEINST *ni;
82 REGISTER WINDOWPART *w;
83 REGISTER ARCINST *ai;
84 REGISTER LIBRARY *lib;
85
86 /* ensure there is a technology option */
87 if (count == 0)
88 {
89 count = ttygetparam(M_("Technology option: "), &us_technologyp, MAXPARS, par);
90 if (count == 0)
91 {
92 us_abortedmsg();
93 return;
94 }
95 }
96 l = estrlen(pp = par[0]);
97
98 /* handle technology editing */
99 if (namesamen(pp, x_("edit"), l) == 0)
100 {
101 us_tecedentry(count-1, &par[1]);
102 return;
103 }
104
105 if (namesamen(pp, x_("autoswitch"), l) == 0)
106 {
107 if (count < 2)
108 {
109 ttyputusage(x_("technology autoswitch on|off"));
110 return;
111 }
112 l = estrlen(pp = par[1]);
113 if (namesamen(pp, x_("on"), l) == 0 && l >= 2)
114 {
115 (void)setvalkey((INTBIG)us_tool, VTOOL, us_optionflagskey,
116 us_useroptions | AUTOSWITCHTECHNOLOGY, VINTEGER);
117 ttyputverbose(M_("Technology will automatically switch to match cell"));
118 return;
119 }
120 if (namesamen(pp, x_("off"), l) == 0 && l >= 2)
121 {
122 (void)setvalkey((INTBIG)us_tool, VTOOL, us_optionflagskey,
123 us_useroptions & ~AUTOSWITCHTECHNOLOGY, VINTEGER);
124 ttyputverbose(M_("Automatic technology changing disabled"));
125 return;
126 }
127 ttyputbadusage(x_("technology autoswitch"));
128 return;
129 }
130
131 /* get the technology */
132 if (count <= 1)
133 {
134 us_abortcommand(_("Must specify a technology name"));
135 return;
136 }
137 tech = gettechnology(par[1]);
138 if (tech == NOTECHNOLOGY)
139 {
140 us_abortcommand(_("No technology called %s"), par[1]);
141 return;
142 }
143
144 /* handle documentation of technology */
145 if (namesamen(pp, x_("document"), l) == 0)
146 {
147 us_printtechnology(tech);
148 return;
149 }
150
151 /* handle technology conversion */
152 if (namesamen(pp, x_("convert"), l) == 0)
153 {
154 np = us_needcell();
155 if (np == NONODEPROTO) return;
156 newnp = us_convertcell(np, tech);
157 if (newnp == NONODEPROTO) return;
158 newpar[0] = describenodeproto(newnp);
159 newpar[1] = x_("new-window");
160 us_editcell(2, newpar);
161 return;
162 }
163
164 /* handle technology switching */
165 if (namesamen(pp, x_("use"), l) == 0 && l >= 2)
166 {
167 if (el_curtech == tech)
168 {
169 ttyputverbose(M_("Already in %s technology"), el_curtech->techname);
170 return;
171 }
172
173 ttyputverbose(M_("Switching to %s"), tech->techdescript);
174 us_setnodeproto(NONODEPROTO);
175 us_setarcproto(NOARCPROTO, TRUE);
176 oldlam = el_curlib->lambda[el_curtech->techindex];
177 us_getcolormap(tech, COLORSEXISTING, TRUE);
178 (void)setvalkey((INTBIG)us_tool, VTOOL, us_current_technology_key, (INTBIG)tech,
179 VTECHNOLOGY|VDONTSAVE);
180
181 /* if lambda changed and grid is drawn, erase it */
182 if (oldlam != el_curlib->lambda[el_curtech->techindex])
183 {
184 for(w = el_topwindowpart; w != NOWINDOWPART; w = w->nextwindowpart)
185 {
186 if ((w->state & GRIDON) == 0) continue;
187 startobjectchange((INTBIG)w, VWINDOWPART);
188 us_gridset(w, 0);
189 endobjectchange((INTBIG)w, VWINDOWPART);
190 w->state |= GRIDON;
191 }
192 }
193
194 /* redraw grids */
195 if (oldlam != el_curlib->lambda[el_curtech->techindex])
196 {
197 for(w = el_topwindowpart; w != NOWINDOWPART; w = w->nextwindowpart)
198 {
199 if ((w->state & GRIDON) == 0) continue;
200 w->state &= ~GRIDON;
201 startobjectchange((INTBIG)w, VWINDOWPART);
202 us_gridset(w, GRIDON);
203 endobjectchange((INTBIG)w, VWINDOWPART);
204 }
205 }
206
207 /* fix up the menu entries */
208 us_setmenunodearcs();
209 if ((us_state&NONPERSISTENTCURNODE) == 0) us_setnodeproto(tech->firstnodeproto);
210 us_setarcproto(tech->firstarcproto, TRUE);
211 return;
212 }
213
214 /* handle technology deletion */
215 if (namesamen(pp, x_("kill"), l) == 0)
216 {
217 /* make sure there are no objects from this technology */
218 for(lib = el_curlib; lib != NOLIBRARY; lib = lib->nextlibrary)
219 {
220 for(np = lib->firstnodeproto; np != NONODEPROTO; np = np->nextnodeproto)
221 {
222 for(ni = np->firstnodeinst; ni != NONODEINST; ni = ni->nextnodeinst)
223 if (ni->proto->primindex != 0 && ni->proto->tech == tech) break;
224 if (ni != NONODEINST) break;
225 for(ai = np->firstarcinst; ai != NOARCINST; ai = ai->nextarcinst)
226 if (ai->proto->tech == tech) break;
227 if (ai != NOARCINST) break;
228 }
229 if (np != NONODEPROTO)
230 {
231 us_abortcommand(_("Technology %s is still in use"), tech->techname);
232 return;
233 }
234 }
235
236 /* cannot delete generic technology */
237 if (tech == gen_tech)
238 {
239 us_abortcommand(_("Cannot delete the generic technology"));
240 return;
241 }
242
243 /* switch technologies if killing current one */
244 if (tech == el_curtech)
245 {
246 newtech = tech->nexttechnology;
247 if (newtech == NOTECHNOLOGY)
248 {
249 newtech = el_technologies;
250 if (newtech == tech)
251 {
252 us_abortcommand(_("Cannot delete the last technology"));
253 return;
254 }
255 }
256 ttyputmsg(_("Switching to %s"), newtech->techdescript);
257 us_setnodeproto(NONODEPROTO);
258 us_setarcproto(NOARCPROTO, TRUE);
259 us_getcolormap(newtech, COLORSEXISTING, TRUE);
260 (void)setvalkey((INTBIG)us_tool, VTOOL, us_current_technology_key,
261 (INTBIG)newtech, VTECHNOLOGY|VDONTSAVE);
262
263 /* fix up the menu entries */
264 us_setmenunodearcs();
265 if ((us_state&NONPERSISTENTCURNODE) == 0) us_setnodeproto(newtech->firstnodeproto);
266 us_setarcproto(newtech->firstarcproto, TRUE);
267 }
268 if (killtechnology(tech))
269 ttyputerr(_("Unable to delete technology %s"), tech->techname);
270 return;
271 }
272
273 /* handle technology information setting */
274 if (namesamen(pp, x_("tell"), l) == 0)
275 {
276 if (tech->setmode != 0)
277 telltech(tech, count-2, &par[2]); else
278 ttyputerr(_("This technology accepts no commands"));
279 return;
280 }
281 ttyputbadusage(x_("technology"));
282 }
283
us_telltool(INTBIG count,CHAR * par[])284 void us_telltool(INTBIG count, CHAR *par[])
285 {
286 extern COMCOMP us_telltoolp;
287 REGISTER TOOL *tool;
288
289 if (count == 0)
290 {
291 count = ttygetparam(M_("Which tool: "), &us_telltoolp, MAXPARS, par);
292 if (count == 0)
293 {
294 us_abortedmsg();
295 return;
296 }
297 }
298 tool = gettool(par[0]);
299 if (tool == NOTOOL)
300 {
301 us_abortcommand(_("No tool called %s"), par[0]);
302 return;
303 }
304 if (tool->setmode == 0)
305 {
306 us_abortcommand(_("Tool %s cannot take commands"), tool->toolname);
307 return;
308 }
309 (*tool->setmode)(count-1, &par[1]);
310 }
311
us_terminal(INTBIG count,CHAR * par[])312 void us_terminal(INTBIG count, CHAR *par[])
313 {
314 REGISTER INTBIG l, forcealpha;
315 REGISTER CHAR *pt, *pp;
316 REGISTER VARIABLE *err;
317 REGISTER CHAR *varname;
318 INTBIG top, left, bottom, right;
319 INTBIG msgcoord[4];
320 CHAR *truename;
321 REGISTER COMCOMP *comcomp;
322 float newfloat;
323 extern COMCOMP us_libraryup,
324 us_colorreadp, us_helpp, us_technologyup, us_technologyeenp, us_viewfp,
325 us_technologyeeap, us_technologyeelp, us_arrayxp, us_colorentryp, us_viewc2p,
326 us_purelayerp, us_defnodesp, us_editcellp, us_spreaddp, us_portlp,
327 us_defnodexsp, us_lambdachp, us_replacep, us_showp, us_viewn1p, us_showop,
328 us_copycellp, us_gridalip, us_defarcsp, us_portep, us_visiblelayersp,
329 us_menup, us_colorpvaluep, us_artlookp, us_colorwritep, us_librarywp,
330 us_varvep, us_nodetp, us_technologyedlp, us_librarydp, us_technologyctdp,
331 us_textdsp, us_noyesp, us_librarywriteformatp, us_windowrnamep, us_defnodep,
332 us_showdp, us_renameop, us_renamenp, us_findnamep, us_varbs1p, us_findintp,
333 us_colorhighp, us_bindgkeyp, us_gridp, us_technologytp, us_nodetcaip,
334 us_librarykp, us_findobjap, us_window3dp, us_nodetptlp, us_renamecp,
335 us_findexportp, us_findnnamep, us_showup, us_varop, us_copycelldp,
336 us_findnodep, us_technologycnnp, us_showep, us_textfp, us_textsp, us_viewdp,
337 us_interpretcp, us_findarcp, us_varvmp, us_showrp, us_varbdp, us_portcp,
338 us_showfp, us_librarynp, us_viewc1p, us_libraryrp, us_defnodenotp,
339 us_nodetptmp;
340
341 if (count == 0)
342 {
343 ttyputusage(x_("terminal OPTIONS"));
344 return;
345 }
346 l = estrlen(pp = par[0]);
347
348 if (namesamen(pp, x_("not"), l) == 0)
349 {
350 if (count < 2)
351 {
352 ttyputusage(x_("terminal not OPTION"));
353 return;
354 }
355 l = estrlen(pp = par[1]);
356 if (namesame(pp, x_("lock-keys-on-error")) == 0)
357 {
358 (void)setval((INTBIG)us_tool, VTOOL, x_("toolstate"), us_tool->toolstate | NOKEYLOCK, VINTEGER);
359 ttyputverbose(M_("Command errors will not lockout single-key commands"));
360 return;
361 }
362 if (namesame(pp, x_("only-informative-messages")) == 0)
363 {
364 (void)setval((INTBIG)us_tool, VTOOL, x_("toolstate"), us_tool->toolstate & ~JUSTTHEFACTS, VINTEGER);
365 ttyputverbose(M_("All messages will be displayed"));
366 return;
367 }
368 if (namesame(pp, x_("use-electric-commands")) == 0)
369 {
370 (void)setval((INTBIG)us_tool, VTOOL, x_("toolstate"), us_tool->toolstate | NODETAILS, VINTEGER);
371 ttyputverbose(M_("Messages will not mention specific commands"));
372 return;
373 }
374 if (namesame(pp, x_("display-dialogs")) == 0)
375 {
376 (void)setval((INTBIG)us_tool, VTOOL, x_("toolstate"), us_tool->toolstate & ~USEDIALOGS, VINTEGER);
377 ttyputverbose(M_("Dialogs will not be used"));
378 return;
379 }
380 if (namesame(pp, x_("permanent-menu-highlighting")) == 0)
381 {
382 (void)setval((INTBIG)us_tool, VTOOL, x_("toolstate"), us_tool->toolstate | ONESHOTMENU, VINTEGER);
383 ttyputverbose(M_("Menu highlighting will clear after each command"));
384 return;
385 }
386 if (namesame(pp, x_("track-cursor-coordinates")) == 0)
387 {
388 (void)setval((INTBIG)us_tool, VTOOL, x_("toolstate"), us_tool->toolstate & ~SHOWXY, VINTEGER);
389 ttyputverbose(M_("Technology and Lambda will be displayed where cursor coordinates are"));
390 us_redostatus(NOWINDOWFRAME);
391 return;
392 }
393 if (namesame(pp, x_("beep")) == 0)
394 {
395 (void)setval((INTBIG)us_tool, VTOOL, x_("toolstate"), us_tool->toolstate & ~TERMBEEP, VINTEGER);
396 ttyputverbose(M_("Terminal beep disabled"));
397 return;
398 }
399 if (namesamen(pp, x_("enable-interrupts"), l) == 0)
400 {
401 (void)setval((INTBIG)us_tool, VTOOL, x_("toolstate"), us_tool->toolstate | TERMNOINTERRUPT, VINTEGER);
402 ttyputmsg(M_("Interrupts disabled"));
403 return;
404 }
405 if (namesamen(pp, x_("audit"), l) == 0)
406 {
407 if (us_termaudit != NULL) xclose(us_termaudit);
408 us_termaudit = NULL;
409 (void)setval((INTBIG)us_tool, VTOOL, x_("toolstate"), us_tool->toolstate & ~TTYAUDIT, VINTEGER);
410 ttyputverbose(M_("No longer saving messages"));
411 return;
412 }
413 ttyputbadusage(x_("terminal not"));
414 return;
415 }
416
417 if (namesamen(pp, x_("clear"), l) == 0)
418 {
419 ttyclearmessages();
420 return;
421 }
422
423 if (namesamen(pp, x_("get-location"), l) == 0)
424 {
425 getmessagesframeinfo(&top, &left, &bottom, &right);
426 msgcoord[0] = top;
427 msgcoord[1] = left;
428 msgcoord[2] = bottom;
429 msgcoord[3] = right;
430 (void)setval((INTBIG)us_tool, VTOOL, x_("USER_messages_position"),
431 (INTBIG)msgcoord, VINTEGER|VISARRAY|(4<<VLENGTHSH));
432 ttyputmsg(_("Window location will be saved with the options"));
433 return;
434 }
435
436 if (namesamen(pp, x_("lock-keys-on-error"), l) == 0 && l >= 2)
437 {
438 (void)setval((INTBIG)us_tool, VTOOL, x_("toolstate"), us_tool->toolstate & ~NOKEYLOCK, VINTEGER);
439 ttyputverbose(M_("Command errors will lockout single-key commands"));
440 return;
441 }
442
443 if (namesamen(pp, x_("only-informative-messages"), l) == 0)
444 {
445 (void)setval((INTBIG)us_tool, VTOOL, x_("toolstate"), us_tool->toolstate | JUSTTHEFACTS, VINTEGER);
446 ttyputverbose(M_("Nonessential messages will be supressed"));
447 return;
448 }
449
450 if (namesamen(pp, x_("display-dialogs"), l) == 0)
451 {
452 (void)setval((INTBIG)us_tool, VTOOL, x_("toolstate"), us_tool->toolstate | USEDIALOGS, VINTEGER);
453 ttyputverbose(M_("Dialogs will be use where appropriate"));
454 return;
455 }
456
457 if (namesamen(pp, x_("permanent-menu-highlighting"), l) == 0)
458 {
459 (void)setval((INTBIG)us_tool, VTOOL, x_("toolstate"), us_tool->toolstate & ~ONESHOTMENU, VINTEGER);
460 ttyputverbose(M_("Menu highlighting will show current node/arc"));
461 return;
462 }
463
464 if (namesame(pp, x_("track-cursor-coordinates")) == 0)
465 {
466 (void)setval((INTBIG)us_tool, VTOOL, x_("toolstate"), us_tool->toolstate | SHOWXY, VINTEGER);
467 ttyputverbose(M_("Cursor coordinates will be displayed where TECH/LAMBDA are"));
468 us_redostatus(NOWINDOWFRAME);
469 return;
470 }
471 if (namesamen(pp, x_("use-electric-commands"), l) == 0)
472 {
473 (void)setval((INTBIG)us_tool, VTOOL, x_("toolstate"), us_tool->toolstate & ~NODETAILS, VINTEGER);
474 ttyputverbose(M_("Messages will use specific Electric commands"));
475 return;
476 }
477 if (namesamen(pp, x_("beep"), l) == 0)
478 {
479 (void)setval((INTBIG)us_tool, VTOOL, x_("toolstate"), us_tool->toolstate | TERMBEEP, VINTEGER);
480 ttyputverbose(M_("Terminal beep enabled"));
481 return;
482 }
483 if (namesamen(pp, x_("enable-interrupts"), l) == 0)
484 {
485 (void)setval((INTBIG)us_tool, VTOOL, x_("toolstate"), us_tool->toolstate & ~TERMNOINTERRUPT, VINTEGER);
486 ttyputmsg(M_("Interrupts enabled"));
487 return;
488 }
489 if (namesamen(pp, x_("audit"), l) == 0)
490 {
491 us_termaudit = xcreate(x_("emessages.txt"), el_filetypetext, 0, &truename);
492 if (us_termaudit == 0)
493 {
494 ttyputerr(_("Cannot create 'emessages.txt'"));
495 return;
496 }
497 ttyputmsg(_("Saving messages to '%s'"), truename);
498 (void)setval((INTBIG)us_tool, VTOOL, x_("toolstate"), us_tool->toolstate | TTYAUDIT, VINTEGER);
499 return;
500 }
501
502 if (namesamen(pp, x_("input"), l) == 0)
503 {
504 /* make sure there are the right number of parameters */
505 if (count < 3)
506 {
507 ttyputusage(x_("terminal input LETTER PROMPT [TYPE]"));
508 return;
509 }
510
511 /* make sure the command interpreter variable is a single letter */
512 if (!isalpha(par[1][0]) != 0 || par[1][1] != 0)
513 {
514 us_abortcommand(_("Input value must be a single letter"));
515 return;
516 }
517 varname = us_commandvarname(par[1][0]);
518
519 /* get the value */
520 forcealpha = 0;
521 if (count == 4 && namesame(par[3], x_("string")) == 0)
522 {
523 count--;
524 forcealpha = 1;
525 }
526 if (count < 4)
527 {
528 pt = ttygetline(par[2]);
529 if (pt == 0) pt = x_("");
530 } else
531 {
532 forcealpha = 1;
533 comcomp = NOCOMCOMP;
534
535 if (namesame(par[3], x_("about")) == 0) comcomp = &us_showep; else
536 if (namesame(par[3], x_("alignment")) == 0) comcomp = &us_gridalip; else
537 if (namesame(par[3], x_("annulus")) == 0) comcomp = &us_nodetcaip; else
538 if (namesame(par[3], x_("array")) == 0) comcomp = &us_arrayxp; else
539 if (namesame(par[3], x_("artlook")) == 0) comcomp = &us_artlookp; else
540 if (namesame(par[3], x_("attreport")) == 0) comcomp = &us_varbs1p; else
541 if (namesame(par[3], x_("attributes")) == 0) comcomp = &us_varop; else
542 if (namesame(par[3], x_("attparam")) == 0) comcomp = &us_varbdp; else
543 if (namesame(par[3], x_("change")) == 0) comcomp = &us_replacep; else
544 if (namesame(par[3], x_("chglibrary")) == 0) comcomp = &us_librarykp; else
545 if (namesame(par[3], x_("copycell")) == 0) comcomp = &us_copycellp; else
546 if (namesame(par[3], x_("copyrightopt")) == 0) comcomp = &us_defnodenotp; else
547 if (namesame(par[3], x_("defarc")) == 0) comcomp = &us_defarcsp; else
548 if (namesame(par[3], x_("defnode")) == 0) comcomp = &us_defnodexsp; else
549 if (namesame(par[3], x_("deftext")) == 0) comcomp = &us_textdsp; else
550 if (namesame(par[3], x_("delcell")) == 0) comcomp = &us_showup; else
551 if (namesame(par[3], x_("delview")) == 0) comcomp = &us_viewdp; else
552 if (namesame(par[3], x_("dependentlibs")) == 0) comcomp = &us_technologyedlp; else
553 if (namesame(par[3], x_("depth3d")) == 0) comcomp = &us_window3dp; else
554 if (namesame(par[3], x_("editcell")) == 0) comcomp = &us_editcellp; else
555 if (namesame(par[3], x_("edtecarc")) == 0) comcomp = &us_technologyeeap; else
556 if (namesame(par[3], x_("edteclayer")) == 0) comcomp = &us_technologyeelp; else
557 if (namesame(par[3], x_("edtecnode")) == 0) comcomp = &us_technologyeenp; else
558 if (namesame(par[3], x_("enumattrs")) == 0) comcomp = &us_varvmp; else
559 if (namesame(par[3], x_("cellinfo")) == 0) comcomp = &us_defnodep; else
560 if (namesame(par[3], x_("celllist")) == 0) comcomp = &us_showfp; else
561 if (namesame(par[3], x_("cellinst")) == 0) comcomp = &us_viewc1p; else
562 if (namesame(par[3], x_("cell")) == 0) comcomp = &us_showdp; else
563 if (namesame(par[3], x_("file")) == 0) comcomp = &us_colorreadp; else
564 if (namesame(par[3], x_("find")) == 0) comcomp = &us_textfp; else
565 if (namesame(par[3], x_("frameopt")) == 0) comcomp = &us_viewfp; else
566 if (namesame(par[3], x_("genopt")) == 0) comcomp = &us_showrp; else
567 if (namesame(par[3], x_("globsignal")) == 0) comcomp = &us_portcp; else
568 if (namesame(par[3], x_("grid")) == 0) comcomp = &us_gridp; else
569 if (namesame(par[3], x_("help")) == 0) comcomp = &us_helpp; else
570 if (namesame(par[3], x_("highlayer")) == 0) comcomp = &us_colorhighp; else
571 if (namesame(par[3], x_("iconopt")) == 0) comcomp = &us_copycelldp; else
572 if (namesame(par[3], x_("javaopt")) == 0) comcomp = &us_interpretcp; else
573 if (namesame(par[3], x_("labels")) == 0) comcomp = &us_portlp; else
574 if (namesame(par[3], x_("lambda")) == 0) comcomp = &us_lambdachp; else
575 if (namesame(par[3], x_("layerpatterns")) == 0) comcomp = &us_colorpvaluep; else
576 if (namesame(par[3], x_("layers")) == 0) comcomp = &us_colorentryp; else
577 if (namesame(par[3], x_("library")) == 0) comcomp = &us_libraryup; else
578 if (namesame(par[3], x_("libtotech")) == 0) comcomp = &us_technologycnnp; else
579 if (namesame(par[3], x_("menu")) == 0) comcomp = &us_menup; else
580 if (namesame(par[3], x_("newview")) == 0) comcomp = &us_viewn1p; else
581 if (namesame(par[3], x_("node")) == 0) comcomp = &us_defnodesp; else
582 if (namesame(par[3], x_("noyes")) == 0) comcomp = &us_noyesp; else
583 if (namesame(par[3], x_("ofile")) == 0) comcomp = &us_colorwritep; else
584 if (namesame(par[3], x_("optionexamine")) == 0) comcomp = &us_librarynp; else
585 if (namesame(par[3], x_("optionfind")) == 0) comcomp = &us_libraryrp; else
586 if (namesame(par[3], x_("optionsave")) == 0) comcomp = &us_librarywp; else
587 if (namesame(par[3], x_("path")) == 0) comcomp = &us_librarydp; else
588 if (namesame(par[3], x_("placetext")) == 0) comcomp = &us_nodetptlp; else
589 if (namesame(par[3], x_("plot")) == 0) comcomp = &us_librarywriteformatp; else
590 if (namesame(par[3], x_("port")) == 0) comcomp = &us_portep; else
591 if (namesame(par[3], x_("purelayer")) == 0) comcomp = &us_purelayerp; else
592 if (namesame(par[3], x_("quickkey")) == 0) comcomp = &us_bindgkeyp; else
593 if (namesame(par[3], x_("renameexport")) == 0) comcomp = &us_renamecp; else
594 if (namesame(par[3], x_("renamelib")) == 0) comcomp = &us_renameop; else
595 if (namesame(par[3], x_("renametech")) == 0) comcomp = &us_renamenp; else
596 if (namesame(par[3], x_("renamecell")) == 0) comcomp = &us_findnamep; else
597 if (namesame(par[3], x_("renamenet")) == 0) comcomp = &us_findintp; else
598 if (namesame(par[3], x_("romgen")) == 0) comcomp = &us_nodetptmp; else
599 if (namesame(par[3], x_("selectarc")) == 0) comcomp = &us_findarcp; else
600 if (namesame(par[3], x_("selectnet")) == 0) comcomp = &us_findnnamep; else
601 if (namesame(par[3], x_("selectnode")) == 0) comcomp = &us_findnodep; else
602 if (namesame(par[3], x_("selectopt")) == 0) comcomp = &us_findobjap; else
603 if (namesame(par[3], x_("selectport")) == 0) comcomp = &us_findexportp; else
604 if (namesame(par[3], x_("showdetail")) == 0) comcomp = &us_showop; else
605 if (namesame(par[3], x_("show")) == 0) comcomp = &us_showp; else
606 if (namesame(par[3], x_("spread")) == 0) comcomp = &us_spreaddp; else
607 if (namesame(par[3], x_("technology")) == 0) comcomp = &us_technologyup; else
608 if (namesame(par[3], x_("techopt")) == 0) comcomp = &us_technologytp; else
609 if (namesame(par[3], x_("techvars")) == 0) comcomp = &us_technologyctdp; else
610 if (namesame(par[3], x_("textsize")) == 0) comcomp = &us_textsp; else
611 if (namesame(par[3], x_("trace")) == 0) comcomp = &us_nodetp; else
612 if (namesame(par[3], x_("variable")) == 0) comcomp = &us_varvep; else
613 if (namesame(par[3], x_("view")) == 0) comcomp = &us_viewc2p; else
614 if (namesame(par[3], x_("visiblelayers")) == 0) comcomp = &us_visiblelayersp; else
615 if (namesame(par[3], x_("windowview")) == 0) comcomp = &us_windowrnamep; else
616 comcomp = us_getcomcompfromkeyword(par[3]);
617 if (comcomp == NOCOMCOMP)
618 {
619 us_abortcommand(_("Unknown input type: %s"), par[3]);
620 return;
621 }
622 count = ttygetparam(par[2], comcomp, MAXPARS-3, &par[3]);
623 if (count < 1) pt = x_(""); else pt = par[3];
624 }
625 if (*pt == 0)
626 {
627 if (getval((INTBIG)us_tool, VTOOL, -1, varname) != NOVARIABLE)
628 (void)delval((INTBIG)us_tool, VTOOL, varname);
629 return;
630 }
631
632 /* store the value */
633 if (isanumber(pt) && forcealpha == 0)
634 {
635 for(pp = pt; *pp != 0; pp++) if (*pp == '.')
636 {
637 newfloat = (float)eatof(pt);
638 err = setval((INTBIG)us_tool, VTOOL, varname, castint(newfloat), VFLOAT|VDONTSAVE);
639 break;
640 }
641 if (*pp == 0)
642 err = setval((INTBIG)us_tool, VTOOL, varname, myatoi(pt), VINTEGER|VDONTSAVE);
643 } else err = setval((INTBIG)us_tool, VTOOL, varname, (INTBIG)pt, VSTRING|VDONTSAVE);
644 if (err == NOVARIABLE)
645 {
646 us_abortcommand(_("Problem setting variable %s"), par[1]);
647 return;
648 }
649 return;
650 }
651
652 if (namesamen(pp, x_("session"), l) == 0)
653 {
654 if (!graphicshas(CANLOGINPUT))
655 {
656 us_abortcommand(_("Sorry, this display driver does not log sessions"));
657 return;
658 }
659
660 /* make sure there are the right number of parameters */
661 if (count <= 1) l = estrlen(pp = x_("?")); else
662 l = estrlen(pp = par[1]);
663
664 if (namesamen(pp, x_("playback"), l) == 0)
665 {
666 if (count <= 2)
667 {
668 ttyputusage(x_("terminal session playback FILE"));
669 return;
670 }
671 if (logplayback(par[2]))
672 us_abortcommand(_("Cannot read playback file %s"), par[2]);
673 return;
674 }
675
676 if (namesamen(pp, x_("begin-record"), l) == 0)
677 {
678 if (us_logrecord != NULL)
679 {
680 us_abortcommand(_("Session is already being recorded"));
681 return;
682 }
683 logstartrecord();
684 return;
685 }
686
687 /* make sure session logging is on */
688 if (us_logrecord == NULL)
689 {
690 us_abortcommand(_("Session is not being recorded"));
691 return;
692 }
693
694 if (namesamen(pp, x_("end-record"), l) == 0)
695 {
696 logfinishrecord();
697 return;
698 }
699
700 if (namesamen(pp, x_("rewind-record"), l) == 0)
701 {
702 logfinishrecord();
703 logstartrecord();
704 return;
705 }
706
707 if (namesamen(pp, x_("checkpoint-frequency"), l) == 0)
708 {
709 if (count <= 2)
710 {
711 ttyputusage(x_("terminal session checkpoint-frequency F"));
712 return;
713 }
714 us_logflushfreq = myatoi(par[2]);
715 ttyputverbose(M_("Session logging will be guaranteed every %ld commands"),
716 us_logflushfreq);
717 return;
718 }
719
720 ttyputbadusage(x_("terminal session"));
721 return;
722 }
723
724 ttyputbadusage(x_("terminal"));
725 }
726
us_text(INTBIG count,CHAR * par[])727 void us_text(INTBIG count, CHAR *par[])
728 {
729 REGISTER INTBIG grabpoint, newgrabpoint, len, font;
730 REGISTER INTBIG i, l;
731 INTBIG xw, yw, xcur, ycur, adjxc, adjyc;
732 UINTBIG descript[TEXTDESCRIPTSIZE], olddescript[TEXTDESCRIPTSIZE];
733 INTBIG tsx, tsy, style;
734 REGISTER CHAR *pp, *str;
735 REGISTER NODEINST *ni;
736 REGISTER NODEPROTO *np;
737 REGISTER VARIABLE *var;
738 REGISTER WINDOWPART *w;
739 REGISTER HIGHLIGHT *high;
740 REGISTER TECHNOLOGY *tech;
741 static POLYGON *poly = NOPOLYGON;
742 static CHAR *smartstyle[3] = {N_("off"), N_("inside"), N_("outside")};
743
744 /* get polygon */
745 (void)needstaticpolygon(&poly, 4, us_tool->cluster);
746
747 if (count == 0)
748 {
749 ttyputusage(x_("text style|size|editor|default-*|read|write"));
750 return;
751 }
752 l = estrlen(pp = par[0]);
753
754 /* handle text saving */
755 if (namesamen(pp, x_("write"), l) == 0 && l >= 1)
756 {
757 if (count < 2)
758 {
759 ttyputusage(x_("text write FILENAME"));
760 return;
761 }
762
763 if (us_needwindow()) return;
764
765 /* make sure the current window is textual */
766 if ((el_curwindowpart->state&WINDOWTYPE) != POPTEXTWINDOW &&
767 (el_curwindowpart->state&WINDOWTYPE) != TEXTWINDOW)
768 {
769 us_abortcommand(_("Current window is not textual"));
770 return;
771 }
772
773 us_writetextfile(el_curwindowpart, par[1]);
774 return;
775 }
776
777 /* handle text cell reading */
778 if (namesamen(pp, x_("read"), l) == 0 && l >= 1)
779 {
780 if (count < 2)
781 {
782 ttyputusage(x_("text read FILENAME"));
783 return;
784 }
785
786 if (us_needwindow()) return;
787
788 /* make sure the current window is textual */
789 if ((el_curwindowpart->state&WINDOWTYPE) != POPTEXTWINDOW &&
790 (el_curwindowpart->state&WINDOWTYPE) != TEXTWINDOW)
791 {
792 us_abortcommand(_("Current window is not textual"));
793 return;
794 }
795
796 us_readtextfile(el_curwindowpart, par[1]);
797 return;
798 }
799
800 /* handle text cell manipulation */
801 if (namesamen(pp, x_("cut"), l) == 0 && l >= 2)
802 {
803 /* first see if this applies to messages window */
804 if (cutfrommessages()) return;
805
806 /* next see if it applies to a text edit window */
807 if (us_needwindow()) return;
808 switch (el_curwindowpart->state&WINDOWTYPE)
809 {
810 case POPTEXTWINDOW:
811 case TEXTWINDOW:
812 us_cuttext(el_curwindowpart);
813 break;
814 case DISPWINDOW:
815 us_cutobjects(el_curwindowpart);
816 break;
817 case WAVEFORMWINDOW:
818 ttyputmsg(_("To copy waveforms, use 'p' to preserve a snapshot"));
819 break;
820 case EXPLORERWINDOW:
821 ttyputmsg(_("You cannot cut from a cell explorer window, but you can copy"));
822 break;
823 default:
824 ttyputmsg(_("Cannot cut from this type of window"));
825 break;
826 }
827 return;
828 }
829 if (namesamen(pp, x_("copy"), l) == 0 && l >= 2)
830 {
831 /* first see if this applies to messages window */
832 if (copyfrommessages()) return;
833
834 /* next see if it applies to a text edit window */
835 if (us_needwindow()) return;
836 switch (el_curwindowpart->state&WINDOWTYPE)
837 {
838 case POPTEXTWINDOW:
839 case TEXTWINDOW:
840 us_copytext(el_curwindowpart);
841 break;
842 case DISPWINDOW:
843 us_copyobjects(el_curwindowpart);
844 break;
845 case WAVEFORMWINDOW:
846 ttyputmsg(_("To copy waveforms, use 'p' to preserve a snapshot"));
847 break;
848 case EXPLORERWINDOW:
849 us_copyexplorerwindow();
850 break;
851 default:
852 ttyputmsg(_("Cannot copy from this type of window"));
853 break;
854 }
855 return;
856 }
857 if (namesamen(pp, x_("paste"), l) == 0 && l >= 1)
858 {
859 /* first see if this applies to messages window */
860 if (pastetomessages()) return;
861
862 /* next see if it applies to a text edit window */
863 if (us_needwindow()) return;
864 switch (el_curwindowpart->state&WINDOWTYPE)
865 {
866 case POPTEXTWINDOW:
867 case TEXTWINDOW:
868 us_pastetext(el_curwindowpart);
869 break;
870 case DISPWINDOW:
871 us_pasteobjects(el_curwindowpart);
872 break;
873 default:
874 ttyputmsg(_("Cannot paste to this type of window"));
875 break;
876 }
877 return;
878 }
879 if (namesamen(pp, x_("find"), l) == 0 && l >= 1)
880 {
881 if (count < 2)
882 {
883 ttyputusage(x_("text find STRING"));
884 return;
885 }
886
887 /* make sure the current window is textual */
888 if (us_needwindow()) return;
889 if ((el_curwindowpart->state&WINDOWTYPE) != POPTEXTWINDOW &&
890 (el_curwindowpart->state&WINDOWTYPE) != TEXTWINDOW)
891 {
892 us_abortcommand(_("Current window is not textual"));
893 return;
894 }
895
896 us_searchtext(el_curwindowpart, par[1], 0, 0);
897 return;
898 }
899
900 /* handle editor selection */
901 if (namesamen(pp, x_("editor"), l) == 0 && l >= 2)
902 {
903 if (count < 2)
904 {
905 ttyputmsg(_("Current text editor is %s"), us_editortable[us_currenteditor].editorname);
906 return;
907 }
908 l = estrlen(pp = par[1]);
909
910 /* make sure there are no text editors running */
911 for(w = el_topwindowpart; w != NOWINDOWPART; w = w->nextwindowpart)
912 if ((w->state&WINDOWTYPE) == TEXTWINDOW || (w->state&WINDOWTYPE) == POPTEXTWINDOW)
913 {
914 us_abortcommand(_("Must terminate all active editors before switching"));
915 return;
916 }
917
918 for(i=0; us_editortable[i].editorname != 0; i++)
919 if (namesamen(pp, us_editortable[i].editorname, l) == 0) break;
920 if (us_editortable[i].editorname == 0)
921 {
922 us_abortcommand(_("Unknown editor: %s"), pp);
923 return;
924 }
925 ttyputverbose(M_("Now using %s editor for text"), us_editortable[i].editorname);
926 setvalkey((INTBIG)us_tool, VTOOL, us_text_editorkey, (INTBIG)us_editortable[i].editorname,
927 VSTRING);
928 return;
929 }
930
931 if (namesamen(pp, x_("easy-text-selection"), l) == 0 && l >= 2)
932 {
933 if ((us_useroptions&NOTEXTSELECT) == 0)
934 ttyputverbose(M_("Annotation text is already easy to select")); else
935 {
936 ttyputverbose(M_("Annotation text will be easily selectable"));
937 (void)setvalkey((INTBIG)us_tool, VTOOL, us_optionflagskey,
938 us_useroptions | NOTEXTSELECT, VINTEGER);
939 }
940 return;
941 }
942
943 if (namesamen(pp, x_("hard-text-selection"), l) == 0 && l >= 1)
944 {
945 if ((us_useroptions&NOTEXTSELECT) != 0)
946 ttyputverbose(M_("Annotation text is already hard to select")); else
947 {
948 ttyputverbose(M_("Annotation text will be hard to select (only when the 'find' command does NOT have the 'port' option)"));
949 (void)setvalkey((INTBIG)us_tool, VTOOL, us_optionflagskey,
950 us_useroptions & ~NOTEXTSELECT, VINTEGER);
951 }
952 return;
953 }
954
955 /* handle default node text size */
956 if (namesamen(pp, x_("default-node-size"), l) == 0 && l >= 9)
957 {
958 /* get new value */
959 if (count < 2)
960 {
961 ttyputusage(x_("text default-node-size SIZE"));
962 return;
963 }
964 defaulttextsize(3, descript);
965 font = us_gettextsize(par[1], TDGETSIZE(descript));
966 if (font < 0) return;
967 TDSETSIZE(descript, font);
968
969 /* set the default text size */
970 setval((INTBIG)us_tool, VTOOL, x_("USER_default_node_text_size"),
971 (INTBIG)descript, VINTEGER|VISARRAY|(TEXTDESCRIPTSIZE<<VLENGTHSH)|VDONTSAVE);
972 ttyputverbose(M_("Default node text size is now %s"), us_describefont(font));
973 return;
974 }
975
976 /* handle default arc text size */
977 if (namesamen(pp, x_("default-arc-size"), l) == 0 && l >= 9)
978 {
979 /* get new value */
980 if (count < 2)
981 {
982 ttyputusage(x_("text default-arc-size SIZE"));
983 return;
984 }
985 defaulttextsize(4, descript);
986 font = us_gettextsize(par[1], TDGETSIZE(descript));
987 if (font < 0) return;
988 TDSETSIZE(descript, font);
989
990 /* set the default text size */
991 setval((INTBIG)us_tool, VTOOL, x_("USER_default_arc_text_size"),
992 (INTBIG)descript, VINTEGER|VISARRAY|(TEXTDESCRIPTSIZE<<VLENGTHSH)|VDONTSAVE);
993 ttyputverbose(M_("Default arc text size is now %s"), us_describefont(font));
994 return;
995 }
996
997 /* handle default export text size */
998 if (namesamen(pp, x_("default-export-size"), l) == 0 && l >= 11)
999 {
1000 /* get new value */
1001 if (count < 2)
1002 {
1003 ttyputusage(x_("text default-export-size SIZE"));
1004 return;
1005 }
1006 defaulttextsize(1, descript);
1007 font = us_gettextsize(par[1], TDGETSIZE(descript));
1008 if (font < 0) return;
1009 TDSETSIZE(descript, font);
1010
1011 /* set the default text size */
1012 setval((INTBIG)us_tool, VTOOL, x_("USER_default_export_text_size"),
1013 (INTBIG)descript, VINTEGER|VISARRAY|(TEXTDESCRIPTSIZE<<VLENGTHSH)|VDONTSAVE);
1014 ttyputverbose(M_("Default export text size is now %s"), us_describefont(font));
1015 return;
1016 }
1017
1018 /* handle default nonlayout text size */
1019 if (namesamen(pp, x_("default-nonlayout-text-size"), l) == 0 && l >= 9)
1020 {
1021 /* get new value */
1022 if (count < 2)
1023 {
1024 ttyputusage(x_("text default-nonlayout-text-size SIZE"));
1025 return;
1026 }
1027 defaulttextsize(2, descript);
1028 font = us_gettextsize(par[1], TDGETSIZE(descript));
1029 if (font < 0) return;
1030 TDSETSIZE(descript, font);
1031
1032 /* set the default text size */
1033 setval((INTBIG)us_tool, VTOOL, x_("USER_default_nonlayout_text_size"),
1034 (INTBIG)descript, VINTEGER|VISARRAY|(TEXTDESCRIPTSIZE<<VLENGTHSH)|VDONTSAVE);
1035 ttyputverbose(M_("Default nonlayout text size is now %s"), us_describefont(font));
1036 return;
1037 }
1038
1039 /* handle default instance name size */
1040 if (namesamen(pp, x_("default-instance-size"), l) == 0 && l >= 9)
1041 {
1042 /* get new value */
1043 if (count < 2)
1044 {
1045 ttyputusage(x_("text default-instance-size SIZE"));
1046 return;
1047 }
1048 defaulttextsize(5, descript);
1049 font = us_gettextsize(par[1], TDGETSIZE(descript));
1050 if (font < 0) return;
1051 TDSETSIZE(descript, font);
1052
1053 /* set the default text size */
1054 setval((INTBIG)us_tool, VTOOL, x_("USER_default_instance_text_size"),
1055 (INTBIG)descript, VINTEGER|VISARRAY|(TEXTDESCRIPTSIZE<<VLENGTHSH)|VDONTSAVE);
1056 ttyputverbose(M_("Default instance text size is now %s"), us_describefont(font));
1057 return;
1058 }
1059
1060 /* handle default cell text size */
1061 if (namesamen(pp, x_("default-cell-size"), l) == 0 && l >= 9)
1062 {
1063 /* get new value */
1064 if (count < 2)
1065 {
1066 ttyputusage(x_("text default-cell-size SIZE"));
1067 return;
1068 }
1069 defaulttextsize(6, descript);
1070 font = us_gettextsize(par[1], TDGETSIZE(descript));
1071 if (font < 0) return;
1072 TDSETSIZE(descript, font);
1073
1074 /* set the default text size */
1075 setval((INTBIG)us_tool, VTOOL, x_("USER_default_facet_text_size"),
1076 (INTBIG)descript, VINTEGER|VISARRAY|(TEXTDESCRIPTSIZE<<VLENGTHSH)|VDONTSAVE);
1077 ttyputverbose(M_("Default cell text size is now %s"), us_describefont(font));
1078 return;
1079 }
1080
1081 /* handle default interior style */
1082 if (namesamen(pp, x_("default-interior-only"), l) == 0 && l >= 9)
1083 {
1084 /* get current value */
1085 var = getval((INTBIG)us_tool, VTOOL, VINTEGER, x_("USER_default_text_style"));
1086 if (var == NOVARIABLE) grabpoint = VTPOSCENT; else grabpoint = var->addr;
1087
1088 /* set the default interior style */
1089 setval((INTBIG)us_tool, VTOOL, x_("USER_default_text_style"),
1090 grabpoint|VTINTERIOR, VINTEGER|VDONTSAVE);
1091 ttyputverbose(M_("Default text is visible only inside cell"));
1092 return;
1093 }
1094 if (namesamen(pp, x_("default-exterior"), l) == 0 && l >= 11)
1095 {
1096 /* get current value */
1097 var = getval((INTBIG)us_tool, VTOOL, VINTEGER, x_("USER_default_text_style"));
1098 if (var == NOVARIABLE) grabpoint = VTPOSCENT; else grabpoint = var->addr;
1099
1100 /* set the default interior style */
1101 setval((INTBIG)us_tool, VTOOL, x_("USER_default_text_style"),
1102 grabpoint & ~VTINTERIOR, VINTEGER|VDONTSAVE);
1103 ttyputverbose(M_("Default text is visible outside of cell"));
1104 return;
1105 }
1106
1107 /* handle default style */
1108 if (namesamen(pp, x_("default-style"), l) == 0 && l >= 9)
1109 {
1110 /* get current value */
1111 var = getval((INTBIG)us_tool, VTOOL, VINTEGER, x_("USER_default_text_style"));
1112 if (var == NOVARIABLE) grabpoint = VTPOSCENT; else grabpoint = var->addr;
1113
1114 /* if no argument provided, show current value */
1115 if (count < 2)
1116 {
1117 ttyputmsg(M_("Default text style is %s"), us_describestyle(grabpoint));
1118 if ((grabpoint&VTINTERIOR) != 0)
1119 ttyputmsg(M_("Default text is visible only inside cell")); else
1120 ttyputmsg(M_("Default text is visible outside of cell"));
1121 return;
1122 }
1123
1124 /* get new value */
1125 newgrabpoint = us_gettextposition(par[1]);
1126 grabpoint = (grabpoint & ~VTPOSITION) | newgrabpoint;
1127
1128 /* set the default text style */
1129 setval((INTBIG)us_tool, VTOOL, x_("USER_default_text_style"),
1130 grabpoint, VINTEGER|VDONTSAVE);
1131 ttyputverbose(M_("Default text style is now %s"), us_describestyle(grabpoint));
1132 return;
1133 }
1134
1135 /* handle default horizontal and vertical style */
1136 if (namesamen(pp, x_("default-horizontal-style"), l) == 0 && l >= 9)
1137 {
1138 /* get current value */
1139 var = getval((INTBIG)us_tool, VTOOL, VINTEGER, x_("USER_default_text_smart_style"));
1140 if (var == NOVARIABLE) grabpoint = 0; else grabpoint = var->addr;
1141
1142 /* if no argument provided, show current value */
1143 if (count < 2)
1144 {
1145 ttyputmsg(M_("Default horizontal text style is %s"),
1146 TRANSLATE(smartstyle[grabpoint&03]));
1147 return;
1148 }
1149
1150 /* get new value */
1151 l = estrlen(pp = par[1]);
1152 if (namesamen(pp, x_("none"), l) == 0) grabpoint = (grabpoint & ~03) | 0; else
1153 if (namesamen(pp, x_("inside"), l) == 0) grabpoint = (grabpoint & ~03) | 1; else
1154 if (namesamen(pp, x_("outside"), l) == 0) grabpoint = (grabpoint & ~03) | 2; else
1155 {
1156 ttyputusage(x_("text default-horizontal-style [none|inside|outside]"));
1157 return;
1158 }
1159
1160 /* set the default text style */
1161 setval((INTBIG)us_tool, VTOOL, x_("USER_default_text_smart_style"), grabpoint, VINTEGER|VDONTSAVE);
1162 ttyputverbose(M_("Default horizontal text style is now %s"), TRANSLATE(smartstyle[grabpoint&03]));
1163 return;
1164 }
1165 if (namesamen(pp, x_("default-vertical-style"), l) == 0 && l >= 9)
1166 {
1167 /* get current value */
1168 var = getval((INTBIG)us_tool, VTOOL, VINTEGER, x_("USER_default_text_smart_style"));
1169 if (var == NOVARIABLE) grabpoint = 0; else grabpoint = var->addr;
1170
1171 /* if no argument provided, show current value */
1172 if (count < 2)
1173 {
1174 ttyputmsg(M_("Default vertical text style is %s"),
1175 TRANSLATE(smartstyle[(grabpoint>>2)&03]));
1176 return;
1177 }
1178
1179 /* get new value */
1180 l = estrlen(pp = par[1]);
1181 if (namesamen(pp, x_("none"), l) == 0) grabpoint = (grabpoint & ~014) | 0; else
1182 if (namesamen(pp, x_("inside"), l) == 0) grabpoint = (grabpoint & ~014) | (1<<2); else
1183 if (namesamen(pp, x_("outside"), l) == 0) grabpoint = (grabpoint & ~014) | (2<<2); else
1184 {
1185 ttyputusage(x_("text default-vertical-style [none|inside|outside]"));
1186 return;
1187 }
1188
1189 /* set the default text style */
1190 setval((INTBIG)us_tool, VTOOL, x_("USER_default_text_smart_style"), grabpoint, VINTEGER|VDONTSAVE);
1191 ttyputverbose(M_("Default vertical text style is now %s"), TRANSLATE(smartstyle[(grabpoint>>2)&03]));
1192 return;
1193 }
1194
1195 /* get the text object */
1196 high = us_getonehighlight();
1197 if (high == NOHIGHLIGHT) return;
1198 if ((high->status&HIGHTYPE) != HIGHTEXT)
1199 {
1200 us_abortcommand(_("Find a single text object first"));
1201 return;
1202 }
1203
1204 /* handle grab-point motion */
1205 if (namesamen(pp, x_("style"), l) == 0 && l >= 2)
1206 {
1207 /* make sure the cursor is in the right cell */
1208 np = us_needcell();
1209 if (np == NONODEPROTO) return;
1210 if (np != high->cell)
1211 {
1212 us_abortcommand(_("Must have cursor in this cell"));
1213 return;
1214 }
1215
1216 /* get the center of the text */
1217 us_gethightextcenter(high, &adjxc, &adjyc, &style);
1218
1219 /* get the text and current descriptor */
1220 str = us_gethighstring(high);
1221 us_gethighdescript(high, olddescript);
1222
1223 /* get size of text */
1224 len = 1;
1225 if (high->fromvar != NOVARIABLE && (high->fromvar->type&VISARRAY) != 0)
1226 len = getlength(high->fromvar);
1227 if (len > 1)
1228 {
1229 xw = high->fromgeom->highx - high->fromgeom->lowx;
1230 yw = high->fromgeom->highy - high->fromgeom->lowy;
1231 } else
1232 {
1233 if (!high->fromgeom->entryisnode)
1234 tech = high->fromgeom->entryaddr.ai->proto->tech; else
1235 tech = high->fromgeom->entryaddr.ni->proto->tech;
1236 screensettextinfo(el_curwindowpart, tech, olddescript);
1237 screengettextsize(el_curwindowpart, str, &tsx, &tsy);
1238 xw = muldiv(tsx, el_curwindowpart->screenhx-el_curwindowpart->screenlx,
1239 el_curwindowpart->usehx-el_curwindowpart->uselx);
1240 yw = muldiv(tsy, el_curwindowpart->screenhy-el_curwindowpart->screenly,
1241 el_curwindowpart->usehy-el_curwindowpart->usely);
1242 }
1243
1244 /* save highlighting */
1245 us_pushhighlight();
1246 us_clearhighlightcount();
1247
1248 /* see if a specific grab point has been mentioned */
1249 if (count >= 2)
1250 {
1251 grabpoint = us_gettextposition(par[1]);
1252 TDCOPY(descript, olddescript);
1253 TDSETPOS(descript, grabpoint);
1254 } else
1255 {
1256 /* get co-ordinates of cursor */
1257 if (us_demandxy(&xcur, &ycur))
1258 {
1259 us_pophighlight(FALSE);
1260 return;
1261 }
1262 gridalign(&xcur, &ycur, 1, np);
1263
1264 /* adjust the cursor position if selecting interactively */
1265 if ((us_tool->toolstate&INTERACTIVE) != 0)
1266 {
1267 us_textgrabinit(olddescript, xw, yw, adjxc, adjyc, high->fromgeom);
1268 trackcursor(FALSE, us_ignoreup, us_textgrabbegin, us_textgrabdown,
1269 us_stopandpoponchar, us_dragup, TRACKDRAGGING);
1270 if (el_pleasestop != 0) return;
1271 if (us_demandxy(&xcur, &ycur)) return;
1272 }
1273
1274 /* determine grab point from current cursor location */
1275 TDCOPY(descript, olddescript);
1276 us_figuregrabpoint(descript, xcur, ycur, adjxc, adjyc, xw, yw);
1277 }
1278
1279 /* set the new descriptor */
1280 startobjectchange((INTBIG)high->fromgeom->entryaddr.blind,
1281 high->fromgeom->entryisnode ? VNODEINST : VARCINST);
1282 us_rotatedescriptI(high->fromgeom, descript);
1283 us_modifytextdescript(high, descript);
1284
1285 /* redisplay the text */
1286 endobjectchange((INTBIG)high->fromgeom->entryaddr.blind,
1287 high->fromgeom->entryisnode ? VNODEINST : VARCINST);
1288
1289 /* restore highlighting */
1290 us_pophighlight(FALSE);
1291 return;
1292 }
1293
1294 if (namesamen(pp, x_("size"), l) == 0 && l >= 2)
1295 {
1296 if (count < 2)
1297 {
1298 ttyputusage(x_("text size SCALE"));
1299 return;
1300 }
1301
1302 /* get old descriptor */
1303 if (high->fromvar != NOVARIABLE)
1304 {
1305 TDCOPY(olddescript, high->fromvar->textdescript);
1306 } else if (high->fromport != NOPORTPROTO)
1307 {
1308 TDCOPY(olddescript, high->fromport->textdescript);
1309 } else if (high->fromgeom->entryisnode)
1310 {
1311 ni = high->fromgeom->entryaddr.ni;
1312 TDCOPY(olddescript, ni->textdescript);
1313 }
1314 font = TDGETSIZE(olddescript);
1315 font = us_gettextsize(par[1], font);
1316 if (font < 0) return;
1317
1318 /* save highlighting */
1319 us_pushhighlight();
1320 us_clearhighlightcount();
1321
1322 /* set the new size */
1323 startobjectchange((INTBIG)high->fromgeom->entryaddr.blind,
1324 high->fromgeom->entryisnode ? VNODEINST : VARCINST);
1325
1326 TDSETSIZE(olddescript, font);
1327 us_modifytextdescript(high, olddescript);
1328
1329 /* redisplay the text */
1330 endobjectchange((INTBIG)high->fromgeom->entryaddr.blind,
1331 high->fromgeom->entryisnode ? VNODEINST : VARCINST);
1332
1333 /* restore highlighting */
1334 us_pophighlight(FALSE);
1335 return;
1336 }
1337
1338 if (namesamen(pp, x_("interior-only"), l) == 0)
1339 {
1340 if (high->fromvar == NOVARIABLE)
1341 {
1342 us_abortcommand(_("Interior style only applies to text variables"));
1343 return;
1344 }
1345 if (!high->fromgeom->entryisnode)
1346 {
1347 us_abortcommand(_("Interior style only applies to nodes"));
1348 return;
1349 }
1350
1351 ni = high->fromgeom->entryaddr.ni;
1352 startobjectchange((INTBIG)ni, VNODEINST);
1353 TDCOPY(descript, high->fromvar->textdescript);
1354 TDSETINTERIOR(descript, VTINTERIOR);
1355 us_modifytextdescript(high, descript);
1356 endobjectchange((INTBIG)ni, VNODEINST);
1357 return;
1358 }
1359
1360 if (namesamen(pp, x_("exterior"), l) == 0 && l >= 2)
1361 {
1362 if (high->fromvar == NOVARIABLE)
1363 {
1364 us_abortcommand(_("Interior style only applies to text variables"));
1365 return;
1366 }
1367 if (!high->fromgeom->entryisnode)
1368 {
1369 us_abortcommand(_("Interior style only applies to nodes"));
1370 return;
1371 }
1372 ni = high->fromgeom->entryaddr.ni;
1373 startobjectchange((INTBIG)ni, VNODEINST);
1374 TDCOPY(descript, high->fromvar->textdescript);
1375 TDSETINTERIOR(descript, 0);
1376 us_modifytextdescript(high, descript);
1377 endobjectchange((INTBIG)ni, VNODEINST);
1378 return;
1379 }
1380
1381 ttyputbadusage(x_("text"));
1382 }
1383
us_undo(INTBIG count,CHAR * par[])1384 void us_undo(INTBIG count, CHAR *par[])
1385 {
1386 REGISTER INTBIG ret, i, j;
1387 REGISTER BOOLEAN majorchange, doingundo;
1388 REGISTER CHAR *direction;
1389 TOOL *tool;
1390 REGISTER NODEPROTO *np;
1391 REGISTER LIBRARY *lib;
1392 INTBIG *totals;
1393
1394 if (count > 0 && namesamen(par[0], x_("clear"), estrlen(par[0])) == 0)
1395 {
1396 noundoallowed();
1397 return;
1398 }
1399
1400 if (count > 0 && namesamen(par[0], x_("save"), estrlen(par[0])) == 0)
1401 {
1402 if (count < 2)
1403 {
1404 ttyputusage(x_("undo save AMOUNT"));
1405 return;
1406 }
1407
1408 /* set new history list size */
1409 i = eatoi(par[1]);
1410 if (i <= 0)
1411 {
1412 us_abortcommand(_("Must have positive history list size"));
1413 return;
1414 }
1415 j = historylistsize(i);
1416 ttyputverbose(M_("History list size changed from %ld to %ld entries"), j, i);
1417 return;
1418 }
1419
1420 doingundo = TRUE;
1421 direction = x_("undo");
1422 if (count > 0 && namesamen(par[0], x_("redo"), estrlen(par[0])) == 0)
1423 {
1424 count--;
1425 doingundo = FALSE;
1426 direction = x_("redo");
1427 }
1428
1429 /* special case if current window is text editor: undo handled by editor */
1430 if (el_curwindowpart != NOWINDOWPART && doingundo)
1431 {
1432 if ((el_curwindowpart->state&WINDOWTYPE) == POPTEXTWINDOW ||
1433 (el_curwindowpart->state&WINDOWTYPE) == TEXTWINDOW)
1434 {
1435 us_undotext(el_curwindowpart);
1436 return;
1437 }
1438 }
1439
1440 if (count != 0)
1441 {
1442 i = eatoi(par[0]);
1443 if (i <= 0)
1444 {
1445 us_abortcommand(_("Must %s a positive number of changes"), direction);
1446 return;
1447 }
1448 } else i = -1;
1449
1450 /* do the undo */
1451 totals = (INTBIG *)emalloc((el_maxtools * SIZEOFINTBIG), el_tempcluster);
1452 if (totals == 0)
1453 {
1454 ttyputnomemory();
1455 return;
1456 }
1457 for(j=0; j<el_maxtools; j++) totals[j] = 0;
1458
1459 /* do the undo/redo */
1460 majorchange = FALSE;
1461 for(j=0; ; j++)
1462 {
1463 if (doingundo) ret = undoabatch(&tool); else
1464 ret = redoabatch(&tool);
1465 if (ret == 0)
1466 {
1467 if (j != 0) ttyputmsg(_("Partial change %sne"), direction); else
1468 us_abortcommand(_("No changes to %s"), direction);
1469 break;
1470 }
1471 totals[tool->toolindex]++;
1472 if (i < 0)
1473 {
1474 /* no batch count specified: go back to significant change */
1475 if (ret > 0) majorchange = TRUE;
1476 if (majorchange)
1477 {
1478 /* if redoing, keep on redoing unimportant batches */
1479 if (!doingundo)
1480 {
1481 for(;;)
1482 {
1483 if (undonature(FALSE) >= 0) break;
1484 (void)redoabatch(&tool);
1485 }
1486 }
1487 break;
1488 }
1489 } else
1490 {
1491 /* batch count given: stop when requested number done */
1492 if (j >= i-1) break;
1493 }
1494 }
1495
1496 for(j=0; j<el_maxtools; j++) if (totals[j] != 0)
1497 ttyputverbose(x_("%ld %s %s %sne"), totals[j], el_tools[j].toolname,
1498 makeplural(_("change"), totals[j]), direction);
1499 efree((CHAR *)totals);
1500
1501 /* if a cell is the current node, make sure it still exists */
1502 if (us_curnodeproto != NONODEPROTO && us_curnodeproto->primindex == 0 &&
1503 (us_state&NONPERSISTENTCURNODE) == 0)
1504 {
1505 for(lib = el_curlib; lib != NOLIBRARY; lib = lib->nextlibrary)
1506 for(np = lib->firstnodeproto; np != NONODEPROTO; np = np->nextnodeproto)
1507 if (us_curnodeproto == np) break;
1508 if (np == NONODEPROTO)
1509 {
1510 np = el_curlib->firstnodeproto;
1511 if (np == NONODEPROTO) np = el_curtech->firstnodeproto;
1512 us_setnodeproto(np);
1513 }
1514 }
1515 }
1516
1517 /*
1518 * routine to determine whether the string "testcase" satisfies the pattern "pattern".
1519 * Returns true if it matches.
1520 */
1521 static BOOLEAN us_patternmatch(CHAR *pattern, CHAR *testcase);
1522 static BOOLEAN us_patternmatchhere(CHAR *pattern, CHAR *testcase);
1523
us_patternmatch(CHAR * pattern,CHAR * testcase)1524 BOOLEAN us_patternmatch(CHAR *pattern, CHAR *testcase)
1525 {
1526 REGISTER INTBIG i, testlen;
1527
1528 /* loop through every position in the testcase, seeing if the pattern matches */
1529 testlen = estrlen(testcase);
1530 for(i=0; i<testlen; i++)
1531 if (us_patternmatchhere(pattern, &testcase[i]) != 0) return(TRUE);
1532
1533 /* not a match */
1534 return(FALSE);
1535 }
1536
us_patternmatchhere(CHAR * pattern,CHAR * testcase)1537 BOOLEAN us_patternmatchhere(CHAR *pattern, CHAR *testcase)
1538 {
1539 REGISTER INTBIG i, j, patlen;
1540 CHAR *subpattern;
1541
1542 /* loop through every character in the pattern, seeing if it matches */
1543 patlen = estrlen(pattern);
1544 for(i=0; i<patlen; i++)
1545 {
1546 if (pattern[i] == '*')
1547 {
1548 subpattern = &pattern[i+1];
1549 if (*subpattern == 0) return(TRUE);
1550 for(j=0; testcase[i+j] != 0; j++)
1551 {
1552 if (us_patternmatchhere(subpattern, &testcase[i+j])) return(TRUE);
1553 }
1554 return(FALSE);
1555 }
1556 if (pattern[i] != testcase[i]) return(FALSE);
1557 }
1558
1559 /* made it through the pattern, it matches */
1560 return(TRUE);
1561 }
1562
us_var(INTBIG count,CHAR * par[])1563 void us_var(INTBIG count, CHAR *par[])
1564 {
1565 REGISTER BOOLEAN negated, inplace;
1566 REGISTER INTBIG maxleng, i, j, k, l, function, newval, search, oldaddr, language,
1567 annotate, *newarray, oldlen, len1, len2, count1, count2, count3, disppart;
1568 INTBIG aindex, objaddr, objaddr1, objaddr2, objtype, objtype1, objtype2, newtype, newaddr;
1569 UINTBIG newdescript[TEXTDESCRIPTSIZE];
1570 INTBIG dummy;
1571 BOOLEAN comvar;
1572 BOOLEAN but;
1573 REGISTER VARIABLE *var, *tvar, *res, *var1, *var2, *nvar;
1574 static VARIABLE fvar;
1575 REGISTER GEOM **list, *geom;
1576 REGISTER NODEINST *ni;
1577 VARIABLE *evar, fvar1, fvar2;
1578 REGISTER NODEPROTO *np;
1579 REGISTER LIBRARY *lib;
1580 REGISTER ARCPROTO *ap;
1581 POPUPMENU *me, *cme;
1582 REGISTER POPUPMENUITEM *mi;
1583 REGISTER WINDOWPART *w, *oldw;
1584 REGISTER EDITOR *ed;
1585 REGISTER float oldfloat, oldden, newfloat;
1586 CHAR *pp, *qual, *qual1, *qual2, varname[100], line[50], *name, *code,
1587 *dummyfile[1], *header, *edname, *savequal, qualname[300];
1588 extern COMCOMP us_varvep, us_varvdp, us_varvsp, us_varvalp, us_varvalcp;
1589 static CHAR nullstr[] = {x_("")};
1590 REGISTER void *infstr;
1591
1592 /* show all command interpreter variables if nothing specified */
1593 if (count == 0)
1594 {
1595 j = 0;
1596 for(i=0; i<52; i++)
1597 {
1598 if (i < 26) l = 'a' + i; else
1599 l = 'A' + i - 26;
1600 var = getval((INTBIG)us_tool, VTOOL, -1, us_commandvarname((INTSML)l));
1601 if (var == NOVARIABLE) continue;
1602 (void)esnprintf(varname, 100, x_("%%%c"), (CHAR)l);
1603 ttyputmsg(_("%s variable '%s' is %s"), us_variableattributes(var, -1),
1604 varname, describevariable(var, -1, 0));
1605 j++;
1606 }
1607 if (j == 0) ttyputmsg(_("No command interpreter variables are set"));
1608 return;
1609 }
1610
1611 /* get the variable option */
1612 l = estrlen(pp = par[0]);
1613
1614 if (namesamen(pp, x_("options"), l) == 0 && l >= 2)
1615 {
1616 if (count <= 1)
1617 {
1618 var = getvalkey((INTBIG)us_tool, VTOOL, VINTEGER, us_ignoreoptionchangeskey);
1619 if (var == NOVARIABLE)
1620 ttyputmsg(_("Option changes are being tracked")); else
1621 ttyputmsg(_("Option changes are being ignored"));
1622 return;
1623 }
1624 l = estrlen(pp = par[1]);
1625 if (namesamen(pp, x_("ignore"), l) == 0)
1626 {
1627 (void)setvalkey((INTBIG)us_tool, VTOOL, us_ignoreoptionchangeskey, 1,
1628 VINTEGER|VDONTSAVE);
1629 ttyputverbose(M_("Option changes are being ignored"));
1630 return;
1631 }
1632 if (namesamen(pp, x_("track"), l) == 0)
1633 {
1634 var = getvalkey((INTBIG)us_tool, VTOOL, VINTEGER, us_ignoreoptionchangeskey);
1635 if (var != NOVARIABLE)
1636 (void)delvalkey((INTBIG)us_tool, VTOOL, us_ignoreoptionchangeskey);
1637 ttyputverbose(M_("Option changes are being tracked"));
1638 return;
1639 }
1640 if (namesamen(pp, x_("save"), l) == 0)
1641 {
1642 us_saveoptions();
1643 return;
1644 }
1645 ttyputusage(x_("var options [ignore | track | save]"));
1646 return;
1647 }
1648
1649 if (namesamen(pp, x_("reinherit"), l) == 0 && l >= 3)
1650 {
1651 list = us_gethighlighted(WANTNODEINST, 0, 0);
1652 if (list[0] == NOGEOM)
1653 {
1654 us_abortcommand(_("Must select nodes for reinheriting attributes"));
1655 return;
1656 }
1657 for(i=0; list[i] != NOGEOM; i++)
1658 {
1659 geom = list[i];
1660 if (!geom->entryisnode) continue;
1661 ni = geom->entryaddr.ni;
1662 us_inheritattributes(ni);
1663 }
1664 ttyputmsg(_("%ld nodes have had their parameters reinherited"), i);
1665 return;
1666 }
1667
1668 if (namesamen(pp, x_("total-reinherit"), l) == 0 && l >= 9)
1669 {
1670 ttyputmsg(_("Reinheriting parameters on all instances in all libraries..."));
1671 i = 0;
1672 for(lib = el_curlib; lib != NOLIBRARY; lib = lib->nextlibrary)
1673 {
1674 for(np = lib->firstnodeproto; np != NONODEPROTO; np = np->nextnodeproto)
1675 {
1676 for(ni = np->firstnodeinst; ni != NONODEINST; ni = ni->nextnodeinst)
1677 {
1678 us_inheritattributes(ni);
1679 i++;
1680 }
1681 }
1682 }
1683 ttyputmsg(_("%ld nodes have had their parameters reinherited"), i);
1684 return;
1685 }
1686
1687
1688 if (namesamen(pp, x_("relocate"), l) == 0 && l >= 3)
1689 {
1690 list = us_gethighlighted(WANTNODEINST, 0, 0);
1691 if (list[0] == NOGEOM)
1692 {
1693 us_abortcommand(_("Must select nodes for relocating attributes"));
1694 return;
1695 }
1696 j = 0;
1697 for(i=0; list[i] != NOGEOM; i++)
1698 {
1699 geom = list[i];
1700 if (!geom->entryisnode) continue;
1701 ni = geom->entryaddr.ni;
1702 if (us_adjustparameterlocations(ni)) j++;
1703 }
1704 ttyputmsg(_("%ld nodes have had their parameters relocated"), j);
1705 return;
1706 }
1707
1708 if (namesamen(pp, x_("total-relocate"), l) == 0 && l >= 9)
1709 {
1710 ttyputmsg(_("Relocating parameters on all instances in all libraries..."));
1711 i = 0;
1712 for(lib = el_curlib; lib != NOLIBRARY; lib = lib->nextlibrary)
1713 {
1714 for(np = lib->firstnodeproto; np != NONODEPROTO; np = np->nextnodeproto)
1715 {
1716 for(ni = np->firstnodeinst; ni != NONODEINST; ni = ni->nextnodeinst)
1717 {
1718 if (us_adjustparameterlocations(ni)) i++;
1719 }
1720 }
1721 }
1722 ttyputmsg(_("%ld nodes have had their parameters relocated"), i);
1723 return;
1724 }
1725
1726 if (namesamen(pp, x_("visible-all"), l) == 0 && l >= 9)
1727 {
1728 /* make all parameters on the current node(s) visible */
1729 list = us_gethighlighted(WANTNODEINST, 0, 0);
1730 for(i=0; list[i] != NOGEOM; i++)
1731 {
1732 ni = list[i]->entryaddr.ni;
1733 if (ni->proto->primindex != 0) continue;
1734 for(j=0; j<ni->numvar; j++)
1735 {
1736 var = &ni->firstvar[j];
1737 nvar = us_findparametersource(var, ni);
1738 if (nvar == NOVARIABLE) continue;
1739 if ((var->type&VDISPLAY) != 0) continue;
1740 startobjectchange((INTBIG)ni, VNODEINST);
1741 var->type |= VDISPLAY;
1742 endobjectchange((INTBIG)ni, VNODEINST);
1743 }
1744 }
1745 return;
1746 }
1747
1748 if (namesamen(pp, x_("visible-none"), l) == 0 && l >= 9)
1749 {
1750 /* make all parameters on the current node(s) invisible */
1751 list = us_gethighlighted(WANTNODEINST, 0, 0);
1752 for(i=0; list[i] != NOGEOM; i++)
1753 {
1754 ni = list[i]->entryaddr.ni;
1755 if (ni->proto->primindex != 0) continue;
1756 for(j=0; j<ni->numvar; j++)
1757 {
1758 var = &ni->firstvar[j];
1759 nvar = us_findparametersource(var, ni);
1760 if (nvar == NOVARIABLE) continue;
1761 if ((var->type&VDISPLAY) == 0) continue;
1762 startobjectchange((INTBIG)ni, VNODEINST);
1763 var->type &= ~VDISPLAY;
1764 endobjectchange((INTBIG)ni, VNODEINST);
1765 }
1766 }
1767 return;
1768 }
1769
1770 if (namesamen(pp, x_("visible-default"), l) == 0 && l >= 9)
1771 {
1772 /* make all parameters on the current node(s) visible or invisible according to the cell */
1773 list = us_gethighlighted(WANTNODEINST, 0, 0);
1774 for(i=0; list[i] != NOGEOM; i++)
1775 {
1776 ni = list[i]->entryaddr.ni;
1777 if (ni->proto->primindex != 0) continue;
1778 for(j=0; j<ni->numvar; j++)
1779 {
1780 var = &ni->firstvar[j];
1781 nvar = us_findparametersource(var, ni);
1782 if (nvar == NOVARIABLE) continue;
1783 if (TDGETINTERIOR(nvar->textdescript) == 0)
1784 {
1785 /* prototype wants parameter to be visible */
1786 if ((var->type&VDISPLAY) != 0) continue;
1787 startobjectchange((INTBIG)ni, VNODEINST);
1788 var->type |= VDISPLAY;
1789 endobjectchange((INTBIG)ni, VNODEINST);
1790 } else
1791 {
1792 /* prototype wants parameter to be invisible */
1793 if ((var->type&VDISPLAY) == 0) continue;
1794 startobjectchange((INTBIG)ni, VNODEINST);
1795 var->type &= ~VDISPLAY;
1796 endobjectchange((INTBIG)ni, VNODEINST);
1797 }
1798 }
1799 }
1800 return;
1801 }
1802
1803 if (namesamen(pp, x_("examine"), l) == 0 && l >= 1)
1804 {
1805 if (count <= 1)
1806 {
1807 count = ttygetparam(M_("Variable: "), &us_varvep, MAXPARS-1, &par[1]) + 1;
1808 if (count == 1)
1809 {
1810 us_abortedmsg();
1811 return;
1812 }
1813 }
1814 if (us_getvar(par[1], &objaddr, &objtype, &qual, &comvar, &aindex))
1815 {
1816 us_abortcommand(_("Incorrect variable name: %s"), par[1]);
1817 return;
1818 }
1819 code = 0;
1820 if (*qual != 0)
1821 {
1822 search = initobjlist(objaddr, objtype, FALSE);
1823 if (search == 0)
1824 {
1825 us_abortcommand(_("Object is invalid"));
1826 return;
1827 }
1828 for(;;)
1829 {
1830 pp = nextobjectlist(&evar, search);
1831 if (pp == 0)
1832 {
1833 us_abortcommand(_("No variable %s on the object"), qual);
1834 return;
1835 }
1836 if (namesame(pp, qual) == 0) break;
1837 }
1838 language = evar->type & (VCODE1|VCODE2);
1839 if (language != 0)
1840 {
1841 code = (CHAR *)evar->addr;
1842 fvar.key = evar->key;
1843 fvar.type = evar->type;
1844 var = doquerry(code, language, evar->type);
1845 if (var == NOVARIABLE) code = 0; else
1846 {
1847 var->key = evar->key;
1848 TDCOPY(var->textdescript, evar->textdescript);
1849 evar = var;
1850 }
1851 }
1852 var = evar;
1853 } else
1854 {
1855 fvar.addr = objaddr; fvar.type = objtype;
1856 var = &fvar;
1857 }
1858 if (aindex >= 0 && (var->type&VISARRAY) == 0)
1859 {
1860 us_abortcommand(_("%s is not an indexable array"), par[1]);
1861 return;
1862 }
1863 (void)esnprintf(varname, 100, x_("%c%s"), (comvar ? '%' : '$'), par[1]);
1864 infstr = initinfstr();
1865 if (code != 0)
1866 {
1867 addstringtoinfstr(infstr, code);
1868 addstringtoinfstr(infstr, x_(" => "));
1869 }
1870 addstringtoinfstr(infstr, describevariable(var, aindex, 0));
1871 ttyputmsg(_("%s variable '%s' is %s"), us_variableattributes(var, aindex),
1872 varname, returninfstr(infstr));
1873 return;
1874 }
1875
1876 if (namesamen(pp, x_("change"), l) == 0 && l >= 1)
1877 {
1878 if (count <= 2)
1879 {
1880 ttyputusage(x_("var change VARIABLE STYLE"));
1881 return;
1882 }
1883 if (us_getvar(par[1], &objaddr, &objtype, &qual, &comvar, &aindex))
1884 {
1885 us_abortcommand(_("Incorrect variable name: %s"), par[1]);
1886 return;
1887 }
1888 if (comvar)
1889 {
1890 us_abortcommand(_("Can only modify database ($) variables"));
1891 return;
1892 }
1893 if (*qual != 0)
1894 {
1895 var = getval(objaddr, objtype, -1, qual);
1896 if (var == NOVARIABLE)
1897 {
1898 us_abortcommand(_("No variable %s on the object"), qual);
1899 return;
1900 }
1901 } else
1902 {
1903 fvar.addr = objaddr; fvar.type = objtype;
1904 var = &fvar;
1905 }
1906 if (aindex >= 0 && (var->type&VISARRAY) == 0)
1907 {
1908 us_abortcommand(_("%s is not an indexable array"), par[1]);
1909 return;
1910 }
1911
1912 /* make the change */
1913 l = estrlen(pp = par[2]);
1914 negated = FALSE;
1915 if (namesamen(pp, x_("not"), l) == 0 && l >= 2)
1916 {
1917 negated = TRUE;
1918 par++;
1919 count--;
1920 if (count <= 2)
1921 {
1922 ttyputusage(x_("var change VARIABLE not STYLE"));
1923 return;
1924 }
1925 l = estrlen(pp = par[2]);
1926 }
1927 if ((namesamen(pp, x_("display"), l) == 0 && l >= 1) ||
1928 (namesamen(pp, x_("na-va-display"), l) == 0 && l >= 2) ||
1929 (namesamen(pp, x_("in-na-va-display"), l) == 0 && l >= 3) ||
1930 (namesamen(pp, x_("inall-na-va-display"), l) == 0 && l >= 3))
1931 {
1932 /* compute the new type field */
1933 TDCOPY(newdescript, var->textdescript);
1934 us_figurevariableplace(newdescript, count-3, &par[3]);
1935
1936 /* signal start of change to nodes and arcs */
1937 if (objtype == VNODEINST || objtype == VARCINST)
1938 {
1939 us_pushhighlight();
1940 us_clearhighlightcount();
1941 startobjectchange(objaddr, objtype);
1942 } else if (objtype == VNODEPROTO)
1943 {
1944 us_undrawcellvariable(var, (NODEPROTO *)objaddr);
1945 }
1946
1947 /* change the variable */
1948 if (!negated)
1949 {
1950 var->type |= VDISPLAY;
1951 modifydescript(objaddr, objtype, var, newdescript);
1952 } else var->type &= ~VDISPLAY;
1953 disppart = 0;
1954 if (namesamen(pp, x_("display"), l) == 0 && l >= 1)
1955 disppart = VTDISPLAYVALUE; else
1956 if (namesamen(pp, x_("na-va-display"), l) == 0 && l >= 2)
1957 disppart = VTDISPLAYNAMEVALUE; else
1958 if (namesamen(pp, x_("in-na-va-display"), l) == 0 && l >= 3)
1959 disppart = VTDISPLAYNAMEVALINH; else
1960 if (namesamen(pp, x_("inall-na-va-display"), l) == 0 && l >= 3)
1961 disppart = VTDISPLAYNAMEVALINHALL;
1962 if ((disppart == VTDISPLAYNAMEVALINH || disppart == VTDISPLAYNAMEVALINHALL) &&
1963 (objtype&VTYPE) != VNODEPROTO)
1964 {
1965 ttyputmsg(_("%s is allowed for cells only, changing to na-va-display"), pp);
1966 disppart = VTDISPLAYNAMEVALUE;
1967 }
1968 TDSETDISPPART(var->textdescript, disppart);
1969
1970 /* signal end of change to nodes and arcs */
1971 if (objtype == VNODEINST || objtype == VARCINST)
1972 {
1973 endobjectchange(objaddr, objtype);
1974 us_pophighlight(FALSE);
1975 } else if (objtype == VNODEPROTO)
1976 {
1977 us_drawcellvariable(var, (NODEPROTO *)objaddr);
1978 }
1979 return;
1980 }
1981 if (negated && namesamen(pp, x_("language"), l) == 0 && l >= 1)
1982 {
1983 var->type |= (VCODE1|VCODE2);
1984 return;
1985 }
1986 if (!negated && namesamen(pp, x_("lisp"), l) == 0 && l >= 1)
1987 {
1988 var->type |= VLISP;
1989 return;
1990 }
1991 if (!negated && namesamen(pp, x_("tcl"), l) == 0 && l >= 1)
1992 {
1993 var->type |= VTCL;
1994 return;
1995 }
1996 if (!negated && namesamen(pp, x_("java"), l) == 0 && l >= 1)
1997 {
1998 var->type |= VJAVA;
1999 return;
2000 }
2001 if (namesamen(pp, x_("temporary"), l) == 0 && l >= 1)
2002 {
2003 if (!negated) var->type |= VDONTSAVE; else
2004 var->type &= ~VDONTSAVE;
2005 return;
2006 }
2007 if (namesamen(pp, x_("cannot-change"), l) == 0 && l >= 1)
2008 {
2009 if (!negated) var->type |= VCANTSET; else
2010 var->type &= ~VCANTSET;
2011 return;
2012 }
2013 if (namesamen(pp, x_("interior-only"), l) == 0 && l >= 3)
2014 {
2015 if (!negated)
2016 {
2017 TDSETINTERIOR(var->textdescript, VTINTERIOR);
2018 } else
2019 {
2020 TDSETINTERIOR(var->textdescript, 0);
2021 }
2022 return;
2023 }
2024 ttyputbadusage(x_("var change"));
2025 return;
2026 }
2027
2028 if (namesamen(pp, x_("delete"), l) == 0 && l >= 1)
2029 {
2030 if (count <= 1)
2031 {
2032 count = ttygetparam(_("Variable: "), &us_varvdp, MAXPARS-1, &par[1]) + 1;
2033 if (count == 1)
2034 {
2035 us_abortedmsg();
2036 return;
2037 }
2038 }
2039 if (us_getvar(par[1], &objaddr, &objtype, &qual, &comvar, &aindex))
2040 {
2041 us_abortcommand(_("Incorrect variable name: %s"), par[1]);
2042 return;
2043 }
2044 if (comvar)
2045 {
2046 us_abortcommand(_("Can't delete command interpreter variables yet"));
2047 return;
2048 }
2049 if (aindex >= 0)
2050 {
2051 us_abortcommand(_("Cannot delete a single variable entry"));
2052 return;
2053 }
2054 if (*qual == 0)
2055 {
2056 us_abortcommand(_("Must delete a variable ON some object"));
2057 return;
2058 }
2059 (void)allocstring(&savequal, qual, el_tempcluster);
2060 var = getval(objaddr, objtype, -1, savequal);
2061 if (var == NOVARIABLE)
2062 {
2063 efree(savequal);
2064 us_abortcommand(_("No variable %s to delete"), savequal);
2065 return;
2066 }
2067
2068 /* signal start of change to nodes and arcs */
2069 if (objtype == VNODEINST || objtype == VARCINST)
2070 {
2071 us_pushhighlight();
2072 us_clearhighlightcount();
2073 startobjectchange(objaddr, objtype);
2074 } else if (objtype == VNODEPROTO)
2075 {
2076 us_undrawcellvariable(var, (NODEPROTO *)objaddr);
2077 }
2078
2079 if (delval(objaddr, objtype, savequal))
2080 ttyputerr(_("Problem deleting variable %s"), par[1]);
2081
2082 /* signal end of change to nodes and arcs */
2083 if (objtype == VNODEINST || objtype == VARCINST)
2084 {
2085 endobjectchange(objaddr, objtype);
2086 us_pophighlight(FALSE);
2087 }
2088 efree(savequal);
2089 return;
2090 }
2091
2092 if (namesamen(pp, x_("textedit"), l) == 0 && l >= 2)
2093 {
2094 if (count <= 1)
2095 {
2096 count = ttygetparam(M_("Variable: "), &us_varvep, MAXPARS-1, &par[1]) + 1;
2097 if (count == 1)
2098 {
2099 us_abortedmsg();
2100 return;
2101 }
2102 }
2103 header = 0;
2104 inplace = FALSE;
2105 name = par[1];
2106 while (count > 2)
2107 {
2108 l = estrlen(pp=par[2]);
2109 if (namesamen(pp, x_("header"), l) == 0)
2110 {
2111 if (count > 3) header = par[3]; else
2112 {
2113 ttyputusage(x_("var textedit VARIABLE header HEADER"));
2114 return;
2115 }
2116 count--;
2117 par++;
2118 } else if (namesamen(pp, x_("in-place"), l) == 0)
2119 {
2120 inplace = TRUE;
2121 } else
2122 {
2123 ttyputbadusage(x_("var textedit"));
2124 return;
2125 }
2126 count--;
2127 par++;
2128 }
2129 if (us_getvar(name, &objaddr, &objtype, &qual, &comvar, &aindex))
2130 {
2131 us_abortcommand(_("Incorrect variable name: %s"), name);
2132 return;
2133 }
2134 if (*qual != 0)
2135 {
2136 var = getval(objaddr, objtype, -1, qual);
2137 if (var == NOVARIABLE)
2138 {
2139 dummyfile[0] = x_("");
2140 (void)setval(objaddr, objtype, qual, (INTBIG)dummyfile, VSTRING|VISARRAY|(1<<VLENGTHSH));
2141 var = getval(objaddr, objtype, -1, qual);
2142 if (var == NOVARIABLE)
2143 {
2144 us_abortcommand(_("Cannot create %s on the object"), qual);
2145 return;
2146 }
2147 ttyputverbose(M_("Creating %s on the object"), qual);
2148 }
2149 fvar.addr = var->addr; fvar.type = var->type;
2150 fvar.key = var->key; TDCOPY(fvar.textdescript, var->textdescript);
2151 } else
2152 {
2153 fvar.addr = objaddr; fvar.type = objtype;
2154 }
2155 var = &fvar;
2156
2157 if (inplace)
2158 {
2159 if ((var->type&VDISPLAY) == 0)
2160 {
2161 us_abortcommand(_("Only displayable variables can be edited in place"));
2162 return;
2163 }
2164 if ((var->type&VTYPE) != VSTRING)
2165 {
2166 us_abortcommand(_("Only string variables can be edited in place"));
2167 return;
2168 }
2169
2170 /* save and clear highlighting */
2171 us_pushhighlight();
2172 us_clearhighlightcount();
2173
2174 /* edit the variable */
2175 us_editvariabletext(var, objtype, objaddr, qual);
2176
2177 /* restore highlighting */
2178 us_pophighlight(FALSE);
2179 return;
2180 }
2181
2182 if ((var->type&VISARRAY) == 0)
2183 {
2184 /* ensure that the variable is settable */
2185 if ((var->type&VCANTSET) != 0)
2186 {
2187 ttyputmsg(_("Variable cannot be changed; use 'examine' option"));
2188 return;
2189 }
2190
2191 /* save the information about this variable */
2192 if (us_varqualsave == 0) (void)allocstring(&us_varqualsave, qual, us_tool->cluster); else
2193 (void)reallocstring(&us_varqualsave, qual, us_tool->cluster);
2194
2195 /* create the editor window and load it with the variable */
2196 if (header == 0)
2197 {
2198 infstr = initinfstr();
2199 us_describeeditor(&edname);
2200 addstringtoinfstr(infstr, edname);
2201 addstringtoinfstr(infstr, _(" Editor for variable: "));
2202 addstringtoinfstr(infstr, name);
2203 header = returninfstr(infstr);
2204 }
2205 us_wpop = us_makeeditor(NOWINDOWPART, header, &dummy, &dummy);
2206 if (us_wpop == NOWINDOWPART) return;
2207
2208 ed = us_wpop->editor;
2209 ed->editobjqual = us_varqualsave;
2210 ed->editobjaddr = (CHAR *)objaddr;
2211 ed->editobjtype = objtype&VTYPE;
2212 ed->editobjvar = var;
2213
2214 /* turn off editor display as data is loaded into it */
2215 us_suspendgraphics(us_wpop);
2216 us_addline(us_wpop, 0, describevariable(var, -1, -1));
2217 us_resumegraphics(us_wpop);
2218
2219 /* loop on input */
2220 oldw = el_curwindowpart;
2221 el_curwindowpart = us_wpop;
2222 ttyputverbose(M_("You are typing to the editor"));
2223 modalloop(us_wpopcharhandler, us_wpopbuttonhandler, us_normalcursor);
2224 el_curwindowpart = oldw;
2225
2226 /* read back the contents of the editor window */
2227 (void)allocstring(&pp, us_getline(us_wpop, 0), el_tempcluster);
2228
2229 /* terminate this popup window */
2230 startobjectchange((INTBIG)us_tool, VTOOL);
2231 killwindowpart(us_wpop);
2232 endobjectchange((INTBIG)us_tool, VTOOL);
2233
2234 /* signal start of change to nodes and arcs */
2235 if ((objtype&VTYPE) == VNODEINST || (objtype&VTYPE) == VARCINST)
2236 {
2237 us_pushhighlight();
2238 us_clearhighlightcount();
2239 startobjectchange(objaddr, objtype&VTYPE);
2240 }
2241
2242 switch (ed->editobjvar->type&VTYPE)
2243 {
2244 case VINTEGER:
2245 case VSHORT:
2246 case VADDRESS:
2247 res = setval((INTBIG)ed->editobjaddr, ed->editobjtype,
2248 ed->editobjqual, myatoi(pp), ed->editobjvar->type);
2249 break;
2250 case VFLOAT:
2251 case VDOUBLE:
2252 newfloat = (float)eatof(pp);
2253 res = setval((INTBIG)ed->editobjaddr, ed->editobjtype,
2254 ed->editobjqual, castint(newfloat), ed->editobjvar->type);
2255 break;
2256 case VSTRING:
2257 res = setval((INTBIG)ed->editobjaddr, ed->editobjtype,
2258 ed->editobjqual, (INTBIG)pp, ed->editobjvar->type);
2259 break;
2260 case VPORTPROTO:
2261 us_renameport((PORTPROTO *)ed->editobjaddr, pp);
2262 break;
2263 default:
2264 ttyputmsg(_("Cannot update this type of variable"));
2265 break;
2266 }
2267 if (res == NOVARIABLE) ttyputerr(_("Error changing variable"));
2268
2269 /* signal end of change to nodes and arcs */
2270 if ((objtype&VTYPE) == VNODEINST || (objtype&VTYPE) == VARCINST)
2271 {
2272 endobjectchange(objaddr, objtype&VTYPE);
2273 us_pophighlight(FALSE);
2274 }
2275 efree(pp);
2276 return;
2277 }
2278
2279 /* array variable: use full editor */
2280 if (aindex >= 0) ttyputmsg(_("WARNING: index specification being ignored"));
2281
2282 /* save the information about this variable */
2283 if (us_varqualsave == 0) (void)allocstring(&us_varqualsave, qual, us_tool->cluster); else
2284 (void)reallocstring(&us_varqualsave, qual, us_tool->cluster);
2285
2286 /* get a new window, put an editor in it */
2287 w = us_wantnewwindow(0);
2288 if (w == NOWINDOWPART) return;
2289 if (header == 0)
2290 {
2291 infstr = initinfstr();
2292 us_describeeditor(&edname);
2293 addstringtoinfstr(infstr, edname);
2294 addstringtoinfstr(infstr, _(" Editor for variable: "));
2295 addstringtoinfstr(infstr, name);
2296 header = returninfstr(infstr);
2297 }
2298 if (us_makeeditor(w, header, &dummy, &dummy) == NOWINDOWPART) return;
2299 ed = w->editor;
2300 ed->editobjqual = us_varqualsave;
2301 ed->editobjaddr = (CHAR *)objaddr;
2302 ed->editobjtype = objtype;
2303 ed->editobjvar = var;
2304 us_suspendgraphics(w);
2305
2306 /* determine the type of this variable for annotation */
2307 annotate = 0;
2308 if (us_varqualsave[0] != 0 && (objtype&VTYPE) == VTECHNOLOGY)
2309 {
2310 /* these variables correspond to layer names */
2311 if (namesame(us_varqualsave, x_("SIM_spice_resistance")) == 0 ||
2312 namesame(us_varqualsave, x_("SIM_spice_capacitance")) == 0 ||
2313 namesame(us_varqualsave, x_("TECH_layer_function")) == 0 ||
2314 namesame(us_varqualsave, x_("USER_layer_letters")) == 0 ||
2315 namesame(us_varqualsave, x_("DRC_max_distances")) == 0 ||
2316 namesame(us_varqualsave, x_("IO_gds_layer_numbers")) == 0 ||
2317 namesame(us_varqualsave, x_("IO_dxf_layer_names")) == 0 ||
2318 namesame(us_varqualsave, x_("IO_cif_layer_names")) == 0 ||
2319 namesame(us_varqualsave, x_("IO_skill_layer_names")) == 0)
2320 {
2321 annotate = 1;
2322 tvar = getval(objaddr, objtype, VSTRING|VISARRAY, x_("TECH_layer_names"));
2323 if (tvar == NOVARIABLE) annotate = 0;
2324 }
2325
2326 /* these variables correspond to a primitive nodeproto */
2327 if (namesame(us_varqualsave, x_("TECH_node_width_offset")) == 0)
2328 {
2329 annotate = 2;
2330 np = ((TECHNOLOGY *)objaddr)->firstnodeproto;
2331 }
2332
2333 /* these variables correspond to a color map */
2334 if (namesame(us_varqualsave, x_("USER_color_map")) == 0) annotate = 3;
2335
2336 /* these variables correspond to an upper-diagonal layer table */
2337 if (namesame(us_varqualsave, x_("DRC_min_connected_distances")) == 0 ||
2338 namesame(us_varqualsave, x_("DRC_min_connected_distances_rule")) == 0 ||
2339 namesame(us_varqualsave, x_("DRC_min_unconnected_distances")) == 0 ||
2340 namesame(us_varqualsave, x_("DRC_min_unconnected_distances_rule")) == 0 ||
2341 namesame(us_varqualsave, x_("DRC_min_connected_distances_wide")) == 0 ||
2342 namesame(us_varqualsave, x_("DRC_min_connected_distances_wide_rule")) == 0 ||
2343 namesame(us_varqualsave, x_("DRC_min_unconnected_distances_wide")) == 0 ||
2344 namesame(us_varqualsave, x_("DRC_min_unconnected_distances_wide_rule")) == 0 ||
2345 namesame(us_varqualsave, x_("DRC_min_connected_distances_multi")) == 0 ||
2346 namesame(us_varqualsave, x_("DRC_min_connected_distances_multi_rule")) == 0 ||
2347 namesame(us_varqualsave, x_("DRC_min_unconnected_distances_multi")) == 0 ||
2348 namesame(us_varqualsave, x_("DRC_min_unconnected_distances_multi_rule")) == 0 ||
2349 namesame(us_varqualsave, x_("DRC_min_edge_distances")) == 0 ||
2350 namesame(us_varqualsave, x_("DRC_min_edge_distances_rule")) == 0)
2351 {
2352 annotate = 4;
2353 maxleng = ((TECHNOLOGY *)objaddr)->layercount;
2354 j = k = 0;
2355 tvar = getval(objaddr, objtype, VSTRING|VISARRAY, x_("TECH_layer_names"));
2356 if (tvar == NOVARIABLE) annotate = 0;
2357 }
2358
2359 /* these variables correspond to pairs of X and Y coordinates */
2360 if (namesame(us_varqualsave, x_("prototype_center")) == 0 ||
2361 namesame(us_varqualsave, x_("trace")) == 0) annotate = 5;
2362
2363 /* these variables correspond to a primitive arcproto */
2364 if (namesame(us_varqualsave, x_("TECH_arc_width_offset")) == 0)
2365 {
2366 annotate = 6;
2367 ap = ((TECHNOLOGY *)objaddr)->firstarcproto;
2368 }
2369 }
2370
2371 l = getlength(var);
2372 for(i=0; i<l; i++)
2373 {
2374 infstr = initinfstr();
2375 addstringtoinfstr(infstr, describevariable(var, i, -1));
2376 switch (annotate)
2377 {
2378 case 0: break;
2379 case 1:
2380 if (i < getlength(tvar))
2381 {
2382 addstringtoinfstr(infstr, x_(" /* "));
2383 addstringtoinfstr(infstr, ((CHAR **)tvar->addr)[i]);
2384 addstringtoinfstr(infstr, x_(" */"));
2385 }
2386 break;
2387 case 2:
2388 if ((i%4) != 0) break;
2389 if (np != NONODEPROTO)
2390 {
2391 addstringtoinfstr(infstr, x_(" /* "));
2392 addstringtoinfstr(infstr, np->protoname);
2393 np = np->nextnodeproto;
2394 addstringtoinfstr(infstr, x_(" */"));
2395 }
2396 break;
2397 case 3:
2398 (void)esnprintf(line, 50, M_(" /* entry %ld "), i/4);
2399 addstringtoinfstr(infstr, line);
2400 switch (i%4)
2401 {
2402 case 0: addstringtoinfstr(infstr, M_("red */")); break;
2403 case 1: addstringtoinfstr(infstr, M_("green */")); break;
2404 case 2: addstringtoinfstr(infstr, M_("blue */")); break;
2405 case 3: addstringtoinfstr(infstr, M_("letter */")); break;
2406 }
2407 break;
2408 case 4:
2409 if (j < getlength(tvar) && k < getlength(tvar))
2410 {
2411 addstringtoinfstr(infstr, x_(" /* "));
2412 addstringtoinfstr(infstr, ((CHAR **)tvar->addr)[j]);
2413 addstringtoinfstr(infstr, x_(" TO "));
2414 addstringtoinfstr(infstr, ((CHAR **)tvar->addr)[k]);
2415 addstringtoinfstr(infstr, x_(" */"));
2416 }
2417 k++;
2418 if (k >= maxleng)
2419 {
2420 j++;
2421 k = j;
2422 }
2423 break;
2424 case 5:
2425 if ((i%1) == 0) (void)esnprintf(line, 50, x_(" /* X[%ld] */"), i/2); else
2426 (void)esnprintf(line, 50, x_(" /* Y[%ld] */"), i/2);
2427 addstringtoinfstr(infstr, line);
2428 break;
2429 case 6:
2430 if (ap != NOARCPROTO)
2431 {
2432 addstringtoinfstr(infstr, x_(" /* "));
2433 addstringtoinfstr(infstr, describearcproto(ap));
2434 ap = ap->nextarcproto;
2435 addstringtoinfstr(infstr, x_(" */"));
2436 }
2437 break;
2438 }
2439 us_addline(w, i, returninfstr(infstr));
2440 }
2441 us_resumegraphics(w);
2442 w->changehandler = us_varchanges;
2443 if (annotate != 0) ed->state |= LINESFIXED;
2444 return;
2445 }
2446
2447 if (namesamen(pp, x_("pick"), l) == 0 && l >= 1)
2448 {
2449 /* get the name of the object to show in a popup menu */
2450 if (count <= 1)
2451 {
2452 count = ttygetparam(_("Object: "), &us_varvep, MAXPARS-1, &par[1]) + 1;
2453 if (count == 1)
2454 {
2455 us_abortedmsg();
2456 return;
2457 }
2458 }
2459
2460 /* parse the name into an object, type, qualification, index, etc. */
2461 if (us_getvar(par[1], &objaddr, &objtype, &qual, &comvar, &aindex))
2462 {
2463 us_abortcommand(_("Incorrect variable name: %s"), par[1]);
2464 return;
2465 }
2466
2467 /* cannot examine database variables */
2468 if (comvar)
2469 {
2470 us_abortcommand(_("Cannot use database variables"));
2471 return;
2472 }
2473
2474 /* if the object is qualified, examine the qualification */
2475 if (*qual != 0)
2476 {
2477 var = getval(objaddr, objtype, -1, qual);
2478 if (var == NOVARIABLE)
2479 {
2480 us_abortcommand(_("No variable %s on the object"), qual);
2481 return;
2482 }
2483 objaddr = var->addr; objtype = var->type;
2484 }
2485
2486 /* cannot examine objects with no structure */
2487 if ((objtype&VTYPE) < VNODEINST || (objtype&VTYPE) == VFRACT || (objtype&VTYPE) == VSHORT || (objtype&VTYPE) == VBOOLEAN)
2488 {
2489 us_abortcommand(_("Cannot examine simple objects"));
2490 return;
2491 }
2492
2493 /* if the object is indexed, grab that entry */
2494 if (aindex >= 0)
2495 {
2496 if ((objtype&VISARRAY) == 0)
2497 {
2498 us_abortcommand(_("Variable is not an array: cannot index it"));
2499 return;
2500 }
2501 objaddr = ((INTBIG *)objaddr)[aindex];
2502 objtype &= ~VISARRAY;
2503 }
2504
2505 /* cannot examine arrays */
2506 if ((objtype&VISARRAY) != 0)
2507 {
2508 us_abortcommand(_("Must pick single entries of arrays"));
2509 return;
2510 }
2511
2512 /* look through all attributes on the variable */
2513 search = initobjlist(objaddr, objtype, TRUE);
2514 if (search == 0)
2515 {
2516 us_abortcommand(_("Cannot access variable components"));
2517 return;
2518 }
2519
2520 /* count the number of nonarray attributes and get longest value */
2521 maxleng = 0;
2522 for(j=0; ;)
2523 {
2524 pp = nextobjectlist(&evar, search);
2525 if (pp == 0) break;
2526 if ((evar->type&VISARRAY) != 0) continue;
2527 j++;
2528 i = estrlen(describevariable(evar, -1, 0));
2529 if (i > maxleng) maxleng = i;
2530 }
2531 maxleng += 5;
2532
2533 /* allocate the pop-up menu structure */
2534 me = (POPUPMENU *)emalloc(sizeof(POPUPMENU), el_tempcluster);
2535 if (me == 0)
2536 {
2537 ttyputnomemory();
2538 return;
2539 }
2540 mi = (POPUPMENUITEM *)emalloc((j * (sizeof (POPUPMENUITEM))), el_tempcluster);
2541 if (mi == 0)
2542 {
2543 ttyputnomemory();
2544 return;
2545 }
2546
2547 /* load up the menu structure */
2548 search = initobjlist(objaddr, objtype, TRUE);
2549 if (search == 0)
2550 {
2551 us_abortcommand(_("Strange error accessing component"));
2552 return;
2553 }
2554 l = 0;
2555 for(i=0; ;)
2556 {
2557 pp = nextobjectlist(&evar, search);
2558 if (pp == 0) break;
2559 if ((evar->type&VISARRAY) != 0) continue;
2560 if (evar->key == (UINTBIG)-1 || (evar->type&VCANTSET) != 0)
2561 {
2562 (void)allocstring(&mi[i].attribute, pp, el_tempcluster);
2563 mi[i].maxlen = -1;
2564 mi[i].valueparse = &us_varvalcp;
2565 } else
2566 {
2567 mi[i].attribute = (CHAR *)emalloc((estrlen(pp)+3) * SIZEOFCHAR, el_tempcluster);
2568 if (mi[i].attribute == 0)
2569 {
2570 ttyputnomemory();
2571 return;
2572 }
2573 (void)estrcpy(mi[i].attribute, x_("* "));
2574 (void)estrcat(mi[i].attribute, pp);
2575 mi[i].maxlen = maxleng;
2576 mi[i].valueparse = &us_varvalp;
2577 l++;
2578 }
2579 mi[i].value = (CHAR *)emalloc((maxleng+1) * SIZEOFCHAR, el_tempcluster);
2580 if (mi[i].value == 0)
2581 {
2582 ttyputnomemory();
2583 return;
2584 }
2585 (void)estrcpy(mi[i].value, describevariable(evar, -1, 0));
2586 mi[i].changed = FALSE;
2587 mi[i].response = NOUSERCOM;
2588 i++;
2589 }
2590 me->name = x_("noname");
2591 me->list = mi;
2592 me->total = j;
2593 if (l != 0) me->header = _("Set values (* only)"); else
2594 me->header = _("Examine values");
2595 but = TRUE;
2596 cme = me;
2597 if (us_popupmenu(&cme, &but, TRUE, -1, -1, 0) == 0)
2598 us_abortcommand(_("This display does not support popup menus"));
2599
2600 /* now deal with changes made */
2601 search = initobjlist(objaddr, objtype, TRUE);
2602 if (search == 0)
2603 {
2604 us_abortcommand(_("Strange error accessing component"));
2605 return;
2606 }
2607 for(i=0; ;)
2608 {
2609 pp = nextobjectlist(&evar, search);
2610 if (pp == 0) break;
2611 if ((evar->type&VISARRAY) != 0) continue;
2612 if (!mi[i].changed) { i++; continue; }
2613 l = 0;
2614 switch (evar->type & VTYPE)
2615 {
2616 case VFLOAT:
2617 case VDOUBLE: j = castint((float)eatof(mi[i].value)); break;
2618 case VSHORT:
2619 case VBOOLEAN:
2620 case VINTEGER: j = myatoi(mi[i].value); break;
2621 case VCHAR: j = (INTBIG)*mi[i].value; break;
2622 case VSTRING:
2623 qual = mi[i].value;
2624 if (*qual == '"' && qual[estrlen(qual)-1] == '"')
2625 {
2626 qual[estrlen(qual)-1] = 0;
2627 qual++;
2628 }
2629 j = (INTBIG)qual;
2630 break;
2631 default:
2632 us_abortcommand(_("Cannot change attribute %s: bad type"), pp);
2633 l++;
2634 break;
2635 }
2636 if (l == 0)
2637 {
2638 (void)setval(objaddr, objtype, pp, j, evar->type);
2639 ttyputmsg(_("Changed attribute %s to %s"), pp, mi[i].value);
2640 }
2641 i++;
2642 }
2643
2644 /* free the space */
2645 for(i=0; i<me->total; i++)
2646 {
2647 efree(mi[i].attribute);
2648 efree(mi[i].value);
2649 }
2650 efree((CHAR *)mi);
2651 efree((CHAR *)me);
2652 return;
2653 }
2654
2655 /* handle array operations */
2656 if (namesamen(pp, x_("vector"), l) == 0 && l >= 2)
2657 {
2658 if (count < 4)
2659 {
2660 ttyputusage(x_("var vector DEST SOURCE1 OPERATOR [SOURCE2]"));
2661 return;
2662 }
2663
2664 /* get the destination variable */
2665 if (us_getvar(par[1], &objaddr, &objtype, &pp, &comvar, &aindex))
2666 {
2667 us_abortcommand(_("Incorrect variable name: %s"), par[1]);
2668 return;
2669 }
2670 if (aindex >= 0)
2671 {
2672 us_abortcommand(_("Use 'var set' to assign values to array entries, not 'var vector'"));
2673 return;
2674 }
2675 if (us_varqualsave == 0) (void)allocstring(&us_varqualsave, pp, us_tool->cluster); else
2676 (void)reallocstring(&us_varqualsave, pp, us_tool->cluster);
2677
2678 /* get the first source variable */
2679 if (us_getvar(par[2], &objaddr1, &objtype1, &qual1, &comvar, &aindex))
2680 {
2681 us_abortcommand(_("Incorrect variable name: %s"), par[2]);
2682 return;
2683 }
2684 if (*qual1 != 0)
2685 {
2686 var1 = getval(objaddr1, objtype1, -1, qual1);
2687 if (var1 == NOVARIABLE)
2688 {
2689 us_abortcommand(_("Cannot find first source: %s"), par[2]);
2690 return;
2691 }
2692 } else
2693 {
2694 fvar1.addr = objaddr1;
2695 fvar1.type = objtype1;
2696 var1 = &fvar1;
2697 }
2698 len1 = getlength(var1);
2699 if (len1 < 0) len1 = 1;
2700 if (us_expandaddrtypearray(&us_varlimit1, &us_varaddr1, &us_vartype1, len1)) return;
2701 if ((var1->type&VISARRAY) == 0)
2702 {
2703 us_varaddr1[0] = var1->addr;
2704 us_vartype1[0] = var1->type;
2705 count1 = 1;
2706 } else
2707 {
2708 if ((var1->type&VTYPE) == VGENERAL)
2709 {
2710 for(i=0; i<len1; i += 2)
2711 {
2712 us_varaddr1[i/2] = ((INTBIG *)var1->addr)[i];
2713 us_vartype1[i/2] = ((INTBIG *)var1->addr)[i+1];
2714 }
2715 count1 = len1 / 2;
2716 } else
2717 {
2718 for(i=0; i<len1; i++)
2719 {
2720 us_varaddr1[i] = ((INTBIG *)var1->addr)[i];
2721 us_vartype1[i] = var1->type;
2722 }
2723 count1 = len1;
2724 }
2725 }
2726
2727 /* get the operator */
2728 l = estrlen(pp = par[3]);
2729 count3 = 0;
2730 if (namesamen(pp, x_("pattern"), l) == 0 && l >= 1)
2731 {
2732 /* set 1 where the pattern matches */
2733 count3 = count1;
2734 if (us_expandaddrtypearray(&us_varlimit3, &us_varaddr3, &us_vartype3, count3)) return;
2735 var = &fvar;
2736 for(i=0; i<count1; i++)
2737 {
2738 fvar.type = us_vartype1[i] & VTYPE;
2739 fvar.addr = us_varaddr1[i];
2740 pp = describevariable(var, -1, -1);
2741 if (us_patternmatch(par[4], pp)) us_varaddr3[i] = 1; else
2742 us_varaddr3[i] = 0;
2743 us_vartype3[i] = VINTEGER;
2744 }
2745 } else if (namesamen(pp, x_("set"), l) == 0 && l >= 3)
2746 {
2747 /* copy the first operand to the destination */
2748 count3 = count1;
2749 if (us_expandaddrtypearray(&us_varlimit3, &us_varaddr3, &us_vartype3, count3)) return;
2750 for(i=0; i<count1; i++)
2751 {
2752 us_varaddr3[i] = us_varaddr1[i];
2753 us_vartype3[i] = us_vartype1[i];
2754 }
2755 } else if (namesamen(pp, x_("type"), l) == 0 && l >= 1)
2756 {
2757 /* set 1 where the type matches */
2758 count3 = count1;
2759 if (us_expandaddrtypearray(&us_varlimit3, &us_varaddr3, &us_vartype3, count3)) return;
2760 j = us_variabletypevalue(par[4]);
2761 for(i=0; i<count1; i++)
2762 {
2763 if ((us_vartype1[i]&VTYPE) == j) us_varaddr3[i] = 1; else us_varaddr3[i] = 0;
2764 us_vartype3[i] = VINTEGER;
2765 }
2766 } else
2767 {
2768 /* two-operand operation: get the second source variable */
2769 if (count < 4)
2770 {
2771 ttyputusage(x_("var vector DEST SOURCE1 OP SOURCE2"));
2772 return;
2773 }
2774
2775 if (us_getvar(par[4], &objaddr2, &objtype2, &qual2, &comvar, &aindex))
2776 {
2777 us_abortcommand(_("Incorrect variable name: %s"), par[4]);
2778 return;
2779 }
2780 if (*qual2 != 0)
2781 {
2782 var2 = getval(objaddr2, objtype2, -1, qual2);
2783 if (var2 == NOVARIABLE)
2784 {
2785 us_abortcommand(_("Cannot find second source: %s"), par[4]);
2786 return;
2787 }
2788 } else
2789 {
2790 fvar2.addr = objaddr2;
2791 fvar2.type = objtype2;
2792 var2 = &fvar2;
2793 }
2794 len2 = getlength(var2);
2795 if (len2 < 0) len2 = 1;
2796 if (us_expandaddrtypearray(&us_varlimit2, &us_varaddr2, &us_vartype2, len2)) return;
2797 if ((var2->type&VISARRAY) == 0)
2798 {
2799 us_varaddr2[0] = var2->addr;
2800 us_vartype2[0] = var2->type;
2801 count2 = 1;
2802 } else
2803 {
2804 if ((var2->type&VTYPE) == VGENERAL)
2805 {
2806 for(i=0; i<len2; i += 2)
2807 {
2808 us_varaddr2[i/2] = ((INTBIG *)var2->addr)[i];
2809 us_vartype2[i/2] = ((INTBIG *)var2->addr)[i+1];
2810 }
2811 count2 = len2 / 2;
2812 } else
2813 {
2814 for(i=0; i<len2; i++)
2815 {
2816 us_varaddr2[i] = ((INTBIG *)var2->addr)[i];
2817 us_vartype2[i] = var2->type;
2818 }
2819 count2 = len2;
2820 }
2821 }
2822
2823 if (namesamen(pp, x_("concat"), l) == 0 && l >= 1)
2824 {
2825 count3 = count1 + count2;
2826 if (us_expandaddrtypearray(&us_varlimit3, &us_varaddr3, &us_vartype3, count3)) return;
2827 for(i=0; i<count1; i++)
2828 {
2829 us_varaddr3[i] = us_varaddr1[i];
2830 us_vartype3[i] = us_vartype1[i];
2831 }
2832 for(i=0; i<count2; i++)
2833 {
2834 us_varaddr3[i+count1] = us_varaddr2[i];
2835 us_vartype3[i+count1] = us_vartype2[i];
2836 }
2837 } else if (namesamen(pp, x_("select"), l) == 0 && l >= 3)
2838 {
2839 count3 = 0;
2840 if (count1 < count2) count2 = count1;
2841 for(i=0; i<count2; i++)
2842 if ((us_vartype2[i]&VTYPE) == VINTEGER && us_varaddr2[i] != 0) count3++;
2843 if (us_expandaddrtypearray(&us_varlimit3, &us_varaddr3, &us_vartype3, count3)) return;
2844 count3 = 0;
2845 for(i=0; i<count2; i++)
2846 if ((us_vartype2[i]&VTYPE) == VINTEGER && us_varaddr2[i] != 0)
2847 {
2848 us_varaddr3[count3] = us_varaddr1[i];
2849 us_vartype3[count3] = us_vartype1[i];
2850 count3++;
2851 }
2852 }
2853 }
2854
2855 /* assign the result to the destination */
2856 if (count3 == 0)
2857 {
2858 /* null array */
2859 us_varaddr3[0] = -1;
2860 setval(objaddr, objtype, us_varqualsave, (INTBIG)us_varaddr3, VUNKNOWN|VISARRAY|VDONTSAVE);
2861 return;
2862 }
2863 if (count3 == 1)
2864 {
2865 setval(objaddr, objtype, us_varqualsave, us_varaddr3[0], (us_vartype3[0]&VTYPE)|VDONTSAVE);
2866 } else
2867 {
2868 for(i=1; i<count3; i++)
2869 if ((us_vartype3[i-1]&VTYPE) != (us_vartype3[i]&VTYPE)) break;
2870 if (count3 > 1 && i < count3)
2871 {
2872 /* general array needed because not all entries are the same type */
2873 newarray = (INTBIG *)emalloc(count3*2 * SIZEOFINTBIG, el_tempcluster);
2874 if (newarray == 0) return;
2875 for(i=0; i<count3; i++)
2876 {
2877 newarray[i*2] = us_varaddr3[i];
2878 newarray[i*2+1] = us_vartype3[i];
2879 }
2880 setval(objaddr, objtype, us_varqualsave, (INTBIG)newarray,
2881 VGENERAL|VISARRAY|((count3*2)<<VLENGTHSH)|VDONTSAVE);
2882 efree((CHAR *)newarray);
2883 } else
2884 {
2885 /* uniform array */
2886 setval(objaddr, objtype, us_varqualsave, (INTBIG)us_varaddr3,
2887 (us_vartype3[0]&VTYPE)|VISARRAY|(count3<<VLENGTHSH)|VDONTSAVE);
2888 }
2889 }
2890 return;
2891 }
2892
2893 /* handle the setting and modifying options */
2894 function = 0;
2895 if (namesamen(pp, x_("set"), l) == 0 && l >= 1) function = 's';
2896 if (namesamen(pp, x_("+"), l) == 0 && l >= 1) function = '+';
2897 if (namesamen(pp, x_("-"), l) == 0 && l >= 1) function = '-';
2898 if (namesamen(pp, x_("*"), l) == 0 && l >= 1) function = '*';
2899 if (namesamen(pp, x_("/"), l) == 0 && l >= 1) function = '/';
2900 if (namesamen(pp, x_("mod"), l) == 0 && l >= 1) function = 'm';
2901 if (namesamen(pp, x_("and"), l) == 0 && l >= 1) function = 'a';
2902 if (namesamen(pp, x_("or"), l) == 0 && l >= 1) function = 'o';
2903 if (namesamen(pp, x_("|"), l) == 0 && l >= 1) function = '|';
2904 if (function == 0)
2905 {
2906 ttyputusage(x_("var [examine|set|delete|OP] VARIABLE MOD"));
2907 ttyputmsg(x_("OP: + - * / mod | or and"));
2908 return;
2909 }
2910
2911 /* make sure there is a variable name to set/modify */
2912 if (count <= 1)
2913 {
2914 count = ttygetparam(x_("Variable: "), &us_varvsp, MAXPARS-1, &par[1]) + 1;
2915 if (count == 1)
2916 {
2917 us_abortedmsg();
2918 return;
2919 }
2920 }
2921 if (us_getvar(par[1], &objaddr, &objtype, &qual, &comvar, &aindex))
2922 {
2923 us_abortcommand(_("Incorrect variable name: %s"), par[1]);
2924 return;
2925 }
2926 estrcpy(qualname, qual);
2927 var = getval(objaddr, objtype, -1, qualname);
2928 if (var != NOVARIABLE)
2929 {
2930 newtype = var->type;
2931 TDCOPY(newdescript, var->textdescript);
2932
2933 /* do some pre-computation on existing variables */
2934 if ((newtype&VCANTSET) != 0)
2935 {
2936 us_abortcommand(_("%s is not a settable variable"), par[1]);
2937 return;
2938 }
2939 oldlen = getlength(var);
2940 if (aindex >= 0 && (newtype&VISARRAY) == 0)
2941 {
2942 us_abortcommand(_("%s is not an array: cannot index it"), par[1]);
2943 return;
2944 }
2945 if (aindex < 0 && (newtype&VISARRAY) != 0)
2946 {
2947 ttyputmsg(_("Warning: %s was an array: now scalar"), par[1]);
2948 newtype &= ~VISARRAY;
2949 }
2950 }
2951
2952 /* make sure there is a value to set/adjust */
2953 if (count <= 2)
2954 {
2955 count = ttygetparam(M_("Value: "), &us_varvalp, MAXPARS-2, &par[2]) + 2;
2956 if (count == 2)
2957 {
2958 us_abortedmsg();
2959 return;
2960 }
2961 }
2962
2963 /* make sure modifications are done on the right types */
2964 if (function != 's')
2965 {
2966 /* operation is "+", "-", "*", "/", "m", "a", "o", "|" */
2967 if (var == NOVARIABLE)
2968 {
2969 us_abortcommand(_("Variable does not exist: cannot be modified"));
2970 return;
2971 }
2972 if (aindex < 0 && (newtype&VISARRAY) != 0)
2973 {
2974 us_abortcommand(_("%s is an array: must index it"), par[1]);
2975 return;
2976 }
2977 if (aindex < 0) oldaddr = var->addr; else
2978 {
2979 if ((newtype&VISARRAY) == 0)
2980 {
2981 us_abortcommand(_("%s is not an array: cannot index it"), par[1]);
2982 return;
2983 }
2984 if (aindex >= oldlen)
2985 {
2986 us_abortcommand(_("%s has only %ld entries, cannot use %ld"), par[1], oldlen, aindex);
2987 return;
2988 }
2989 if ((newtype&VTYPE) == VDOUBLE)
2990 oldaddr = (INTBIG)(((double *)var->addr)[aindex]); else
2991 oldaddr = ((INTBIG *)var->addr)[aindex];
2992 }
2993 if (function != '|')
2994 {
2995 /* operation is "+", "-", "*", "/", "m", "a", "o" */
2996 if ((newtype&VTYPE) != VINTEGER && (newtype&VTYPE) != VFLOAT &&
2997 (newtype&VTYPE) != VDOUBLE && (newtype&VTYPE) != VFRACT &&
2998 (newtype&VTYPE) != VSHORT)
2999 {
3000 us_abortcommand(_("Can only do arithmetic on numbers"));
3001 return;
3002 }
3003
3004 if ((newtype&VTYPE) == VFLOAT || (newtype&VTYPE) == VDOUBLE)
3005 {
3006 oldfloat = castfloat(oldaddr);
3007 } else if ((newtype&VTYPE) == VINTEGER)
3008 {
3009 /* might be able to re-cast integers as floats */
3010 for(pp = par[2]; *pp != 0; pp++) if (*pp == '.')
3011 {
3012 if ((newtype&VISARRAY) != 0)
3013 {
3014 us_abortcommand(_("Cannot change array to floating point"));
3015 return;
3016 }
3017 newtype = (newtype & ~VTYPE) | VFLOAT;
3018 oldfloat = (float)oldaddr;
3019 break;
3020 }
3021 }
3022 if ((newtype&VTYPE) != VINTEGER && (function == 'o' || function == 'a' || function == 'm'))
3023 {
3024 us_abortcommand(_("Must do bit or modulo arithmetic on integers"));
3025 return;
3026 }
3027 } else if ((newtype&VTYPE) != VSTRING)
3028 {
3029 us_abortcommand(_("Can only do concatentation on strings"));
3030 return;
3031 }
3032 } else
3033 {
3034 /* setting a nonexistent variable: determine the type */
3035 if (var == NOVARIABLE || (var->type&VISARRAY) == 0)
3036 {
3037 /* establish the type of this parameter if it is being set */
3038 getsimpletype(par[2], &newtype, &newaddr, 0);
3039 if (objtype == VARCINST) geom = ((ARCINST *)objaddr)->geom; else
3040 if (objtype == VNODEINST) geom = ((NODEINST *)objaddr)->geom; else
3041 geom = NOGEOM;
3042 TDCLEAR(newdescript);
3043 defaulttextdescript(newdescript, geom);
3044 }
3045 }
3046
3047 /* get options on how to change the variable */
3048 disppart = 0;
3049 if (count >= 4)
3050 {
3051 l = estrlen(pp = par[3]);
3052 if (namesamen(pp, x_("display"), l) == 0 && l >= 1)
3053 {
3054 newtype |= VDISPLAY;
3055 disppart = VTDISPLAYVALUE;
3056 us_figurevariableplace(newdescript, count-4, &par[4]);
3057 l = 0;
3058 } else if (namesamen(pp, x_("na-va-display"), l) == 0 && l >= 1)
3059 {
3060 newtype |= VDISPLAY;
3061 disppart = VTDISPLAYNAMEVALUE;
3062 us_figurevariableplace(newdescript, count-4, &par[4]);
3063 l = 0;
3064 } else if (namesamen(pp, x_("in-na-va-display"), l) == 0 && l >= 3)
3065 {
3066 newtype |= VDISPLAY;
3067 disppart = VTDISPLAYNAMEVALINH;
3068 if ((objtype&VTYPE) != VNODEPROTO)
3069 {
3070 ttyputmsg(_("%s is allowed for cells only, changing to na-va-display"), pp);
3071 disppart = VTDISPLAYNAMEVALUE;
3072 }
3073 us_figurevariableplace(newdescript, count-4, &par[4]);
3074 l = 0;
3075 } else if (namesamen(pp, x_("inall-na-va-display"), l) == 0 && l >= 3)
3076 {
3077 newtype |= VDISPLAY;
3078 disppart = VTDISPLAYNAMEVALINHALL;
3079 if ((objtype&VTYPE) != VNODEPROTO)
3080 {
3081 ttyputmsg(_("%s is allowed for cells only, changing to na-va-display"), pp);
3082 disppart = VTDISPLAYNAMEVALUE;
3083 }
3084 us_figurevariableplace(newdescript, count-4, &par[4]);
3085 l = 0;
3086 } else if (namesamen(pp, x_("lisp"), l) == 0 && l >= 1)
3087 {
3088 if (aindex < 0 || var == NOVARIABLE) newtype = (newtype & ~(VCODE1|VCODE2)) | VLISP;
3089 l = 0;
3090 } else if (namesamen(pp, x_("tcl"), l) == 0 && l >= 1)
3091 {
3092 if (aindex < 0 || var == NOVARIABLE) newtype = (newtype & ~(VCODE1|VCODE2)) | VTCL;
3093 l = 0;
3094 } else if (namesamen(pp, x_("java"), l) == 0 && l >= 1)
3095 {
3096 if (aindex < 0 || var == NOVARIABLE) newtype = (newtype & ~(VCODE1|VCODE2)) | VJAVA;
3097 l = 0;
3098 } else if (namesamen(pp, x_("temporary"), l) == 0 && l >= 1)
3099 {
3100 if (aindex < 0 || var == NOVARIABLE) newtype |= VDONTSAVE;
3101 l = 0;
3102 } else if (namesamen(pp, x_("fractional"), l) == 0 && l >= 1)
3103 {
3104 if (aindex < 0 || var == NOVARIABLE) newtype = (newtype & ~VTYPE) | VFRACT;
3105 l = 0;
3106 } else if (namesamen(pp, x_("float"), l) == 0 && l >= 1)
3107 {
3108 if (aindex < 0 || var == NOVARIABLE) newtype = (newtype & ~VTYPE) | VFLOAT;
3109 l = 0;
3110 } else if (namesamen(pp, x_("cannot-change"), l) == 0 && l >= 1)
3111 {
3112 if (aindex < 0 || var == NOVARIABLE) newtype |= VCANTSET;
3113 l = 0;
3114 }
3115 if (l > 0)
3116 {
3117 ttyputusage(x_("var set VARIABLE [OPTION]"));
3118 ttyputusage(x_("OPTION: lisp|tcl|java|display|temporary|fractional|float|cannot-change"));
3119 return;
3120 }
3121 }
3122
3123 /* do the modification */
3124 switch (function)
3125 {
3126 case '+':
3127 if ((newtype&VTYPE) == VINTEGER) newval = oldaddr + myatoi(par[2]); else
3128 if ((newtype&VTYPE) == VFRACT) newval = oldaddr + atofr(par[2]); else
3129 newval = castint(oldfloat + (float)eatof(par[2]));
3130 break;
3131 case '-':
3132 if ((newtype&VTYPE) == VINTEGER) newval = oldaddr - myatoi(par[2]); else
3133 if ((newtype&VTYPE) == VFRACT) newval = oldaddr - atofr(par[2]); else
3134 newval = castint(oldfloat - (float)eatof(par[2]));
3135 break;
3136 case '*':
3137 if ((newtype&VTYPE) == VINTEGER) newval = oldaddr * myatoi(par[2]); else
3138 if ((newtype&VTYPE) == VFRACT) newval = muldiv(oldaddr, atofr(par[2]), WHOLE); else
3139 newval = castint(oldfloat * (float)eatof(par[2]));
3140 break;
3141 case '/':
3142 if ((newtype&VTYPE) == VINTEGER)
3143 {
3144 i = myatoi(par[2]);
3145 if (i != 0) newval = oldaddr / i; else
3146 {
3147 ttyputerr(_("Attempt to divide by zero"));
3148 newval = 0;
3149 }
3150 } else if ((newtype&VTYPE) == VFRACT)
3151 {
3152 i = atofr(par[2]);
3153 if (i != 0) newval = muldiv(oldaddr, WHOLE, i); else
3154 {
3155 ttyputerr(_("Attempt to divide by zero"));
3156 newval = 0;
3157 }
3158 } else
3159 {
3160 oldden = (float)eatof(par[2]);
3161 if (oldden != 0.0)
3162 newval = castint((float)(oldfloat / oldden)); else
3163 {
3164 ttyputerr(_("Attempt to divide by zero"));
3165 newval = castint(0.0);
3166 }
3167 }
3168 break;
3169 case 'm':
3170 i = myatoi(par[2]);
3171 if (i != 0) newval = oldaddr % i; else
3172 {
3173 ttyputerr(_("Attempt to modulo by zero"));
3174 newval = 0;
3175 }
3176 break;
3177 case 'a':
3178 newval = oldaddr & myatoi(par[2]); break;
3179 case 'o':
3180 newval = oldaddr | myatoi(par[2]); break;
3181 case '|':
3182 infstr = initinfstr();
3183 addstringtoinfstr(infstr, (CHAR *)oldaddr);
3184 addstringtoinfstr(infstr, par[2]);
3185 newval = (INTBIG)returninfstr(infstr);
3186 break;
3187 case 's':
3188 if ((newtype&VTYPE) == VINTEGER || (newtype&VTYPE) == VSHORT || (newtype&VTYPE) == VBOOLEAN)
3189 newval = myatoi(par[2]); else
3190 if ((newtype&VTYPE) == VFRACT) newval = atofr(par[2]); else
3191 if ((newtype&VTYPE) == VFLOAT || (newtype&VTYPE) == VDOUBLE)
3192 newval = castint((float)eatof(par[2])); else
3193 newval = (INTBIG)par[2];
3194 break;
3195 }
3196
3197 /* ensure that command interpreter variables are always temporary */
3198 if (comvar) newtype |= VDONTSAVE;
3199
3200 /* signal start of change to nodes and arcs */
3201 if (objtype == VNODEINST || objtype == VARCINST)
3202 {
3203 us_pushhighlight();
3204 us_clearhighlightcount();
3205 startobjectchange(objaddr, objtype);
3206 } else if (objtype == VNODEPROTO)
3207 {
3208 if (var != NOVARIABLE) us_undrawcellvariable(var, (NODEPROTO *)objaddr);
3209 }
3210
3211 /* change the variable */
3212 if (aindex < 0) res = setval(objaddr, objtype, qualname, newval, newtype); else
3213 {
3214 if (var == NOVARIABLE)
3215 {
3216 /* creating array variable */
3217 newarray = emalloc(((aindex+1) * SIZEOFINTBIG), el_tempcluster);
3218 if (newarray == 0)
3219 {
3220 ttyputnomemory();
3221 return;
3222 }
3223 for(j=0; j<=aindex; j++) newarray[j] = newval;
3224 newtype |= VISARRAY | ((aindex+1)<<VLENGTHSH);
3225 res = setval(objaddr, objtype, qualname, (INTBIG)newarray, newtype);
3226 efree((CHAR *)newarray);
3227 } else if (oldlen <= aindex)
3228 {
3229 /* extend existing array variable */
3230 newarray = emalloc(((aindex+1) * SIZEOFINTBIG), el_tempcluster);
3231 if (newarray == 0)
3232 {
3233 ttyputnomemory();
3234 return;
3235 }
3236 if ((newtype&VTYPE) == VSTRING)
3237 {
3238 for(j=0; j<oldlen; j++)
3239 (void)allocstring((CHAR **)&newarray[j],
3240 (CHAR *)((INTBIG *)var->addr)[j], el_tempcluster);
3241 for(j=oldlen; j<aindex; j++) newarray[j] = (INTBIG)nullstr;
3242 } else
3243 {
3244 for(j=0; j<oldlen; j++) newarray[j] = ((INTBIG *)var->addr)[j];
3245 for(j=oldlen; j<aindex; j++) newarray[j] = 0;
3246 }
3247 newarray[aindex] = newval;
3248 newtype = (newtype & ~VLENGTH) | ((aindex+1)<<VLENGTHSH);
3249 res = setval(objaddr, objtype, qualname, (INTBIG)newarray, newtype);
3250 if ((newtype&VTYPE) == VSTRING)
3251 for(j=0; j<oldlen; j++) efree((CHAR *)newarray[j]);
3252 efree((CHAR *)newarray);
3253 } else
3254 {
3255 if (setind(objaddr, objtype, qualname, aindex, newval))
3256 res = NOVARIABLE; else res = (VARIABLE *)1;
3257 }
3258 }
3259 if (res == NOVARIABLE)
3260 {
3261 ttyputnomemory();
3262 return;
3263 }
3264 if (res != (VARIABLE *)1)
3265 {
3266 TDCOPY(res->textdescript, newdescript);
3267 TDSETDISPPART(res->textdescript, disppart);
3268 }
3269
3270 /* signal end of change to nodes and arcs */
3271 if (objtype == VNODEINST || objtype == VARCINST)
3272 {
3273 endobjectchange(objaddr, objtype);
3274 us_pophighlight(FALSE);
3275 } else if (objtype == VNODEPROTO)
3276 {
3277 if (res != NOVARIABLE) us_drawcellvariable(res, (NODEPROTO *)objaddr);
3278 }
3279 }
3280
us_view(INTBIG count,CHAR * par[])3281 void us_view(INTBIG count, CHAR *par[])
3282 {
3283 REGISTER CHAR *pp, *abbrev, *pt;
3284 REGISTER INTBIG i, l;
3285 REGISTER BOOLEAN found;
3286 REGISTER LIBRARY *lib;
3287 REGISTER NODEPROTO *np;
3288 REGISTER VARIABLE *var;
3289 REGISTER VIEW *nv;
3290 REGISTER WINDOWPART *w;
3291 REGISTER EDITOR *ed;
3292 REGISTER void *infstr;
3293 CHAR line[10];
3294
3295 if (count == 0)
3296 {
3297 ttyputusage(x_("view new | delete | change | frame"));
3298 return;
3299 }
3300
3301 l = estrlen(pp = par[0]);
3302
3303 if (namesamen(pp, x_("new"), l) == 0 && l >= 1)
3304 {
3305 if (count < 2)
3306 {
3307 ttyputusage(x_("view new NEWVIEWNAME [ABBREVIATION [TYPE]]"));
3308 return;
3309 }
3310
3311 pp = par[1];
3312 nv = getview(pp);
3313
3314 /* special case for multi-page schematics */
3315 if (namesamen(pp, x_("schematic-page-"), 15) == 0)
3316 {
3317 /* check validity of abbreviation for schematic page view */
3318 pt = &pp[15];
3319 if (!isanumber(&pp[15]))
3320 {
3321 us_abortcommand(_("Page number must follow 'schematics-page-'"));
3322 return;
3323 }
3324 if (nv != NOVIEW)
3325 {
3326 ttyputverbose(M_("Schematic page %s already exists"), &pp[15]);
3327 return;
3328 }
3329 }
3330
3331 /* make sure name is unique */
3332 if (nv != NOVIEW)
3333 {
3334 us_abortcommand(_("Already a view called '%s'"), nv->viewname);
3335 return;
3336 }
3337
3338 if (count >= 3)
3339 {
3340 /* get the short view name */
3341 abbrev = par[2];
3342 if (namesamen(pp, x_("schematic-page-"), 15) == 0)
3343 {
3344 if ((abbrev[0] != 'p' && abbrev[0] != 'P') || estrcmp(&pp[15], &abbrev[1]) != 0)
3345 {
3346 us_abortcommand(_("Incorrect abbreviation for schematic page"));
3347 count = 2;
3348 }
3349 } else
3350 {
3351 /* make sure the abbreviation is not confused with schematic one */
3352 if ((abbrev[0] == 'p' || abbrev[0] == 'P') && isanumber(&abbrev[1]))
3353 {
3354 us_abortcommand(_("Can only use 'Pnumber' abbreviation for multipage schematic views"));
3355 return;
3356 }
3357 }
3358 }
3359 if (count < 3)
3360 {
3361 /* generate a short view name */
3362 if (namesamen(pp, x_("schematic-page-"), 15) == 0)
3363 {
3364 /* special case for schematics pages */
3365 abbrev = (CHAR *)emalloc((estrlen(&pp[15])+2) * SIZEOFCHAR, el_tempcluster);
3366 abbrev[0] = 'p';
3367 (void)estrcpy(&abbrev[1], &pp[15]);
3368 } else
3369 {
3370 /* simply find initial unique letters */
3371 for(i=0; pp[i] != 0; i++)
3372 {
3373 for(nv = el_views; nv != NOVIEW; nv = nv->nextview)
3374 if (namesamen(nv->sviewname, pp, i+1) == 0) break;
3375 if (nv == NOVIEW) break;
3376 }
3377 abbrev = (CHAR *)emalloc((i+2) * SIZEOFCHAR, el_tempcluster);
3378 (void)estrncpy(abbrev, pp, i+1);
3379 abbrev[i+1] = 0;
3380 }
3381 ttyputverbose(M_("Using '%s' as abbreviation"), abbrev);
3382 }
3383
3384 /* see if the view already exists */
3385 nv = getview(pp);
3386 if (nv != NOVIEW)
3387 {
3388 if (namesame(nv->sviewname, abbrev) != 0)
3389 ttyputmsg(_("View %s already exists with abbreviation %s"), nv->viewname, nv->sviewname);
3390 return;
3391 }
3392
3393 /* create the view */
3394 nv = newview(pp, abbrev);
3395 if (nv == NOVIEW)
3396 {
3397 us_abortcommand(_("Could not create the new view"));
3398 return;
3399 }
3400
3401 /* get type of view */
3402 if (count >= 4)
3403 {
3404 pp = par[3];
3405 if (namesamen(pp, x_("text"), estrlen(pp)) == 0) nv->viewstate |= TEXTVIEW;
3406 }
3407 ttyputverbose(M_("View '%s' created"), pp);
3408
3409 /* clean up */
3410 if (count < 3) efree(abbrev);
3411 return;
3412 }
3413
3414 if (namesamen(pp, x_("delete"), l) == 0 && l >= 1)
3415 {
3416 if (count < 2)
3417 {
3418 ttyputusage(x_("view delete VIEWNAME"));
3419 return;
3420 }
3421
3422 /* make sure name exists */
3423 nv = getview(par[1]);
3424 if (nv == NOVIEW)
3425 {
3426 us_abortcommand(_("Unknown view: %s"), par[1]);
3427 return;
3428 }
3429
3430 if ((nv->viewstate&PERMANENTVIEW) != 0)
3431 {
3432 us_abortcommand(_("Cannot delete important views like %s"), nv->viewname);
3433 return;
3434 }
3435
3436 /* make sure no cells in any library have this view */
3437 found = FALSE;
3438 for(lib = el_curlib; lib != NOLIBRARY; lib = lib->nextlibrary)
3439 for(np = lib->firstnodeproto; np != NONODEPROTO; np = np->nextnodeproto)
3440 if (np->cellview == nv)
3441 {
3442 if (!found)
3443 {
3444 us_abortcommand(_("Must first remove these cells in view %s"), nv->viewname);
3445 found = TRUE;
3446 }
3447 ttyputmsg(x_(" %s"), describenodeproto(np));
3448 }
3449 if (found) return;
3450
3451 /* delete the view */
3452 if (killview(nv)) ttyputerr(_("Problem deleting view"));
3453 else ttyputverbose(M_("View '%s' deleted"), par[1]);
3454 return;
3455 }
3456
3457 if (namesamen(pp, x_("change"), l) == 0 && l >= 1)
3458 {
3459 if (count != 3)
3460 {
3461 ttyputusage(x_("view change CELL VIEW"));
3462 return;
3463 }
3464
3465 /* get cell */
3466 np = getnodeproto(par[1]);
3467 if (np == NONODEPROTO || np->primindex != 0)
3468 {
3469 us_abortcommand(_("'%s' is not a cell"), par[1]);
3470 return;
3471 }
3472
3473 /* disallow change if lock is on */
3474 if (us_cantedit(np, NONODEINST, TRUE)) return;
3475
3476 /* get view */
3477 nv = getview(par[2]);
3478 if (nv == NOVIEW)
3479 {
3480 us_abortcommand(_("Unknown view type: %s"), par[2]);
3481 return;
3482 }
3483
3484 if (!changecellview(np, nv))
3485 {
3486 ttyputverbose(M_("Cell %s is now %s"), par[1], describenodeproto(np));
3487
3488 /* set current nodeproto to itself to redisplay its name */
3489 if (np == getcurcell())
3490 (void)setval((INTBIG)el_curlib, VLIBRARY, x_("curnodeproto"), (INTBIG)np, VNODEPROTO);
3491
3492 /* update status display if necessary */
3493 for(w = el_topwindowpart; w != NOWINDOWPART; w = w->nextwindowpart)
3494 {
3495 if (w->curnodeproto != np) continue;
3496
3497 /* if this window is textual, change the header string */
3498 if ((w->state&WINDOWTYPE) == TEXTWINDOW)
3499 {
3500 ed = w->editor;
3501 if (ed != NOEDITOR)
3502 {
3503 (void)reallocstring(&ed->header, describenodeproto(np), us_tool->cluster);
3504 (*w->redisphandler)(w);
3505 }
3506 }
3507 us_setcellname(w);
3508 }
3509 if (us_curnodeproto != NONODEPROTO && us_curnodeproto == np)
3510 {
3511 us_curnodeproto = NONODEPROTO;
3512 us_setnodeproto(np);
3513 }
3514 }
3515 return;
3516 }
3517
3518 if (namesamen(pp, x_("frame"), l) == 0 && l >= 1)
3519 {
3520 /* get cell */
3521 np = us_needcell();
3522 if (np == NONODEPROTO) return;
3523
3524 if (count == 1)
3525 {
3526 /* report the frame in use here */
3527 var = getvalkey((INTBIG)np, VNODEPROTO, VSTRING, el_schematic_page_size_key);
3528 if (var == NOVARIABLE)
3529 {
3530 ttyputmsg(M_("This cell has no frame"));
3531 return;
3532 }
3533 pt = (CHAR *)var->addr;
3534 infstr = initinfstr();
3535 switch (*pt)
3536 {
3537 case 'x': case 'X': addtoinfstr(infstr, 'X'); break;
3538 case 'a': case 'A': addtoinfstr(infstr, 'A'); break;
3539 case 'b': case 'B': addtoinfstr(infstr, 'B'); break;
3540 case 'c': case 'C': addtoinfstr(infstr, 'C'); break;
3541 case 'd': case 'D': addtoinfstr(infstr, 'D'); break;
3542 case 'e': case 'E': addtoinfstr(infstr, 'E'); break;
3543 }
3544 pt++;
3545 while (*pt != 0)
3546 {
3547 if (*pt == 'v' || *pt == 'V') addstringtoinfstr(infstr, M_(", vertical"));
3548 if (*pt == 'n' || *pt == 'N') addstringtoinfstr(infstr, M_(", no title box"));
3549 pt++;
3550 }
3551 ttyputmsg(M_("This cell has a frame of size %s"), returninfstr(infstr));
3552 return;
3553 }
3554
3555 /* set the frame size */
3556 l = estrlen(pp = par[1]);
3557 if (namesamen(pp, x_("none"), l) == 0 && l >= 1)
3558 {
3559 if (getvalkey((INTBIG)np, VNODEPROTO, VSTRING, el_schematic_page_size_key) != NOVARIABLE)
3560 (void)delvalkey((INTBIG)np, VNODEPROTO, el_schematic_page_size_key);
3561 return;
3562 }
3563 if (namesamen(pp, x_("title-only"), l) == 0 && l >= 1)
3564 {
3565 estrcpy(line, x_("x"));
3566 (void)setvalkey((INTBIG)np, VNODEPROTO, el_schematic_page_size_key, (INTBIG)line, VSTRING);
3567 return;
3568 }
3569 line[0] = 0;
3570 if (namesamen(pp, x_("A"), l) == 0 && l >= 1) estrcat(line, x_("a")); else
3571 if (namesamen(pp, x_("B"), l) == 0 && l >= 1) estrcat(line, x_("b")); else
3572 if (namesamen(pp, x_("C"), l) == 0 && l >= 1) estrcat(line, x_("c")); else
3573 if (namesamen(pp, x_("D"), l) == 0 && l >= 1) estrcat(line, x_("d")); else
3574 if (namesamen(pp, x_("E"), l) == 0 && l >= 1) estrcat(line, x_("e")); else
3575 if (namesamen(pp, x_("Half-A"), l) == 0 && l >= 1) estrcat(line, x_("h")); else
3576 {
3577 ttyputbadusage(x_("view frame"));
3578 return;
3579 }
3580 for(i=2; i<count; i++)
3581 {
3582 if (namesamen(par[i], x_("vertical"), estrlen(par[i])) == 0)
3583 estrcat(line, x_("v"));
3584 if (namesamen(par[i], x_("no-title"), estrlen(par[i])) == 0)
3585 estrcat(line, x_("n"));
3586 }
3587 (void)setvalkey((INTBIG)np, VNODEPROTO, el_schematic_page_size_key, (INTBIG)line, VSTRING);
3588 return;
3589 }
3590 ttyputbadusage(x_("view"));
3591 }
3592
us_visiblelayers(INTBIG count,CHAR * par[])3593 void us_visiblelayers(INTBIG count, CHAR *par[])
3594 {
3595 CHAR line[100];
3596 REGISTER INTBIG i, j, val;
3597 REGISTER BOOLEAN defstate, noprint, addstate;
3598 REGISTER INTBIG fun;
3599 REGISTER CHAR *ch, *la;
3600
3601 /* if the user wants every layer, do it */
3602 if (us_needwindow()) return;
3603 noprint = FALSE;
3604 if (count > 0)
3605 {
3606 if (count > 1 && namesame(par[1], x_("no-list")) == 0) noprint = TRUE;
3607 if (estrcmp(par[0], x_("*")) == 0)
3608 {
3609 /* save highlighting */
3610 us_pushhighlight();
3611 us_clearhighlightcount();
3612 startobjectchange((INTBIG)el_curwindowpart, VWINDOWPART);
3613
3614 for(i=0; i<el_curtech->layercount; i++)
3615 {
3616 if ((el_curtech->layers[i]->colstyle&INVISIBLE) == 0) continue;
3617 (void)setval((INTBIG)el_curtech->layers[i], VGRAPHICS, x_("style"),
3618 el_curtech->layers[i]->colstyle & ~INVISIBLE, VSHORT);
3619 }
3620
3621 /* restore highlighting and redisplay */
3622 endobjectchange((INTBIG)el_curwindowpart, VWINDOWPART);
3623 us_pophighlight(FALSE);
3624 } else
3625 {
3626 /* handle specific request for visible layers */
3627 defstate = TRUE;
3628 addstate = FALSE;
3629 if (par[0][0] == '*' && par[0][1] == '-' && par[0][2] != 0)
3630 {
3631 par[0] += 2;
3632 defstate = FALSE;
3633 } else if (par[0][0] == '-' && par[0][1] != 0)
3634 {
3635 par[0] += 1;
3636 defstate = FALSE;
3637 addstate = TRUE;
3638 } else if (par[0][0] == '+' && par[0][1] != 0)
3639 {
3640 par[0] += 1;
3641 addstate = TRUE;
3642 }
3643
3644 /* collect all of the layer letters */
3645 (void)estrcpy(line, x_(""));
3646 for(i=0; i<el_curtech->layercount; i++)
3647 (void)estrcat(line, us_layerletters(el_curtech, i));
3648
3649 /* now see if the user-requested layers are valid names */
3650 for(ch = par[0]; *ch != 0 && *ch != '('; ch++)
3651 {
3652 for(i=0; line[i] != 0; i++) if (*ch == line[i]) break;
3653 if (line[i] == 0)
3654 {
3655 us_abortcommand(_("No such layer: %c"), *ch);
3656 return;
3657 }
3658 }
3659
3660 /* initially set all layers to default if not adding */
3661 if (!addstate)
3662 {
3663 for(i=0; i<el_curtech->layercount; i++)
3664 {
3665 if (!defstate)
3666 el_curtech->layers[i]->colstyle &= ~INVTEMP; else
3667 el_curtech->layers[i]->colstyle |= INVTEMP;
3668 }
3669 }
3670
3671 /* set the changes */
3672 for(i=0; i<el_curtech->layercount; i++)
3673 {
3674 la = us_layerletters(el_curtech, i);
3675 for(j=0; la[j] != 0; j++)
3676 for(ch = par[0]; *ch != 0 && *ch != '('; ch++)
3677 if (*ch == la[j])
3678 {
3679 if (!defstate) el_curtech->layers[i]->colstyle |= INVTEMP; else
3680 el_curtech->layers[i]->colstyle &= ~INVTEMP;
3681 }
3682 }
3683
3684 /* save highlighting */
3685 us_pushhighlight();
3686 us_clearhighlightcount();
3687 startobjectchange((INTBIG)el_curwindowpart, VWINDOWPART);
3688
3689 /* make the changes */
3690 for(i=0; i<el_curtech->layercount; i++)
3691 {
3692 val = el_curtech->layers[i]->colstyle;
3693 if ((val&(INVTEMP|INVISIBLE)) == INVTEMP)
3694 {
3695 (void)setval((INTBIG)el_curtech->layers[i], VGRAPHICS,
3696 x_("style"), val | INVISIBLE, VSHORT);
3697 continue;
3698 }
3699 if ((val&(INVTEMP|INVISIBLE)) == INVISIBLE)
3700 {
3701 (void)setval((INTBIG)el_curtech->layers[i], VGRAPHICS,
3702 x_("style"), val & ~INVISIBLE, VSHORT);
3703 continue;
3704 }
3705 }
3706
3707 /* restore highlighting */
3708 endobjectchange((INTBIG)el_curwindowpart, VWINDOWPART);
3709 us_pophighlight(FALSE);
3710 }
3711 }
3712
3713 /* tell which layers are visible */
3714 if (noprint) return;
3715 j = 0;
3716 for(i=0; i<el_curtech->layercount; i++)
3717 {
3718 if ((el_curtech->layers[i]->colstyle&INVISIBLE) != 0) continue;
3719 if (j++ == 0) ttyputmsg(M_("Visible layers:"));
3720 ch = us_layerletters(el_curtech, i);
3721 fun = layerfunction(el_curtech, i);
3722 if (*ch == 0) ttyputmsg(M_("Layer %s"), layername(el_curtech, i)); else
3723 ttyputmsg(M_("Layer %s, letters %s%s"), layername(el_curtech, i), us_layerletters(el_curtech, i),
3724 (fun&(LFTRANS1|LFTRANS2|LFTRANS3|LFTRANS4|LFTRANS5)) != 0 ? M_(" (transparent)") : x_(""));
3725 }
3726 if (j == 0) ttyputmsg(M_("No visible layers"));
3727 }
3728
us_wpopcharhandler(INTSML chr,INTBIG special)3729 static BOOLEAN us_wpopcharhandler(INTSML chr, INTBIG special)
3730 {
3731 return((*us_wpop->charhandler)(us_wpop, chr, special));
3732 }
3733
us_wpopbuttonhandler(INTBIG x,INTBIG y,INTBIG but)3734 static BOOLEAN us_wpopbuttonhandler(INTBIG x, INTBIG y, INTBIG but)
3735 {
3736 if (us_wpop->buttonhandler != 0) (*us_wpop->buttonhandler)(us_wpop, but, x, y);
3737 return(FALSE);
3738 }
3739