X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=builtins%2Fset.def;h=3bb327040f99abd48224ce6cd3a5489411dfccfa;hb=95732b497d12c98613bb3c5db16b61f377501a59;hp=700b5188ab8480cacf8ceab7dda460cc1b517f05;hpb=28ef6c316f1aff914bb95ac09787a3c83c1815fd;p=platform%2Fupstream%2Fbash.git diff --git a/builtins/set.def b/builtins/set.def index 700b518..3bb3270 100644 --- a/builtins/set.def +++ b/builtins/set.def @@ -1,7 +1,7 @@ This file is set.def, from which is created set.c. It implements the "set" and "unset" builtins in Bash. -Copyright (C) 1987, 1989, 1991 Free Software Foundation, Inc. +Copyright (C) 1987-2004 Free Software Foundation, Inc. This file is part of GNU Bash, the Bourne Again SHell. @@ -33,6 +33,7 @@ $PRODUCES set.c #include #include "../bashansi.h" +#include "../bashintl.h" #include "../shell.h" #include "../flags.h" @@ -49,8 +50,10 @@ $PRODUCES set.c # include "../bashhist.h" #endif -extern int interactive; -extern int noclobber, posixly_correct, ignoreeof, eof_encountered_limit; +extern int posixly_correct, ignoreeof, eof_encountered_limit; +#if defined (HISTORY) +extern int dont_save_function_defs; +#endif #if defined (READLINE) extern int no_line_editing; #endif /* READLINE */ @@ -63,8 +66,6 @@ $SHORT_DOC set [--abefhkmnptuvxBCHP] [-o option] [arg ...] -e Exit immediately if a command exits with a non-zero status. -f Disable file name generation (globbing). -h Remember the location of commands as they are looked up. - -i Force the shell to be an "interactive" one. Interactive shells - always read `~/.bashrc' on startup. -k All assignment arguments are placed in the environment for a command, not just those that precede the command name. -m Job control is enabled. @@ -77,6 +78,8 @@ $SHORT_DOC set [--abefhkmnptuvxBCHP] [-o option] [arg ...] emacs use an emacs-style line editing interface #endif /* READLINE */ errexit same as -e + errtrace same as -E + functrace same as -T hashall same as -h #if defined (BANG_HISTORY) histexpand same as -H @@ -92,10 +95,14 @@ $SHORT_DOC set [--abefhkmnptuvxBCHP] [-o option] [arg ...] noclobber same as -C noexec same as -n noglob same as -f + nolog currently accepted but ignored notify same as -b nounset same as -u onecmd same as -t physical same as -P + pipefail the return value of a pipeline is the status of + the last command to exit with a non-zero status, + or zero if no command exited with a non-zero status posix change the behavior of bash where the default operation differs from the 1003.2 standard to match the standard @@ -118,12 +125,16 @@ $SHORT_DOC set [--abefhkmnptuvxBCHP] [-o option] [arg ...] #endif /* BRACE_EXPANSION */ -C If set, disallow existing regular files to be overwritten by redirection of output. + -E If set, the ERR trap is inherited by shell functions. #if defined (BANG_HISTORY) -H Enable ! style history substitution. This flag is on - by default. + by default when the shell is interactive. #endif /* BANG_HISTORY */ -P If set, do not follow symbolic links when executing commands such as cd which change the current directory. + -T If set, the DEBUG trap is inherited by shell functions. + - Assign any remaining arguments to the positional parameters. + The -x and -v options are turned off. Using + rather than - causes these flags to be turned off. The flags can also be used upon invocation of the shell. The current @@ -132,79 +143,90 @@ parameters and are assigned, in order, to $1, $2, .. $n. If no ARGs are given, all shell variables are printed. $END -static int set_ignoreeof (); -static int set_posix_mode (); +typedef int setopt_set_func_t __P((int, char *)); +typedef int setopt_get_func_t __P((char *)); + +static void print_minus_o_option __P((char *, int, int)); +static void print_all_shell_variables __P((void)); + +static int set_ignoreeof __P((int, char *)); +static int set_posix_mode __P((int, char *)); #if defined (READLINE) -static int set_edit_mode (); -static int get_edit_mode (); +static int set_edit_mode __P((int, char *)); +static int get_edit_mode __P((char *)); #endif #if defined (HISTORY) -static int bash_set_history (); +static int bash_set_history __P((int, char *)); #endif static char *on = "on"; static char *off = "off"; -/* An a-list used to match long options for set -o to the corresponding - option letter. */ +/* A struct used to match long options for set -o to the corresponding + option letter or internal variable. The functions can be called to + dynamically generate values. */ struct { char *name; int letter; + int *variable; + setopt_set_func_t *set_func; + setopt_get_func_t *get_func; } o_options[] = { - { "allexport", 'a' }, + { "allexport", 'a', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL }, #if defined (BRACE_EXPANSION) - { "braceexpand",'B' }, + { "braceexpand",'B', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL }, #endif - { "errexit", 'e' }, - { "hashall", 'h' }, +#if defined (READLINE) + { "emacs", '\0', (int *)NULL, set_edit_mode, get_edit_mode }, +#endif + { "errexit", 'e', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL }, + { "errtrace", 'E', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL }, + { "functrace", 'T', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL }, + { "hashall", 'h', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL }, #if defined (BANG_HISTORY) - { "histexpand", 'H' }, + { "histexpand", 'H', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL }, #endif /* BANG_HISTORY */ - { "keyword", 'k' }, - { "monitor", 'm' }, - { "noclobber", 'C' }, - { "noexec", 'n' }, - { "noglob", 'f' }, -#if defined (JOB_CONTROL) - { "notify", 'b' }, -#endif /* JOB_CONTROL */ - { "nounset", 'u' }, - { "onecmd", 't' }, - { "physical", 'P' }, - { "privileged", 'p' }, - { "verbose", 'v' }, - { "xtrace", 'x' }, - {(char *)NULL, 0 }, -}; - -struct { - char *name; - int *variable; - Function *set_func; - Function *get_func; -} binary_o_options[] = { #if defined (HISTORY) - { "history", &remember_on_history, bash_set_history, (Function *)NULL }, + { "history", '\0', &remember_on_history, bash_set_history, (setopt_get_func_t *)NULL }, +#endif + { "ignoreeof", '\0', &ignoreeof, set_ignoreeof, (setopt_get_func_t *)NULL }, + { "interactive-comments", '\0', &interactive_comments, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL }, + { "keyword", 'k', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL }, + { "monitor", 'm', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL }, + { "noclobber", 'C', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL }, + { "noexec", 'n', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL }, + { "noglob", 'f', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL }, +#if defined (HISTORY) + { "nolog", '\0', &dont_save_function_defs, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL }, #endif - { "ignoreeof", &ignoreeof, set_ignoreeof, (Function *)NULL }, - { "interactive-comments", &interactive_comments, (Function *)NULL, (Function *)NULL }, - { "posix", &posixly_correct, set_posix_mode, (Function *)NULL }, +#if defined (JOB_CONTROL) + { "notify", 'b', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL }, +#endif /* JOB_CONTROL */ + { "nounset", 'u', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL }, + { "onecmd", 't', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL }, + { "physical", 'P', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL }, + { "pipefail", '\0', &pipefail_opt, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL }, + { "posix", '\0', &posixly_correct, set_posix_mode, (setopt_get_func_t *)NULL }, + { "privileged", 'p', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL }, + { "verbose", 'v', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL }, #if defined (READLINE) - { "emacs", (int *)NULL, set_edit_mode, get_edit_mode }, - { "vi", (int *)NULL, set_edit_mode, get_edit_mode }, + { "vi", '\0', (int *)NULL, set_edit_mode, get_edit_mode }, #endif - { (char *)NULL, (int *)NULL } + { "xtrace", 'x', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL }, + {(char *)NULL, 0 , (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL }, }; +#define N_O_OPTIONS (sizeof (o_options) / sizeof (o_options[0])) + #define GET_BINARY_O_OPTION_VALUE(i, name) \ - ((binary_o_options[i].get_func) ? (*binary_o_options[i].get_func) (name) \ - : (*binary_o_options[i].variable)) + ((o_options[i].get_func) ? (*o_options[i].get_func) (name) \ + : (*o_options[i].variable)) #define SET_BINARY_O_OPTION_VALUE(i, onoff, name) \ - ((binary_o_options[i].set_func) ? (*binary_o_options[i].set_func) (onoff, name) \ - : (*binary_o_options[i].variable = (onoff == FLAG_ON))) + ((o_options[i].set_func) ? (*o_options[i].set_func) (onoff, name) \ + : (*o_options[i].variable = (onoff == FLAG_ON))) int minus_o_option_value (name) @@ -217,15 +239,15 @@ minus_o_option_value (name) { if (STREQ (name, o_options[i].name)) { - on_or_off = find_flag (o_options[i].letter); - return ((on_or_off == FLAG_UNKNOWN) ? -1 : *on_or_off); + if (o_options[i].letter) + { + on_or_off = find_flag (o_options[i].letter); + return ((on_or_off == FLAG_UNKNOWN) ? -1 : *on_or_off); + } + else + return (GET_BINARY_O_OPTION_VALUE (i, name)); } } - for (i = 0; binary_o_options[i].name; i++) - { - if (STREQ (name, binary_o_options[i].name)) - return (GET_BINARY_O_OPTION_VALUE (i, name)); - } return (-1); } @@ -250,19 +272,23 @@ list_minus_o_opts (mode, reusable) register int i; int *on_or_off, value; - for (value = i = 0; o_options[i].name; i++) - { - on_or_off = find_flag (o_options[i].letter); - if (on_or_off == FLAG_UNKNOWN) - on_or_off = &value; - if (mode == -1 || mode == *on_or_off) - print_minus_o_option (o_options[i].name, *on_or_off, reusable); - } - for (i = 0; binary_o_options[i].name; i++) + for (i = 0; o_options[i].name; i++) { - value = GET_BINARY_O_OPTION_VALUE (i, binary_o_options[i].name); - if (mode == -1 || mode == value) - print_minus_o_option (binary_o_options[i].name, value, reusable); + if (o_options[i].letter) + { + value = 0; + on_or_off = find_flag (o_options[i].letter); + if (on_or_off == FLAG_UNKNOWN) + on_or_off = &value; + if (mode == -1 || mode == *on_or_off) + print_minus_o_option (o_options[i].name, *on_or_off, reusable); + } + else + { + value = GET_BINARY_O_OPTION_VALUE (i, o_options[i].name); + if (mode == -1 || mode == value) + print_minus_o_option (o_options[i].name, value, reusable); + } } } @@ -270,16 +296,12 @@ char ** get_minus_o_opts () { char **ret; - int n, i, ind; - - n = (sizeof (o_options) / sizeof (o_options[0])) + - (sizeof (binary_o_options) / sizeof (binary_o_options[0])); - ret = alloc_array (n + 1); - for (i = ind = 0; o_options[i].name; i++) - ret[ind++] = o_options[i].name; - for (i = 0; binary_o_options[i].name; i++) - ret[ind++] = binary_o_options[i].name; - ret[ind] = (char *)NULL; + int i; + + ret = strvec_create (N_O_OPTIONS + 1); + for (i = 0; o_options[i].name; i++) + ret[i] = o_options[i].name; + ret[i] = (char *)NULL; return ret; } @@ -291,7 +313,7 @@ set_ignoreeof (on_or_off, option_name) ignoreeof = on_or_off == FLAG_ON; unbind_variable ("ignoreeof"); if (ignoreeof) - bind_variable ("IGNOREEOF", "10"); + bind_variable ("IGNOREEOF", "10", 0); else unbind_variable ("IGNOREEOF"); sv_ignoreeof ("IGNOREEOF"); @@ -307,7 +329,7 @@ set_posix_mode (on_or_off, option_name) if (posixly_correct == 0) unbind_variable ("POSIXLY_CORRECT"); else - bind_variable ("POSIXLY_CORRECT", "y"); + bind_variable ("POSIXLY_CORRECT", "y", 0); sv_strict_posix ("POSIXLY_CORRECT"); return (0); } @@ -374,38 +396,33 @@ set_minus_o_option (on_or_off, option_name) int on_or_off; char *option_name; { - int option_char; - VFunction *set_func; register int i; - for (i = 0; binary_o_options[i].name; i++) - { - if (STREQ (option_name, binary_o_options[i].name)) - { - SET_BINARY_O_OPTION_VALUE (i, on_or_off, option_name); - return (EXECUTION_SUCCESS); - } - } - - for (i = 0, option_char = -1, set_func = 0; o_options[i].name; i++) + for (i = 0; o_options[i].name; i++) { if (STREQ (option_name, o_options[i].name)) { - option_char = o_options[i].letter; - break; + if (o_options[i].letter == 0) + { + SET_BINARY_O_OPTION_VALUE (i, on_or_off, option_name); + return (EXECUTION_SUCCESS); + } + else + { + if (change_flag (o_options[i].letter, on_or_off) == FLAG_ERROR) + { + sh_invalidoptname (option_name); + return (EXECUTION_FAILURE); + } + else + return (EXECUTION_SUCCESS); + } + } } - if (option_char == -1) - { - builtin_error ("%s: unknown option name", option_name); - return (EXECUTION_FAILURE); - } - if (change_flag (option_char, on_or_off) == FLAG_ERROR) - { - bad_option (option_name); - return (EXECUTION_FAILURE); - } - return (EXECUTION_SUCCESS); + + sh_invalidoptname (option_name); + return (EXECUTION_FAILURE); } static void @@ -437,38 +454,41 @@ void set_shellopts () { char *value; + char tflag[N_O_OPTIONS]; int vsize, i, vptr, *ip, exported; SHELL_VAR *v; for (vsize = i = 0; o_options[i].name; i++) { - ip = find_flag (o_options[i].letter); - if (ip && *ip) - vsize += strlen (o_options[i].name) + 1; + tflag[i] = 0; + if (o_options[i].letter) + { + ip = find_flag (o_options[i].letter); + if (ip && *ip) + { + vsize += strlen (o_options[i].name) + 1; + tflag[i] = 1; + } + } + else if (GET_BINARY_O_OPTION_VALUE (i, o_options[i].name)) + { + vsize += strlen (o_options[i].name) + 1; + tflag[i] = 1; + } } - for (i = 0; binary_o_options[i].name; i++) - if (GET_BINARY_O_OPTION_VALUE (i, binary_o_options[i].name)) - vsize += strlen (binary_o_options[i].name) + 1; - value = xmalloc (vsize + 1); + value = (char *)xmalloc (vsize + 1); for (i = vptr = 0; o_options[i].name; i++) { - ip = find_flag (o_options[i].letter); - if (ip && *ip) + if (tflag[i]) { strcpy (value + vptr, o_options[i].name); vptr += strlen (o_options[i].name); value[vptr++] = ':'; } } - for (i = 0; binary_o_options[i].name; i++) - if (GET_BINARY_O_OPTION_VALUE (i, binary_o_options[i].name)) - { - strcpy (value + vptr, binary_o_options[i].name); - vptr += strlen (binary_o_options[i].name); - value[vptr++] = ':'; - } + if (vptr) vptr--; /* cut off trailing colon */ value[vptr] = '\0'; @@ -485,7 +505,7 @@ set_shellopts () else exported = 0; - v = bind_variable ("SHELLOPTS", value); + v = bind_variable ("SHELLOPTS", value, 0); /* Turn the read-only attribute back on, and turn off the export attribute if it was set implicitly by mark_modified_vars and SHELLOPTS was not @@ -560,6 +580,7 @@ set_builtin (list) int on_or_off, flag_name, force_assignment, opts_changed; WORD_LIST *l; register char *arg; + char s[3]; if (list == 0) { @@ -568,34 +589,19 @@ set_builtin (list) } /* Check validity of flag arguments. */ - if (*list->word->word == '-' || *list->word->word == '+') + reset_internal_getopt (); + while ((flag_name = internal_getopt (list, optflags)) != -1) { - for (l = list; l && (arg = l->word->word); l = l->next) + switch (flag_name) { - char c; - - if (arg[0] != '-' && arg[0] != '+') - break; - - /* `-' or `--' signifies end of flag arguments. */ - if (arg[0] == '-' && (!arg[1] || (arg[1] == '-' && !arg[2]))) + case '?': + builtin_usage (); + return (list_optopt == '?' ? EXECUTION_SUCCESS : EX_USAGE); + default: break; - - while (c = *++arg) - { - if (find_flag (c) == FLAG_UNKNOWN && c != 'o') - { - char s[2]; - s[0] = c; s[1] = '\0'; - bad_option (s); - if (c == '?') - builtin_usage (); - return (c == '?' ? EXECUTION_SUCCESS : EXECUTION_FAILURE); - } - } } } - + /* Do the set command. While the list consists of words starting with '-' or '+' treat them as flags, otherwise, start assigning them to $1 ... $n. */ @@ -667,11 +673,10 @@ set_builtin (list) } else if (change_flag (flag_name, on_or_off) == FLAG_ERROR) { - char opt[3]; - opt[0] = on_or_off; - opt[1] = flag_name; - opt[2] = '\0'; - bad_option (opt); + s[0] = on_or_off; + s[1] = flag_name; + s[2] = '\0'; + sh_invalidopt (s); builtin_usage (); set_shellopts (); return (EXECUTION_FAILURE); @@ -737,7 +742,7 @@ unset_builtin (list) if (unset_function && unset_variable) { - builtin_error ("cannot simultaneously unset a function and a variable"); + builtin_error (_("cannot simultaneously unset a function and a variable")); return (EXECUTION_FAILURE); } @@ -752,6 +757,7 @@ unset_builtin (list) name = list->word->word; #if defined (ARRAY_VARS) + unset_array = 0; if (!unset_function && valid_array_reference (name)) { t = strchr (name, '['); @@ -765,7 +771,7 @@ unset_builtin (list) mode when unsetting a function. */ if (((unset_function && posixly_correct) || !unset_function) && legal_identifier (name) == 0) { - builtin_error ("`%s': not a valid identifier", name); + sh_invalidid (name); NEXT_VARIABLE (); } @@ -773,14 +779,14 @@ unset_builtin (list) if (var && !unset_function && non_unsettable_p (var)) { - builtin_error ("%s: cannot unset", name); + builtin_error (_("%s: cannot unset"), name); NEXT_VARIABLE (); } /* Posix.2 says that unsetting readonly variables is an error. */ if (var && readonly_p (var)) { - builtin_error ("%s: cannot unset: readonly %s", + builtin_error (_("%s: cannot unset: readonly %s"), name, unset_function ? "function" : "variable"); NEXT_VARIABLE (); } @@ -791,26 +797,31 @@ unset_builtin (list) { if (array_p (var) == 0) { - builtin_error ("%s: not an array variable", name); + builtin_error (_("%s: not an array variable"), name); NEXT_VARIABLE (); } else - tem = unbind_array_element (var, t); + { + tem = unbind_array_element (var, t); + if (tem == -1) + any_failed++; + } } else #endif /* ARRAY_VARS */ - tem = makunbound (name, unset_function ? shell_functions : shell_variables); + tem = unset_function ? unbind_func (name) : unbind_variable (name); /* This is what Posix.2 draft 11+ says. ``If neither -f nor -v is specified, the name refers to a variable; if a variable by that name does not exist, a function by that name, if any, shall be unset.'' */ if (tem == -1 && !unset_function && !unset_variable) - tem = makunbound (name, shell_functions); + tem = unbind_func (name); + + /* SUSv3, POSIX.1-2001 say: ``Unsetting a variable or function that + was not previously set shall not be considered an error.'' */ - if (tem == -1) - any_failed++; - else if (!unset_function) + if (unset_function == 0) stupidly_hack_special_variables (name); list = list->next;