date and time created 95/05/04 17:59:12 by christos
[unix-history] / usr / src / bin / sh / options.c
index 158b5a3..5496d7a 100644 (file)
@@ -1,6 +1,6 @@
 /*-
 /*-
- * Copyright (c) 1991 The Regents of the University of California.
- * All rights reserved.
+ * Copyright (c) 1991, 1993
+ *     The Regents of the University of California.  All rights reserved.
  *
  * This code is derived from software contributed to Berkeley by
  * Kenneth Almquist.
  *
  * This code is derived from software contributed to Berkeley by
  * Kenneth Almquist.
@@ -9,7 +9,7 @@
  */
 
 #ifndef lint
  */
 
 #ifndef lint
-static char sccsid[] = "@(#)options.c  5.3 (Berkeley) %G%";
+static char sccsid[] = "@(#)options.c  8.1 (Berkeley) %G%";
 #endif /* not lint */
 
 #include "shell.h"
 #endif /* not lint */
 
 #include "shell.h"
@@ -39,9 +39,11 @@ char *minusc;                        /* argument to -c option */
 #ifdef __STDC__
 STATIC void options(int);
 STATIC void setoption(int, int);
 #ifdef __STDC__
 STATIC void options(int);
 STATIC void setoption(int, int);
+STATIC void minus_o(char *, int);
 #else
 STATIC void options();
 STATIC void setoption();
 #else
 STATIC void options();
 STATIC void setoption();
+STATIC void minus_o();
 #endif
 
 
 #endif
 
 
@@ -54,23 +56,23 @@ void
 procargs(argc, argv)
        char **argv;
        {
 procargs(argc, argv)
        char **argv;
        {
-       char *p;
+       int i;
 
        argptr = argv;
        if (argc > 0)
                argptr++;
 
        argptr = argv;
        if (argc > 0)
                argptr++;
-       for (p = optval ; p < optval + sizeof optval - 1 ; p++)
-               *p = 2;
+       for (i = 0; i < NOPTS; i++)
+               optlist[i].val = 2;
        options(1);
        if (*argptr == NULL && minusc == NULL)
                sflag = 1;
        if (iflag == 2 && sflag == 1 && isatty(0) && isatty(1))
                iflag = 1;
        options(1);
        if (*argptr == NULL && minusc == NULL)
                sflag = 1;
        if (iflag == 2 && sflag == 1 && isatty(0) && isatty(1))
                iflag = 1;
-       if (jflag == 2)
-               jflag = iflag;
-       for (p = optval ; p < optval + sizeof optval - 1 ; p++)
-               if (*p == 2)
-                       *p = 0;
+       if (mflag == 2)
+               mflag = iflag;
+       for (i = 0; i < NOPTS; i++)
+               if (optlist[i].val == 2)
+                       optlist[i].val = 0;
        arg0 = argv[0];
        if (sflag == 0 && minusc == NULL) {
                commandname = arg0 = *argptr++;
        arg0 = argv[0];
        if (sflag == 0 && minusc == NULL) {
                commandname = arg0 = *argptr++;
@@ -82,12 +84,15 @@ procargs(argc, argv)
                shellparam.nparam++;
                argptr++;
        }
                shellparam.nparam++;
                argptr++;
        }
-       setinteractive(iflag);
-       histedit();
-       setjobctl(jflag);
+       optschanged();
 }
 
 
 }
 
 
