PATCH: using getopt(3) for command line parsing
Until now, ngspice (and thus nutmeg) used a homegrown way of parsing
the command line. The attached patch allows you to use the getopt
function available in the C library to do the command line parsing for
you.
I have very hard to make sure the patch is equivalent in functionality
to the previous parser. However, there are a number of other
relatively minor differences:
o The new parser accepts long versions of the old command switches.
All switches have a long name equivalent.
o The new parser is *case sensitive* to the command switches.
o The new parser introduces two new switches: a help swith (-h or
--help) and a version switch (-v or --version)
o The -m (master) switch didn't seem to do anything, so I removed
it. It wasn't documented in any way. If somebody misses it and can
explain its importance, I'm sure we can put it back in.
This patch also fixes the problem that the autogen.sh script was not
included in the list of files to be kept when doing a `make
distcheck'.
If you notice any other problems or bugs with this patch, I would like
to hear them. This patch is against ng-spice-rework-10.
Regards,
--
Arno
diff -ruN ng-spice-rework-10.orig/Makefile.am ng-spice-rework-10/Makefile.am
--- ng-spice-rework-10.orig/Makefile.am Tue Mar 28 21:39:34 2000
+++ ng-spice-rework-10/Makefile.am Sat Apr 15 20:58:04 2000
@@ -2,7 +2,7 @@
SUBDIRS = doc src man tests
-EXTRA_DIST = FAQ acconfig.h notes contrib
+EXTRA_DIST = FAQ acconfig.h autogen.sh notes contrib
MAINTAINERCLEANFILES = Makefile.in aclocal.m4 config.guess \
config.h.in config.sub configure install-sh \
diff -ruN ng-spice-rework-10.orig/autogen.sh ng-spice-rework-10/autogen.sh
--- ng-spice-rework-10.orig/autogen.sh Thu Jan 1 01:00:00 1970
+++ ng-spice-rework-10/autogen.sh Sat Apr 15 20:57:16 2000
@@ -0,0 +1,73 @@
+#!/bin/sh
+# Run this to generate all the initial makefiles, etc.
+
+PROJECT=ng-spice
+TEST_TYPE=-d
+FILE=src/circuit
+
+DIE=0
+
+(autoconf --version) < /dev/null > /dev/null 2>&1 || {
+ echo
+ echo "You must have autoconf installed to compile $PROJECT."
+ echo "Download the appropriate package for your distribution,"
+ echo "or get the source tarball at ftp://ftp.gnu.org/pub/gnu/"
+ DIE=1
+}
+
+(libtool --version) < /dev/null > /dev/null 2>&1 || {
+ echo
+ echo "You must have libtool installed to compile $PROJECT."
+ echo "Get ftp://alpha.gnu.org/gnu/libtool-1.0h.tar.gz"
+ echo "(or a newer version if it is available)"
+ DIE=1
+}
+
+(automake --version) < /dev/null > /dev/null 2>&1 || {
+ echo
+ echo "You must have automake installed to compile $PROJECT."
+ echo "Get ftp://ftp.cygnus.com/pub/home/tromey/automake-1.2d.tar.gz"
+ echo "(or a newer version if it is available)"
+ DIE=1
+}
+
+if test "$DIE" -eq 1; then
+ exit 1
+fi
+
+test $TEST_TYPE $FILE || {
+ echo "You must run this script in the top-level $PROJECT directory"
+ exit 1
+}
+
+if test -z "$*"; then
+ echo "I am going to run ./configure with no arguments - if you wish "
+ echo "to pass any to it, please specify them on the $0 command line."
+fi
+
+case $CC in
+*lcc | *lcc\ *) am_opt=--include-deps;;
+esac
+
+#echo "Running gettextize... Ignore non-fatal messages."
+# Hmm, we specify --force here, since otherwise things don't
+# get added reliably, but we don't want to overwrite intl
+# while making dist.
+#echo "no" | gettextize --copy --force
+
+echo "Running libtoolize"
+libtoolize --copy --force
+
+aclocal $ACLOCAL_FLAGS
+
+# optionally feature autoheader
+(autoheader --version) < /dev/null > /dev/null 2>&1 && autoheader
+
+automake -c -a $am_opt
+autoconf
+
+./configure "$@"
+
+echo
+echo "Now type 'make' to compile $PROJECT."
+
diff -ruN ng-spice-rework-10.orig/src/conf.c ng-spice-rework-10/src/conf.c
--- ng-spice-rework-10.orig/src/conf.c Sun Mar 26 12:30:42 2000
+++ ng-spice-rework-10/src/conf.c Sat Apr 15 21:42:21 2000
@@ -9,7 +9,6 @@
char Spice_Build_Date[ ] = NGSPICEBUILDDATE;
char *Spice_Exec_Dir = NGSPICEBINDIR;
char *Spice_Lib_Dir = NGSPICEDATADIR;
-char Spice_OptChar = '-';
char *Def_Editor = "vi";
int AsciiRawFile = 0;
diff -ruN ng-spice-rework-10.orig/src/conf.h ng-spice-rework-10/src/conf.h
--- ng-spice-rework-10.orig/src/conf.h Sun Mar 26 12:30:42 2000
+++ ng-spice-rework-10/src/conf.h Sat Apr 15 21:44:56 2000
@@ -6,7 +6,6 @@
char Spice_Build_Date[];
char *Spice_Exec_Dir;
char *Spice_Lib_Dir;
-char Spice_OptChar;
char *Def_Editor;
int AsciiRawFile;
diff -ruN ng-spice-rework-10.orig/src/devices/bsim3v1/Makefile.am
ng-spice-rework-10/src/devices/bsim3v1/Makefile.am
--- ng-spice-rework-10.orig/src/devices/bsim3v1/Makefile.am Sun Mar 26
12:30:44 2000
+++ ng-spice-rework-10/src/devices/bsim3v1/Makefile.am Sat Apr 15 20:59:48
+2000
@@ -28,3 +28,5 @@
INCLUDES = -I$(top_srcdir)/src/include
+
+MAINTAINERCLEANFILES = Makefile.in
diff -ruN ng-spice-rework-10.orig/src/devices/bsim3v2/Makefile.am
ng-spice-rework-10/src/devices/bsim3v2/Makefile.am
--- ng-spice-rework-10.orig/src/devices/bsim3v2/Makefile.am Sun Mar 26
12:30:44 2000
+++ ng-spice-rework-10/src/devices/bsim3v2/Makefile.am Sat Apr 15 21:01:07
+2000
@@ -28,3 +28,5 @@
INCLUDES = -I$(top_srcdir)/src/include
+
+MAINTAINERCLEANFILES = Makefile.in
diff -ruN ng-spice-rework-10.orig/src/frontend/inp.c
ng-spice-rework-10/src/frontend/inp.c
--- ng-spice-rework-10.orig/src/frontend/inp.c Sun Mar 26 12:30:48 2000
+++ ng-spice-rework-10/src/frontend/inp.c Sat Apr 15 18:42:17 2000
@@ -265,7 +265,7 @@
if (!deck) { /* MW. We must close fp always when returning */
(void) fclose(fp);
return;
- }
+ }
if (!comfile)
options = inp_getopts(deck);
@@ -278,7 +278,7 @@
if (!deck->li_next)
fprintf(cp_err, "Warning: no lines in input\n");
}
- (void) fclose(fp);
+ 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
diff -ruN ng-spice-rework-10.orig/src/help.c ng-spice-rework-10/src/help.c
--- ng-spice-rework-10.orig/src/help.c Sun Mar 26 12:30:42 2000
+++ ng-spice-rework-10/src/help.c Sat Apr 15 21:44:16 2000
@@ -21,7 +21,6 @@
FILE *cp_in, *cp_out, *cp_err;
char *Spice_Exec_Dir = NGSPICEBINDIR;
char *Spice_Lib_Dir = NGSPICEDATADIR;
-char Spice_OptChar = '-';
char *Def_Editor = "vi";
int AsciiRawFile = 0;
@@ -35,9 +34,7 @@
char *hlp_filelist[] = { "ngspice", 0 };
int
-main(ac, av)
- int ac;
- char **av;
+main(int ac, char **av)
{
wordlist *wl = NULL;
@@ -87,8 +84,7 @@
}
void
-fatal(s)
- char *s;
+fatal(char *s)
{
fprintf(stderr, "fatal error: %s\n", s);
exit(1);
@@ -106,16 +102,13 @@
*/
bool
-cp_getvar(n, t, r)
- char *n, *r;
- int t;
+cp_getvar(char *n, int t, char *r)
{
return (FALSE);
}
char *
-cp_tildexpand(s)
- char *s;
+cp_tildexpand(char *s)
{
return tilde_expand(s);
}
diff -ruN ng-spice-rework-10.orig/src/include/fteext.h
ng-spice-rework-10/src/include/fteext.h
--- ng-spice-rework-10.orig/src/include/fteext.h Sun Mar 26 12:30:52
2000
+++ ng-spice-rework-10/src/include/fteext.h Sun Apr 9 15:17:27 2000
@@ -409,10 +409,7 @@
/* spice.c & nutmeg.c */
-extern bool menumode;
-extern bool ft_batchmode;
extern bool ft_nutmeg;
-extern bool ft_servermode;
extern IFsimulator *ft_sim;
extern char *ft_rawfile;
extern char *cp_program;
diff -ruN ng-spice-rework-10.orig/src/include/ngspice.h
ng-spice-rework-10/src/include/ngspice.h
--- ng-spice-rework-10.orig/src/include/ngspice.h Sun Mar 26 12:50:30
2000
+++ ng-spice-rework-10/src/include/ngspice.h Sat Apr 15 21:45:10 2000
@@ -134,7 +134,6 @@
extern char *Spice_Exec_Dir;
extern char *Spice_Lib_Dir;
-extern char Spice_OptChar;
extern char *Def_Editor;
extern char *Bug_Addr;
extern int AsciiRawFile;
diff -ruN ng-spice-rework-10.orig/src/main.c ng-spice-rework-10/src/main.c
--- ng-spice-rework-10.orig/src/main.c Thu Apr 6 21:52:18 2000
+++ ng-spice-rework-10/src/main.c Sun Apr 16 11:18:54 2000
@@ -1,17 +1,18 @@
-/**********
-Copyright 1990 Regents of the University of California. All rights reserved.
-Author: 1985 Wayne A. Christopher
-**********/
-
-/*
- * The main routine for ngspice
- */
+/* Copyright 1990
+ Regents of the University of California.
+ All rights reserved.
+
+ Author: 1985 Wayne A. Christopher
+
+ The main routine for ngspice */
#include <stdio.h>
#include <setjmp.h>
#include <signal.h>
#include <sys/types.h>
+#define _GNU_SOURCE
+#include <getopt.h>
#include "ngspice.h"
#include "ifsim.h"
@@ -33,37 +34,35 @@
#endif
#endif
+/* Main options */
+static bool ft_servermode = FALSE;
+static bool ft_batchmode = FALSE;
+
+/* Frontend options */
+bool ft_intrpt = FALSE; /* Set by the (void) signal handlers. */
+bool ft_setflag = FALSE; /* Don't abort after an interrupt. */
+char *ft_rawfile = "rawspice.raw";
+
+/* Frontend and circuit options */
+IFsimulator *ft_sim = NULL;
+
/* (Virtual) Machine architecture parameters */
int ARCHme;
int ARCHsize;
-char *ft_rawfile = "rawspice.raw";
-
char *errRtn;
char *errMsg;
char *cp_program;
-bool ft_servermode = FALSE;
-bool ft_intrpt = FALSE; /* Set by the (void) signal handlers. */
-bool ft_setflag = FALSE; /* Don't abort after an interrupt. */
-
struct variable *(*if_getparam)( );
-bool ft_batchmode = FALSE;
jmp_buf jbuf;
-static char *usage =
-"Usage: %s [-] [-b] [-i] [-s] [-n] [-o outfile] [-r rawfile]\n\
-\t[-t term] [file ...]\n";
-struct options *exitoption;
-struct options *helpoption;
-
static int started = FALSE;
-IFsimulator *ft_sim = 0;
@@ -87,45 +86,157 @@
extern struct comm nutcp_coms[ ];
struct comm *cp_coms = nutcp_coms;
static IFfrontEnd nutmeginfo;
-/* XXX */
-/* ARGSUSED */ int if_run(char *t, char *w, wordlist *s, char *b)
- { return (0); }
-/* ARGSUSED */ int if_sens_run(char *t, char *w, wordlist *s, char *b)
- { return (0); }
-/* ARGSUSED */ void if_dump(char *ckt, FILE *fp) { }
-/* ARGSUSED */ char * if_inpdeck(struct line *deck, char **tab)
- { return ((char *) 0); }
-/* ARGSUSED */ int if_option(char *ckt, char *name, int type, char *value)
- { return 0; }
-/* ARGSUSED */ void if_cktfree(char *ckt, char *tab) { }
-/* ARGSUSED */ void if_setndnames(char *line) { }
-/* ARGSUSED */ char * if_errstring(int code) { return ("spice error"); }
-/* ARGSUSED */ void if_setparam(char *ckt, char *name, char *param,
- struct variable *val) {}
-/* ARGSUSED */
+
+int
+if_run(char *t, char *w, wordlist *s, char *b)
+{
+ return (0);
+}
+
+int
+if_sens_run(char *t, char *w, wordlist *s, char *b)
+{
+ return (0);
+}
+
+void
+if_dump(char *ckt, FILE *fp)
+{}
+
+char *
+if_inpdeck(struct line *deck, char **tab)
+{
+ return ((char *) 0);
+}
+
+int
+if_option(char *ckt, char *name, int type, char *value)
+{
+ return 0;
+}
+
+void if_cktfree(char *ckt, char *tab)
+{}
+
+void if_setndnames(char *line)
+{}
+
+char *
+if_errstring(int code)
+{
+ return ("spice error");
+}
+
+void
+if_setparam(char *ckt, char *name, char *param, struct variable *val)
+{}
+
bool
if_tranparams(struct circ *ckt, double *start, double *stop, double *step)
{
return (FALSE);
}
-/* ARGSUSED */ struct variable *if_getstat(char *n, char *c) { return
(NULL);}
+
+struct variable *
+if_getstat(char *n, char *c)
+{
+ return (NULL);
+}
#endif /* SIMULATOR */
char *hlp_filelist[] = { "ngspice", 0 };
+
+/* allocate space for global constants in 'CONST.h' */
+
+double CONSTroot2;
+double CONSTvt0;
+double CONSTKoverQ;
+double CONSTe;
+IFfrontEnd *SPfrontEnd = NULL;
+
+
+
+int SIMinit(IFfrontEnd *frontEnd, IFsimulator **simulator)
+{
+ SPfrontEnd = frontEnd;
+ *simulator = &SIMinfo;
+ CONSTroot2 = sqrt(2.);
+ CONSTvt0 = CONSTboltz * (27 /* deg c */ + CONSTCtoK ) / CHARGE;
+ CONSTKoverQ = CONSTboltz / CHARGE;
+ CONSTe = exp((double)1.0);
+ return(OK);
+}
+
+
+/* Shutdown gracefully. */
+int
+shutdown(int exitval)
+{
+ cleanvars();
+#ifdef PARALLEL_ARCH
+ if (exitval == EXIT_BAD) {
+ Error("Fatal error in SPICE", -1);
+ } else {
+ PEND_();
+ }
+#endif /* PARALLEL_ARCH */
+ exit (exitval);
+}
+
+void
+show_help(void)
+{
+ printf("Usage: %s [OPTION]... [FILE]...\n"
+ "Simulate the electical circuits in FILE.\n"
+ "\n"
+ " -b, --batch process FILE in batch mode\n"
+ " -c, --circuitfile=FILE set the circuitfile\n"
+ " -i, --interactive run in interactive mode\n"
+ " -n, --no-spiceinit don't load the .spiceinit
+configfile\n"
+ " -o, --output=FILE set the outputfile\n"
+ " -q, --completion activate command completion\n"
+ " -r, --rawfile=FILE set the rawfile output\n"
+ " -s, --server run spice as a server process\n"
+ " -t, --term=TERM set the terminal type\n"
+ " -h, --help display this help and exit\n"
+ " -v, --version output version information and exit\n"
+ "\n"
+ "Report bugs to %s.\n", cp_program, Bug_Addr);
+}
+
+void
+show_version(void)
+{
+ printf("%s compiled from %s revision %s\n"
+ "Written originally by Berkeley University\n"
+ "Currently maintained by the NG-Spice Project\n\n"
+ "Copyright (C) 1985-1996,"
+ " The Regents of the University of California\n"
+ "Copyright (C) 1999-2000,"
+ " The NG-Spice Project\n", cp_program, PACKAGE, VERSION);
+}
+
+void
+append_to_stream(FILE *dest, FILE *source)
+{
+ char *buf[BSIZE_SP];
+ int i;
+
+ while ((i = fread(buf, 1, BSIZE_SP, source)) > 0)
+ fwrite(buf, i, 1, dest);
+}
+
int
-main(int ac, char **av)
+main(int argc, char **argv)
{
- char **tv;
- int tc;
+ int c;
int err;
bool gotone = FALSE;
- char *cmd_line_term = 0, term_1stch;
#ifdef SIMULATOR
-
- int i,error2;
+ int error2;
extern int OUTpBeginPlot(), OUTpData(), OUTwBeginPlot(), OUTwReference();
extern int OUTwData(), OUTwEnd(), OUTendPlot(), OUTbeginDomain();
@@ -147,14 +258,18 @@
OUTendDomain,
OUTattributes
};
-
-#endif /* SIMULATOR */
+#else /* ~ SIMULATOR */
+ bool gdata = TRUE;
+#endif /* ~ SIMULATOR */
char buf[BSIZE_SP];
- bool readinit = TRUE, rflag = FALSE, ciprefix();
- bool istty = TRUE, iflag = FALSE, qflag = FALSE;
- bool gdata = TRUE;
+ bool ciprefix();
+ bool readinit = TRUE;
+ bool rflag = FALSE;
+ bool istty = TRUE;
+ bool iflag = FALSE;
+ bool qflag = FALSE;
FILE *fp;
FILE *circuit_file;
@@ -167,13 +282,13 @@
started = TRUE;
#ifdef PARALLEL_ARCH
- PBEGIN_(ac, av);
+ PBEGIN_(argc, argv);
ARCHme = NODEID_();
ARCHsize = NNODES_();
SETDBG_(&debug_flag);
fprintf( stderr, "On-line: process %d of %d total.\n", ARCHme, ARCHsize
);
evlog(EVKEY_ENABLE, EVKEY_EVENT, "On-line", EVKEY_DUMP, EVKEY_DISABLE,
- EVKEY_LAST_ARG);
+ EVKEY_LAST_ARG);
#else
ARCHme = 0;
ARCHsize = 1;
@@ -211,157 +326,115 @@
srandom(getpid());
-#ifdef PARALLEL_ARCH
-#ifdef NOTDEF
- tv = av;
- tc = ac;
-
- /* Print Arguments. */
- fprintf( stderr, "\nArgs:\n" );
- while (--tc > 0) {
- tv++;
- fprintf( stderr, "\t%s\n", *tv );
- }
-#endif /* NOTDEF */
-
- /* Skip processor group file. */ /* XXX What if it's not first? */
- ac--; av++;
-#endif /* PARALLEL_ARCH */
+ while (1) {
+ int option_index = 0;
+ static struct option long_options[] = {
+ {"help", 0, 0, 'h'},
+ {"version", 0, 0, 'v'},
+ {"batch", 0, 0, 'b'},
+ {"circuitfile", 0, 0, 'c'},
+ {"interactive", 0, 0, 'i'},
+ {"no-spiceinit", 0, 0, 'n'},
+ {"output", 0, 0, 'o'},
+ {"completion", 0, 0, 'q'},
+ {"rawfile", 1, 0, 'r'},
+ {"server", 0, 0, 's'},
+ {"terminal", 1, 0, 't'},
+ {0, 0, 0, 0}
+ };
+
+ c = getopt_long (argc, argv, "hvbc:ihno:qr:st:",
+ long_options, &option_index);
+ if (c == -1)
+ break;
+
+ switch (c) {
+ case 'h': /* Help */
+ show_help();
+ shutdown (EXIT_NORMAL);
+ break;
+
+ case 'v': /* Version info */
+ show_version();
+ shutdown (EXIT_NORMAL);
+ break;
+
+ case 'b': /* Batch mode */
+ ft_batchmode = TRUE;
+ break;
+
+ case 'c': /* Circuit file */
+ if (optarg) {
+ if (!(circuit_file = fopen(optarg, "r"))) {
+ perror("circuit file not available");
+ shutdown(EXIT_BAD);
+ }
+ istty = FALSE;
+ }
+ break;
- tv = av;
- tc = ac;
+ case 'i': /* Interactive mode */
+ iflag = TRUE;
+ break;
+
+ case 'n': /* Don't read .spiceinit */
+ readinit = FALSE;
+ break;
- /* Pass 1 -- get options. */
- while (--tc > 0) {
- tv++;
- if (**tv == Spice_OptChar) /* Option argument. */
- switch ((*tv)[1]) {
-
-
- case '\0': /* No raw file. */
- gdata = FALSE;
- break;
-
- case 'b': /* Batch mode. */
- case 'B':
- ft_batchmode = TRUE;
- break;
-
- case 's': /* Server mode. */
- case 'S':
- ft_servermode = TRUE;
- break;
-
- case 'i': /* Interactive mode. */
- case 'I':
- iflag = TRUE;
- break;
-
- case 'q': /* No command completion. */
- case 'Q':
- qflag = TRUE;
- break;
-
- case 'n': /* Don't read .spiceinit. */
- case 'N':
- readinit = FALSE;
- break;
-
- case 't': /* Terminal type. */
- case 'T':
- if (tc > 1) {
- tc--;
- tv++;
- cmd_line_term = *tv;
- term_1stch = **tv;
- **tv = Spice_OptChar;
- } else {
- fprintf(cp_err, usage,
- cp_program);
- shutdown(EXIT_BAD);
- }
- break;
-
- case 'r': /* The rawfile. */
- case 'R':
- if (tc > 1) {
- tc--;
- tv++;
- sprintf( buf, "%s", *tv );
- cp_vset("rawfile", VT_STRING, buf);
- **tv = Spice_OptChar;
- }
- rflag = TRUE;
- break;
-
- case 'o': /* Output file. */
- case 'O':
- if (tc > 1) {
- tc--;
- tv++;
+ case 'o': /* Output file */
+ if (optarg) {
#ifdef PARALLEL_ARCH
- sprintf( buf, "%s%03d", *tv, ARCHme );
+ sprintf (buf, "%s%03d", optarg, ARCHme);
#else
- sprintf( buf,"%s",*tv);
-/* sprintf( buf, "%s%%", *tv ); */
+ sprintf (buf, "%s", optarg);
#endif
- if (!(freopen(buf, "w", stdout))) {
- perror(buf);
- shutdown(EXIT_BAD);
- }
- **tv = Spice_OptChar;
- } else {
- fprintf(cp_err, usage, av[0]);
- shutdown(EXIT_BAD);
- }
- break;
-
- case 'c': /* Circuit file. */
- case 'C':
- if (tc > 1) {
- tc--;
- tv++;
- if (!(circuit_file = fopen(*tv, "r"))) {
- perror(*tv);
- shutdown(EXIT_BAD);
- }
- istty = FALSE;
- **tv = Spice_OptChar;
- } else {
- fprintf(cp_err, usage, av[0]);
- shutdown(EXIT_BAD);
- }
- break;
+ if (!(freopen (buf, "w", stdout))) {
+ perror (buf);
+ shutdown (EXIT_BAD);
+ }
+ }
+ break;
-#ifdef PARALLEL_ARCH
- case 'm': /* '-master' option from "parallel". */
- if (tc > 6) {
- for (i =0; i < 6; i++) {
- tc--;
- tv++;
- **tv = Spice_OptChar;
- }
- } else {
- fprintf(cp_err, usage,
- cp_program);
- shutdown(EXIT_BAD);
- }
- break;
-#endif /* PARALLEL_ARCH */
+ case 'q': /* Command completion */
+ qflag = TRUE;
+ break;
+
+ case 'r': /* The raw file */
+ if (optarg) {
+ cp_vset("rawfile", VT_STRING, optarg);
+ }
+ rflag = TRUE;
+ break;
- default:
- fprintf(cp_err, "Error: bad option %s\n", *tv);
- fprintf(cp_err, usage, cp_program);
- shutdown(EXIT_BAD);
- }
+ case 's': /* Server mode */
+ ft_servermode = TRUE;
+ break;
+
+ case 't':
+ if (optarg) {
+ cp_vset("term", VT_STRING, optarg);
+ }
+ break;
+
+ case '?':
+ break;
+
+ default:
+ printf ("?? getopt returned character code 0%o ??\n", c);
+ }
}
+
#ifdef SIMULATOR
if_getparam = spif_getparam;
#else
if_getparam = nutif_getparam;
-#endif
+ if (optind == argc) {
+ /* No raw file */
+ gdata = FALSE;
+ }
+#endif
if ((!iflag && !istty) || ft_servermode)
@@ -386,31 +459,32 @@
goto bot;
}
- /* Set up (void) signal handling */
+ /* Set up signal handling */
if (!ft_batchmode) {
- (void) signal(SIGINT, ft_sigintr);
- (void) signal(SIGFPE, sigfloat);
-# ifdef SIGTSTP
- (void) signal(SIGTSTP, sigstop);
-# endif
- }
- /* Set up (void) signal handling for fatal errors. */
- (void) signal(SIGILL, sigill);
-
-# ifdef SIGBUS
- (void) signal(SIGBUS, sigbus);
-# endif
-# ifdef SIGSEGV
- (void) signal(SIGSEGV, sigsegv);
-# endif
-# ifdef SIGSYS
- (void) signal(SIGSYS, sig_sys);
-# endif
+ signal(SIGINT, ft_sigintr);
+ signal(SIGFPE, sigfloat);
+#ifdef SIGTSTP
+ signal(SIGTSTP, sigstop);
+#endif
+ }
+
+ /* Set up signal handling for fatal errors. */
+ signal(SIGILL, sigill);
+
+#ifdef SIGBUS
+ signal(SIGBUS, sigbus);
+#endif
+#ifdef SIGSEGV
+ signal(SIGSEGV, sigsegv);
+#endif
+#ifdef SIGSYS
+ signal(SIGSYS, sig_sys);
+#endif
-# ifdef HAVE_PWD_H
if (readinit) {
- /* Try to source either .spiceinit or ~/.spiceinit. */
+#ifdef HAVE_PWD_H
+ /* Try to source either .spiceinit or ~/.spiceinit. */
if (access(".spiceinit", 0) == 0)
inp_source(".spiceinit");
else {
@@ -422,26 +496,16 @@
if (access(s, 0) == 0)
inp_source(s);
/* free(s); */
- /* XXX Need to free() char* fields in pw as well? XXX */
+ /* FIXME: Do we need to free() char* fields in pw as well? */
/* free(pw); */
-
- }
-# else /* ~ HAVE_PWD_H */
- /* Try to source the file "spice.rc" in the current directory. */
- if (readinit) {
+ }
+#else /* ~ HAVE_PWD_H */
+ /* Try to source the file "spice.rc" in the current directory. */
if ((fp = fopen("spice.rc", "r")) != NULL) {
(void) fclose(fp);
inp_source("spice.rc");
}
- }
-# endif /* ~ HAVE_PWD_H */
-
- if (cmd_line_term) {
- *cmd_line_term = term_1stch; /* XXX oh, gross!
- * First char got squashed scanning the
- * command line
- */
- cp_vset("term", VT_STRING, cmd_line_term);
+#endif /* ~ HAVE_PWD_H */
}
if (!ft_batchmode) {
@@ -462,8 +526,7 @@
/* Pass 2 -- get the filenames. If we are spice, then this means
* build a circuit for this file. If this is in server mode, don't
- * process any of these args.
- */
+ * process any of these args. */
if (setjmp(jbuf) == 1)
goto evl;
@@ -474,47 +537,41 @@
#ifdef SIMULATOR
if (!ft_servermode && !ft_nutmeg) {
- FILE *file = NULL, *tp = NULL;
- char *tempfile = NULL, buf[BSIZE_SP], *smktemp();
+ /* Concatenate all non-option arguments into a temporary file
+ and load that file into the spice core.
+
+ The original routine took a special path if there was only
+ one non-option argument. In that case, it didn't create
+ the temporary file but used the original file instead. The
+ current algorithm is uniform at the expense of a little
+ startup time. */
+ FILE *tempfile;
+
+ tempfile = tmpfile();
+ if (optind == argc && !istty) {
+ append_to_stream(tempfile, stdin);
+ }
+ while (optind < argc) {
+ char *arg;
+ FILE *tp;
+
+ /* Copy all the arguments into the temporary file */
+ arg = argv[optind++];
+ tp = fopen(arg, "r");
+ if (!tp) {
+ perror(arg);
+ err = 1;
+ break;
+ }
+ append_to_stream(tempfile, tp);
+ fclose(tp);
+ }
+ fseek(tempfile, (long) 0, 0);
- for (tv = av + 1, i = 0; *tv; tv++)
- if (**tv != Spice_OptChar)
- i++;
- if (i == 1) {
- for (tv = av + 1, i = 0; *tv; tv++)
- if (**tv != Spice_OptChar)
- break;
- if (!(file = fopen(*tv, "r"))) {
- perror(*tv);
- i = 0;
- if (ft_batchmode)
- shutdown(EXIT_BAD);
- }
- } else if (i) {
- tempfile = smktemp("sp");
- if (!(file = fopen(tempfile, "w+"))) {
- perror(tempfile);
- shutdown(EXIT_BAD);
- }
- for (tv = av + 1, i = 0; *tv; tv++)
- if (**tv != Spice_OptChar) {
- if (!(tp = fopen(*tv, "r"))) {
- perror(*tv);
- err = 1;
- break;
- }
- while ((i = fread(buf, 1, BSIZE_SP, tp)) > 0)
- (void) fwrite(buf, i, 1, file);
- (void) fclose(tp);
- }
- (void) fseek(file, (long) 0, 0);
- }
- if (file && (!err || !ft_batchmode)) {
- inp_spsource(file, FALSE, tempfile ? (char *) NULL : *tv);
+ if (tempfile && (!err || !ft_batchmode)) {
+ inp_spsource(tempfile, FALSE, NULL);
gotone = TRUE;
}
- if (tempfile)
- (void) unlink(tempfile);
if (ft_batchmode && err)
shutdown(EXIT_BAD);
}
@@ -522,12 +579,10 @@
if (!gotone && ft_batchmode && !ft_nutmeg)
inp_spsource(circuit_file, FALSE, (char *) NULL);
-
evl:
if (ft_batchmode) {
- /* If we get back here in batch mode then something is
- * wrong, so exit.
- */
+ /* If we get back here in batch mode then something is wrong,
+ * so exit. */
bool st = FALSE;
(void) setjmp(jbuf);
@@ -545,26 +600,25 @@
shutdown(EXIT_BAD);
shutdown(EXIT_NORMAL);
}
+
/* If -r is specified, then we don't bother with the dot
- * cards. Otherwise, we use wrd_run, but we are careful
- * not to save too much.
- */
+ * cards. Otherwise, we use wrd_run, but we are careful not to
+ * save too much. */
cp_interactive = FALSE;
if (rflag) {
ft_dotsaves();
error2 = ft_dorun(ft_rawfile);
if (ft_cktcoms(TRUE) || error2)
shutdown(EXIT_BAD);
- } else {
- if (ft_savedotargs()) {
- error2 = ft_dorun(NULL);
- if (ft_cktcoms(FALSE) || error2)
- shutdown(EXIT_BAD);
- } else {
- fprintf(stderr,
- "Note: No \".plot\", \".print\", or \".fourier\" lines;
no simulations run\n");
+ } else if (ft_savedotargs()) {
+ error2 = ft_dorun(NULL);
+ if (ft_cktcoms(FALSE) || error2)
shutdown(EXIT_BAD);
- }
+ } else {
+ fprintf(stderr,
+ "Note: No \".plot\", \".print\", or \".fourier\" lines; "
+ "no simulations run\n");
+ shutdown(EXIT_BAD);
}
} else {
(void) setjmp(jbuf);
@@ -572,16 +626,13 @@
while (cp_evloop((char *) NULL) == 1) ;
}
-
-#else
+#else /* ~ SIMULATOR */
if (ft_nutmeg && gdata) {
- /* Read in the rawfiles */
- for (av++; *av; av++)
- if (**av != Spice_OptChar) {
- ft_loadfile(*av);
- gotone = TRUE;
- }
+ while (optind < argc) {
+ ft_loadfile(argv[optind++]);
+ gotone = TRUE;
+ }
if (!gotone)
ft_loadfile(ft_rawfile);
}
@@ -592,52 +643,8 @@
cp_interactive = TRUE;
while (cp_evloop((char *) NULL) == 1) ;
-#endif
+#endif /* ~ SIMULATOR */
shutdown(EXIT_NORMAL);
return EXIT_NORMAL;
}
-
-}
-/* Shutdown gracefully. */
-int
-shutdown(int exitval)
-{
- cleanvars();
-#ifdef PARALLEL_ARCH
- if (exitval == EXIT_BAD) {
- Error("Fatal error in SPICE", -1);
- } else {
- PEND_();
- }
-#endif /* PARALLEL_ARCH */
- exit (exitval);
-}
-
-/* allocate space for global constants in 'CONST.h' */
-
-double CONSTroot2;
-double CONSTvt0;
-double CONSTKoverQ;
-double CONSTe;
-IFfrontEnd *SPfrontEnd = NULL;
-
-int
-SPIinit(IFfrontEnd *frtEnd, IFsimulator **description)
-{
- SPfrontEnd = frtEnd;
- *description = &SIMinfo;
- CONSTroot2 = sqrt(2.);
- CONSTvt0 = CONSTboltz * (27 /* deg c */ + CONSTCtoK ) / CHARGE;
- CONSTKoverQ = CONSTboltz / CHARGE;
- CONSTe = exp((double)1.0);
- return(OK);
-}
-
-/* XXX SIMinit and SPIinit ?? */
-
-int SIMinit(IFfrontEnd *frontEnd, IFsimulator **simulator)
-{
- return(SPIinit(frontEnd,simulator));
-}
-
diff -ruN ng-spice-rework-10.orig/src/misc/mktemp.c
ng-spice-rework-10/src/misc/mktemp.c
--- ng-spice-rework-10.orig/src/misc/mktemp.c Sun Mar 26 12:30:52 2000
+++ ng-spice-rework-10/src/misc/mktemp.c Sat Apr 15 21:06:18 2000
@@ -4,6 +4,8 @@
/*
* A more portable version of the standard "mktemp( )" function
+ *
+ * FIXME: remove smktemp() and adjust all callers to use tmpfile(3).
*/
#include "ngspice.h"
diff -ruN ng-spice-rework-10.orig/src/ngspice.c
ng-spice-rework-10/src/ngspice.c
--- ng-spice-rework-10.orig/src/ngspice.c Tue Apr 4 22:16:47 2000
+++ ng-spice-rework-10/src/ngspice.c Sat Apr 15 20:43:11 2000
@@ -179,9 +179,9 @@
};
IFsimulator SIMinfo = {
- "Ng-spice", /* name */
+ "ngspice", /* name */
"Circuit level simulation program", /* more about me */
- Spice_Version, /* version */
+ Spice_Version, /* version */
CKTinit, /* newCircuit function */
CKTdestroy, /* deleteCircuit function */
PGP signature
Partial thread listing: