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
48 #include "crosshair.h"
55 #include "lrealpath.h"
56 #include "free_atexit.h"
58 #include "hid/common/actions.h"
60 /* This next one is so we can print the help messages. */
61 #include "hid/hidint.h"
71 #ifdef HAVE_LIBDMALLOC
78 #define PCBLIBPATH ".:" PCBLIBDIR
82 extern void stroke_init (void);
86 /* ----------------------------------------------------------------------
87 * initialize signal and error handlers
93 signal(SIGHUP, CatchSignal);
94 signal(SIGQUIT, CatchSignal);
95 signal(SIGABRT, CatchSignal);
96 signal(SIGSEGV, CatchSignal);
97 signal(SIGTERM, CatchSignal);
98 signal(SIGINT, CatchSignal);
101 /* calling external program by popen() may cause a PIPE signal,
105 signal (SIGPIPE
, SIG_IGN
);
110 /* ----------------------------------------------------------------------
111 | command line and rc file processing.
113 static char *command_line_pcb
;
119 " COPYRIGHT for %s version %s\n\n"
120 " PCB, interactive printed circuit board design\n"
121 " Copyright (C) 1994,1995,1996,1997 Thomas Nau\n"
122 " Copyright (C) 1998, 1999, 2000 Harry Eaton\n\n"
123 " This program is free software; you can redistribute it and/or modify\n"
124 " it under the terms of the GNU General Public License as published by\n"
125 " the Free Software Foundation; either version 2 of the License, or\n"
126 " (at your option) any later version.\n\n"
127 " This program is distributed in the hope that it will be useful,\n"
128 " but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
129 " MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
130 " GNU General Public License for more details.\n\n"
131 " You should have received a copy of the GNU General Public License\n"
132 " along with this program; if not, write to the Free Software\n"
133 " Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\n\n",
139 u (const char *fmt
, ...)
143 vfprintf (stderr
, fmt
, ap
);
144 fputc ('\n', stderr
);
148 typedef struct UsageNotes
{
149 struct UsageNotes
*next
;
153 static UsageNotes
*usage_notes
= NULL
;
156 usage_attr (HID_Attribute
* a
)
159 static char buf
[200];
161 if (a
->help_text
== ATTR_UNDOCUMENTED
)
170 sprintf (buf
, "--%s <num>", a
->name
);
173 sprintf (buf
, "--%s <string>", a
->name
);
176 sprintf (buf
, "--%s", a
->name
);
180 sprintf (buf
, "--%s ", a
->name
);
181 if (a
->type
== HID_Mixed
)
182 strcat (buf
, " <val>");
183 for (i
= 0; a
->enumerations
[i
]; i
++)
185 strcat (buf
, i
? "|" : "<");
186 strcat (buf
, a
->enumerations
[i
]);
191 sprintf (buf
, "--%s <path>", a
->name
);
195 if (strlen (buf
) <= 30)
198 fprintf (stderr
, " %-30s\t%s\n", buf
, a
->help_text
);
200 fprintf (stderr
, " %-30s\n", buf
);
202 else if (a
->help_text
&& strlen (a
->help_text
) + strlen (buf
) < 72)
203 fprintf (stderr
, " %s\t%s\n", buf
, a
->help_text
);
204 else if (a
->help_text
)
205 fprintf (stderr
, " %s\n\t\t\t%s\n", buf
, a
->help_text
);
207 fprintf (stderr
, " %s\n", buf
);
213 HID_Attribute
*attributes
;
214 int i
, n_attributes
= 0;
219 fprintf (stderr
, "\n%s gui options:\n", h
->name
);
220 attributes
= h
->get_export_options (&n_attributes
);
224 fprintf (stderr
, "\n%s options:\n", h
->name
);
226 attributes
= exporter
->get_export_options (&n_attributes
);
230 note
= malloc (sizeof (UsageNotes
));
231 note
->next
= usage_notes
;
232 note
->seen
= attributes
;
235 for (i
= 0; i
< n_attributes
; i
++)
236 usage_attr (attributes
+ i
);
242 HID
**hl
= hid_enumerate ();
246 int n_printer
= 0, n_gui
= 0, n_exporter
= 0;
248 for (i
= 0; hl
[i
]; i
++)
258 u ("PCB Printed Circuit Board editing program, http://pcb.gpleda.org");
259 u ("%s [-h|-V|--copyright]\t\t\tHelp, version, copyright", Progname
);
260 u ("%s [gui options] <pcb file>\t\tto edit", Progname
);
261 u ("Available GUI hid%s:", n_gui
== 1 ? "" : "s");
262 for (i
= 0; hl
[i
]; i
++)
264 fprintf (stderr
, "\t%-8s %s\n", hl
[i
]->name
, hl
[i
]->description
);
265 u ("%s -p [printing options] <pcb file>\tto print", Progname
);
266 u ("Available printing hid%s:", n_printer
== 1 ? "" : "s");
267 for (i
= 0; hl
[i
]; i
++)
269 fprintf (stderr
, "\t%-8s %s\n", hl
[i
]->name
, hl
[i
]->description
);
270 u ("%s -x hid [export options] <pcb file>\tto export", Progname
);
271 u ("Available export hid%s:", n_exporter
== 1 ? "" : "s");
272 for (i
= 0; hl
[i
]; i
++)
274 fprintf (stderr
, "\t%-8s %s\n", hl
[i
]->name
, hl
[i
]->description
);
276 for (i
= 0; hl
[i
]; i
++)
279 for (i
= 0; hl
[i
]; i
++)
282 for (i
= 0; hl
[i
]; i
++)
286 u ("\nCommon options:");
287 for (ha
= hid_attr_nodes
; ha
; ha
= ha
->next
)
289 for (note
= usage_notes
; note
&& note
->seen
!= ha
->attributes
; note
= note
->next
)
293 for (i
= 0; i
< ha
->n
; i
++)
295 usage_attr (ha
->attributes
+ i
);
303 print_defaults_1 (HID_Attribute
* a
, void *value
)
309 /* Remember, at this point we've parsed the command line, so they
310 may be in the global variable instead of the default_val. */
314 i
= value
? *(int *) value
: a
->default_val
.int_value
;
315 fprintf (stderr
, "%s %d\n", a
->name
, i
);
318 i
= value
? *(char *) value
: a
->default_val
.int_value
;
319 fprintf (stderr
, "%s %s\n", a
->name
, i
? "yes" : "no");
322 d
= value
? *(double *) value
: a
->default_val
.real_value
;
323 fprintf (stderr
, "%s %g\n", a
->name
, d
);
327 s
= value
? *(char **) value
: a
->default_val
.str_value
;
328 fprintf (stderr
, "%s \"%s\"\n", a
->name
, s
);
331 i
= value
? *(int *) value
: a
->default_val
.int_value
;
332 fprintf (stderr
, "%s %s\n", a
->name
, a
->enumerations
[i
]);
336 ((HID_Attr_Val
*)value
)->int_value
: a
->default_val
.int_value
;
338 ((HID_Attr_Val
*)value
)->real_value
: a
->default_val
.real_value
;
339 fprintf (stderr
, "%s %g%s\n", a
->name
, d
, a
->enumerations
[i
]);
349 HID
**hl
= hid_enumerate ();
353 for (hi
= 0; hl
[hi
]; hi
++)
359 fprintf (stderr
, "\ngui defaults:\n");
360 for (ha
= hid_attr_nodes
; ha
; ha
= ha
->next
)
361 for (i
= 0; i
< ha
->n
; i
++)
362 print_defaults_1 (ha
->attributes
+ i
, ha
->attributes
[i
].value
);
366 fprintf (stderr
, "\n%s defaults:\n", h
->name
);
368 e
= exporter
->get_export_options (&n
);
371 for (i
= 0; i
< n
; i
++)
372 print_defaults_1 (e
+ i
, 0);
378 #define SSET(F,D,N,H) { N, H, \
379 HID_String, 0, 0, { 0, D, 0 }, 0, &Settings.F }
380 #define ISET(F,D,N,H) { N, H, \
381 HID_Integer, 0, 0, { D, 0, 0 }, 0, &Settings.F }
382 #define BSET(F,D,N,H) { N, H, \
383 HID_Boolean, 0, 0, { D, 0, 0 }, 0, &Settings.F }
384 #define RSET(F,D,N,H) { N, H, \
385 HID_Real, 0, 0, { 0, 0, D }, 0, &Settings.F }
387 #define COLOR(F,D,N,H) { N, H, \
388 HID_String, 0, 0, { 0, D, 0 }, 0, &Settings.F }
389 #define LAYERCOLOR(N,D) { "layer-color-" #N, "Color for layer " #N, \
390 HID_String, 0, 0, { 0, D, 0 }, 0, &Settings.LayerColor[N-1] }
391 #define LAYERNAME(N,D) { "layer-name-" #N, "Name for layer " #N, \
392 HID_String, 0, 0, { 0, D, 0 }, 0, &Settings.DefaultLayerName[N-1] }
393 #define LAYERSELCOLOR(N) { "layer-selected-color-" #N, "Color for layer " #N " when selected", \
394 HID_String, 0, 0, { 0, "#00ffff", 0 }, 0, &Settings.LayerSelectedColor[N-1] }
396 static int show_help
= 0;
397 static int show_version
= 0;
398 static int show_copyright
= 0;
399 static int show_defaults
= 0;
400 static int show_actions
= 0;
401 static int do_dump_actions
= 0;
403 HID_Attribute main_attribute_list
[] = {
404 {"help", "Show Help", HID_Boolean
, 0, 0, {0, 0, 0}, 0, &show_help
},
405 {"version", "Show Version", HID_Boolean
, 0, 0, {0, 0, 0}, 0, &show_version
},
406 {"verbose", "Be verbose", HID_Boolean
, 0, 0, {0, 0, 0}, 0,
408 {"copyright", "Show Copyright", HID_Boolean
, 0, 0, {0, 0, 0}, 0,
410 {"show-defaults", "Show option defaults", HID_Boolean
, 0, 0, {0, 0, 0}, 0,
412 {"show-actions", "Show actions", HID_Boolean
, 0, 0, {0, 0, 0}, 0,
414 {"dump-actions", "Dump actions (for documentation)", HID_Boolean
, 0, 0,
418 BSET (grid_units_mm
, 0, "grid-units-mm", 0),
420 COLOR (BlackColor
, "#000000", "black-color", "color for black"),
421 COLOR (WhiteColor
, "#ffffff", "white-color", "color for white"),
422 COLOR (BackgroundColor
, "#e5e5e5", "background-color",
423 "color for background"),
424 COLOR (CrosshairColor
, "#ff0000", "crosshair-color",
425 "color for the crosshair"),
426 COLOR (CrossColor
, "#cdcd00", "cross-color", "color for cross"),
427 COLOR (ViaColor
, "#7f7f7f", "via-color", "color for vias"),
428 COLOR (ViaSelectedColor
, "#00ffff", "via-selected-color",
429 "color for selected vias"),
430 COLOR (PinColor
, "#4d4d4d", "pin-color", "color for pins"),
431 COLOR (PinSelectedColor
, "#00ffff", "pin-selected-color",
432 "color for selected pins"),
433 COLOR (PinNameColor
, "#ff0000", "pin-name-color",
434 "color for pin names and numbers"),
435 COLOR (ElementColor
, "#000000", "element-color", "color for elements"),
436 COLOR (RatColor
, "#b8860b", "rat-color", "color for ratlines"),
437 COLOR (InvisibleObjectsColor
, "#cccccc", "invisible-objects-color",
438 "color for invisible objects"),
439 COLOR (InvisibleMarkColor
, "#cccccc", "invisible-mark-color",
440 "color for invisible marks"),
441 COLOR (ElementSelectedColor
, "#00ffff", "element-selected-color",
442 "color for selected elements"),
443 COLOR (RatSelectedColor
, "#00ffff", "rat-selected-color",
444 "color for selected rats"),
445 COLOR (ConnectedColor
, "#00ff00", "connected-color",
446 "color for connections"),
447 COLOR (OffLimitColor
, "#cccccc", "off-limit-color",
448 "color for off-limits areas"),
449 COLOR (GridColor
, "#ff0000", "grid-color", "color for the grid"),
450 LAYERCOLOR (1, "#8b2323"),
451 LAYERCOLOR (2, "#3a5fcd"),
452 LAYERCOLOR (3, "#104e8b"),
453 LAYERCOLOR (4, "#cd3700"),
454 LAYERCOLOR (5, "#548b54"),
455 LAYERCOLOR (6, "#8b7355"),
456 LAYERCOLOR (7, "#00868b"),
457 LAYERCOLOR (8, "#228b22"),
458 LAYERCOLOR (9, "#8b2323"),
459 LAYERCOLOR (10, "#3a5fcd"),
460 LAYERCOLOR (11, "#104e8b"),
461 LAYERCOLOR (12, "#cd3700"),
462 LAYERCOLOR (13, "#548b54"),
463 LAYERCOLOR (14, "#8b7355"),
464 LAYERCOLOR (15, "#00868b"),
465 LAYERCOLOR (16, "#228b22"),
482 COLOR (WarnColor
, "#ff8000", "warn-color", "color for warnings"),
483 COLOR (MaskColor
, "#ff0000", "mask-color", "color for solder mask"),
485 ISET (ViaThickness
, 6000, "via-thickness", 0),
486 ISET (ViaDrillingHole
, 2800, "via-drilling-hole", 0),
487 ISET (LineThickness
, 1000, "line-thickness",
488 "Initial thickness of new lines."),
489 ISET (RatThickness
, 1000, "rat-thickness", 0),
490 ISET (Keepaway
, 1000, "keepaway", 0),
491 ISET (MaxWidth
, 600000, "default-PCB-width", 0),
492 ISET (MaxHeight
, 500000, "default-PCB-height", 0),
493 ISET (TextScale
, 100, "text-scale", 0),
494 ISET (AlignmentDistance
, 200, "alignment-distance", 0),
495 ISET (Bloat
, 1000, "bloat", 0),
496 ISET (Shrink
, 1000, "shrink", 0),
497 ISET (minWid
, 1000, "min-width", "DRC minimum copper spacing"),
498 ISET (minSlk
, 1000, "min-silk", "DRC minimum silk width"),
499 ISET (minDrill
, 1500, "min-drill", "DRC minimum drill diameter"),
500 ISET (minRing
, 1000, "min-ring", "DRC minimum annular ring"),
502 RSET (Grid
, 1000, "grid", 0),
503 RSET (grid_increment_mm
, 0.1, "grid-increment-mm", 0),
504 RSET (grid_increment_mil
, 5.0, "grid-increment-mil", 0),
505 RSET (size_increment_mm
, 0.2, "size-increment-mm", 0),
506 RSET (size_increment_mil
, 10.0, "size-increment-mil", 0),
507 RSET (line_increment_mm
, 0.1, "line-increment-mm", 0),
508 RSET (line_increment_mil
, 5.0, "line-increment-mil", 0),
509 RSET (clear_increment_mm
, 0.05, "clear-increment-mm", 0),
510 RSET (clear_increment_mil
, 2.0, "clear-increment-mil", 0),
511 RSET (IsleArea
, 200000000, "minimum polygon area", 0),
513 ISET (BackupInterval
, 60, "backup-interval", 0),
515 LAYERNAME (1, "component"),
516 LAYERNAME (2, "solder"),
517 LAYERNAME (3, "GND"),
518 LAYERNAME (4, "power"),
519 LAYERNAME (5, "signal1"),
520 LAYERNAME (6, "signal2"),
521 LAYERNAME (7, "signal3"),
522 LAYERNAME (8, "signal4"),
524 SSET (FontCommand
, "",
526 SSET (FileCommand
, "", "file-command", "Command to read a file."),
527 SSET (ElementCommand
,
528 "M4PATH='%p';export M4PATH;echo 'include(%f)' | " GNUM4
,
529 "element-command", 0),
530 SSET (PrintFile
, "%f.output", "print-file", 0),
531 SSET (LibraryCommandDir
, PCBLIBDIR
, "lib-command-dir", 0),
532 SSET (LibraryCommand
, "QueryLibrary.sh '%p' '%f' %a",
534 SSET (LibraryContentsCommand
, "ListLibraryContents.sh '%p' '%f'",
535 "lib-contents-command", 0),
536 SSET (LibraryTree
, PCBTREEPATH
, "lib-newlib",
537 "Top level directory for the newlib style library"),
538 SSET (SaveCommand
, "", "save-command", 0),
539 SSET (LibraryFilename
, LIBRARYFILENAME
, "lib-name", 0),
540 SSET (FontFile
, "default_font", "default-font",
541 "File name of default font."),
542 SSET (Groups
, "1,c:2,s:3:4:5:6:7:8", "groups", 0),
543 SSET (Routes
, "Signal,1000,3600,2000,1000:Power,2500,6000,3500,1000"
544 ":Fat,4000,6000,3500,1000:Skinny,600,2402,1181,600", "route-styles",
546 SSET (FilePath
, "", "file-path", 0),
547 SSET (RatCommand
, "", "rat-command", 0),
548 SSET (FontPath
, PCBLIBPATH
, "font-path", 0),
549 SSET (ElementPath
, PCBLIBPATH
, "element-path", 0),
550 SSET (LibraryPath
, PCBLIBPATH
, "lib-path", 0),
551 SSET (MenuFile
, "pcb-menu.res", "menu-file", 0),
552 SSET (ScriptFilename
, 0, "action-script",
553 "If set, this file is executed at startup."),
554 SSET (ActionString
, 0, "action-string",
555 "If set, this is executed at startup."),
556 SSET (FabAuthor
, "", "fab-author", 0),
557 SSET (InitialLayerStack
, "", "layer-stack",
558 "Initial layer stackup, for setting up an export."),
560 SSET (MakeProgram
, NULL
, "make-program",
561 "Sets the name and optionally full path to a make(3) program"),
562 SSET (GnetlistProgram
, NULL
, "gnetlist",
563 "Sets the name and optionally full path to the gnetlist(3) program"),
565 ISET (PinoutOffsetX
, 100, "pinout-offset-x", 0),
566 ISET (PinoutOffsetY
, 100, "pinout-offset-y", 0),
567 ISET (PinoutTextOffsetX
, 800, "pinout-text-offset-x", 0),
568 ISET (PinoutTextOffsetY
, -100, "pinout-text-offset-y", 0),
570 BSET (DrawGrid
, 0, "draw-grid", "default to drawing the grid at startup"),
571 BSET (ClearLine
, 1, "clear-line", 0),
572 BSET (FullPoly
, 0, "full-poly", 0),
573 BSET (UniqueNames
, 1, "unique-names", 0),
574 BSET (SnapPin
, 1, "snap-pin", 0),
575 BSET (SaveLastCommand
, 0, "save-last-command", 0),
576 BSET (SaveInTMP
, 0, "save-in-tmp", 0),
577 BSET (AllDirectionLines
, 0, "all-direction-lines", 0),
578 BSET (ShowNumber
, 0, "show-number", 0),
579 BSET (ResetAfterElement
, 1, "reset-after-element", 0),
580 BSET (RingBellWhenFinished
, 0, "ring-bell-finished", 0),
583 REGISTER_ATTRIBUTES (main_attribute_list
)
584 /* ----------------------------------------------------------------------
585 * post-process settings.
587 static void settings_post_process ()
591 if (Settings
.LibraryCommand
[0] != PCB_DIR_SEPARATOR_C
&& Settings
.LibraryCommand
[0] != '.')
593 Settings
.LibraryCommand
595 Concat (Settings
.LibraryCommandDir
, PCB_DIR_SEPARATOR_S
,
596 Settings
.LibraryCommand
,
599 if (Settings
.LibraryContentsCommand
[0] != PCB_DIR_SEPARATOR_C
600 && Settings
.LibraryContentsCommand
[0] != '.')
602 Settings
.LibraryContentsCommand
604 Concat (Settings
.LibraryCommandDir
, PCB_DIR_SEPARATOR_S
,
605 Settings
.LibraryContentsCommand
, NULL
);
608 if (Settings
.LineThickness
> MAX_LINESIZE
609 || Settings
.LineThickness
< MIN_LINESIZE
)
610 Settings
.LineThickness
= 1000;
612 if (Settings
.ViaThickness
> MAX_PINORVIASIZE
613 || Settings
.ViaThickness
< MIN_PINORVIASIZE
)
614 Settings
.ViaThickness
= 4000;
616 if (Settings
.ViaDrillingHole
<= 0)
617 Settings
.ViaDrillingHole
=
618 DEFAULT_DRILLINGHOLE
* Settings
.ViaThickness
/ 100;
620 Settings
.MaxWidth
= MIN (MAX_COORD
, MAX (Settings
.MaxWidth
, MIN_SIZE
));
621 Settings
.MaxHeight
= MIN (MAX_COORD
, MAX (Settings
.MaxHeight
, MIN_SIZE
));
623 ParseRouteString (Settings
.Routes
, &Settings
.RouteStyle
[0], 1);
626 * Make sure we have settings for some various programs we may wish
629 if (Settings
.MakeProgram
== NULL
) {
630 tmps
= getenv ("PCB_MAKE_PROGRAM");
632 Settings
.MakeProgram
= strdup (tmps
);
634 if (Settings
.MakeProgram
== NULL
) {
635 Settings
.MakeProgram
= strdup ("make");
638 if (Settings
.GnetlistProgram
== NULL
) {
639 tmps
= getenv ("PCB_GNETLIST");
641 Settings
.GnetlistProgram
= strdup (tmps
);
643 if (Settings
.GnetlistProgram
== NULL
) {
644 Settings
.GnetlistProgram
= strdup ("gnetlist");
650 /* ----------------------------------------------------------------------
651 * Print help or version messages.
657 printf ("PCB version %s\n", VERSION
);
661 /* ----------------------------------------------------------------------
662 * Figure out the canonical name of the executed program
663 * and fix up the defaults for various paths
666 char *exec_prefix
= NULL
;
667 char *pcblibdir
= NULL
;
668 char *pcblibpath
= NULL
;
669 char *pcbtreedir
= NULL
;
670 char *pcbtreepath
= NULL
;
671 char *homedir
= NULL
;
674 InitPaths (char *argv0
)
680 int found_bindir
= 0;
682 /* see if argv0 has enough of a path to let lrealpath give the
683 * real path. This should be the case if you invoke pcb with
684 * something like /usr/local/bin/pcb or ./pcb or ./foo/pcb
685 * but if you just use pcb and it exists in your path, you'll
686 * just get back pcb again.
690 for (i
= 0; i
< strlen (argv0
) ; i
++)
692 if (argv0
[i
] == PCB_DIR_SEPARATOR_C
)
697 printf ("InitPaths (%s): haspath = %d\n", argv0
, haspath
);
702 bindir
= strdup (lrealpath (argv0
));
707 char *path
, *p
, *tmps
;
711 tmps
= getenv ("PATH");
715 path
= strdup (tmps
);
717 /* search through the font path for a font file */
718 for (p
= strtok (path
, PCB_PATH_DELIMETER
); p
&& *p
;
719 p
= strtok (NULL
, PCB_PATH_DELIMETER
))
722 printf ("Looking for %s in %s\n", argv0
, p
);
724 if ( (tmps
= malloc ( (strlen (argv0
) + strlen (p
) + 2) * sizeof (char))) == NULL
)
726 fprintf (stderr
, "InitPaths(): malloc failed\n");
729 sprintf (tmps
, "%s%s%s", p
, PCB_DIR_SEPARATOR_S
, argv0
);
730 r
= stat (tmps
, &sb
);
734 printf ("Found it: \"%s\"\n", tmps
);
736 bindir
= lrealpath (tmps
);
748 printf ("InitPaths(): bindir = \"%s\"\n", bindir
);
753 /* strip off the executible name leaving only the path */
755 t1
= strchr (bindir
, PCB_DIR_SEPARATOR_C
);
756 while (t1
!= NULL
&& *t1
!= '\0')
759 t1
= strchr (t2
+ 1, PCB_DIR_SEPARATOR_C
);
765 printf ("After stripping off the executible name, we found\n");
766 printf ("bindir = \"%s\"\n", bindir
);
771 /* we have failed to find out anything from argv[0] so fall back to the original
774 bindir
= strdup (BINDIR
);
777 /* now find the path to exec_prefix */
778 l
= strlen (bindir
) + 1 + strlen (BINDIR_TO_EXECPREFIX
) + 1;
779 if ( (exec_prefix
= (char *) malloc (l
* sizeof (char) )) == NULL
)
781 fprintf (stderr
, "InitPaths(): malloc failed\n");
784 sprintf (exec_prefix
, "%s%s%s", bindir
, PCB_DIR_SEPARATOR_S
,
785 BINDIR_TO_EXECPREFIX
);
787 /* now find the path to PCBLIBDIR */
788 l
= strlen (bindir
) + 1 + strlen (BINDIR_TO_PCBLIBDIR
) + 1;
789 if ( (pcblibdir
= (char *) malloc (l
* sizeof (char) )) == NULL
)
791 fprintf (stderr
, "InitPaths(): malloc failed\n");
794 sprintf (pcblibdir
, "%s%s%s", bindir
, PCB_DIR_SEPARATOR_S
,
795 BINDIR_TO_PCBLIBDIR
);
797 /* and the path to PCBTREEDIR */
798 l
= strlen (bindir
) + 1 + strlen (BINDIR_TO_PCBTREEDIR
) + 1;
799 if ( (pcbtreedir
= (char *) malloc (l
* sizeof (char) )) == NULL
)
801 fprintf (stderr
, "InitPaths(): malloc failed\n");
804 sprintf (pcbtreedir
, "%s%s%s", bindir
, PCB_DIR_SEPARATOR_S
,
805 BINDIR_TO_PCBTREEDIR
);
807 /* and the search path including PCBLIBDIR */
808 l
= strlen (pcblibdir
) + 3;
809 if ( (pcblibpath
= (char *) malloc (l
* sizeof (char) )) == NULL
)
811 fprintf (stderr
, "InitPaths(): malloc failed\n");
814 sprintf (pcblibpath
, ".%s%s", PCB_PATH_DELIMETER
, pcblibdir
);
816 /* and the newlib search path */
817 l
= strlen (pcblibdir
) + 1 + strlen (pcbtreedir
)
818 + strlen ("pcblib-newlib") + 2;
819 if ( (pcbtreepath
= (char *) malloc (l
* sizeof (char) )) == NULL
)
821 fprintf (stderr
, "InitPaths(): malloc failed\n");
824 sprintf (pcbtreepath
, "%s%s%s%spcblib-newlib", pcbtreedir
,
825 PCB_PATH_DELIMETER
, pcblibdir
,
826 PCB_DIR_SEPARATOR_S
);
829 printf ("bindir = %s\n", bindir
);
830 printf ("pcblibdir = %s\n", pcblibdir
);
831 printf ("pcblibpath = %s\n", pcblibpath
);
832 printf ("pcbtreedir = %s\n", pcbtreedir
);
833 printf ("pcbtreepath = %s\n", pcbtreepath
);
836 l
= sizeof (main_attribute_list
) / sizeof (main_attribute_list
[0]);
837 for (i
= 0; i
< l
; i
++)
839 if (NSTRCMP (main_attribute_list
[i
].name
, "lib-command-dir") == 0)
841 main_attribute_list
[i
].default_val
.str_value
= pcblibdir
;
844 if ( (NSTRCMP (main_attribute_list
[i
].name
, "font-path") == 0)
845 || (NSTRCMP (main_attribute_list
[i
].name
, "element-path") == 0)
846 || (NSTRCMP (main_attribute_list
[i
].name
, "lib-path") == 0) )
848 main_attribute_list
[i
].default_val
.str_value
= pcblibpath
;
851 if (NSTRCMP (main_attribute_list
[i
].name
, "lib-newlib") == 0)
853 main_attribute_list
[i
].default_val
.str_value
= pcbtreepath
;
861 tmps
= getenv ("HOME");
864 tmps
= getenv ("USERPROFILE");
868 homedir
= strdup (tmps
);
876 /* ----------------------------------------------------------------------
880 char *program_name
= 0;
881 char *program_basename
= 0;
882 char *program_directory
= 0;
887 main (int argc
, char *argv
[])
892 * - make program name available for error handlers
893 * - evaluate special options
894 * - initialize toplevel shell and resources
895 * - create an empty PCB with default symbols
896 * - initialize all other widgets
897 * - update screen and get size of drawing area
898 * - evaluate command-line arguments
899 * - register 'call on exit()' function
902 #include "core_lists.h"
906 bindtextdomain (GETTEXT_PACKAGE
, LOCALEDIR
);
907 bind_textdomain_codeset(GETTEXT_PACKAGE
, "UTF-8");
911 hid_load_settings ();
913 program_name
= argv
[0];
914 program_basename
= strrchr (program_name
, PCB_DIR_SEPARATOR_C
);
915 if (program_basename
)
917 program_directory
= strdup (program_name
);
918 *strrchr (program_directory
, PCB_DIR_SEPARATOR_C
) = 0;
923 program_directory
= ".";
924 program_basename
= program_name
;
926 Progname
= program_basename
;
928 /* Print usage or version if requested. Then exit. */
929 if (argc
> 1 && strcmp (argv
[1], "-h") == 0)
931 if (argc
> 1 && strcmp (argv
[1], "-V") == 0)
933 /* Export pcb from command line if requested. */
934 if (argc
> 1 && strcmp (argv
[1], "-p") == 0)
936 exporter
= gui
= hid_find_printer ();
940 else if (argc
> 2 && strcmp (argv
[1], "-x") == 0)
942 exporter
= gui
= hid_find_exporter (argv
[2]);
946 /* Otherwise start GUI. */
948 gui
= hid_find_gui ();
950 /* Exit with error if GUI failed to start. */
955 for (i
= 0; i
< MAX_LAYER
; i
++)
958 sprintf (buf
, "signal%d", i
+ 1);
959 Settings
.DefaultLayerName
[i
] = strdup (buf
);
960 Settings
.LayerColor
[i
] = "#c49350";
961 Settings
.LayerSelectedColor
[i
] = "#00ffff";
964 gui
->parse_arguments (&argc
, &argv
);
966 if (show_help
|| (argc
> 1 && argv
[1][0] == '-'))
975 Output
.bgGC
= gui
->make_gc ();
976 Output
.fgGC
= gui
->make_gc ();
977 Output
.pmGC
= gui
->make_gc ();
978 Output
.GridGC
= gui
->make_gc ();
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
));