From 81365ece569e8cd574298c6f5b4397223d3adf7c Mon Sep 17 00:00:00 2001 From: mhx Date: Sun, 4 Sep 2016 02:12:56 +0200 Subject: [PATCH] Add all predefined constants as .PARAM, too. Make a .CSPARAM become a .PARAM. --- src/frontend/cpitf.c | 34 ++++++++++++------------ src/frontend/cpitf.h | 3 ++- src/frontend/inp.c | 42 +++++++++--------------------- src/frontend/inpcom.c | 60 ++++++++++++++++++++++++++++++++++++++----- 4 files changed, 85 insertions(+), 54 deletions(-) diff --git a/src/frontend/cpitf.c b/src/frontend/cpitf.c index b61ea9741..e10068717 100644 --- a/src/frontend/cpitf.c +++ b/src/frontend/cpitf.c @@ -20,6 +20,23 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group #include "completion.h" #include "variable.h" +char *predefs[] = { + "yes", "1", + "TRUE", "1", + "no", "0", + "FALSE", "0", + "pi", "3.1415926535897932384626433832795028841971693993751058", + "e", "2.7182818284590452353602874713526624977572470936999595", + "c", "299792458e00", + "i", "(0,1)", + "kelvin", "-273.15", + "echarge", "1.6021766e-19", + "boltz", "1.38065e-23", + "planck", "6.62607e-34" +}; + +int szpredefs = NUMELEMS(predefs); + /* Set some standard variables and aliases, etc, and init the ccom stuff. Called by fcn main() */ @@ -32,21 +49,6 @@ ft_cpinit(void) int i; FILE *fp; - static char *predefs[] = { - "yes", "1", - "TRUE", "1", - "no", "0", - "FALSE", "0", - "pi", "3.14159265358979323846", - "e", "2.71828182845904523536", - "c", "2.997925e8", - "i", "0,1", - "kelvin", "-273.15", - "echarge", "1.60219e-19", - "boltz", "1.38062e-23", - "planck", "6.62620e-34" - }; - static char *udfs[] = { "max(x,y)", "(x gt y) * x + (x le y) * y", "min(x,y)", "(x lt y) * x + (x ge y) * y", @@ -206,7 +208,7 @@ ft_cpinit(void) wl3.wl_prev = &wl2; wl3.wl_next = NULL; wl2.wl_word = "="; - for (i = 0; (size_t) i < NUMELEMS(predefs); i += 2) { + for (i = 0; (size_t) i < szpredefs; i += 2) { wl1.wl_word = predefs[i]; wl3.wl_word = predefs[i + 1]; com_let(&wl1); diff --git a/src/frontend/cpitf.h b/src/frontend/cpitf.h index defbacd84..49e6fe8c5 100644 --- a/src/frontend/cpitf.h +++ b/src/frontend/cpitf.h @@ -6,6 +6,7 @@ #ifndef ngspice_CPITF_H #define ngspice_CPITF_H - +extern char *predefs[]; +extern int szpredefs; #endif diff --git a/src/frontend/inp.c b/src/frontend/inp.c index 37b0e7ca5..9f4cce278 100644 --- a/src/frontend/inp.c +++ b/src/frontend/inp.c @@ -674,40 +674,22 @@ inp_spsource(FILE *fp, bool comfile, char *filename, bool intfile) if (ft_ngdebug) { /*debug: print into file*/ FILE *fdo = fopen("debug-out2.txt", "w"); - struct line *t = NULL; + struct line *te = NULL; fprintf(fdo, "**************** uncommented deck **************\n\n"); /* always print first line */ fprintf(fdo, "%6d %6d %s\n", deck->li_linenum_orig, deck->li_linenum, deck->li_line); /* here without out-commented lines */ - for (t = deck->li_next; t; t = t->li_next) { - if (*(t->li_line) == '*') + for (te = deck->li_next; te; te = te->li_next) { + if (*(te->li_line) == '*') continue; - fprintf(fdo, "%6d %6d %s\n", t->li_linenum_orig, t->li_linenum, t->li_line); + fprintf(fdo, "%6d %6d %s\n", te->li_linenum_orig, te->li_linenum, te->li_line); } fprintf(fdo, "\n****************** complete deck ***************\n\n"); /* now completely */ - for (t = deck; t; t = t->li_next) - fprintf(fdo, "%6d %6d %s\n", t->li_linenum_orig, t->li_linenum, t->li_line); + for (te = deck; te; te = te->li_next) + fprintf(fdo, "%6d %6d %s\n", te->li_linenum_orig, te->li_linenum, te->li_line); fclose(fdo); } - for (dd = deck; dd; dd = dd->li_next) { - /* get csparams and create vectors, being - available in .control section, in plot 'const' */ - if (ciprefix(".csparam", dd->li_line)) { - wordlist *wlist = NULL; - char *cstoken[3]; - int i; - dd->li_line[0] = '*'; - s = skip_ws(dd->li_line + 8); - cstoken[0] = gettok_char(&s, '=', FALSE, FALSE); - cstoken[1] = gettok_char(&s, '=', TRUE, FALSE); - cstoken[2] = gettok(&s); - for (i = 3; --i >= 0;) - wlist = wl_cons(cstoken[i], wlist); - com_let(wlist); - wl_free(wlist); - } - } /* handle .if ... .elseif ... .else ... .endif statements. */ dotifeval(deck); @@ -816,20 +798,20 @@ inp_spsource(FILE *fp, bool comfile, char *filename, bool intfile) if (ft_ngdebug) { /*debug: print into file*/ FILE *fdo = fopen("debug-out3.txt", "w"); - struct line *t = NULL; + struct line *tz = NULL; fprintf(fdo, "**************** uncommented deck **************\n\n"); /* always print first line */ fprintf(fdo, "%6d %6d %s\n", deck->li_linenum_orig, deck->li_linenum, deck->li_line); /* here without out-commented lines */ - for (t = deck->li_next; t; t = t->li_next) { - if (*(t->li_line) == '*') + for (tz = deck->li_next; tz; tz = tz->li_next) { + if (*(tz->li_line) == '*') continue; - fprintf(fdo, "%6d %6d %s\n", t->li_linenum_orig, t->li_linenum, t->li_line); + fprintf(fdo, "%6d %6d %s\n", tz->li_linenum_orig, tz->li_linenum, tz->li_line); } fprintf(fdo, "\n****************** complete deck ***************\n\n"); /* now completely */ - for (t = deck; t; t = t->li_next) - fprintf(fdo, "%6d %6d %s\n", t->li_linenum_orig, t->li_linenum, t->li_line); + for (tz = deck; tz; tz = tz->li_next) + fprintf(fdo, "%6d %6d %s\n", tz->li_linenum_orig, tz->li_linenum, tz->li_line); fclose(fdo); } diff --git a/src/frontend/inpcom.c b/src/frontend/inpcom.c index 96095b022..6302f6b48 100644 --- a/src/frontend/inpcom.c +++ b/src/frontend/inpcom.c @@ -17,6 +17,8 @@ Author: 1985 Wayne A. Christopher #include "ngspice/dvec.h" #include "ngspice/fteinp.h" #include "ngspice/compatmode.h" +#include "cpitf.h" +#include "com_let.h" #include #include @@ -103,7 +105,7 @@ long dynsubst; /* spicenum.c 221 */ /* Expression handling with 'temper' parameter required */ bool expr_w_temper = FALSE; - +static void add_all_constants_as_params(struct line *cc); /* mhx */ static char *readline(FILE *fd); static int get_number_terminals(char *c); static void inp_stripcomments_deck(struct line *deck, bool cs); @@ -191,6 +193,18 @@ xx_new_line(struct line *next, char *line, int linenum, int linenum_orig, unsign return x; } +static void add_all_constants_as_params(struct line *cc) { + char buf[4096] = ".param "; char *p = buf; int i; + for (i = 0; i < szpredefs; i += 2) { + strcat_s(p, 4096, predefs[i]); strcat_s(p, 4096, " = "); + strcat_s(p, 4096, predefs[i + 1]); strcat_s(p, 4096, " "); + if (strlen(p) > 4000) { + fprintf(cp_err, "ERROR: not enough space for predefined constants.\n"); + controlled_exit(EXIT_FAILURE); + } + } + cc->li_next = xx_new_line(cc->li_next, copy(buf), 2, 1, NULL); +} static struct library * new_lib(void) @@ -550,6 +564,37 @@ inp_readall(FILE *fp, char *dir_name, bool comfile, bool intfile) inp_expand_macros_in_deck(NULL, working); inp_fix_param_values(working); + /* + * mhx: Had to move this section here because it defines extra .param lines, + * and this must be done before inp_spsource() moves such lines to a + * continguous block at the top of the file. + * See "all parameter lines should be sequentially ordered and placed at beginning of deck" in inp.c + */ + { + struct line *dd; char *s; + for (dd = cc; dd; dd = dd->li_next) { + /* get csparams and create vectors, available in the .control section, in plot 'const' */ + if (ciprefix(".csparam", dd->li_line)) { + wordlist *wlist = NULL, *wl = NULL; char *cstoken[3]; int i; + s = dd->li_line; + /* mhx: Instead of making the original line a comment, we reuse it as a the .param line. */ + /* 01234567 */ + /* .csparam */ + /* .param */ + for (i = 1; i <= 5; i++) dd->li_line[i] = dd->li_line[i + 2]; + dd->li_line[i] = ' '; dd->li_line[i + 1] = ' '; + s = dd->li_line + 8; + while (isspace((int)*s)) s++; + cstoken[0] = gettok_char(&s, '=', FALSE, FALSE); + cstoken[1] = gettok_char(&s, '=', TRUE, FALSE); + cstoken[2] = gettok(&s); + for (i = 0; i < 3; i++) wl_append_word(&wlist, &wl, cstoken[i]); + com_let(wlist); + wl_free(wlist); + } + } + } + inp_reorder_params(subckt_w_params, cc); inp_fix_inst_calls_for_numparam(subckt_w_params, working); @@ -656,10 +701,10 @@ inp_read(FILE *fp, int call_depth, char *dir_name, bool comfile, bool intfile) int line_count = 0; #endif char *new_title = NULL; - int line_number = 1; /* sjb - renamed to avoid confusion with struct line */ - int line_number_orig = 1; - int cirlinecount = 0; /* length of circarray */ - static int is_control = 0; /* We are reading from a .control section */ + int line_number = 2; /* sjb - renamed to avoid confusion with struct line */ + int line_number_orig = 2; /* mhx: this was 1, but we need line 1 to define all constants as .params */ + int cirlinecount = 0; /* length of circarray */ + static int is_control = 0; /* We are reading from a .control section */ bool found_end = FALSE, shell_eol_continuation = FALSE; @@ -1008,7 +1053,8 @@ inp_read(FILE *fp, int call_depth, char *dir_name, bool comfile, bool intfile) comfile = TRUE; if (call_depth == 0 && !comfile) { - cc->li_next = xx_new_line(cc->li_next, copy(".global gnd"), 1, 0, NULL); + cc->li_next = xx_new_line(cc->li_next, copy(".global gnd"), 1, 0, NULL); /* uses line #0 */ + add_all_constants_as_params(cc); /* uses up line #1, therefore first line will be 2 */ if (inp_compat_mode == COMPATMODE_ALL || inp_compat_mode == COMPATMODE_HS || @@ -3032,7 +3078,7 @@ inp_get_func_from_line(struct function_env *env, char *line) Lerror: // fixme, free() - fprintf(stderr, "ERROR: faild to parse .func in: %s\n", orig_line); + fprintf(stderr, "ERROR: failed to parse .func in: %s\n", orig_line); controlled_exit(EXIT_FAILURE); }