home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright (c) 1990 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.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND CARNEGIE MELLON UNIVERSITY
- * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT
- * SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
- * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
- * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * Users of this software agree to return to Carnegie Mellon any
- * improvements or extensions that they make and grant Carnegie the
- * rights to redistribute these changes.
- *
- * Export of this software is permitted only after complying with the
- * regulations of the U.S. Deptartment of Commerce relating to the
- * Export of Technical Data.
- */
- /* ci -- command interpreter
- *
- * Usage (etc.)
- *
- * HISTORY
- * $Log: ci.c,v $
- * Revision 1.2 90/12/11 17:51:01 mja
- * Add copyright/disclaimer for distribution.
- *
- * 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 <stdlib.h>
- #include <libc.h>
- #include <ci.h>
- #include <del.h>
-
- extern char _argbreak;
-
- /*************************
- *** 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/cs/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:;
- }
- }
-