src/Makefile.am src/help.c src/main.c

src/circuit/Makefile.am src/circuit/ifnewuid.c
	src/frontend/Makefile.am src/frontend/aspice.c
	src/frontend/circuits.h src/frontend/com_display.c
	src/frontend/com_hardcopy.c src/frontend/commands.c
	src/frontend/commands.h src/frontend/cpitf.c
	src/frontend/debugcom.c src/frontend/device.c
	src/frontend/diff.c src/frontend/display.c
	src/frontend/dotcards.c src/frontend/fourier.c
	src/frontend/inp.c src/frontend/inpcom.c src/frontend/linear.c
	src/frontend/misccoms.c src/frontend/mw_coms.c
	src/frontend/nutinp.c src/frontend/options.c
	src/frontend/outitf.c src/frontend/parse.c
	src/frontend/postcoms.c src/frontend/postsc.c
	src/frontend/rawfile.c src/frontend/resource.c
	src/frontend/runcoms.c src/frontend/runcoms2.c
	src/frontend/shyu.c src/frontend/spec.c src/frontend/spiceif.c
	src/frontend/subckt.c src/frontend/vectors.c
	src/frontend/where.c src/frontend/plotting/Makefile.am
	src/frontend/plotting/agraf.c src/frontend/plotting/graf.c
	src/frontend/plotting/plotcurv.c
	src/frontend/plotting/plotit.c src/frontend/plotting/x11.c
	src/frontend/plotting/xgraph.c src/include/Makefile.am
	src/maths/cmaths/cmath4.c src/misc/terminal.c
	src/misc/terminal.h src/parser/cshpar.c src/parser/front.c
	src/parser/front.h src/parser/history.c src/parser/history.h
	src/parser/modify.c src/parser/var2.c src/parser/var2.h
	src/parser/variable.c: Refactoring of frontend code.

	* src/include/ftehelp.h src/include/variable.h: Moved into
	frontend directory.

	* src/include/cpdefs.h src/include/cpextern.h
	src/include/ftedefs.h src/include/plot.h: Updates.
This commit is contained in:
arno 2000-06-27 16:09:02 +00:00
parent 96da984f7a
commit 489fc66afd
67 changed files with 185 additions and 3199 deletions

View File

@ -1,3 +1,9 @@
2000-06-27 Arno W. Peters <A.W.Peters@ieee.org>
* src/parser: Refactored commands from the frontend into the
frontend directory. Major changes to organization, but not to
functionality.
2000-06-19 Arno W. Peters <A.W.Peters@ieee.org>
* src/analysis/cktask.c: moved to src/devices.

View File

@ -99,6 +99,7 @@ help_SOURCES = help.c
help_LDADD = \
hlp/libhlp.a \
parser/libparser.a \
frontend/libfte.a \
misc/libmisc.a

View File

@ -59,6 +59,6 @@ libinp_a_SOURCES = \
inp.h
INCLUDES = -I$(top_srcdir)/src/include
INCLUDES = -I$(top_srcdir)/src/include -I$(top_srcdir)/src/frontend
MAINTAINERCLEANFILES = Makefile.in

View File

@ -5,10 +5,15 @@ Author: 1988 Thomas L. Quarles
#include "ngspice.h"
#include <stdio.h>
#include "inpdefs.h"
#include <wordlist.h>
#include <bool.h>
#include <inpdefs.h>
#include <circuits.h>
#include <cpdefs.h>
#include "ifsim.h"
#include "iferrmsg.h"
#include "cpdefs.h"
#include "fteext.h"
#include "inp.h"
@ -21,14 +26,9 @@ IFnewUid(void *ckt, IFuid * newuid, IFuid olduid, char *suffix, int type,
int error;
if (olduid) {
newname = (char *)
MALLOC(sizeof(char) *
(strlen(suffix) + strlen((char *) olduid) + 2));
/* 2 = '#' + '\0' */
sprintf(newname, "%s#%s", (char *) olduid, suffix);
asprintf(&newname, "%s#%s", (char *) olduid, suffix);
} else {
newname = (char *) MALLOC(sizeof(char) * (strlen(suffix) + 1)); /* 1 = '\0' */
sprintf(newname, "%s", suffix);
asprintf(&newname, "%s", suffix);
}
switch (type) {

View File

@ -7,23 +7,50 @@ noinst_LIBRARIES = libfte.a
libfte_a_SOURCES = \
commands.c \
commands.h \
com_ahelp.c \
com_ahelp.h \
com_asciiplot.c \
com_asciiplot.h \
com_cdump.c \
com_cdump.h \
com_compose.c \
com_compose.h \
com_display.c \
com_display.h \
com_ghelp.c \
com_ghelp.h \
com_hardcopy.c \
com_hardcopy.h \
com_help.c \
com_help.h \
com_history.c \
com_history.h \
com_let.c \
com_let.h \
com_plot.c \
com_plot.h \
com_set.c \
com_setscale.c \
com_setscale.h \
com_shift.c \
com_strcmp.c \
com_strcmp.h \
com_unset.c \
com_xgraph.c \
com_xgraph.h \
completion.h \
control.h \
control.c \
ftehelp.h \
hcomp.c \
hcomp.h \
init.c \
init.h \
streams.h \
terminal.c \
terminal.h \
variable.c \
variable.h \
\
arg.c \
arg.h \

View File

@ -10,8 +10,10 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
#include "ngspice.h"
#include "cpdefs.h"
#include "ftedefs.h"
#include "aspice.h"
#include "aspice.h"
#include "variable.h"
#include "circuits.h"
# ifdef HAVE_SYS_WAIT_H
/* should be more tests here I think */

View File

@ -6,6 +6,38 @@
#ifndef CIRCUITS_H_INCLUDED
#define CIRCUITS_H_INCLUDED
/* The curcuits that are currently available to the user. */
struct circ {
char *ci_name; /* What the circuit can be called. */
char *ci_ckt; /* The CKTcircuit structure. */
INPtables *ci_symtab; /* The INP symbol table. */
struct line *ci_deck; /* The input deck. */
struct line *ci_origdeck;/* The input deck, before subckt expansion. */
struct line *ci_options;/* The .option cards from the deck... */
struct variable *ci_vars; /* ... and the parsed versions. */
bool ci_inprogress; /* We are in a break now. */
bool ci_runonce; /* So com_run can to a reset if necessary... */
wordlist *ci_commands; /* Things to do when this circuit is done. */
struct circ *ci_next; /* The next in the list. */
char *ci_nodes; /* ccom structs for the nodes... */
char *ci_devices; /* and devices in the circuit. */
char *ci_filename; /* Where this circuit came from. */
char *ci_defTask; /* the default task for this circuit */
char *ci_specTask; /* the special task for command line jobs */
char *ci_curTask; /* the most recent task for this circuit */
char *ci_defOpt; /* the default options anal. for this circuit */
char *ci_specOpt; /* the special options anal. for command line jobs */
char *ci_curOpt; /* the most recent options anal. for the circuit */
} ;
struct subcirc {
char *sc_name; /* Whatever... */
} ;
extern struct circ *ft_curckt; /* The default active circuit. */
void ft_newcirc(struct circ *ckt);

View File

@ -1,10 +1,11 @@
#include <ngspice.h>
#include <bool.h>
#include <variable.h>
#include <wordlist.h>
#include <fteext.h>
#include <cpextern.h>
#include "com_display.h"
#include "variable.h"
#include "plotting/plotting.h"
#include "plotting/pvec.h"

View File

@ -16,6 +16,7 @@
#include "arg.h"
#include "display.h"
#include "com_hardcopy.h"
#include "variable.h"
/* hardcopy file plotargs, or 'hardcopy file' -- with no other args

View File

@ -32,10 +32,22 @@
#include <ngspice.h>
#include <ftedefs.h>
#include <ftehelp.h>
#include <cpdefs.h>
#include "ftehelp.h"
#include "commands.h"
#include "com_ahelp.h"
#include "com_asciiplot.h"
#include "com_compose.h"
#include "com_display.h"
#include "com_hardcopy.h"
#include "com_help.h"
#include "com_let.h"
#include "com_plot.h"
#include "com_setscale.h"
#include "com_xgraph.h"
/* FIXME: Integrate spcp_coms and nutcp_coms into one variable. */
@ -43,7 +55,6 @@
/* Bool fields: stringargs, spiceonly, major */
struct comm spcp_coms[] = {
{ "let", com_let, FALSE, FALSE, TRUE,
{ 040000, 040000, 040000, 040000 }, E_DEFHMASK, 0, LOTS,
arg_let,

View File

@ -1,9 +1,6 @@
#ifndef _COMMANDS_H
#define _COMMANDS_H
#include <cpdefs.h>
extern struct comm spcp_coms[];
extern struct comm nutcp_coms[];

View File

@ -13,6 +13,7 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
#include <terminal.h>
#include "completion.h"
#include "variable.h"
/* Set some standard variables and aliases, etc, and init the ccom stuff. */

View File

@ -13,6 +13,8 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
#include "ftedebug.h"
#include "dvec.h"
#include "fteinp.h"
#include "circuits.h"
#include "debugcom.h"

View File

@ -13,8 +13,10 @@ Author: 1986 Wayne A. Christopher, U. C. Berkeley CAD Group
#include "cpdefs.h"
#include "ftedefs.h"
#include "dgen.h"
#include "device.h"
#include "circuits.h"
#include "device.h"
#include "variable.h"
static wordlist *devexpand(char *name);

View File

@ -13,6 +13,7 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
#include <sim.h>
#include "diff.h"
#include "variable.h"
/* Determine if two vectors have the 'same' name. */

View File

@ -11,7 +11,7 @@ Copyright 1990 Regents of the University of California. All rights reserved.
#include <ftedefs.h> /* for mylog() */
#include "display.h"
#include "variable.h"
/* static declarations */
static void gen_DatatoScreen(GRAPH *graph, double x, double y, int *screenx, int *screeny);

View File

@ -14,7 +14,9 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
#include "fteinp.h"
#include <sim.h>
#include "circuits.h"
#include "dotcards.h"
#include "variable.h"
/* Extract all the .save lines */

View File

@ -16,7 +16,9 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
#include "fteparse.h"
#include "sperror.h"
#include "const.h"
#include "fourier.h"
#include "variable.h"
/* static declarations */

View File

@ -16,7 +16,10 @@ Author: 1985 Wayne A. Christopher
#include "fteinp.h"
#include "inp.h"
#include "circuits.h"
#include "completion.h"
#include "variable.h"
/* static declarations */
static char * upper(register char *string);

View File

@ -13,7 +13,10 @@ Author: 1985 Wayne A. Christopher
#include "ftedefs.h"
#include "dvec.h"
#include "fteinp.h"
#include "inpcom.h"
#include "variable.h"
/* This routine reads a line (of arbitrary length), up to a '\n' or 'EOF'

View File

@ -7,6 +7,8 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
#include "cpdefs.h"
#include "ftedefs.h"
#include "dvec.h"
#include "circuits.h"
#include "linear.h"

View File

@ -11,233 +11,13 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
#include "hlpdefs.h"
#include "misccoms.h"
#include "circuits.h"
#include "hcomp.h"
#include "variable.h"
static void byemesg(void);
static int
hcomp(const void *a, const void *b)
{
struct comm **c1 = (struct comm **) a;
struct comm **c2 = (struct comm **) b;
return (strcmp((*c1)->co_comname, (*c2)->co_comname));
}
void
com_help(wordlist *wl)
{
struct comm *c;
struct comm *ccc[512]; /* Should be enough. */
int numcoms, i;
bool allflag = FALSE;
if (wl && eq(wl->wl_word, "all")) {
allflag = TRUE;
wl = NULL; /* XXX Probably right */
}
/* We want to use more mode whether "moremode" is set or not. */
out_moremode = TRUE;
out_init();
out_moremode = FALSE;
if (wl == NULL) {
out_printf(
"For a complete description read the Spice3 User's Manual manual.\n");
if (!allflag) {
out_printf(
"For a list of all commands type \"help all\", for a short\n");
out_printf(
"description of \"command\", type \"help command\".\n");
}
/* Sort the commands */
for (numcoms = 0; cp_coms[numcoms].co_func != NULL; numcoms++)
ccc[numcoms] = &cp_coms[numcoms];
qsort((char *) ccc, numcoms, sizeof (struct comm *), hcomp);
for (i = 0; i < numcoms; i++) {
if ((ccc[i]->co_spiceonly && ft_nutmeg) ||
(ccc[i]->co_help == NULL) ||
(!allflag && !ccc[i]->co_major))
continue;
out_printf("%s ", ccc[i]->co_comname);
out_printf(ccc[i]->co_help, cp_program);
out_send("\n");
}
} else {
while (wl != NULL) {
for (c = &cp_coms[0]; c->co_func != NULL; c++)
if (eq(wl->wl_word, c->co_comname)) {
out_printf("%s ", c->co_comname);
out_printf(c->co_help, cp_program);
if (c->co_spiceonly && ft_nutmeg)
out_send(
" (Not available in nutmeg)");
out_send("\n");
break;
}
if (c->co_func == NULL) {
/* See if this is aliased. */
struct alias *al;
for (al = cp_aliases; al; al = al->al_next)
if (eq(al->al_name, wl->wl_word))
break;
if (al == NULL)
fprintf(cp_out,
"Sorry, no help for %s.\n",
wl->wl_word);
else {
out_printf("%s is aliased to ",
wl->wl_word);
/* Minor badness here... */
wl_print(al->al_text, cp_out);
out_send("\n");
}
}
wl = wl->wl_next;
}
}
out_send("\n");
return;
}
void
com_ahelp(wordlist *wl)
{
int i, n;
/* assert: number of commands must be less than 512 */
struct comm *cc[512];
int env = 0;
struct comm *com;
int level;
char slevel[256];
if (wl) {
com_help(wl);
return;
}
out_init();
/* determine environment */
if (plot_list->pl_next) { /* plots load */
env |= E_HASPLOTS;
} else {
env |= E_NOPLOTS;
}
/* determine level */
if (cp_getvar("level", VT_STRING, slevel)) {
switch (*slevel) {
case 'b': level = 1;
break;
case 'i': level = 2;
break;
case 'a': level = 4;
break;
default: level = 1;
break;
}
} else {
level = 1;
}
out_printf(
"For a complete description read the Spice3 User's Manual manual.\n");
out_printf(
"For a list of all commands type \"help all\", for a short\n");
out_printf(
"description of \"command\", type \"help command\".\n");
/* sort the commands */
for (n = 0; cp_coms[n].co_func != (void (*)()) NULL; n++) {
cc[n] = &cp_coms[n];
}
qsort((char *) cc, n, sizeof(struct comm *), hcomp);
/* filter the commands */
for (i=0; i< n; i++) {
com = cc[i];
if ((com->co_env < (level << 13)) && (!(com->co_env & 4095) ||
(env & com->co_env))) {
if ((com->co_spiceonly && ft_nutmeg) ||
(com->co_help == (char *) NULL)) {
continue;
}
out_printf("%s ", com->co_comname);
out_printf(com->co_help, cp_program);
out_send("\n");
}
}
out_send("\n");
return;
}
void
com_ghelp(wordlist *wl)
{
char *npath, *path = Help_Path, buf[BSIZE_SP];
int i;
if (cp_getvar("helppath", VT_STRING, buf))
path = copy(buf);
if (!path) {
fprintf(cp_err, "Note: defaulting to old help.\n\n");
com_help(wl);
return;
}
if (!(npath = cp_tildexpand(path))) {
fprintf(cp_err, "Note: can't find help dir %s\n", path);
fprintf(cp_err, "Defaulting to old help.\n\n");
com_help(wl);
return;
}
path = npath;
if (cp_getvar("helpregfont", VT_STRING, buf))
hlp_regfontname = copy(buf);
if (cp_getvar("helpboldfont", VT_STRING, buf))
hlp_boldfontname = copy(buf);
if (cp_getvar("helpitalicfont", VT_STRING, buf))
hlp_italicfontname = copy(buf);
if (cp_getvar("helptitlefont", VT_STRING, buf))
hlp_titlefontname = copy(buf);
if (cp_getvar("helpbuttonfont", VT_STRING, buf))
hlp_buttonfontname = copy(buf);
if (cp_getvar("helpinitxpos", VT_NUM, (char *) &i))
hlp_initxpos = i;
if (cp_getvar("helpinitypos", VT_NUM, (char *) &i))
hlp_initypos = i;
if (cp_getvar("helpbuttonstyle", VT_STRING, buf)) {
if (cieq(buf, "left"))
hlp_buttonstyle = BS_LEFT;
else if (cieq(buf, "center"))
hlp_buttonstyle = BS_CENTER;
else if (cieq(buf, "unif"))
hlp_buttonstyle = BS_UNIF;
else
fprintf(cp_err, "Warning: no such button style %s\n",
buf);
}
if (cp_getvar("width", VT_NUM, (char *) &i))
hlp_width = i;
if (cp_getvar("display", VT_STRING, buf))
hlp_displayname = copy(buf);
else if (cp_getvar("device", VT_STRING, buf))
hlp_displayname = copy(buf);
else
hlp_displayname = NULL;
hlp_main(path, wl);
return;
}
void
com_quit(wordlist *wl)
{
@ -306,11 +86,6 @@ com_quit(wordlist *wl)
#ifdef SYSTEM_MAIL
#define MAIL_BUGS_
#endif
#ifdef MAIL_BUGS_
void
com_bug(wordlist *wl)

View File

@ -8,8 +8,10 @@
#include "ftedev.h"
#include "ftedebug.h"
#include "dvec.h"
#include "mw_coms.h"
#include "circuits.h"
#include "mw_coms.h"
#include "variable.h"
extern FILE *rawfileFp;
extern bool rawfileBinary;

View File

@ -12,8 +12,9 @@ Author: 1985 Wayne A. Christopher
#include "ftedefs.h"
#include "dvec.h"
#include "fteinp.h"
#include "nutinp.h"
#include "nutinp.h"
#include "variable.h"
/* The routine to source a spice input deck. We read the deck in, take out
* the front-end commands, and create a CKT structure. Also we filter out

View File

@ -15,8 +15,10 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
#include "ftedefs.h"
#include "dvec.h"
#include "fteinp.h"
#include "options.h"
#include "circuits.h"
#include "options.h"
#include "variable.h"
/* static declarations */

View File

@ -20,7 +20,10 @@ Author: 1988 Wayne A. Christopher, U. C. Berkeley CAD Group
#include "ifsim.h"
#include "jobdefs.h"
#include "iferrmsg.h"
#include "circuits.h"
#include "outitf.h"
#include "variable.h"
extern void gr_end_iplot(void);

View File

@ -598,8 +598,12 @@ struct func ft_funcs[] = {
{ "vector", cx_vector } ,
{ "unitvec", cx_unitvec } ,
{ "length", cx_length } ,
#if 0
/* These functions have been temporarily been disabled. See
their definitions for the reason. */
{ "interpolate",cx_interpolate } ,
{ "deriv", cx_deriv } ,
#endif
{ "v", NULL } ,
{ NULL, NULL }
} ;

View File

@ -26,6 +26,6 @@ libplotting_a_SOURCES = \
xgraph.c \
xgraph.h
INCLUDES = -I$(top_srcdir)/src/include @X_CFLAGS@
INCLUDES = -I$(top_srcdir)/src/include -I$(top_srcdir)/src/frontend @X_CFLAGS@
MAINTAINERCLEANFILES = Makefile.in

View File

@ -14,6 +14,8 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
#include "fteparse.h"
#include "agraf.h"
#include <variable.h>
#define FUDGE 7
#define MARGIN_BASE 11
#define LCHAR '.'

View File

@ -22,6 +22,7 @@ Author: 1988 Jeffrey M. Hsu
#include "ftedbgra.h"
#include "ftedev.h"
#include <terminal.h>
#include <variable.h>
#include "graf.h"

View File

@ -13,6 +13,7 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
#include <dvec.h>
#include <graph.h>
#include <ftedbgra.h>
#include <variable.h>
#include "plotcurv.h"

View File

@ -7,6 +7,9 @@
#include <sim.h>
#include <fteext.h>
#include <circuits.h>
#include <variable.h>
#include "plotit.h"
#include "agraf.h"
#include "xgraph.h"

View File

@ -22,6 +22,7 @@ Author: 1988 Jeffrey M. Hsu
# include <fteinput.h>
# include <cpdefs.h>
# include <ftedefs.h>
# include <variable.h>
/* Added X11/ prefix to the next includes - ER */

View File

@ -14,6 +14,7 @@ Author: 1992 David A. Gates, U. C. Berkeley CAD Group
#include "fteparse.h"
#include "xgraph.h"
#include <variable.h>
#define XG_MAXVECTORS 64

View File

@ -16,6 +16,7 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
#include "postcoms.h"
#include "completion.h"
#include "variable.h"
/* static declarations */
static void killplot(struct plot *pl);

View File

@ -13,8 +13,9 @@ Author: 1988 Jeffrey M. Hsu
#include "ftedbgra.h"
#include "ftedev.h"
#include "fteinput.h"
#include "postsc.h"
#include "postsc.h"
#include "variable.h"
#define RAD_TO_DEG (180.0 / M_PI)
#define DEVDEP(g) (*((PSdevdep *) (g)->devdep))

View File

@ -12,8 +12,9 @@ Author: 1986 Wayne A. Christopher, U. C. Berkeley CAD Group
#include "cpdefs.h"
#include "ftedefs.h"
#include "dvec.h"
#include "rawfile.h"
#include "rawfile.h"
#include "variable.h"
/* static declarations */
static void fixdims(struct dvec *v, char *s);

View File

@ -11,10 +11,10 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
#include "ngspice.h"
#include "cpdefs.h"
#include "ftedefs.h"
#include "circuits.h"
#include "resource.h"
#include "variable.h"
/* static declarations */
static void printres(char *name);

View File

@ -13,9 +13,11 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
#include "ftedev.h"
#include "ftedebug.h"
#include "dvec.h"
#include "runcoms.h"
#include "circuits.h"
#include "completion.h"
#include "runcoms.h"
#include "variable.h"
/* static declarations */
static int dosim(char *what, wordlist *wl);

View File

@ -13,8 +13,10 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
#include "ftedev.h"
#include "ftedebug.h"
#include "dvec.h"
#include "runcoms2.h"
#include "circuits.h"
#include "runcoms2.h"
#include "variable.h"
extern FILE *rawfileFp;
extern bool rawfileBinary;

View File

@ -19,6 +19,8 @@ Copyright 1990 Regents of the University of California. All rights reserved.
#include "inpdefs.h"
#include "iferrmsg.h"
#include "ifsim.h"
#include "circuits.h"
#include "shyu.h"

View File

@ -13,7 +13,7 @@ Author: 1994 Anthony E. Parker, Department of Electronics, Macquarie Uni.
#include "sim.h"
#include "spec.h"
#include "variable.h"
void
com_spec(wordlist *wl)

View File

@ -18,8 +18,10 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
#include "inpdefs.h"
#include "iferrmsg.h"
#include "ifsim.h"
#include "spiceif.h"
#include "circuits.h"
#include "spiceif.h"
#include "variable.h"
/* static declarations */
static struct variable * parmtovar(IFvalue *pv, IFparm *opt);

View File

@ -12,8 +12,9 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
#include "cpdefs.h"
#include "ftedefs.h"
#include "fteinp.h"
#include "subckt.h"
#include "subckt.h"
#include "variable.h"
/* static declarations */
static struct line * doit(struct line *deck);

View File

@ -13,8 +13,10 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
#include <dvec.h>
#include <sim.h>
#include "vectors.h"
#include "circuits.h"
#include "completion.h"
#include "variable.h"
#include "vectors.h"
#include "plotting/plotting.h"

View File

@ -9,8 +9,9 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
#include "dvec.h"
#include "ftehelp.h"
#include "hlpdefs.h"
#include "where.h"
#include "circuits.h"
#include "where.h"
void
com_where(void)

View File

@ -12,7 +12,7 @@ Author: 1986 Wayne A. Christopher, U. C. Berkeley CAD Group
#include "cpdefs.h"
#include "hlpdefs.h"
#include "frontend/variable.h"
#ifndef X_DISPLAY_MISSING
Widget toplevel;

View File

@ -19,7 +19,6 @@ noinst_HEADERS = \
ftedefs.h \
ftedev.h \
fteext.h \
ftehelp.h \
fteinp.h \
fteinput.h \
fteparse.h \
@ -34,6 +33,7 @@ noinst_HEADERS = \
inpptree.h \
jobdefs.h \
macros.h \
memory.h \
missing_math.h \
ngspice.h \
noisedef.h \
@ -56,7 +56,6 @@ noinst_HEADERS = \
trandefs.h \
trcvdefs.h \
tskdefs.h \
variable.h \
wordlist.h
MAINTAINERCLEANFILES = Makefile.in

View File

@ -66,12 +66,6 @@ struct histent {
};
/* FIXME: Split this file and adjust all callers to the new header files. */
#if 0
#warning "Please use a header file more specific than cpdef.h"
#endif
#include "variable.h"
/* The values returned by cp_userset(). */

View File

@ -12,7 +12,6 @@ Author: 1986 Wayne A. Christopher, U. C. Berkeley CAD Group
#include "wordlist.h"
#include "bool.h"
#include "variable.h"
/* alias.c */
@ -159,18 +158,14 @@ extern bool cp_nonomatch;
extern char cp_dol;
extern void cp_remvar(char *varname);
extern void cp_vset(char *varname, char type, char *value);
extern wordlist *cp_varwl(struct variable *var);
extern struct variable *cp_setparse(wordlist *wl);
/* var2.c */
extern wordlist *vareval(char *string);
extern wordlist *cp_variablesubst(wordlist *wlist);
extern void cp_vprint(void);
extern void com_set(wordlist *wl);
extern void com_unset(wordlist *wl);
extern void com_shift(wordlist *wl);
extern bool cp_getvar(char *name, int type, char *retval);
extern wordlist *cp_variablesubst(wordlist *wlist);
/* cpinterface.c etc -- stuff CP needs from FTE */

View File

@ -16,35 +16,6 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
#include "fteparse.h"
#include "fteinp.h"
/* The curcuits that are currently available to the user. */
struct circ {
char *ci_name; /* What the circuit can be called. */
char *ci_ckt; /* The CKTcircuit structure. */
INPtables *ci_symtab; /* The INP symbol table. */
struct line *ci_deck; /* The input deck. */
struct line *ci_origdeck;/* The input deck, before subckt expansion. */
struct line *ci_options;/* The .option cards from the deck... */
struct variable *ci_vars; /* ... and the parsed versions. */
bool ci_inprogress; /* We are in a break now. */
bool ci_runonce; /* So com_run can to a reset if necessary... */
wordlist *ci_commands; /* Things to do when this circuit is done. */
struct circ *ci_next; /* The next in the list. */
char *ci_nodes; /* ccom structs for the nodes... */
char *ci_devices; /* and devices in the circuit. */
char *ci_filename; /* Where this circuit came from. */
char *ci_defTask; /* the default task for this circuit */
char *ci_specTask; /* the special task for command line jobs */
char *ci_curTask; /* the most recent task for this circuit */
char *ci_defOpt; /* the default options anal. for this circuit */
char *ci_specOpt; /* the special options anal. for command line jobs */
char *ci_curOpt; /* the most recent options anal. for the circuit */
} ;
struct subcirc {
char *sc_name; /* Whatever... */
} ;
struct save_info {
char *name;
IFuid *analysis;

View File

@ -1,22 +0,0 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1987 Jeffrey M. Hsu
**********/
/*
Defines for help.
*/
#define E_HASPLOTS 1
#define E_NOPLOTS 2
#define E_HASGRAPHS 4
#define E_MENUMODE 8
#define E_BEGINNING 4096
#define E_INTERMED 8192
#define E_ADVANCED 16384
#define E_ALWAYS 32768
/* default is intermediate level */
#define E_DEFHMASK 8192

View File

@ -4,7 +4,6 @@
#include "wordlist.h"
#include "bool.h"
#include "dvec.h"
#include "variable.h"
/* The information for a particular set of vectors that come from one
* plot. */

View File

@ -1,36 +0,0 @@
#ifndef _VARIABLE_H
#define _VARIABLE_H
/* Variables that are accessible to the parser via $varname expansions.
* If the type is VT_LIST the value is a pointer to a list of the elements.
*/
struct variable {
char va_type;
char *va_name;
union {
bool vV_bool;
int vV_num;
double vV_real;
char *vV_string;
struct variable *vV_list;
} va_V;
struct variable *va_next; /* Link. */
} ;
#define va_bool va_V.vV_bool
#define va_num va_V.vV_num
#define va_real va_V.vV_real
#define va_string va_V.vV_string
#define va_vlist va_V.vV_list
enum vt_types {
VT_BOOL,
VT_NUM,
VT_REAL,
VT_STRING,
VT_LIST
};
#endif

View File

@ -22,6 +22,7 @@
#include <devices/dev.h>
#include <misc/ivars.h>
#include <frontend/resource.h>
#include <frontend/variable.h>
#ifdef HAVE_PWD_H
#include <pwd.h>

View File

@ -128,6 +128,12 @@ cx_not(void *data, short int type, int length, int *newlength, short int *newtyp
return ((void *) d);
}
#if 0
/* These functions have been temporarily disabled. They contain code
only found in the frontend and their prototype does not conform to
the prototypes found for other complex functions. They will not be
re-enabled until these issues have been resolved. */
/* This is a strange function. What we do is fit a polynomial to the
* curve, of degree $polydegree, and then evaluate it at the points
* in the time scale. What we do is this: for every set of points that
@ -135,9 +141,8 @@ cx_not(void *data, short int type, int length, int *newlength, short int *newtyp
* (i.e, between the last value of the old scale we went from to this
* one). At the ends we just use what we have... We have to detect
* badness here too...
* Note that we pass arguments differently for this one cx_ function...
*/
*
* Note that we pass arguments differently for this one cx_ function... */
void *
cx_interpolate(void *data, short int type, int length, int *newlength, short int *newtype, struct plot *pl, struct plot *newpl, int grouping)
{
@ -160,28 +165,10 @@ cx_interpolate(void *data, short int type, int length, int *newlength, short int
if (iscomplex(ns)) {
fprintf(cp_err, "Error: new scale has complex data\n");
return (NULL);
/*
for (i = ns->v_length - 1; i >= 0; i--)
if (imagpart(&ns->v_compdata[i])) {
fprintf(cp_err,
"Error: new scale has complex data\n");
return (NULL);
}
osbuf = alloc_d(olen);
*/
}
if (iscomplex(os)) {
fprintf(cp_err, "Error: old scale has complex data\n");
return (NULL);
/*
for (i = os->v_length - 1; i >= 0; i--)
if (imagpart(&os->v_compdata[i])) {
fprintf(cp_err,
"Error: old scale has complex data\n");
return (NULL);
}
nsbuf = alloc_d(nlen);
*/
}
if (length != os->v_length) {
@ -193,9 +180,8 @@ cx_interpolate(void *data, short int type, int length, int *newlength, short int
return (NULL);
}
/* Now make sure that either both scales are strictly increasing or
* both are strictly decreasing.
*/
/* Now make sure that either both scales are strictly increasing
* or both are strictly decreasing. */
if (os->v_realdata[0] < os->v_realdata[1])
oincreasing = TRUE;
else
@ -382,3 +368,4 @@ cx_deriv(void *data, short int type, int length, int *newlength, short int *newt
}
}
#endif

View File

@ -1,326 +0,0 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1986 Wayne A. Christopher, U. C. Berkeley CAD Group
**********/
/*
* Routines to handle "more"d output. There are some serious system
* dependencies in here, and it isn't clear that versions of this stuff
* can be written for every possible machine...
*/
#include <config.h>
#ifdef HAVE_SGTTY_H
#include <sgtty.h>
#endif
#if 0
/* Bad interaction with bool type in bool.h because curses also
defines this symbol. */
#ifdef HAVE_TERMCAP
#include <curses.h>
#include <term.h>
#endif
#endif
#include "ngspice.h"
#include "cpdefs.h"
#include "terminal.h"
static char *motion_chars;
static char *clear_chars;
static char *home_chars;
static char *cleol_chars;
#define DEF_SCRHEIGHT 24
#define DEF_SCRWIDTH 80
bool out_moremode = TRUE;
bool out_isatty = TRUE;
static int xsize, ysize;
static int xpos, ypos;
static bool noprint, nopause;
/* out_printf doesn't handle double arguments correctly, so we
sprintf into this buf and call out_send w/ it */
char out_pbuf[BSIZE_SP];
/* Start output... */
void
out_init(void)
{
#ifdef TIOCGWINSZ
struct winsize ws;
#endif
bool moremode;
noprint = nopause = FALSE;
if (cp_getvar("nomoremode", VT_BOOL, (char *) &moremode))
out_moremode = FALSE;
else
out_moremode = TRUE;
if (!out_moremode || !cp_interactive)
out_isatty = FALSE;
if (!out_isatty)
return;
xsize = ysize = 0;
/* Figure out the screen size. We try, in order, TIOCGSIZE,
* tgetent(), and cp_getvar(height). Default is 24 x 80.
*/
#ifdef TIOCGWINSZ
if (!xsize || !ysize) {
(void) ioctl(fileno(stdout), TIOCGWINSZ, (char *) &ws);
xsize = ws.ws_col;
ysize = ws.ws_row;
}
#endif
if (!xsize)
(void) cp_getvar("width", VT_NUM, (char *) &xsize);
if (!ysize)
(void) cp_getvar("height", VT_NUM, (char *) &ysize);
if (!xsize)
xsize = DEF_SCRWIDTH;
if (!ysize)
ysize = DEF_SCRHEIGHT;
ysize -= 2; /* Fudge room... */
xpos = ypos = 0;
return;
}
/* Putc may not be buffered (sp?), so we do it ourselves. */
static char staticbuf[BUFSIZ];
struct {
int count;
char *ptr;
} ourbuf = { BUFSIZ, staticbuf };
/* send buffer out */
void
outbufputc(void)
{
if (ourbuf.count != BUFSIZ) {
fputs(staticbuf, cp_out);
memset(staticbuf, 0, BUFSIZ-ourbuf.count);
ourbuf.count = BUFSIZ;
ourbuf.ptr = staticbuf;
}
}
static void
bufputc(char c)
{
if (--ourbuf.count >= 0) {
*ourbuf.ptr++ = c;
} else {
/* Flush and reset the buffer */
outbufputc();
/* and store the character. */
ourbuf.count--;
*ourbuf.ptr++ = c;
}
}
/* prompt for a return */
void
promptreturn(void)
{
char buf[16];
moe:
fprintf(cp_out,
"\n\t-- hit return for more, ? for help -- ");
if (!fgets(buf, 16, cp_in)) {
clearerr(cp_in);
*buf = 'q';
}
switch (*buf) {
case '\n':
break;
case 'q':
noprint = TRUE;
break;
case 'c':
nopause = TRUE;
break;
case ' ':
break;
case '?':
fprintf(cp_out,
"\nPossible responses:\n\
\t<cr> : Print another screenful\n\
\tq <cr> : Discard the rest of the output\n\
\tc <cr> : Continuously print the rest of the output\n\
\t? <cr> : Print this help message\n");
goto moe;
default:
fprintf(cp_out, "Character %d is no good\n", *buf);
goto moe;
}
}
/* Print a string to the output. If this would cause the screen to scroll,
* print "more".
*/
void
out_send(char *string)
{
if (noprint)
return;
if (!out_isatty || nopause) {
fputs(string, cp_out);
return;
}
while (*string) {
switch (*string) {
case '\n':
xpos = 0;
ypos++;
break;
case '\f':
ypos = ysize;
xpos = 0;
break;
case '\t':
xpos = xpos / 8 + 1;
xpos *= 8;
break;
default:
xpos++;
break;
}
while (xpos >= xsize) {
xpos -= xsize;
ypos++;
}
if (ypos >= ysize) {
outbufputc(); /* out goes buffer */
promptreturn();
(void) fflush(cp_out);
ypos = xpos = 0;
}
bufputc(*string); /* we need to buffer these */
string++;
}
(void) outbufputc();
return;
}
/* Printf some stuff using more mode. */
#define MAXLEN 4096
void
out_printf(char *fmt, char *s1, char *s2, char *s3, char *s4, char *s5, char *s6, char *s7, char *s8, char *s9, char *s10)
{
char buf[MAXLEN];
sprintf(buf, fmt, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10);
out_send(buf);
return;
}
static int
outfn(int c)
{
putc(c, stdout);
return c;
}
void
tcap_init(void)
{
char *s;
#ifdef HAVE_TERMCAP
char tbuf[1025];
static char buf2[100];
char *charbuf;
charbuf = buf2;
if ((s = getenv("TERM"))) {
if (tgetent(tbuf, s) != -1) {
xsize = tgetnum("co");
ysize = tgetnum("li");
if ((xsize <= 0) || (ysize <= 0))
xsize = ysize = 0;
clear_chars = (char *) tgetstr("cl", &charbuf);
motion_chars = (char *) tgetstr("cm", &charbuf);
home_chars = (char *) tgetstr("ho", &charbuf);
cleol_chars = (char *) tgetstr("ce", &charbuf);
}
}
#endif
if (!xsize) {
if ((s = getenv("COLS")))
xsize = atoi(s);
if (xsize <= 0)
xsize = 0;
}
if (!ysize) {
if ((s = getenv("LINES")))
ysize = atoi(s);
if (ysize <= 0)
ysize = 0;
}
}
void
term_clear(void)
{
#ifdef HAVE_TERMCAP
if (*clear_chars)
tputs(clear_chars, 1, outfn);
else
fputs("\n", stdout);
#endif
}
void
term_home(void)
{
#ifdef HAVE_TERMCAP
if (*home_chars)
tputs(home_chars, 1, outfn);
else if (*motion_chars)
tputs(tgoto(motion_chars, 1, 1), 1, outfn);
else
fputs("\n", stdout);
#endif
}
void
term_cleol(void)
{
#ifdef HAVE_TERMCAP
if (*cleol_chars)
tputs(cleol_chars, 1, outfn);
#endif
}

View File

@ -1,16 +0,0 @@
#ifndef _TERMINAL_H
#define _TERMINAL_H
void out_init(void);
void outbufputc(void);
void promptreturn(void);
void out_send(char *string);
void out_printf(char *fmt, char *s1, char *s2, char *s3,
char *s4, char *s5, char *s6,
char *s7, char *s8, char *s9, char *s10);
void term_clear(void);
void term_home(void);
void term_cleol(void);
void tcap_init(void);
#endif

View File

@ -456,24 +456,3 @@ com_chdir(wordlist *wl)
return;
}
/* This is a truly evil thing */
void
com_strcmp(wordlist *wl)
{
char *var, *s1, *s2;
int i;
var = wl->wl_word;
s1 = cp_unquote(wl->wl_next->wl_word);
s2 = cp_unquote(wl->wl_next->wl_next->wl_word);
i = strcmp(s1, s2);
cp_vset(var, VT_NUM, (char *) &i);
return;
}

View File

@ -1,951 +0,0 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
**********/
/*
* The front-end command loop.
*/
#include "ngspice.h"
#include "cpdefs.h"
#include "front.h"
/* Return values from doblock(). I am assuming that nobody will use
* these characters in a string. */
#define NORMAL '\001'
#define BROKEN '\002'
#define CONTINUED '\003'
#define NORMAL_STR "\001"
#define BROKEN_STR "\002"
#define CONTINUED_STR "\003"
/* Are we waiting for a command? This lets signal handling be
* more clever. */
bool cp_cwait = FALSE;
char *cp_csep = ";";
bool cp_dounixcom = FALSE;
enum co_command {
CO_UNFILLED,
CO_STATEMENT,
CO_WHILE,
CO_DOWHILE,
CO_IF,
CO_FOREACH,
CO_BREAK,
CO_CONTINUE,
CO_LABEL,
CO_GOTO,
CO_REPEAT
};
/* We have to keep the control structures in a stack, so that when we do
* a 'source', we can push a fresh set onto the top... Actually there have
* to be two stacks -- one for the pointer to the list of control structs,
* and one for the 'current command' pointer...
*/
#define CONTROLSTACKSIZE 256 /* Better be enough. */
static struct control *control[CONTROLSTACKSIZE], *cend[CONTROLSTACKSIZE];
/* static declarations */
static char * doblock(struct control *bl, int *num);
static struct control * findlabel(char *s, struct control *ct);
static void docommand(register wordlist *wlist);
static wordlist * getcommand(char *string);
static void pwlist(wordlist *wlist, char *name);
static void dodump(struct control *cc);
static int stackp = 0;
/* If there is an argument, give this to cshpar to use instead of
* stdin. In a few places, we call cp_evloop again if it returns 1 and
* exit (or close a file) if it returns 0... Because of the way
* sources are done, we can't allow the control structures to get
* blown away every time we return -- probably every time we type
* source at the keyboard and every time a source returns to keyboard
* input is ok though -- use ft_controlreset. */
static char *noredirect[] = { "stop", NULL } ; /* Only one?? */
int
cp_evloop(char *string)
{
wordlist *wlist, *ww;
struct control *x;
char *i;
int nn;
#define newblock cend[stackp]->co_children = alloc(struct control); \
ZERO(cend[stackp]->co_children,struct control), \
cend[stackp]->co_children->co_parent = cend[stackp]; \
cend[stackp] = cend[stackp]->co_children; \
cend[stackp]->co_type = CO_UNFILLED;
for (;;) {
wlist = getcommand(string);
if (wlist == NULL) { /* End of file or end of user input. */
if (cend[stackp]->co_parent && !string) {
cp_resetcontrol();
continue;
} else
return (0);
}
if ((wlist->wl_word == NULL) || (*wlist->wl_word == '\0')) {
/* User just typed return. */
if (string)
return (1);
else {
cp_event--;
continue;
}
}
/* Just a check... */
for (ww = wlist; ww; ww = ww->wl_next)
if (!ww->wl_word) {
fprintf(cp_err,
"cp_evloop: Internal Error: NULL word pointer\n");
continue;
}
/* Add this to the control structure list. If cend->co_type is
* CO_UNFILLED, the last line was the beginning of a block,
* and this is the unfilled first statement. */
if (cend[stackp] && (cend[stackp]->co_type != CO_UNFILLED)) {
cend[stackp]->co_next = alloc(struct control);
ZERO(cend[stackp]->co_next, struct control);
cend[stackp]->co_next->co_prev = cend[stackp];
cend[stackp]->co_next->co_parent =
cend[stackp]->co_parent;
cend[stackp] = cend[stackp]->co_next;
} else if (!cend[stackp]) {
control[stackp] = cend[stackp] = alloc(struct control);
ZERO(cend[stackp], struct control);
}
if (eq(wlist->wl_word, "while")) {
cend[stackp]->co_type = CO_WHILE;
cend[stackp]->co_cond = wlist->wl_next;
if (!cend[stackp]->co_cond) {
fprintf(stderr,
"Error: missing while condition.\n");
}
newblock;
} else if (eq(wlist->wl_word, "dowhile")) {
cend[stackp]->co_type = CO_DOWHILE;
cend[stackp]->co_cond = wlist->wl_next;
if (!cend[stackp]->co_cond) {
fprintf(stderr,
"Error: missing dowhile condition.\n");
}
newblock;
} else if (eq(wlist->wl_word, "repeat")) {
cend[stackp]->co_type = CO_REPEAT;
if (!wlist->wl_next) {
cend[stackp]->co_numtimes = -1;
} else {
char *s;
double *dd;
wlist = cp_variablesubst(cp_bquote(
cp_doglob(wl_copy(wlist))));
s = wlist->wl_next->wl_word;
dd = ft_numparse(&s, FALSE);
if (dd) {
if (*dd < 0) {
fprintf(cp_err,
"Error: can't repeat a negative number of times\n");
*dd = 0.0;
}
cend[stackp]->co_numtimes = (int) *dd;
} else
fprintf(cp_err,
"Error: bad repeat argument %s\n",
wlist->wl_next->wl_word);
}
newblock;
} else if (eq(wlist->wl_word, "if")) {
cend[stackp]->co_type = CO_IF;
cend[stackp]->co_cond = wlist->wl_next;
if (!cend[stackp]->co_cond) {
fprintf(stderr,
"Error: missing if condition.\n");
}
newblock;
} else if (eq(wlist->wl_word, "foreach")) {
cend[stackp]->co_type = CO_FOREACH;
if (wlist->wl_next) {
wlist = wlist->wl_next;
cend[stackp]->co_foreachvar =
copy(wlist->wl_word);
wlist = wlist->wl_next;
} else
fprintf(stderr,
"Error: missing foreach variable.\n");
wlist = cp_doglob(wlist);
cend[stackp]->co_text = wl_copy(wlist);
newblock;
} else if (eq(wlist->wl_word, "label")) {
cend[stackp]->co_type = CO_LABEL;
if (wlist->wl_next) {
cend[stackp]->co_text = wl_copy(wlist->wl_next);
/* I think of everything, don't I? */
cp_addkword(CT_LABEL, wlist->wl_next->wl_word);
if (wlist->wl_next->wl_next)
fprintf(cp_err,
"Warning: ignored extra junk after label.\n");
} else
fprintf(stderr, "Error: missing label.\n");
} else if (eq(wlist->wl_word, "goto")) {
/* Incidentally, this won't work if the values 1 and 2 ever get
* to be valid character pointers -- I think it's reasonably
* safe to assume they aren't... */
cend[stackp]->co_type = CO_GOTO;
if (wlist->wl_next) {
cend[stackp]->co_text = wl_copy(wlist->wl_next);
if (wlist->wl_next->wl_next)
fprintf(cp_err,
"Warning: ignored extra junk after goto.\n");
} else
fprintf(stderr, "Error: missing label.\n");
} else if (eq(wlist->wl_word, "continue")) {
cend[stackp]->co_type = CO_CONTINUE;
if (wlist->wl_next) {
cend[stackp]->co_numtimes = scannum(wlist->
wl_next->wl_word);
if (wlist->wl_next->wl_next)
fprintf(cp_err,
"Warning: ignored extra junk after continue %d.\n",
cend[stackp]->co_numtimes);
} else
cend[stackp]->co_numtimes = 1;
} else if (eq(wlist->wl_word, "break")) {
cend[stackp]->co_type = CO_BREAK;
if (wlist->wl_next) {
cend[stackp]->co_numtimes = scannum(wlist->
wl_next->wl_word);
if (wlist->wl_next->wl_next)
fprintf(cp_err,
"Warning: ignored extra junk after break %d.\n",
cend[stackp]->co_numtimes);
} else
cend[stackp]->co_numtimes = 1;
} else if (eq(wlist->wl_word, "end")) {
/* Throw away this thing. */
if (!cend[stackp]->co_parent) {
fprintf(stderr, "Error: no block to end.\n");
cend[stackp]->co_type = CO_UNFILLED;
} else if (cend[stackp]->co_prev) {
cend[stackp]->co_prev->co_next = NULL;
x = cend[stackp];
cend[stackp] = cend[stackp]->co_parent;
tfree(x);
} else {
x = cend[stackp];
cend[stackp] = cend[stackp]->co_parent;
cend[stackp]->co_children = NULL;
tfree(x);
}
} else if (eq(wlist->wl_word, "else")) {
if (!cend[stackp]->co_parent ||
(cend[stackp]->co_parent->co_type !=
CO_IF)) {
fprintf(stderr, "Error: misplaced else.\n");
cend[stackp]->co_type = CO_UNFILLED;
} else {
if (cend[stackp]->co_prev)
cend[stackp]->co_prev->co_next = NULL;
else
cend[stackp]->co_parent->co_children = NULL;
cend[stackp]->co_parent->co_elseblock = cend[stackp];
cend[stackp]->co_prev = NULL;
}
} else {
cend[stackp]->co_type = CO_STATEMENT;
cend[stackp]->co_text = wlist;
}
if (!cend[stackp]->co_parent) {
x = cend[stackp];
/* We have to toss this do-while loop in here so
* that gotos at the top level will work.
*/
do {
i = doblock(x, &nn);
switch (*i) {
case NORMAL:
break;
case BROKEN:
fprintf(cp_err,
"Error: break not in loop or too many break levels given\n");
break;
case CONTINUED:
fprintf(cp_err,
"Error: continue not in loop or too many continue levels given\n");
break;
default:
x = findlabel(i, control[stackp]);
if (!x)
fprintf(cp_err, "Error: label %s not found\n", i);
}
if (x)
x = x->co_next;
} while (x);
}
if (string)
return (1); /* The return value is irrelevant. */
}
}
/* Execute a block. There can be a number of return values from this routine.
* NORMAL indicates a normal termination
* BROKEN indicates a break -- if the caller is a breakable loop,
* terminate it, otherwise pass the break upwards
* CONTINUED indicates a continue -- if the caller is a continuable loop,
* continue, else pass the continue upwards
* Any other return code is considered a pointer to a string which is
* a label somewhere -- if this label is present in the block,
* goto it, otherwise pass it up. Note that this prevents jumping
* into a loop, which is good.
* Note that here is where we expand variables, ``, and globs for controls.
* The 'num' argument is used by break n and continue n.
*/
static char *
doblock(struct control *bl, int *num)
{
struct control *ch, *cn = NULL;
wordlist *wl;
char *i;
int nn;
switch (bl->co_type) {
case CO_WHILE:
while (bl->co_cond && cp_isTRUE(bl->co_cond)) {
for (ch = bl->co_children; ch; ch = cn) {
cn = ch->co_next;
i = doblock(ch, &nn);
switch (*i) {
case NORMAL:
break;
case BROKEN: /* Break. */
if (nn < 2)
return (NORMAL_STR);
else {
*num = nn - 1;
return (BROKEN_STR);
}
case CONTINUED: /* Continue. */
if (nn < 2) {
cn = NULL;
break;
} else {
*num = nn - 1;
return (CONTINUED_STR);
}
default:
cn = findlabel(i, bl->co_children);
if (!cn)
return (i);
}
}
}
break;
case CO_DOWHILE:
do {
for (ch = bl->co_children; ch; ch = cn) {
cn = ch->co_next;
i = doblock(ch, &nn);
switch (*i) {
case NORMAL:
break;
case BROKEN: /* Break. */
if (nn < 2)
return (NORMAL_STR);
else {
*num = nn - 1;
return (BROKEN_STR);
}
case CONTINUED: /* Continue. */
if (nn < 2) {
cn = NULL;
break;
} else {
*num = nn - 1;
return (CONTINUED_STR);
}
default:
cn = findlabel(i, bl->co_children);
if (!cn)
return (i);
}
}
} while (bl->co_cond && cp_isTRUE(bl->co_cond));
break;
case CO_REPEAT:
while ((bl->co_numtimes > 0) ||
(bl->co_numtimes == -1)) {
if (bl->co_numtimes != -1)
bl->co_numtimes--;
for (ch = bl->co_children; ch; ch = cn) {
cn = ch->co_next;
i = doblock(ch, &nn);
switch (*i) {
case NORMAL:
break;
case BROKEN: /* Break. */
if (nn < 2)
return (NORMAL_STR);
else {
*num = nn - 1;
return (BROKEN_STR);
}
case CONTINUED: /* Continue. */
if (nn < 2) {
cn = NULL;
break;
} else {
*num = nn - 1;
return (CONTINUED_STR);
}
default:
cn = findlabel(i, bl->co_children);
if (!cn)
return (i);
}
}
}
break;
case CO_IF:
if (bl->co_cond && cp_isTRUE(bl->co_cond)) {
for (ch = bl->co_children; ch; ch = cn) {
cn = ch->co_next;
i = doblock(ch, &nn);
if (*i > 2) {
cn = findlabel(i,
bl->co_children);
if (!cn)
return (i);
} else if (*i != NORMAL) {
*num = nn;
return (i);
}
}
} else {
for (ch = bl->co_elseblock; ch; ch = cn) {
cn = ch->co_next;
i = doblock(ch, &nn);
if (*i > 2) {
cn = findlabel(i,
bl->co_elseblock);
if (!cn)
return (i);
} else if (*i != NORMAL) {
*num = nn;
return (i);
}
}
}
break;
case CO_FOREACH:
for (wl = cp_variablesubst(cp_bquote(cp_doglob(wl_copy(bl->co_text))));
wl;
wl = wl->wl_next) {
cp_vset(bl->co_foreachvar, VT_STRING, wl->wl_word);
for (ch = bl->co_children; ch; ch = cn) {
cn = ch->co_next;
i = doblock(ch, &nn);
switch (*i) {
case NORMAL:
break;
case BROKEN: /* Break. */
if (nn < 2)
return (NORMAL_STR);
else {
*num = nn - 1;
return (BROKEN_STR);
}
case CONTINUED: /* Continue. */
if (nn < 2) {
cn = NULL;
break;
} else {
*num = nn - 1;
return (CONTINUED_STR);
}
default:
cn = findlabel(i, bl->co_children);
if (!cn)
return (i);
}
}
}
break;
case CO_BREAK:
if (bl->co_numtimes > 0) {
*num = bl->co_numtimes;
return (BROKEN_STR);
} else {
fprintf(cp_err, "Warning: break %d a no-op\n",
bl->co_numtimes);
return (NORMAL_STR);
}
case CO_CONTINUE:
if (bl->co_numtimes > 0) {
*num = bl->co_numtimes;
return (CONTINUED_STR);
} else {
fprintf(cp_err, "Warning: continue %d a no-op\n",
bl->co_numtimes);
return (NORMAL_STR);
}
case CO_GOTO:
wl = cp_variablesubst(cp_bquote(cp_doglob(
wl_copy(bl->co_text))));
return (wl->wl_word);
case CO_LABEL:
/* Do nothing. */
break;
case CO_STATEMENT:
docommand(wl_copy(bl->co_text));
break;
case CO_UNFILLED:
/* There was probably an error here... */
fprintf(cp_err, "Warning: ignoring previous error\n");
break;
default:
fprintf(cp_err,
"doblock: Internal Error: bad block type %d\n",
bl->co_type);
return (NORMAL_STR);
}
return (NORMAL_STR);
}
static struct control *
findlabel(char *s, struct control *ct)
{
while (ct) {
if ((ct->co_type == CO_LABEL) && eq(s, ct->co_text->wl_word))
break;
ct = ct->co_next;
}
return (ct);
}
/* This blows away the control structures... */
void
cp_resetcontrol(void)
{
if (cend[stackp] && cend[stackp]->co_parent)
fprintf(cp_err, "Warning: EOF before block terminated\n");
/* We probably should free the control structures... */
control[0] = cend[0] = NULL;
stackp = 0;
cp_kwswitch(CT_LABEL, (char *) NULL);
return;
}
/* Push or pop a new control structure set... */
void
cp_popcontrol(void)
{
if (cp_debug)
fprintf(cp_err, "pop: stackp: %d -> %d\n", stackp, stackp - 1);
if (stackp < 1)
fprintf(cp_err, "cp_popcontrol: Internal Error: stack empty\n");
else
stackp--;
return;
}
void
cp_pushcontrol(void)
{
if (cp_debug)
fprintf(cp_err, "push: stackp: %d -> %d\n", stackp, stackp + 1);
if (stackp > CONTROLSTACKSIZE - 2) {
fprintf(cp_err, "Error: stack overflow -- max depth = %d\n",
CONTROLSTACKSIZE);
stackp = 0;
} else {
stackp++;
control[stackp] = cend[stackp] = NULL;
}
return;
}
/* And this returns to the top level (for use in the interrupt handlers). */
void
cp_toplevel(void)
{
stackp = 0;
if (cend[stackp])
while (cend[stackp]->co_parent)
cend[stackp] = cend[stackp]->co_parent;
return;
}
/* Note that we only do io redirection when we get to here - we also
* postpone some other things until now. */
static void
docommand(register wordlist *wlist)
{
register char *r, *s, *t;
char *lcom;
int nargs;
register int i;
struct comm *command;
wordlist *wl, *nextc, *ee, *rwlist;
if (cp_debug) {
printf("docommand ");
wl_print(wlist, stdout);
putc('\n', stdout);
}
/* Do all the things that used to be done by cshpar when the line
* was read... */
wlist = cp_variablesubst(wlist);
pwlist(wlist, "After variable substitution");
wlist = cp_bquote(wlist);
pwlist(wlist, "After backquote substitution");
wlist = cp_doglob(wlist);
pwlist(wlist, "After globbing");
if (!wlist || !wlist->wl_word)
return;
/* Now loop through all of the commands given. */
rwlist = wlist;
do {
for (nextc = wlist; nextc; nextc = nextc->wl_next)
if (eq(nextc->wl_word, cp_csep))
break;
/* Temporarily hide the rest of the command... */
if (nextc && nextc->wl_prev)
nextc->wl_prev->wl_next = NULL;
ee = wlist->wl_prev;
if (ee)
wlist->wl_prev = NULL;
if (nextc == wlist) {
/* There was no text... */
goto out;
}
/* And do the redirection. */
cp_ioreset();
for (i = 0; noredirect[i]; i++)
if (eq(wlist->wl_word, noredirect[i]))
break;
if (!noredirect[i]) {
if (!(wlist = cp_redirect(wlist))) {
cp_ioreset();
return;
}
}
/* Get rid of all the 8th bits now... */
cp_striplist(wlist);
s = wlist->wl_word;
/* Look for the command in the command list. */
for (i = 0; cp_coms[i].co_comname; i++) {
/* strcmp(cp_coms[i].co_comname, s) ... */
for (t = cp_coms[i].co_comname, r = s; *t && *r;
t++, r++)
if (*t != *r)
break;
if (!*t && !*r)
break;
}
/* Now give the user-supplied command routine a try... */
if (!cp_coms[i].co_func && cp_oddcomm(s, wlist->wl_next))
goto out;
/* If it's not there, try it as a unix command. */
if (!cp_coms[i].co_comname) {
if (cp_dounixcom && cp_unixcom(wlist))
goto out;
fprintf(cp_err,"%s: no such command available in %s\n",
s, cp_program);
goto out;
/* If it's there but spiceonly, and this is nutmeg, error. */
} else if (!cp_coms[i].co_func && ft_nutmeg &&
(cp_coms[i].co_spiceonly)) {
fprintf(cp_err,"%s: command available only in spice\n",
s);
goto out;
}
/* The command was a valid spice/nutmeg command. */
command = &cp_coms[i];
nargs = 0;
for (wl = wlist->wl_next; wl; wl = wl->wl_next)
nargs++;
if (command->co_stringargs) {
lcom = wl_flatten(wlist->wl_next);
(*command->co_func) (lcom);
} else {
if (nargs < command->co_minargs) {
if (command->co_argfn) {
(*command->co_argfn) (wlist->wl_next, command);
} else {
fprintf(cp_err, "%s: too few args.\n", s);
}
} else if (nargs > command->co_maxargs) {
fprintf(cp_err, "%s: too many args.\n", s);
} else
(*command->co_func) (wlist->wl_next);
}
/* Now fix the pointers and advance wlist. */
out: wlist->wl_prev = ee;
if (nextc) {
if (nextc->wl_prev)
nextc->wl_prev->wl_next = nextc;
wlist = nextc->wl_next;
}
} while (nextc && wlist);
wl_free(rwlist);
/* Do periodic sorts of things... */
cp_periodic();
cp_ioreset();
return;
}
/* Get a command. This does all the bookkeeping things like turning
* command completion on and off... */
static wordlist *
getcommand(char *string)
{
wordlist *wlist;
int i = 0, j;
static char buf[64];
struct control *c;
if (cp_debug)
fprintf(cp_err, "calling getcommand %s\n",
string ? string : "");
if (cend[stackp]) {
for (c = cend[stackp]->co_parent; c; c = c->co_parent)
i++;
if (i) {
for (j = 0; j < i; j++)
buf[j] = '>';
buf[j] = ' ';
buf[j + 1] = '\0';
cp_altprompt = buf;
} else
cp_altprompt = NULL;
} else
cp_altprompt = NULL;
cp_cwait = TRUE;
wlist = cp_parse(string);
cp_cwait = FALSE;
if (cp_debug) {
printf("getcommand ");
wl_print(wlist, stdout);
putc('\n', stdout);
}
return (wlist);
}
/* This is also in cshpar.c ... */
static void
pwlist(wordlist *wlist, char *name)
{
wordlist *wl;
if (!cp_debug)
return;
fprintf(cp_err, "%s : [ ", name);
for (wl = wlist; wl; wl = wl->wl_next)
fprintf(cp_err, "%s ", wl->wl_word);
fprintf(cp_err, "]\n");
return;
}
static int indent;
void
com_cdump(wordlist *wl)
{
struct control *c;
indent = 0;
for (c = control[stackp]; c; c = c->co_next)
dodump(c);
return;
}
#define tab(num) for (i = 0; i < num; i++) putc(' ', cp_out);
static void
dodump(struct control *cc)
{
int i;
struct control *tc;
switch (cc->co_type) {
case CO_UNFILLED:
tab(indent);
fprintf(cp_out, "(unfilled)\n");
break;
case CO_STATEMENT:
tab(indent);
wl_print(cc->co_text, cp_out);
putc('\n', cp_out);
break;
case CO_WHILE:
tab(indent);
fprintf(cp_out, "while ");
wl_print(cc->co_cond, cp_out);
putc('\n', cp_out);
indent += 8;
for (tc = cc->co_children; tc; tc = tc->co_next)
dodump(tc);
indent -= 8;
tab(indent);
fprintf(cp_out, "end\n");
break;
case CO_REPEAT:
tab(indent);
fprintf(cp_out, "repeat ");
if (cc->co_numtimes != -1)
fprintf(cp_out, "%d\n", cc->co_numtimes);
else
putc('\n', cp_out);
indent += 8;
for (tc = cc->co_children; tc; tc = tc->co_next)
dodump(tc);
indent -= 8;
tab(indent);
fprintf(cp_out, "end\n");
break;
case CO_DOWHILE:
tab(indent);
fprintf(cp_out, "dowhile ");
wl_print(cc->co_cond, cp_out);
putc('\n', cp_out);
indent += 8;
for (tc = cc->co_children; tc; tc = tc->co_next)
dodump(tc);
indent -= 8;
tab(indent);
fprintf(cp_out, "end\n");
break;
case CO_IF:
tab(indent);
fprintf(cp_out, "if ");
wl_print(cc->co_cond, cp_out);
putc('\n', cp_out);
indent += 8;
for (tc = cc->co_children; tc; tc = tc->co_next)
dodump(tc);
indent -= 8;
tab(indent);
fprintf(cp_out, "end\n");
break;
case CO_FOREACH:
tab(indent);
fprintf(cp_out, "foreach %s ", cc->co_foreachvar);
wl_print(cc->co_text, cp_out);
putc('\n', cp_out);
indent += 8;
for (tc = cc->co_children; tc; tc = tc->co_next)
dodump(tc);
indent -= 8;
tab(indent);
fprintf(cp_out, "end\n");
break;
case CO_BREAK:
tab(indent);
if (cc->co_numtimes != 1)
fprintf(cp_out, "break %d\n", cc->co_numtimes);
else
fprintf(cp_out, "break\n");
break;
case CO_CONTINUE:
tab(indent);
if (cc->co_numtimes != 1)
fprintf(cp_out, "continue %d\n",
cc->co_numtimes);
else
fprintf(cp_out, "continue\n");
break;
case CO_LABEL:
tab(indent);
fprintf(cp_out, "label %s\n", cc->co_text->wl_word);
break;
case CO_GOTO:
tab(indent);
fprintf(cp_out, "goto %s\n", cc->co_text->wl_word);
break;
default:
tab(indent);
fprintf(cp_out, "bad type %d\n", cc->co_type);
break;
}
return;
}

View File

@ -1,40 +0,0 @@
/*************
* Header file for front.c
* 1999 E. Rouat
************/
#ifndef FRONT_H_INCLUDED
#define FRONT_H_INCLUDED
/* Stuff to do control structures. We keep a history (seperate from the
* cshpar history, for now at least) of commands and their event numbers,
* with a block considered as a statement. In a goto, the first word in
* co_text is where to go, likewise for label. For conditional controls,
* we have to call ft_getpnames and ft_evaluate each time, since the
* dvec pointers will change... Also we should do variable and backquote
* substitution each time...
*/
struct control {
int co_type; /* One of CO_* ... */
wordlist *co_cond; /* if, while, dowhile */
char *co_foreachvar; /* foreach */
int co_numtimes; /* repeat, break & continue levels */
wordlist *co_text; /* Ordinary text and foreach values. */
struct control *co_parent; /* If this is inside a block. */
struct control *co_children; /* The contents of this block. */
struct control *co_elseblock; /* For if-then-else. */
struct control *co_next;
struct control *co_prev;
} ;
int cp_evloop(char *string);
void cp_resetcontrol(void);
void cp_popcontrol(void);
void cp_pushcontrol(void);
void cp_toplevel(void);
void com_cdump(wordlist *wl);
#endif

View File

@ -1,489 +0,0 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
**********/
/*
* Do history substitutions.
*/
#include "ngspice.h"
#include "cpdefs.h"
#include "history.h"
/* static declarations */
static wordlist * dohsubst(char *string);
static wordlist * dohmod(char **string, wordlist *wl);
static wordlist * hpattern(char *buf);
static wordlist * hprefix(char *buf);
static wordlist * getevent(int num);
static void freehist(int num);
static char * dohs(char *pat, char *str);
struct histent *cp_lastone = NULL;
int cp_maxhistlength = 10000; /* Chris Inbody */
char cp_hat = '^';
char cp_bang = '!';
bool cp_didhsubst;
static struct histent *histlist = NULL;
static int histlength = 0;
/* First check for a ^ at the beginning
* of the line, and then search each word for !. Following this can be any
* of string, number, ?string, -number ; then there may be a word specifier,
* the same as csh, and then the : modifiers. For the :s modifier,
* the syntax is :sXoooXnnnX, where X is any character, and ooo and nnn are
* strings not containing X.
*/
wordlist *
cp_histsubst(wordlist *wlist)
{
wordlist *nwl, *w, *n;
char buf[BSIZE_SP], *s, *b;
/* Replace ^old^new with !:s^old^new. */
cp_didhsubst = FALSE;
if (*wlist->wl_word == cp_hat) {
(void) sprintf(buf, "%c%c:s%s", cp_bang, cp_bang,
wlist->wl_word);
tfree(wlist->wl_word);
wlist->wl_word = copy(buf);
}
for (w = wlist; w; w = w->wl_next) {
b = w->wl_word;
for (s = b; *s; s++)
if (*s == cp_bang) {
cp_didhsubst = TRUE;
n = dohsubst(s + 1);
if (!n) {
wlist->wl_word = NULL;
return (wlist);
}
if (b < s) {
(void) sprintf(buf, "%.*s%s", s - b, b,
n->wl_word);
tfree(n->wl_word);
n->wl_word = copy(buf);
}
nwl = wl_splice(w, n);
if (wlist == w)
wlist = n;
w = nwl;
break;
}
}
return (wlist);
}
/* Do a history substitution on one word. Figure out which event is
* being referenced, then do word selections and modifications, and
* then stick anything left over on the end of the last word.
*/
static wordlist *
dohsubst(char *string)
{
wordlist *wl, *nwl;
char buf[BSIZE_SP], *s, *r = NULL, *t;
if (*string == cp_bang) {
if (cp_lastone) {
wl = cp_lastone->hi_wlist;
string++;
} else {
fprintf(cp_err, "0: event not found.\n");
return (NULL);
}
} else {
switch(*string) {
case '-':
wl = getevent(cp_event - scannum(++string));
if (!wl)
return (NULL);
while (isdigit(*string))
string++;
break;
case '?':
(void) strcpy(buf, string + 1);
if ((s =strchr(buf, '?')))
*s = '\0';
wl = hpattern(buf);
if (!wl)
return (NULL);
if (s == NULL) /* No modifiers on this one. */
return (wl_copy(wl));
break;
case '\0': /* Maybe this should be cp_event. */
wl = alloc(struct wordlist);
wl->wl_word = copy("!");
wl->wl_next = NULL;
wl->wl_prev = NULL;
cp_didhsubst = FALSE;
return (wl);
default:
if (isdigit(*string)) {
wl = getevent(scannum(string));
if (!wl)
return (NULL);
while (isdigit(*string))
string++;
} else {
(void) strcpy(buf, string);
for (s = ":^$*-%"; *s; s++) {
t =strchr(buf, *s);
if (t && ((t < r) || !r)) {
r = t;
string += r - buf;
}
}
if (r)
*r = '\0';
else
while (*string)
string++;
if ((buf[0] == '\0') && cp_lastone)
wl = cp_lastone->hi_wlist;
else
wl = hprefix(buf);
if (!wl)
return (NULL);
}
}
}
if (wl == NULL) { /* Shouldn't happen. */
fprintf(cp_err, "Event not found.\n");
return (NULL);
}
nwl = dohmod(&string, wl_copy(wl));
if (!nwl)
return (NULL);
if (*string) {
for (wl = nwl; wl->wl_next; wl = wl->wl_next)
;
(void) sprintf(buf, "%s%s", wl->wl_word, string);
tfree(wl->wl_word);
wl->wl_word = copy(buf);
}
return (nwl);
}
static wordlist *
dohmod(char **string, wordlist *wl)
{
wordlist *w;
char *s;
char *r = NULL, *t;
int numwords, eventlo, eventhi, i;
bool globalsubst;
anothermod:
numwords = wl_length(wl);
globalsubst = FALSE;
eventlo = 0;
eventhi = numwords - 1;
/* Now we know what wordlist we want. Take care of modifiers now. */
r = NULL;
for (s = ":^$*-%"; *s; s++) {
t =strchr(*string, *s);
if (t && ((t < r) || (r == NULL)))
r = t;
}
if (!r) /* No more modifiers. */
return (wl);
*string = r;
if (**string == ':')
(*string)++;
switch(**string) {
case '$': /* Last word. */
eventhi = eventlo = numwords - 1;
break;
case '*': /* Words 1 through $ */
if (numwords == 1)
return (NULL);
eventlo = 1;
eventhi = numwords - 1;
break;
case '-': /* Words 0 through ... */
eventlo = 0;
if (*(*string + 1))
eventhi = scannum(*string + 1);
else
eventhi = numwords - 1;
if (eventhi > numwords - 1)
eventhi = numwords - 1;
break;
case 'p': /* Print the command and don't execute it.
* This doesn't work quite like csh.
*/
wl_print(wl, cp_out);
(void) putc('\n', cp_out);
return (NULL);
case 's': /* Do a substitution. */
for (w = wl; w; w = w->wl_next) {
s = dohs(*string + 1, w->wl_word);
if (s) {
tfree(w->wl_word);
w->wl_word = s;
if (globalsubst == FALSE) {
while (**string)
(*string)++;
break;
}
}
}
/* In case globalsubst is TRUE... */
while (**string)
(*string)++;
break;
default:
if (!isdigit(**string)) {
fprintf(cp_err, "Error: %s: bad modifier.\n",
*string);
return (NULL);
}
i = scannum(*string);
if (i > eventhi) {
fprintf(cp_err, "Error: bad event number %d\n",
i);
return (NULL);
}
eventhi = eventlo = i;
while (isdigit(**string))
(*string)++;
if (**string == '*')
eventhi = numwords - 1;
if (**string == '-') {
if (!isdigit(*(*string + 1)))
eventhi = numwords - 1;
else {
eventhi = scannum(++*string);
while (isdigit(**string))
(*string)++;
}
}
}
/* Now change the word list accordingly and make another pass
* if there is more of the substitute left.
*/
wl = wl_range(wl, eventlo, eventhi);
numwords = wl_length(wl);
if (**string && *++*string)
goto anothermod;
return (wl);
}
/* Look for an event with a pattern in it... */
static wordlist *
hpattern(char *buf)
{
struct histent *hi;
wordlist *wl;
if (*buf == '\0') {
fprintf(cp_err, "Bad pattern specification.\n");
return (NULL);
}
for (hi = cp_lastone; hi; hi = hi->hi_prev)
for (wl = hi->hi_wlist; wl; wl = wl->wl_next)
if (substring(buf, wl->wl_word))
return (hi->hi_wlist);
fprintf(cp_err, "%s: event not found.\n", buf);
return (NULL);
}
static wordlist *
hprefix(char *buf)
{
struct histent *hi;
if (*buf == '\0') {
fprintf(cp_err, "Bad pattern specification.\n");
return (NULL);
}
for (hi = cp_lastone; hi; hi = hi->hi_prev)
if (hi->hi_wlist && prefix(buf, hi->hi_wlist->wl_word))
return (hi->hi_wlist);
fprintf(cp_err, "%s: event not found.\n", buf);
return (NULL);
}
/* Add a wordlist to the history list. (Done after the first parse.) Note
* that if event numbers are given in a random order that's how they'll
* show up in the history list.
*/
void
cp_addhistent(int event, wordlist *wlist)
{
if (cp_lastone && !cp_lastone->hi_wlist)
fprintf(cp_err, "Internal error: bad history list\n");
if (cp_lastone == NULL) {
cp_lastone = histlist = alloc(struct histent);
cp_lastone->hi_prev = NULL;
} else {
cp_lastone->hi_next = alloc(struct histent);
cp_lastone->hi_next->hi_prev = cp_lastone;
cp_lastone = cp_lastone->hi_next;
}
cp_lastone->hi_next = NULL;
cp_lastone->hi_event = event;
cp_lastone->hi_wlist = wl_copy(wlist);
freehist(histlength - cp_maxhistlength);
histlength++;
return;
}
/* Get a copy of the wordlist associated with an event. Error if out
* of range.
*/
static wordlist *
getevent(int num)
{
struct histent *hi;
for (hi = histlist; hi; hi = hi->hi_next)
if (hi->hi_event == num)
break;
if (hi == NULL) {
fprintf(cp_err, "%d: event not found.\n", num);
return (NULL);
}
return (wl_copy(hi->hi_wlist));
}
/* Print out history between eventhi and eventlo.
* This doesn't remember quoting, so 'hodedo' prints as hodedo.
*/
void
cp_hprint(int eventhi, int eventlo, bool rev)
{
struct histent *hi;
if (rev) {
for (hi = histlist; hi->hi_next; hi = hi->hi_next)
;
for (; hi; hi = hi->hi_prev)
if ((hi->hi_event <= eventhi) &&
(hi->hi_event >= eventlo) &&
hi->hi_wlist) {
fprintf(cp_out, "%d\t", hi->hi_event);
wl_print(hi->hi_wlist, cp_out);
(void) putc('\n', cp_out);
}
} else {
for (hi = histlist; hi; hi = hi->hi_next)
if ((hi->hi_event <= eventhi) &&
(hi->hi_event >= eventlo) &&
hi->hi_wlist) {
fprintf(cp_out, "%d\t", hi->hi_event);
wl_print(hi->hi_wlist, cp_out);
(void) putc('\n', cp_out);
}
}
return;
}
/* This just gets rid of the first num entries on the history list, and
* decrements histlength.
*/
static void
freehist(int num)
{
struct histent *hi;
if (num < 1)
return;
histlength -= num;
hi = histlist;
while (num-- && histlist->hi_next)
histlist = histlist->hi_next;
if (histlist->hi_prev) {
histlist->hi_prev->hi_next = NULL;
histlist->hi_prev = NULL;
} else
{
fprintf(cp_err, "Internal error: history list mangled\n");
exit(0); /* Chris Inbody */
}
while (hi->hi_next) {
wl_free(hi->hi_wlist);
hi = hi->hi_next;
tfree(hi->hi_prev);
}
wl_free(hi->hi_wlist);
tfree(hi);
return;
}
/* Do a :s substitution. */
static char *
dohs(char *pat, char *str)
{
char schar, *s, *p, buf[BSIZE_SP];
int i = 0, plen;
bool ok = FALSE;
pat = copy(pat); /* Don't want to mangle anything. */
schar = *pat++;
s =strchr(pat, schar);
if (s == NULL) {
fprintf(cp_err, "Bad substitute.\n");
return (NULL);
}
*s++ = '\0';
p =strchr(s, schar);
if (p)
*p = '\0';
plen = strlen(pat) - 1;
for (i = 0; *str; str++) {
if ((*str == *pat) && prefix(pat, str) && (ok == FALSE)) {
for (p = s; *p; p++)
buf[i++] = *p;
str += plen;
ok = TRUE;
} else
buf[i++] = *str;
}
buf[i] = '\0';
if (ok)
return (copy(buf));
else
return (NULL);
}
/* The "history" command. history [-r] [number] */
void
com_history(wordlist *wl)
{
bool rev = FALSE;
if (wl && eq(wl->wl_word, "-r")) {
wl = wl->wl_next;
rev = TRUE;
}
if (wl == NULL)
cp_hprint(cp_event - 1, cp_event - histlength, rev);
else
cp_hprint(cp_event - 1, cp_event - 1 - atoi(wl->wl_word), rev);
return;
}

View File

@ -1,16 +0,0 @@
/*************
* Header file for history.c
* 1999 E. Rouat
************/
#ifndef HISTORY_H_INCLUDED
#define HISTORY_H_INCLUDED
wordlist * cp_histsubst(wordlist *wlist);
void cp_addhistent(int event, wordlist *wlist);
void cp_hprint(int eventhi, int eventlo, bool rev);
void com_history(wordlist *wl);
#endif

View File

@ -1,38 +0,0 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
**********/
/*
*/
#include "ngspice.h"
#include "cpdefs.h"
#include "modify.h"
char cp_chars[128];
static char *singlec = "<>;&";
/* Initialize stuff. */
void
cp_init(void)
{
char *s, *getenv(const char *);
bzero(cp_chars, 128);
for (s = singlec; *s; s++)
cp_chars[(int) *s] = (CPC_BRR | CPC_BRL);
cp_vset("history", VT_NUM, (char *) &cp_maxhistlength);
cp_curin = stdin;
cp_curout = stdout;
cp_curerr = stderr;
cp_ioreset();
return;
}

View File

@ -11,481 +11,3 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
#include "cpdefs.h"
#include "var2.h"
/* Print the values of currently defined variables. */
extern struct variable *variables;
/* A variable substitution is
* indicated by a $, and the variable name is the following string of
* non-special characters. All variable values are inserted as a single
* word, except for lists, which are a list of words.
* A routine cp_usrset must be supplied by the host program to deal
* with variables that aren't used by cshpar -- it should be
* cp_usrset(var, isset), where var is a variable *, and isset is
* TRUE if the variable is being set, FALSE if unset.
* Also required is a routine cp_enqvar(name) which returns a struct
* variable *, which allows the host program to provide values for
* non-cshpar variables.
*/
char cp_dol = '$';
/* Non-alphanumeric characters that may appear in variable names. < is very
* special...
*/
#define VALIDCHARS "$-_<#?@.()[]&"
wordlist *
cp_variablesubst(wordlist *wlist)
{
wordlist *wl, *nwl;
char *s, *t, buf[BSIZE_SP], wbuf[BSIZE_SP], tbuf[BSIZE_SP];
/* MW. tbuf holds curret word after wl_splice() calls free() on it */
int i;
for (wl = wlist; wl; wl = wl->wl_next) {
t = wl->wl_word;
i = 0;
while ((s =strchr(t, cp_dol))) {
while (t < s)
wbuf[i++] = *t++;
wbuf[i] = '\0';
(void) strcpy(buf, ++s);
s = buf;
t++;
while (*s && (isalphanum(*s) ||
strchr(VALIDCHARS, *s))) {
/* Get s and t past the end of the var name. */
t++;
s++;
}
*s = '\0';
nwl = vareval(buf);
if (i) {
(void) strcpy(buf, wbuf);
if (nwl) {
(void) strcat(buf, nwl->wl_word);
tfree(nwl->wl_word);
} else {
nwl = alloc(struct wordlist);
nwl->wl_next = nwl->wl_prev = NULL;
}
nwl->wl_word = copy(buf);
}
(void) strcpy(tbuf, t); /* MW. Save t*/
if (!(wl = wl_splice(wl, nwl)))
return (NULL);
/* This is bad... */
for (wlist = wl; wlist->wl_prev; wlist = wlist->wl_prev)
;
(void) strcpy(buf, wl->wl_word);
i = strlen(buf);
(void) strcat(buf, tbuf); /* MW. tbuf is used here only */
tfree(wl->wl_word);
wl->wl_word = copy(buf);
t = &wl->wl_word[i];
s = wl->wl_word;
for (i = 0; s < t; s++)
wbuf[i++] = *s;
}
}
return (wlist);
}
/* Evaluate a variable. */
wordlist *
vareval(char *string)
{
struct variable *v;
wordlist *wl;
char buf[BSIZE_SP], *s;
char *oldstring = copy(string);
char *range = NULL;
int i, up, low;
cp_wstrip(string);
if ((s =strchr(string, '['))) {
*s = '\0';
range = s + 1;
}
switch (*string) {
case '$':
wl = alloc(struct wordlist);
wl->wl_next = wl->wl_prev = NULL;
(void) sprintf(buf, "%d", getpid());
wl->wl_word = copy(buf);
return (wl);
case '<':
(void) fflush(cp_out);
if (!fgets(buf, BSIZE_SP, cp_in)) {
clearerr(cp_in);
(void) strcpy(buf, "EOF");
}
for (s = buf; *s && (*s != '\n'); s++)
;
*s = '\0';
wl = cp_lexer(buf);
/* This is a hack. */
if (!wl->wl_word)
wl->wl_word = copy("");
return (wl);
case '?':
wl = alloc(struct wordlist);
wl->wl_next = wl->wl_prev = NULL;
string++;
for (v = variables; v; v = v->va_next)
if (eq(v->va_name, string))
break;
if (!v)
v = cp_enqvar(string);
wl->wl_word = copy(v ? "1" : "0");
return (wl);
case '#':
wl = alloc(struct wordlist);
wl->wl_next = wl->wl_prev = NULL;
string++;
for (v = variables; v; v = v->va_next)
if (eq(v->va_name, string))
break;
if (!v)
v = cp_enqvar(string);
if (!v) {
fprintf(cp_err, "Error: %s: no such variable.\n",
string);
return (NULL);
}
if (v->va_type == VT_LIST)
for (v = v->va_vlist, i = 0; v; v = v->va_next)
i++;
else
i = (v->va_type != VT_BOOL);
(void) sprintf(buf, "%d", i);
wl->wl_word = copy(buf);
return (wl);
case '\0':
wl = alloc(struct wordlist);
wl->wl_next = wl->wl_prev = NULL;
wl->wl_word = copy("$");
return (wl);
}
/* The notation var[stuff] has two meanings... If this is a real
* variable, then the [] denotes range, but if this is a strange
* (e.g, device parameter) variable, it could be anything...
*/
for (v = variables; v; v = v->va_next)
if (eq(v->va_name, string))
break;
if (!v && isdigit(*string)) {
for (v = variables; v; v = v->va_next)
if (eq(v->va_name, "argv"))
break;
range = string;
}
if (!v) {
range = NULL;
string = oldstring;
v = cp_enqvar(string);
}
if (!v && (s = getenv(string))) {
wl = alloc(struct wordlist);
wl->wl_next = wl->wl_prev = NULL;
wl->wl_word = copy(s);
return (wl);
}
if (!v) {
fprintf(cp_err, "Error: %s: no such variable.\n", string);
return (NULL);
}
wl = cp_varwl(v);
/* Now parse and deal with 'range' ... */
if (range) {
for (low = 0; isdigit(*range); range++)
low = low * 10 + *range - '0';
if ((*range == '-') && isdigit(range[1]))
for (up = 0, range++; isdigit(*range); range++)
up = up * 10 + *range - '0';
else if (*range == '-')
up = wl_length(wl);
else
up = low;
up--, low--;
wl = wl_range(wl, low, up);
}
return (wl);
}
static int
vcmp(const void *a, const void *b)
{
int i;
struct xxx *v1 = (struct xxx *) a;
struct xxx *v2 = (struct xxx *) b;
if ((i = strcmp(v1->x_v->va_name, v2->x_v->va_name)))
return (i);
else
return (v1->x_char - v2->x_char);
}
void
cp_vprint(void)
{
struct variable *v;
struct variable *uv1, *uv2;
wordlist *wl;
int i, j;
char *s;
struct xxx *vars;
cp_usrvars(&uv1, &uv2);
for (v = uv1, i = 0; v; v = v->va_next)
i++;
for (v = uv2; v; v = v->va_next)
i++;
for (v = variables; v; v = v->va_next)
i++;
vars = (struct xxx *) tmalloc(sizeof (struct xxx) * i);
out_init();
for (v = variables, i = 0; v; v = v->va_next, i++) {
vars[i].x_v = v;
vars[i].x_char = ' ';
}
for (v = uv1; v; v = v->va_next, i++) {
vars[i].x_v = v;
vars[i].x_char = '*';
}
for (v = uv2; v; v = v->va_next, i++) {
vars[i].x_v = v;
vars[i].x_char = '+';
}
qsort((char *) vars, i, sizeof (struct xxx), vcmp);
for (j = 0; j < i; j++) {
if (j && eq(vars[j].x_v->va_name, vars[j - 1].x_v->va_name))
continue;
v = vars[j].x_v;
if (v->va_type == VT_BOOL) {
/* out_printf("%c %s\n", vars[j].x_char, v->va_name); */
sprintf(out_pbuf, "%c %s\n", vars[j].x_char, v->va_name);
out_send(out_pbuf);
} else {
out_printf("%c %s\t", vars[j].x_char, v->va_name);
wl = vareval(v->va_name);
s = wl_flatten(wl);
if (v->va_type == VT_LIST) {
out_printf("( %s )\n", s);
} else
out_printf("%s\n", s);
}
}
tfree(vars);
return;
}
/* The set command. Syntax is
* set [opt ...] [opt = val ...]. Val may be a string, an int, a float,
* or a list of the form (elt1 elt2 ...).
*/
void
com_set(wordlist *wl)
{
struct variable *vars;
char *s;
if (wl == NULL) {
cp_vprint();
return;
}
vars = cp_setparse(wl);
/* This is sort of a hassle... */
while (vars) {
switch (vars->va_type) {
case VT_BOOL:
s = (char *) &vars->va_bool;
break;
case VT_NUM:
s = (char *) &vars->va_num;
break;
case VT_REAL:
s = (char *) &vars->va_real;
break;
case VT_STRING:
s = vars->va_string;
break;
case VT_LIST:
s = (char *) vars->va_vlist;
break;
default:
s = (char *) NULL;
}
cp_vset(vars->va_name, vars->va_type, s);
vars = vars->va_next;
}
return;
}
void
com_unset(wordlist *wl)
{
register char *name;
struct variable *var, *nv;
if (eq(wl->wl_word, "*")) {
for (var = variables; var; var = nv) {
nv = var->va_next;
cp_remvar(var->va_name);
}
wl = wl->wl_next;
}
while (wl != NULL) {
name = wl->wl_word;
cp_remvar(name);
wl = wl->wl_next;
}
return;
}
/* Shift a list variable, by default argv, one to the left (or more if a
* second argument is given.
*/
void
com_shift(wordlist *wl)
{
struct variable *v, *vv;
char *n = "argv";
int num = 1;
if (wl) {
n = wl->wl_word;
wl = wl->wl_next;
}
if (wl)
num = scannum(wl->wl_word);
for (v = variables; v; v = v->va_next)
if (eq(v->va_name, n))
break;
if (!v) {
fprintf(cp_err, "Error: %s: no such variable\n", n);
return;
}
if (v->va_type != VT_LIST) {
fprintf(cp_err, "Error: %s not of type list\n", n);
return;
}
for (vv = v->va_vlist; vv && (num > 0); num--)
vv = vv->va_next;
if (num) {
fprintf(cp_err, "Error: variable %s not long enough\n", n);
return;
}
v->va_vlist = vv;
return;
}
/* Determine the value of a variable. Fail if the variable is unset,
* and if the type doesn't match, try and make it work...
*/
bool
cp_getvar(char *name, int type, char *retval)
{
struct variable *v;
for (v = variables; v; v = v->va_next)
if (eq(name, v->va_name))
break;
if (v == NULL) {
if (type == VT_BOOL)
* (bool *) retval = FALSE;
return (FALSE);
}
if (v->va_type == type) {
switch (type) {
case VT_BOOL:
* (bool *) retval = TRUE;
break;
case VT_NUM: {
int *i;
i = (int *) retval;
*i = v->va_num;
break;
}
case VT_REAL: {
double *d;
d = (double *) retval;
*d = v->va_real;
break;
}
case VT_STRING: { /* Gotta be careful to have room. */
char *s;
s = cp_unquote(v->va_string);
cp_wstrip(s);
(void) strcpy(retval, s);
break;
}
case VT_LIST: { /* Funny case... */
struct variable **tv;
tv = (struct variable **) retval;
*tv = v->va_vlist;
break;
}
default:
fprintf(cp_err,
"cp_getvar: Internal Error: bad var type %d.\n",
type);
break;
}
return (TRUE);
} else {
/* Try to coerce it.. */
if ((type == VT_NUM) && (v->va_type == VT_REAL)) {
int *i;
i = (int *) retval;
*i = (int) v->va_real;
return (TRUE);
} else if ((type == VT_REAL) && (v->va_type == VT_NUM)) {
double *d;
d = (double *) retval;
*d = (double) v->va_num;
return (TRUE);
} else if ((type == VT_STRING) && (v->va_type == VT_NUM)) {
(void) sprintf(retval, "%d", v->va_num);
return (TRUE);
} else if ((type == VT_STRING) && (v->va_type == VT_REAL)) {
(void) sprintf(retval, "%f", v->va_real);
return (TRUE);
}
return (FALSE);
}
}

View File

@ -7,11 +7,6 @@
#define VAR2_H_INCLUDED
struct xxx {
struct variable *x_v;
char x_char;
} ;
wordlist * cp_variablesubst(wordlist *wlist);
wordlist * vareval(char *string);
void cp_vprint(void);

View File

@ -1,429 +0,0 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
**********/
#include "ngspice.h"
#include "cpdefs.h"
#include "fteext.h"
#include "ftedefs.h"
#include "variable.h"
bool cp_noglob = TRUE;
bool cp_nonomatch = FALSE;
bool cp_noclobber = FALSE;
bool cp_ignoreeof = FALSE;
struct variable *variables = NULL;
wordlist *
cp_varwl(struct variable *var)
{
wordlist *wl = NULL, *w, *wx = NULL;
char buf[BSIZE_SP];
struct variable *vt;
switch(var->va_type) {
case VT_BOOL:
/* Can't ever be FALSE. */
(void) sprintf(buf, "%s", var->va_bool ? "TRUE" :
"FALSE");
break;
case VT_NUM:
(void) sprintf(buf, "%d", var->va_num);
break;
case VT_REAL:
/* This is a case where printnum isn't too good... */
(void) sprintf(buf, "%G", var->va_real);
break;
case VT_STRING:
(void) strcpy(buf, cp_unquote(var->va_string));
break;
case VT_LIST: /* The tricky case. */
for (vt = var->va_vlist; vt; vt = vt->va_next) {
w = cp_varwl(vt);
if (wl == NULL)
wl = wx = w;
else {
wx->wl_next = w;
w->wl_prev = wx;
wx = w;
}
}
return (wl);
default:
fprintf(cp_err,
"cp_varwl: Internal Error: bad variable type %d\n",
var->va_type);
return (NULL);
}
wl = alloc(struct wordlist);
wl->wl_next = wl->wl_prev = NULL;
wl->wl_word = copy(buf);
return (wl);
}
/* Set a variable. */
void
cp_vset(char *varname, char type, char *value)
{
struct variable *v, *u, *w;
int i;
bool alreadythere = FALSE;
/* for (v = variables; v; v = v->va_next) ; printf("ok while setting %s\n",
varname);*/
varname = cp_unquote(varname);
w = NULL;
for (v = variables; v; v = v->va_next) {
if (eq(varname, v->va_name)) {
alreadythere = TRUE;
break;
}
w = v;
}
if (!v) {
v = alloc(struct variable);
v->va_name = copy(varname);
v->va_next = NULL;
}
switch (type) {
case VT_BOOL:
if (* ((bool *) value) == FALSE) {
cp_remvar(varname);
return;
} else
v->va_bool = TRUE;
break;
case VT_NUM:
v->va_num = * (int *) value;
break;
case VT_REAL:
v->va_real = * (double *) value;
break;
case VT_STRING:
v->va_string = copy(value);
break;
case VT_LIST:
v->va_vlist = (struct variable *) value;
break;
default:
fprintf(cp_err,
"cp_vset: Internal Error: bad variable type %d.\n",
type);
return;
}
v->va_type = type;
/* Now, see if there is anything interesting going on. We recognise
* these special variables: noglob, nonomatch, history, echo,
* noclobber, prompt, and verbose. cp_remvar looks for these variables
* too. The host program will get any others.
*/
if (eq(varname, "noglob"))
cp_noglob = TRUE;
else if (eq(varname, "nonomatch"))
cp_nonomatch = TRUE;
else if (eq(varname, "history") && (type == VT_NUM))
cp_maxhistlength = v->va_num;
else if (eq(varname, "history") && (type == VT_REAL))
cp_maxhistlength = v->va_real;
else if (eq(varname, "noclobber"))
cp_noclobber = TRUE;
else if (eq(varname, "prompt") && (type == VT_STRING))
cp_promptstring = copy(v->va_string);
else if (eq(varname, "ignoreeof"))
cp_ignoreeof = TRUE;
else if (eq(varname, "cpdebug")) {
cp_debug = TRUE;
#ifndef CPDEBUG
fprintf(cp_err,
"Warning: program not compiled with cshpar debug messages\n");
#endif
}
switch (i = cp_usrset(v, TRUE)) {
case US_OK:
/* Normal case. */
if (!alreadythere) {
v->va_next = variables;
variables = v;
}
break;
case US_DONTRECORD:
/* Do nothing... */
if (alreadythere) {
fprintf(cp_err,
"cp_vset: Internal Error: %s already there, but 'dont record'\n",
v->va_name);
}
break;
case US_READONLY:
fprintf(cp_err, "Error: %s is a read-only variable.\n",
v->va_name);
if (alreadythere)
fprintf(cp_err,
"cp_vset: Internal Error: it was already there too!!\n");
break;
case US_SIMVAR:
if (alreadythere) {
/* somehow it got into the front-end list of variables */
if (w) {
w->va_next = v->va_next;
} else {
variables = v->va_next;
}
}
alreadythere = FALSE;
if (ft_curckt) {
for (u = ft_curckt->ci_vars; u; u = u->va_next)
if (eq(varname, u->va_name)) {
alreadythere = TRUE;
break;
}
if (!alreadythere) {
v->va_next = ft_curckt->ci_vars;
ft_curckt->ci_vars = v;
} else {
w = u->va_next;
bcopy(v, u, sizeof(*u));
u->va_next = w;
}
}
break;
case US_NOSIMVAR:
/* What do you do? */
tfree(v);
break;
default:
fprintf(cp_err, "cp_vset: Internal Error: bad US val %d\n", i);
break;
}
return;
}
struct variable *
cp_setparse(wordlist *wl)
{
char *name, *val, *s, *ss;
double *td;
struct variable *listv = NULL, *vv, *lv = NULL;
struct variable *vars = NULL;
int balance;
while (wl) {
name = cp_unquote(wl->wl_word);
wl = wl->wl_next;
if (((wl == NULL) || (*wl->wl_word != '=')) &&
strchr(name, '=') == NULL) {
vv = alloc(struct variable);
vv->va_name = copy(name);
vv->va_type = VT_BOOL;
vv->va_bool = TRUE;
vv->va_next = vars;
vars = vv;
continue;
}
if (wl && eq(wl->wl_word, "=")) {
wl = wl->wl_next;
if (wl == NULL) {
fprintf(cp_err, "Error: bad set form.\n");
return (NULL);
}
val = wl->wl_word;
wl = wl->wl_next;
} else if (wl && (*wl->wl_word == '=')) {
val = wl->wl_word + 1;
wl = wl->wl_next;
} else if ((s =strchr(name, '='))) {
val = s + 1;
*s = '\0';
if (*val == '\0') {
if (!wl) {
fprintf(cp_err,
"Error: %s equals what?.\n",
name);
return (NULL);
} else {
val = wl->wl_word;
wl = wl->wl_next;
}
}
} else {
fprintf(cp_err, "Error: bad set form.\n");
return (NULL);
}
val = cp_unquote(val);
if (eq(val, "(")) { /* ) */
/* The beginning of a list... We have to walk down
* the list until we find a close paren... If there
* are nested ()'s, treat them as tokens...
*/
balance = 1;
while (wl && wl->wl_word) {
if (eq(wl->wl_word, "(")) { /* ) ( */
balance++;
} else if (eq(wl->wl_word, ")")) {
if (!--balance)
break;
}
vv = alloc(struct variable);
vv->va_next = NULL;
ss = cp_unquote(wl->wl_word);
td = ft_numparse(&ss, FALSE);
if (td) {
vv->va_type = VT_REAL;
vv->va_real = *td;
} else {
vv->va_type = VT_STRING;
vv->va_string = copy(ss);
}
if (listv) {
lv->va_next = vv;
lv = vv;
} else
listv = lv = vv;
wl = wl->wl_next;
}
if (balance && !wl) {
fprintf(cp_err, "Error: bad set form.\n");
return (NULL);
}
vv = alloc(struct variable);
vv->va_name = copy(name);
vv->va_type = VT_LIST;
vv->va_vlist = listv;
vv->va_next = vars;
vars = vv;
wl = wl->wl_next;
continue;
}
ss = cp_unquote(val);
td = ft_numparse(&ss, FALSE);
vv = alloc(struct variable);
vv->va_name = copy(name);
vv->va_next = vars;
vars = vv;
if (td) {
/*** We should try to get VT_NUM's... */
vv->va_type = VT_REAL;
vv->va_real = *td;
} else {
vv->va_type = VT_STRING;
vv->va_string = copy(val);
}
}
return (vars);
}
void
cp_remvar(char *varname)
{
struct variable *v, *u, *lv = NULL;
bool found = TRUE;
int i;
for (v = variables; v; v = v->va_next) {
if (eq(v->va_name, varname))
break;
lv = v;
}
if (!v) {
/* Gotta make up a var struct for cp_usrset()... */
v = alloc(struct variable);
ZERO(v, struct variable);
v->va_name = varname;
v->va_type = VT_NUM;
v->va_bool = 0;
found = FALSE;
}
/* Note that 'unset history' doesn't do anything here... Causes
* trouble...
*/
if (eq(varname, "noglob"))
cp_noglob = FALSE;
else if (eq(varname, "nonomatch"))
cp_nonomatch = FALSE;
else if (eq(varname, "noclobber"))
cp_noclobber = FALSE;
else if (eq(varname, "prompt"))
cp_promptstring = "";
else if (eq(varname, "cpdebug"))
cp_debug = FALSE;
else if (eq(varname, "ignoreeof"))
cp_ignoreeof = FALSE;
switch (i = cp_usrset(v, FALSE)) {
case US_OK:
/* Normal case. */
if (found) {
if (lv)
lv->va_next = v->va_next;
else
variables = v->va_next;
}
break;
case US_DONTRECORD:
/* Do nothing... */
if (found)
fprintf(cp_err,
"cp_remvar: Internal Error: var %d\n", *varname);
break;
case US_READONLY:
/* Badness... */
fprintf(cp_err, "Error: %s is read-only.\n",
v->va_name);
if (found)
fprintf(cp_err,
"cp_remvar: Internal Error: var %d\n", *varname);
break;
case US_SIMVAR:
lv = NULL;
if (ft_curckt) {
for (u = ft_curckt->ci_vars; u; u = u->va_next) {
if (eq(varname, u->va_name)) {
break;
}
lv = u;
}
if (u) {
if (lv)
lv->va_next = u->va_next;
else
ft_curckt->ci_vars = u->va_next;
tfree(u);
}
}
break;
default:
fprintf(cp_err, "cp_remvar: Internal Error: US val %d\n", i);
break;
}
tfree(v);
return;
}