diff --git a/src/actions.c b/src/actions.c index 8e54a980..29b096e1 100644 --- a/src/actions.c +++ b/src/actions.c @@ -44,19 +44,23 @@ unsigned int hash_file(const char *f, int skip_path_lines) size_t n; int cr = 0; unsigned int h=5381; - char line[4096]; + char *line = NULL; fd = fopen(f, "r"); /* windows won't return \r in the lines and we chop them out anyway in the code */ if(fd) { - while( fgets(line, sizeof(line), fd) ) { + while((line = my_fgets(fd))) { /* skip lines of type: '** sch_path: ...' or '-- sch_path: ...' or '// sym_path: ...' */ - if(skip_path_lines) { - if(!strncmp(line+2, " sch_path: ", 11) || !strncmp(line+2, " sym_path: ", 11) ) continue; + if(skip_path_lines && strlen(line) > 14) { + if(!strncmp(line+2, " sch_path: ", 11) || !strncmp(line+2, " sym_path: ", 11) ) { + my_free(1388, &line); + continue; + } } n = strlen(line); for(i = 0; i < n; i++) { /* skip CRs so hashes will match on unix / windows */ if(line[i] == '\r') { cr = 1; + my_free(1519, &line); continue; } else if(line[i] == '\n' && cr) { cr = 0; @@ -66,6 +70,7 @@ unsigned int hash_file(const char *f, int skip_path_lines) } h += (h << 5) + (unsigned char)line[i]; } + my_free(1545, &line); } if(cr) h += (h << 5) + '\r'; /* file ends with \r not followed by \n: keep it */ fclose(fd); diff --git a/src/editprop.c b/src/editprop.c index 70f5f510..bddaa0d9 100644 --- a/src/editprop.c +++ b/src/editprop.c @@ -57,6 +57,22 @@ int my_strncasecmp(const char *s1, const char *s2, size_t n) return tolower(*s1) - tolower(*s2); } +/* caller should free allocated storage for s */ +char *my_fgets(FILE *fd) +{ + enum { SIZE = 1024 }; + char buf[SIZE]; + char *s = NULL; + size_t len; + + while(fgets(buf, SIZE, fd)) { + my_strcat(425, &s, buf); + len = strlen(buf); + if(buf[len - 1] == '\n') break; + } + return s; +} + /* split a string into tokens like standard strtok_r, * if quote string is not empty any character matching quote is considered a quoting * character, removed from input and all characters before next quote are considered @@ -510,7 +526,7 @@ void my_realloc(int id, void *ptr,size_t size) } -void my_free(int id, void *ptr) +char *my_free(int id, void *ptr) { if(*(void **)ptr) { free(*(void **)ptr); @@ -519,6 +535,7 @@ void my_free(int id, void *ptr) } else { dbg(3, "\n--> my_free(%d,): trying to free NULL pointer\n", id); } + return NULL; } /* n characters at most are copied, *d will be always NUL terminated if *s does diff --git a/src/save.c b/src/save.c index da933371..f45a79fe 100644 --- a/src/save.c +++ b/src/save.c @@ -299,14 +299,16 @@ static void read_binary_block(FILE *fd) static int read_dataset(FILE *fd, const char *type) { int variables = 0, i, done_points = 0; - char line[PATH_MAX], varname[PATH_MAX]; + char *line = NULL, *varname = NULL, *lowerline = NULL; char *ptr; int n = 0, done_header = 0, ac = 0; int exit_status = 0, npoints, nvars; int dbglev=1; xctx->graph_sim_type = NULL; dbg(1, "read_dataset(): type=%s\n", type ? type : ""); - while((fgets(line, sizeof(line), fd)) ) { + while((line = my_fgets(fd))) { + my_strdup2(971, &lowerline, line); + strtolower(lowerline); /* this is an ASCII raw file. We don't handle this (yet) */ if(!strcmp(line, "Values:\n") || !strcmp(line, "Values:\r\n")) { free_rawfile(0); @@ -334,28 +336,28 @@ static int read_dataset(FILE *fd, const char *type) } /* if type is given (not NULL) choose the simulation that matches type, else take the first one */ /* if xctx->graph_sim_type is set skip all datasets that do not match */ - else if(!strncmp(line, "Plotname:", 9) && strstr(line, "Transient Analysis")) { + else if(!strncmp(line, "Plotname:", 9) && strstr(lowerline, "transient analysis")) { if(xctx->graph_sim_type && strcmp(xctx->graph_sim_type, "tran")) xctx->graph_sim_type = NULL; else if(type && !strcmp(type, "tran")) xctx->graph_sim_type = "tran"; else if(type && strcmp(type, "tran")) xctx->graph_sim_type = NULL; else xctx->graph_sim_type = "tran"; dbg(dbglev, "read_dataset(): tran graph_sim_type=%s\n", xctx->graph_sim_type ? xctx->graph_sim_type : ""); } - else if(!strncmp(line, "Plotname:", 9) && strstr(line, "DC transfer characteristic")) { + else if(!strncmp(line, "Plotname:", 9) && strstr(lowerline, "dc transfer characteristic")) { if(xctx->graph_sim_type && strcmp(xctx->graph_sim_type, "dc")) xctx->graph_sim_type = NULL; else if(type && !strcmp(type, "dc")) xctx->graph_sim_type = "dc"; else if(type && strcmp(type, "dc")) xctx->graph_sim_type = NULL; else xctx->graph_sim_type = "dc"; dbg(dbglev, "read_dataset(): dc graph_sim_type=%s\n", xctx->graph_sim_type ? xctx->graph_sim_type : ""); } - else if(!strncmp(line, "Plotname:", 9) && strstr(line, "Operating Point")) { + else if(!strncmp(line, "Plotname:", 9) && strstr(lowerline, "operating point")) { if(xctx->graph_sim_type && strcmp(xctx->graph_sim_type, "op")) xctx->graph_sim_type = NULL; else if(type && !strcmp(type, "op")) xctx->graph_sim_type = "op"; else if(type && strcmp(type, "op")) xctx->graph_sim_type = NULL; else xctx->graph_sim_type = "op"; dbg(dbglev, "read_dataset(): op graph_sim_type=%s\n", xctx->graph_sim_type ? xctx->graph_sim_type : ""); } - else if(!strncmp(line, "Plotname:", 9) && strstr(line, "AC Analysis")) { + else if(!strncmp(line, "Plotname:", 9) && strstr(lowerline, "ac analysis")) { ac = 1; if(xctx->graph_sim_type && strcmp(xctx->graph_sim_type, "ac")) xctx->graph_sim_type = NULL; else if(type && !strcmp(type, "ac")) xctx->graph_sim_type = "ac"; @@ -431,6 +433,7 @@ static int read_dataset(FILE *fd, const char *type) if(xctx->graph_sim_type && !done_header && variables) { /* get the list of lines with index and node name */ if(!xctx->graph_names) xctx->graph_names = my_calloc(426, xctx->graph_nvars, sizeof(char *)); + my_realloc(1249, &varname, strlen(line) + 1) ; n = sscanf(line, "%d %s", &i, varname); /* read index and name of saved waveform */ if(n < 2) { dbg(0, "read_dataset(): WAARNING: malformed raw file, aborting\n"); @@ -463,7 +466,10 @@ static int read_dataset(FILE *fd, const char *type) if(xctx->graph_sim_type && !strncmp(line, "Variables:", 10)) { variables = 1 ; } - } + my_free(969, &line); + } /* while((line = my_fgets(fd)) */ + my_free(1248, &lowerline); + my_free(1382, &varname); if(exit_status == 0 && xctx->graph_datasets && xctx->graph_npoints) { dbg(dbglev, "raw file read: datasets=%d, last dataset points=%d, nvars=%d\n", xctx->graph_datasets, xctx->graph_npoints[xctx->graph_datasets-1], xctx->graph_nvars); diff --git a/src/xschem.h b/src/xschem.h index 4e055f94..4dcfc6ae 100644 --- a/src/xschem.h +++ b/src/xschem.h @@ -1336,6 +1336,7 @@ extern size_t my_snprintf(char *str, size_t size, const char *fmt, ...); extern size_t my_strdup(int id, char **dest, const char *src); extern void my_strndup(int id, char **dest, const char *src, size_t n); extern size_t my_strdup2(int id, char **dest, const char *src); +extern char *my_fgets(FILE *fd); extern char *my_strtok_r(char *str, const char *delim, const char *quote, char **saveptr); extern int my_strncpy(char *d, const char *s, size_t n); extern int my_strcasecmp(const char *s1, const char *s2); @@ -1347,7 +1348,7 @@ extern char* strtoupper(char* s); extern void *my_malloc(int id, size_t size); extern void my_realloc(int id, void *ptr,size_t size); extern void *my_calloc(int id, size_t nmemb, size_t size); -extern void my_free(int id, void *ptr); +extern char *my_free(int id, void *ptr); extern size_t my_strcat(int id, char **, const char *); extern size_t my_mstrcat(int id, char **str, const char *append_str, ...); extern char *my_itoa(int i); diff --git a/tests/xschemtest.tcl b/tests/xschemtest.tcl index 25682c21..f826d401 100644 --- a/tests/xschemtest.tcl +++ b/tests/xschemtest.tcl @@ -190,10 +190,10 @@ proc test_xschem_simulation {{f simulate_ff.sch}} { proc netlist_test {} { global netlist_dir foreach {f t h} { - rom8k.sch spice 1975420796 + rom8k.sch spice 2260553850 greycnt.sch verilog 2415454714 autozero_comp.sch spice 1181616733 - loading.sch vhdl 584526899 + loading.sch vhdl 3300682141 mos_power_ampli.sch spice 1004049459 hierarchical_tedax.sch tedax 998070173 LCC_instances.sch spice 2610855064