add command 'circbyline' to allow entering circuit

line by line
This commit is contained in:
h_vogt 2013-03-06 23:01:37 +01:00
parent 8ec5bacc3a
commit 7d948f3455
9 changed files with 119 additions and 61 deletions

View File

@ -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,

View File

@ -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;

View File

@ -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);

View File

@ -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);
}

View File

@ -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

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -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);
}