diff --git a/src/frontend/control.c b/src/frontend/control.c index 157a43b75..253ff9ca5 100644 --- a/src/frontend/control.c +++ b/src/frontend/control.c @@ -647,7 +647,7 @@ cp_evloop(char *string) freewl = wlist = getcommand(string); if (wlist == NULL) { /* End of file or end of user input. */ if (cend[stackp] && cend[stackp]->co_parent && !string) { - cp_resetcontrol(); + cp_resetcontrol(TRUE); continue; } else { @@ -889,13 +889,15 @@ cp_evloop(char *string) /* This blows away the control structures... */ -void cp_resetcontrol(void) +void cp_resetcontrol(bool warn) { - fprintf(cp_err, "Warning: clearing control structures\n"); - if (cend[stackp] && cend[stackp]->co_parent) - fprintf(cp_err, "Warning: EOF before block terminated\n"); - /* We probably should free the control structures... */ - cp_free_control(); /* va: free it */ + if (warn) { + fprintf(cp_err, "Warning: clearing control structures\n"); + if (cend[stackp] && cend[stackp]->co_parent) + fprintf(cp_err, "Warning: EOF before block terminated\n"); + } + /* free the control structures */ + cp_free_control(); control[0] = cend[0] = NULL; stackp = 0; cp_kwswitch(CT_LABEL, NULL); diff --git a/src/frontend/signal_handler.c b/src/frontend/signal_handler.c index 6a53c633f..a4b24532a 100644 --- a/src/frontend/signal_handler.c +++ b/src/frontend/signal_handler.c @@ -1,178 +1,178 @@ -/********** -Copyright 1990 Regents of the University of California. All rights reserved. -Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group -**********/ - -/* - * The signal routines for spice 3 and nutmeg. - */ - -#include "ngspice/ngspice.h" -#include "ngspice/ifsim.h" -#include "ngspice/iferrmsg.h" -#include "ngspice/cpdefs.h" -#include "ngspice/ftedefs.h" -#include "ngspice/ftedev.h" -#include -#include -#include "signal_handler.h" -#include "plotting/graf.h" - -#ifdef HAS_WINGUI -void winmessage(char* new_msg); -#endif - -#ifdef HAVE_GNUREADLINE -/* Added GNU Readline Support 11/3/97 -- Andrew Veliath */ -/* from spice3f4 patch to ng-spice. jmr */ -#include -#include -#endif - -#ifdef HAVE_BSDEDITLINE -/* SJB added edit line support 2005-05-05 */ -#include -#endif /* HAVE_BSDEDITLINE */ - -JMP_BUF jbuf; - -/* The (void) signal handlers... SIGINT is the only one that gets reset (by - * cshpar) so it is global. They are ifdef BSD because of the sigmask - * stuff in sigstop. We set the interrupt flag and return if ft_setflag - * is TRUE. - */ - - -/* The purpose of ft_sigintr_cleanup() is to handle all processing of asynchronous - * signals which require user process context. Some kernel services are not - * allowed to be called from asynchronous signal handlers. (e.g. mutexes) - */ - -void -ft_sigintr_cleanup(void) -{ - gr_clean(); /* Clean up plot window */ - - /* sjb - what to do for editline??? - The following are not supported in editline */ -#if defined(HAVE_GNUREADLINE) - /* Clean up readline after catching signals */ - /* One or all of these might be superfluous */ - (void) rl_free_line_state(); - (void) rl_cleanup_after_signal(); - (void) rl_reset_after_signal(); -#endif /* defined(HAVE_GNUREADLINE) || defined(HAVE_BSDEDITLINE) */ - - /* To restore screen after an interrupt to a plot for instance */ - cp_interactive = TRUE; - cp_resetcontrol(); -} - - -/* invoke this function upon keyboard interrupt */ -RETSIGTYPE -ft_sigintr(void) -{ - static int interrupt_counter = 0; - - /* fprintf(cp_err, "Received interrupt. Handling it . . . . .\n"); */ - - /* Reinstall ft_signintr as the signal handler. */ - (void) signal(SIGINT, (SIGNAL_FUNCTION) ft_sigintr); - - if (ft_intrpt) { /* check to see if we're being interrupted repeatedly */ - fprintf(cp_err, "\nInterrupted again (ouch)\n"); - interrupt_counter++; - } else { - fprintf(cp_err, "\nInterrupted once . . .\n"); - ft_intrpt = TRUE; - interrupt_counter = 1; - } - - if (interrupt_counter >= 3) { - fprintf(cp_err, "\nKilling, since %d interrupts have been requested\n\n", interrupt_counter); - controlled_exit(1); - } - - if (ft_setflag) { - return; /* just return without aborting simulation if ft_setflag = TRUE */ - } - - /* here we jump to the start of command processing in main() after resetting everything. */ - LONGJMP(jbuf, 1); -} - - -RETSIGTYPE -sigfloat(int sig, int code) -{ - NG_IGNORE(sig); - - fperror("Error", code); - rewind(cp_out); - (void) signal(SIGFPE, (SIGNAL_FUNCTION) sigfloat); - LONGJMP(jbuf, 1); -} - - -/* This should give a new prompt if cshpar is waiting for input. */ - -#ifdef SIGTSTP - -RETSIGTYPE -sigstop(void) -{ - gr_clean(); - cp_ccon(FALSE); - (void) signal(SIGTSTP, SIG_DFL); - (void) kill(getpid(), SIGTSTP); /* This should stop us */ -} - - -RETSIGTYPE -sigcont(void) -{ - (void) signal(SIGTSTP, (SIGNAL_FUNCTION) sigstop); - if (cp_cwait) - LONGJMP(jbuf, 1); -} - - -#endif - - -/* Special (void) signal handlers. */ - -RETSIGTYPE -sigill(void) -{ - fprintf(cp_err, "\ninternal error -- illegal instruction\n"); - fatal(); -} - - -RETSIGTYPE -sigbus(void) -{ - fprintf(cp_err, "\ninternal error -- bus error\n"); - fatal(); -} - - -RETSIGTYPE -sigsegv(void) -{ - fprintf(cp_err, "\ninternal error -- segmentation violation\n"); -#ifdef HAS_WINGUI - winmessage("Fatal error in NGSPICE"); -#endif - fatal(); -} - - -RETSIGTYPE -sig_sys(void) -{ - fprintf(cp_err, "\ninternal error -- bad argument to system call\n"); - fatal(); -} +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group +**********/ + +/* + * The signal routines for spice 3 and nutmeg. + */ + +#include "ngspice/ngspice.h" +#include "ngspice/ifsim.h" +#include "ngspice/iferrmsg.h" +#include "ngspice/cpdefs.h" +#include "ngspice/ftedefs.h" +#include "ngspice/ftedev.h" +#include +#include +#include "signal_handler.h" +#include "plotting/graf.h" + +#ifdef HAS_WINGUI +void winmessage(char* new_msg); +#endif + +#ifdef HAVE_GNUREADLINE +/* Added GNU Readline Support 11/3/97 -- Andrew Veliath */ +/* from spice3f4 patch to ng-spice. jmr */ +#include +#include +#endif + +#ifdef HAVE_BSDEDITLINE +/* SJB added edit line support 2005-05-05 */ +#include +#endif /* HAVE_BSDEDITLINE */ + +JMP_BUF jbuf; + +/* The (void) signal handlers... SIGINT is the only one that gets reset (by + * cshpar) so it is global. They are ifdef BSD because of the sigmask + * stuff in sigstop. We set the interrupt flag and return if ft_setflag + * is TRUE. + */ + + +/* The purpose of ft_sigintr_cleanup() is to handle all processing of asynchronous + * signals which require user process context. Some kernel services are not + * allowed to be called from asynchronous signal handlers. (e.g. mutexes) + */ + +void +ft_sigintr_cleanup(void) +{ + gr_clean(); /* Clean up plot window */ + + /* sjb - what to do for editline??? + The following are not supported in editline */ +#if defined(HAVE_GNUREADLINE) + /* Clean up readline after catching signals */ + /* One or all of these might be superfluous */ + (void) rl_free_line_state(); + (void) rl_cleanup_after_signal(); + (void) rl_reset_after_signal(); +#endif /* defined(HAVE_GNUREADLINE) || defined(HAVE_BSDEDITLINE) */ + + /* To restore screen after an interrupt to a plot for instance */ + cp_interactive = TRUE; + cp_resetcontrol(TRUE); +} + + +/* invoke this function upon keyboard interrupt */ +RETSIGTYPE +ft_sigintr(void) +{ + static int interrupt_counter = 0; + + /* fprintf(cp_err, "Received interrupt. Handling it . . . . .\n"); */ + + /* Reinstall ft_signintr as the signal handler. */ + (void) signal(SIGINT, (SIGNAL_FUNCTION) ft_sigintr); + + if (ft_intrpt) { /* check to see if we're being interrupted repeatedly */ + fprintf(cp_err, "\nInterrupted again (ouch)\n"); + interrupt_counter++; + } else { + fprintf(cp_err, "\nInterrupted once . . .\n"); + ft_intrpt = TRUE; + interrupt_counter = 1; + } + + if (interrupt_counter >= 3) { + fprintf(cp_err, "\nKilling, since %d interrupts have been requested\n\n", interrupt_counter); + controlled_exit(1); + } + + if (ft_setflag) { + return; /* just return without aborting simulation if ft_setflag = TRUE */ + } + + /* here we jump to the start of command processing in main() after resetting everything. */ + LONGJMP(jbuf, 1); +} + + +RETSIGTYPE +sigfloat(int sig, int code) +{ + NG_IGNORE(sig); + + fperror("Error", code); + rewind(cp_out); + (void) signal(SIGFPE, (SIGNAL_FUNCTION) sigfloat); + LONGJMP(jbuf, 1); +} + + +/* This should give a new prompt if cshpar is waiting for input. */ + +#ifdef SIGTSTP + +RETSIGTYPE +sigstop(void) +{ + gr_clean(); + cp_ccon(FALSE); + (void) signal(SIGTSTP, SIG_DFL); + (void) kill(getpid(), SIGTSTP); /* This should stop us */ +} + + +RETSIGTYPE +sigcont(void) +{ + (void) signal(SIGTSTP, (SIGNAL_FUNCTION) sigstop); + if (cp_cwait) + LONGJMP(jbuf, 1); +} + + +#endif + + +/* Special (void) signal handlers. */ + +RETSIGTYPE +sigill(void) +{ + fprintf(cp_err, "\ninternal error -- illegal instruction\n"); + fatal(); +} + + +RETSIGTYPE +sigbus(void) +{ + fprintf(cp_err, "\ninternal error -- bus error\n"); + fatal(); +} + + +RETSIGTYPE +sigsegv(void) +{ + fprintf(cp_err, "\ninternal error -- segmentation violation\n"); +#ifdef HAS_WINGUI + winmessage("Fatal error in NGSPICE"); +#endif + fatal(); +} + + +RETSIGTYPE +sig_sys(void) +{ + fprintf(cp_err, "\ninternal error -- bad argument to system call\n"); + fatal(); +} diff --git a/src/frontend/vectors.c b/src/frontend/vectors.c index 99bb47d77..d6ef08bbd 100644 --- a/src/frontend/vectors.c +++ b/src/frontend/vectors.c @@ -757,7 +757,7 @@ plot_docoms(wordlist *wl) (void) cp_evloop(wl->wl_word); wl = wl->wl_next; } - cp_resetcontrol(); + cp_resetcontrol(TRUE); cp_interactive = inter; } diff --git a/src/include/ngspice/cpextern.h b/src/include/ngspice/cpextern.h index 539ea9c9f..fedf26307 100644 --- a/src/include/ngspice/cpextern.h +++ b/src/include/ngspice/cpextern.h @@ -72,7 +72,7 @@ extern bool cp_dounixcom; extern char *cp_csep; extern char * get_alt_prompt(void); extern int cp_evloop(char *string); -extern void cp_resetcontrol(void); +extern void cp_resetcontrol(bool warn); extern void cp_toplevel(void); extern void cp_popcontrol(void); extern void cp_pushcontrol(void); diff --git a/src/sharedspice.c b/src/sharedspice.c index eea42015f..839db8c43 100644 --- a/src/sharedspice.c +++ b/src/sharedspice.c @@ -905,15 +905,17 @@ sh_delete_myvec(void) } /* retrieve a ngspice command from caller and run it -immediately */ + immediately. + If NULL is sent, we clear the command memory */ IMPEXP int ngSpice_Command(char* comexec) { - /* Check if command is reasonable */ + /* delete existing command memory */ if (comexec == NULL) { - fprintf(stderr, "Warning: Received command NULL, ignored"); - return 1; + cp_resetcontrol(FALSE); + return 0; } + /* Check if command is reasonable */ if (*comexec == '\0') { fprintf(stderr, "Warning: Received empty string as command, ignored"); return 1;