Index: import_sch.c =================================================================== --- import_sch.c (revision 36727) +++ import_sch.c (revision 36728) @@ -33,11 +33,13 @@ #include #include #include +#include #include "globalconst.h" #include "board.h" #include "undo.h" #include "plug_import.h" +#include "conf_core.h" #include "import_sch_conf.h" #define MAX_ARGS 16 Index: import_sch_conf.h =================================================================== --- import_sch_conf.h (revision 36727) +++ import_sch_conf.h (revision 36728) @@ -9,6 +9,7 @@ RND_CFT_STRING import_fmt; /* name of the input format */ RND_CFT_LIST args; /* import_fmt arguments, typically file names */ RND_CFT_BOOLEAN verbose; /* verbose logging of the import code */ + RND_CFT_BOOLEAN design_relative; /* generate design-relative paths using $(rc.path.design) when GUI-selecting input file names */ /* obsolete: temporary compatibility with import_sch for the transition period */ RND_CFT_STRING gnetlist_program; /* DEPRECATED: gnetlist program name */ Index: import_sch_dlg.c =================================================================== --- import_sch_dlg.c (revision 36727) +++ import_sch_dlg.c (revision 36728) @@ -2,7 +2,7 @@ * COPYRIGHT * * pcb-rnd, interactive printed circuit board design - * Copyright (C) 2020 Tibor 'Igor2' Palinkas + * Copyright (C) 2020,2022 Tibor 'Igor2' Palinkas * * 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 @@ -190,6 +190,55 @@ } } +/* Convert path to be relative to the current rc.path.design; free's path, + returns a newly allocated path instead */ +static char *path_to_design_relative(char *path) +{ + gds_t tmp = {0}; + char *s, *d, *sch = rnd_lrealpath(path), *des = rnd_lrealpath(conf_core.rc.path.design); + + if ((*sch != '/') || (*des != '/')) { + rnd_message(RND_MSG_ERROR, "path_to_design_relative: failed to resolve to absolue\n"); + free(sch); + free(des); + return path; + } + + s = sch; + d = des; + +/* sch: /a/b/ c/d/1/2/foo.rs + des: /a/b/ R/8 */ + + /* ignore common prefix */ + for(; *s == *d; s++,d++) ; + + /* ... only up to the last / of it */ + for(; *s != '/'; s--,d--) ; + + gds_append_str(&tmp, "$(rc.path.design)/"); + + /* add all the ..'s: anything left on the design path */ + for(; *d != '\0'; d++) + if (*d == '/') + gds_append_str(&tmp, "../"); + + /* avoid //, tmp ends with / for sure */ + if (*s == '/') + s++; + + /* we are at the common ancestor path, append remaining sch */ + gds_append_str(&tmp, s); + + rnd_trace("design relative:\n sch '%s'\n des '%s'\n RES '%s'\n", path, conf_core.rc.path.design, tmp.array); + + free(sch); + free(des); + free(path); + + return tmp.array; /* owner: caller */ +} + static void isch_browse_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) { int n, idx = -1, wid = attr - isch_ctx.dlg; @@ -212,6 +261,9 @@ if (name == NULL) return; + if (conf_import_sch.plugins.import_sch.design_relative) + name = path_to_design_relative(name); + isch_conf_lock++; rnd_conf_set(RND_CFR_DESIGN, "plugins/import_sch/args", idx, name, RND_POL_OVERWRITE); isch_pcb2dlg();