diff --git a/ChangeLog b/ChangeLog index 7e168049b..046500368 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2000-06-27 Arno W. Peters + + * 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 * src/analysis/cktask.c: moved to src/devices. diff --git a/src/Makefile.am b/src/Makefile.am index 05b82f754..53ab54b13 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -99,6 +99,7 @@ help_SOURCES = help.c help_LDADD = \ hlp/libhlp.a \ parser/libparser.a \ + frontend/libfte.a \ misc/libmisc.a diff --git a/src/circuit/Makefile.am b/src/circuit/Makefile.am index 61da8e94f..c389dc7c7 100644 --- a/src/circuit/Makefile.am +++ b/src/circuit/Makefile.am @@ -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 diff --git a/src/circuit/ifnewuid.c b/src/circuit/ifnewuid.c index 08465f21e..da9000dc7 100644 --- a/src/circuit/ifnewuid.c +++ b/src/circuit/ifnewuid.c @@ -5,10 +5,15 @@ Author: 1988 Thomas L. Quarles #include "ngspice.h" #include -#include "inpdefs.h" + +#include +#include +#include +#include +#include + #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) { diff --git a/src/frontend/Makefile.am b/src/frontend/Makefile.am index ab64c5f3e..73af9aa2e 100644 --- a/src/frontend/Makefile.am +++ b/src/frontend/Makefile.am @@ -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 \ diff --git a/src/frontend/aspice.c b/src/frontend/aspice.c index 29e8c56e1..af3b1039d 100644 --- a/src/frontend/aspice.c +++ b/src/frontend/aspice.c @@ -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 */ diff --git a/src/frontend/circuits.h b/src/frontend/circuits.h index 9fad52a8d..d83d57830 100644 --- a/src/frontend/circuits.h +++ b/src/frontend/circuits.h @@ -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); diff --git a/src/frontend/com_display.c b/src/frontend/com_display.c index 1435f44db..0c81b5054 100644 --- a/src/frontend/com_display.c +++ b/src/frontend/com_display.c @@ -1,10 +1,11 @@ #include #include -#include +#include #include #include #include "com_display.h" +#include "variable.h" #include "plotting/plotting.h" #include "plotting/pvec.h" diff --git a/src/frontend/com_hardcopy.c b/src/frontend/com_hardcopy.c index 0dce53c85..71a2649c2 100644 --- a/src/frontend/com_hardcopy.c +++ b/src/frontend/com_hardcopy.c @@ -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 diff --git a/src/frontend/commands.c b/src/frontend/commands.c index b91332646..1f8647509 100644 --- a/src/frontend/commands.c +++ b/src/frontend/commands.c @@ -32,10 +32,22 @@ #include #include -#include +#include +#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, diff --git a/src/frontend/commands.h b/src/frontend/commands.h index bfbd5a89f..a26246336 100644 --- a/src/frontend/commands.h +++ b/src/frontend/commands.h @@ -1,9 +1,6 @@ #ifndef _COMMANDS_H #define _COMMANDS_H -#include - - extern struct comm spcp_coms[]; extern struct comm nutcp_coms[]; diff --git a/src/frontend/cpitf.c b/src/frontend/cpitf.c index 6bd878496..72a267539 100644 --- a/src/frontend/cpitf.c +++ b/src/frontend/cpitf.c @@ -13,6 +13,7 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group #include #include "completion.h" +#include "variable.h" /* Set some standard variables and aliases, etc, and init the ccom stuff. */ diff --git a/src/frontend/debugcom.c b/src/frontend/debugcom.c index 36846e594..07f045ee0 100644 --- a/src/frontend/debugcom.c +++ b/src/frontend/debugcom.c @@ -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" diff --git a/src/frontend/device.c b/src/frontend/device.c index 86131d5df..736cb59f8 100644 --- a/src/frontend/device.c +++ b/src/frontend/device.c @@ -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); diff --git a/src/frontend/diff.c b/src/frontend/diff.c index 3f5309978..6a50d1d88 100644 --- a/src/frontend/diff.c +++ b/src/frontend/diff.c @@ -13,6 +13,7 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group #include #include "diff.h" +#include "variable.h" /* Determine if two vectors have the 'same' name. */ diff --git a/src/frontend/display.c b/src/frontend/display.c index f2451b378..f627087e1 100644 --- a/src/frontend/display.c +++ b/src/frontend/display.c @@ -11,7 +11,7 @@ Copyright 1990 Regents of the University of California. All rights reserved. #include /* for mylog() */ #include "display.h" - +#include "variable.h" /* static declarations */ static void gen_DatatoScreen(GRAPH *graph, double x, double y, int *screenx, int *screeny); diff --git a/src/frontend/dotcards.c b/src/frontend/dotcards.c index a2e4f59f9..e28857f6d 100644 --- a/src/frontend/dotcards.c +++ b/src/frontend/dotcards.c @@ -14,7 +14,9 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group #include "fteinp.h" #include +#include "circuits.h" #include "dotcards.h" +#include "variable.h" /* Extract all the .save lines */ diff --git a/src/frontend/fourier.c b/src/frontend/fourier.c index c1fe674f1..8148ef3f9 100644 --- a/src/frontend/fourier.c +++ b/src/frontend/fourier.c @@ -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 */ diff --git a/src/frontend/inp.c b/src/frontend/inp.c index e1e34811f..461886914 100644 --- a/src/frontend/inp.c +++ b/src/frontend/inp.c @@ -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); diff --git a/src/frontend/inpcom.c b/src/frontend/inpcom.c index b9c61fba2..fc2112c1d 100644 --- a/src/frontend/inpcom.c +++ b/src/frontend/inpcom.c @@ -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' diff --git a/src/frontend/linear.c b/src/frontend/linear.c index d9e54a781..302230bcb 100644 --- a/src/frontend/linear.c +++ b/src/frontend/linear.c @@ -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" diff --git a/src/frontend/misccoms.c b/src/frontend/misccoms.c index cf2e110a1..b0d338b93 100644 --- a/src/frontend/misccoms.c +++ b/src/frontend/misccoms.c @@ -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) diff --git a/src/frontend/mw_coms.c b/src/frontend/mw_coms.c index 217ce1b30..f7bdae5f2 100644 --- a/src/frontend/mw_coms.c +++ b/src/frontend/mw_coms.c @@ -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; diff --git a/src/frontend/nutinp.c b/src/frontend/nutinp.c index fe83755b8..dbdd8ad77 100644 --- a/src/frontend/nutinp.c +++ b/src/frontend/nutinp.c @@ -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 diff --git a/src/frontend/options.c b/src/frontend/options.c index b918dbbe8..78022de0c 100644 --- a/src/frontend/options.c +++ b/src/frontend/options.c @@ -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 */ diff --git a/src/frontend/outitf.c b/src/frontend/outitf.c index 247f61ff3..025599da8 100644 --- a/src/frontend/outitf.c +++ b/src/frontend/outitf.c @@ -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); diff --git a/src/frontend/parse.c b/src/frontend/parse.c index 3080ea30f..d9c9f7e4a 100644 --- a/src/frontend/parse.c +++ b/src/frontend/parse.c @@ -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 } } ; diff --git a/src/frontend/plotting/Makefile.am b/src/frontend/plotting/Makefile.am index 184d02c8f..ec152081e 100644 --- a/src/frontend/plotting/Makefile.am +++ b/src/frontend/plotting/Makefile.am @@ -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 diff --git a/src/frontend/plotting/agraf.c b/src/frontend/plotting/agraf.c index f6532dd1f..f0059054b 100644 --- a/src/frontend/plotting/agraf.c +++ b/src/frontend/plotting/agraf.c @@ -14,6 +14,8 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group #include "fteparse.h" #include "agraf.h" +#include + #define FUDGE 7 #define MARGIN_BASE 11 #define LCHAR '.' diff --git a/src/frontend/plotting/graf.c b/src/frontend/plotting/graf.c index c20f408a4..9a648f049 100644 --- a/src/frontend/plotting/graf.c +++ b/src/frontend/plotting/graf.c @@ -22,6 +22,7 @@ Author: 1988 Jeffrey M. Hsu #include "ftedbgra.h" #include "ftedev.h" #include +#include #include "graf.h" diff --git a/src/frontend/plotting/plotcurv.c b/src/frontend/plotting/plotcurv.c index b02e9272e..c50b2a5a2 100644 --- a/src/frontend/plotting/plotcurv.c +++ b/src/frontend/plotting/plotcurv.c @@ -13,6 +13,7 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group #include #include #include +#include #include "plotcurv.h" diff --git a/src/frontend/plotting/plotit.c b/src/frontend/plotting/plotit.c index a0171d7a8..d1ca6df48 100644 --- a/src/frontend/plotting/plotit.c +++ b/src/frontend/plotting/plotit.c @@ -7,6 +7,9 @@ #include #include +#include +#include + #include "plotit.h" #include "agraf.h" #include "xgraph.h" diff --git a/src/frontend/plotting/x11.c b/src/frontend/plotting/x11.c index 86e5be0f5..f2e115789 100644 --- a/src/frontend/plotting/x11.c +++ b/src/frontend/plotting/x11.c @@ -22,6 +22,7 @@ Author: 1988 Jeffrey M. Hsu # include # include # include +# include /* Added X11/ prefix to the next includes - ER */ diff --git a/src/frontend/plotting/xgraph.c b/src/frontend/plotting/xgraph.c index c24076718..761c0a165 100644 --- a/src/frontend/plotting/xgraph.c +++ b/src/frontend/plotting/xgraph.c @@ -14,6 +14,7 @@ Author: 1992 David A. Gates, U. C. Berkeley CAD Group #include "fteparse.h" #include "xgraph.h" +#include #define XG_MAXVECTORS 64 diff --git a/src/frontend/postcoms.c b/src/frontend/postcoms.c index bfdc35b55..fc4f9768f 100644 --- a/src/frontend/postcoms.c +++ b/src/frontend/postcoms.c @@ -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); diff --git a/src/frontend/postsc.c b/src/frontend/postsc.c index 481491e40..d736b71bc 100644 --- a/src/frontend/postsc.c +++ b/src/frontend/postsc.c @@ -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)) diff --git a/src/frontend/rawfile.c b/src/frontend/rawfile.c index e6ccac13f..f1aa44388 100644 --- a/src/frontend/rawfile.c +++ b/src/frontend/rawfile.c @@ -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); diff --git a/src/frontend/resource.c b/src/frontend/resource.c index 0bd9d84e8..cbf3bd6b7 100644 --- a/src/frontend/resource.c +++ b/src/frontend/resource.c @@ -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); diff --git a/src/frontend/runcoms.c b/src/frontend/runcoms.c index 5c4d0976d..5a9d93a9a 100644 --- a/src/frontend/runcoms.c +++ b/src/frontend/runcoms.c @@ -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); diff --git a/src/frontend/runcoms2.c b/src/frontend/runcoms2.c index f3c2e159d..ea5094844 100644 --- a/src/frontend/runcoms2.c +++ b/src/frontend/runcoms2.c @@ -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; diff --git a/src/frontend/shyu.c b/src/frontend/shyu.c index f3a6d6a99..c1a7a8c1d 100644 --- a/src/frontend/shyu.c +++ b/src/frontend/shyu.c @@ -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" diff --git a/src/frontend/spec.c b/src/frontend/spec.c index c2b022a39..f479af8b9 100644 --- a/src/frontend/spec.c +++ b/src/frontend/spec.c @@ -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) diff --git a/src/frontend/spiceif.c b/src/frontend/spiceif.c index b24c2f2d2..54dfeef31 100644 --- a/src/frontend/spiceif.c +++ b/src/frontend/spiceif.c @@ -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); diff --git a/src/frontend/subckt.c b/src/frontend/subckt.c index dbc26a588..3758011ff 100644 --- a/src/frontend/subckt.c +++ b/src/frontend/subckt.c @@ -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); diff --git a/src/frontend/vectors.c b/src/frontend/vectors.c index 91ea4b033..93661df1d 100644 --- a/src/frontend/vectors.c +++ b/src/frontend/vectors.c @@ -13,8 +13,10 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group #include #include -#include "vectors.h" +#include "circuits.h" #include "completion.h" +#include "variable.h" +#include "vectors.h" #include "plotting/plotting.h" diff --git a/src/frontend/where.c b/src/frontend/where.c index cf66568ad..c8e3c4f99 100644 --- a/src/frontend/where.c +++ b/src/frontend/where.c @@ -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) diff --git a/src/help.c b/src/help.c index 12ac354eb..0e9a1d3fe 100644 --- a/src/help.c +++ b/src/help.c @@ -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; diff --git a/src/include/Makefile.am b/src/include/Makefile.am index bd92ff670..4b3f6460e 100644 --- a/src/include/Makefile.am +++ b/src/include/Makefile.am @@ -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 diff --git a/src/include/cpdefs.h b/src/include/cpdefs.h index a9be20520..2da52d533 100644 --- a/src/include/cpdefs.h +++ b/src/include/cpdefs.h @@ -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(). */ diff --git a/src/include/cpextern.h b/src/include/cpextern.h index 70377ba47..10746a330 100644 --- a/src/include/cpextern.h +++ b/src/include/cpextern.h @@ -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 */ diff --git a/src/include/ftedefs.h b/src/include/ftedefs.h index accd88509..c70c27133 100644 --- a/src/include/ftedefs.h +++ b/src/include/ftedefs.h @@ -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; diff --git a/src/include/ftehelp.h b/src/include/ftehelp.h deleted file mode 100644 index de368fe80..000000000 --- a/src/include/ftehelp.h +++ /dev/null @@ -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 diff --git a/src/include/plot.h b/src/include/plot.h index aa388a74e..b718fa14a 100644 --- a/src/include/plot.h +++ b/src/include/plot.h @@ -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. */ diff --git a/src/include/variable.h b/src/include/variable.h deleted file mode 100644 index 0e5a47d36..000000000 --- a/src/include/variable.h +++ /dev/null @@ -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 diff --git a/src/main.c b/src/main.c index 4da189c3e..d516c751d 100644 --- a/src/main.c +++ b/src/main.c @@ -22,6 +22,7 @@ #include #include #include +#include #ifdef HAVE_PWD_H #include diff --git a/src/maths/cmaths/cmath4.c b/src/maths/cmaths/cmath4.c index 90b84c239..014138247 100644 --- a/src/maths/cmaths/cmath4.c +++ b/src/maths/cmaths/cmath4.c @@ -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 diff --git a/src/misc/terminal.c b/src/misc/terminal.c index 4ccb7a56e..e69de29bb 100644 --- a/src/misc/terminal.c +++ b/src/misc/terminal.c @@ -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 - -#ifdef HAVE_SGTTY_H -#include -#endif - -#if 0 -/* Bad interaction with bool type in bool.h because curses also - defines this symbol. */ -#ifdef HAVE_TERMCAP -#include -#include -#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 : Print another screenful\n\ -\tq : Discard the rest of the output\n\ -\tc : Continuously print the rest of the output\n\ -\t? : 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 -} diff --git a/src/misc/terminal.h b/src/misc/terminal.h index a3890750c..e69de29bb 100644 --- a/src/misc/terminal.h +++ b/src/misc/terminal.h @@ -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 diff --git a/src/parser/cshpar.c b/src/parser/cshpar.c index 74eb68dee..578e9dcd2 100644 --- a/src/parser/cshpar.c +++ b/src/parser/cshpar.c @@ -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; -} - diff --git a/src/parser/front.c b/src/parser/front.c index efaea65ba..e69de29bb 100644 --- a/src/parser/front.c +++ b/src/parser/front.c @@ -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; -} - diff --git a/src/parser/front.h b/src/parser/front.h index b261bf57d..e69de29bb 100644 --- a/src/parser/front.h +++ b/src/parser/front.h @@ -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 diff --git a/src/parser/history.c b/src/parser/history.c index 3fd80a272..e69de29bb 100644 --- a/src/parser/history.c +++ b/src/parser/history.c @@ -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; -} - diff --git a/src/parser/history.h b/src/parser/history.h index a98a3ab25..e69de29bb 100644 --- a/src/parser/history.h +++ b/src/parser/history.h @@ -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 diff --git a/src/parser/modify.c b/src/parser/modify.c index c76bea376..e69de29bb 100644 --- a/src/parser/modify.c +++ b/src/parser/modify.c @@ -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; -} - diff --git a/src/parser/var2.c b/src/parser/var2.c index 4ca3c7add..03df7a93f 100644 --- a/src/parser/var2.c +++ b/src/parser/var2.c @@ -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); - } -} - diff --git a/src/parser/var2.h b/src/parser/var2.h index a553639ce..5b0613cbd 100644 --- a/src/parser/var2.h +++ b/src/parser/var2.h @@ -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); diff --git a/src/parser/variable.c b/src/parser/variable.c index f1d3bffa4..e69de29bb 100644 --- a/src/parser/variable.c +++ b/src/parser/variable.c @@ -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; -}