summaryrefslogtreecommitdiff
path: root/usr.sbin/sup/lib/ci.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr.sbin/sup/lib/ci.c')
-rw-r--r--usr.sbin/sup/lib/ci.c847
1 files changed, 847 insertions, 0 deletions
diff --git a/usr.sbin/sup/lib/ci.c b/usr.sbin/sup/lib/ci.c
new file mode 100644
index 000000000000..8960eb50ceed
--- /dev/null
+++ b/usr.sbin/sup/lib/ci.c
@@ -0,0 +1,847 @@
+/*
+ * Copyright (c) 1991 Carnegie Mellon University
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the rights
+ * to redistribute these changes.
+ */
+/* ci -- command interpreter
+ *
+ * Usage (etc.)
+ *
+ * HISTORY
+ * 22-Nov-85 Glenn Marcy (gm0w) at Carnegie-Mellon University
+ * Removed checks for VIRTUE window manager. If they don't like
+ * it then they can fix the more program.
+ *
+ * 08-May-85 Steven Shafer (sas) at Carnegie-Mellon University
+ * Increased MAXENTRIES and MAXHELPS from 200 to 400.
+ *
+ * 30-Apr-85 Steven Shafer (sas) at Carnegie-Mellon University
+ * Adapted for 4.2 UNIX. Added calls to check for
+ * using window manager of VIRTUE.
+ *
+ * 29-Apr-85 Steven Shafer (sas) at Carnegie-Mellon University
+ * Added two small bug fixes (courtesy of Richard Cohn).
+ *
+ * 14-Aug-84 Steven Shafer (sas) at Carnegie-Mellon University
+ * Added fflush(stdout) after printing prompt, before asking for input line.
+ *
+ * 01-Jul-83 Steven Shafer (sas) at Carnegie-Mellon University
+ * Bug fix: whitespace now required before ">filename" and not permitted
+ * within or after filename.
+ *
+ * 06-Jun-83 Steven Shafer (sas) at Carnegie-Mellon University
+ * Bug fix: added line to initialize "redirected" to 0.
+ *
+ * 20-May-83 Steven Shafer (sas) at Carnegie-Mellon University
+ * Added quiet bits CINOSEM, CINOFILE, CIFIRSTEQUAL to allow user to
+ * have special characters ; > = treated as normal data (except =
+ * after first argument, which still means "variable assignment").
+ * Also added output redirection via >filename on input line.
+ *
+ * 07-Mar-83 Dave McKeown (dmm) at Carnegie-Mellon University
+ * (Slight alterations by Steve Shafer.)
+ * Made cidepth a global, used for recursive and nested calls to
+ * ci(), and accessable to the user. Added '@x' command, similar
+ * to '^x' except that the previous command interpreter name is
+ * remembered and after 'x' is executed, the previous command
+ * interpreter is reinvoked. Users who plan to use this feature
+ * must save the name of the previous ci in global variable
+ * 'ciprev' after exit from the ci(). ie.
+ * ci(.........);
+ * strcpy(ciprev,"ci-name");
+ * Added ci state CICMDNOINDENT to allow for no indentation of the
+ * command line prompt based on cidepth.
+ * Reduced amount of indentation on source code.
+ * Bug: the "depth" argument is now a no-op, retained for backward
+ * compatibility. Cidepth is initialized to zero, and incremented
+ * upon invocation of a ci(). If cidepth is <1 then you are not
+ * in a ci() instantiation.
+ *
+ * 21-Feb-83 Steven Shafer (sas) at Carnegie-Mellon University
+ * Added up-arrow (^) command (and variable cinext). ^x is used when
+ * you have a ci program in which one command invokes ci with a
+ * new set of commands (i.e. a subsystem of the program). Inside the
+ * subsystem, ^x will exit the subsystem, and cause the main level
+ * to execute the command line "x" before reading more input lines.
+ * The cinext variable is used to implement this. Cinext can also be
+ * used by any user code which desires to force ci to execute a
+ * specific command before reading more input from the current file.
+ *
+ * 16-Jul-82 Steven Shafer (sas) at Carnegie-Mellon University
+ * Added extra code in _ci_help to eliminate duplicate help file
+ * names. This way, if several directories are specified and there
+ * is are files with the same name in more than one directory, only
+ * the first of each file will be included in the help list.
+ *
+ * It would have been nice to do this after the qsort instead of
+ * before (in ci_help). However, qsort does not ensure that
+ * "equivalent" entries are kept in the same relative
+ * order; thus there would be no way to ensure that the
+ * file being used was the first such file found.
+ *
+ * 07-Jul-82 William Chiles (wpc) at Carnegie-Mellon University
+ * Modified so that "!" invokes shell commands from the type of
+ * shell specified by the environment variable SHELL. If SHELL
+ * is not defined the standard shell is used.
+ *
+ * 21-Sep-81 Steven Shafer (sas) at Carnegie-Mellon University
+ * Increased LINELENGTH (input buffer length) to 1100 to satisfy
+ * voracious requirements of a certain user whose name I won't mention
+ * but whose initials are "faa".
+ *
+ * 08-Oct-80 Steven Shafer (sas) at Carnegie-Mellon University
+ * Added class variables: ci_tclass cases in ci_show and ci_set.
+ * Also added CICMDFPEEK in addition to existing CISETPEEK.
+ *
+ * 22-May-80 Steven Shafer (sas) at Carnegie-Mellon University
+ * Ci now sorts help topics into alphabetical order. Some interrupt
+ * handling has been added, but there are bugs, for example, when
+ * you interrupt "*" (the listing of command names). The right thing
+ * happens, but bogus messages are printed.
+ *
+ * 16-Apr-80 Steven Shafer (sas) at Carnegie-Mellon University
+ * Ci now prints lists of names with prstab(). This uses multiple
+ * columns when appropriate.
+ *
+ * 12-Mar-80 Steven Shafer (sas) at Carnegie-Mellon University
+ * Added code to skip over leading blanks and tabs in the argument list
+ * when executing commands, and setting and displaying variables.
+ * Also fixed meta-help, which mysteriously disappeared.
+ *
+ * 19-Feb-80 Steven Shafer (sas) at Carnegie-Mellon University
+ * Added "if (0) del();" to force del() routine to be loaded. This is
+ * the safest way I know of to define the external int "_del_". If you
+ * don't believe it, think again about separately compiled files.
+ *
+ * 28-Jan-80 Steven Shafer (sas) at Carnegie-Mellon University
+ * Created. Patterned (somewhat) after ci() on PDP-11.
+ *
+ */
+
+
+#include <strings.h>
+#include <libc.h>
+#include <ci.h>
+#include <del.h>
+
+char *index(),*getenv(),*rindex();
+extern char _argbreak;
+long atol();
+double atof();
+static int ci_help(), ci_show();
+static int _ci_sho(), _ci_set(), ci_set();
+
+/*************************
+ *** M A C R O S ***
+ *************************/
+
+#define LINELENGTH 1100 /* max length of input line */
+#define MAXENTRIES 400 /* max entries in entry list */
+#define MAXHELPS 400 /* max help files available */
+#define METAHELP "/usr/lib/ci.help" /* standard help file */
+
+/*********************************************
+ *** G L O B A L V A R I A B L E S ***
+ *********************************************/
+
+int ciquiet = 0; /* init globals */
+int ciexit = 0;
+int cidepth = 0;
+int ciback = 0; /* for use in '@' command */
+FILE *ciinput;
+
+char cinext[LINELENGTH] = "";
+char ciprev[LINELENGTH] = "";
+
+static char *delchoice[] = { /* breakpoint choices */
+ "abort abort command file",
+ "breakpoint break to tty, then resume command file",
+ 0};
+
+/*************************************
+ *** M A I N R O U T I N E ***
+ *************************************/
+
+ci (prompt,fil,depth,list,helppath,cmdfpath)
+char *prompt; /* prompt message */
+FILE *fil; /* input file */
+int depth; /* recursion depth */
+CIENTRY *list; /* entry list */
+char *helppath; /* search list for help files */
+char *cmdfpath; /* search list for command files */
+
+{
+
+ FILE *savfile; /* input file for calling instance of ci */
+ int savquiet, savexit; /* globals for calling instance of ci */
+ char *p,*q,*cmd,*arg; /* temps for parsing input */
+ int i; /* temp */
+ char line[LINELENGTH]; /* input line buffer */
+ int firststmt; /* temp */
+ char *equals,*star; /* index of = and * in input line */
+ char cfnam[200]; /* name of command file */
+ char *name[MAXENTRIES]; /* name list for entries */
+ char *vname[MAXENTRIES]; /* name list for just variables */
+ int vnum[MAXENTRIES]; /* correspondence list for variables */
+ int nv; /* number of variables */
+ int helpcmd; /* "help" command index */
+ FILE *newfile; /* command file just opened */
+ char bprompt[100]; /* breakpoint prompt */
+ char *tname[MAXENTRIES]; /* temp name list */
+ int tnum; /* # entries in tname */
+ char *Shell; /* holds SHELL value from .login */
+ int redirected; /* 1 iff currently redirected output */
+ FILE savestdout; /* place to save normal std. output */
+ FILE *outfile; /* current output file */
+ char *outname; /* output file name */
+
+
+ /* force del() routine to be declared */
+ if (0) del();
+ /* save globals on stack */
+ cidepth++; /* bump the global depth, first CI() is 1 */
+ savquiet = ciquiet;
+ savexit = ciexit;
+ savfile = ciinput;
+ ciexit = 0; /* don't exit until this is set */
+ ciinput = (fil ? fil : stdin); /* new input file */
+
+ /* construct name lists for stablk */
+
+ nv = 0;
+ for (i=0; list[i].ci_etyp != ci_tend; i++) {
+ name[i] = list[i].ci_enam;
+ if (list[i].ci_etyp != ci_tcmd) { /* is variable */
+ vname[nv] = name[i];
+ vnum[nv] = i;
+ nv++;
+ }
+ }
+ helpcmd = i++; /* force-feed "help" onto list */
+ name[helpcmd] = "help";
+ name[i] = 0;
+ vname[nv] = 0;
+
+ /* loop for input lines */
+
+ redirected = 0;
+ while (!ciexit) {
+
+ if (*cinext) { /* get line from ^ command */
+ if (ciback) {
+ sprintf(line,"%s;%s",cinext,ciprev);
+ ciback = 0;
+ }
+ else {
+ strcpy (line,cinext);
+ }
+ strcpy (cinext,"");
+ p = line;
+ }
+ else { /* else read file */
+ if ((ciinput == stderr) || (ciinput == stdin) || (!(ciquiet&CICMDFPROMPT))) {
+ if (!(ciquiet &CICMDNOINDENT)) {
+ for (i=1; i<cidepth; i++) {
+ printf (" ");
+ }
+ }
+ printf ("%s ",prompt);
+ if ((ciinput == stderr) || (ciinput == stdin)) fflush (stdout);
+ }
+ p = fgets (line,LINELENGTH,ciinput); /* read input line */
+ if (p == 0) { /* EOF */
+ if (_del_) {
+ DELCLEAR;
+ strcpy (line,"");
+ p = line;
+ }
+ else {
+ ciexit = 1;
+ if ((ciinput==stdin) || (ciinput==stderr) ||
+ (!(ciquiet&CICMDFECHO))) printf ("\n");
+ }
+ }
+ else {
+ if ((ciinput != stderr) && (ciinput != stdin) &&
+ (!(ciquiet&CICMDFECHO))) printf ("%s",line);
+
+ for (p=line; (*p) && (*p != '\n'); p++) ;
+ *p = 0; /* kill trailing newline */
+ p = line; /* points to start of line */
+ }
+ }
+
+ /* check for redirection of output */
+
+ if (!ciexit) {
+ outname = rindex (p,'>');
+ if (outname) {
+ if (outname == p || *(outname+1) == 0
+ || ((*(outname-1) != ' ') && (*(outname-1) != '\t'))) {
+ outname = 0;
+ }
+ else {
+ for (q=outname+1; *q && (*q != ' ') && (*q != '\t'); q++) ;
+ if (*q) outname = 0;
+ }
+ }
+ if (outname && !(ciquiet&CINOFILE)) {
+ *outname++ = 0;
+ outfile = fopen (outname,"w");
+ if (outfile == 0) {
+ printf ("ci: Can't create output file %s\n",outname);
+ p = "";
+ }
+ else {
+ fflush (stdout);
+ savestdout = *stdout;
+ *stdout = *outfile;
+ redirected = 1;
+ }
+ }
+ }
+
+ /* loop for each command */
+
+ firststmt = 1; /* first time through loop */
+ while ((!ciexit) && (((ciquiet&CINOSEM) && firststmt) || *(cmd=nxtarg(&p,";")) || _argbreak)) {
+
+ if (ciquiet & CINOSEM) {
+ cmd = p;
+ firststmt = 0;
+ }
+
+ switch (*cmd) { /* what kind of line? */
+
+ case ':': /* : comment */
+ case 0: /* null line */
+ break;
+
+ case '!': /* ! shell command */
+ cmd = skipover (cmd+1," ");
+ if ((Shell = getenv("SHELL")) == 0) Shell = "sh";
+ if (*cmd) runp (Shell, Shell, "-c", cmd, 0);
+ else runp (Shell, Shell, 0);
+ if (!(ciquiet&CISHEXIT)) printf ("Back to %s\n",prompt);
+ break;
+
+ case '?': /* ? help */
+ cmd = skipover (cmd+1," ");
+ ci_help (cmd,helppath);
+ break;
+
+ case '<': /* < command file */
+ arg = cmd + 1;
+ cmd = nxtarg (&arg,0); /* parse name */
+ if (*cmd == 0) printf ("ci: missing filename\n");
+ else {
+ if (cmdfpath) newfile = fopenp (cmdfpath,cmd,cfnam,"r");
+ else newfile = fopen (cmd,"r");
+
+ if (newfile == 0)
+ printf ("ci: can't open command file %s\n",cmd);
+ else {
+ if (!(ciquiet&CICMDFECHO)) printf ("\n");
+ ci (prompt,newfile,cidepth,list,helppath,cmdfpath);
+ fclose (newfile);
+ if (!(ciquiet&CICMDFEXIT)) printf ("End of file\n\n");
+ }
+ }
+ break;
+
+ case '^': /* exit and do command */
+ case '@':
+ if (cidepth > 1) {
+ if (*cmd == '@') ciback = 1;
+ if (_argbreak == ';') *(cmd+strlen(cmd)) = ';';
+ ciexit = 1;
+ cmd = skipover(cmd+1," ");
+ strcpy (cinext,cmd);
+ }
+ else printf ("ci: ^ not allowed at top level of ci\n");
+ break;
+
+ default: /* list cmds, etc. */
+ equals = index (cmd,'=');
+ if (equals == cmd) cmd++;
+
+ if (equals) {
+ if (*(equals+1) == 0) *equals = 0;
+ else *equals = ' ';
+ }
+
+ arg = cmd; /* parse first word */
+ cmd = nxtarg (&arg,0);
+ if ((ciquiet&CIFIRSTEQUAL) && equals && equals>arg) {
+ *equals = '='; /* if user doesn't want extra =, kill */
+ equals = 0;
+ }
+ star = index (cmd,'*');
+ if (star) *star = 0;
+ if (star && equals) { /* list vars */
+ printf ("\n");
+ for (i=0; vname[i]; i++) {
+ if (stlmatch (vname[i],cmd)) {
+ ci_show (list[vnum[i]],arg,CIPEEK);
+ }
+ DELBREAK;
+ }
+ printf ("\n");
+ }
+ else if (star) { /* list cmds */
+ printf ("\n");
+ tnum = 0;
+ for (i=0;name[i]; i++) {
+ if ((i==helpcmd || list[i].ci_etyp == ci_tcmd) &&
+ stlmatch (name[i],cmd)) {
+ tname[tnum++] = name[i];
+ }
+ }
+ tname[tnum] = 0;
+ prstab (tname);
+ if (_del_) {_DELNOTE_}
+ printf ("\n");
+ }
+ else if (equals) { /* set var */
+ i = stablk (cmd,vname,0);
+ if (i >= 0) ci_set (list[vnum[i]],skipover(arg," \t"));
+ }
+ else {
+ i = stablk (cmd,name,0);
+
+ if (i == helpcmd) ci_help (arg,helppath);
+ else if (i >= 0) {
+ if (list[i].ci_etyp == ci_tcmd) {
+ (* (int(*)()) (list[i].ci_eptr)) (skipover(arg," \t"));
+ }
+ else ci_show (list[i],skipover(arg," \t"),CISHOW);
+ }
+ }
+ }
+
+ /* end of command */
+
+ /* DEL trapping */
+
+ if (_del_) {
+ if (ciinput == stdin) {
+ DELCLEAR; /* already at tty level */
+ }
+ else {
+ _del_ = 0;
+ i = getstab ("INTERRUPT: abort or breakpoint?",delchoice,"abort");
+ if (i == 0) ciexit = 1; /* abort */
+ else { /* breakpoint */
+ sprintf (bprompt,"Breakpoint for %s",prompt);
+ ci (bprompt,0,cidepth,list,helppath,cmdfpath);
+ }
+ }
+ }
+
+ /* end of loop for commands */
+
+ }
+
+ /* end of loop for lines of input file */
+
+ if (redirected) {
+ fflush (stdout);
+ fclose (stdout);
+ *stdout = savestdout;
+ redirected = 0;
+ }
+
+ }
+
+ /* restore globals */
+ cidepth --; /* update current depth */
+ ciinput = savfile;
+ ciquiet = savquiet;
+ ciexit = savexit;
+}
+
+/********************************************
+ *** P R I N T H E L P F I L E ***
+ ********************************************/
+
+static int _h_found; /* how many matching names? */
+static char **_h_list; /* list of matching names */
+static char (*_h_nlist)[20]; /* list of filename part of names */
+
+static int _ci_help (filspec)
+/* called by searchp to expand filspec, adding names to _h_list */
+char *filspec;
+{
+ register int i,j,result;
+ char dir[200];
+
+ result = expand (filspec, _h_list + _h_found, MAXHELPS - _h_found);
+ if (result > 0) {
+ for (i=0; i<result; ) { /* elim duplicates */
+ path (_h_list[i+_h_found],dir,_h_nlist[i+_h_found]);
+ for (j=0;
+ j<_h_found && strcmp(_h_nlist[j],_h_nlist[i+_h_found]) != 0;
+ j++) ;
+ if (j < _h_found) { /* is duplicate */
+ --result;
+ strcpy (_h_list[i+_h_found],_h_list[result+_h_found]);
+ }
+ else i++; /* isn't duplicate */
+ }
+
+ _h_found += result;
+ }
+
+ return (1); /* keep searching */
+}
+
+/* for use in sorting help file names */
+static ci_hcomp (p,q)
+char **p,**q;
+{
+ char dir[200],file1[20],file2[20];
+ path ((*p),dir,file1);
+ path ((*q),dir,file2);
+ return (strcmp(file1,file2));
+}
+
+static ci_help (topic,helppath)
+char *topic,*helppath;
+{
+ char *fnames[MAXHELPS]; /* names of matching files */
+ char names[MAXHELPS][20]; /* stripped filenames */
+ char *nptr[MAXHELPS+1]; /* list of ptrs for stablk */
+ char dir[200]; /* temp */
+ char shstr[300]; /* shell string for system */
+ int i;
+ char *star;
+ FILE *f;
+
+ if (*topic == 0) { /* wants meta-help */
+ f = fopen (METAHELP,"r");
+ if (f == 0) {
+ printf ("Yikes!! Can't open standard help file!\n");
+ }
+ else {
+ printf ("\n");
+ runp("more","more",METAHELP,0);
+ if (_del_) {_DELNOTE_}
+ printf ("\n");
+ fclose (f);
+ }
+ if (helppath && (*helppath) && (!getbool("Do you want a list of help topics?",1))) {
+ return;
+ }
+ }
+ else { /* chop at * */
+ star = index (topic,'*');
+ if (star) *star = 0;
+ }
+
+ if (helppath == 0) { /* no help at all */
+ printf ("Sorry, no specific help is available for this program.\n");
+ }
+ else {
+ _h_found = 0;
+ _h_list = fnames;
+ _h_nlist = names;
+ searchp (helppath,"*",dir,_ci_help); /* find file names */
+ qsort (fnames,_h_found,sizeof(char *),ci_hcomp);
+
+ for (i=0; i<_h_found; i++) { /* strip pathnames */
+ path (fnames[i],dir,names[i]);
+ nptr[i] = names[i];
+ }
+ nptr[i] = 0;
+
+ if (*topic) { /* request some topic */
+ if (_h_found == 0) {
+ printf ("No help for %s. Type '?*' for list of help messages.\n",topic);
+ }
+ else {
+ i = stablk (topic,nptr,1);
+ if (i < 0) i = stabsearch (topic,nptr,0);
+ if (i >= 0) {
+ f = fopen (fnames[i],"r");
+ if (f == 0)
+ printf ("Yikes! Can't open help file %s\n",fnames[i]);
+ else {
+ printf ("\n");
+ runp("more","more",fnames[i],0);
+ if (_del_) {_DELNOTE_}
+ printf ("\n");
+ fclose (f);
+ }
+ }
+ }
+ }
+ else { /* request topic list */
+ printf ("\nHelp is available for these topics:\n");
+ prstab (nptr);
+ if (_del_) {_DELNOTE_}
+ printf ("\n");
+ }
+
+ for (i=0; i<_h_found; i++) free (fnames[i]);
+
+ }
+}
+
+/*********************************************************
+ *** S H O W V A L U E O F V A R I A B L E ***
+ *********************************************************/
+
+static ci_show (entry,arg,mode)
+CIENTRY entry; /* entry to display */
+char *arg; /* arg for variable procedures */
+CIMODE mode; /* mode (CIPEEK or CISHOW) */
+{
+ if (entry.ci_etyp == ci_tproc) { /* procedure */
+ (* (int(*)()) (entry.ci_eptr)) (mode,arg);
+ }
+ else if (entry.ci_etyp == ci_tclass) { /* class variable */
+ (* (int(*)()) (entry.ci_eptr)) (mode,arg,entry.ci_evar,entry.ci_enam);
+ }
+ else {
+ printf ("%-14s \t",entry.ci_enam);
+ _ci_sho (entry.ci_etyp, entry.ci_eptr);
+ printf ("\n");
+ }
+}
+
+static _ci_sho (etype,eptr)
+ci_type etype;
+ci_union *eptr;
+{
+ int i;
+ unsigned int u;
+
+ switch (etype) {
+
+ case ci_tint:
+ printf ("%d",eptr->ci_uint);
+ break;
+ case ci_tshort:
+ printf ("%d",eptr->ci_ushort);
+ break;
+ case ci_tlong:
+ printf ("%D",eptr->ci_ulong);
+ break;
+ case ci_toct:
+ if (eptr->ci_uoct) printf ("0");
+ printf ("%o",eptr->ci_uoct);
+ break;
+ case ci_thex:
+ if (eptr->ci_uhex) printf ("0x");
+ printf ("%x",eptr->ci_uhex);
+ break;
+ case ci_tdouble:
+ printf ("%g",eptr->ci_udouble);
+ break;
+ case ci_tfloat:
+ printf ("%g",eptr->ci_ufloat);
+ break;
+ case ci_tbool:
+ if (eptr->ci_ubool) printf ("yes");
+ else printf ("no");
+ break;
+ case ci_tstring:
+ printf ("%s",(char *)eptr);
+ break;
+ case ci_tcint:
+ printf ("%d",*(eptr->ci_ucint.ci_ival));
+ break;
+ case ci_tcshort:
+ printf ("%d",*(eptr->ci_ucshort.ci_sval));
+ break;
+ case ci_tclong:
+ printf ("%D",*(eptr->ci_uclong.ci_lval));
+ break;
+ case ci_tcoct:
+ u = *(eptr->ci_ucoct.ci_uval);
+ if (u) printf ("0");
+ printf ("%o",u);
+ break;
+ case ci_tchex:
+ u = *(eptr->ci_uchex.ci_uval);
+ if (u) printf ("0x");
+ printf ("%x",u);
+ break;
+ case ci_tcdouble:
+ printf ("%g",*(eptr->ci_ucdouble.ci_dval));
+ break;
+ case ci_tcfloat:
+ printf ("%g",*(eptr->ci_ucfloat.ci_fval));
+ break;
+ case ci_tcbool:
+ i = *(eptr->ci_ucbool.ci_bval);
+ if (i) printf ("yes");
+ else printf ("no");
+ break;
+ case ci_tcchr:
+ i = *(eptr->ci_ucchr.ci_cval);
+ printf ("%c",eptr->ci_ucchr.ci_cleg[i]);
+ break;
+ case ci_tcstring:
+ printf ("%s",eptr->ci_ucstring.ci_pval);
+ break;
+ case ci_tctab:
+ i = *(eptr->ci_ucstab.ci_tval);
+ printf ("%s",eptr->ci_ucstab.ci_ttab[i]);
+ break;
+ case ci_tcsearch:
+ i = *(eptr->ci_ucsearch.ci_tval);
+ printf ("%s",eptr->ci_ucsearch.ci_ttab[i]);
+ break;
+ default:
+ printf ("Yeek! Illegal cientry type %d!\n",(int) etype);
+ }
+}
+
+/*************************************************************
+ *** A S S I G N V A L U E T O V A R I A B L E ***
+ *************************************************************/
+
+static ci_set (entry,arg)
+CIENTRY entry;
+char *arg;
+{
+ if (entry.ci_etyp == ci_tproc) { /* variable procedure */
+ (* (int(*)()) (entry.ci_eptr)) (CISET,arg);
+ }
+ else if (entry.ci_etyp == ci_tclass) { /* class variable */
+ (* (int(*)()) (entry.ci_eptr)) (CISET,arg,entry.ci_evar,entry.ci_enam);
+ }
+ else {
+ _ci_set (entry.ci_etyp, entry.ci_eptr, arg);
+ if (!(ciquiet & (((ciinput==stdin)||(ciinput==stderr)) ? CISETPEEK : CICMDFPEEK)))
+ ci_show (entry,arg,CIPEEK);
+ }
+}
+
+static _ci_set (etype,eptr,arg)
+ci_type etype;
+ci_union *eptr;
+char *arg;
+{
+ int i;
+ unsigned int u;
+ char *p;
+
+ if (etype == ci_tstring) {
+ strcpy ((char *)eptr,arg);
+ return;
+ }
+ if (etype == ci_tcstring) {
+ strarg (&arg, ";", eptr->ci_ucstring.ci_pmsg,
+ eptr->ci_ucstring.ci_pval,eptr->ci_ucstring.ci_pval);
+ return;
+ }
+
+ p = arg; /* parse first word */
+ arg = nxtarg (&p,0);
+
+ switch (etype) {
+
+ case ci_tint:
+ eptr->ci_uint = atoi (arg);
+ break;
+ case ci_tshort:
+ eptr->ci_ushort = atoi (arg);
+ break;
+ case ci_tlong:
+ eptr->ci_ulong = atol (arg);
+ break;
+ case ci_toct:
+ eptr->ci_uoct = atoo (arg);
+ break;
+ case ci_thex:
+ if (stlmatch(arg,"0x") || stlmatch(arg,"0X")) arg += 2;
+ eptr->ci_uhex = atoh (arg);
+ break;
+ case ci_tdouble:
+ eptr->ci_udouble = atof (arg);
+ break;
+ case ci_tfloat:
+ eptr->ci_ufloat = atof (arg);
+ break;
+ case ci_tbool:
+ eptr->ci_ubool = (index("yYtT",*arg) != 0);
+ break;
+ case ci_tcint:
+ *(eptr->ci_ucint.ci_ival) =
+ intarg (&arg,0,eptr->ci_ucint.ci_imsg,eptr->ci_ucint.ci_imin,
+ eptr->ci_ucint.ci_imax,*(eptr->ci_ucint.ci_ival));
+ break;
+ case ci_tcshort:
+ *(eptr->ci_ucshort.ci_sval) =
+ shortarg (&arg,0,eptr->ci_ucshort.ci_smsg,eptr->ci_ucshort.ci_smin,
+ eptr->ci_ucshort.ci_smax,*(eptr->ci_ucshort.ci_sval));
+ break;
+ case ci_tclong:
+ *(eptr->ci_uclong.ci_lval) =
+ longarg (&arg,0,eptr->ci_uclong.ci_lmsg,eptr->ci_uclong.ci_lmin,
+ eptr->ci_uclong.ci_lmax,*(eptr->ci_uclong.ci_lval));
+ break;
+ case ci_tcoct:
+ *(eptr->ci_ucoct.ci_uval) =
+ octarg (&arg,0,eptr->ci_ucoct.ci_umsg,eptr->ci_ucoct.ci_umin,
+ eptr->ci_ucoct.ci_umax,*(eptr->ci_ucoct.ci_uval));
+ break;
+ case ci_tchex:
+ *(eptr->ci_uchex.ci_uval) =
+ hexarg (&arg,0,eptr->ci_uchex.ci_umsg,eptr->ci_uchex.ci_umin,
+ eptr->ci_uchex.ci_umax,*(eptr->ci_uchex.ci_uval));
+ break;
+ case ci_tcdouble:
+ *(eptr->ci_ucdouble.ci_dval) =
+ doublearg (&arg,0,eptr->ci_ucdouble.ci_dmsg,eptr->ci_ucdouble.ci_dmin,
+ eptr->ci_ucdouble.ci_dmax,*(eptr->ci_ucdouble.ci_dval));
+ break;
+ case ci_tcfloat:
+ *(eptr->ci_ucfloat.ci_fval) =
+ floatarg (&arg,0,eptr->ci_ucfloat.ci_fmsg,eptr->ci_ucfloat.ci_fmin,
+ eptr->ci_ucfloat.ci_fmax,*(eptr->ci_ucfloat.ci_fval));
+ break;
+ case ci_tcbool:
+ *(eptr->ci_ucbool.ci_bval) =
+ boolarg (&arg,0,eptr->ci_ucbool.ci_bmsg,*(eptr->ci_ucbool.ci_bval));
+ break;
+ case ci_tcchr:
+ *(eptr->ci_ucchr.ci_cval) =
+ chrarg (&arg,0,eptr->ci_ucchr.ci_cmsg,eptr->ci_ucchr.ci_cleg,
+ eptr->ci_ucchr.ci_cleg[*(eptr->ci_ucchr.ci_cval)]);
+ break;
+ case ci_tctab:
+ *(eptr->ci_ucstab.ci_tval) =
+ stabarg (&arg,0,eptr->ci_ucstab.ci_tmsg,eptr->ci_ucstab.ci_ttab,
+ eptr->ci_ucstab.ci_ttab[*(eptr->ci_ucstab.ci_tval)]);
+ break;
+ case ci_tcsearch:
+ *(eptr->ci_ucsearch.ci_tval) =
+ searcharg (&arg,0,eptr->ci_ucsearch.ci_tmsg,
+ eptr->ci_ucsearch.ci_ttab,
+ eptr->ci_ucsearch.ci_ttab[*(eptr->ci_ucsearch.ci_tval)]);
+ break;
+ default:;
+ }
+}