diff --git a/src/xspice/cmpp/Makefile.am b/src/xspice/cmpp/Makefile.am index c858a3348..71bdb80c9 100644 --- a/src/xspice/cmpp/Makefile.am +++ b/src/xspice/cmpp/Makefile.am @@ -17,11 +17,15 @@ cmpp_SOURCES = main.c cmpp.h file_buffer.c file_buffer.h\ mod_lex.l mod_yacc.y mod_yacc_y.h if WINGUI -cmpp_LDADD = -lShlwapi +cmpp_LDADD = -lshlwapi endif if WINCONSOLE -cmpp_LDADD = -lShlwapi +cmpp_LDADD = -lshlwapi +endif + +if SHWIN +cmpp_LDADD = -lshlwapi endif mod_lex.c : mod_lex.l diff --git a/src/xspice/cmpp/file_buffer.c b/src/xspice/cmpp/file_buffer.c index 74e602a4c..27a9d10ff 100644 --- a/src/xspice/cmpp/file_buffer.c +++ b/src/xspice/cmpp/file_buffer.c @@ -14,12 +14,21 @@ static int fb_fill(FILEBUF *p_fb); -static int fbget_quoted_unescaped_string(FILEBUF *p_fb, FBSTRING *p_fbstr); +static int fbget_quoted_unescaped_string(FILEBUF *p_fb, + FBTYPE *p_type_found, FBOBJ *p_fbobj); static size_t fb_make_space_at_end(FILEBUF *p_fb); -static int fbget_quoted_string(FILEBUF *p_fb, FBSTRING *p_fbstr); -static int fbget_quoted_escaped_string(FILEBUF *p_fb, FBSTRING *p_fbstr); -static int fbget_unquoted_string(FILEBUF *p_fb, FBSTRING *p_fbstr); -static int fb_return_string(FILEBUF *p_fb, FBSTRING *p_fbstr); +static int fbget_quoted_string(FILEBUF *p_fb, + FBTYPE *p_type_found, FBOBJ *p_fbobj); +static int fbget_quoted_escaped_string(FILEBUF *p_fb, + FBTYPE *p_type_found, FBOBJ *p_fbobj); +static int fbget_unquoted_string(FILEBUF *p_fb, + unsigned int n_type_wanted, FBTYPE *p_type_wanted, + FBTYPE *p_type_found, FBOBJ *p_fbobj); +static int fb_return_obj(FILEBUF *p_fb, + unsigned int n_type_wanted, FBTYPE *p_type_wanted, + FBTYPE *p_type_found, FBOBJ *p_fbobj); +static int fb_return_string(FILEBUF *p_fb, + FBTYPE *p_type_found, FBOBJ *p_fbobj); static int fb_skip_to_eol(FILEBUF *p_fb); static int fb_skip_whitespace(FILEBUF *p_fb); @@ -138,7 +147,12 @@ int fbclose(FILEBUF *p_fb) * * Parameters * p_fb: FILEBUF pointer initialized using fbopen() - * p_fbstr: Address of an FBSTRING structure to receive the data + * n_type_wanted: number of desired type conversions for data from highest + * priority to lowest. + * p_type_wanted: Desired type conversions for data from highest priority + * to lowest. + * p_type_found: Address to receive the type of the data obtained + * p_fbobj: Address of an FBOBJ structure to receive the data * * Return codes * +1: EOF reached @@ -166,7 +180,9 @@ int fbclose(FILEBUF *p_fb) * 0: Normal * -1: Error */ -int fbget(FILEBUF *p_fb, FBSTRING *p_fbstr) +int fbget(FILEBUF *p_fb, + unsigned int n_type_wanted, FBTYPE *p_type_wanted, + FBTYPE *p_type_found, FBOBJ *p_fbobj) { /* Test for existing EOF */ if (p_fb->is_eof && p_fb->p_data_cur == p_fb->p_data_end) { /* no data */ @@ -194,11 +210,12 @@ int fbget(FILEBUF *p_fb, FBSTRING *p_fbstr) /* Current char exists and starts the item */ if (*p_fb->p_data_cur == '"') { /* quoted string */ - return fbget_quoted_string(p_fb, p_fbstr); + return fbget_quoted_string(p_fb, p_type_found, p_fbobj); } /* Else unquoted string */ - return fbget_unquoted_string(p_fb, p_fbstr); + return fbget_unquoted_string(p_fb, n_type_wanted, p_type_wanted, + p_type_found, p_fbobj); } /* end of function fbget */ @@ -207,7 +224,8 @@ int fbget(FILEBUF *p_fb, FBSTRING *p_fbstr) * to the quote starting the quoted string. On return it points to the first * character after the current item or equals p_fb->p_data_end if the * current item extens to the end of the current data string. */ -static int fbget_quoted_string(FILEBUF *p_fb, FBSTRING *p_fbstr) +static int fbget_quoted_string(FILEBUF *p_fb, + FBTYPE *p_type_found, FBOBJ *p_fbobj) { /* Advance past the opening quote to the true start of the string */ if (++p_fb->p_data_cur == p_fb->p_data_end) { @@ -225,7 +243,7 @@ static int fbget_quoted_string(FILEBUF *p_fb, FBSTRING *p_fbstr) * and the buffer has at leat 1 byte a NULL to create the * string "" can be written here */ *(p_fb->p_obj_end = p_fb->p_obj_start = p_fb->p_buf) = '\0'; - return fb_return_string(p_fb, p_fbstr); + return fb_return_string(p_fb, p_type_found, p_fbobj); } /* Else data is now available at p_fb->p_data_cur */ } /* end of case that at end of data from file */ @@ -235,14 +253,15 @@ static int fbget_quoted_string(FILEBUF *p_fb, FBSTRING *p_fbstr) /* Continue processing as an unescaped string, unless the contrary * is found to be true */ - return fbget_quoted_unescaped_string(p_fb, p_fbstr); + return fbget_quoted_unescaped_string(p_fb, p_type_found, p_fbobj); } /* end of function fbget_quoted_string */ /* Get a quoted string with no escape. The start has already been set on * entry. If an escape is found, processing continues as an escaped string */ -int fbget_quoted_unescaped_string(FILEBUF *p_fb, FBSTRING *p_fbstr) +int fbget_quoted_unescaped_string(FILEBUF *p_fb, + FBTYPE *p_type_found, FBOBJ *p_fbobj) { /* Step through characters until end or escape */ char *p_data_cur = p_fb->p_data_cur; @@ -253,13 +272,14 @@ int fbget_quoted_unescaped_string(FILEBUF *p_fb, FBSTRING *p_fbstr) if (ch_cur == '"') { /* Closing quote, so done */ *(p_fb->p_obj_end = p_data_cur) = '\0'; p_fb->p_data_cur = p_data_cur + 1; - return fb_return_string(p_fb, p_fbstr); + return fb_return_string(p_fb, p_type_found, p_fbobj); } if (ch_cur == '\\') { /* Escape */ /* After an escape, data must be moved to fill in the gap * left by the escape character */ p_fb->p_data_cur = p_data_cur; /* Reprocess the escape */ - return fbget_quoted_escaped_string(p_fb, p_fbstr); + return fbget_quoted_escaped_string(p_fb, + p_type_found, p_fbobj); } /* Else the character is part of the quoted string */ } /* end of loop over current text */ @@ -275,7 +295,7 @@ int fbget_quoted_unescaped_string(FILEBUF *p_fb, FBSTRING *p_fbstr) * did not return -1, there is at least 1 byte at the end of * the buffer where the read would have gone. */ *(p_fb->p_obj_end = p_fb->p_data_cur) = '\0'; - return fb_return_string(p_fb, p_fbstr); + return fb_return_string(p_fb, p_type_found, p_fbobj); } p_data_cur = p_fb->p_data_cur; /* Update after fill */ p_data_end = p_fb->p_data_end; @@ -286,7 +306,8 @@ int fbget_quoted_unescaped_string(FILEBUF *p_fb, FBSTRING *p_fbstr) /* Get a quoted string with an escape. The start has already been set on * entry */ -static int fbget_quoted_escaped_string(FILEBUF *p_fb, FBSTRING *p_fbstr) +static int fbget_quoted_escaped_string(FILEBUF *p_fb, + FBTYPE *p_type_found, FBOBJ *p_fbobj) { /* Step through characters until end */ char *p_data_src = p_fb->p_data_cur; /* at current char */ @@ -304,7 +325,7 @@ static int fbget_quoted_escaped_string(FILEBUF *p_fb, FBSTRING *p_fbstr) if (ch_cur == '"') { /* Closing quote, so done */ p_fb->p_data_cur = p_data_src + 1; *(p_fb->p_obj_end = p_data_dst) = '\0'; - return fb_return_string(p_fb, p_fbstr); + return fb_return_string(p_fb, p_type_found, p_fbobj); } if (ch_cur == '\\') { /* Escape */ f_escape_in_progress = true; @@ -323,7 +344,8 @@ static int fbget_quoted_escaped_string(FILEBUF *p_fb, FBSTRING *p_fbstr) /* If no pending escape, can switch back to unescaped version and * avoid the moves */ if (!f_escape_in_progress) { - return fbget_quoted_unescaped_string(p_fb, p_fbstr); + return fbget_quoted_unescaped_string(p_fb, p_type_found, + p_fbobj); } /* Else escape must be processed, so continue with escaped version */ @@ -337,7 +359,7 @@ static int fbget_quoted_escaped_string(FILEBUF *p_fb, FBSTRING *p_fbstr) * did not return -1, there is at least 1 byte at the end of * the buffer where the read would have gone. */ *(p_fb->p_obj_end = p_fb->p_data_cur) = '\0'; - return fb_return_string(p_fb, p_fbstr); + return fb_return_string(p_fb, p_type_found, p_fbobj); } p_data_dst = p_data_src = p_fb->p_data_cur; /* Update after fill */ p_data_end = p_fb->p_data_end; @@ -347,7 +369,9 @@ static int fbget_quoted_escaped_string(FILEBUF *p_fb, FBSTRING *p_fbstr) /* Get an unquoted string starting at the current position */ -static int fbget_unquoted_string(FILEBUF *p_fb, FBSTRING *p_fbstr) +static int fbget_unquoted_string(FILEBUF *p_fb, + unsigned int n_type_wanted, FBTYPE *p_type_wanted, + FBTYPE *p_type_found, FBOBJ *p_fbobj) { /* Save the start of the string as the current position */ p_fb->p_obj_start = p_fb->p_data_cur; @@ -373,7 +397,8 @@ static int fbget_unquoted_string(FILEBUF *p_fb, FBSTRING *p_fbstr) *(p_fb->p_obj_end = p_data_cur) = '\0'; p_fb->p_data_cur = p_data_cur + 1; /* 1st char past string */ p_fb->f_skip_to_eol = map_cur < 0; - return fb_return_string(p_fb, p_fbstr); + return fb_return_obj(p_fb, n_type_wanted, p_type_wanted, + p_type_found, p_fbobj); } /* Else more of the string */ } /* end of loop over current text */ @@ -389,7 +414,8 @@ static int fbget_unquoted_string(FILEBUF *p_fb, FBSTRING *p_fbstr) * did not return -1, there is at least 1 byte at the end of * the buffer where the read would have gone. */ *(p_fb->p_obj_end = p_fb->p_data_cur) = '\0'; - return fb_return_string(p_fb, p_fbstr); + return fb_return_obj(p_fb, n_type_wanted, p_type_wanted, + p_type_found, p_fbobj); } p_data_cur = p_fb->p_data_cur; /* Update after fill */ p_data_end = p_fb->p_data_end; @@ -456,7 +482,7 @@ static size_t fb_make_space_at_end(FILEBUF *p_fb) /* Shift data in use to the front of the buffer if not already */ if (p_dst != p_src) { /* object is not at start of buffer */ - const size_t n = (size_t) (p_fb->p_data_end - p_src); + const size_t n = p_fb->p_data_end - p_src; if (n > 0) { /* Will be 0 if skipping whitespace and comments */ (void) memmove(p_dst, p_src, n); } @@ -502,7 +528,7 @@ static size_t fb_make_space_at_end(FILEBUF *p_fb) } } - return (size_t) (p_fb->p_buf_end - p_fb->p_data_end); + return p_fb->p_buf_end - p_fb->p_data_end; } /* end of function fb_make_space_at_end */ @@ -593,11 +619,78 @@ static int fb_skip_to_eol(FILEBUF *p_fb) -/* Return string */ -static int fb_return_string(FILEBUF *p_fb, FBSTRING *p_fbstr) +/* Return the data found in the most preferred format possible */ +static int fb_return_obj(FILEBUF *p_fb, + unsigned int n_type_wanted, FBTYPE *p_type_wanted, + FBTYPE *p_type_found, FBOBJ *p_fbobj) { - const char *p_data_start = p_fbstr->sz = p_fb->p_obj_start; - p_fbstr->n_char = (size_t) (p_fb->p_obj_end - p_data_start); + const char * const p_obj_start = p_fb->p_obj_start; /* data to convert */ + const char * const p_obj_end = p_fb->p_obj_end; + + /* Must test for null string separately since strto* does not set + * errno in this case. Aside from that, it can only be returned + * as a string anyhow. */ + if (p_obj_start != p_obj_end) { /* have a string besides "" */ + unsigned int i; + for (i = 0; i < n_type_wanted; ++i) { + FBTYPE type_cur = p_type_wanted[i]; + errno = 0; + if (type_cur == BUF_TYPE_ULONG) { + char *p_end; + unsigned long val = strtoul(p_obj_start, &p_end, 10); + /* Test for processing of full string. Note that checking + * for the end of the string rather than a NULL handles the + * case of an embedded NULL which the latter test would + * not */ + if (errno == 0 && p_end == p_obj_end) { + *p_type_found = BUF_TYPE_ULONG; + p_fbobj->ulong_value = val; + return 0; + } + } + else if (type_cur == BUF_TYPE_LONG) { + char *p_end; + long val = strtol(p_obj_start, &p_end, 10); + if (errno == 0 && p_end == p_obj_end) { + *p_type_found = BUF_TYPE_LONG; + p_fbobj->long_value = val; + return 0; + } + } + else if (type_cur == BUF_TYPE_DOUBLE) { + char *p_end; + double val = strtod(p_obj_start, &p_end); + if (errno == 0 && p_end == p_obj_end) { + *p_type_found = BUF_TYPE_DOUBLE; + p_fbobj->dbl_value = val; + return 0; + } + } + else if (type_cur == BUF_TYPE_STRING) { + break; /* exit loop and use default return of string */ + } + else { /* unknown type */ + print_error("Unknown output data type %d is ignored.", + (int) type_cur); + } + } /* end of loop trying types */ + } /* end of case that string is not "" */ + + /* If no rquested type was converted OK or string requested, return as + * a string */ + return fb_return_string(p_fb, p_type_found, p_fbobj); +} /* end of function fb_return_obj */ + + + +/* Return string */ +static int fb_return_string(FILEBUF *p_fb, + FBTYPE *p_type_found, FBOBJ *p_fbobj) +{ + const char *p_data_start = + p_fbobj->str_value.sz = p_fb->p_obj_start; + p_fbobj->str_value.n_char = p_fb->p_obj_end - p_data_start; + *p_type_found = BUF_TYPE_STRING; return 0; } /* end of function fb_return_string */ diff --git a/src/xspice/cmpp/file_buffer.h b/src/xspice/cmpp/file_buffer.h index 0c7686bb7..bee1f76fc 100644 --- a/src/xspice/cmpp/file_buffer.h +++ b/src/xspice/cmpp/file_buffer.h @@ -10,6 +10,14 @@ typedef struct Filebuf_len_str { char *sz; /* Start of string */ } FBSTRING; +/* Union for returned value */ +typedef union Filebuf_obj { + FBSTRING str_value; + unsigned long ulong_value; + long long_value; + double dbl_value; +} FBOBJ; + /* Structure for getting file data */ typedef struct Filebuf { FILE *fp; /* handle to file */ @@ -42,7 +50,8 @@ typedef enum FBtype { FILEBUF *fbopen(const char *filename, size_t n_byte_buf_init); -int fbget(FILEBUF *p_fb, FBSTRING *p_fbstr); +int fbget(FILEBUF *p_fb, unsigned int n_type_wanted, FBTYPE *p_type_wanted, + FBTYPE *p_type_found, FBOBJ *p_fbobj); int fbclose(FILEBUF *fbp); diff --git a/src/xspice/cmpp/pp_lst.c b/src/xspice/cmpp/pp_lst.c index 297d83b08..3d321a396 100644 --- a/src/xspice/cmpp/pp_lst.c +++ b/src/xspice/cmpp/pp_lst.c @@ -67,12 +67,14 @@ typedef struct { char *path_name; /* Pathname read from model path file */ char *spice_name; /* Name of model from ifspec.ifs */ char *cfunc_name; /* Name of C fcn from ifspec.ifs */ + unsigned int version; /* version of the code model */ } Model_Info_t; typedef struct { char *path_name; /* Pathname read from udn path file */ char *node_name; /* Name of node type */ + unsigned int version; /* version of the code model */ } Node_Info_t; @@ -109,8 +111,10 @@ static bool test_for_duplicates(unsigned int n, struct Key_src *p_ks, static inline void trim_slash(size_t *p_n, char *p); static int write_CMextrn(int num_models, Model_Info_t *model_info); static int write_CMinfo(int num_models, Model_Info_t *model_info); +static int write_CMinfo2(int num_models, Model_Info_t *model_info); static int write_UDNextrn(int num_nodes, Node_Info_t *node_info); static int write_UDNinfo(int num_nodes, Node_Info_t *node_info); +static int write_UDNinfo2(int num_nodes, Node_Info_t *node_info); static int write_objects_inc(int num_models, Model_Info_t *model_info, int num_nodes, Node_Info_t *node_info); static int read_udn_type_name(const char *path, char **node_name); @@ -188,6 +192,10 @@ void preprocess_lst_files(void) if(status != 0) { exit(1); } + status = write_CMinfo2(num_models, model_info); + if(status != 0) { + exit(1); + } /* Write out the UDNextrn.h file used to compile SPIinit.c */ status = write_UDNextrn(num_nodes, node_info); @@ -200,6 +208,10 @@ void preprocess_lst_files(void) if(status != 0) { exit(1); } + status = write_UDNinfo2(num_nodes, node_info); + if(status != 0) { + exit(1); + } /* Write the make_include file used to link the models and */ /* user-defined node functions with the simulator */ @@ -211,10 +223,10 @@ void preprocess_lst_files(void) /* Free allocations */ if (model_info != (Model_Info_t *) NULL) { - free_model_info((int) num_models, model_info); + free_model_info(num_models, model_info); } if (node_info != (Node_Info_t *) NULL) { - free_node_info((int) num_nodes, node_info); + free_node_info(num_nodes, node_info); } } /* end of function preprocess_lst_files */ @@ -237,10 +249,40 @@ int output_paths_from_lst_file(const char *filename) goto EXITPOINT; } - FBSTRING fbstr; + bool f_have_path = false; /* do not have a path to store */ + FBTYPE fbtype; + FBOBJ fbobj; for ( ; ; ) { /* Read items until end of file */ /* Get the next path if not found yet */ - const int rc = fbget(fbp, &fbstr); + if (!f_have_path) { + const int rc = fbget(fbp, 0, (FBTYPE *) NULL, &fbtype, &fbobj); + if (rc != 0) { + if (rc == -1) { /* Error */ + print_error("ERROR - Unable to read item to buffer"); + xrc = -1; + goto EXITPOINT; + } + else { /* +1 -- EOF */ + break; + } + } /* end of abnormal case */ + + /* Remove trailing slash if appended to path */ + trim_slash(&fbobj.str_value.n_char, fbobj.str_value.sz); + } + + /* Output the file that was found */ + if (fprintf(stdout, "%s\n", fbobj.str_value.sz) < 0) { + print_error("ERROR - Unable to output path name to stdout: %s", + strerror(errno)); + xrc = -1; + goto EXITPOINT; + } + ++n_path; /* 1 more path printed OK */ + + /* Try getting a version. If found, it will be discarded */ + FBTYPE type_wanted = BUF_TYPE_ULONG; + const int rc = fbget(fbp, 1, &type_wanted, &fbtype, &fbobj); if (rc != 0) { if (rc == -1) { /* Error */ print_error("ERROR - Unable to read item to buffer"); @@ -252,17 +294,15 @@ int output_paths_from_lst_file(const char *filename) } } /* end of abnormal case */ - /* Remove trailing slash if appended to path */ - trim_slash(&fbstr.n_char, fbstr.sz); - - /* Output the file that was found */ - if (fprintf(stdout, "%s\n", fbstr.sz) < 0) { - print_error("ERROR - Unable to output path name to stdout: %s", - strerror(errno)); - xrc = -1; - goto EXITPOINT; + if (fbtype == BUF_TYPE_ULONG) { /* found version number */ + f_have_path = false; + } + else { /* it was a string, so it is the next path */ + f_have_path = true; + + /* Remove trailing slash if appended to path */ + trim_slash(&fbobj.str_value.n_char, fbobj.str_value.sz); } - ++n_path; /* 1 more path printed OK */ } /* end of loop reading items into buffer */ EXITPOINT: @@ -337,23 +377,27 @@ static int read_modpath( } n_model_info_alloc = N_MODEL_INIT; - FBSTRING fbstr; + bool f_have_path = false; /* do not have a path to store */ + FBTYPE fbtype; + FBOBJ fbobj; for ( ; ; ) { /* Read items until end of file */ /* Get the next path if not found yet */ - const int rc = fbget(fbp, &fbstr); - if (rc != 0) { - if (rc == -1) { /* Error */ - print_error("ERROR - Unable to read item to buffer"); - xrc = -1; - goto EXITPOINT; - } - else { /* +1 -- EOF */ - break; - } - } /* end of abnormal case */ + if (!f_have_path) { + const int rc = fbget(fbp, 0, (FBTYPE *) NULL, &fbtype, &fbobj); + if (rc != 0) { + if (rc == -1) { /* Error */ + print_error("ERROR - Unable to read item to buffer"); + xrc = -1; + goto EXITPOINT; + } + else { /* +1 -- EOF */ + break; + } + } /* end of abnormal case */ - /* Remove trailing slash if appended to path */ - trim_slash(&fbstr.n_char, fbstr.sz); + /* Remove trailing slash if appended to path */ + trim_slash(&fbobj.str_value.n_char, fbobj.str_value.sz); + } /* Enlarge model array if full */ if (n_model_info_alloc == n_model_info) { @@ -373,18 +417,44 @@ static int read_modpath( n_model_info; if ((p_model_info_cur->path_name = (char *) malloc( - fbstr.n_char + 1)) == (char *) NULL) { + fbobj.str_value.n_char + 1)) == (char *) NULL) { print_error("ERROR - Unable to allocate path name"); xrc = -1; goto EXITPOINT; } - strcpy(p_model_info_cur->path_name, fbstr.sz); + strcpy(p_model_info_cur->path_name, fbobj.str_value.sz); p_model_info_cur->spice_name = (char *) NULL; p_model_info_cur->cfunc_name = (char *) NULL; /* Must set before returning due to EOF. */ + p_model_info_cur->version = 1; ++n_model_info; + + /* Try getting a version */ + FBTYPE type_wanted = BUF_TYPE_ULONG; + const int rc = fbget(fbp, 1, &type_wanted, &fbtype, &fbobj); + if (rc != 0) { + if (rc == -1) { /* Error */ + print_error("ERROR - Unable to read item to buffer"); + xrc = -1; + goto EXITPOINT; + } + else { /* +1 -- EOF */ + break; + } + } /* end of abnormal case */ + + if (fbtype == BUF_TYPE_ULONG) { /* found version number */ + f_have_path = false; + p_model_info_cur->version = (unsigned int) fbobj.ulong_value; + } + else { /* it was a string, so it is the next path */ + f_have_path = true; + + /* Remove trailing slash if appended to path */ + trim_slash(&fbobj.str_value.n_char, fbobj.str_value.sz); + } } /* end of loop reading items into buffer */ EXITPOINT: @@ -402,12 +472,12 @@ EXITPOINT: /* If error, free model info */ if (xrc != 0) { - free_model_info((int) n_model_info, p_model_info); + free_model_info(n_model_info, p_model_info); n_model_info = 0; p_model_info = (Model_Info_t *) NULL; } - *p_num_model_info = (int) n_model_info; + *p_num_model_info = n_model_info; *pp_model_info = p_model_info; return xrc; @@ -482,24 +552,29 @@ static int read_udnpath( } n_node_info_alloc = N_NODE_INIT; - FBSTRING fbstr; + bool f_have_path = false; /* do not have a path to store */ + FBTYPE fbtype; + FBOBJ fbobj; for ( ; ; ) { /* Read items until end of file */ /* Get the next path if not found yet */ - const int rc = fbget(fbp, &fbstr); - if (rc != 0) { - if (rc == -1) { /* Error */ - print_error("ERROR - Unable to read item to buffer"); - xrc = -1; - goto EXITPOINT; - } - else { /* +1 -- EOF */ - break; - } - } /* end of abnormal case */ + if (!f_have_path) { + const int rc = fbget(fbp, 0, (FBTYPE *) NULL, &fbtype, &fbobj); + if (rc != 0) { + if (rc == -1) { /* Error */ + print_error("ERROR - Unable to read item to buffer"); + xrc = -1; + goto EXITPOINT; + } + else { /* +1 -- EOF */ + break; + } + } /* end of abnormal case */ + + /* Remove trailing slash if appended to path */ + trim_slash(&fbobj.str_value.n_char, fbobj.str_value.sz); + } - /* Remove trailing slash if appended to path */ - trim_slash(&fbstr.n_char, fbstr.sz); /* Enlarge node array if full */ if (n_node_info_alloc == n_node_info) { @@ -519,14 +594,44 @@ static int read_udnpath( n_node_info; if ((p_node_info_cur->path_name = (char *) malloc( - fbstr.n_char + 1)) == (char *) NULL) { + fbobj.str_value.n_char + 1)) == (char *) NULL) { print_error("ERROR - Unable to allocate path name"); xrc = -1; goto EXITPOINT; } - strcpy(p_node_info_cur->path_name, fbstr.sz); + strcpy(p_node_info_cur->path_name, fbobj.str_value.sz); p_node_info_cur->node_name = NULL; + + /* Must set before returning due to EOF. */ + p_node_info_cur->version = 1; + ++n_node_info; + + /* Try getting a version */ + FBTYPE type_wanted = BUF_TYPE_ULONG; + const int rc = fbget(fbp, 1, &type_wanted, &fbtype, &fbobj); + if (rc != 0) { + if (rc == -1) { /* Error */ + print_error("ERROR - Unable to read item to buffer"); + xrc = -1; + goto EXITPOINT; + } + else { /* +1 -- EOF */ + break; + } + } /* end of abnormal case */ + + if (fbtype == BUF_TYPE_ULONG) { /* found version number */ + f_have_path = false; + p_node_info_cur->version = (unsigned int) fbobj.ulong_value; + } + else { /* it was a string, so it is the next path */ + f_have_path = true; + + /* Remove trailing slash if appended to path */ + trim_slash(&fbobj.str_value.n_char, fbobj.str_value.sz); + } + } /* end of loop reading items into buffer */ EXITPOINT: @@ -544,12 +649,12 @@ EXITPOINT: /* If error, free node info */ if (xrc != 0) { - free_node_info((int) n_node_info, p_node_info); + free_node_info(n_node_info, p_node_info); n_node_info = 0; p_node_info = (Node_Info_t *) NULL; } - *p_num_node_info = (int) n_node_info; + *p_num_node_info = n_node_info; *pp_node_info = p_node_info; return xrc; @@ -841,8 +946,8 @@ static int check_uniqueness( } /* Sizes of models and nodes */ - const unsigned int n_model = (unsigned int) (numSPICEmodels + num_models); - const unsigned int n_node = (unsigned int) (numUDNidentifiers + num_nodes); + const unsigned int n_model = (unsigned int) numSPICEmodels + num_models; + const unsigned int n_node = (unsigned int) numUDNidentifiers + num_nodes; const unsigned int n_ks = n_model > n_node ? n_model : n_node; /* Allocate structure to compare */ @@ -890,8 +995,8 @@ static int check_uniqueness( } /* Test for duplicates */ - f_have_duplicate |= test_for_duplicates((unsigned int) num_models, - p_ks, &report_error_function_name); + f_have_duplicate |= test_for_duplicates(num_models, p_ks, + &report_error_function_name); } } @@ -1125,7 +1230,10 @@ static int write_CMinfo( /* Write out the data */ for(i = 0; i < num_models; i++) { - fprintf(fp, "&%s_info,\n", model_info[i].cfunc_name); + Model_Info_t *p_mi_cur = model_info + i; + if (p_mi_cur->version == 1) { + fprintf(fp, "&%s_info,\n", model_info[i].cfunc_name); + } } /* Close the file and return */ @@ -1141,6 +1249,49 @@ static int write_CMinfo( +static int write_CMinfo2( + int num_models, /* Number of model pathnames */ + Model_Info_t *model_info /* Info about each model */ +) +{ + int i; /* A temporary counter */ + FILE *fp; /* File pointer for writing CMinfo.h */ + + char *filename = (char *) NULL; + + /* Open the file to be written */ + if ((filename = gen_filename("cminfo2.h", "w")) == (char *) NULL) { + print_error("ERROR - Unable to build path to cminfo2.h"); + return -1; + } + fp = fopen(filename, "w"); + if(fp == NULL) { + print_error("ERROR - Problems opening %s for write", filename); + free(filename); + return -1; + } + + /* Write out the data */ + for (i = 0; i < num_models; i++) { + Model_Info_t *p_mi_cur = model_info + i; + if (p_mi_cur->version <= 2) { + fprintf(fp, "&%s_info,\n", model_info[i].cfunc_name); + } + } + + /* Close the file and return */ + if (fclose(fp) != 0) { + print_error("ERROR - Problems closing %s", filename); + free(filename); + return -1; + } + + free(filename); + return 0; +} /* end of function write_CMinfo2 */ + + + /* *********************************************************************** */ @@ -1232,7 +1383,51 @@ static int write_UDNinfo( /* Write out the data */ for(i = 0; i < num_nodes; i++) { Node_Info_t *p_ni_cur = node_info + i; - fprintf(fp, "&udn_%s_info,\n", p_ni_cur->node_name); + if (p_ni_cur->version == 1) { + fprintf(fp, "&udn_%s_info,\n", p_ni_cur->node_name); + } + } + + /* Close the file and return */ + if (fclose(fp) != 0) { + print_error("ERROR - Problems closing %s", filename); + free(filename); + return -1; + } + + free(filename); + return 0; +} /* end of function write_UDNinfo */ + + + +static int write_UDNinfo2( + int num_nodes, /* Number of node pathnames */ + Node_Info_t *node_info /* Info about each node */ +) +{ + int i; /* A temporary counter */ + FILE *fp; /* File pointer for writing UDNinfo.h */ + + char *filename = (char *) NULL; + + /* Open the file to be written */ + if ((filename = gen_filename("udninfo2.h", "w")) == (char *) NULL) { + print_error("ERROR - Unable to build path to udninfo2.h"); + return -1; + } + fp = fopen(filename, "w"); + if(fp == NULL) { + print_error("ERROR - Problems opening %s for write", filename); + return -1; + } + + /* Write out the data */ + for(i = 0; i < num_nodes; i++) { + Node_Info_t *p_ni_cur = node_info + i; + if (p_ni_cur->version <= 2) { + fprintf(fp, "&udn_%s_info,\n", p_ni_cur->node_name); + } } /* Close the file and return */ @@ -1394,14 +1589,14 @@ static int read_udn_type_name( c = fgetc(fp); if(c == '"') { found = true; - if (i >= (int) sizeof name) { + if (i >= sizeof name) { print_error("name too long"); exit(1); } name[i] = '\0'; } else if(c != EOF) { - if (i > (int) sizeof name) { + if (i > sizeof name) { print_error("name too long"); exit(1); } diff --git a/src/xspice/cmpp/writ_ifs.c b/src/xspice/cmpp/writ_ifs.c index 3438751dc..e1ab2d5e6 100644 --- a/src/xspice/cmpp/writ_ifs.c +++ b/src/xspice/cmpp/writ_ifs.c @@ -1220,7 +1220,7 @@ static char *value_to_str(Data_Type_t type, Value_t value) /* be careful, the string could conceivably be very long... */ str_len = (int) strlen(value.svalue); if ((str_len + BASE_STR_LEN) > max_len) { - size_t n_byte_alloc = (size_t) (max_len + str_len + 1); + size_t n_byte_alloc = max_len + str_len + 1; void * const p = realloc(str, n_byte_alloc); if (p == NULL) { (void) fprintf(stderr, "Unable to resize string "