diff --git a/src/ciderlib/support/logfile.c b/src/ciderlib/support/logfile.c index ba42a1309..6222790c1 100644 --- a/src/ciderlib/support/logfile.c +++ b/src/ciderlib/support/logfile.c @@ -8,6 +8,7 @@ Author: 1992 David A. Gates, U. C. Berkeley CAD Group static char *LogFileName = "cider.log"; static int LogError = 0; +extern char *set_output_path(char *filename); void LOGmakeEntry(char *name, char *description) @@ -27,14 +28,17 @@ LOGmakeEntry(char *name, char *description) #ifdef ultrix if ((fpLog = fopen(LogFileName, "A")) == NULL) { #else - if ((fpLog = fopen(LogFileName, "a")) == NULL) { + /* add user defined path (nname has to be freed after usage) */ + char *nname = set_output_path(LogFileName); + if ((fpLog = fopen(nname, "a")) == NULL) { #endif if (!LogError) - perror(LogFileName); + perror(nname); LogError = 1; } else { fprintf(fpLog, "<%05d> %s: %s\n", procStamp, name, description); fclose(fpLog); LogError = 0; } + tfree(nname); } diff --git a/src/frontend/hpgl.c b/src/frontend/hpgl.c index bb5761a76..f9833202d 100644 --- a/src/frontend/hpgl.c +++ b/src/frontend/hpgl.c @@ -116,11 +116,14 @@ GL_NewViewport(GRAPH *graph) { hcopygraphid = graph->graphid; - if ((plotfile = fopen((char*) graph->devdep, "w")) == NULL) { - perror((char*) graph->devdep); - graph->devdep = NULL; + /* add user defined path (nname has to be freed after usage) */ + char *nname = set_output_path(graph->devdep); + if ((plotfile = fopen((char*) nname, "w")) == NULL) { + perror(nname); + tfree(nname); return (1); } + tfree(nname); if (graph->absolute.width) { /* hardcopying from the screen */ diff --git a/src/frontend/inp.c b/src/frontend/inp.c index 680e93837..18f606d8f 100644 --- a/src/frontend/inp.c +++ b/src/frontend/inp.c @@ -678,7 +678,10 @@ inp_spsource(FILE *fp, bool comfile, char *filename, bool intfile) /* print out the expanded deck into debug-out2.txt */ if (ft_ngdebug) { /*debug: print into file*/ - FILE *fdo = fopen("debug-out2.txt", "w"); + /* add user defined path (nname has to be freed after usage) */ + char *nname = set_output_path("debug-out2.txt"); + FILE *fdo = fopen(nname, "w"); + tfree(nname); if (!fdo) fprintf(cp_err, "Could not open file debug-out2.txt for writing debug info. \n"); else { @@ -832,7 +835,10 @@ inp_spsource(FILE *fp, bool comfile, char *filename, bool intfile) /* print out the expanded deck into debug-out3.txt */ if (ft_ngdebug) { /*debug: print into file*/ - FILE *fdo = fopen("debug-out3.txt", "w"); + /* add user defined path (nname has to be freed after usage) */ + char *nname = set_output_path("debug-out3.txt"); + FILE *fdo = fopen(nname, "w"); + tfree(nname); if (!fdo) fprintf(cp_err, "Could not open file debug-out3.txt for writing debug info. \n"); else { diff --git a/src/frontend/inpcom.c b/src/frontend/inpcom.c index d2bbd6874..d780214e7 100644 --- a/src/frontend/inpcom.c +++ b/src/frontend/inpcom.c @@ -640,8 +640,11 @@ inp_readall(FILE *fp, char *dir_name, bool comfile, bool intfile, bool *expr_w_t if (ft_ngdebug) { /*debug: print into file*/ - FILE *fd = fopen("debug-out.txt", "w"); - if(!fd) + /* add user defined path (nname has to be freed after usage) */ + char *nname = set_output_path("debug-out.txt"); + FILE *fd = fopen(nname, "w"); + tfree(nname); + if (!fd) fprintf(cp_err, "Could not open file debug-out.txt for writing debug info. \n"); else { struct line *t; @@ -5707,7 +5710,16 @@ tprint(struct line *t, int numb) char *filename = tprintf("tprint-out%d.txt", numb); /*debug: print into file*/ - FILE *fd = fopen(filename, "w"); + /* add user defined path (nname has to be freed after usage) */ + char *nname = set_output_path(filename); + FILE *fd = fopen(nname, "w"); + tfree(nname); + if (!fd) { + fprintf(cp_err, "Could not open file debug file %s for writing debug info. \n", filename); + tfree(filename); + return; + } + tfree(filename); for (tmp = t; tmp; tmp = tmp->li_next) if (*(tmp->li_line) != '*') { fprintf(fd, "%6d %6d %s", tmp->li_linenum_orig, tmp->li_linenum, tmp->li_line); @@ -5729,7 +5741,6 @@ tprint(struct line *t, int numb) if (*(tmp->li_line) != '*') fprintf(fd, "%s\n",tmp->li_line); fclose(fd); - tfree(filename); } diff --git a/src/frontend/numparam/spicenum.c b/src/frontend/numparam/spicenum.c index ed37d4429..7437e856a 100644 --- a/src/frontend/numparam/spicenum.c +++ b/src/frontend/numparam/spicenum.c @@ -426,8 +426,11 @@ putlogfile(char c, int num, char *t) if (!logfileS) { char *fname = tprintf("logfile.%d", ++nblogS); - logfileS = fopen(fname, "w"); + /* add user defined path (nname has to be freed after usage) */ + char *nname = set_output_path(fname); + logfileS = fopen(nname, "w"); tfree(fname); + tfree(nname); } if (logfileS) diff --git a/src/frontend/plotting/gnuplot.c b/src/frontend/plotting/gnuplot.c index c4f3eca7c..0af2151b1 100644 --- a/src/frontend/plotting/gnuplot.c +++ b/src/frontend/plotting/gnuplot.c @@ -124,11 +124,15 @@ ft_gnuplot(double *xlims, double *ylims, char *filename, char *title, char *xlab return; } + /* add user defined path (nname has to be freed after usage) */ + char *nname = set_output_path(filename_plt); /* Open the output gnuplot file. */ - if ((file = fopen(filename_plt, "w")) == NULL) { - perror(filename); + if ((file = fopen(nname, "w")) == NULL) { + perror(nname); + tfree(nname); return; } + tfree(nname); /* Set up the file header. */ #if !defined(__MINGW32__) && !defined(_MSC_VER) @@ -210,11 +214,15 @@ ft_gnuplot(double *xlims, double *ylims, char *filename, char *title, char *xlab strcpy(plotstyle, "lines"); } + /* add user defined path (nname has to be freed after usage) */ + nname = set_output_path(filename_data); /* Open the output gnuplot data file. */ - if ((file_data = fopen(filename_data, "w")) == NULL) { - perror(filename); + if ((file_data = fopen(nname, "w")) == NULL) { + perror(nname); + tfree(nname); return; } + tfree(nname); fprintf(file, "set format y \"%%g\"\n"); fprintf(file, "set format x \"%%g\"\n"); fprintf(file, "plot "); @@ -357,11 +365,15 @@ ft_writesimple(double *xlims, double *ylims, char *filename, char *title, char * maxlen = MAX(v->v_scale->v_length, maxlen); } + /* add user defined path (nname has to be freed after usage) */ + char *nname = set_output_path(filename); /* Open the output data file. */ - if ((file_data = fopen(filename, appendwrite ? "a" : "w")) == NULL) { - perror(filename); + if ((file_data = fopen(nname, appendwrite ? "a" : "w")) == NULL) { + perror(nname); + tfree(nname); return; } + tfree(nname); /* If option numdgt is set, use it for printout precision. */ if (cp_numdgt > 0) diff --git a/src/frontend/plotting/plot5.c b/src/frontend/plotting/plot5.c index f07b26426..068e871fc 100644 --- a/src/frontend/plotting/plot5.c +++ b/src/frontend/plotting/plot5.c @@ -45,11 +45,15 @@ Plt5_Init(void) int Plt5_NewViewport(GRAPH *graph) { - if ((plotfile = fopen((char*) graph->devdep, "w")) == NULL) { + /* add user defined path (nname has to be freed after usage) */ + char *nname = set_output_path((char*) graph->devdep); + if ((plotfile = fopen(nname, "w")) == NULL) { graph->devdep = NULL; perror((char*) graph->devdep); + tfree(nname); return (1); } + tfree(nname); if (graph->absolute.width) { diff --git a/src/frontend/plotting/xgraph.c b/src/frontend/plotting/xgraph.c index 216bd650b..2255e3546 100644 --- a/src/frontend/plotting/xgraph.c +++ b/src/frontend/plotting/xgraph.c @@ -13,6 +13,7 @@ Author: 1992 David A. Gates, U. C. Berkeley CAD Group #include "ngspice/dvec.h" #include "ngspice/fteparse.h" #include "xgraph.h" +#include "ngspice/fteext.h" #define XG_MAXVECTORS 64 @@ -80,10 +81,14 @@ ft_xgraph(double *xlims, double *ylims, char *filename, char *title, char *xlabe } /* Open the output file. */ - if ((file = fopen(filename, "w")) == NULL) { + /* add user defined path (nname has to be freed after usage) */ + char *nname = set_output_path(filename); + if ((file = fopen(nname, "w")) == NULL) { perror(filename); + tfree(nname); return; } + tfree(nname); /* Set up the file header. */ if (title) { diff --git a/src/frontend/postsc.c b/src/frontend/postsc.c index 94aa27962..0fd873b40 100644 --- a/src/frontend/postsc.c +++ b/src/frontend/postsc.c @@ -168,11 +168,15 @@ PS_NewViewport(GRAPH *graph) int x1, x2, y1, y2; hcopygraphid = graph->graphid; /* devdep initially contains name of output file */ - if ((plotfile = fopen((char*)graph->devdep, "w")) == NULL) { + /* add user defined path (nname has to be freed after usage) */ + char *nname = set_output_path((char*)graph->devdep); + if ((plotfile = fopen(nname, "w")) == NULL) { perror((char*)graph->devdep); graph->devdep = NULL; + tfree(nname); return (1); } + tfree(nname); if (graph->absolute.width) { /* hardcopying from the screen */ diff --git a/src/frontend/rawfile.c b/src/frontend/rawfile.c index 6eb0993b8..a8af304e4 100644 --- a/src/frontend/rawfile.c +++ b/src/frontend/rawfile.c @@ -18,6 +18,7 @@ Author: 1986 Wayne A. Christopher, U. C. Berkeley CAD Group #include "rawfile.h" #include "variable.h" #include "../misc/misc_time.h" +#include static void fixdims(struct dvec *v, char *s); @@ -755,10 +756,15 @@ spar_write(char *name, struct plot *pl, double Rbaseval) }*/ } - if ((fp = fopen(name, "w")) == NULL) { - perror(name); + /* add user defined path (nnmae has to be freed after usage) */ + char *nname = set_output_path(name); + + if ((fp = fopen(nname, "w")) == NULL) { + perror(nname); + tfree(nname); return; } + tfree(nname); fprintf(fp, "!2-port S-parameter file\n"); fprintf(fp, "!Title: %s\n", pl->pl_title); @@ -812,6 +818,9 @@ char * set_output_path(char *filename) { char varpath[BSIZE_SP]; + char *ret; + struct stat st; + char *fpath, *dirloc = NULL; #if defined(__MINGW32__) || defined(_MSC_VER) /* If variable 'mingwpath' is set: convert mingw /d/... to d:/... */ @@ -825,11 +834,32 @@ set_output_path(char *filename) #endif if (is_absolute_pathname(filename)) - return copy(filename); + ret = copy(filename); else if (cp_getvar("outputpath", CP_STRING, &varpath)) - return tprintf("%s/%s", varpath, filename); + ret = tprintf("%s%c%s", varpath, DIR_TERM, filename); else if (Outp_Path) - return tprintf("%s/%s", Outp_Path, filename); + ret = tprintf("%s%c%s", Outp_Path, DIR_TERM, filename); else - return copy(filename); + ret = copy(filename); + /* get path string */ + dirloc = strrchr(ret, DIR_TERM); +#if defined(__MINGW32__) || defined(_MSC_VER) + if(!dirloc) + dirloc = strrchr(ret, DIR_TERM_LINUX); +#endif + if (dirloc) + fpath = copy_substring(ret, dirloc); + else + fpath = copy(ret); + /* test if path exists */ + if (stat(fpath, &st) == 0) { + tfree(fpath); + return ret; + } + else { + fprintf(cp_err, "Error: Output path %s does not exist\n", fpath); + tfree(ret); + tfree(fpath); + controlled_exit(1); + } } diff --git a/src/frontend/runcoms.c b/src/frontend/runcoms.c index d8cede126..3e508323c 100644 --- a/src/frontend/runcoms.c +++ b/src/frontend/runcoms.c @@ -261,33 +261,41 @@ dosim( if (dofile) { if (!*wl->wl_word) rawfileFp = stdout; -#if defined(__MINGW32__) || defined(_MSC_VER) /* ask if binary or ASCII, open file with wb or w */ - else if (ascii) { - if ((rawfileFp = fopen(wl->wl_word, "w")) == NULL) { - perror(wl->wl_word); - ft_setflag = FALSE; - return 1; + else { + /* add user defined path (nname has to be freed after usage) */ + char *nname = set_output_path(wl->wl_word); +#if defined(__MINGW32__) || defined(_MSC_VER) + if (ascii) { + if ((rawfileFp = fopen(nname, "w")) == NULL) { + perror(wl->wl_word); + ft_setflag = FALSE; + tfree(nname); + return 1; + } + fprintf(cp_out, "ASCII raw file \"%s\"\n", nname); } - fprintf(cp_out, "ASCII raw file \"%s\"\n", wl->wl_word); - } - else if (!ascii) { - if ((rawfileFp = fopen(wl->wl_word, "wb")) == NULL) { - perror(wl->wl_word); - ft_setflag = FALSE; - return 1; + else { + if ((rawfileFp = fopen(nname, "wb")) == NULL) { + perror(wl->wl_word); + ft_setflag = FALSE; + tfree(nname); + return 1; + } + fprintf(cp_out, "binary raw file \"%s\"\n", nname); } - fprintf(cp_out, "binary raw file \"%s\"\n", wl->wl_word); - } /*---------------------------------------------------------------------------*/ #else - else if (!(rawfileFp = fopen(wl->wl_word, "w"))) { - setvbuf(rawfileFp, rawfileBuf, _IOFBF, RAWBUF_SIZE); - perror(wl->wl_word); - ft_setflag = FALSE; - return 1; - } + if (!(rawfileFp = fopen(nname, "w"))) { + setvbuf(rawfileFp, rawfileBuf, _IOFBF, RAWBUF_SIZE); + perror(wl->wl_word); + ft_setflag = FALSE; + tfree(nname); + return 1; + } #endif /* __MINGW32__ */ + tfree(nname); + } rawfileBinary = !ascii; } else { rawfileFp = NULL; diff --git a/src/frontend/runcoms2.c b/src/frontend/runcoms2.c index 91efd3e49..a9f7cbe23 100644 --- a/src/frontend/runcoms2.c +++ b/src/frontend/runcoms2.c @@ -106,30 +106,41 @@ com_resume(wordlist *wl) rawfileFp = stdout; #if defined(__MINGW32__) || defined(_MSC_VER) /* ask if binary or ASCII, open file with w or wb hvogt 15.3.2000 */ - else if (ascii) { - if ((rawfileFp = fopen(last_used_rawfile, "a")) == NULL) { - setvbuf(rawfileFp, rawfileBuf, _IOFBF, RAWBUF_SIZE); - perror(last_used_rawfile); - ft_setflag = FALSE; - return; + else { + /* add user defined path (nname has to be freed after usage) */ + char *nname = set_output_path(last_used_rawfile); + if (ascii) { + if ((rawfileFp = fopen(nname, "a")) == NULL) { + setvbuf(rawfileFp, rawfileBuf, _IOFBF, RAWBUF_SIZE); + perror(last_used_rawfile); + ft_setflag = FALSE; + tfree(nname); + return; + } } - } else if (!ascii) { - if ((rawfileFp = fopen(last_used_rawfile, "ab")) == NULL) { - setvbuf(rawfileFp, rawfileBuf, _IOFBF, RAWBUF_SIZE); - perror(last_used_rawfile); - ft_setflag = FALSE; - return; + else { + if ((rawfileFp = fopen(nname, "ab")) == NULL) { + setvbuf(rawfileFp, rawfileBuf, _IOFBF, RAWBUF_SIZE); + perror(last_used_rawfile); + ft_setflag = FALSE; + tfree(nname); + return; + } } - } - /*---------------------------------------------------------------------------*/ + /*---------------------------------------------------------------------------*/ #else - else if (!(rawfileFp = fopen(last_used_rawfile, "a"))) { - setvbuf(rawfileFp, rawfileBuf, _IOFBF, RAWBUF_SIZE); - perror(last_used_rawfile); - ft_setflag = FALSE; - return; - } + else { + char *nname = set_output_path(last_used_rawfile); + if (!(rawfileFp = fopen(nname, "a"))) { + setvbuf(rawfileFp, rawfileBuf, _IOFBF, RAWBUF_SIZE); + perror(last_used_rawfile); + ft_setflag = FALSE; + tfree(nname); + return; + } #endif + tfree(nname); + } rawfileBinary = !ascii; } else { rawfileFp = NULL; diff --git a/src/frontend/spiceif.c b/src/frontend/spiceif.c index 4eaf32f11..a406ae6ff 100644 --- a/src/frontend/spiceif.c +++ b/src/frontend/spiceif.c @@ -1620,9 +1620,10 @@ void com_snsave(wordlist *wl) fprintf(cp_err, "Only saving of tran analysis is implemented\n"); return; } - - file = fopen(wl->wl_word, "wb"); - + /* add user defined path (nname has to be freed after usage) */ + char *nname = set_output_path(wl->wl_word); + file = fopen(nname, "wb"); + tfree(nname); if (!file) { fprintf(cp_err, "Error: Couldn't open \"%s\" for writing\n", wl->wl_word); diff --git a/src/frontend/streams.c b/src/frontend/streams.c index 8906fd33c..80ebe0336 100644 --- a/src/frontend/streams.c +++ b/src/frontend/streams.c @@ -11,6 +11,7 @@ #include "quote.h" #include "ngspice/cpextern.h" #include "streams.h" +#include "ngspice/fteext.h" bool cp_debug = FALSE; @@ -134,9 +135,11 @@ cp_redirect(wordlist *wl) fprintf(stderr, "Error: %s: file exists\n", fname); goto error; } - - fp = fopen(fname, append ? "a" : "w+"); + /* add user defined path (nname has to be freed after usage) */ + char *nname = set_output_path(fname); + fp = fopen(nname, append ? "a" : "w+"); tfree(fname); + tfree(nname); if (!fp) { perror(fname); diff --git a/src/main.c b/src/main.c index 707ef7799..dc8b30f47 100644 --- a/src/main.c +++ b/src/main.c @@ -1039,7 +1039,10 @@ main(int argc, char **argv) /* Open the log file */ #ifdef HAS_WINGUI /* flogp used by winmain's putc which writes to file 'log_file' */ - flogp = fopen(log_file, "w"); + /* add user defined path (nname has to be freed after usage) */ + char *nname = set_output_path(log_file); + flogp = fopen(nname, "w"); + tfree(nname); if (!flogp) { perror(log_file); sp_shutdown(EXIT_BAD); @@ -1060,8 +1063,11 @@ main(int argc, char **argv) fprintf(stdout, "\nSOA warnings go to log-file: %s\n", soa_log_file); + /* add user defined path (nname has to be freed after usage) */ + char *nname = set_output_path(soa_log_file); /* Open the soa log file */ - slogp = fopen(soa_log_file, "w"); + slogp = fopen(nname, "w"); + tfree(nname); if (!slogp) { perror(soa_log_file); sp_shutdown(EXIT_BAD); @@ -1229,7 +1235,10 @@ main(int argc, char **argv) if (tempfile == NULL) { tpf = smktemp("sp"); - tempfile = fopen(tpf, "w+bTD"); + /* add user defined path (nname has to be freed after usage) */ + char *nname = set_output_path(tpf); + tempfile = fopen(nname, "w+bTD"); + tfree(nname); if (tempfile == NULL) { fprintf(stderr, "Could not open a temporary file to save and use optional arguments."); sp_shutdown(EXIT_BAD); diff --git a/src/maths/sparse/spoutput.c b/src/maths/sparse/spoutput.c index dc0832395..d5ee6c477 100644 --- a/src/maths/sparse/spoutput.c +++ b/src/maths/sparse/spoutput.c @@ -60,6 +60,7 @@ int Printer_Width = PRINTER_WIDTH; #include "ngspice/wstdio.h" #endif +extern char *set_output_path(char *filename); #if DOCUMENTATION @@ -449,8 +450,13 @@ spFileMatrix(MatrixPtr Matrix, char *File, char *Label, int Reordered, assert( IS_SPARSE( Matrix ) ); /* Open file matrix file in write mode. */ - if ((pMatrixFile = fopen(File, "w")) == NULL) + /* add user defined path (nname has to be freed after usage) */ + char *nname = set_output_path(File); + if ((pMatrixFile = fopen(nname, "w")) == NULL) { + SP_FREE(nname); return 0; + } + SP_FREE(nname); /* Output header. */ Size = Matrix->Size; @@ -604,10 +610,13 @@ spFileVector(MatrixPtr Matrix, char *File, RealVector RHS, RealVector iRHS) assert( IS_SPARSE( Matrix ) && RHS != NULL); if (File) { + /* add user defined path (nname has to be freed after usage) */ + char *nname = set_output_path(File); /* Open File in append mode. */ - pMatrixFile = fopen(File,"a"); + pMatrixFile = fopen(nname,"a"); + SP_FREE(nname); if (pMatrixFile == NULL) - return 0; + return 0; } else pMatrixFile=stdout;