+optschanged() {
+       setinteractive(iflag);
+       histedit();
+       setjobctl(mflag);
+}
 
 /*
  * Process shell options.  The global variable argptr contains a pointer
 
 /*
  * Process shell options.  The global variable argptr contains a pointer
@@ -136,26 +141,60 @@ options(cmdline) {
 #ifdef NOHACK
                                break;
 #endif
 #ifdef NOHACK
                                break;
 #endif
+                       } else if (c == 'o') {
+                               minus_o(*argptr, val);
+                               if (*argptr)
+                                       argptr++;
                        } else {
                                setoption(c, val);
                        }
                }
                        } else {
                                setoption(c, val);
                        }
                }
-               if (! cmdline)
-                       break;
        }
 }
 
        }
 }
 
+STATIC void
+minus_o(name, val)
+       char *name;
+       int val;
+{
+       int i;
+
+       if (name == NULL) {
+               out1str("Current option settings\n");
+               for (i = 0; i < NOPTS; i++)
+                       out1fmt("%-16s%s\n", optlist[i].name,
+                               optlist[i].val ? "on" : "off");
+       } else {
+               for (i = 0; i < NOPTS; i++)
+                       if (equal(name, optlist[i].name)) {
+                               setoption(optlist[i].letter, val);
+                               return;
+                       }
+               error("Illegal option -o %s", name);
+       }
+}
+                       
 
 STATIC void
 setoption(flag, val)
        char flag;
        int val;
        {
 
 STATIC void
 setoption(flag, val)
        char flag;
        int val;
        {
-       register char *p;
-
-       if ((p = strchr(optchar, flag)) == NULL)
-               error("Illegal option -%c", flag);
-       optval[p - optchar] = val;
+       int i;
+
+       for (i = 0; i < NOPTS; i++)
+               if (optlist[i].letter == flag) {
+                       optlist[i].val = val;
+                       if (val) {
+                               /* #%$ hack for ksh semantics */
+                               if (flag == 'V')
+                                       Eflag = 0;
+                               else if (flag == 'E')
+                                       Vflag = 0;
+                       }
+                       return;
+               }
+       error("Illegal option -%c", flag);
 }
 
 
 }
 
 
@@ -164,10 +203,12 @@ setoption(flag, val)
 INCLUDE "options.h"
 
 SHELLPROC {
 INCLUDE "options.h"
 
 SHELLPROC {
-       char *p;
+       int i;
+
+       for (i = 0; i < NOPTS; i++)
+               optlist[i].val = 0;
+       optschanged();
 
 
-       for (p = optval ; p < optval + sizeof optval ; p++)
-               *p = 0;
 }
 #endif
 
 }
 #endif
 
@@ -229,7 +270,7 @@ shiftcmd(argc, argv)  char **argv; {
        if (argc > 1)
                n = number(argv[1]);
        if (n > shellparam.nparam)
        if (argc > 1)
                n = number(argv[1]);
        if (n > shellparam.nparam)
-               n = shellparam.nparam;
+               error("can't shift that many");
        INTOFF;
        shellparam.nparam -= n;
        for (ap1 = shellparam.p ; --n >= 0 ; ap1++) {
        INTOFF;
        shellparam.nparam -= n;
        for (ap1 = shellparam.p ; --n >= 0 ; ap1++) {
@@ -254,9 +295,7 @@ setcmd(argc, argv)  char **argv; {
                return showvarscmd(argc, argv);
        INTOFF;
        options(0);
                return showvarscmd(argc, argv);
        INTOFF;
        options(0);
-       setinteractive(iflag);
-       histedit();
-       setjobctl(jflag);
+       optschanged();
        if (*argptr != NULL) {
                setparam(argptr);
        }
        if (*argptr != NULL) {
                setparam(argptr);
        }
@@ -325,6 +364,10 @@ out:
 }
 
 /*
 }
 
 /*
+ * XXX - should get rid of.  have all builtins use getopt(3).  the
+ * library getopt must have the BSD extension static variable "optreset"
+ * otherwise it can't be used within the shell safely.
+ *
  * Standard option processing (a la getopt) for builtin routines.  The
  * only argument that is passed to nextopt is the option string; the
  * other arguments are unnecessary.  It return the character, or '\0' on
  * Standard option processing (a la getopt) for builtin routines.  The
  * only argument that is passed to nextopt is the option string; the
  * other arguments are unnecessary.  It return the character, or '\0' on