If ngSpice_Command(NULL) is sent to shared ngspice,
the internal control structure memory is freed.
This commit is contained in:
parent
ada7c54263
commit
ded0092ad6
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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 <setjmp.h>
|
||||
#include <signal.h>
|
||||
#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 <veliaa@rpi.edu> */
|
||||
/* from spice3f4 patch to ng-spice. jmr */
|
||||
#include <readline/readline.h>
|
||||
#include <readline/history.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_BSDEDITLINE
|
||||
/* SJB added edit line support 2005-05-05 */
|
||||
#include <editline/readline.h>
|
||||
#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 <setjmp.h>
|
||||
#include <signal.h>
|
||||
#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 <veliaa@rpi.edu> */
|
||||
/* from spice3f4 patch to ng-spice. jmr */
|
||||
#include <readline/readline.h>
|
||||
#include <readline/history.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_BSDEDITLINE
|
||||
/* SJB added edit line support 2005-05-05 */
|
||||
#include <editline/readline.h>
|
||||
#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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in New Issue