Make the ngSpice_Circ(char** circa) more robust:

Error message when .end card is missing
Reset if .end card is missing, to allow loading
a netlist again.
NULL as last element is no longer required, but .end card
(this has been implicitedly assumed).
Remove a bug that skippoed the last line (the .end card).
This commit is contained in:
Holger Vogt 2020-11-21 13:58:57 +01:00
parent fd79e4b5c4
commit 87751ad073
3 changed files with 27 additions and 7 deletions

View File

@ -55,7 +55,7 @@ static struct card *mc_deck = NULL;
static struct card *recent_deck = NULL;
static void cktislinear(CKTcircuit *ckt, struct card *deck);
void create_circbyline(char *line);
void create_circbyline(char *line, bool reset, bool lastline);
static bool doedit(char *filename);
static void dotifeval(struct card *deck);
static void eval_agauss(struct card *deck, char *fcn);
@ -1716,11 +1716,17 @@ static void cktislinear(CKTcircuit *ckt, struct card *deck)
char **circarray;
void create_circbyline(char *line)
void create_circbyline(char *line, bool reset, bool lastline)
{
static unsigned int linec = 0;
static unsigned int n_elem_alloc = 0;
if (reset) {
linec = 0;
n_elem_alloc = 0;
tfree(circarray);
}
/* Ensure up to 2 cards can be added */
if (n_elem_alloc < linec + 2) {
n_elem_alloc = n_elem_alloc == 0 ? 256 : 2 * n_elem_alloc;
@ -1754,6 +1760,10 @@ void create_circbyline(char *line)
linec = 0;
n_elem_alloc = 0;
}
/* If the .end statement is missing */
else if (lastline) {
fprintf(stderr, "Error: .end statement is missing in netlist!\n");
}
} /* end of function create_circbyline */
@ -1766,7 +1776,7 @@ void com_circbyline(wordlist *wl)
This memory will be released line by line in inp_source(). */
char *newline = wl_flatten(wl);
create_circbyline(newline);
create_circbyline(newline, FALSE, FALSE);
}
/* handle .if('expr') ... .elseif('expr') ... .else ... .endif statements.

View File

@ -371,7 +371,7 @@ int ngSpice_Init_Evt(SendEvtData* sevtdata, SendInitEvtData* sinitevtdata, void
/* send a circuit to ngspice.dll
The circuit description is a dynamic array
of char*. Each char* corresponds to a single circuit
line. The last entry of the array has to be a NULL */
line. The last entry of the array has to be a .end card. */
IMPEXP
int ngSpice_Circ(char** circarray);

View File

@ -194,7 +194,7 @@ extern struct comm spcp_coms[ ];
extern void DevInit(void);
extern int SIMinit(IFfrontEnd *frontEnd, IFsimulator **simulator);
extern wordlist *cp_varwl(struct variable *var);
extern void create_circbyline(char *line);
extern void create_circbyline(char *line, bool reset, bool lastline);
void exec_controls(wordlist *shcontrols);
void rem_controls(void);
@ -971,6 +971,7 @@ IMPEXP
int ngSpice_Circ(char** circa){
int entries = 0, i;
char* newline;
bool reset = FALSE, lastline = FALSE;
if ( ! setjmp(errbufm) ) {
intermj = 0;
@ -978,14 +979,23 @@ int ngSpice_Circ(char** circa){
/* count the entries */
while (circa[entries]) {
entries++;
char* line = circa[entries - 1];
if (ciprefix(".end", line) && (line[4] == '\0' || isspace_c(line[4])))
break;
}
entries--; /* don't send the empty line */
if (ft_ngdebug)
fprintf(stdout, "\nngspiceCirc: received netlist array with %d entries\n", entries);
/* create a local copy (to be freed in inpcom.c) */
for (i = 0; i < entries; i++) {
newline = copy(circa[i]);
create_circbyline(newline);
if (i == 0)
reset = TRUE;
else
reset = FALSE;
if (i == entries - 1)
lastline = TRUE;
create_circbyline(newline, reset, lastline);
}
return 0;
}