add command 'circbyline' to allow entering circuit line by line
This commit is contained in:
parent
b503ea2d12
commit
1e88db6f7d
|
|
@ -146,6 +146,10 @@ struct comm spcp_coms[] = {
|
||||||
{ 1, 040000, 040000, 040000 }, E_DEFHMASK, 2, 2,
|
{ 1, 040000, 040000, 040000 }, E_DEFHMASK, 2, 2,
|
||||||
NULL,
|
NULL,
|
||||||
"file : Load a snapshot." } ,
|
"file : Load a snapshot." } ,
|
||||||
|
{ "circbyline", com_circbyline, FALSE, TRUE,
|
||||||
|
{ 1, 040000, 040000, 040000 }, E_DEFHMASK, 1, LOTS,
|
||||||
|
NULL,
|
||||||
|
"line : Enter a circuit line." } ,
|
||||||
{ "alias", com_alias, FALSE, FALSE,
|
{ "alias", com_alias, FALSE, FALSE,
|
||||||
{ 02, 04, 04, 04 }, E_ADVANCED, 0, LOTS,
|
{ 02, 04, 04, 04 }, E_ADVANCED, 0, LOTS,
|
||||||
NULL,
|
NULL,
|
||||||
|
|
|
||||||
|
|
@ -263,7 +263,7 @@ ft_cpinit(void)
|
||||||
if ((fp = fopen(buf, "r")) != NULL) {
|
if ((fp = fopen(buf, "r")) != NULL) {
|
||||||
|
|
||||||
cp_interactive = FALSE;
|
cp_interactive = FALSE;
|
||||||
inp_spsource(fp, TRUE, buf);
|
inp_spsource(fp, TRUE, buf, FALSE);
|
||||||
cp_interactive = TRUE;
|
cp_interactive = TRUE;
|
||||||
found = TRUE;
|
found = TRUE;
|
||||||
break;
|
break;
|
||||||
|
|
@ -276,7 +276,7 @@ ft_cpinit(void)
|
||||||
} else if ((fp = fopen("./spinit", "r")) != NULL) {
|
} else if ((fp = fopen("./spinit", "r")) != NULL) {
|
||||||
#endif
|
#endif
|
||||||
cp_interactive = FALSE;
|
cp_interactive = FALSE;
|
||||||
inp_spsource(fp, TRUE, buf);
|
inp_spsource(fp, TRUE, buf, FALSE);
|
||||||
cp_interactive = TRUE;
|
cp_interactive = TRUE;
|
||||||
found = TRUE;
|
found = TRUE;
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -1464,7 +1464,7 @@ com_alter_mod(wordlist *wl)
|
||||||
modfile = inp_pathopen(filename, readmode);
|
modfile = inp_pathopen(filename, readmode);
|
||||||
{
|
{
|
||||||
char *dir_name = ngdirname(filename);
|
char *dir_name = ngdirname(filename);
|
||||||
modeldeck = inp_readall(modfile, 0, dir_name, 0);
|
modeldeck = inp_readall(modfile, 0, dir_name, 0, 0);
|
||||||
free(dir_name);
|
free(dir_name);
|
||||||
}
|
}
|
||||||
tfree(input);
|
tfree(input);
|
||||||
|
|
|
||||||
|
|
@ -278,11 +278,12 @@ line_free_x(struct line *deck, bool recurse)
|
||||||
* .plot, to perform after the run is over.
|
* .plot, to perform after the run is over.
|
||||||
* Then, we run dodeck, which parses up the deck. */
|
* Then, we run dodeck, which parses up the deck. */
|
||||||
void
|
void
|
||||||
inp_spsource(FILE *fp, bool comfile, char *filename)
|
inp_spsource(FILE *fp, bool comfile, char *filename, bool intfile)
|
||||||
/* arguments:
|
/* arguments:
|
||||||
* *fp = pointer to the input file
|
* *fp = pointer to the input file
|
||||||
* comfile = whether it is a command file. Values are TRUE/FALSE
|
* comfile = whether it is a command file. Values are TRUE/FALSE
|
||||||
* *filename = name of input file
|
* *filename = name of input file
|
||||||
|
* intfile = whether input is from internal array. Values are TRUE/FALSE
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
struct line *deck, *dd, *ld, *prev_param = NULL, *prev_card = NULL;
|
struct line *deck, *dd, *ld, *prev_param = NULL, *prev_card = NULL;
|
||||||
|
|
@ -301,13 +302,14 @@ inp_spsource(FILE *fp, bool comfile, char *filename)
|
||||||
char *dir_name = ngdirname(filename ? filename : ".");
|
char *dir_name = ngdirname(filename ? filename : ".");
|
||||||
|
|
||||||
startTime = seconds();
|
startTime = seconds();
|
||||||
deck = inp_readall(fp, 0, dir_name, comfile);
|
deck = inp_readall(fp, 0, dir_name, comfile, intfile);
|
||||||
endTime = seconds();
|
endTime = seconds();
|
||||||
tfree(dir_name);
|
tfree(dir_name);
|
||||||
|
|
||||||
/* if nothing came back from inp_readall, just close fp and return to caller */
|
/* if nothing came back from inp_readall, just close fp and return to caller */
|
||||||
if (!deck) { /* MW. We must close fp always when returning */
|
if (!deck) { /* MW. We must close fp always when returning */
|
||||||
fclose(fp);
|
if (!intfile)
|
||||||
|
fclose(fp);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -321,7 +323,8 @@ inp_spsource(FILE *fp, bool comfile, char *filename)
|
||||||
if (!deck->li_next)
|
if (!deck->li_next)
|
||||||
fprintf(cp_err, "Warning: no lines in input\n");
|
fprintf(cp_err, "Warning: no lines in input\n");
|
||||||
}
|
}
|
||||||
fclose(fp);
|
if (!intfile)
|
||||||
|
fclose(fp);
|
||||||
|
|
||||||
/* Now save the IO context and start a new control set. After we
|
/* Now save the IO context and start a new control set. After we
|
||||||
are done with the source we'll put the old file descriptors
|
are done with the source we'll put the old file descriptors
|
||||||
|
|
@ -976,7 +979,7 @@ com_edit(wordlist *wl)
|
||||||
cp_interactive = inter;
|
cp_interactive = inter;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
inp_spsource(fp, FALSE, wl->wl_word);
|
inp_spsource(fp, FALSE, wl->wl_word, FALSE);
|
||||||
} else {
|
} else {
|
||||||
/* If there is no circuit yet, then create one */
|
/* If there is no circuit yet, then create one */
|
||||||
if (ft_curckt && ft_curckt->ci_filename) {
|
if (ft_curckt && ft_curckt->ci_filename) {
|
||||||
|
|
@ -1016,7 +1019,7 @@ com_edit(wordlist *wl)
|
||||||
cp_interactive = inter;
|
cp_interactive = inter;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
inp_spsource(fp, FALSE, permfile ? filename : NULL);
|
inp_spsource(fp, FALSE, permfile ? filename : NULL, FALSE);
|
||||||
|
|
||||||
/* fclose(fp); */
|
/* fclose(fp); */
|
||||||
/* MW. inp_spsource already closed fp */
|
/* MW. inp_spsource already closed fp */
|
||||||
|
|
@ -1107,9 +1110,9 @@ com_source(wordlist *wl)
|
||||||
|
|
||||||
/* Don't print the title if this is a spice initialisation file. */
|
/* Don't print the title if this is a spice initialisation file. */
|
||||||
if (ft_nutmeg || substring(INITSTR, owl->wl_word) || substring(ALT_INITSTR, owl->wl_word))
|
if (ft_nutmeg || substring(INITSTR, owl->wl_word) || substring(ALT_INITSTR, owl->wl_word))
|
||||||
inp_spsource(fp, TRUE, tempfile ? NULL : wl->wl_word);
|
inp_spsource(fp, TRUE, tempfile ? NULL : wl->wl_word, FALSE);
|
||||||
else
|
else
|
||||||
inp_spsource(fp, FALSE, tempfile ? NULL : wl->wl_word);
|
inp_spsource(fp, FALSE, tempfile ? NULL : wl->wl_word, FALSE);
|
||||||
|
|
||||||
cp_interactive = inter;
|
cp_interactive = inter;
|
||||||
if (tempfile)
|
if (tempfile)
|
||||||
|
|
@ -1161,3 +1164,45 @@ cktislinear(CKTcircuit *ckt, struct line *deck)
|
||||||
|
|
||||||
ckt->CKTisLinear = 1;
|
ckt->CKTisLinear = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* global array for assembling circuit lines entered by fcn circbyline
|
||||||
|
or receiving array from external caller. Array is created once per ngspice call.
|
||||||
|
Last line of the array has to get the value NULL */
|
||||||
|
char **circarray;
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
create_circbyline(char *line)
|
||||||
|
{
|
||||||
|
static int linec = 0;
|
||||||
|
static int memlen = 256;
|
||||||
|
FILE *fp = NULL;
|
||||||
|
if (!circarray)
|
||||||
|
circarray = TMALLOC(char*, memlen);
|
||||||
|
circarray[linec++] = line;
|
||||||
|
if (linec < memlen) {
|
||||||
|
if (ciprefix(".end", line) && (line[4] == '\0' || isspace(line[4]))) {
|
||||||
|
circarray[linec] = NULL;
|
||||||
|
inp_spsource(fp, FALSE, "", TRUE);
|
||||||
|
linec = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
memlen += memlen;
|
||||||
|
circarray = TREALLOC(char*, circarray, memlen);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* fcn called by command 'circbyline' */
|
||||||
|
void
|
||||||
|
com_circbyline(wordlist *wl)
|
||||||
|
{
|
||||||
|
/* undo the automatic wordline creation.
|
||||||
|
wl_flatten allocates memory on the heap for each newline.
|
||||||
|
This memory will be released line by line in inp_source(). */
|
||||||
|
|
||||||
|
char *newline = wl_flatten(wl);
|
||||||
|
create_circbyline(newline);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@
|
||||||
void com_listing(wordlist *wl);
|
void com_listing(wordlist *wl);
|
||||||
void com_edit(wordlist *wl);
|
void com_edit(wordlist *wl);
|
||||||
void com_source(wordlist *wl);
|
void com_source(wordlist *wl);
|
||||||
|
void com_circbyline(wordlist *wl);
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -170,10 +170,10 @@ read_a_lib(char *y, int call_depth, char *dir_name)
|
||||||
|
|
||||||
if (dir_name_flag == FALSE) {
|
if (dir_name_flag == FALSE) {
|
||||||
char *y_dir_name = ngdirname(y);
|
char *y_dir_name = ngdirname(y);
|
||||||
library_deck[num_libraries-1] = inp_readall(newfp, call_depth+1, y_dir_name, FALSE);
|
library_deck[num_libraries-1] = inp_readall(newfp, call_depth+1, y_dir_name, FALSE, FALSE);
|
||||||
tfree(y_dir_name);
|
tfree(y_dir_name);
|
||||||
} else {
|
} else {
|
||||||
library_deck[num_libraries-1] = inp_readall(newfp, call_depth+1, dir_name, FALSE);
|
library_deck[num_libraries-1] = inp_readall(newfp, call_depth+1, dir_name, FALSE, FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
fclose(newfp);
|
fclose(newfp);
|
||||||
|
|
@ -332,11 +332,12 @@ expand_section_references(int line_number)
|
||||||
debug printout to debug-out.txt
|
debug printout to debug-out.txt
|
||||||
*-------------------------------------------------------------------------*/
|
*-------------------------------------------------------------------------*/
|
||||||
struct line *
|
struct line *
|
||||||
inp_readall(FILE *fp, int call_depth, char *dir_name, bool comfile)
|
inp_readall(FILE *fp, int call_depth, char *dir_name, bool comfile, bool intfile)
|
||||||
/* fp: in, pointer to file to be read,
|
/* fp: in, pointer to file to be read,
|
||||||
call_depth: in, nested call to fcn
|
call_depth: in, nested call to fcn
|
||||||
dir_name: in, name of directory of file to be read
|
dir_name: in, name of directory of file to be read
|
||||||
comfile: in, TRUE if command file (e.g. spinit, .spiceinit
|
comfile: in, TRUE if command file (e.g. spinit, .spiceinit)
|
||||||
|
intfile: in, TRUE if deck is generated from internal circarray
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
struct line *end = NULL, *cc = NULL, *prev, *working, *newcard, *global_card;
|
struct line *end = NULL, *cc = NULL, *prev, *working, *newcard, *global_card;
|
||||||
|
|
@ -353,6 +354,7 @@ inp_readall(FILE *fp, int call_depth, char *dir_name, bool comfile)
|
||||||
int line_number = 1; /* sjb - renamed to avoid confusion with struct line */
|
int line_number = 1; /* sjb - renamed to avoid confusion with struct line */
|
||||||
int line_number_orig = 1, line_number_inc = 1;
|
int line_number_orig = 1, line_number_inc = 1;
|
||||||
unsigned int no_braces = 0; /* number of '{' */
|
unsigned int no_braces = 0; /* number of '{' */
|
||||||
|
int cirlinecount = 0; /* length of circarray */
|
||||||
|
|
||||||
size_t max_line_length; /* max. line length in input deck */
|
size_t max_line_length; /* max. line length in input deck */
|
||||||
|
|
||||||
|
|
@ -371,46 +373,57 @@ inp_readall(FILE *fp, int call_depth, char *dir_name, bool comfile)
|
||||||
|
|
||||||
/* First read in all lines & put them in the struct cc */
|
/* First read in all lines & put them in the struct cc */
|
||||||
for (;;) {
|
for (;;) {
|
||||||
|
/* derive lines from circarray */
|
||||||
#ifdef XSPICE
|
if (intfile) {
|
||||||
/* gtri - modify - 12/12/90 - wbk - read from mailbox if ipc enabled */
|
buffer = circarray[cirlinecount++];
|
||||||
|
if (!buffer) {
|
||||||
/* If IPC is not enabled, do equivalent of what SPICE did before */
|
tfree(circarray);
|
||||||
if (! g_ipc.enabled) {
|
|
||||||
if (call_depth == 0 && line_count == 0) {
|
|
||||||
line_count++;
|
|
||||||
if (fgets(big_buff, 5000, fp))
|
|
||||||
buffer = copy(big_buff);
|
|
||||||
} else {
|
|
||||||
buffer = readline(fp);
|
|
||||||
if (!buffer)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
/* else, get the line from the ipc channel. */
|
|
||||||
/* We assume that newlines are not sent by the client */
|
|
||||||
/* so we add them here */
|
|
||||||
ipc_status = ipc_get_line(ipc_buffer, &ipc_len, IPC_WAIT);
|
|
||||||
if (ipc_status == IPC_STATUS_END_OF_DECK) {
|
|
||||||
buffer = NULL;
|
|
||||||
break;
|
break;
|
||||||
} else if (ipc_status == IPC_STATUS_OK) {
|
|
||||||
buffer = TMALLOC(char, strlen(ipc_buffer) + 3);
|
|
||||||
strcpy(buffer, ipc_buffer);
|
|
||||||
strcat(buffer, "\n");
|
|
||||||
} else { /* No good way to report this so just die */
|
|
||||||
controlled_exit(EXIT_FAILURE);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/* read lines from file fp */
|
||||||
|
else {
|
||||||
|
|
||||||
|
#ifdef XSPICE
|
||||||
|
/* gtri - modify - 12/12/90 - wbk - read from mailbox if ipc enabled */
|
||||||
|
|
||||||
|
/* If IPC is not enabled, do equivalent of what SPICE did before */
|
||||||
|
if (! g_ipc.enabled) {
|
||||||
|
if (call_depth == 0 && line_count == 0) {
|
||||||
|
line_count++;
|
||||||
|
if (fgets(big_buff, 5000, fp))
|
||||||
|
buffer = copy(big_buff);
|
||||||
|
} else {
|
||||||
|
buffer = readline(fp);
|
||||||
|
if (!buffer)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* else, get the line from the ipc channel. */
|
||||||
|
/* We assume that newlines are not sent by the client */
|
||||||
|
/* so we add them here */
|
||||||
|
ipc_status = ipc_get_line(ipc_buffer, &ipc_len, IPC_WAIT);
|
||||||
|
if (ipc_status == IPC_STATUS_END_OF_DECK) {
|
||||||
|
buffer = NULL;
|
||||||
|
break;
|
||||||
|
} else if (ipc_status == IPC_STATUS_OK) {
|
||||||
|
buffer = TMALLOC(char, strlen(ipc_buffer) + 3);
|
||||||
|
strcpy(buffer, ipc_buffer);
|
||||||
|
strcat(buffer, "\n");
|
||||||
|
} else { /* No good way to report this so just die */
|
||||||
|
controlled_exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* gtri - end - 12/12/90 */
|
/* gtri - end - 12/12/90 */
|
||||||
#else
|
#else
|
||||||
|
|
||||||
buffer = readline(fp);
|
buffer = readline(fp);
|
||||||
if(!buffer)
|
if(!buffer)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef TRACE
|
#ifdef TRACE
|
||||||
/* SDB debug statement */
|
/* SDB debug statement */
|
||||||
|
|
@ -554,10 +567,10 @@ inp_readall(FILE *fp, int call_depth, char *dir_name, bool comfile)
|
||||||
|
|
||||||
if (dir_name_flag == FALSE) {
|
if (dir_name_flag == FALSE) {
|
||||||
char *y_dir_name = ngdirname(y);
|
char *y_dir_name = ngdirname(y);
|
||||||
newcard = inp_readall(newfp, call_depth+1, y_dir_name, FALSE); /* read stuff in include file into netlist */
|
newcard = inp_readall(newfp, call_depth+1, y_dir_name, FALSE, FALSE); /* read stuff in include file into netlist */
|
||||||
tfree(y_dir_name);
|
tfree(y_dir_name);
|
||||||
} else {
|
} else {
|
||||||
newcard = inp_readall(newfp, call_depth+1, dir_name, FALSE); /* read stuff in include file into netlist */
|
newcard = inp_readall(newfp, call_depth+1, dir_name, FALSE, FALSE); /* read stuff in include file into netlist */
|
||||||
}
|
}
|
||||||
|
|
||||||
(void) fclose(newfp);
|
(void) fclose(newfp);
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ inp_nutsource(FILE *fp, bool comfile, char *filename)
|
||||||
wordlist *controls = NULL;
|
wordlist *controls = NULL;
|
||||||
FILE *lastin, *lastout, *lasterr;
|
FILE *lastin, *lastout, *lasterr;
|
||||||
|
|
||||||
deck = inp_readall(fp, 0, NULL, comfile); /* still to check if . or filename instead of NULL */
|
deck = inp_readall(fp, 0, NULL, comfile, FALSE); /* still to check if . or filename instead of NULL */
|
||||||
if (!deck)
|
if (!deck)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -203,12 +203,14 @@ extern bool gr_circular;
|
||||||
void inp_dodeck(struct line *deck, char *tt, wordlist *end, bool reuse,
|
void inp_dodeck(struct line *deck, char *tt, wordlist *end, bool reuse,
|
||||||
struct line *options, char *filename);
|
struct line *options, char *filename);
|
||||||
extern void inp_source(char *file);
|
extern void inp_source(char *file);
|
||||||
void inp_spsource(FILE *fp, bool comfile, char *filename);
|
void inp_spsource(FILE *fp, bool comfile, char *filename, bool intfile);
|
||||||
extern void inp_casefix(char *string);
|
extern void inp_casefix(char *string);
|
||||||
extern void inp_list(FILE *file, struct line *deck, struct line *extras, int type);
|
extern void inp_list(FILE *file, struct line *deck, struct line *extras, int type);
|
||||||
extern struct line *inp_readall(FILE *fp, int call_depth, char *dir_name, bool comfile);
|
extern struct line *inp_readall(FILE *fp, int call_depth, char *dir_name, bool comfile, bool intfile);
|
||||||
extern FILE *inp_pathopen(char *name, char *mode);
|
extern FILE *inp_pathopen(char *name, char *mode);
|
||||||
|
|
||||||
|
extern char** circarray;
|
||||||
|
|
||||||
/* nutinp.c */
|
/* nutinp.c */
|
||||||
|
|
||||||
void inp_nutsource(FILE *fp, bool comfile, char *filename);
|
void inp_nutsource(FILE *fp, bool comfile, char *filename);
|
||||||
|
|
|
||||||
|
|
@ -1222,10 +1222,10 @@ main(int argc, char **argv)
|
||||||
if (tempfile && (!err || !ft_batchmode)) {
|
if (tempfile && (!err || !ft_batchmode)) {
|
||||||
#if defined(HAS_WINDOWS) || defined(_MSC_VER) || defined(__MINGW32__)
|
#if defined(HAS_WINDOWS) || defined(_MSC_VER) || defined(__MINGW32__)
|
||||||
/* Copy the input file name for adding another file search path */
|
/* Copy the input file name for adding another file search path */
|
||||||
inp_spsource(tempfile, FALSE, dname);
|
inp_spsource(tempfile, FALSE, dname, FALSE);
|
||||||
tfree(dname);
|
tfree(dname);
|
||||||
#else
|
#else
|
||||||
inp_spsource(tempfile, FALSE, NULL);
|
inp_spsource(tempfile, FALSE, NULL, FALSE);
|
||||||
#endif
|
#endif
|
||||||
gotone = TRUE;
|
gotone = TRUE;
|
||||||
}
|
}
|
||||||
|
|
@ -1236,7 +1236,7 @@ main(int argc, char **argv)
|
||||||
} /* --- if (!ft_servermode) --- */
|
} /* --- if (!ft_servermode) --- */
|
||||||
|
|
||||||
if (!gotone && ft_batchmode)
|
if (!gotone && ft_batchmode)
|
||||||
inp_spsource(circuit_file, FALSE, NULL);
|
inp_spsource(circuit_file, FALSE, NULL, FALSE);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue