add command 'circbyline' to allow entering circuit
line by line
This commit is contained in:
parent
8ec5bacc3a
commit
7d948f3455
|
|
@ -146,6 +146,10 @@ struct comm spcp_coms[] = {
|
|||
{ 1, 040000, 040000, 040000 }, E_DEFHMASK, 2, 2,
|
||||
NULL,
|
||||
"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,
|
||||
{ 02, 04, 04, 04 }, E_ADVANCED, 0, LOTS,
|
||||
NULL,
|
||||
|
|
|
|||
|
|
@ -263,7 +263,7 @@ ft_cpinit(void)
|
|||
if ((fp = fopen(buf, "r")) != NULL) {
|
||||
|
||||
cp_interactive = FALSE;
|
||||
inp_spsource(fp, TRUE, buf);
|
||||
inp_spsource(fp, TRUE, buf, FALSE);
|
||||
cp_interactive = TRUE;
|
||||
found = TRUE;
|
||||
break;
|
||||
|
|
@ -276,7 +276,7 @@ ft_cpinit(void)
|
|||
} else if ((fp = fopen("./spinit", "r")) != NULL) {
|
||||
#endif
|
||||
cp_interactive = FALSE;
|
||||
inp_spsource(fp, TRUE, buf);
|
||||
inp_spsource(fp, TRUE, buf, FALSE);
|
||||
cp_interactive = TRUE;
|
||||
found = TRUE;
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -1464,7 +1464,7 @@ com_alter_mod(wordlist *wl)
|
|||
modfile = inp_pathopen(filename, readmode);
|
||||
{
|
||||
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);
|
||||
}
|
||||
tfree(input);
|
||||
|
|
|
|||
|
|
@ -278,11 +278,12 @@ line_free_x(struct line *deck, bool recurse)
|
|||
* .plot, to perform after the run is over.
|
||||
* Then, we run dodeck, which parses up the deck. */
|
||||
void
|
||||
inp_spsource(FILE *fp, bool comfile, char *filename)
|
||||
inp_spsource(FILE *fp, bool comfile, char *filename, bool intfile)
|
||||
/* arguments:
|
||||
* *fp = pointer to the input file
|
||||
* comfile = whether it is a command file. Values are TRUE/FALSE
|
||||
* *filename = name of input file
|
||||
*fp = pointer to the input file
|
||||
comfile = whether it is a command file. Values are TRUE/FALSE
|
||||
*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;
|
||||
|
|
@ -301,13 +302,14 @@ inp_spsource(FILE *fp, bool comfile, char *filename)
|
|||
char *dir_name = ngdirname(filename ? filename : ".");
|
||||
|
||||
startTime = seconds();
|
||||
deck = inp_readall(fp, 0, dir_name, comfile);
|
||||
deck = inp_readall(fp, 0, dir_name, comfile, intfile);
|
||||
endTime = seconds();
|
||||
tfree(dir_name);
|
||||
|
||||
/* if nothing came back from inp_readall, just close fp and return to caller */
|
||||
if (!deck) { /* MW. We must close fp always when returning */
|
||||
fclose(fp);
|
||||
if (!intfile)
|
||||
fclose(fp);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -321,7 +323,8 @@ inp_spsource(FILE *fp, bool comfile, char *filename)
|
|||
if (!deck->li_next)
|
||||
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
|
||||
are done with the source we'll put the old file descriptors
|
||||
|
|
@ -976,7 +979,7 @@ com_edit(wordlist *wl)
|
|||
cp_interactive = inter;
|
||||
return;
|
||||
}
|
||||
inp_spsource(fp, FALSE, wl->wl_word);
|
||||
inp_spsource(fp, FALSE, wl->wl_word, FALSE);
|
||||
} else {
|
||||
/* If there is no circuit yet, then create one */
|
||||
if (ft_curckt && ft_curckt->ci_filename) {
|
||||
|
|
@ -1016,7 +1019,7 @@ com_edit(wordlist *wl)
|
|||
cp_interactive = inter;
|
||||
return;
|
||||
}
|
||||
inp_spsource(fp, FALSE, permfile ? filename : NULL);
|
||||
inp_spsource(fp, FALSE, permfile ? filename : NULL, FALSE);
|
||||
|
||||
/* fclose(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. */
|
||||
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
|
||||
inp_spsource(fp, FALSE, tempfile ? NULL : wl->wl_word);
|
||||
inp_spsource(fp, FALSE, tempfile ? NULL : wl->wl_word, FALSE);
|
||||
|
||||
cp_interactive = inter;
|
||||
if (tempfile)
|
||||
|
|
@ -1161,3 +1164,42 @@ cktislinear(CKTcircuit *ckt, struct line *deck)
|
|||
|
||||
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,6 @@
|
|||
void com_listing(wordlist *wl);
|
||||
void com_edit(wordlist *wl);
|
||||
void com_source(wordlist *wl);
|
||||
|
||||
void com_circbyline(wordlist *wl);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -170,10 +170,10 @@ read_a_lib(char *y, int call_depth, char *dir_name)
|
|||
|
||||
if (dir_name_flag == FALSE) {
|
||||
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);
|
||||
} 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);
|
||||
|
|
@ -332,11 +332,12 @@ expand_section_references(int line_number)
|
|||
debug printout to debug-out.txt
|
||||
*-------------------------------------------------------------------------*/
|
||||
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,
|
||||
call_depth: in, nested call to fcn
|
||||
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;
|
||||
|
|
@ -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_orig = 1, line_number_inc = 1;
|
||||
unsigned int no_braces = 0; /* number of '{' */
|
||||
int cirlinecount = 0; /* length of circarray */
|
||||
|
||||
size_t max_line_length; /* max. line length in input deck */
|
||||
|
||||
|
|
@ -371,47 +373,55 @@ inp_readall(FILE *fp, int call_depth, char *dir_name, bool comfile)
|
|||
|
||||
/* First read in all lines & put them in the struct cc */
|
||||
for (;;) {
|
||||
|
||||
#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;
|
||||
/* derive lines from circarray */
|
||||
if (intfile) {
|
||||
buffer = circarray[cirlinecount++];
|
||||
if (!buffer) {
|
||||
tfree(circarray);
|
||||
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 */
|
||||
#else
|
||||
|
||||
buffer = readline(fp);
|
||||
if(!buffer)
|
||||
break;
|
||||
|
||||
buffer = readline(fp);
|
||||
if(!buffer)
|
||||
break;
|
||||
#endif
|
||||
|
||||
}
|
||||
#ifdef TRACE
|
||||
/* SDB debug statement */
|
||||
printf("in inp_readall, just read %s", buffer);
|
||||
|
|
@ -554,10 +564,10 @@ inp_readall(FILE *fp, int call_depth, char *dir_name, bool comfile)
|
|||
|
||||
if (dir_name_flag == FALSE) {
|
||||
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);
|
||||
} 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);
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ inp_nutsource(FILE *fp, bool comfile, char *filename)
|
|||
wordlist *controls = NULL;
|
||||
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)
|
||||
return;
|
||||
|
||||
|
|
|
|||
|
|
@ -203,12 +203,14 @@ extern bool gr_circular;
|
|||
void inp_dodeck(struct line *deck, char *tt, wordlist *end, bool reuse,
|
||||
struct line *options, char *filename);
|
||||
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_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 char** circarray;
|
||||
|
||||
/* nutinp.c */
|
||||
|
||||
void inp_nutsource(FILE *fp, bool comfile, char *filename);
|
||||
|
|
|
|||
|
|
@ -1222,10 +1222,10 @@ main(int argc, char **argv)
|
|||
if (tempfile && (!err || !ft_batchmode)) {
|
||||
#if defined(HAS_WINDOWS) || defined(_MSC_VER) || defined(__MINGW32__)
|
||||
/* Copy the input file name for adding another file search path */
|
||||
inp_spsource(tempfile, FALSE, dname);
|
||||
inp_spsource(tempfile, FALSE, dname, FALSE);
|
||||
tfree(dname);
|
||||
#else
|
||||
inp_spsource(tempfile, FALSE, NULL);
|
||||
inp_spsource(tempfile, FALSE, NULL, FALSE);
|
||||
#endif
|
||||
gotone = TRUE;
|
||||
}
|
||||
|
|
@ -1236,7 +1236,7 @@ main(int argc, char **argv)
|
|||
} /* --- if (!ft_servermode) --- */
|
||||
|
||||
if (!gotone && ft_batchmode)
|
||||
inp_spsource(circuit_file, FALSE, NULL);
|
||||
inp_spsource(circuit_file, FALSE, NULL, FALSE);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue