From bef157aacf0740ba8ed916d8a83d48970e1f90ed Mon Sep 17 00:00:00 2001 From: stefan schippers Date: Fri, 15 Mar 2024 11:56:35 +0100 Subject: [PATCH] More return codes when something goes wrong, like loading failure of a file given on cmdline --- doc/xschem_man/developer_info.html | 5 ++++- src/actions.c | 2 +- src/main.c | 4 ++-- src/save.c | 15 +++++++++------ src/scheduler.c | 14 +++++++++----- src/xinit.c | 22 ++++++++++++---------- src/xschem.h | 2 +- xschem_library/examples/0_examples_top.sch | 5 ++--- 8 files changed, 40 insertions(+), 29 deletions(-) diff --git a/doc/xschem_man/developer_info.html b/doc/xschem_man/developer_info.html index a9976ff0..30cbbf37 100644 --- a/doc/xschem_man/developer_info.html +++ b/doc/xschem_man/developer_info.html @@ -680,8 +680,9 @@ C {verilog_timescale.sym} 1050 -100 0 0 {name=s1 timestep="1ns" precision="1ns"
  • escape_chars source [charset]
  •     escape tcl special characters with backslash
        if charset is given escape characters in charset 
    -
  • exit [closewindow] [force]
  • +   
  • exit [exit_code] [closewindow] [force]
  •     Exit the program, ask for confirm if current file modified.
    +   if exit_code is given exit with its value, otherwise use 0 exit code
        if 'closewindow' is given close the window, otherwise leave with a blank schematic
        when closing the last remaining window
        if 'force' is given do not ask before closing modified schematic windows/tabs
    @@ -1589,6 +1590,8 @@ C {verilog_timescale.sym} 1050 -100 0 0 {name=s1 timestep="1ns" precision="1ns"
     
     
     
    +
    +
     
     
     
    diff --git a/src/actions.c b/src/actions.c
    index 1ff48a57..7f0daeae 100644
    --- a/src/actions.c
    +++ b/src/actions.c
    @@ -457,7 +457,7 @@ void new_xschem_process(const char *cell, int symbol)
       } else {
         /* error */
         fprintf(errfp, "new_xschem_process(): fork error 2\n");
    -    tcleval("exit");
    +    tcleval("exit 1");
       }
     }
     #else
    diff --git a/src/main.c b/src/main.c
    index 914107da..3f284a7c 100644
    --- a/src/main.c
    +++ b/src/main.c
    @@ -43,7 +43,7 @@ static void sig_handler(int s){
                  get_cell(xctx->sch[xctx->currsch], 0));
         if( !(emergency_dir = create_tmpdir(emergency_prefix)) ) {
           fprintf(errfp, "xinit(): problems creating emergency save dir\n");
    -      tcleval("exit");
    +      tcleval("exit 1");
         }
       
         if(rename(xctx->undo_dirname, emergency_dir)) {
    @@ -153,6 +153,6 @@ int main(int argc, char **argv)
         if(has_x) Tk_Main(1, argv, Tcl_AppInit);
         else     Tcl_Main(1, argv, Tcl_AppInit);
       }
    -  return 0;
    +  return(0);
     }
     
    diff --git a/src/save.c b/src/save.c
    index 8431cc3d..14439e35 100644
    --- a/src/save.c
    +++ b/src/save.c
    @@ -3060,13 +3060,13 @@ void link_symbols_to_instances(int from)
     
     /* ALWAYS use absolute pathname for fname!!!
      * alert = 0 --> do not show alert if file not existing */
    -void load_schematic(int load_symbols, const char *fname, int reset_undo, int alert)
    +int load_schematic(int load_symbols, const char *fname, int reset_undo, int alert)
     {
       FILE *fd;
       char name[PATH_MAX];
       char msg[PATH_MAX+100];
       struct stat buf;
    -  int i;
    +  int i, ret = 1; /* success */
       
       xctx->prep_hi_structs=0;
       xctx->prep_net_structs=0;
    @@ -3122,7 +3122,7 @@ void load_schematic(int load_symbols, const char *fname, int reset_undo, int ale
     
         dbg(1, "load_schematic(): opening file for loading:%s, fname=%s\n", name, fname);
         dbg(1, "load_schematic(): sch[currsch]=%s\n", xctx->sch[xctx->currsch]);
    -    if(!name[0]) return; /* empty filename */
    +    if(!name[0]) return 0; /* empty filename */
         if(reset_undo) {
           if(!stat(name, &buf)) { /* file exists */
             xctx->time_last_modify =  buf.st_mtime;
    @@ -3141,10 +3141,13 @@ void load_schematic(int load_symbols, const char *fname, int reset_undo, int ale
         }
         else fd=fopen(name,fopen_read_mode);
         if( fd == NULL) {
    +      ret = 0;
           if(alert) {
             fprintf(errfp, "load_schematic(): unable to open file: %s, fname=%s\n", name, fname );
    -        my_snprintf(msg, S(msg), "update; alert_ {Unable to open file: %s}", fname);
    -        tcleval(msg);
    +        if(has_x) {
    +          my_snprintf(msg, S(msg), "update; alert_ {Unable to open file: %s}", fname);
    +          tcleval(msg);
    +        }
           }
           clear_drawing();
           if(reset_undo) set_modify(0);
    @@ -3206,7 +3209,7 @@ void load_schematic(int load_symbols, const char *fname, int reset_undo, int ale
       }
       /* set local simulation directory if local_netlist_dir is set*/
       if(reset_undo) set_netlist_dir(2, NULL);
    -
    +  return ret;
     }
     
     void clear_undo(void)
    diff --git a/src/scheduler.c b/src/scheduler.c
    index e1e1bcd7..64498c16 100644
    --- a/src/scheduler.c
    +++ b/src/scheduler.c
    @@ -843,8 +843,9 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
           }
         }
     
    -    /* exit [closewindow] [force]
    +    /* exit [exit_code] [closewindow] [force]
          *   Exit the program, ask for confirm if current file modified.
    +     *   if exit_code is given exit with its value, otherwise use 0 exit code
          *   if 'closewindow' is given close the window, otherwise leave with a blank schematic
          *   when closing the last remaining window
          *   if 'force' is given do not ask before closing modified schematic windows/tabs
    @@ -853,11 +854,14 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
         {
           int closewindow = 0;
           int force = 0;
    +      const char *exit_status = "0";
    +      
     
           if(!xctx) {Tcl_SetResult(interp, not_avail, TCL_STATIC); return TCL_ERROR;}
           for(i = 2; i < argc; ++i) {
             if(!strcmp(argv[i], "closewindow")) closewindow = 1;
             if(!strcmp(argv[i], "force")) force = 1;
    +        if(strpbrk(argv[i], "0123456789-")) exit_status = argv[i];
           }     
           if(!strcmp(xctx->current_win_path, ".drw")) {
             /* non tabbed interface */
    @@ -883,7 +887,7 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
                             ": UNSAVED data: want to exit?\"");
                 }
                 if(force || !xctx->modified || !strcmp(tclresult(), "ok")) {
    -               if(closewindow) tcleval("exit");
    +               if(closewindow) tclvareval("exit ", exit_status, NULL);
                    else clear_schematic(0, 0);
                 }
               }
    @@ -910,7 +914,7 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
                             ": UNSAVED data: want to exit?\"");
                 }
                 if(!has_x || force || !xctx->modified || !strcmp(tclresult(), "ok")) {
    -               if(closewindow) tcleval("exit");
    +               if(closewindow) tclvareval("exit ", exit_status, NULL);
                    else clear_schematic(0, 0);
                 }
               }
    @@ -1449,7 +1453,7 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
                   if(ret_val > MAX_PATH || (ret_val == 0)) {
                     Tcl_SetResult(interp, "xschem get temp_dir failed\n", TCL_STATIC);
                     fprintf(errfp, "xschem get temp_dir: path error\n");
    -                tcleval("exit");
    +                tcleval("exit 1");
                   }
                   else {
                     char s[MAX_PATH];
    @@ -1458,7 +1462,7 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
                     if(err != 0) {
                       Tcl_SetResult(interp, "xschem get temp_dir conversion failed\n", TCL_STATIC);
                       fprintf(errfp, "xschem get temp_dir: conversion error\n");
    -                  tcleval("exit");
    +                  tcleval("exit 1");
                     }
                     else {
                       change_to_unix_fn(s);
    diff --git a/src/xinit.c b/src/xinit.c
    index cba04c6a..fefd045c 100644
    --- a/src/xinit.c
    +++ b/src/xinit.c
    @@ -2721,7 +2721,7 @@ int Tcl_AppInit(Tcl_Interp *inter)
         create_gc();
     
         dbg(1, "Tcl_AppInit(): done step c of xinit()\n");
    -    if(build_colors(0.0, 0.0)) exit(-1);
    +    if(build_colors(0.0, 0.0)) exit(1);
         dbg(1, "Tcl_AppInit(): done step e of xinit()\n");
         /* xctx->save_pixmap must be created as resetwin() frees it before recreating with new size. */
       }
    @@ -2815,7 +2815,7 @@ int Tcl_AppInit(Tcl_Interp *inter)
     
      if(cli_opt_filename[0]) {
         char f[PATH_MAX];
    -
    +    int file_loaded = 1;
        /* check if local_netlist_dir is set and set netlist_dir accordingly
         * following call is needed since load_schematic() may be called with 
         * reset_undo=0 and will not call set_netlist_dir */
    @@ -2844,13 +2844,15 @@ int Tcl_AppInit(Tcl_Interp *inter)
        remove_symbols();
        /* if cli_opt_do_netlist=1 call load_schematic with 'reset_undo=0' avoiding call 
           to tcl is_xschem_file that could change xctx->netlist_type to symbol */
    -   load_schematic(1, f, !cli_opt_do_netlist, 1);
    +   file_loaded = load_schematic(1, f, !cli_opt_do_netlist, 1);
    +   if(!file_loaded) tcleval("exit 1");
        if(cli_opt_do_netlist) set_modify(-1); /* set tab/window title */
        tclvareval("update_recent_file {", f, "}", NULL);
      } else /* if(!cli_opt_tcl_script[0]) */
      {
        char * tmp;
        char fname[PATH_MAX];
    +   int file_loaded = 1;
        tmp = (char *) tclgetvar("XSCHEM_START_WINDOW");
        #ifndef __unix__
        change_to_unix_fn(tmp);
    @@ -2859,7 +2861,8 @@ int Tcl_AppInit(Tcl_Interp *inter)
        my_strncpy(fname, abs_sym_path(tmp, ""), S(fname));
         /* if cli_opt_do_netlist=1 call load_schematic with 'reset_undo=0' avoiding call 
            to tcl is_xschem_file that could change xctx->netlist_type to symbol */
    -   load_schematic(1, fname, !cli_opt_do_netlist, 1);
    +   file_loaded = load_schematic(1, fname, !cli_opt_do_netlist, 1);
    +   if(!file_loaded) tcleval("exit 1");
        if(cli_opt_do_netlist) set_modify(-1); /* set tab/window title */
      }
      /* Necessary to tell xschem the initial area to display */
    @@ -2868,7 +2871,7 @@ int Tcl_AppInit(Tcl_Interp *inter)
      if(cli_opt_do_netlist) {
        if(!cli_opt_filename[0]) {
          fprintf(errfp, "xschem: cant do a netlist without a filename\n");
    -     tcleval("exit");
    +     tcleval("exit 1");
        }
        if(set_netlist_dir(0, NULL)) { /* necessary to create netlist dir if not existing */
          if(debug_var>=1) {
    @@ -2890,7 +2893,7 @@ int Tcl_AppInit(Tcl_Interp *inter)
      if(cli_opt_do_print) {
        if(!cli_opt_filename[0]) {
          dbg(0, "xschem: can't do a print without a filename\n");
    -     tcleval("exit");
    +     tcleval("exit 1");
        }
        if(cli_opt_do_print==1) {
     
    @@ -2915,7 +2918,6 @@ int Tcl_AppInit(Tcl_Interp *inter)
          }
        }
        else {
    -     tcleval("tkwait visibility .drw");
          svg_draw();
        }
      }
    @@ -2923,7 +2925,7 @@ int Tcl_AppInit(Tcl_Interp *inter)
      if(cli_opt_do_simulation) {
        if(!cli_opt_filename[0]) {
          fprintf(errfp, "xschem: can't do a simulation without a filename\n");
    -     tcleval("exit");
    +     tcleval("exit 1");
        }
        tcleval( "simulate");
      }
    @@ -2931,7 +2933,7 @@ int Tcl_AppInit(Tcl_Interp *inter)
      if(cli_opt_do_waves) {
        if(!cli_opt_filename[0]) {
          fprintf(errfp, "xschem: can't show simulation waves without a filename\n");
    -     tcleval("exit");
    +     tcleval("exit 1");
        }
        tcleval( "waves [file tail \"[xschem get schname]\"]");
      }
    @@ -2966,7 +2968,7 @@ int Tcl_AppInit(Tcl_Interp *inter)
      tcleval("eval_postinit_commands");
     
      if(cli_opt_quit) {
    -   tcleval("exit");
    +   tcleval("exit 0");
      }
     
     
    diff --git a/src/xschem.h b/src/xschem.h
    index e77060fa..19b81009 100644
    --- a/src/xschem.h
    +++ b/src/xschem.h
    @@ -1478,7 +1478,7 @@ extern void mem_push_undo(void);
     extern void mem_pop_undo(int redo, int set_modify_status);
     extern void mem_delete_undo(void);
     extern void mem_clear_undo(void);
    -extern void load_schematic(int load_symbol, const char *fname, int reset_undo, int alert);
    +extern int load_schematic(int load_symbol, const char *fname, int reset_undo, int alert);
     /* check if filename already in an open window/tab */
     extern int get_tab_or_window_number(const char *win_path);
     extern void swap_tabs(void);
    diff --git a/xschem_library/examples/0_examples_top.sch b/xschem_library/examples/0_examples_top.sch
    index 536090ca..0e198963 100644
    --- a/xschem_library/examples/0_examples_top.sch
    +++ b/xschem_library/examples/0_examples_top.sch
    @@ -122,8 +122,7 @@ C {loading.sym} 160 -860 0 0 {name=x9}
     C {inv_bsource.sym} 880 -320 0 0 {name=B1 TABLE="1.4 3.0 1.6 0.0"}
     C {launcher.sym} 460 -140 0 0 {name=h1 
     descr="XSCHEM ON REPO.HU" 
    -url="http://repo.hu/projects/xschem"
    -program=x-www-browser}
    +url="http://repo.hu/projects/xschem"}
     C {launcher.sym} 460 -90 0 0 {name=h3 
     descr="Toggle light/dark 
     colorscheme" 
    @@ -132,7 +131,7 @@ tclcommand="xschem toggle_colorscheme"
     C {launcher.sym} 460 -190 0 0 {name=h2 
     descr="LOCAL DOCUMENTATION" 
     url="$\{XSCHEM_SHAREDIR\}/../doc/xschem/index.html"
    -program=x-www-browser
    +
     
     }
     C {rlc.sym} 160 -900 0 0 {name=x0}