about summary refs log tree commit diff
path: root/Src/options.c
diff options
context:
space:
mode:
authorTanaka Akira <akr@users.sourceforge.net>1999-04-15 18:05:35 +0000
committerTanaka Akira <akr@users.sourceforge.net>1999-04-15 18:05:35 +0000
commit32c2ebbaa5d7927f33ee0ecf98472a71cf902cf3 (patch)
tree212c29fe244d0222bab8efe3032e7fa965842945 /Src/options.c
parentc175751b501a3a4cb40ad4787340a597ea769be4 (diff)
downloadzsh-32c2ebbaa5d7927f33ee0ecf98472a71cf902cf3.tar.gz
zsh-32c2ebbaa5d7927f33ee0ecf98472a71cf902cf3.tar.xz
zsh-32c2ebbaa5d7927f33ee0ecf98472a71cf902cf3.zip
zsh-3.1.5 zsh-3.1.5
Diffstat (limited to 'Src/options.c')
-rw-r--r--Src/options.c663
1 files changed, 663 insertions, 0 deletions
diff --git a/Src/options.c b/Src/options.c
new file mode 100644
index 000000000..745a6627c
--- /dev/null
+++ b/Src/options.c
@@ -0,0 +1,663 @@
+/*
+ * options.c - shell options
+ *
+ * This file is part of zsh, the Z shell.
+ *
+ * Copyright (c) 1992-1997 Paul Falstad
+ * All rights reserved.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and to distribute modified versions of this software for any
+ * purpose, provided that the above copyright notice and the following
+ * two paragraphs appear in all copies of this software.
+ *
+ * In no event shall Paul Falstad or the Zsh Development Group be liable
+ * to any party for direct, indirect, special, incidental, or consequential
+ * damages arising out of the use of this software and its documentation,
+ * even if Paul Falstad and the Zsh Development Group have been advised of
+ * the possibility of such damage.
+ *
+ * Paul Falstad and the Zsh Development Group specifically disclaim any
+ * warranties, including, but not limited to, the implied warranties of
+ * merchantability and fitness for a particular purpose.  The software
+ * provided hereunder is on an "as is" basis, and Paul Falstad and the
+ * Zsh Development Group have no obligation to provide maintenance,
+ * support, updates, enhancements, or modifications.
+ *
+ */
+
+#include "zsh.mdh"
+#include "options.pro"
+
+/* current emulation (used to decide which set of option letters is used) */
+
+/**/
+int emulation;
+ 
+/* the options; e.g. if opts[SHGLOB] != 0, SH_GLOB is turned on */
+ 
+/**/
+char opts[OPT_SIZE];
+ 
+/* Option name hash table */
+
+/**/
+HashTable optiontab;
+ 
+typedef struct optname *Optname;
+
+struct optname {
+    HashNode next;		/* next in hash chain */
+    char *nam;			/* hash data */
+    int flags;
+    int optno;			/* option number */
+};
+
+/* The canonical option name table */
+
+#define OPT_CSH		EMULATE_CSH
+#define OPT_KSH		EMULATE_KSH
+#define OPT_SH		EMULATE_SH
+#define OPT_ZSH		EMULATE_ZSH
+
+#define OPT_ALL		(OPT_CSH|OPT_KSH|OPT_SH|OPT_ZSH)
+#define OPT_BOURNE	(OPT_KSH|OPT_SH)
+#define OPT_BSHELL	(OPT_KSH|OPT_SH|OPT_ZSH)
+#define OPT_NONBOURNE	(OPT_ALL & ~OPT_BOURNE)
+#define OPT_NONZSH	(OPT_ALL & ~OPT_ZSH)
+
+#define OPT_EMULATE	(1<<5)	/* option is relevant to emulation */
+#define OPT_SPECIAL	(1<<6)	/* option should never be set by emulate() */
+#define OPT_ALIAS	(1<<7)	/* option is an alias to an other option */
+
+#define defset(X) (!!((X)->flags & emulation))
+
+static struct optname optns[] = {
+{NULL, "allexport",	      0,			 ALLEXPORT},
+{NULL, "alwayslastprompt",    OPT_ALL,			 ALWAYSLASTPROMPT},
+{NULL, "alwaystoend",	      0,			 ALWAYSTOEND},
+{NULL, "appendhistory",	      OPT_ALL,			 APPENDHISTORY},
+{NULL, "autocd",	      0,			 AUTOCD},
+{NULL, "autolist",	      OPT_ALL,			 AUTOLIST},
+{NULL, "automenu",	      OPT_ALL,			 AUTOMENU},
+{NULL, "autonamedirs",	      0,			 AUTONAMEDIRS},
+{NULL, "autoparamkeys",	      OPT_ALL,			 AUTOPARAMKEYS},
+{NULL, "autoparamslash",      OPT_ALL,			 AUTOPARAMSLASH},
+{NULL, "autopushd",	      0,			 AUTOPUSHD},
+{NULL, "autoremoveslash",     OPT_ALL,			 AUTOREMOVESLASH},
+{NULL, "autoresume",	      0,			 AUTORESUME},
+{NULL, "badpattern",	      OPT_EMULATE|OPT_NONBOURNE, BADPATTERN},
+{NULL, "banghist",	      OPT_EMULATE|OPT_NONBOURNE, BANGHIST},
+{NULL, "bareglobqual",        OPT_EMULATE|OPT_ZSH,       BAREGLOBQUAL},
+{NULL, "beep",		      OPT_ALL,			 BEEP},
+{NULL, "bgnice",	      OPT_EMULATE|OPT_NONBOURNE, BGNICE},
+{NULL, "braceccl",	      0,			 BRACECCL},
+{NULL, "bsdecho",	      OPT_EMULATE|OPT_SH,	 BSDECHO},
+{NULL, "cdablevars",	      0,			 CDABLEVARS},
+{NULL, "chaselinks",	      0,			 CHASELINKS},
+{NULL, "clobber",	      OPT_ALL,			 CLOBBER},
+{NULL, "completealiases",     0,			 COMPLETEALIASES},
+{NULL, "completeinword",      0,			 COMPLETEINWORD},
+{NULL, "correct",	      0,			 CORRECT},
+{NULL, "correctall",	      0,			 CORRECTALL},
+{NULL, "cshjunkiehistory",    OPT_EMULATE|OPT_CSH,	 CSHJUNKIEHISTORY},
+{NULL, "cshjunkieloops",      OPT_EMULATE|OPT_CSH,	 CSHJUNKIELOOPS},
+{NULL, "cshjunkiequotes",     OPT_EMULATE|OPT_CSH,	 CSHJUNKIEQUOTES},
+{NULL, "cshnullglob",	      OPT_EMULATE|OPT_CSH,	 CSHNULLGLOB},
+{NULL, "equals",	      OPT_EMULATE|OPT_ZSH,	 EQUALS},
+{NULL, "errexit",	      0,			 ERREXIT},
+{NULL, "exec",		      OPT_ALL,			 EXECOPT},
+{NULL, "extendedglob",	      0,			 EXTENDEDGLOB},
+{NULL, "extendedhistory",     OPT_EMULATE|OPT_CSH,	 EXTENDEDHISTORY},
+{NULL, "flowcontrol",	      OPT_ALL,			 FLOWCONTROL},
+{NULL, "functionargzero",     OPT_EMULATE|OPT_NONBOURNE, FUNCTIONARGZERO},
+{NULL, "glob",		      OPT_ALL,			 GLOBOPT},
+{NULL, "globassign",	      OPT_EMULATE|OPT_CSH,	 GLOBASSIGN},
+{NULL, "globcomplete",	      0,			 GLOBCOMPLETE},
+{NULL, "globdots",	      0,			 GLOBDOTS},
+{NULL, "globsubst",	      OPT_EMULATE|OPT_NONZSH,	 GLOBSUBST},
+{NULL, "hashcmds",	      OPT_ALL,			 HASHCMDS},
+{NULL, "hashdirs",	      OPT_ALL,			 HASHDIRS},
+{NULL, "hashlistall",	      OPT_ALL,			 HASHLISTALL},
+{NULL, "histallowclobber",    0,			 HISTALLOWCLOBBER},
+{NULL, "histbeep",	      OPT_ALL,			 HISTBEEP},
+{NULL, "histignoredups",      0,			 HISTIGNOREDUPS},
+{NULL, "histignorespace",     0,			 HISTIGNORESPACE},
+{NULL, "histnofunctions",     0,			 HISTNOFUNCTIONS},
+{NULL, "histnostore",	      0,			 HISTNOSTORE},
+{NULL, "histreduceblanks",    0,			 HISTREDUCEBLANKS},
+{NULL, "histverify",	      0,			 HISTVERIFY},
+{NULL, "hup",		      OPT_EMULATE|OPT_ZSH,	 HUP},
+{NULL, "ignorebraces",	      OPT_EMULATE|OPT_SH,	 IGNOREBRACES},
+{NULL, "ignoreeof",	      0,			 IGNOREEOF},
+{NULL, "interactive",	      OPT_SPECIAL,		 INTERACTIVE},
+{NULL, "interactivecomments", OPT_EMULATE|OPT_BOURNE,	 INTERACTIVECOMMENTS},
+{NULL, "ksharrays",	      OPT_EMULATE|OPT_BOURNE,	 KSHARRAYS},
+{NULL, "kshautoload",	      OPT_EMULATE|OPT_BOURNE,	 KSHAUTOLOAD},
+{NULL, "kshglob",             OPT_EMULATE|OPT_KSH,       KSHGLOB},
+{NULL, "kshoptionprint",      OPT_EMULATE|OPT_KSH,	 KSHOPTIONPRINT},
+{NULL, "listambiguous",	      OPT_ALL,			 LISTAMBIGUOUS},
+{NULL, "listbeep",	      OPT_ALL,			 LISTBEEP},
+{NULL, "listtypes",	      OPT_ALL,			 LISTTYPES},
+{NULL, "localoptions",	      OPT_EMULATE|OPT_KSH,	 LOCALOPTIONS},
+{NULL, "login",		      OPT_SPECIAL,		 LOGINSHELL},
+{NULL, "longlistjobs",	      0,			 LONGLISTJOBS},
+{NULL, "magicequalsubst",     0,			 MAGICEQUALSUBST},
+{NULL, "mailwarning",	      0,			 MAILWARNING},
+{NULL, "markdirs",	      0,			 MARKDIRS},
+{NULL, "menucomplete",	      0,			 MENUCOMPLETE},
+{NULL, "monitor",	      OPT_SPECIAL,		 MONITOR},
+{NULL, "multios",	      OPT_EMULATE|OPT_ZSH,	 MULTIOS},
+{NULL, "nomatch",	      OPT_EMULATE|OPT_NONBOURNE, NOMATCH},
+{NULL, "notify",	      OPT_ZSH,			 NOTIFY},
+{NULL, "nullglob",	      OPT_EMULATE,		 NULLGLOB},
+{NULL, "numericglobsort",     0,			 NUMERICGLOBSORT},
+{NULL, "overstrike",	      0,			 OVERSTRIKE},
+{NULL, "pathdirs",	      0,			 PATHDIRS},
+{NULL, "posixbuiltins",	      OPT_EMULATE|OPT_BOURNE,	 POSIXBUILTINS},
+{NULL, "printeightbit",       0,                         PRINTEIGHTBIT},
+{NULL, "printexitvalue",      0,			 PRINTEXITVALUE},
+{NULL, "privileged",	      OPT_SPECIAL,		 PRIVILEGED},
+{NULL, "promptbang",	      OPT_EMULATE|OPT_KSH,	 PROMPTBANG},
+{NULL, "promptcr",	      OPT_ALL,			 PROMPTCR},
+{NULL, "promptpercent",	      OPT_EMULATE|OPT_NONBOURNE, PROMPTPERCENT},
+{NULL, "promptsubst",	      OPT_EMULATE|OPT_KSH,	 PROMPTSUBST},
+{NULL, "pushdignoredups",     0,			 PUSHDIGNOREDUPS},
+{NULL, "pushdminus",	      0,			 PUSHDMINUS},
+{NULL, "pushdsilent",	      0,			 PUSHDSILENT},
+{NULL, "pushdtohome",	      0,			 PUSHDTOHOME},
+{NULL, "rcexpandparam",	      0,			 RCEXPANDPARAM},
+{NULL, "rcquotes",	      0,			 RCQUOTES},
+{NULL, "rcs",		      OPT_ALL,			 RCS},
+{NULL, "recexact",	      0,			 RECEXACT},
+{NULL, "restricted",	      OPT_SPECIAL,		 RESTRICTED},
+{NULL, "rmstarsilent",	      OPT_BOURNE,		 RMSTARSILENT},
+{NULL, "rmstarwait",	      0,			 RMSTARWAIT},
+{NULL, "shfileexpansion",     OPT_EMULATE|OPT_BOURNE,	 SHFILEEXPANSION},
+{NULL, "shglob",	      OPT_EMULATE|OPT_BOURNE,	 SHGLOB},
+{NULL, "shinstdin",	      OPT_SPECIAL,		 SHINSTDIN},
+{NULL, "shoptionletters",     OPT_EMULATE|OPT_BOURNE,	 SHOPTIONLETTERS},
+{NULL, "shortloops",	      OPT_ALL,			 SHORTLOOPS},
+{NULL, "shwordsplit",	      OPT_EMULATE|OPT_BOURNE,	 SHWORDSPLIT},
+{NULL, "singlecommand",	      OPT_SPECIAL,		 SINGLECOMMAND},
+{NULL, "singlelinezle",	      OPT_KSH,			 SINGLELINEZLE},
+{NULL, "sunkeyboardhack",     0,			 SUNKEYBOARDHACK},
+{NULL, "unset",		      OPT_EMULATE|OPT_BSHELL,	 UNSET},
+{NULL, "verbose",	      0,			 VERBOSE},
+{NULL, "xtrace",	      0,			 XTRACE},
+{NULL, "zle",		      OPT_SPECIAL,		 USEZLE},
+{NULL, "braceexpand",	      OPT_ALIAS, /* ksh/bash */	 -IGNOREBRACES},
+{NULL, "dotglob",	      OPT_ALIAS, /* bash */	 GLOBDOTS},
+{NULL, "hashall",	      OPT_ALIAS, /* bash */	 HASHCMDS},
+{NULL, "histappend",	      OPT_ALIAS, /* bash */	 APPENDHISTORY},
+{NULL, "histexpand",	      OPT_ALIAS, /* bash */	 BANGHIST},
+{NULL, "log",		      OPT_ALIAS, /* ksh */	 -HISTNOFUNCTIONS},
+{NULL, "mailwarn",	      OPT_ALIAS, /* bash */	 MAILWARNING},
+{NULL, "onecmd",	      OPT_ALIAS, /* bash */	 SINGLECOMMAND},
+{NULL, "physical",	      OPT_ALIAS, /* ksh/bash */	 CHASELINKS},
+{NULL, "promptvars",	      OPT_ALIAS, /* bash */	 PROMPTSUBST},
+{NULL, "stdin",		      OPT_ALIAS, /* ksh */	 SHINSTDIN},
+{NULL, "trackall",	      OPT_ALIAS, /* ksh */	 HASHCMDS},
+{NULL, NULL, 0, 0}
+};
+
+/* Option letters */
+
+#define optletters (isset(SHOPTIONLETTERS) ? kshletters : zshletters)
+
+#define FIRST_OPT '0'
+#define LAST_OPT 'y'
+
+static short zshletters[LAST_OPT - FIRST_OPT + 1] = {
+    /* 0 */  CORRECT,
+    /* 1 */  PRINTEXITVALUE,
+    /* 2 */ -BADPATTERN,
+    /* 3 */ -NOMATCH,
+    /* 4 */  GLOBDOTS,
+    /* 5 */  NOTIFY,
+    /* 6 */  BGNICE,
+    /* 7 */  IGNOREEOF,
+    /* 8 */  MARKDIRS,
+    /* 9 */  AUTOLIST,
+    /* : */  0,
+    /* ; */  0,
+    /* < */  0,
+    /* = */  0,
+    /* > */  0,
+    /* ? */  0,
+    /* @ */  0,
+    /* A */  0,
+    /* B */ -BEEP,
+    /* C */ -CLOBBER,
+    /* D */  PUSHDTOHOME,
+    /* E */  PUSHDSILENT,
+    /* F */ -GLOBOPT,
+    /* G */  NULLGLOB,
+    /* H */  RMSTARSILENT,
+    /* I */  IGNOREBRACES,
+    /* J */  AUTOCD,
+    /* K */ -BANGHIST,
+    /* L */  SUNKEYBOARDHACK,
+    /* M */  SINGLELINEZLE,
+    /* N */  AUTOPUSHD,
+    /* O */  CORRECTALL,
+    /* P */  RCEXPANDPARAM,
+    /* Q */  PATHDIRS,
+    /* R */  LONGLISTJOBS,
+    /* S */  RECEXACT,
+    /* T */  CDABLEVARS,
+    /* U */  MAILWARNING,
+    /* V */ -PROMPTCR,
+    /* W */  AUTORESUME,
+    /* X */  LISTTYPES,
+    /* Y */  MENUCOMPLETE,
+    /* Z */  USEZLE,
+    /* [ */  0,
+    /* \ */  0,
+    /* ] */  0,
+    /* ^ */  0,
+    /* _ */  0,
+    /* ` */  0,
+    /* a */  ALLEXPORT,
+    /* b */  0,
+    /* c */  0,
+    /* d */  0,
+    /* e */  ERREXIT,
+    /* f */ -RCS,
+    /* g */  HISTIGNORESPACE,
+    /* h */  HISTIGNOREDUPS,
+    /* i */  INTERACTIVE,
+    /* j */  0,
+    /* k */  INTERACTIVECOMMENTS,
+    /* l */  LOGINSHELL,
+    /* m */  MONITOR,
+    /* n */ -EXECOPT,
+    /* o */  0,
+    /* p */  PRIVILEGED,
+    /* q */  0,
+    /* r */  RESTRICTED,
+    /* s */  SHINSTDIN,
+    /* t */  SINGLECOMMAND,
+    /* u */ -UNSET,
+    /* v */  VERBOSE,
+    /* w */  CHASELINKS,
+    /* x */  XTRACE,
+    /* y */  SHWORDSPLIT,
+};
+
+static short kshletters[LAST_OPT - FIRST_OPT + 1] = {
+    /* 0 */  0,
+    /* 1 */  0,
+    /* 2 */  0,
+    /* 3 */  0,
+    /* 4 */  0,
+    /* 5 */  0,
+    /* 6 */  0,
+    /* 7 */  0,
+    /* 8 */  0,
+    /* 9 */  0,
+    /* : */  0,
+    /* ; */  0,
+    /* < */  0,
+    /* = */  0,
+    /* > */  0,
+    /* ? */  0,
+    /* @ */  0,
+    /* A */  0,
+    /* B */  0,
+    /* C */ -CLOBBER,
+    /* D */  0,
+    /* E */  0,
+    /* F */  0,
+    /* G */  0,
+    /* H */  0,
+    /* I */  0,
+    /* J */  0,
+    /* K */  0,
+    /* L */  0,
+    /* M */  0,
+    /* N */  0,
+    /* O */  0,
+    /* P */  0,
+    /* Q */  0,
+    /* R */  0,
+    /* S */  0,
+    /* T */  0,
+    /* U */  0,
+    /* V */  0,
+    /* W */  0,
+    /* X */  MARKDIRS,
+    /* Y */  0,
+    /* Z */  0,
+    /* [ */  0,
+    /* \ */  0,
+    /* ] */  0,
+    /* ^ */  0,
+    /* _ */  0,
+    /* ` */  0,
+    /* a */  ALLEXPORT,
+    /* b */  NOTIFY,
+    /* c */  0,
+    /* d */  0,
+    /* e */  ERREXIT,
+    /* f */ -GLOBOPT,
+    /* g */  0,
+    /* h */  0,
+    /* i */  INTERACTIVE,
+    /* j */  0,
+    /* k */  0,
+    /* l */  LOGINSHELL,
+    /* m */  MONITOR,
+    /* n */ -EXECOPT,
+    /* o */  0,
+    /* p */  PRIVILEGED,
+    /* q */  0,
+    /* r */  RESTRICTED,
+    /* s */  SHINSTDIN,
+    /* t */  SINGLECOMMAND,
+    /* u */ -UNSET,
+    /* v */  VERBOSE,
+    /* w */  0,
+    /* x */  XTRACE,
+    /* y */  0,
+};
+
+/* Initialisation of the option name hash table */
+
+/**/
+static void
+printoptionnode(HashNode hn, int set)
+{
+    Optname on = (Optname) hn;
+    int optno = on->optno;
+
+    if (optno < 0)
+	optno = -optno;
+    if (isset(KSHOPTIONPRINT)) {
+	if (defset(on))
+	    printf("no%-20s%s\n", on->nam, isset(optno) ? "off" : "on");
+	else
+	    printf("%-22s%s\n", on->nam, isset(optno) ? "on" : "off");
+    } else if (set == (isset(optno) ^ defset(on))) {
+	if (set ^ isset(optno))
+	    fputs("no", stdout);
+	puts(on->nam);
+    }
+}
+
+/**/
+void
+createoptiontable(void)
+{
+    Optname on;
+
+    optiontab = newhashtable(101, "optiontab", NULL);
+
+    optiontab->hash        = hasher;
+    optiontab->emptytable  = NULL;
+    optiontab->filltable   = NULL;
+    optiontab->addnode     = addhashnode;
+    optiontab->getnode     = gethashnode;
+    optiontab->getnode2    = gethashnode2;
+    optiontab->removenode  = NULL;
+    optiontab->disablenode = disablehashnode;
+    optiontab->enablenode  = enablehashnode;
+    optiontab->freenode    = NULL;
+    optiontab->printnode   = printoptionnode;
+
+    for (on = optns; on->nam; on++)
+	optiontab->addnode(optiontab, on->nam, on);
+}
+
+/* Setting of default options */
+
+/**/
+static void
+setemulate(HashNode hn, int fully)
+{
+    Optname on = (Optname) hn;
+
+    /* Set options: each non-special option is set according to the *
+     * current emulation mode if either it is considered relevant   *
+     * to emulation or we are doing a full emulation (as indicated  *
+     * by the `fully' parameter).                                   */
+    if (!(on->flags & OPT_ALIAS) &&
+	((fully && !(on->flags & OPT_SPECIAL)) ||
+	 (on->flags & OPT_EMULATE)))
+	opts[on->optno] = defset(on);
+}
+
+/**/
+void
+emulate(const char *zsh_name, int fully)
+{
+    char ch = *zsh_name;
+
+    if (ch == 'r')
+	ch = zsh_name[1];
+
+    /* Work out the new emulation mode */
+    if (ch == 'c')
+	emulation = EMULATE_CSH;
+    else if (ch == 'k')
+	emulation = EMULATE_KSH;
+    else if (ch == 's' || ch == 'b')
+	emulation = EMULATE_SH;
+    else
+	emulation = EMULATE_ZSH;
+
+    scanhashtable(optiontab, 0, 0, 0, setemulate, fully);
+}
+
+/* setopt, unsetopt */
+
+/**/
+static void
+setoption(HashNode hn, int value)
+{
+    dosetopt(((Optname) hn)->optno, value, 0);
+}
+
+/**/
+int
+bin_setopt(char *nam, char **args, char *ops, int isun)
+{
+    int action, optno, match = 0;
+
+    /* With no arguments or options, display options. */
+    if (!*args) {
+	scanhashtable(optiontab, 1, 0, OPT_ALIAS, optiontab->printnode, !isun);
+	return 0;
+    }
+
+    /* loop through command line options (begins with "-" or "+") */
+    while (*args && (**args == '-' || **args == '+')) {
+	action = (**args == '-') ^ isun;
+	if(!args[0][1])
+	    *args = "--";
+	while (*++*args) {
+	    if(**args == Meta)
+		*++*args ^= 32;
+	    /* The pseudo-option `--' signifies the end of options. */
+	    if (**args == '-') {
+		args++;
+		goto doneoptions;
+	    } else if (**args == 'o') {
+		if (!*++*args)
+		    args++;
+		if (!*args) {
+		    zwarnnam(nam, "string expected after -o", NULL, 0);
+		    inittyptab();
+		    return 1;
+		}
+		if(!(optno = optlookup(*args)))
+		    zwarnnam(nam, "no such option: %s", *args, 0);
+		else if(dosetopt(optno, action, 0))
+		    zwarnnam(nam, "can't change option: %s", *args, 0);
+		break;
+	    } else if(**args == 'm') {
+		match = 1;
+	    } else {
+	    	if (!(optno = optlookupc(**args)))
+		    zwarnnam(nam, "bad option: -%c", NULL, **args);
+		else if(dosetopt(optno, action, 0))
+		    zwarnnam(nam, "can't change option: -%c", NULL, **args);
+	    }
+	}
+	args++;
+    }
+    doneoptions:
+
+    if (!match) {
+	/* Not globbing the arguments -- arguments are simply option names. */
+	while (*args) {
+	    if(!(optno = optlookup(*args++)))
+		zwarnnam(nam, "no such option: %s", args[-1], 0);
+	    else if(dosetopt(optno, !isun, 0))
+		zwarnnam(nam, "can't change option: %s", args[-1], 0);
+	}
+    } else {
+	/* Globbing option (-m) set. */
+	while (*args) {
+	    Comp com;
+
+	    /* Expand the current arg. */
+	    tokenize(*args);
+	    if (!(com = parsereg(*args))) {
+		untokenize(*args);
+		zwarnnam(nam, "bad pattern: %s", *args, 0);
+		continue;
+	    }
+	    /* Loop over expansions. */
+	    scanmatchtable(optiontab, com, 0, OPT_ALIAS, setoption, !isun);
+	    args++;
+	}
+    }
+    inittyptab();
+    return 0;
+}
+
+/* Identify an option name */
+
+/**/
+int
+optlookup(char const *name)
+{
+    char *s, *t;
+    Optname n;
+
+    s = t = dupstring(name);
+
+    /* exorcise underscores, and change to lowercase */
+    while (*t)
+	if (*t == '_')
+	    chuck(t);
+	else {
+	    *t = tulower(*t);
+	    t++;
+	}
+
+    /* look up name in the table */
+    if (s[0] == 'n' && s[1] == 'o' &&
+	(n = (Optname) optiontab->getnode(optiontab, s + 2))) {
+	return -n->optno;
+    } else if ((n = (Optname) optiontab->getnode(optiontab, s)))
+	return n->optno;
+    else
+	return OPT_INVALID;
+}
+
+/* Identify an option letter */
+
+/**/
+int
+optlookupc(char c)
+{
+    if(c < FIRST_OPT || c > LAST_OPT)
+	return 0;
+
+    return optletters[c - FIRST_OPT];
+}
+
+/**/
+static void
+restrictparam(char *nam)
+{
+    Param pm = (Param) paramtab->getnode(paramtab, nam);
+
+    if (pm) {
+	pm->flags |= PM_SPECIAL | PM_RESTRICTED;
+	return;
+    }
+    createparam(nam, PM_SCALAR | PM_UNSET | PM_SPECIAL | PM_RESTRICTED);
+}
+
+/* list of restricted parameters which are not otherwise special */
+static char *rparams[] = {
+    "SHELL", "HISTFILE", "LD_LIBRARY_PATH", "LD_AOUT_LIBRARY_PATH",
+    "LD_PRELOAD", "LD_AOUT_PRELOAD", NULL
+};
+
+/* Set or unset an option, as a result of user request.  The option *
+ * number may be negative, indicating that the sense is reversed    *
+ * from the usual meaning of the option.                            */
+
+/**/
+int
+dosetopt(int optno, int value, int force)
+{
+    if(!optno)
+	return -1;
+    if(optno < 0) {
+	optno = -optno;
+	value = !value;
+    }
+    if (optno == RESTRICTED) {
+	if (isset(RESTRICTED))
+	    return value ? 0 : -1;
+	if (value) {
+	    char **s;
+
+	    for (s = rparams; *s; s++)
+		restrictparam(*s);
+	}
+    } else if(!force && (optno == INTERACTIVE || optno == SHINSTDIN ||
+	    optno == SINGLECOMMAND)) {
+	/* it is not permitted to change the value of these options */
+	return -1;
+    } else if(!force && optno == USEZLE && value) {
+	/* we require a terminal in order to use ZLE */
+	if(!interact || SHTTY == -1 || !shout)
+	    return -1;
+    } else if(optno == PRIVILEGED && !value) {
+	/* unsetting PRIVILEGED causes the shell to make itself unprivileged */
+#ifdef HAVE_SETUID
+	setuid(getuid());
+	setgid(getgid());
+#endif /* HAVE_SETUID */
+    }
+    opts[optno] = value;
+    if (optno == BANGHIST || optno == SHINSTDIN)
+	inittyptab();
+    return 0;
+}
+
+/* Function to get value for special parameter `-' */
+
+/**/
+char *
+dashgetfn(Param pm)
+{
+    static char buf[LAST_OPT - FIRST_OPT + 2];
+    char *val = buf;
+    int i;
+
+    for(i = 0; i <= LAST_OPT - FIRST_OPT; i++) {
+	int optno = optletters[i];
+	if(optno && ((optno > 0) ? isset(optno) : unset(-optno)))
+	    *val++ = FIRST_OPT + i;
+    }
+    *val = '\0';
+    return buf;
+}