openenvutils/commandshell/shell/src/options.c
changeset 0 2e3d3ce01487
child 4 0fdb7f6b0309
equal deleted inserted replaced
-1:000000000000 0:2e3d3ce01487
       
     1 // options.c - shell options
       
     2 //
       
     3 // © Portions Copyright (c) Symbian Software Ltd 2007. All rights reserved.
       
     4 //
       
     5 /*
       
     6  * This file is part of zsh, the Z shell.
       
     7  *
       
     8  * Copyright (c) 1992-1997 Paul Falstad
       
     9  * All rights reserved.
       
    10  *
       
    11  * Permission is hereby granted, without written agreement and without
       
    12  * license or royalty fees, to use, copy, modify, and distribute this
       
    13  * software and to distribute modified versions of this software for any
       
    14  * purpose, provided that the above copyright notice and the following
       
    15  * two paragraphs appear in all copies of this software.
       
    16  *
       
    17  * In no event shall Paul Falstad or the Zsh Development Group be liable
       
    18  * to any party for direct, indirect, special, incidental, or consequential
       
    19  * damages arising out of the use of this software and its documentation,
       
    20  * even if Paul Falstad and the Zsh Development Group have been advised of
       
    21  * the possibility of such damage.
       
    22  *
       
    23  * Paul Falstad and the Zsh Development Group specifically disclaim any
       
    24  * warranties, including, but not limited to, the implied warranties of
       
    25  * merchantability and fitness for a particular purpose.  The software
       
    26  * provided hereunder is on an "as is" basis, and Paul Falstad and the
       
    27  * Zsh Development Group have no obligation to provide maintenance,
       
    28  * support, updates, enhancements, or modifications.
       
    29  *
       
    30  */
       
    31 #include "zsh.mdh"
       
    32 #include "options.pro"
       
    33 
       
    34 #ifdef __SYMBIAN32__
       
    35 #ifdef __WINSCW__
       
    36 #pragma warn_unusedarg off
       
    37 #endif//__WINSCW__
       
    38 #endif//__SYMBIAN32__
       
    39 
       
    40 /* current emulation (used to decide which set of option letters is used) */
       
    41 
       
    42 /**/
       
    43 int emulation;
       
    44  
       
    45 /* the options; e.g. if opts[SHGLOB] != 0, SH_GLOB is turned on */
       
    46  
       
    47 /**/
       
    48 mod_export char opts[OPT_SIZE];
       
    49  
       
    50 /* Option name hash table */
       
    51 
       
    52 /**/
       
    53 mod_export HashTable optiontab;
       
    54  
       
    55 /* The canonical option name table */
       
    56 
       
    57 #define OPT_CSH		EMULATE_CSH
       
    58 #define OPT_KSH		EMULATE_KSH
       
    59 #define OPT_SH		EMULATE_SH
       
    60 #define OPT_ZSH		EMULATE_ZSH
       
    61 
       
    62 #define OPT_ALL		(OPT_CSH|OPT_KSH|OPT_SH|OPT_ZSH)
       
    63 #define OPT_BOURNE	(OPT_KSH|OPT_SH)
       
    64 #define OPT_BSHELL	(OPT_KSH|OPT_SH|OPT_ZSH)
       
    65 #define OPT_NONBOURNE	(OPT_ALL & ~OPT_BOURNE)
       
    66 #define OPT_NONZSH	(OPT_ALL & ~OPT_ZSH)
       
    67 
       
    68 #define OPT_EMULATE	(1<<5)	/* option is relevant to emulation */
       
    69 #define OPT_SPECIAL	(1<<6)	/* option should never be set by emulate() */
       
    70 #define OPT_ALIAS	(1<<7)	/* option is an alias to an other option */
       
    71 
       
    72 #define defset(X) (!!((X)->flags & emulation))
       
    73 
       
    74 /*
       
    75  * Note that option names should usually be fewer than 20 characters long
       
    76  * to avoid formatting problems.
       
    77  */
       
    78 static struct optname optns[] = {
       
    79 {NULL, "aliases",	      OPT_EMULATE|OPT_ALL,	 ALIASESOPT},
       
    80 {NULL, "allexport",	      OPT_EMULATE,		 ALLEXPORT},
       
    81 {NULL, "alwayslastprompt",    OPT_ALL,			 ALWAYSLASTPROMPT},
       
    82 {NULL, "alwaystoend",	      0,			 ALWAYSTOEND},
       
    83 {NULL, "appendhistory",	      OPT_ALL,			 APPENDHISTORY},
       
    84 {NULL, "autocd",	      OPT_EMULATE,		 AUTOCD},
       
    85 {NULL, "autocontinue",	      0,			 AUTOCONTINUE},
       
    86 {NULL, "autolist",	      OPT_ALL,			 AUTOLIST},
       
    87 {NULL, "automenu",	      OPT_ALL,			 AUTOMENU},
       
    88 {NULL, "autonamedirs",	      0,			 AUTONAMEDIRS},
       
    89 {NULL, "autoparamkeys",	      OPT_ALL,			 AUTOPARAMKEYS},
       
    90 {NULL, "autoparamslash",      OPT_ALL,			 AUTOPARAMSLASH},
       
    91 {NULL, "autopushd",	      0,			 AUTOPUSHD},
       
    92 {NULL, "autoremoveslash",     OPT_ALL,			 AUTOREMOVESLASH},
       
    93 {NULL, "autoresume",	      0,			 AUTORESUME},
       
    94 {NULL, "badpattern",	      OPT_EMULATE|OPT_NONBOURNE, BADPATTERN},
       
    95 {NULL, "banghist",	      OPT_NONBOURNE,		 BANGHIST},
       
    96 {NULL, "bareglobqual",        OPT_EMULATE|OPT_ZSH,       BAREGLOBQUAL},
       
    97 {NULL, "bashautolist",	      0,                         BASHAUTOLIST},
       
    98 {NULL, "beep",		      OPT_ALL,			 BEEP},
       
    99 {NULL, "bgnice",	      OPT_EMULATE|OPT_NONBOURNE, BGNICE},
       
   100 {NULL, "braceccl",	      OPT_EMULATE,		 BRACECCL},
       
   101 {NULL, "bsdecho",	      OPT_EMULATE|OPT_SH,	 BSDECHO},
       
   102 {NULL, "caseglob",	      OPT_ALL,			 CASEGLOB},
       
   103 {NULL, "cbases",	      0,			 CBASES},
       
   104 {NULL, "cdablevars",	      OPT_EMULATE,		 CDABLEVARS},
       
   105 {NULL, "chasedots",	      OPT_EMULATE,		 CHASEDOTS},
       
   106 {NULL, "chaselinks",	      OPT_EMULATE,		 CHASELINKS},
       
   107 {NULL, "checkjobs",	      OPT_EMULATE|OPT_ZSH,	 CHECKJOBS},
       
   108 {NULL, "clobber",	      OPT_EMULATE|OPT_ALL,	 CLOBBER},
       
   109 {NULL, "completealiases",     0,			 COMPLETEALIASES},
       
   110 {NULL, "completeinword",      0,			 COMPLETEINWORD},
       
   111 {NULL, "correct",	      0,			 CORRECT},
       
   112 {NULL, "correctall",	      0,			 CORRECTALL},
       
   113 {NULL, "cshjunkiehistory",    OPT_EMULATE|OPT_CSH,	 CSHJUNKIEHISTORY},
       
   114 {NULL, "cshjunkieloops",      OPT_EMULATE|OPT_CSH,	 CSHJUNKIELOOPS},
       
   115 {NULL, "cshjunkiequotes",     OPT_EMULATE|OPT_CSH,	 CSHJUNKIEQUOTES},
       
   116 {NULL, "cshnullcmd",	      OPT_EMULATE|OPT_CSH,	 CSHNULLCMD},
       
   117 {NULL, "cshnullglob",	      OPT_EMULATE|OPT_CSH,	 CSHNULLGLOB},
       
   118 {NULL, "emacs",		      0,			 EMACSMODE},
       
   119 {NULL, "equals",	      OPT_EMULATE|OPT_ZSH,	 EQUALS},
       
   120 {NULL, "errexit",	      OPT_EMULATE,		 ERREXIT},
       
   121 {NULL, "errreturn",	      OPT_EMULATE,		 ERRRETURN},
       
   122 {NULL, "exec",		      OPT_ALL,			 EXECOPT},
       
   123 {NULL, "extendedglob",	      OPT_EMULATE,		 EXTENDEDGLOB},
       
   124 {NULL, "extendedhistory",     OPT_CSH,			 EXTENDEDHISTORY},
       
   125 {NULL, "evallineno",	      OPT_EMULATE|OPT_ZSH,	 EVALLINENO},
       
   126 {NULL, "flowcontrol",	      OPT_ALL,			 FLOWCONTROL},
       
   127 {NULL, "functionargzero",     OPT_EMULATE|OPT_NONBOURNE, FUNCTIONARGZERO},
       
   128 {NULL, "glob",		      OPT_EMULATE|OPT_ALL,	 GLOBOPT},
       
   129 {NULL, "globalexport",        OPT_EMULATE|OPT_ZSH,	 GLOBALEXPORT},
       
   130 {NULL, "globalrcs",           OPT_ALL,			 GLOBALRCS},
       
   131 {NULL, "globassign",	      OPT_EMULATE|OPT_CSH,	 GLOBASSIGN},
       
   132 {NULL, "globcomplete",	      0,			 GLOBCOMPLETE},
       
   133 {NULL, "globdots",	      OPT_EMULATE,		 GLOBDOTS},
       
   134 {NULL, "globsubst",	      OPT_EMULATE|OPT_NONZSH,	 GLOBSUBST},
       
   135 {NULL, "hashcmds",	      OPT_ALL,			 HASHCMDS},
       
   136 {NULL, "hashdirs",	      OPT_ALL,			 HASHDIRS},
       
   137 {NULL, "hashlistall",	      OPT_ALL,			 HASHLISTALL},
       
   138 {NULL, "histallowclobber",    0,			 HISTALLOWCLOBBER},
       
   139 {NULL, "histbeep",	      OPT_ALL,			 HISTBEEP},
       
   140 {NULL, "histexpiredupsfirst", 0,			 HISTEXPIREDUPSFIRST},
       
   141 {NULL, "histfindnodups",      0,			 HISTFINDNODUPS},
       
   142 {NULL, "histignorealldups",   0,			 HISTIGNOREALLDUPS},
       
   143 {NULL, "histignoredups",      0,			 HISTIGNOREDUPS},
       
   144 {NULL, "histignorespace",     0,			 HISTIGNORESPACE},
       
   145 {NULL, "histnofunctions",     0,			 HISTNOFUNCTIONS},
       
   146 {NULL, "histnostore",	      0,			 HISTNOSTORE},
       
   147 {NULL, "histreduceblanks",    0,			 HISTREDUCEBLANKS},
       
   148 {NULL, "histsavenodups",      0,			 HISTSAVENODUPS},
       
   149 {NULL, "histverify",	      0,			 HISTVERIFY},
       
   150 {NULL, "hup",		      OPT_EMULATE|OPT_ZSH,	 HUP},
       
   151 {NULL, "ignorebraces",	      OPT_EMULATE|OPT_SH,	 IGNOREBRACES},
       
   152 {NULL, "ignoreeof",	      0,			 IGNOREEOF},
       
   153 {NULL, "incappendhistory",    0,			 INCAPPENDHISTORY},
       
   154 {NULL, "interactive",	      OPT_SPECIAL,		 INTERACTIVE},
       
   155 {NULL, "interactivecomments", OPT_BOURNE,		 INTERACTIVECOMMENTS},
       
   156 {NULL, "ksharrays",	      OPT_EMULATE|OPT_BOURNE,	 KSHARRAYS},
       
   157 {NULL, "kshautoload",	      OPT_EMULATE|OPT_BOURNE,	 KSHAUTOLOAD},
       
   158 {NULL, "kshglob",             OPT_EMULATE|OPT_KSH,       KSHGLOB},
       
   159 {NULL, "kshoptionprint",      OPT_EMULATE|OPT_KSH,	 KSHOPTIONPRINT},
       
   160 {NULL, "kshtypeset",          OPT_EMULATE|OPT_KSH,	 KSHTYPESET},
       
   161 {NULL, "listambiguous",	      OPT_ALL,			 LISTAMBIGUOUS},
       
   162 {NULL, "listbeep",	      OPT_ALL,			 LISTBEEP},
       
   163 {NULL, "listpacked",	      0,			 LISTPACKED},
       
   164 {NULL, "listrowsfirst",	      0,			 LISTROWSFIRST},
       
   165 {NULL, "listtypes",	      OPT_ALL,			 LISTTYPES},
       
   166 {NULL, "localoptions",	      OPT_EMULATE|OPT_KSH,	 LOCALOPTIONS},
       
   167 {NULL, "localtraps",	      OPT_EMULATE|OPT_KSH,	 LOCALTRAPS},
       
   168 {NULL, "login",		      OPT_SPECIAL,		 LOGINSHELL},
       
   169 {NULL, "longlistjobs",	      0,			 LONGLISTJOBS},
       
   170 {NULL, "magicequalsubst",     OPT_EMULATE,		 MAGICEQUALSUBST},
       
   171 {NULL, "mailwarning",	      0,			 MAILWARNING},
       
   172 {NULL, "markdirs",	      0,			 MARKDIRS},
       
   173 {NULL, "menucomplete",	      0,			 MENUCOMPLETE},
       
   174 {NULL, "monitor",	      OPT_SPECIAL,		 MONITOR},
       
   175 {NULL, "multios",	      OPT_EMULATE|OPT_ZSH,	 MULTIOS},
       
   176 {NULL, "nomatch",	      OPT_EMULATE|OPT_NONBOURNE, NOMATCH},
       
   177 {NULL, "notify",	      OPT_ZSH,			 NOTIFY},
       
   178 {NULL, "nullglob",	      OPT_EMULATE,		 NULLGLOB},
       
   179 {NULL, "numericglobsort",     OPT_EMULATE,		 NUMERICGLOBSORT},
       
   180 {NULL, "octalzeroes",         OPT_EMULATE|OPT_SH,	 OCTALZEROES},
       
   181 {NULL, "overstrike",	      0,			 OVERSTRIKE},
       
   182 {NULL, "pathdirs",	      OPT_EMULATE,		 PATHDIRS},
       
   183 {NULL, "posixbuiltins",	      OPT_EMULATE|OPT_BOURNE,	 POSIXBUILTINS},
       
   184 {NULL, "printeightbit",       0,                         PRINTEIGHTBIT},
       
   185 {NULL, "printexitvalue",      0,			 PRINTEXITVALUE},
       
   186 {NULL, "privileged",	      OPT_SPECIAL,		 PRIVILEGED},
       
   187 {NULL, "promptbang",	      OPT_KSH,			 PROMPTBANG},
       
   188 {NULL, "promptcr",	      OPT_ALL,			 PROMPTCR},
       
   189 {NULL, "promptpercent",	      OPT_NONBOURNE,		 PROMPTPERCENT},
       
   190 {NULL, "promptsubst",	      OPT_KSH,			 PROMPTSUBST},
       
   191 {NULL, "pushdignoredups",     OPT_EMULATE,		 PUSHDIGNOREDUPS},
       
   192 {NULL, "pushdminus",	      OPT_EMULATE,		 PUSHDMINUS},
       
   193 {NULL, "pushdsilent",	      0,			 PUSHDSILENT},
       
   194 {NULL, "pushdtohome",	      OPT_EMULATE,		 PUSHDTOHOME},
       
   195 {NULL, "rcexpandparam",	      OPT_EMULATE,		 RCEXPANDPARAM},
       
   196 {NULL, "rcquotes",	      OPT_EMULATE,		 RCQUOTES},
       
   197 {NULL, "rcs",		      OPT_ALL,			 RCS},
       
   198 {NULL, "recexact",	      0,			 RECEXACT},
       
   199 {NULL, "restricted",	      OPT_SPECIAL,		 RESTRICTED},
       
   200 {NULL, "rmstarsilent",	      OPT_BOURNE,		 RMSTARSILENT},
       
   201 {NULL, "rmstarwait",	      0,			 RMSTARWAIT},
       
   202 {NULL, "sharehistory",	      OPT_KSH,			 SHAREHISTORY},
       
   203 {NULL, "shfileexpansion",     OPT_EMULATE|OPT_BOURNE,	 SHFILEEXPANSION},
       
   204 {NULL, "shglob",	      OPT_EMULATE|OPT_BOURNE,	 SHGLOB},
       
   205 {NULL, "shinstdin",	      OPT_SPECIAL,		 SHINSTDIN},
       
   206 {NULL, "shnullcmd",           OPT_EMULATE|OPT_BOURNE,	 SHNULLCMD},
       
   207 {NULL, "shoptionletters",     OPT_EMULATE|OPT_BOURNE,	 SHOPTIONLETTERS},
       
   208 {NULL, "shortloops",	      OPT_EMULATE|OPT_NONBOURNE, SHORTLOOPS},
       
   209 {NULL, "shwordsplit",	      OPT_EMULATE|OPT_BOURNE,	 SHWORDSPLIT},
       
   210 {NULL, "singlecommand",	      OPT_SPECIAL,		 SINGLECOMMAND},
       
   211 {NULL, "singlelinezle",	      OPT_KSH,			 SINGLELINEZLE},
       
   212 {NULL, "sunkeyboardhack",     0,			 SUNKEYBOARDHACK},
       
   213 {NULL, "transientrprompt",    0,			 TRANSIENTRPROMPT},
       
   214 {NULL, "trapsasync",	      0,			 TRAPSASYNC},
       
   215 {NULL, "typesetsilent",	      OPT_EMULATE|OPT_BOURNE,	 TYPESETSILENT},
       
   216 {NULL, "unset",		      OPT_EMULATE|OPT_BSHELL,	 UNSET},
       
   217 {NULL, "verbose",	      0,			 VERBOSE},
       
   218 {NULL, "vi",		      0,			 VIMODE},
       
   219 {NULL, "xtrace",	      0,			 XTRACE},
       
   220 {NULL, "zle",		      OPT_SPECIAL,		 USEZLE},
       
   221 {NULL, "braceexpand",	      OPT_ALIAS, /* ksh/bash */	 -IGNOREBRACES},
       
   222 {NULL, "dotglob",	      OPT_ALIAS, /* bash */	 GLOBDOTS},
       
   223 {NULL, "hashall",	      OPT_ALIAS, /* bash */	 HASHCMDS},
       
   224 {NULL, "histappend",	      OPT_ALIAS, /* bash */	 APPENDHISTORY},
       
   225 {NULL, "histexpand",	      OPT_ALIAS, /* bash */	 BANGHIST},
       
   226 {NULL, "log",		      OPT_ALIAS, /* ksh */	 -HISTNOFUNCTIONS},
       
   227 {NULL, "mailwarn",	      OPT_ALIAS, /* bash */	 MAILWARNING},
       
   228 {NULL, "onecmd",	      OPT_ALIAS, /* bash */	 SINGLECOMMAND},
       
   229 {NULL, "physical",	      OPT_ALIAS, /* ksh/bash */	 CHASELINKS},
       
   230 {NULL, "promptvars",	      OPT_ALIAS, /* bash */	 PROMPTSUBST},
       
   231 {NULL, "stdin",		      OPT_ALIAS, /* ksh */	 SHINSTDIN},
       
   232 {NULL, "trackall",	      OPT_ALIAS, /* ksh */	 HASHCMDS},
       
   233 {NULL, "dvorak",	      0,			 DVORAK},
       
   234 {NULL, NULL, 0, 0}
       
   235 };
       
   236 
       
   237 /* Option letters */
       
   238 
       
   239 #define optletters (isset(SHOPTIONLETTERS) ? kshletters : zshletters)
       
   240 
       
   241 #define FIRST_OPT '0'
       
   242 #define LAST_OPT 'y'
       
   243 
       
   244 static short zshletters[LAST_OPT - FIRST_OPT + 1] = {
       
   245     /* 0 */  CORRECT,
       
   246     /* 1 */  PRINTEXITVALUE,
       
   247     /* 2 */ -BADPATTERN,
       
   248     /* 3 */ -NOMATCH,
       
   249     /* 4 */  GLOBDOTS,
       
   250     /* 5 */  NOTIFY,
       
   251     /* 6 */  BGNICE,
       
   252     /* 7 */  IGNOREEOF,
       
   253     /* 8 */  MARKDIRS,
       
   254     /* 9 */  AUTOLIST,
       
   255     /* : */  0,
       
   256     /* ; */  0,
       
   257     /* < */  0,
       
   258     /* = */  0,
       
   259     /* > */  0,
       
   260     /* ? */  0,
       
   261     /* @ */  0,
       
   262     /* A */  0,			/* use with set for arrays */
       
   263     /* B */ -BEEP,
       
   264     /* C */ -CLOBBER,
       
   265     /* D */  PUSHDTOHOME,
       
   266     /* E */  PUSHDSILENT,
       
   267     /* F */ -GLOBOPT,
       
   268     /* G */  NULLGLOB,
       
   269     /* H */  RMSTARSILENT,
       
   270     /* I */  IGNOREBRACES,
       
   271     /* J */  AUTOCD,
       
   272     /* K */ -BANGHIST,
       
   273     /* L */  SUNKEYBOARDHACK,
       
   274     /* M */  SINGLELINEZLE,
       
   275     /* N */  AUTOPUSHD,
       
   276     /* O */  CORRECTALL,
       
   277     /* P */  RCEXPANDPARAM,
       
   278     /* Q */  PATHDIRS,
       
   279     /* R */  LONGLISTJOBS,
       
   280     /* S */  RECEXACT,
       
   281     /* T */  CDABLEVARS,
       
   282     /* U */  MAILWARNING,
       
   283     /* V */ -PROMPTCR,
       
   284     /* W */  AUTORESUME,
       
   285     /* X */  LISTTYPES,
       
   286     /* Y */  MENUCOMPLETE,
       
   287     /* Z */  USEZLE,
       
   288     /* [ */  0,
       
   289     /* \ */  0,
       
   290     /* ] */  0,
       
   291     /* ^ */  0,
       
   292     /* _ */  0,
       
   293     /* ` */  0,
       
   294     /* a */  ALLEXPORT,
       
   295     /* b */  0,			/* in non-Bourne shells, end of options */
       
   296     /* c */  0,			/* command follows */
       
   297     /* d */ -GLOBALRCS,
       
   298     /* e */  ERREXIT,
       
   299     /* f */ -RCS,
       
   300     /* g */  HISTIGNORESPACE,
       
   301     /* h */  HISTIGNOREDUPS,
       
   302     /* i */  INTERACTIVE,
       
   303     /* j */  0,
       
   304     /* k */  INTERACTIVECOMMENTS,
       
   305     /* l */  LOGINSHELL,
       
   306     /* m */  MONITOR,
       
   307     /* n */ -EXECOPT,
       
   308     /* o */  0,			/* long option name follows */
       
   309     /* p */  PRIVILEGED,
       
   310     /* q */  0,
       
   311     /* r */  RESTRICTED,
       
   312     /* s */  SHINSTDIN,
       
   313     /* t */  SINGLECOMMAND,
       
   314     /* u */ -UNSET,
       
   315     /* v */  VERBOSE,
       
   316     /* w */  CHASELINKS,
       
   317     /* x */  XTRACE,
       
   318     /* y */  SHWORDSPLIT,
       
   319 };
       
   320 
       
   321 static short kshletters[LAST_OPT - FIRST_OPT + 1] = {
       
   322     /* 0 */  0,
       
   323     /* 1 */  0,
       
   324     /* 2 */  0,
       
   325     /* 3 */  0,
       
   326     /* 4 */  0,
       
   327     /* 5 */  0,
       
   328     /* 6 */  0,
       
   329     /* 7 */  0,
       
   330     /* 8 */  0,
       
   331     /* 9 */  0,
       
   332     /* : */  0,
       
   333     /* ; */  0,
       
   334     /* < */  0,
       
   335     /* = */  0,
       
   336     /* > */  0,
       
   337     /* ? */  0,
       
   338     /* @ */  0,
       
   339     /* A */  0,
       
   340     /* B */  0,
       
   341     /* C */ -CLOBBER,
       
   342     /* D */  0,
       
   343     /* E */  0,
       
   344     /* F */  0,
       
   345     /* G */  0,
       
   346     /* H */  0,
       
   347     /* I */  0,
       
   348     /* J */  0,
       
   349     /* K */  0,
       
   350     /* L */  0,
       
   351     /* M */  0,
       
   352     /* N */  0,
       
   353     /* O */  0,
       
   354     /* P */  0,
       
   355     /* Q */  0,
       
   356     /* R */  0,
       
   357     /* S */  0,
       
   358     /* T */  TRAPSASYNC,
       
   359     /* U */  0,
       
   360     /* V */  0,
       
   361     /* W */  0,
       
   362     /* X */  MARKDIRS,
       
   363     /* Y */  0,
       
   364     /* Z */  0,
       
   365     /* [ */  0,
       
   366     /* \ */  0,
       
   367     /* ] */  0,
       
   368     /* ^ */  0,
       
   369     /* _ */  0,
       
   370     /* ` */  0,
       
   371     /* a */  ALLEXPORT,
       
   372     /* b */  NOTIFY,
       
   373     /* c */  0,
       
   374     /* d */  0,
       
   375     /* e */  ERREXIT,
       
   376     /* f */ -GLOBOPT,
       
   377     /* g */  0,
       
   378     /* h */  0,
       
   379     /* i */  INTERACTIVE,
       
   380     /* j */  0,
       
   381     /* k */  0,
       
   382     /* l */  LOGINSHELL,
       
   383     /* m */  MONITOR,
       
   384     /* n */ -EXECOPT,
       
   385     /* o */  0,
       
   386     /* p */  PRIVILEGED,
       
   387     /* q */  0,
       
   388     /* r */  RESTRICTED,
       
   389     /* s */  SHINSTDIN,
       
   390     /* t */  SINGLECOMMAND,
       
   391     /* u */ -UNSET,
       
   392     /* v */  VERBOSE,
       
   393     /* w */  0,
       
   394     /* x */  XTRACE,
       
   395     /* y */  0,
       
   396 };
       
   397 
       
   398 /* Initialisation of the option name hash table */
       
   399 
       
   400 /**/
       
   401 static void
       
   402 printoptionnode(HashNode hn, int set)
       
   403 {
       
   404     Optname on = (Optname) hn;
       
   405     int optno = on->optno;
       
   406 
       
   407     if (optno < 0)
       
   408 	optno = -optno;
       
   409     if (isset(KSHOPTIONPRINT)) {
       
   410 	if (defset(on))
       
   411 	    printf("no%-19s %s\n", on->nam, isset(optno) ? "off" : "on");
       
   412 	else
       
   413 	    printf("%-21s %s\n", on->nam, isset(optno) ? "on" : "off");
       
   414     } else if (set == (isset(optno) ^ defset(on))) {
       
   415 	if (set ^ isset(optno))
       
   416 	    fputs("no", stdout);
       
   417 	puts(on->nam);
       
   418     }
       
   419 }
       
   420 
       
   421 /**/
       
   422 void
       
   423 createoptiontable(void)
       
   424 {
       
   425     Optname on;
       
   426 
       
   427     optiontab = newhashtable(101, "optiontab", NULL);
       
   428 
       
   429     optiontab->hash        = hasher;
       
   430     optiontab->emptytable  = NULL;
       
   431     optiontab->filltable   = NULL;
       
   432     optiontab->cmpnodes    = strcmp;
       
   433     optiontab->addnode     = addhashnode;
       
   434     optiontab->getnode     = gethashnode;
       
   435     optiontab->getnode2    = gethashnode2;
       
   436     optiontab->removenode  = NULL;
       
   437     optiontab->disablenode = disablehashnode;
       
   438     optiontab->enablenode  = enablehashnode;
       
   439     optiontab->freenode    = NULL;
       
   440     optiontab->printnode   = printoptionnode;
       
   441 
       
   442     for (on = optns; on->nam; on++)
       
   443 	optiontab->addnode(optiontab, on->nam, on);
       
   444 }
       
   445 
       
   446 /* Setting of default options */
       
   447 
       
   448 /**/
       
   449 static void
       
   450 setemulate(HashNode hn, int fully)
       
   451 {
       
   452     Optname on = (Optname) hn;
       
   453 
       
   454     /* Set options: each non-special option is set according to the *
       
   455      * current emulation mode if either it is considered relevant   *
       
   456      * to emulation or we are doing a full emulation (as indicated  *
       
   457      * by the `fully' parameter).                                   */
       
   458     if (!(on->flags & OPT_ALIAS) &&
       
   459 	((fully && !(on->flags & OPT_SPECIAL)) ||
       
   460 	 (on->flags & OPT_EMULATE)))
       
   461 	opts[on->optno] = defset(on);
       
   462 }
       
   463 
       
   464 /**/
       
   465 void
       
   466 emulate(const char *zsh_name, int fully)
       
   467 {
       
   468     char ch = *zsh_name;
       
   469 
       
   470     if (ch == 'r')
       
   471 	ch = zsh_name[1];
       
   472 
       
   473     /* Work out the new emulation mode */
       
   474     if (ch == 'c')
       
   475 	emulation = EMULATE_CSH;
       
   476     else if (ch == 'k')
       
   477 	emulation = EMULATE_KSH;
       
   478     else if (ch == 's' || ch == 'b')
       
   479 	emulation = EMULATE_SH;
       
   480     else
       
   481 	emulation = EMULATE_ZSH;
       
   482 
       
   483     scanhashtable(optiontab, 0, 0, 0, setemulate, fully);
       
   484 }
       
   485 
       
   486 /* setopt, unsetopt */
       
   487 
       
   488 /**/
       
   489 static void
       
   490 setoption(HashNode hn, int value)
       
   491 {
       
   492     dosetopt(((Optname) hn)->optno, value, 0);
       
   493 }
       
   494 
       
   495 /**/
       
   496 int
       
   497 bin_setopt(char *nam, char **args, UNUSED(Options ops), int isun)
       
   498 {
       
   499     int action, optno, match = 0;
       
   500 
       
   501     /* With no arguments or options, display options. */
       
   502     if (!*args) {
       
   503 	scanhashtable(optiontab, 1, 0, OPT_ALIAS, optiontab->printnode, !isun);
       
   504 	return 0;
       
   505     }
       
   506 
       
   507     /* loop through command line options (begins with "-" or "+") */
       
   508     while (*args && (**args == '-' || **args == '+')) {
       
   509 	action = (**args == '-') ^ isun;
       
   510 	if(!args[0][1])
       
   511 	    *args = "--";
       
   512 	while (*++*args) {
       
   513 	    if(**args == Meta)
       
   514 		*++*args ^= 32;
       
   515 	    /* The pseudo-option `--' signifies the end of options. */
       
   516 	    if (**args == '-') {
       
   517 		args++;
       
   518 		goto doneoptions;
       
   519 	    } else if (**args == 'o') {
       
   520 		if (!*++*args)
       
   521 		    args++;
       
   522 		if (!*args) {
       
   523 		    zwarnnam(nam, "string expected after -o", NULL, 0);
       
   524 		    inittyptab();
       
   525 		    return 1;
       
   526 		}
       
   527 		if(!(optno = optlookup(*args)))
       
   528 		    zwarnnam(nam, "no such option: %s", *args, 0);
       
   529 		else if(dosetopt(optno, action, 0))
       
   530 		    zwarnnam(nam, "can't change option: %s", *args, 0);
       
   531 		break;
       
   532 	    } else if(**args == 'm') {
       
   533 		match = 1;
       
   534 	    } else {
       
   535 	    	if (!(optno = optlookupc(**args)))
       
   536 		    zwarnnam(nam, "bad option: -%c", NULL, **args);
       
   537 		else if(dosetopt(optno, action, 0))
       
   538 		    zwarnnam(nam, "can't change option: -%c", NULL, **args);
       
   539 	    }
       
   540 	}
       
   541 	args++;
       
   542     }
       
   543     doneoptions:
       
   544 
       
   545     if (!match) {
       
   546 	/* Not globbing the arguments -- arguments are simply option names. */
       
   547 	while (*args) {
       
   548 	    if(!(optno = optlookup(*args++)))
       
   549 		zwarnnam(nam, "no such option: %s", args[-1], 0);
       
   550 	    else if(dosetopt(optno, !isun, 0))
       
   551 		zwarnnam(nam, "can't change option: %s", args[-1], 0);
       
   552 	}
       
   553     } else {
       
   554 	/* Globbing option (-m) set. */
       
   555 	while (*args) {
       
   556 	    Patprog pprog;
       
   557 	    char *s, *t;
       
   558 
       
   559 	    t = s = dupstring(*args);
       
   560 	    while (*t)
       
   561 		if (*t == '_')
       
   562 		    chuck(t);
       
   563 		else {
       
   564 		    *t = tulower(*t);
       
   565 		    t++;
       
   566 		}
       
   567 
       
   568 	    /* Expand the current arg. */
       
   569 	    tokenize(s);
       
   570 	    if (!(pprog = patcompile(s, PAT_STATIC, NULL))) {
       
   571 		zwarnnam(nam, "bad pattern: %s", *args, 0);
       
   572 		continue;
       
   573 	    }
       
   574 	    /* Loop over expansions. */
       
   575 	    scanmatchtable(optiontab, pprog, 0, OPT_ALIAS, setoption, !isun);
       
   576 	    args++;
       
   577 	}
       
   578     }
       
   579     inittyptab();
       
   580     return 0;
       
   581 }
       
   582 
       
   583 /* Identify an option name */
       
   584 
       
   585 /**/
       
   586 mod_export int
       
   587 optlookup(char const *name)
       
   588 {
       
   589     char *s, *t;
       
   590     Optname n;
       
   591 
       
   592     s = t = dupstring(name);
       
   593 
       
   594     /* exorcise underscores, and change to lowercase */
       
   595     while (*t)
       
   596 	if (*t == '_')
       
   597 	    chuck(t);
       
   598 	else {
       
   599 	    *t = tulower(*t);
       
   600 	    t++;
       
   601 	}
       
   602 
       
   603     /* look up name in the table */
       
   604     if (s[0] == 'n' && s[1] == 'o' &&
       
   605 	(n = (Optname) optiontab->getnode(optiontab, s + 2))) {
       
   606 	return -n->optno;
       
   607     } else if ((n = (Optname) optiontab->getnode(optiontab, s)))
       
   608 	return n->optno;
       
   609     else
       
   610 	return OPT_INVALID;
       
   611 }
       
   612 
       
   613 /* Identify an option letter */
       
   614 
       
   615 /**/
       
   616 int
       
   617 optlookupc(char c)
       
   618 {
       
   619     if(c < FIRST_OPT || c > LAST_OPT)
       
   620 	return 0;
       
   621 
       
   622     return optletters[c - FIRST_OPT];
       
   623 }
       
   624 
       
   625 /**/
       
   626 static void
       
   627 restrictparam(char *nam)
       
   628 {
       
   629     Param pm = (Param) paramtab->getnode(paramtab, nam);
       
   630 
       
   631     if (pm) {
       
   632 	pm->flags |= PM_SPECIAL | PM_RESTRICTED;
       
   633 	return;
       
   634     }
       
   635     createparam(nam, PM_SCALAR | PM_UNSET | PM_SPECIAL | PM_RESTRICTED);
       
   636 }
       
   637 
       
   638 /* list of restricted parameters which are not otherwise special */
       
   639 static char *rparams[] = {
       
   640     "SHELL", "HISTFILE", "LD_LIBRARY_PATH", "LD_AOUT_LIBRARY_PATH",
       
   641     "LD_PRELOAD", "LD_AOUT_PRELOAD", NULL
       
   642 };
       
   643 
       
   644 /* Set or unset an option, as a result of user request.  The option *
       
   645  * number may be negative, indicating that the sense is reversed    *
       
   646  * from the usual meaning of the option.                            */
       
   647 
       
   648 /**/
       
   649 mod_export int
       
   650 dosetopt(int optno, int value, int force)
       
   651 {
       
   652     if(!optno)
       
   653 	return -1;
       
   654     if(optno < 0) {
       
   655 	optno = -optno;
       
   656 	value = !value;
       
   657     }
       
   658     if (optno == RESTRICTED) {
       
   659 	if (isset(RESTRICTED))
       
   660 	    return value ? 0 : -1;
       
   661 	if (value) {
       
   662 	    char **s;
       
   663 
       
   664 	    for (s = rparams; *s; s++)
       
   665 		restrictparam(*s);
       
   666 	}
       
   667     } else if(!force && optno == EXECOPT && !value && interact) {
       
   668 	/* cannot set noexec when interactive */
       
   669 	return -1;
       
   670     } else if(!force && (optno == INTERACTIVE || optno == SHINSTDIN ||
       
   671 	    optno == SINGLECOMMAND)) {
       
   672 	if (opts[optno] == value)
       
   673 	    return 0;
       
   674 	/* it is not permitted to change the value of these options */
       
   675 	return -1;
       
   676     } else if(!force && optno == USEZLE && value) {
       
   677 	/* we require a terminal in order to use ZLE */
       
   678 	if(!interact || SHTTY == -1 || !shout)
       
   679 	    return -1;
       
   680     } else if(optno == PRIVILEGED && !value) {
       
   681 	/* unsetting PRIVILEGED causes the shell to make itself unprivileged */
       
   682 #ifdef HAVE_SETUID
       
   683 	setuid(getuid());
       
   684 	setgid(getgid());
       
   685 #endif /* HAVE_SETUID */
       
   686 #ifndef JOB_CONTROL
       
   687     } else if(optno == MONITOR && value) {
       
   688 	    return -1;
       
   689 #endif /* not JOB_CONTROL */
       
   690 #ifdef GETPWNAM_FAKED
       
   691     } else if(optno == CDABLEVARS && value) {
       
   692 	    return -1;
       
   693 #endif /* GETPWNAM_FAKED */
       
   694     } else if ((optno == EMACSMODE || optno == VIMODE) && value) {
       
   695 	(*zlesetkeymapptr)(optno);
       
   696 	opts[(optno == EMACSMODE) ? VIMODE : EMACSMODE] = 0;
       
   697     }
       
   698     opts[optno] = value;
       
   699     if (optno == BANGHIST || optno == SHINSTDIN)
       
   700 	inittyptab();
       
   701     return 0;
       
   702 }
       
   703 
       
   704 /* Function to get value for special parameter `-' */
       
   705 
       
   706 /**/
       
   707 char *
       
   708 dashgetfn(UNUSED(Param pm))
       
   709 {
       
   710     static char buf[LAST_OPT - FIRST_OPT + 2];
       
   711     char *val = buf;
       
   712     int i;
       
   713 
       
   714     for(i = 0; i <= LAST_OPT - FIRST_OPT; i++) {
       
   715 	int optno = optletters[i];
       
   716 	if(optno && ((optno > 0) ? isset(optno) : unset(-optno)))
       
   717 	    *val++ = FIRST_OPT + i;
       
   718     }
       
   719     *val = '\0';
       
   720     return buf;
       
   721 }
       
   722 
       
   723 /* print options for set -o/+o */
       
   724 
       
   725 /**/
       
   726 void
       
   727 printoptionstates(int hadplus)
       
   728 {
       
   729     scanhashtable(optiontab, 1, 0, OPT_ALIAS, printoptionnodestate, hadplus);
       
   730 }
       
   731 
       
   732 /**/
       
   733 static void
       
   734 printoptionnodestate(HashNode hn, int hadplus)
       
   735 {
       
   736     Optname on = (Optname) hn;
       
   737     int optno = on->optno;
       
   738 
       
   739     if (hadplus) {
       
   740         if (defset(on) != isset(optno))
       
   741 	    printf("set -o %s%s\n", defset(on) ? "no" : "", on->nam);
       
   742     } else {
       
   743 	if (defset(on))
       
   744 	    printf("no%-19s %s\n", on->nam, isset(optno) ? "off" : "on");
       
   745 	else
       
   746 	    printf("%-21s %s\n", on->nam, isset(optno) ? "on" : "off");
       
   747     }
       
   748 }
       
   749 
       
   750 /* Print option list for --help */
       
   751 
       
   752 /**/
       
   753 void
       
   754 printoptionlist(void)
       
   755 {
       
   756     short *lp;
       
   757     char c;
       
   758 
       
   759     printf("\nNamed options:\n");
       
   760     scanhashtable(optiontab, 1, 0, OPT_ALIAS, printoptionlist_printoption, 0);
       
   761     printf("\nOption aliases:\n");
       
   762     scanhashtable(optiontab, 1, OPT_ALIAS, 0, printoptionlist_printoption, 0);
       
   763     printf("\nOption letters:\n");
       
   764     for(lp = optletters, c = FIRST_OPT; c <= LAST_OPT; lp++, c++) {
       
   765 	if(!*lp)
       
   766 	    continue;
       
   767 	printf("  -%c  ", c);
       
   768 	printoptionlist_printequiv(*lp);
       
   769     }
       
   770 }
       
   771 
       
   772 /**/
       
   773 static void
       
   774 printoptionlist_printoption(HashNode hn, UNUSED(int ignored))
       
   775 {
       
   776     Optname on = (Optname) hn;
       
   777 
       
   778     if(on->flags & OPT_ALIAS) {
       
   779 	printf("  --%-19s  ", on->nam);
       
   780 	printoptionlist_printequiv(on->optno);
       
   781     } else
       
   782 	printf("  --%s\n", on->nam);
       
   783 }
       
   784 
       
   785 /**/
       
   786 static void
       
   787 printoptionlist_printequiv(int optno)
       
   788 {
       
   789     int isneg = optno < 0;
       
   790 
       
   791     optno *= (isneg ? -1 : 1);
       
   792     printf("  equivalent to --%s%s\n", isneg ? "no-" : "", optns[optno-1].nam);
       
   793 }