Index: trunk/scconfig/Rev.h =================================================================== --- trunk/scconfig/Rev.h (revision 37806) +++ trunk/scconfig/Rev.h (revision 37807) @@ -1 +1 @@ -static const int myrev = 36904; +static const int myrev = 37807; Index: trunk/scconfig/Rev.tab =================================================================== --- trunk/scconfig/Rev.tab (revision 37806) +++ trunk/scconfig/Rev.tab (revision 37807) @@ -1,3 +1,4 @@ +37807 configure gsch2pcb-rnd removal 36904 configure enable plugin the order and order_pcbway plugins 36851 configure order plugin: constraint language 36722 configure import_sch from sch-rnd Index: trunk/util/gsch2pcb-rnd/run.h =================================================================== --- trunk/util/gsch2pcb-rnd/run.h (revision 37806) +++ trunk/util/gsch2pcb-rnd/run.h (nonexistent) @@ -1,13 +0,0 @@ -/** - * Build and run a command. No redirection or error handling is - * done. Format string is split on whitespace. Specifiers %l and %s - * are replaced with contents of positional args. To be recognized, - * specifiers must be separated from other arguments in the format by - * whitespace. - * - %L expects a gadl_list_t vith char * payload, contents used as separate arguments - * - %s expects a char*, contents used as a single argument (omitted if NULL) - * @param[in] format used to specify command to be executed - * @param[in] ... positional parameters - */ -int build_and_run_command(const char * format_, ...); - Index: trunk/util/gsch2pcb-rnd/method_import.h =================================================================== --- trunk/util/gsch2pcb-rnd/method_import.h (revision 37806) +++ trunk/util/gsch2pcb-rnd/method_import.h (nonexistent) @@ -1 +0,0 @@ -void method_import_register(void); Index: trunk/util/gsch2pcb-rnd/netlister.h =================================================================== --- trunk/util/gsch2pcb-rnd/netlister.h (revision 37806) +++ trunk/util/gsch2pcb-rnd/netlister.h (nonexistent) @@ -1,11 +0,0 @@ -/* Run gnetlist to generate a netlist and a PCB board file. gnetlist - * has exit status of 0 even if it's given an invalid arg, so do some - * stat() hoops to decide if gnetlist successfully generated the PCB - * board file (only gnetlist >= 20030901 recognizes -m). - */ -int run_gnetlist(const char *pins_file, const char *net_file, const char *pcb_file, const char * basename, const gadl_list_t *largs); - - -/* Return the name of gnetlist that should be executed */ -const char *gnetlist_name(void); - Index: trunk/util/gsch2pcb-rnd/help.h =================================================================== --- trunk/util/gsch2pcb-rnd/help.h (revision 37806) +++ trunk/util/gsch2pcb-rnd/help.h (nonexistent) @@ -1 +0,0 @@ -void usage(void); Index: trunk/util/gsch2pcb-rnd/run.c =================================================================== --- trunk/util/gsch2pcb-rnd/run.c (revision 37806) +++ trunk/util/gsch2pcb-rnd/run.c (nonexistent) @@ -1,134 +0,0 @@ -/* gsch2pcb-rnd - * - * Original version: Bill Wilson billw@wt.net - * rnd-version: (C) 2015..2016, Tibor 'Igor2' Palinkas - * - * This program is free software which I release under the GNU General Public - * License. You may redistribute and/or modify this program under the terms - * of that 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. Version 2 is in the - * COPYRIGHT file in the top level directory of this distribution. - * - * To get a copy of the GNU General Puplic License, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include -#include -#include -#include -#include -#include "gsch2pcb.h" -#include -#include -#include -#include "gsch2pcb_rnd_conf.h" - - -int build_and_run_command(const char * format_, ...) -{ - va_list vargs; - int result = FALSE; - vts0_t args; - char *format, *s, *start; - - /* Translate the format string; args elements point to const char *'s - within a copy of the format string. The format string is copied so - that these parts can be terminated by overwriting whitepsace with \0 */ - va_start(vargs, format_); - format = rnd_strdup(format_); - vts0_init(&args); - for(s = start = format; *s != '\0'; s++) { - /* if word separator is reached, save the previous word */ - if (isspace(s[0])) { - if (start == s) { /* empty word - skip */ - start++; - continue; - } - *s = '\0'; - vts0_append(&args, start); - start = s+1; - continue; - } - - /* check if current word is a format */ - if ((s == start) && (s[0] == '%') && (s[1] != '\0') && ((s[2] == '\0') || isspace(s[2]))) { - switch(s[1]) { - case 'L': /* append contents of char * gadl_list_t */ - { - gadl_list_t *list = va_arg(vargs, gadl_list_t *); - gadl_iterator_t it; - char **s; - gadl_foreach(list, &it, s) { - vts0_append(&args, *s); - } - } - start = s+2; - s++; - continue; - case 's': - { - char *arg = va_arg(vargs, char *); - if (arg != NULL) - vts0_append(&args, arg); - start = s+2; - s++; - } - continue; - } - } - } - va_end(vargs); - - if (args.used > 0) { - int i, l; - char *cmd, *end, line[1024]; - FILE *f; - - l = 0; - for (i = 0; i < args.used; i++) - l += strlen(args.array[i]) + 3; - - end = cmd = malloc(l+1); - for (i = 0; i < args.used; i++) { - l = strlen(args.array[i]); - *end = '"'; end++; - memcpy(end, args.array[i], l); - end += l; - *end = '"'; end++; - *end = ' '; end++; - } - end--; - *end = '\0'; - - /* we have something in the list, build & call command */ - if (conf_g2pr.utils.gsch2pcb_rnd.verbose) { - printf("Running command:\n\t%s\n", cmd); - printf("%s", SEP_STRING); - } - - f = rnd_popen(NULL, cmd, "r"); - while(fgets(line, sizeof(line), f) != NULL) { - if (conf_g2pr.utils.gsch2pcb_rnd.verbose) - fputs(line, stdout); - } - - if (rnd_pclose(f) == 0) - result = TRUE; - else - fprintf(stderr, "Failed to execute external program\n"); - free(cmd); - - if (conf_g2pr.utils.gsch2pcb_rnd.verbose) - printf("\n%s", SEP_STRING); - } - - free(format); - vts0_uninit(&args); - return result; -} Index: trunk/util/gsch2pcb-rnd/method.h =================================================================== --- trunk/util/gsch2pcb-rnd/method.h (revision 37806) +++ trunk/util/gsch2pcb-rnd/method.h (nonexistent) @@ -1,16 +0,0 @@ -typedef struct method_s method_t; - -struct method_s { - const char *name; - const char *desc; - void (*init)(void); - void (*go)(void); - void (*uninit)(void); - int (*guess_out_name)(void); /* returns 1 if the output file of the format exists for the current project */ - int not_by_guess; /* if non-zero, never try to use this method automatically, guessing from file names or anything else */ - method_t *next; -}; - -extern method_t *methods; - -void method_register(method_t *fmt); Index: trunk/util/gsch2pcb-rnd/method_import.c =================================================================== --- trunk/util/gsch2pcb-rnd/method_import.c (revision 37806) +++ trunk/util/gsch2pcb-rnd/method_import.c (nonexistent) @@ -1,149 +0,0 @@ -/* gsch2pcb-rnd - * - * Original version: Bill Wilson billw@wt.net - * rnd-version: (C) 2015..2016,2020 Tibor 'Igor2' Palinkas - * - * This program is free software which I release under the GNU General Public - * License. You may redistribute and/or modify this program under the terms - * of that 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. Version 2 is in the - * COPYRIGHT file in the top level directory of this distribution. - * - * To get a copy of the GNU General Puplic License, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include -#include -#include -#include "config.h" -#include "gsch2pcb.h" -#include "gsch2pcb_rnd_conf.h" -#include "method_import.h" -#include "run.h" -#include "netlister.h" -#include "method.h" -#include -#include -#include -#include -#include - -char *cmd_file_name; -char *pcb_file_name; -char *net_file_name; - -static void method_import_init(void) -{ - pcb_file_name = rnd_concat(conf_g2pr.utils.gsch2pcb_rnd.sch_basename, ".pcb", NULL); - cmd_file_name = rnd_concat(conf_g2pr.utils.gsch2pcb_rnd.sch_basename, ".cmd", NULL); - net_file_name = rnd_concat(conf_g2pr.utils.gsch2pcb_rnd.sch_basename, ".net", NULL); - local_project_pcb_name = pcb_file_name; -} - -static void import_go(int sep_net) -{ - char *verbose_str = NULL; - const char *gnetlist, *backend; - - gnetlist = gnetlist_name(); - if (!conf_g2pr.utils.gsch2pcb_rnd.verbose) - verbose_str = "-q"; - - backend = sep_net ? "pcbrndfwd_elem" : "pcbrndfwd"; - require_gnetlist_backend(SCMDIR, backend); - if (!build_and_run_command("%s %s -L %s -g %s -o %s %L %L", gnetlist, verbose_str, PCBLIBDIR, backend, cmd_file_name, &extra_gnetlist_arg_list, &schematics)) { - fprintf(stderr, "Failed to run gnetlist with backend %s to generate the elements\n", backend); - exit(1); - } - - if (sep_net) { - if (!build_and_run_command("%s %s -L %s -g PCB -o %s %L %L", gnetlist, verbose_str, PCBLIBDIR, net_file_name, &extra_gnetlist_arg_list, &schematics)) { - fprintf(stderr, "Failed to run gnetlist net file\n"); - exit(1); - } - } - - if (conf_g2pr.utils.gsch2pcb_rnd.quiet_mode) - return; - - /* Tell user what to do next */ - printf("\nNext step:\n"); - printf("1. Run pcb-rnd on your board file (or on an empty board if it's the first time).\n"); - printf("2. From within pcb-rnd, enter\n\n"); - printf(" :ExecuteFile(%s)\n\n", cmd_file_name); - - if (sep_net) { - printf(" (this will update the elements)\n\n"); - printf("3. From within pcb-rnd, select \"File -> Load netlist file\" and select \n"); - printf(" %s to load the updated netlist.\n\n", net_file_name); - } - else - printf(" (this will update the elements and the netlist)\n\n"); -} - -static void method_import_go() -{ - import_go(0); -} - -static void method_import_sep_go() -{ - import_go(1); -} - - -static int method_import_guess_out_name(void) -{ - int res; - char *name; - - name = rnd_concat(conf_g2pr.utils.gsch2pcb_rnd.sch_basename, ".lht", NULL); - res = rnd_file_readable_(name); - free(name); - if (!res) { - name = rnd_concat(conf_g2pr.utils.gsch2pcb_rnd.sch_basename, ".pcb.lht", NULL); - res = rnd_file_readable_(name); - free(name); - } - return res; -} - -static void method_import_uninit(void) -{ - if (pcb_file_name != NULL) - free(pcb_file_name); - if (cmd_file_name != NULL) - free(cmd_file_name); - if (net_file_name != NULL) - free(net_file_name); -} - -static method_t method_import; -static method_t method_import_sep; - -void method_import_register(void) -{ - method_import.name = "import"; - method_import.desc = "import schematics (pure action script)"; - method_import.init = method_import_init; - method_import.go = method_import_go; - method_import.uninit = method_import_uninit; - method_import.guess_out_name = method_import_guess_out_name; - method_import.not_by_guess = 0; - method_register(&method_import); - - method_import_sep.name = "importsep"; - method_import_sep.desc = "import schematics (separate action script and netlist)"; - method_import_sep.init = method_import_init; - method_import_sep.go = method_import_sep_go; - method_import_sep.uninit = method_import_uninit; - method_import_sep.guess_out_name = method_import_guess_out_name; - method_import_sep.not_by_guess = 1; - method_register(&method_import_sep); -} Index: trunk/util/gsch2pcb-rnd/netlister.c =================================================================== --- trunk/util/gsch2pcb-rnd/netlister.c (revision 37806) +++ trunk/util/gsch2pcb-rnd/netlister.c (nonexistent) @@ -1,108 +0,0 @@ -/* gsch2pcb-rnd - * - * Original version: Bill Wilson billw@wt.net - * rnd-version: (C) 2015..2016, Tibor 'Igor2' Palinkas - * - * This program is free software which I release under the GNU General Public - * License. You may redistribute and/or modify this program under the terms - * of that 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. Version 2 is in the - * COPYRIGHT file in the top level directory of this distribution. - * - * To get a copy of the GNU General Puplic License, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "config.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "../config.h" -#include -#include "gsch2pcb_rnd_conf.h" -#include "gsch2pcb.h" -#include -#include "run.h" - -const char *gnetlist_name(void) -{ - const char *gnetlist; - /* Allow the user to specify a full path or a different name for - * the gnetlist command. Especially useful if multiple copies - * are installed at once. - */ - gnetlist = getenv("GNETLIST"); - if (gnetlist == NULL) - gnetlist = "gnetlist"; - return gnetlist; -} - -int run_gnetlist(const char *pins_file, const char *net_file, const char *pcb_file, const char * basename, const gadl_list_t *largs) -{ - struct stat st; - time_t mtime; - const char *gnetlist; - gadl_iterator_t it; - char **sp; - char *verbose_str = NULL; - - gnetlist = gnetlist_name(); - - if (!conf_g2pr.utils.gsch2pcb_rnd.verbose) - verbose_str = "-q"; - - - if (!build_and_run_command("%s %s -g pcbpins -o %s %L %L", gnetlist, verbose_str, pins_file, &extra_gnetlist_arg_list, largs)) - return FALSE; - - if (!build_and_run_command("%s %s -g PCB -o %s %L %L", gnetlist, verbose_str, net_file, &extra_gnetlist_arg_list, largs)) - return FALSE; - - mtime = (stat(pcb_file, &st) == 0) ? st.st_mtime : 0; - - require_gnetlist_backend(SCMDIR, "gsch2pcb-rnd"); - - if (!build_and_run_command("%s %s -L " SCMDIR " -g gsch2pcb-rnd -o %s %L %L", - gnetlist, verbose_str, pcb_file, &extra_gnetlist_arg_list, largs)) { - if (stat(pcb_file, &st) != 0 || mtime == st.st_mtime) { - fprintf(stderr, "gsch2pcb: gnetlist command failed, `%s' not updated\n", pcb_file); - return FALSE; - } - return FALSE; - } - - gadl_foreach(&extra_gnetlist_list, &it, sp) { - const char *s = *sp; - const char *s2 = strstr(s, " -o "); - char *out_file; - char *backend; - if (!s2) { - out_file = rnd_concat(basename, ".", s, NULL); - backend = rnd_strdup(s); - } - else { - out_file = rnd_strdup(s2 + 4); - backend = rnd_strndup(s, s2 - s); - } - - if (!build_and_run_command("%s %s -g %s -o %s %L %L", - gnetlist, verbose_str, backend, out_file, &extra_gnetlist_arg_list, largs)) - return FALSE; - free(out_file); - free(backend); - } - - return TRUE; -} Index: trunk/util/gsch2pcb-rnd/help.c =================================================================== --- trunk/util/gsch2pcb-rnd/help.c (revision 37806) +++ trunk/util/gsch2pcb-rnd/help.c (nonexistent) @@ -1,156 +0,0 @@ -/* gsch2pcb-rnd - * - * Original version: Bill Wilson billw@wt.net - * rnd-version: (C) 2015..2016, Tibor 'Igor2' Palinkas - * - * This program is free software which I release under the GNU General Public - * License. You may redistribute and/or modify this program under the terms - * of that 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. Version 2 is in the - * COPYRIGHT file in the top level directory of this distribution. - * - * To get a copy of the GNU General Puplic License, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - * Retrieved from the official git (2015.07.15) - - Behavior different from the original: - - use getenv() instead of g_getenv(): on windows this won't do recursive variable expansion - - use rnd-specific .scm - - use rnd_popen() instead of glib's spawn (stderr is always printed to stderr) - */ -#include "config.h" -#include "method.h" -#include -#include - - -extern char *pcb_file_name, *pcb_new_file_name, *bak_file_name, *pins_file_name, *net_file_name; - -static char *usage_string0a = - "usage: gsch2pcb-rnd [options] {project | foo.sch [foo1.sch ...]}\n" - "\n" - "Generate a PCB annotation file from a set of gschem schematics.\n" - " gnetlist -g PCB is run to generate foo.net from the schematics.\n" "\n"; -/* TODO */ -/* " gnetlist -g gsch2pcb is run to get PCB elements which\n" - " match schematic footprints. For schematic footprints which don't match\n" - " any PCB layout elements, search a set of file element directories in\n" - " an attempt to find matching PCB file elements.\n"*/ -static char *usage_string0b = - " Output to foo.cmd if it doesn't exist.\n" - " The annotation command file (to be run by the user from pcb-rnd) contains:.\n" - " If any elements with a non-empty element name on the board\n" - " have no matching schematic component, then remove those elements from\n" - " the board unless it's marked nonetlist. Load and palce the footprints\n" - " for new elements; replace elements in-place if their footprint changed;" - " update attributes, value and other metadata in-place." - "\n"; -static char *usage_string0c = - " gnetlist -g pcbpins is run to get a PCB actions file which will rename all\n" - " of the pins in a .pcb file to match pin names from the schematic.\n" - "\n" - " \"project\" is a file (not ending in .sch) containing a list of\n" - " schematics to process and some options. A schematics line is like:\n" - " schematics foo1.sch foo2.sch ...\n" - " Options in a project file are like command line args without the \"-\":\n" - " output-name myproject\n" - "\n" - "options (may be included in a project file):\n"; -static char *usage_string0d = - " -d, --elements-dir D Search D for PCB file elements. These defaults\n" - " are searched if they exist. See the default\n" - " search paths at the end of this text." - " -c, --elements-dir-clr Clear the elements dir. Useful before a series\n" - " if -d's to flush defaults.\n" - " -m, --method M Use method M for the import. See available\n" - " methods below.\n"; -static char *usage_string0e = - " -s, --elements-shell S Use S as a prefix for running parametric footrint\n" - " generators. It is useful on systems where popen()\n" - " doesn't do the right thing or the process should\n" - " be wrapped. Example -s \"/bin/sh -c\"\n" - " -P, --default-pcb Change the default PCB file's name; this file is\n" - " inserted on top of the *.new.pcb generated, for\n" - " PCB default settings\n"; -static char *usage_string0f = - " -o, --output-name N Use output file names N.net, N.pcb, and N.new.pcb\n" - " instead of foo.net, ... where foo is the basename\n" - " of the first command line .sch file.\n" - " -r, --remove-unfound Don't include references to unfound elements in\n" - " the generated .pcb files. Use if you want PCB to\n" - " be able to load the (incomplete) .pcb file.\n" - " This is the default behavior.\n"; -static char *usage_string0g = - " -k, --keep-unfound Keep include references to unfound elements in\n" - " the generated .pcb files. Use if you want to hand\n" - " edit or otherwise preprocess the generated .pcb file\n" - " before running pcb.\n"; -static char *usage_string0h = - " -p, --preserve Preserve elements in PCB files which are not found\n" - " in the schematics. Note that elements with an empty\n" - " element name (schematic refdes) are never deleted,\n" - " so you really shouldn't need this option.\n"; -static char *usage_string0i = - " -q, --quiet Don't tell the user what to do next after running\n" - " gsch2pcb-rnd.\n" "\n"; - -static char *usage_string1a = - " --gnetlist backend A convenience run of extra gnetlist -g commands.\n" - " Example: gnetlist partslist3\n" - " Creates: myproject.partslist3\n" - " --empty-footprint name See the project.sample file.\n" - "\n"; -static char *usage_string1b = - "options (not recognized in a project file):\n" - " --gnetlist-arg arg Allows additional arguments to be passed to gnetlist.\n" - " --fix-elements If a schematic component footprint is not equal\n" - " to its PCB element Description, update the\n" - " Description instead of replacing the element.\n" - " Do this the first time gsch2pcb-rnd is used with\n" - " PCB files originally created with gschem2pcb.\n"; -static char *usage_string1c = - " -v, --verbose Use -v -v for additional file element debugging.\n" - " -V, --version\n\n" - "environment variables:\n" - " GNETLIST If set, this specifies the name of the gnetlist program\n" - " to execute.\n" - "\n"; - -static char *usage_string_foot = - "Additional Resources:\n" - "\n" - " pcb-rnd homepage: http://repo.hu/projects/pcb-rnd\n" - " gnetlist user guide: http://wiki.geda-project.org/geda:gnetlist_ug\n" - " gEDA homepage: http://www.geda-project.org\n" - "\n"; - - -void usage(void) -{ - method_t *m; - printf("%s", usage_string0a); - printf("%s", usage_string0b); - printf("%s", usage_string0c); - printf("%s", usage_string0d); - printf("%s", usage_string0e); - printf("%s", usage_string0f); - printf("%s", usage_string0g); - printf("%s", usage_string0h); - printf("%s", usage_string0i); - printf("%s", usage_string1a); - printf("%s", usage_string1b); - printf("%s", usage_string1c); - - printf("\nMethods available:\n"); - for(m = methods; m != NULL; m = m->next) - printf(" %-12s %s\n", m->name, m->desc); - printf("\n"); - printf("%s", usage_string_foot); - exit(0); -} Index: trunk/util/gsch2pcb-rnd/Makefile.in =================================================================== --- trunk/util/gsch2pcb-rnd/Makefile.in (revision 37806) +++ trunk/util/gsch2pcb-rnd/Makefile.in (revision 37807) @@ -42,11 +42,7 @@ FP_LDFLAGS = @/local/rnd/LDFLAGS@ FP_CFLAGS = @/local/rnd/CFLAGS@ OBJS = \ - gsch2pcb.o \ - help.o \ - netlister.o \ - run.o \ - method_import.o + gsch2pcb.o all: $(MAKE) revcheck Index: trunk/util/gsch2pcb-rnd/gsch2pcb.c =================================================================== --- trunk/util/gsch2pcb-rnd/gsch2pcb.c (revision 37806) +++ trunk/util/gsch2pcb-rnd/gsch2pcb.c (revision 37807) @@ -1,502 +1,47 @@ -/* gsch2pcb-rnd - * - * Original version: Bill Wilson billw@wt.net - * rnd-version: (C) 2015..2016,2020,2021 Tibor 'Igor2' Palinkas - * - * This program is free software which I release under the GNU General Public - * License. You may redistribute and/or modify this program under the terms - * of that 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. Version 2 is in the - * COPYRIGHT file in the top level directory of this distribution. - * - * To get a copy of the GNU General Puplic License, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - * Retrieved from the official git (2015.07.15) - - Behavior different from the original: - - use getenv() instead of g_getenv(): on windows this won't do recursive variable expansion - - use rnd-specific .scm - - use pcb-rnd's conf system - - use rnd_popen() instead of glib's spawn (stderr is always printed to stderr) - */ - -#include "config.h" - -#define LOCAL_PROJECT_FILE "project.lht" - #include -#include -#include -#include -#include -#include -#include "../src_3rd/qparse/qparse.h" -#include "../config.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include "method.h" -#include "help.h" -#include "gsch2pcb_rnd_conf.h" -#include "gsch2pcb.h" -#include "method_import.h" -static const char *want_method_default = "import"; +#define NL "\n" -#define CONF_USER_DIR "~/.gsch2pcb-rnd" +static const char *oops[] = { + NL, NL, NL, + NL "gsch2pcb-rnd has been deprecated and removed from pcb-rnd.", + NL "If you see this message:", + NL, + NL "1. Please consider switching to the import schematics workflow, using", + NL " the lepton or the gnetlist (for gschem) format; see file menu, import,", + NL " import schematics submenu. For the GUI usage, see first half of:", + NL " http://repo.hu/cgi-bin/pool.cgi?project=pcb-rnd&cmd=show&node=isch_switch", + NL, + NL "2. If you are using gsch2pcb-rnd from a shell script or Makefile:", + NL " import schematics can be automated too, no GUI involved. See second", + NL " half of:", + NL " http://repo.hu/cgi-bin/pool.cgi?project=pcb-rnd&cmd=show&node=isch_switch", + NL, + NL "3. Alternatively: get lepton-netlist or gnetlist to export a tEDAx", + NL " netlist (both supports this format natively for years already) and", + NL " load that in pcb-rnd (either from GUI or calling pcb-rnd with --hid batch", + NL " and using a few commands from stdin)", + NL, + NL "4. If none of the above worked for some reason, please contact the", + NL " developers to get free help/support with the switchover:", + NL " - use the \"HELP on-line support\" button (blue, top right in pcb-rnd)", + NL " - send a mail to the mailing list", + NL " - send a mail to the lead developer: http://igor2.repo.hu/contact.html", + NL, + NL "5. If that failed too, you can install the latest, unmaintained version", + NL " of gsch2pcb-rnd from source: http://www.repo.hu/projects/gsch2pcb-rnd", + NL, + NL "You may also be interested in sch-rnd: http://www.repo.hu/projects/sch-rnd", + NL "which is the schematics editor of Ringdove, very similar to pcb-rnd and" + NL "can fully replace lepton-eda or gschem." + NL, NL, NL, + NULL + }; - -gdl_list_t pcb_element_list; /* initialized to 0 */ -gadl_list_t schematics, extra_gnetlist_arg_list, extra_gnetlist_list; - -int n_deleted, n_added_ef, n_fixed, n_PKG_removed_new, - n_PKG_removed_old, n_preserved, n_changed_value, n_not_found, - n_unknown, n_none, n_empty; - -int bak_done, need_PKG_purge; - -conf_gsch2pcb_rnd_t conf_g2pr; - -method_t *methods = NULL, *current_method; - -void method_register(method_t *method) +int main(int argc, char *argv[]) { - method->next = methods; - methods = method; -} - -method_t *method_find(const char *name) -{ - method_t *m; - for(m = methods; m != NULL; m = m->next) - if (strcmp(m->name, name) == 0) - return m; - return NULL; -} - -/* Return a pointer to the suffix if inp ends in that suffix */ -static const char *loc_str_has_suffix(const char *inp, const char *suffix, int suff_len) -{ - int len = strlen(inp); - if ((len >= suff_len) && (strcmp(inp + len - suff_len, suffix) == 0)) - return inp + len - suff_len; - return NULL; -} - -char *fix_spaces(char * str) -{ - char *s; - - if (!str) - return NULL; - for (s = str; *s; ++s) - if (*s == ' ' || *s == '\t') - *s = '_'; - return str; -} - -static void add_schematic(const char *sch) -{ - char **n; - n = gadl_new(&schematics); - *n = rnd_strdup(sch); - gadl_append(&schematics, n); - if (!conf_g2pr.utils.gsch2pcb_rnd.sch_basename) { - const char *suff = loc_str_has_suffix(sch, ".sch", 4); - if (suff != NULL) { - char *tmp = rnd_strndup(sch, suff - sch); - rnd_conf_set(RND_CFR_CLI, "utils/gsch2pcb_rnd/sch_basename", -1, tmp, RND_POL_OVERWRITE); - free(tmp); - } - } -} - -static void add_multiple_schematics(const char * sch) -{ - /* parse the string using shell semantics */ - int count; - char **args; - char *tmp = rnd_strdup(sch); - - count = qparse(tmp, &args); - free(tmp); - if (count > 0) { - int i; - for (i = 0; i < count; ++i) - if (*args[i] != '\0') - add_schematic(args[i]); - qparse_free(count, &args); - } - else { - fprintf(stderr, "invalid `schematics' option: %s\n", sch); - } -} - -static int parse_config(char * config, char * arg) -{ - char *s; - - /* remove trailing white space otherwise strange things can happen */ - if ((arg != NULL) && (strlen(arg) >= 1)) { - s = arg + strlen(arg) - 1; - while ((*s == ' ' || *s == '\t') && (s != arg)) - s--; - s++; - *s = '\0'; - } - if (conf_g2pr.utils.gsch2pcb_rnd.verbose) - printf(" %s \"%s\"\n", config, arg ? arg : ""); - - if (!strcmp(config, "remove-unfound") || !strcmp(config, "r")) { - /* This is default behavior set in header section */ - rnd_conf_set(RND_CFR_CLI, "utils/gsch2pcb_rnd/remove_unfound_elements", -1, "1", RND_POL_OVERWRITE); - return 0; - } - if (!strcmp(config, "keep-unfound") || !strcmp(config, "k")) { - rnd_conf_set(RND_CFR_CLI, "utils/gsch2pcb_rnd/remove_unfound_elements", -1, "0", RND_POL_OVERWRITE); - return 0; - } - if (!strcmp(config, "quiet") || !strcmp(config, "q")) { - rnd_conf_set(RND_CFR_CLI, "utils/gsch2pcb_rnd/quiet_mode", -1, "1", RND_POL_OVERWRITE); - return 0; - } - if (!strcmp(config, "preserve") || !strcmp(config, "p")) { - rnd_conf_set(RND_CFR_CLI, "utils/gsch2pcb_rnd/preserve", -1, "1", RND_POL_OVERWRITE); - return 0; - } - if (!strcmp(config, "elements-shell") || !strcmp(config, "s")) - rnd_conf_set(RND_CFR_CLI, "rc/library_shell", -1, arg, RND_POL_OVERWRITE); - else if (!strcmp(config, "elements-dir") || !strcmp(config, "d")) { - static int warned = 0; - if (!warned) { - rnd_message(RND_MSG_WARNING, "ERROR: ignoring elements-dir from %s\n", config); - warned = 1; - } - } - else if (!strcmp(config, "output-name") || !strcmp(config, "o")) - rnd_conf_set(RND_CFR_CLI, "utils/gsch2pcb_rnd/sch_basename", -1, arg, RND_POL_OVERWRITE); - else if (!strcmp(config, "default-pcb") || !strcmp(config, "P")) - rnd_conf_set(RND_CFR_CLI, "utils/gsch2pcb_rnd/default_pcb", -1, arg, RND_POL_OVERWRITE); - else if (!strcmp(config, "schematics")) - add_multiple_schematics(arg); - else if (!strcmp(config, "gnetlist")) { - char **n; - n = gadl_new(&extra_gnetlist_list); - *n = rnd_strdup(arg); - gadl_append(&extra_gnetlist_list, n); - } - else if (!strcmp(config, "empty-footprint")) - rnd_conf_set(RND_CFR_CLI, "utils/gsch2pcb_rnd/empty_footprint_name", -1, arg, RND_POL_OVERWRITE); - else - return -1; - + const char **s; + for(s = oops; *s != NULL; s++) + fputs(*s, stderr); return 1; } - -static void load_project(char * path) -{ - FILE *f; - char *s, buf[1024], config[32], arg[768]; - int n; - - f = rnd_fopen(NULL, path, "r"); - if (!f) - return; - - /* check if we have a lihata project file or config file by looking at the first 16 non-comments */ - for(n = 0; n < 16;) { - if (fgets(buf, sizeof(buf), f) == NULL) - break; - s = buf; - while(isspace(*s)) s++; - if ((*s == '#') || (*s == '\r') || (*s == '\n') || (*s == '\0')) - continue; - /* look for known lihata roots */ - if (strncmp(s, "ha:geda-project-v1", 18) == 0) - goto lihata_prj; - if (strncmp(s, "li:pcb-rnd-conf-v1", 18) == 0) - goto lihata_prj; - n++; - } - - rewind(f); - - if (conf_g2pr.utils.gsch2pcb_rnd.verbose) - printf("Reading project file: %s\n", path); - while (fgets(buf, sizeof(buf), f)) { - for (s = buf; *s == ' ' || *s == '\t' || *s == '\n'; ++s); - if (!*s || *s == '#' || *s == '/' || *s == ';') - continue; - arg[0] = '\0'; - sscanf(s, "%31s %767[^\n]", config, arg); - parse_config(config, arg); - } - fclose(f); - return; - -lihata_prj:; - fclose(f); - if (rnd_conf_load_as(RND_CFR_PROJECT, path, 0) != 0) { - rnd_message(RND_MSG_ERROR, "Failed to parse project file %s.\n", path); - exit(1); - } - rnd_conf_update(NULL, -1); /* because of our new project file */ -} - -static void load_extra_project_files(void) -{ - char *path; - static int done = FALSE; - - if (done) - return; - - load_project("/etc/gsch2pcb"); - load_project("/usr/local/etc/gsch2pcb"); - - path = rnd_concat(rnd_conf.rc.path.home, RND_DIR_SEPARATOR_S, ".gEDA", RND_DIR_SEPARATOR_S, "gsch2pcb", NULL); - load_project(path); - free(path); - - done = TRUE; -} - -int have_cli_project_file = 0; -int have_cli_schematics = 0; -static void get_args(int argc, char ** argv) -{ - char *opt, *arg; - int i, r; - - for (i = 1; i < argc; ++i) { - opt = argv[i]; - arg = argv[i + 1]; - if (*opt == '-') { - ++opt; - if (*opt == '-') - ++opt; - if (!strcmp(opt, "version") || !strcmp(opt, "V")) { - printf("gsch2pcb-rnd %s\n", GSCH2PCB_RND_VERSION); - exit(0); - } - else if (!strcmp(opt, "verbose") || !strcmp(opt, "v")) { - char tmp[64]; - sprintf(tmp, "%ld", conf_g2pr.utils.gsch2pcb_rnd.verbose + 1); - rnd_conf_set(RND_CFR_CLI, "utils/gsch2pcb_rnd/verbose", -1, tmp, RND_POL_OVERWRITE); - continue; - } - else if (!strcmp(opt, "m") || !strcmp(opt, "method")) { - if (method_find(arg) == NULL) { - rnd_message(RND_MSG_ERROR, "Error: can't use unknown method '%s'; try --help\n", arg); - exit(1); - } - rnd_conf_set(RND_CFR_CLI, "utils/gsch2pcb_rnd/method", -1, arg, RND_POL_OVERWRITE); - i++; - continue; - } - else if (!strcmp(opt, "c") || !strcmp(opt, "conf")) { - const char *stmp; - if (rnd_conf_set_from_cli(NULL, arg, NULL, &stmp) != 0) { - fprintf(stderr, "Error: failed to set config %s: %s\n", arg, stmp); - exit(1); - } - i++; - continue; - } - else if (!strcmp(opt, "fix-elements")) { - rnd_conf_set(RND_CFR_CLI, "utils/gsch2pcb_rnd/fix_elements", -1, "1", RND_POL_OVERWRITE); - continue; - } - else if (!strcmp(opt, "gnetlist-arg")) { - char **n; - n = gadl_new(&extra_gnetlist_arg_list); - *n = rnd_strdup(arg); - gadl_append(&extra_gnetlist_arg_list, n); - i++; - continue; - } - else if (!strcmp(opt, "help") || !strcmp(opt, "h")) - usage(); - else if (i < argc && ((r = parse_config(opt, (i < argc - 1) ? arg : NULL)) - >= 0) - ) { - i += r; - continue; - } - printf("gsch2pcb: bad or incomplete arg: %s\n", argv[i]); - usage(); - } - else { - if (loc_str_has_suffix(argv[i], ".sch", 4) == NULL) { - if (have_cli_project_file) { - rnd_message(RND_MSG_ERROR, "ERROR: multiple project files specified on the command line (last one: %s). Either use multiple schematics or a single project file. Try %s --help\n", argv[i], argv[0]); - exit(1); - } - load_extra_project_files(); - load_project(argv[i]); - have_cli_project_file = 1; - } - else { - add_schematic(argv[i]); - have_cli_schematics = 1; - } - } - } -} - -void free_strlist(gadl_list_t *lst) -{ - char **s; - - while((s = gadl_first(lst)) != NULL) { - char *str = *s; - gadl_free(s); - free(str); - } -} - -void require_gnetlist_backend(const char *dir, const char *backend) -{ - char *path = rnd_strdup_printf("%s/gnet-%s.scm", dir, backend); - if (!rnd_file_readable_(path)) - rnd_message(RND_MSG_WARNING, "WARNING: %s is not found, gnetlist will probably fail; please check your pcb-rnd installation!\n", path); - free(path); -} - - -const char *local_project_pcb_name = NULL; - -void gsch2pcb_conf_core_init(void) {} - -/************************ main ***********************/ -int main(int argc, char ** argv) -{ - const char *want_method; - char *exec_prefix; - - method_import_register(); - - rnd_app.package = "gsch2pcb-rnd"; - rnd_app.version = PCB_VERSION; - rnd_app.revision = PCB_REVISION; - - rnd_app.conf_userdir_path = CONF_USER_DIR; - rnd_app.conf_user_path = rnd_concat(CONF_USER_DIR, "/conf_core.lht", NULL); - - exec_prefix = rnd_exec_prefix(argv[0], BINDIR, BINDIR_TO_EXECPREFIX); - rnd_hidlib_init1(gsch2pcb_conf_core_init, exec_prefix); - free(exec_prefix); - - rnd_units_init(); - - rnd_file_loaded_init(); - rnd_conf_init(); - - rnd_conf_set(RND_CFR_CLI, "rc/dup_log_to_stderr", 0, "1", RND_POL_OVERWRITE); - - gadl_list_init(&schematics, sizeof(char *), NULL, NULL); - gadl_list_init(&extra_gnetlist_arg_list, sizeof(char *), NULL, NULL); - gadl_list_init(&extra_gnetlist_list, sizeof(char *), NULL, NULL); - -#define conf_reg(field,isarray,type_name,cpath,cname,desc,flags) \ - rnd_conf_reg_field(conf_g2pr, field,isarray,type_name,cpath,cname,desc,flags); -#include "gsch2pcb_rnd_conf_fields.h" - - get_args(argc, argv); - - rnd_conf_load_all(NULL, NULL); - rnd_conf_update(NULL, -1); - - load_extra_project_files(); - rnd_conf_update(NULL, -1); /* because of CLI changes */ - - if (!have_cli_project_file && !have_cli_schematics) { - if (!rnd_file_readable_(LOCAL_PROJECT_FILE)) { - rnd_message(RND_MSG_ERROR, "Don't know what to do: no project or schematics given, no local project file %s found. Try %s --help\n", LOCAL_PROJECT_FILE, argv[0]); - exit(1); - } - if (rnd_conf_load_as(RND_CFR_PROJECT, LOCAL_PROJECT_FILE, 0) != 0) { - rnd_message(RND_MSG_ERROR, "Failed to load project file %s. Try %s --help\n", LOCAL_PROJECT_FILE, argv[0]); - exit(1); - } - rnd_conf_update(NULL, -1); /* because of our new project file */ - } - else if ((local_project_pcb_name != NULL) && (!have_cli_project_file)) - rnd_conf_load_project(NULL, local_project_pcb_name); - - if (!have_cli_schematics) { /* load all schematics from the project file unless we have schematics from the cli */ - rnd_conf_native_t *nat = rnd_conf_get_field("utils/gsch2pcb_rnd/schematics"); - if (nat != NULL) { - rnd_conf_listitem_t *ci; - for (ci = rnd_conflist_first(nat->val.list); ci != NULL; ci = rnd_conflist_next(ci)) { - const char *p = ci->val.string[0]; - if (ci->type != RND_CFN_STRING) - continue; - add_schematic(p); - } - } - else { - rnd_message(RND_MSG_ERROR, "No schematics specified on the cli or in project files. Try %s --help\n", argv[0]); - exit(1); - } - } - - if (gadl_length(&schematics) == 0) { - rnd_message(RND_MSG_ERROR, "No schematics specified on the cli; can't find any in the project files/configs either. Try %s --help\n", argv[0]); - exit(1); - } - - rnd_conf_update(NULL, -1); /* because of the project file */ - - want_method = conf_g2pr.utils.gsch2pcb_rnd.method; - if (want_method == NULL) { - method_t *m; - for(m = methods; m != NULL; m = m->next) { - if (m->not_by_guess) - continue; - if (m->guess_out_name()) { - current_method = m; - break; - } - } - if (current_method == NULL) { - want_method = want_method_default; - if (!conf_g2pr.utils.gsch2pcb_rnd.quiet_mode) - rnd_message(RND_MSG_WARNING, "Warning: method not specified for a project (that has no board or project file yet); defaulting to -m %s. This warning is harmless if you are running gsch2pcb-rnd for the first time on this project and you are fine with this method.", want_method); - } - } - - if (current_method == NULL) { - current_method = method_find(want_method); - if (current_method == NULL) { - rnd_message(RND_MSG_ERROR, "Error: can't find method %s\n", want_method); - exit(1); - } - } - - current_method->init(); - rnd_conf_update(NULL, -1); - - - current_method->go(); /* the traditional, "parse element and edit the pcb file" approach */ - - current_method->uninit(); - - free_strlist(&schematics); - free_strlist(&extra_gnetlist_arg_list); - free_strlist(&extra_gnetlist_list); - - rnd_units_uninit(); - return 0; -}