Index: scconfig/hooks.c =================================================================== --- scconfig/hooks.c (revision 1109) +++ scconfig/hooks.c (revision 1110) @@ -84,6 +84,10 @@ {"buildin-stroke", "/local/pcb/stroke/buildin", arg_true, "$static link libstroke gestures into the executable"}, {"plugin-stroke", "/local/pcb/stroke/buildin", arg_false, "$libstroke gestures is dynamic loadable plugin"}, + {"disable-import_sch", "/local/pcb/import_sch/enable", arg_false, "$do not compile the import schematics action"}, + {"buildin-import_sch", "/local/pcb/import_sch/buildin", arg_true, "$static link the import schematics action into the executable"}, + {"plugin-import_sch", "/local/pcb/import_sch/buildin", arg_false, "$the import schematics action is dynamic loadable plugin"}, + {NULL, NULL, NULL, NULL} }; @@ -188,6 +192,10 @@ put("/local/pcb/stroke/enable", sfalse); put("/local/pcb/stroke/buildin", strue); + db_mkdir("/local/pcb/import_sch"); + put("/local/pcb/import_sch/enable", strue); + put("/local/pcb/import_sch/buildin", strue); + return 0; } @@ -411,6 +419,7 @@ plugin_stat("Mincut: ", "/local/pcb/mincut"); plugin_stat("renumber:", "/local/pcb/renumber"); plugin_stat("old actions:", "/local/pcb/oldactions"); + plugin_stat("import_sch:", "/local/pcb/import_sch"); plugin_stat("stroke:", "/local/pcb/stroke"); Index: src/import_sch.c =================================================================== --- src/import_sch.c (revision 1109) +++ src/import_sch.c (nonexistent) @@ -1,427 +0,0 @@ -/* - * COPYRIGHT - * - * PCB, interactive printed circuit board design - * Copyright (C) 1994,1995,1996 Thomas Nau - * Copyright (C) 1997, 1998, 1999, 2000, 2001 Harry Eaton - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - * Contact addresses for paper mail and Email: - * Harry Eaton, 6697 Buttonhole Ct, Columbia, MD 21044, USA - * haceaton@aplcomm.jhuapl.edu - * - */ -#include "config.h" -#include "global.h" -#include "data.h" -#include "action.h" -#include "change.h" -#include "error.h" -#include "undo.h" - -#include "misc.h" -#include "portability.h" -#include "pcb-printf.h" -#include "remove.h" -#include "rats.h" - -/* ---------------------------------------------------------------- */ -static const char import_syntax[] = - "Import()\n" - "Import([gnetlist|make[,source,source,...]])\n" "Import(setnewpoint[,(mark|center|X,Y)])\n" "Import(setdisperse,D,units)\n"; - -static const char import_help[] = "Import schematics."; - -/* %start-doc actions Import - -Imports element and netlist data from the schematics (or some other -source). The first parameter, which is optional, is the mode. If not -specified, the @code{import::mode} attribute in the PCB is used. -@code{gnetlist} means gnetlist is used to obtain the information from -the schematics. @code{make} invokes @code{make}, assuming the user -has a @code{Makefile} in the current directory. The @code{Makefile} -will be invoked with the following variables set: - -@table @code - -@item PCB -The name of the .pcb file - -@item SRCLIST -A space-separated list of source files - -@item OUT -The name of the file in which to put the command script, which may -contain any @pcb{} actions. By default, this is a temporary file -selected by @pcb{}, but if you specify an @code{import::outfile} -attribute, that file name is used instead (and not automatically -deleted afterwards). - -@end table - -The target specified to be built is the first of these that apply: - -@itemize @bullet - -@item -The target specified by an @code{import::target} attribute. - -@item -The output file specified by an @code{import::outfile} attribute. - -@item -If nothing else is specified, the target is @code{pcb_import}. - -@end itemize - -If you specify an @code{import::makefile} attribute, then "-f " will be added to the command line. - -If you specify the mode, you may also specify the source files -(schematics). If you do not specify any, the list of schematics is -obtained by reading the @code{import::src@var{N}} attributes (like -@code{import::src0}, @code{import::src1}, etc). - -For compatibility with future extensions to the import file format, -the generated file @emph{must not} start with the two characters -@code{#%}. - -If a temporary file is needed the @code{TMPDIR} environment variable -is used to select its location. - -Note that the programs @code{gnetlist} and @code{make} may be -overridden by the user via the @code{make-program} and @code{gnetlist} -@code{pcb} settings (i.e. in @code{~/.pcb/settings} or on the command -line). - -If @pcb{} cannot determine which schematic(s) to import from, the GUI -is called to let user choose (see @code{ImportGUI()}). - -Note that Import() doesn't delete anything - after an Import, elements -which shouldn't be on the board are selected and may be removed once -it's determined that the deletion is appropriate. - -If @code{Import()} is called with @code{setnewpoint}, then the location -of new components can be specified. This is where parts show up when -they're added to the board. The default is the center of the board. - -@table @code - -@item Import(setnewpoint) - -Prompts the user to click on the board somewhere, uses that point. If -called by a hotkey, uses the current location of the crosshair. - -@item Import(setnewpoint,mark) - -Uses the location of the mark. If no mark is present, the point is -not changed. - -@item Import(setnewpoint,center) - -Resets the point to the center of the board. - -@item Import(setnewpoint,X,Y,units) - -Sets the point to the specific coordinates given. Example: -@code{Import(setnewpoint,50,25,mm)} - -@end table - -Note that the X and Y locations are stored in attributes named -@code{import::newX} and @code{import::newY} so you could change them -manually if you wished. - -Calling @code{Import(setdisperse,D,units)} sets how much the newly -placed elements are dispersed relative to the set point. For example, -@code{Import(setdisperse,10,mm)} will offset each part randomly up to -10mm away from the point. The default dispersion is 1/10th of the -smallest board dimension. Dispersion is saved in the -@code{import::disperse} attribute. - -%end-doc */ - -static int ActionImport(int argc, char **argv, Coord x, Coord y) -{ - char *mode; - char **sources = NULL; - int nsources = 0; - -#ifdef DEBUG - printf("ActionImport: =========== Entering ActionImport ============\n"); -#endif - - mode = ARG(0); - - if (mode && strcasecmp(mode, "setdisperse") == 0) { - char *ds, *units; - char buf[50]; - - ds = ARG(1); - units = ARG(2); - if (!ds) { - const char *as = AttributeGet(PCB, "import::disperse"); - ds = gui->prompt_for(_("Enter dispersion:"), as ? as : "0"); - } - if (units) { - sprintf(buf, "%s%s", ds, units); - AttributePut(PCB, "import::disperse", buf); - } - else - AttributePut(PCB, "import::disperse", ds); - if (ARG(1) == NULL) - free(ds); - return 0; - } - - if (mode && strcasecmp(mode, "setnewpoint") == 0) { - const char *xs, *ys, *units; - Coord x, y; - char buf[50]; - - xs = ARG(1); - ys = ARG(2); - units = ARG(3); - - if (!xs) { - gui->get_coords(_("Click on a location"), &x, &y); - } - else if (strcasecmp(xs, "center") == 0) { - AttributeRemove(PCB, "import::newX"); - AttributeRemove(PCB, "import::newY"); - return 0; - } - else if (strcasecmp(xs, "mark") == 0) { - if (Marked.status) { - x = Marked.X; - y = Marked.Y; - } - } - else if (ys) { - x = GetValue(xs, units, NULL); - y = GetValue(ys, units, NULL); - } - else { - Message(_("Bad syntax for Import(setnewpoint)")); - return 1; - } - - pcb_sprintf(buf, "%$ms", x); - AttributePut(PCB, "import::newX", buf); - pcb_sprintf(buf, "%$ms", y); - AttributePut(PCB, "import::newY", buf); - return 0; - } - - if (!mode) - mode = AttributeGet(PCB, "import::mode"); - if (!mode) - mode = "gnetlist"; - - if (argc > 1) { - sources = argv + 1; - nsources = argc - 1; - } - - if (!sources) { - char sname[40]; - char *src; - - nsources = -1; - do { - nsources++; - sprintf(sname, "import::src%d", nsources); - src = AttributeGet(PCB, sname); - } while (src); - - if (nsources > 0) { - sources = (char **) malloc((nsources + 1) * sizeof(char *)); - nsources = -1; - do { - nsources++; - sprintf(sname, "import::src%d", nsources); - src = AttributeGet(PCB, sname); - sources[nsources] = src; - } while (src); - } - } - - if (!sources) { - /* Replace .pcb with .sch and hope for the best. */ - char *pcbname = PCB->Filename; - char *schname; - char *dot, *slash, *bslash; - - if (!pcbname) - return hid_action("ImportGUI"); - - schname = (char *) malloc(strlen(pcbname) + 5); - strcpy(schname, pcbname); - dot = strchr(schname, '.'); - slash = strchr(schname, '/'); - bslash = strchr(schname, '\\'); - if (dot && slash && dot < slash) - dot = NULL; - if (dot && bslash && dot < bslash) - dot = NULL; - if (dot) - *dot = 0; - strcat(schname, ".sch"); - - if (access(schname, F_OK)) - return hid_action("ImportGUI"); - - sources = (char **) malloc(2 * sizeof(char *)); - sources[0] = schname; - sources[1] = NULL; - nsources = 1; - } - - if (strcasecmp(mode, "gnetlist") == 0) { - char *tmpfile = tempfile_name_new("gnetlist_output"); - char **cmd; - int i; - - if (tmpfile == NULL) { - Message(_("Could not create temp file")); - return 1; - } - - cmd = (char **) malloc((7 + nsources) * sizeof(char *)); - cmd[0] = Settings.GnetlistProgram; - cmd[1] = "-g"; - cmd[2] = "pcbfwd"; - cmd[3] = "-o"; - cmd[4] = tmpfile; - cmd[5] = "--"; - for (i = 0; i < nsources; i++) - cmd[6 + i] = sources[i]; - cmd[6 + nsources] = NULL; - -#ifdef DEBUG - printf("ActionImport: =========== About to run gnetlist ============\n"); - printf("%s %s %s %s %s %s %s ...\n", cmd[0], cmd[1], cmd[2], cmd[3], cmd[4], cmd[5], cmd[6]); -#endif - - if (pcb_spawnvp(cmd)) { - unlink(tmpfile); - return 1; - } - -#ifdef DEBUG - printf("ActionImport: =========== About to run ActionExecuteFile, file = %s ============\n", tmpfile); -#endif - - cmd[0] = tmpfile; - cmd[1] = NULL; - ActionExecuteFile(1, cmd, 0, 0); - - free(cmd); - tempfile_unlink(tmpfile); - } - else if (strcasecmp(mode, "make") == 0) { - int must_free_tmpfile = 0; - char *tmpfile; - char *cmd[10]; - int i; - char *srclist; - int srclen; - char *user_outfile = NULL; - char *user_makefile = NULL; - char *user_target = NULL; - - - user_outfile = AttributeGet(PCB, "import::outfile"); - user_makefile = AttributeGet(PCB, "import::makefile"); - user_target = AttributeGet(PCB, "import::target"); - if (user_outfile && !user_target) - user_target = user_outfile; - - if (user_outfile) - tmpfile = user_outfile; - else { - tmpfile = tempfile_name_new("gnetlist_output"); - if (tmpfile == NULL) { - Message(_("Could not create temp file")); - return 1; - } - must_free_tmpfile = 1; - } - - srclen = sizeof("SRCLIST=") + 2; - for (i = 0; i < nsources; i++) - srclen += strlen(sources[i]) + 2; - srclist = (char *) malloc(srclen); - strcpy(srclist, "SRCLIST="); - for (i = 0; i < nsources; i++) { - if (i) - strcat(srclist, " "); - strcat(srclist, sources[i]); - } - - cmd[0] = Settings.MakeProgram; - cmd[1] = "-s"; - cmd[2] = Concat("PCB=", PCB->Filename, NULL); - cmd[3] = srclist; - cmd[4] = Concat("OUT=", tmpfile, NULL); - i = 5; - if (user_makefile) { - cmd[i++] = "-f"; - cmd[i++] = user_makefile; - } - cmd[i++] = user_target ? user_target : (char *) "pcb_import"; - cmd[i++] = NULL; - - if (pcb_spawnvp(cmd)) { - if (must_free_tmpfile) - unlink(tmpfile); - free(cmd[2]); - free(cmd[3]); - free(cmd[4]); - return 1; - } - - cmd[0] = tmpfile; - cmd[1] = NULL; - ActionExecuteFile(1, cmd, 0, 0); - - free(cmd[2]); - free(cmd[3]); - free(cmd[4]); - if (must_free_tmpfile) - tempfile_unlink(tmpfile); - } - else { - Message(_("Unknown import mode: %s\n"), mode); - return 1; - } - - DeleteRats(false); - AddAllRats(false, NULL); - -#ifdef DEBUG - printf("ActionImport: =========== Leaving ActionImport ============\n"); -#endif - - return 0; -} - -HID_Action import_sch_action_list[] = { - {"Import", 0, ActionImport, - import_help, import_syntax} -}; - -REGISTER_ACTIONS(import_sch_action_list) Index: src/Makefile.in =================================================================== --- src/Makefile.in (revision 1109) +++ src/Makefile.in (revision 1110) @@ -36,7 +36,6 @@ free_atexit.o gui_act.o heap.o - import_sch.o insert.o intersect.o line.o @@ -103,7 +102,7 @@ # main: action registrations put /local/pcb/ACTION_REG_SRC { action.c buffer.c change_act.c command.c file_act.c find_act.c - flags.c gui_act.c import_sch.c main.c misc.c move.c netlist.c + flags.c gui_act.c main.c misc.c move.c netlist.c object_act.c plugins.c polygon_act.c rats_act.c rats_patch.c remove_act.c report.c select_act.c undo_act.c } @@ -146,6 +145,7 @@ include {../src_plugins/oldactions/Plug.tmpasm} include {../src_plugins/renumber/Plug.tmpasm} include {../src_plugins/stroke/Plug.tmpasm} +include {../src_plugins/import_sch/Plug.tmpasm} append /local/pcb/CFLAGS /target/libs/sul/glib/cflags append /local/pcb/LIBS /target/libs/sul/glib/ldflags Index: src/action_list.h =================================================================== --- src/action_list.h (revision 1109) +++ src/action_list.h (revision 1110) @@ -72,9 +72,6 @@ /* flags.c () */ REGISTER_FLAGS(flags_flag_list) -/* import_sch.c () */ -REGISTER_ACTIONS(import_sch_action_list) - /* buffer.c () */ REGISTER_ACTIONS(buffer_action_list) Index: src_plugins/import_sch/import_sch.c =================================================================== --- src_plugins/import_sch/import_sch.c (nonexistent) +++ src_plugins/import_sch/import_sch.c (revision 1110) @@ -0,0 +1,433 @@ +/* + * COPYRIGHT + * + * PCB, interactive printed circuit board design + * Copyright (C) 1994,1995,1996 Thomas Nau + * Copyright (C) 1997, 1998, 1999, 2000, 2001 Harry Eaton + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact addresses for paper mail and Email: + * Harry Eaton, 6697 Buttonhole Ct, Columbia, MD 21044, USA + * haceaton@aplcomm.jhuapl.edu + * + */ +#include "config.h" +#include "global.h" +#include "data.h" +#include "action.h" +#include "change.h" +#include "error.h" +#include "undo.h" + +#include "misc.h" +#include "portability.h" +#include "pcb-printf.h" +#include "remove.h" +#include "rats.h" + +/* ---------------------------------------------------------------- */ +static const char import_syntax[] = + "Import()\n" + "Import([gnetlist|make[,source,source,...]])\n" "Import(setnewpoint[,(mark|center|X,Y)])\n" "Import(setdisperse,D,units)\n"; + +static const char import_help[] = "Import schematics."; + +/* %start-doc actions Import + +Imports element and netlist data from the schematics (or some other +source). The first parameter, which is optional, is the mode. If not +specified, the @code{import::mode} attribute in the PCB is used. +@code{gnetlist} means gnetlist is used to obtain the information from +the schematics. @code{make} invokes @code{make}, assuming the user +has a @code{Makefile} in the current directory. The @code{Makefile} +will be invoked with the following variables set: + +@table @code + +@item PCB +The name of the .pcb file + +@item SRCLIST +A space-separated list of source files + +@item OUT +The name of the file in which to put the command script, which may +contain any @pcb{} actions. By default, this is a temporary file +selected by @pcb{}, but if you specify an @code{import::outfile} +attribute, that file name is used instead (and not automatically +deleted afterwards). + +@end table + +The target specified to be built is the first of these that apply: + +@itemize @bullet + +@item +The target specified by an @code{import::target} attribute. + +@item +The output file specified by an @code{import::outfile} attribute. + +@item +If nothing else is specified, the target is @code{pcb_import}. + +@end itemize + +If you specify an @code{import::makefile} attribute, then "-f " will be added to the command line. + +If you specify the mode, you may also specify the source files +(schematics). If you do not specify any, the list of schematics is +obtained by reading the @code{import::src@var{N}} attributes (like +@code{import::src0}, @code{import::src1}, etc). + +For compatibility with future extensions to the import file format, +the generated file @emph{must not} start with the two characters +@code{#%}. + +If a temporary file is needed the @code{TMPDIR} environment variable +is used to select its location. + +Note that the programs @code{gnetlist} and @code{make} may be +overridden by the user via the @code{make-program} and @code{gnetlist} +@code{pcb} settings (i.e. in @code{~/.pcb/settings} or on the command +line). + +If @pcb{} cannot determine which schematic(s) to import from, the GUI +is called to let user choose (see @code{ImportGUI()}). + +Note that Import() doesn't delete anything - after an Import, elements +which shouldn't be on the board are selected and may be removed once +it's determined that the deletion is appropriate. + +If @code{Import()} is called with @code{setnewpoint}, then the location +of new components can be specified. This is where parts show up when +they're added to the board. The default is the center of the board. + +@table @code + +@item Import(setnewpoint) + +Prompts the user to click on the board somewhere, uses that point. If +called by a hotkey, uses the current location of the crosshair. + +@item Import(setnewpoint,mark) + +Uses the location of the mark. If no mark is present, the point is +not changed. + +@item Import(setnewpoint,center) + +Resets the point to the center of the board. + +@item Import(setnewpoint,X,Y,units) + +Sets the point to the specific coordinates given. Example: +@code{Import(setnewpoint,50,25,mm)} + +@end table + +Note that the X and Y locations are stored in attributes named +@code{import::newX} and @code{import::newY} so you could change them +manually if you wished. + +Calling @code{Import(setdisperse,D,units)} sets how much the newly +placed elements are dispersed relative to the set point. For example, +@code{Import(setdisperse,10,mm)} will offset each part randomly up to +10mm away from the point. The default dispersion is 1/10th of the +smallest board dimension. Dispersion is saved in the +@code{import::disperse} attribute. + +%end-doc */ + +static int ActionImport(int argc, char **argv, Coord x, Coord y) +{ + char *mode; + char **sources = NULL; + int nsources = 0; + +#ifdef DEBUG + printf("ActionImport: =========== Entering ActionImport ============\n"); +#endif + + mode = ARG(0); + + if (mode && strcasecmp(mode, "setdisperse") == 0) { + char *ds, *units; + char buf[50]; + + ds = ARG(1); + units = ARG(2); + if (!ds) { + const char *as = AttributeGet(PCB, "import::disperse"); + ds = gui->prompt_for(_("Enter dispersion:"), as ? as : "0"); + } + if (units) { + sprintf(buf, "%s%s", ds, units); + AttributePut(PCB, "import::disperse", buf); + } + else + AttributePut(PCB, "import::disperse", ds); + if (ARG(1) == NULL) + free(ds); + return 0; + } + + if (mode && strcasecmp(mode, "setnewpoint") == 0) { + const char *xs, *ys, *units; + Coord x, y; + char buf[50]; + + xs = ARG(1); + ys = ARG(2); + units = ARG(3); + + if (!xs) { + gui->get_coords(_("Click on a location"), &x, &y); + } + else if (strcasecmp(xs, "center") == 0) { + AttributeRemove(PCB, "import::newX"); + AttributeRemove(PCB, "import::newY"); + return 0; + } + else if (strcasecmp(xs, "mark") == 0) { + if (Marked.status) { + x = Marked.X; + y = Marked.Y; + } + } + else if (ys) { + x = GetValue(xs, units, NULL); + y = GetValue(ys, units, NULL); + } + else { + Message(_("Bad syntax for Import(setnewpoint)")); + return 1; + } + + pcb_sprintf(buf, "%$ms", x); + AttributePut(PCB, "import::newX", buf); + pcb_sprintf(buf, "%$ms", y); + AttributePut(PCB, "import::newY", buf); + return 0; + } + + if (!mode) + mode = AttributeGet(PCB, "import::mode"); + if (!mode) + mode = "gnetlist"; + + if (argc > 1) { + sources = argv + 1; + nsources = argc - 1; + } + + if (!sources) { + char sname[40]; + char *src; + + nsources = -1; + do { + nsources++; + sprintf(sname, "import::src%d", nsources); + src = AttributeGet(PCB, sname); + } while (src); + + if (nsources > 0) { + sources = (char **) malloc((nsources + 1) * sizeof(char *)); + nsources = -1; + do { + nsources++; + sprintf(sname, "import::src%d", nsources); + src = AttributeGet(PCB, sname); + sources[nsources] = src; + } while (src); + } + } + + if (!sources) { + /* Replace .pcb with .sch and hope for the best. */ + char *pcbname = PCB->Filename; + char *schname; + char *dot, *slash, *bslash; + + if (!pcbname) + return hid_action("ImportGUI"); + + schname = (char *) malloc(strlen(pcbname) + 5); + strcpy(schname, pcbname); + dot = strchr(schname, '.'); + slash = strchr(schname, '/'); + bslash = strchr(schname, '\\'); + if (dot && slash && dot < slash) + dot = NULL; + if (dot && bslash && dot < bslash) + dot = NULL; + if (dot) + *dot = 0; + strcat(schname, ".sch"); + + if (access(schname, F_OK)) + return hid_action("ImportGUI"); + + sources = (char **) malloc(2 * sizeof(char *)); + sources[0] = schname; + sources[1] = NULL; + nsources = 1; + } + + if (strcasecmp(mode, "gnetlist") == 0) { + char *tmpfile = tempfile_name_new("gnetlist_output"); + char **cmd; + int i; + + if (tmpfile == NULL) { + Message(_("Could not create temp file")); + return 1; + } + + cmd = (char **) malloc((7 + nsources) * sizeof(char *)); + cmd[0] = Settings.GnetlistProgram; + cmd[1] = "-g"; + cmd[2] = "pcbfwd"; + cmd[3] = "-o"; + cmd[4] = tmpfile; + cmd[5] = "--"; + for (i = 0; i < nsources; i++) + cmd[6 + i] = sources[i]; + cmd[6 + nsources] = NULL; + +#ifdef DEBUG + printf("ActionImport: =========== About to run gnetlist ============\n"); + printf("%s %s %s %s %s %s %s ...\n", cmd[0], cmd[1], cmd[2], cmd[3], cmd[4], cmd[5], cmd[6]); +#endif + + if (pcb_spawnvp(cmd)) { + unlink(tmpfile); + return 1; + } + +#ifdef DEBUG + printf("ActionImport: =========== About to run ActionExecuteFile, file = %s ============\n", tmpfile); +#endif + + cmd[0] = tmpfile; + cmd[1] = NULL; + ActionExecuteFile(1, cmd, 0, 0); + + free(cmd); + tempfile_unlink(tmpfile); + } + else if (strcasecmp(mode, "make") == 0) { + int must_free_tmpfile = 0; + char *tmpfile; + char *cmd[10]; + int i; + char *srclist; + int srclen; + char *user_outfile = NULL; + char *user_makefile = NULL; + char *user_target = NULL; + + + user_outfile = AttributeGet(PCB, "import::outfile"); + user_makefile = AttributeGet(PCB, "import::makefile"); + user_target = AttributeGet(PCB, "import::target"); + if (user_outfile && !user_target) + user_target = user_outfile; + + if (user_outfile) + tmpfile = user_outfile; + else { + tmpfile = tempfile_name_new("gnetlist_output"); + if (tmpfile == NULL) { + Message(_("Could not create temp file")); + return 1; + } + must_free_tmpfile = 1; + } + + srclen = sizeof("SRCLIST=") + 2; + for (i = 0; i < nsources; i++) + srclen += strlen(sources[i]) + 2; + srclist = (char *) malloc(srclen); + strcpy(srclist, "SRCLIST="); + for (i = 0; i < nsources; i++) { + if (i) + strcat(srclist, " "); + strcat(srclist, sources[i]); + } + + cmd[0] = Settings.MakeProgram; + cmd[1] = "-s"; + cmd[2] = Concat("PCB=", PCB->Filename, NULL); + cmd[3] = srclist; + cmd[4] = Concat("OUT=", tmpfile, NULL); + i = 5; + if (user_makefile) { + cmd[i++] = "-f"; + cmd[i++] = user_makefile; + } + cmd[i++] = user_target ? user_target : (char *) "pcb_import"; + cmd[i++] = NULL; + + if (pcb_spawnvp(cmd)) { + if (must_free_tmpfile) + unlink(tmpfile); + free(cmd[2]); + free(cmd[3]); + free(cmd[4]); + return 1; + } + + cmd[0] = tmpfile; + cmd[1] = NULL; + ActionExecuteFile(1, cmd, 0, 0); + + free(cmd[2]); + free(cmd[3]); + free(cmd[4]); + if (must_free_tmpfile) + tempfile_unlink(tmpfile); + } + else { + Message(_("Unknown import mode: %s\n"), mode); + return 1; + } + + DeleteRats(false); + AddAllRats(false, NULL); + +#ifdef DEBUG + printf("ActionImport: =========== Leaving ActionImport ============\n"); +#endif + + return 0; +} + +HID_Action import_sch_action_list[] = { + {"Import", 0, ActionImport, + import_help, import_syntax} +}; + +REGISTER_ACTIONS(import_sch_action_list) + +#include "dolists.h" +void hid_import_sch_init(void) +{ + REGISTER_ACTIONS(import_sch_action_list) +}