From 82c15a8d980bd11a826d75e29d0ce0da7a5eb878 Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Sat, 25 May 2024 16:06:46 +0200 Subject: [PATCH] Search path for .lib and .include has been enhanced to read complete or partial paths from an environmental variable. The env variable name has to start with '$' as the first character after the .inc or .lib token. It is read until it hits a directory separator '/' or '\\', or if none is found, until the end of the line. In this case the filename has to be included in the env variable. If the env variable is read successfully, a ngspice variable with the same name (without leading '$') and contents is defined for use in a .control section. --- src/frontend/inpcom.c | 55 +++++++++++++++++++++++++++++++++++++++---- 1 file changed, 51 insertions(+), 4 deletions(-) diff --git a/src/frontend/inpcom.c b/src/frontend/inpcom.c index a92e6b242..f4e7bed35 100644 --- a/src/frontend/inpcom.c +++ b/src/frontend/inpcom.c @@ -122,7 +122,7 @@ static bool has_if = FALSE; /* if we have an .if ... .endif pair */ static char *readline(FILE *fd); int get_number_terminals(char *c); static void inp_stripcomments_deck(struct card *deck, bool cs); -static void inp_stripcomments_line(char *s, bool cs); +static void inp_stripcomments_line(char *s, bool cs, bool inc); static void inp_fix_for_numparam( struct names *subckt_w_params, struct card *deck); static void inp_remove_excess_ws(struct card *deck); @@ -1417,7 +1417,7 @@ static struct inp_read_t inp_read(FILE* fp, int call_depth, const char* dir_name struct card* newcard; - inp_stripcomments_line(buffer, FALSE); + inp_stripcomments_line(buffer, FALSE, TRUE); s = skip_non_ws(buffer); /* advance past non-space chars */ @@ -1952,6 +1952,47 @@ static char *inp_pathresolve_at(const char *name, const char *dir) return inp_pathresolve(name); } + /* this might contain an environmental variable at the front of the string */ + if (name[0] == '$') { + char* s, *tmpnam, *tmpcurr; + tmpcurr = tmpnam = copy(name); + /* extract env variable, add rest of token to its contents */ + char *envvar = gettok_char(&tmpcurr, '\\', FALSE, FALSE); + if (envvar) { + s = getenv(envvar + 1);/* skip '$' */ + if (s) { + cp_vset(s, CP_STRING, envvar + 1); + char* newname = tprintf("%s%s", s, tmpcurr); + char* const r = inp_pathresolve(newname); + tfree(newname); + return r; + } + } else { + tmpcurr = tmpnam; + envvar = gettok_char(&tmpcurr, '/', FALSE, FALSE); + } + if (envvar) { + s = getenv(envvar + 1);/* skip '$' */ + if (s) { + cp_vset(s, CP_STRING, envvar + 1); + char* newname = tprintf("%s%s", s, tmpcurr); + char* const r = inp_pathresolve(newname); + tfree(newname); + return r; + } + /* no directory separator found, just use the env entry (must include file name) */ + } else { + envvar = tmpnam; + s = getenv(envvar + 1);/* skip '$' */ + if (s) { + cp_vset(s, CP_STRING, envvar + 1); + char* const r = inp_pathresolve(s); + return r; + } + tfree(envvar); + } + } + if (name[0] == '~' && name[1] == '/') { char * const y = cp_tildexpand(name); if (y) { @@ -3239,7 +3280,7 @@ static void inp_stripcomments_deck(struct card *c, bool cf) found_control = TRUE; if (ciprefix(".endc", c->line)) found_control = FALSE; - inp_stripcomments_line(c->line, found_control | cf); + inp_stripcomments_line(c->line, found_control | cf, FALSE); } } @@ -3267,7 +3308,7 @@ static void inp_stripcomments_deck(struct card *c, bool cf) character, not as end-of-line comment delimiter, except for that it is located at the beginning of a line. If inside of a control section, still '$ ' is read a an end-of-line comment delimiter.*/ -static void inp_stripcomments_line(char *s, bool cs) +static void inp_stripcomments_line(char *s, bool cs, bool inc) { char c = ' '; /* anything other than a comment character */ char *d = s; @@ -3280,6 +3321,12 @@ static void inp_stripcomments_line(char *s, bool cs) return; } + if (inc) { + d = nexttok(d); + if (*d == '$') + d = nexttok(d); + } + /* Look for comments in body of line. */ while ((c = *d) != '\0') { d++;