6 * PCB, interactive printed circuit board design
7 * Copyright (C) 1994,1995,1996, 2004 Thomas Nau
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 * Contact addresses for paper mail and Email:
24 * Thomas Nau, Schlehenweg 15, 88471 Baustetten, Germany
25 * Thomas.Nau@rz.uni-ulm.de
30 /* main program, initializes some stuff and handles user input
43 #include <time.h> /* Seed for srand() */
49 #include "crosshair.h"
56 #include "lrealpath.h"
57 #include "free_atexit.h"
60 #include "hid/common/actions.h"
62 /* This next one is so we can print the help messages. */
63 #include "hid/hidint.h"
73 #ifdef HAVE_LIBDMALLOC
80 #define PCBLIBPATH ".:" PCBLIBDIR
84 extern void stroke_init (void);
88 /* ----------------------------------------------------------------------
89 * initialize signal and error handlers
95 signal(SIGHUP, CatchSignal);
96 signal(SIGQUIT, CatchSignal);
97 signal(SIGABRT, CatchSignal);
98 signal(SIGSEGV, CatchSignal);
99 signal(SIGTERM, CatchSignal);
100 signal(SIGINT, CatchSignal);
103 /* calling external program by popen() may cause a PIPE signal,
107 signal (SIGPIPE
, SIG_IGN
);
112 /* ----------------------------------------------------------------------
113 | command line and rc file processing.
115 static char *command_line_pcb
;
121 " COPYRIGHT for %s version %s\n\n"
122 " PCB, interactive printed circuit board design\n"
123 " Copyright (C) 1994,1995,1996,1997 Thomas Nau\n"
124 " Copyright (C) 1998, 1999, 2000 Harry Eaton\n\n"
125 " This program is free software; you can redistribute it and/or modify\n"
126 " it under the terms of the GNU General Public License as published by\n"
127 " the Free Software Foundation; either version 2 of the License, or\n"
128 " (at your option) any later version.\n\n"
129 " This program is distributed in the hope that it will be useful,\n"
130 " but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
131 " MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
132 " GNU General Public License for more details.\n\n"
133 " You should have received a copy of the GNU General Public License\n"
134 " along with this program; if not, write to the Free Software\n"
135 " Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\n\n",
141 u (const char *fmt
, ...)
145 vfprintf (stderr
, fmt
, ap
);
146 fputc ('\n', stderr
);
150 typedef struct UsageNotes
{
151 struct UsageNotes
*next
;
155 static UsageNotes
*usage_notes
= NULL
;
158 usage_attr (HID_Attribute
* a
)
161 static char buf
[200];
163 if (a
->help_text
== ATTR_UNDOCUMENTED
)
172 sprintf (buf
, "--%s <num>", a
->name
);
175 sprintf (buf
, "--%s <string>", a
->name
);
178 sprintf (buf
, "--%s", a
->name
);
182 sprintf (buf
, "--%s ", a
->name
);
183 if (a
->type
== HID_Mixed
)
184 strcat (buf
, " <val>");
185 for (i
= 0; a
->enumerations
[i
]; i
++)
187 strcat (buf
, i
? "|" : "<");
188 strcat (buf
, a
->enumerations
[i
]);
193 sprintf (buf
, "--%s <path>", a
->name
);
197 if (strlen (buf
) <= 30)
200 fprintf (stderr
, " %-30s\t%s\n", buf
, a
->help_text
);
202 fprintf (stderr
, " %-30s\n", buf
);
204 else if (a
->help_text
&& strlen (a
->help_text
) + strlen (buf
) < 72)
205 fprintf (stderr
, " %s\t%s\n", buf
, a
->help_text
);
206 else if (a
->help_text
)
207 fprintf (stderr
, " %s\n\t\t\t%s\n", buf
, a
->help_text
);
209 fprintf (stderr
, " %s\n", buf
);
215 HID_Attribute
*attributes
;
216 int i
, n_attributes
= 0;
221 fprintf (stderr
, "\n%s gui options:\n", h
->name
);
222 attributes
= h
->get_export_options (&n_attributes
);
226 fprintf (stderr
, "\n%s options:\n", h
->name
);
228 attributes
= exporter
->get_export_options (&n_attributes
);
232 note
= (UsageNotes
*)malloc (sizeof (UsageNotes
));
233 note
->next
= usage_notes
;
234 note
->seen
= attributes
;
237 for (i
= 0; i
< n_attributes
; i
++)
238 usage_attr (attributes
+ i
);
244 HID
**hl
= hid_enumerate ();
248 int n_printer
= 0, n_gui
= 0, n_exporter
= 0;
250 for (i
= 0; hl
[i
]; i
++)
260 u ("PCB Printed Circuit Board editing program, http://pcb.gpleda.org");
261 u ("%s [-h|-V|--copyright]\t\t\tHelp, version, copyright", Progname
);
262 u ("%s [gui options] <pcb file>\t\tto edit", Progname
);
263 u ("Available GUI hid%s:", n_gui
== 1 ? "" : "s");
264 for (i
= 0; hl
[i
]; i
++)
266 fprintf (stderr
, "\t%-8s %s\n", hl
[i
]->name
, hl
[i
]->description
);
267 u ("%s -p [printing options] <pcb file>\tto print", Progname
);
268 u ("Available printing hid%s:", n_printer
== 1 ? "" : "s");
269 for (i
= 0; hl
[i
]; i
++)
271 fprintf (stderr
, "\t%-8s %s\n", hl
[i
]->name
, hl
[i
]->description
);
272 u ("%s -x hid [export options] <pcb file>\tto export", Progname
);
273 u ("Available export hid%s:", n_exporter
== 1 ? "" : "s");
274 for (i
= 0; hl
[i
]; i
++)
276 fprintf (stderr
, "\t%-8s %s\n", hl
[i
]->name
, hl
[i
]->description
);
278 for (i
= 0; hl
[i
]; i
++)
281 for (i
= 0; hl
[i
]; i
++)
284 for (i
= 0; hl
[i
]; i
++)
288 u ("\nCommon options:");
289 for (ha
= hid_attr_nodes
; ha
; ha
= ha
->next
)
291 for (note
= usage_notes
; note
&& note
->seen
!= ha
->attributes
; note
= note
->next
)
295 for (i
= 0; i
< ha
->n
; i
++)
297 usage_attr (ha
->attributes
+ i
);
305 print_defaults_1 (HID_Attribute
* a
, void *value
)
311 /* Remember, at this point we've parsed the command line, so they
312 may be in the global variable instead of the default_val. */
316 i
= value
? *(int *) value
: a
->default_val
.int_value
;
317 fprintf (stderr
, "%s %d\n", a
->name
, i
);
320 i
= value
? *(char *) value
: a
->default_val
.int_value
;
321 fprintf (stderr
, "%s %s\n", a
->name
, i
? "yes" : "no");
324 d
= value
? *(double *) value
: a
->default_val
.real_value
;
325 fprintf (stderr
, "%s %g\n", a
->name
, d
);
329 s
= value
? *(char **) value
: a
->default_val
.str_value
;
330 fprintf (stderr
, "%s \"%s\"\n", a
->name
, s
);
333 i
= value
? *(int *) value
: a
->default_val
.int_value
;
334 fprintf (stderr
, "%s %s\n", a
->name
, a
->enumerations
[i
]);
338 ((HID_Attr_Val
*)value
)->int_value
: a
->default_val
.int_value
;
340 ((HID_Attr_Val
*)value
)->real_value
: a
->default_val
.real_value
;
341 fprintf (stderr
, "%s %g%s\n", a
->name
, d
, a
->enumerations
[i
]);
351 HID
**hl
= hid_enumerate ();
355 for (hi
= 0; hl
[hi
]; hi
++)
361 fprintf (stderr
, "\ngui defaults:\n");
362 for (ha
= hid_attr_nodes
; ha
; ha
= ha
->next
)
363 for (i
= 0; i
< ha
->n
; i
++)
364 print_defaults_1 (ha
->attributes
+ i
, ha
->attributes
[i
].value
);
368 fprintf (stderr
, "\n%s defaults:\n", h
->name
);
370 e
= exporter
->get_export_options (&n
);
373 for (i
= 0; i
< n
; i
++)
374 print_defaults_1 (e
+ i
, 0);
380 #define SSET(F,D,N,H) { N, H, \
381 HID_String, 0, 0, { 0, D, 0 }, 0, &Settings.F }
382 #define ISET(F,D,N,H) { N, H, \
383 HID_Integer, 0, 0, { D, 0, 0 }, 0, &Settings.F }
384 #define BSET(F,D,N,H) { N, H, \
385 HID_Boolean, 0, 0, { D, 0, 0 }, 0, &Settings.F }
386 #define RSET(F,D,N,H) { N, H, \
387 HID_Real, 0, 0, { 0, 0, D }, 0, &Settings.F }
389 #define COLOR(F,D,N,H) { N, H, \
390 HID_String, 0, 0, { 0, D, 0 }, 0, &Settings.F }
391 #define LAYERCOLOR(N,D) { "layer-color-" #N, "Color for layer " #N, \
392 HID_String, 0, 0, { 0, D, 0 }, 0, &Settings.LayerColor[N-1] }
393 #define LAYERNAME(N,D) { "layer-name-" #N, "Name for layer " #N, \
394 HID_String, 0, 0, { 0, D, 0 }, 0, &Settings.DefaultLayerName[N-1] }
395 #define LAYERSELCOLOR(N) { "layer-selected-color-" #N, "Color for layer " #N " when selected", \
396 HID_String, 0, 0, { 0, "#00ffff", 0 }, 0, &Settings.LayerSelectedColor[N-1] }
398 static int show_help
= 0;
399 static int show_version
= 0;
400 static int show_copyright
= 0;
401 static int show_defaults
= 0;
402 static int show_actions
= 0;
403 static int do_dump_actions
= 0;
405 HID_Attribute main_attribute_list
[] = {
406 {"help", "Show Help", HID_Boolean
, 0, 0, {0, 0, 0}, 0, &show_help
},
407 {"version", "Show Version", HID_Boolean
, 0, 0, {0, 0, 0}, 0, &show_version
},
408 {"verbose", "Be verbose", HID_Boolean
, 0, 0, {0, 0, 0}, 0,
410 {"copyright", "Show Copyright", HID_Boolean
, 0, 0, {0, 0, 0}, 0,
412 {"show-defaults", "Show option defaults", HID_Boolean
, 0, 0, {0, 0, 0}, 0,
414 {"show-actions", "Show actions", HID_Boolean
, 0, 0, {0, 0, 0}, 0,
416 {"dump-actions", "Dump actions (for documentation)", HID_Boolean
, 0, 0,
420 BSET (grid_units_mm
, 0, "grid-units-mm", 0),
422 COLOR (BlackColor
, "#000000", "black-color", "color for black"),
423 COLOR (WhiteColor
, "#ffffff", "white-color", "color for white"),
424 COLOR (BackgroundColor
, "#e5e5e5", "background-color",
425 "color for background"),
426 COLOR (CrosshairColor
, "#ff0000", "crosshair-color",
427 "color for the crosshair"),
428 COLOR (CrossColor
, "#cdcd00", "cross-color", "color for cross"),
429 COLOR (ViaColor
, "#7f7f7f", "via-color", "color for vias"),
430 COLOR (ViaSelectedColor
, "#00ffff", "via-selected-color",
431 "color for selected vias"),
432 COLOR (PinColor
, "#4d4d4d", "pin-color", "color for pins"),
433 COLOR (PinSelectedColor
, "#00ffff", "pin-selected-color",
434 "color for selected pins"),
435 COLOR (PinNameColor
, "#ff0000", "pin-name-color",
436 "color for pin names and numbers"),
437 COLOR (ElementColor
, "#000000", "element-color", "color for elements"),
438 COLOR (RatColor
, "#b8860b", "rat-color", "color for ratlines"),
439 COLOR (InvisibleObjectsColor
, "#cccccc", "invisible-objects-color",
440 "color for invisible objects"),
441 COLOR (InvisibleMarkColor
, "#cccccc", "invisible-mark-color",
442 "color for invisible marks"),
443 COLOR (ElementSelectedColor
, "#00ffff", "element-selected-color",
444 "color for selected elements"),
445 COLOR (RatSelectedColor
, "#00ffff", "rat-selected-color",
446 "color for selected rats"),
447 COLOR (ConnectedColor
, "#00ff00", "connected-color",
448 "color for connections"),
449 COLOR (OffLimitColor
, "#cccccc", "off-limit-color",
450 "color for off-limits areas"),
451 COLOR (GridColor
, "#ff0000", "grid-color", "color for the grid"),
452 LAYERCOLOR (1, "#8b2323"),
453 LAYERCOLOR (2, "#3a5fcd"),
454 LAYERCOLOR (3, "#104e8b"),
455 LAYERCOLOR (4, "#cd3700"),
456 LAYERCOLOR (5, "#548b54"),
457 LAYERCOLOR (6, "#8b7355"),
458 LAYERCOLOR (7, "#00868b"),
459 LAYERCOLOR (8, "#228b22"),
460 LAYERCOLOR (9, "#8b2323"),
461 LAYERCOLOR (10, "#3a5fcd"),
462 LAYERCOLOR (11, "#104e8b"),
463 LAYERCOLOR (12, "#cd3700"),
464 LAYERCOLOR (13, "#548b54"),
465 LAYERCOLOR (14, "#8b7355"),
466 LAYERCOLOR (15, "#00868b"),
467 LAYERCOLOR (16, "#228b22"),
484 COLOR (WarnColor
, "#ff8000", "warn-color", "color for warnings"),
485 COLOR (MaskColor
, "#ff0000", "mask-color", "color for solder mask"),
487 ISET (ViaThickness
, MIL_TO_COORD(60), "via-thickness", 0),
488 ISET (ViaDrillingHole
, MIL_TO_COORD(28), "via-drilling-hole", 0),
489 ISET (LineThickness
, MIL_TO_COORD(10), "line-thickness",
490 "Initial thickness of new lines."),
491 ISET (RatThickness
, MIL_TO_COORD(10), "rat-thickness", 0),
492 ISET (Keepaway
, MIL_TO_COORD(10), "keepaway", 0),
493 ISET (MaxWidth
, MIL_TO_COORD(MIL_TO_COORD(60)), "default-PCB-width", 0),
494 ISET (MaxHeight
, MIL_TO_COORD(MIL_TO_COORD(50)), "default-PCB-height", 0),
495 ISET (TextScale
, 100, "text-scale", 0),
496 ISET (AlignmentDistance
, MIL_TO_COORD(2), "alignment-distance", 0),
497 ISET (Bloat
, MIL_TO_COORD(10), "bloat", 0),
498 ISET (Shrink
, MIL_TO_COORD(10), "shrink", 0),
499 ISET (minWid
, MIL_TO_COORD(10), "min-width", "DRC minimum copper spacing"),
500 ISET (minSlk
, MIL_TO_COORD(10), "min-silk", "DRC minimum silk width"),
501 ISET (minDrill
, MIL_TO_COORD(15), "min-drill", "DRC minimum drill diameter"),
502 ISET (minRing
, MIL_TO_COORD(10), "min-ring", "DRC minimum annular ring"),
504 RSET (Grid
, MIL_TO_COORD(10), "grid", 0),
505 RSET (grid_increment_mm
, 0.1, "grid-increment-mm", 0),
506 RSET (grid_increment_mil
, 5.0, "grid-increment-mil", 0),
507 RSET (size_increment_mm
, 0.2, "size-increment-mm", 0),
508 RSET (size_increment_mil
, 10.0, "size-increment-mil", 0),
509 RSET (line_increment_mm
, 0.1, "line-increment-mm", 0),
510 RSET (line_increment_mil
, 5.0, "line-increment-mil", 0),
511 RSET (clear_increment_mm
, 0.05, "clear-increment-mm", 0),
512 RSET (clear_increment_mil
, 2.0, "clear-increment-mil", 0),
513 RSET (IsleArea
, MIL_TO_COORD(1400) * MIL_TO_COORD(1400), "minimum polygon area", 0),
515 ISET (BackupInterval
, 60, "backup-interval", 0),
517 LAYERNAME (1, "top"),
518 LAYERNAME (2, "ground"),
519 LAYERNAME (3, "signal2"),
520 LAYERNAME (4, "signal3"),
521 LAYERNAME (5, "power"),
522 LAYERNAME (6, "bottom"),
523 LAYERNAME (7, "outline"),
524 LAYERNAME (8, "spare"),
525 SSET (Groups
, "1,c:2:3:4:5:6,s:7:8", "groups", 0),
527 SSET (FontCommand
, "",
529 SSET (FileCommand
, "", "file-command", "Command to read a file."),
530 SSET (ElementCommand
,
531 "M4PATH='%p';export M4PATH;echo 'include(%f)' | " GNUM4
,
532 "element-command", 0),
533 SSET (PrintFile
, "%f.output", "print-file", 0),
534 SSET (LibraryCommandDir
, PCBLIBDIR
, "lib-command-dir", 0),
535 SSET (LibraryCommand
, "QueryLibrary.sh '%p' '%f' %a",
537 SSET (LibraryContentsCommand
, "ListLibraryContents.sh '%p' '%f'",
538 "lib-contents-command", 0),
539 SSET (LibraryTree
, PCBTREEPATH
, "lib-newlib",
540 "Top level directory for the newlib style library"),
541 SSET (SaveCommand
, "", "save-command", 0),
542 SSET (LibraryFilename
, LIBRARYFILENAME
, "lib-name", 0),
543 SSET (FontFile
, "default_font", "default-font",
544 "File name of default font."),
545 SSET (Routes
, "Signal,1000,3600,2000,1000:Power,2500,6000,3500,1000"
546 ":Fat,4000,6000,3500,1000:Skinny,600,2402,1181,600", "route-styles",
548 SSET (FilePath
, "", "file-path", 0),
549 SSET (RatCommand
, "", "rat-command", 0),
550 SSET (FontPath
, PCBLIBPATH
, "font-path", 0),
551 SSET (ElementPath
, PCBLIBPATH
, "element-path", 0),
552 SSET (LibraryPath
, PCBLIBPATH
, "lib-path", 0),
553 SSET (MenuFile
, "pcb-menu.res", "menu-file", 0),
554 SSET (ScriptFilename
, 0, "action-script",
555 "If set, this file is executed at startup."),
556 SSET (ActionString
, 0, "action-string",
557 "If set, this is executed at startup."),
558 SSET (FabAuthor
, "", "fab-author", 0),
559 SSET (InitialLayerStack
, "", "layer-stack",
560 "Initial layer stackup, for setting up an export."),
562 SSET (MakeProgram
, NULL
, "make-program",
563 "Sets the name and optionally full path to a make(3) program"),
564 SSET (GnetlistProgram
, NULL
, "gnetlist",
565 "Sets the name and optionally full path to the gnetlist(3) program"),
567 ISET (PinoutOffsetX
, MIL_TO_COORD(1), "pinout-offset-x", 0),
568 ISET (PinoutOffsetY
, MIL_TO_COORD(1), "pinout-offset-y", 0),
569 ISET (PinoutTextOffsetX
, MIL_TO_COORD(8), "pinout-text-offset-x", 0),
570 ISET (PinoutTextOffsetY
, MIL_TO_COORD(-1), "pinout-text-offset-y", 0),
572 BSET (DrawGrid
, 0, "draw-grid", "default to drawing the grid at startup"),
573 BSET (ClearLine
, 1, "clear-line", 0),
574 BSET (FullPoly
, 0, "full-poly", 0),
575 BSET (UniqueNames
, 1, "unique-names", 0),
576 BSET (SnapPin
, 1, "snap-pin", 0),
577 BSET (SaveLastCommand
, 0, "save-last-command", 0),
578 BSET (SaveInTMP
, 0, "save-in-tmp", 0),
579 BSET (AllDirectionLines
, 0, "all-direction-lines", 0),
580 BSET (ShowNumber
, 0, "show-number", 0),
581 BSET (ResetAfterElement
, 1, "reset-after-element", 0),
582 BSET (RingBellWhenFinished
, 0, "ring-bell-finished", 0),
585 REGISTER_ATTRIBUTES (main_attribute_list
)
586 /* ----------------------------------------------------------------------
587 * post-process settings.
589 static void settings_post_process ()
593 if (Settings
.LibraryCommand
[0] != PCB_DIR_SEPARATOR_C
&& Settings
.LibraryCommand
[0] != '.')
595 Settings
.LibraryCommand
597 Concat (Settings
.LibraryCommandDir
, PCB_DIR_SEPARATOR_S
,
598 Settings
.LibraryCommand
,
601 if (Settings
.LibraryContentsCommand
[0] != PCB_DIR_SEPARATOR_C
602 && Settings
.LibraryContentsCommand
[0] != '.')
604 Settings
.LibraryContentsCommand
606 Concat (Settings
.LibraryCommandDir
, PCB_DIR_SEPARATOR_S
,
607 Settings
.LibraryContentsCommand
, NULL
);
610 if (Settings
.LineThickness
> MAX_LINESIZE
611 || Settings
.LineThickness
< MIN_LINESIZE
)
612 Settings
.LineThickness
= MIL_TO_COORD(10);
614 if (Settings
.ViaThickness
> MAX_PINORVIASIZE
615 || Settings
.ViaThickness
< MIN_PINORVIASIZE
)
616 Settings
.ViaThickness
= MIL_TO_COORD(40);
618 if (Settings
.ViaDrillingHole
<= 0)
619 Settings
.ViaDrillingHole
=
620 DEFAULT_DRILLINGHOLE
* Settings
.ViaThickness
/ 100;
622 Settings
.MaxWidth
= MIN (MAX_COORD
, MAX (Settings
.MaxWidth
, MIN_SIZE
));
623 Settings
.MaxHeight
= MIN (MAX_COORD
, MAX (Settings
.MaxHeight
, MIN_SIZE
));
625 ParseRouteString (Settings
.Routes
, &Settings
.RouteStyle
[0], "cmil");
628 * Make sure we have settings for some various programs we may wish
631 if (Settings
.MakeProgram
== NULL
) {
632 tmps
= getenv ("PCB_MAKE_PROGRAM");
634 Settings
.MakeProgram
= strdup (tmps
);
636 if (Settings
.MakeProgram
== NULL
) {
637 Settings
.MakeProgram
= strdup ("make");
640 if (Settings
.GnetlistProgram
== NULL
) {
641 tmps
= getenv ("PCB_GNETLIST");
643 Settings
.GnetlistProgram
= strdup (tmps
);
645 if (Settings
.GnetlistProgram
== NULL
) {
646 Settings
.GnetlistProgram
= strdup ("gnetlist");
652 /* ----------------------------------------------------------------------
653 * Print help or version messages.
659 printf ("PCB version %s\n", VERSION
);
663 /* ----------------------------------------------------------------------
664 * Figure out the canonical name of the executed program
665 * and fix up the defaults for various paths
668 char *exec_prefix
= NULL
;
669 char *pcblibdir
= NULL
;
670 char *pcblibpath
= NULL
;
671 char *pcbtreedir
= NULL
;
672 char *pcbtreepath
= NULL
;
673 char *homedir
= NULL
;
676 InitPaths (char *argv0
)
682 int found_bindir
= 0;
684 /* see if argv0 has enough of a path to let lrealpath give the
685 * real path. This should be the case if you invoke pcb with
686 * something like /usr/local/bin/pcb or ./pcb or ./foo/pcb
687 * but if you just use pcb and it exists in your path, you'll
688 * just get back pcb again.
692 for (i
= 0; i
< strlen (argv0
) ; i
++)
694 if (argv0
[i
] == PCB_DIR_SEPARATOR_C
)
699 printf ("InitPaths (%s): haspath = %d\n", argv0
, haspath
);
704 bindir
= strdup (lrealpath (argv0
));
709 char *path
, *p
, *tmps
;
713 tmps
= getenv ("PATH");
717 path
= strdup (tmps
);
719 /* search through the font path for a font file */
720 for (p
= strtok (path
, PCB_PATH_DELIMETER
); p
&& *p
;
721 p
= strtok (NULL
, PCB_PATH_DELIMETER
))
724 printf ("Looking for %s in %s\n", argv0
, p
);
726 if ( (tmps
= (char *)malloc ( (strlen (argv0
) + strlen (p
) + 2) * sizeof (char))) == NULL
)
728 fprintf (stderr
, "InitPaths(): malloc failed\n");
731 sprintf (tmps
, "%s%s%s", p
, PCB_DIR_SEPARATOR_S
, argv0
);
732 r
= stat (tmps
, &sb
);
736 printf ("Found it: \"%s\"\n", tmps
);
738 bindir
= lrealpath (tmps
);
750 printf ("InitPaths(): bindir = \"%s\"\n", bindir
);
755 /* strip off the executible name leaving only the path */
757 t1
= strchr (bindir
, PCB_DIR_SEPARATOR_C
);
758 while (t1
!= NULL
&& *t1
!= '\0')
761 t1
= strchr (t2
+ 1, PCB_DIR_SEPARATOR_C
);
767 printf ("After stripping off the executible name, we found\n");
768 printf ("bindir = \"%s\"\n", bindir
);
773 /* we have failed to find out anything from argv[0] so fall back to the original
776 bindir
= strdup (BINDIR
);
779 /* now find the path to exec_prefix */
780 l
= strlen (bindir
) + 1 + strlen (BINDIR_TO_EXECPREFIX
) + 1;
781 if ( (exec_prefix
= (char *) malloc (l
* sizeof (char) )) == NULL
)
783 fprintf (stderr
, "InitPaths(): malloc failed\n");
786 sprintf (exec_prefix
, "%s%s%s", bindir
, PCB_DIR_SEPARATOR_S
,
787 BINDIR_TO_EXECPREFIX
);
789 /* now find the path to PCBLIBDIR */
790 l
= strlen (bindir
) + 1 + strlen (BINDIR_TO_PCBLIBDIR
) + 1;
791 if ( (pcblibdir
= (char *) malloc (l
* sizeof (char) )) == NULL
)
793 fprintf (stderr
, "InitPaths(): malloc failed\n");
796 sprintf (pcblibdir
, "%s%s%s", bindir
, PCB_DIR_SEPARATOR_S
,
797 BINDIR_TO_PCBLIBDIR
);
799 /* and the path to PCBTREEDIR */
800 l
= strlen (bindir
) + 1 + strlen (BINDIR_TO_PCBTREEDIR
) + 1;
801 if ( (pcbtreedir
= (char *) malloc (l
* sizeof (char) )) == NULL
)
803 fprintf (stderr
, "InitPaths(): malloc failed\n");
806 sprintf (pcbtreedir
, "%s%s%s", bindir
, PCB_DIR_SEPARATOR_S
,
807 BINDIR_TO_PCBTREEDIR
);
809 /* and the search path including PCBLIBDIR */
810 l
= strlen (pcblibdir
) + 3;
811 if ( (pcblibpath
= (char *) malloc (l
* sizeof (char) )) == NULL
)
813 fprintf (stderr
, "InitPaths(): malloc failed\n");
816 sprintf (pcblibpath
, ".%s%s", PCB_PATH_DELIMETER
, pcblibdir
);
818 /* and the newlib search path */
819 l
= strlen (pcblibdir
) + 1 + strlen (pcbtreedir
)
820 + strlen ("pcblib-newlib") + 2;
821 if ( (pcbtreepath
= (char *) malloc (l
* sizeof (char) )) == NULL
)
823 fprintf (stderr
, "InitPaths(): malloc failed\n");
826 sprintf (pcbtreepath
, "%s%s%s%spcblib-newlib", pcbtreedir
,
827 PCB_PATH_DELIMETER
, pcblibdir
,
828 PCB_DIR_SEPARATOR_S
);
831 printf ("bindir = %s\n", bindir
);
832 printf ("pcblibdir = %s\n", pcblibdir
);
833 printf ("pcblibpath = %s\n", pcblibpath
);
834 printf ("pcbtreedir = %s\n", pcbtreedir
);
835 printf ("pcbtreepath = %s\n", pcbtreepath
);
838 l
= sizeof (main_attribute_list
) / sizeof (main_attribute_list
[0]);
839 for (i
= 0; i
< l
; i
++)
841 if (NSTRCMP (main_attribute_list
[i
].name
, "lib-command-dir") == 0)
843 main_attribute_list
[i
].default_val
.str_value
= pcblibdir
;
846 if ( (NSTRCMP (main_attribute_list
[i
].name
, "font-path") == 0)
847 || (NSTRCMP (main_attribute_list
[i
].name
, "element-path") == 0)
848 || (NSTRCMP (main_attribute_list
[i
].name
, "lib-path") == 0) )
850 main_attribute_list
[i
].default_val
.str_value
= pcblibpath
;
853 if (NSTRCMP (main_attribute_list
[i
].name
, "lib-newlib") == 0)
855 main_attribute_list
[i
].default_val
.str_value
= pcbtreepath
;
863 tmps
= getenv ("HOME");
866 tmps
= getenv ("USERPROFILE");
870 homedir
= strdup (tmps
);
878 /* ----------------------------------------------------------------------
882 char *program_name
= 0;
883 char *program_basename
= 0;
884 char *program_directory
= 0;
889 main (int argc
, char *argv
[])
894 * - make program name available for error handlers
895 * - evaluate special options
896 * - initialize toplevel shell and resources
897 * - create an empty PCB with default symbols
898 * - initialize all other widgets
899 * - update screen and get size of drawing area
900 * - evaluate command-line arguments
901 * - register 'call on exit()' function
904 #include "core_lists.h"
908 bindtextdomain (GETTEXT_PACKAGE
, LOCALEDIR
);
909 bind_textdomain_codeset(GETTEXT_PACKAGE
, "UTF-8");
911 srand ( time(NULL
) ); /* Set seed for rand() */
916 hid_load_settings ();
918 program_name
= argv
[0];
919 program_basename
= strrchr (program_name
, PCB_DIR_SEPARATOR_C
);
920 if (program_basename
)
922 program_directory
= strdup (program_name
);
923 *strrchr (program_directory
, PCB_DIR_SEPARATOR_C
) = 0;
928 program_directory
= ".";
929 program_basename
= program_name
;
931 Progname
= program_basename
;
933 /* Print usage or version if requested. Then exit. */
934 if (argc
> 1 && strcmp (argv
[1], "-h") == 0)
936 if (argc
> 1 && strcmp (argv
[1], "-V") == 0)
938 /* Export pcb from command line if requested. */
939 if (argc
> 1 && strcmp (argv
[1], "-p") == 0)
941 exporter
= gui
= hid_find_printer ();
945 else if (argc
> 2 && strcmp (argv
[1], "-x") == 0)
947 exporter
= gui
= hid_find_exporter (argv
[2]);
951 /* Otherwise start GUI. */
953 gui
= hid_find_gui ();
955 /* Exit with error if GUI failed to start. */
960 for (i
= 0; i
< MAX_LAYER
; i
++)
963 sprintf (buf
, "signal%d", i
+ 1);
964 Settings
.DefaultLayerName
[i
] = strdup (buf
);
965 Settings
.LayerColor
[i
] = "#c49350";
966 Settings
.LayerSelectedColor
[i
] = "#00ffff";
969 gui
->parse_arguments (&argc
, &argv
);
971 if (show_help
|| (argc
> 1 && argv
[1][0] == '-'))
980 settings_post_process ();
991 extern void dump_actions (void);
996 /* Create a new PCB object in memory */
997 PCB
= CreateNewPCB (true);
998 PCB
->Data
->LayerN
= DEF_LAYER
;
999 ParseGroupString (Settings
.Groups
, &PCB
->LayerGroups
, DEF_LAYER
);
1000 /* Add silk layers to newly created PCB */
1001 CreateNewPCBPost (PCB
, 1);
1003 command_line_pcb
= argv
[1];
1005 ResetStackAndVisibility ();
1007 CreateDefaultFont ();
1012 SetMode (ARROW_MODE
);
1014 if (command_line_pcb
)
1016 /* keep filename even if initial load command failed;
1017 * file might not exist
1019 if (LoadPCB (command_line_pcb
))
1020 PCB
->Filename
= strdup (command_line_pcb
);
1023 if (Settings
.InitialLayerStack
1024 && Settings
.InitialLayerStack
[0])
1026 LayerStringToLayerStack (Settings
.InitialLayerStack
);
1030 LoadBackgroundImage (Settings.BackgroundImage); */
1032 /* This must be called before any other atexit functions
1033 * are registered, as it configures an atexit function to
1034 * clean up and free various items of allocated memory,
1035 * and must be the last last atexit function to run.
1039 /* Register a function to be called when the program terminates.
1040 * This makes sure that data is saved even if LEX/YACC routines
1041 * abort the program.
1042 * If the OS doesn't have at least one of them,
1043 * the critical sections will be handled by parse_l.l
1045 atexit (EmergencySave
);
1047 /* read the library file and display it if it's not empty
1049 if (!ReadLibraryContents () && Library
.MenuN
)
1050 hid_action ("LibraryChanged");
1052 #ifdef HAVE_LIBSTROKE
1056 if (Settings
.ScriptFilename
)
1058 Message (_("Executing startup script file %s\n"),
1059 Settings
.ScriptFilename
);
1060 hid_actionl ("ExecuteFile", Settings
.ScriptFilename
, NULL
);
1062 if (Settings
.ActionString
)
1064 Message (_("Executing startup action %s\n"), Settings
.ActionString
);
1065 hid_parse_actions (Settings
.ActionString
);
1068 if (gui
->printer
|| gui
->exporter
)
1081 printf ("Settings.LibraryCommandDir = \"%s\"\n",
1082 Settings
.LibraryCommandDir
);
1083 printf ("Settings.FontPath = \"%s\"\n",
1085 printf ("Settings.ElementPath = \"%s\"\n",
1086 Settings
.ElementPath
);
1087 printf ("Settings.LibraryPath = \"%s\"\n",
1088 Settings
.LibraryPath
);
1089 printf ("Settings.LibraryTree = \"%s\"\n",
1090 Settings
.LibraryTree
);
1091 printf ("Settings.MakeProgram = \"%s\"\n",
1092 UNKNOWN (Settings
.MakeProgram
));
1093 printf ("Settings.GnetlistProgram = \"%s\"\n",
1094 UNKNOWN (Settings
.GnetlistProgram
));