From 167c708e6923556af991ca74e8b7a14aea9afc97 Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Fri, 27 Jan 2023 10:08:16 +0100 Subject: [PATCH] Add searchpath for *.osdi relative to ngspice executable --- src/include/ngspice/ngspice.h | 1 + src/misc/ivars.c | 19 +++++++++++++- src/osdi/osdiregistry.c | 48 ++++++++++++++++++++++++++++------- 3 files changed, 58 insertions(+), 10 deletions(-) diff --git a/src/include/ngspice/ngspice.h b/src/include/ngspice/ngspice.h index 74535553e..0937f597d 100644 --- a/src/include/ngspice/ngspice.h +++ b/src/include/ngspice/ngspice.h @@ -279,6 +279,7 @@ extern char *Help_Path; extern char *Lib_Path; extern char *Inp_Path; extern char *Infile_Path; +extern char *Spice_Exec_Path; #ifdef TCL_MODULE diff --git a/src/misc/ivars.c b/src/misc/ivars.c index 5c8afcaa9..5bbeea7e9 100644 --- a/src/misc/ivars.c +++ b/src/misc/ivars.c @@ -11,6 +11,7 @@ char *News_File; char *Help_Path; char *Lib_Path; char *Inp_Path; +char *Spice_Exec_Path; static void @@ -102,7 +103,22 @@ ivars(char *argv0) env_overr(&temp, "SPICE_ASCIIRAWFILE"); if(temp) AsciiRawFile = atoi(temp); - + + /* path of the ngspice executable */ + Spice_Exec_Path = copy(argv0); + /* find the last occurence of "ngspice" in Spice_Exec_Path */ + char* path_end = strstr(Spice_Exec_Path, "ngspice"); + if (path_end) { + char* exec_only = strstr(path_end + 7, "ngspice"); + while (exec_only) { + path_end = strstr(Spice_Exec_Path, "ngspice"); + if (path_end) + exec_only = strstr(path_end + 7, "ngspice"); + } + if (path_end) + *path_end = '\0'; + fprintf(stdout, "ngspice path %s\n", Spice_Exec_Path); + } } void @@ -113,4 +129,5 @@ destroy_ivars(void) tfree(Lib_Path); tfree(Spice_Path); tfree(Inp_Path); + tfree(Spice_Exec_Path); } diff --git a/src/osdi/osdiregistry.c b/src/osdi/osdiregistry.c index 164ed741e..6da846451 100644 --- a/src/osdi/osdiregistry.c +++ b/src/osdi/osdiregistry.c @@ -121,7 +121,8 @@ static char *resolve_input_path(const char *name) { /* * If called from a script inputdir != NULL so try relativ to that dir - * Otherwise try relativ to the current workdir + * Otherwise try relativ to the current workdir and relativ to the + * executables path */ if (inputdir) { @@ -152,18 +153,47 @@ static char *resolve_input_path(const char *name) { if (r) return r; } + + if (Spice_Exec_Path && *Spice_Exec_Path) { + DS_CREATE(ds, 100); + int rc_ds = 0; + rc_ds |= ds_cat_str(&ds, Spice_Exec_Path); /* copy the dir name */ + const size_t n = ds_get_length(&ds); /* end of copied dir name */ + + /* Append a directory separator if not present already */ + const char ch_last = n > 0 ? Spice_Exec_Path[n - 1] : '\0'; + if (ch_last != DIR_TERM +#ifdef _WIN32 + && ch_last != DIR_TERM_LINUX +#endif + ) { + rc_ds |= ds_cat_char(&ds, DIR_TERM); + } + rc_ds |= ds_cat_str(&ds, name); /* append the file name */ + + if (rc_ds != 0) { + (void)fprintf(cp_err, "Unable to build \"dir\" path name " + "in inp_pathresolve_at"); + controlled_exit(EXIT_FAILURE); + } + + char* const r = resolve_path(ds_get_buf(&ds)); + ds_free(&ds); + if (r) + return r; + } /* no inputdir, or not found relative to inputdir: - search relative to current working directory */ + search relative to current working directory */ DS_CREATE(ds, 100); if (ds_cat_printf(&ds, ".%c%s", DIR_TERM, name) != 0) { - (void)fprintf(cp_err, - "Unable to build \".\" path name in inp_pathresolve_at"); - controlled_exit(EXIT_FAILURE); + (void)fprintf(cp_err, + "Unable to build \".\" path name in inp_pathresolve_at"); + controlled_exit(EXIT_FAILURE); } - char *const r = resolve_path(ds_get_buf(&ds)); + char* const r = resolve_path(ds_get_buf(&ds)); ds_free(&ds); - if (r != (char *)NULL) { - return r; + if (r != (char*)NULL) { + return r; } return NULL; @@ -194,7 +224,7 @@ static size_t calc_osdi_instance_data_off(const OsdiDescriptor *descr) { #define ERR_AND_RET \ error = dlerror(); \ - printf("Error opening osdi lib \"%s\": %s\n", path, error); \ + fprintf(stderr, "Error opening osdi lib \"%s\": %s\n", path, error); \ FREE_DLERR_MSG(error); \ return INVALID_OBJECT;