]> git.ipfire.org Git - thirdparty/bash.git/blobdiff - builtins/shopt.def
Bash-4.3 patch 11
[thirdparty/bash.git] / builtins / shopt.def
index d30a869d5d98eb6a868301c1f7adaf0ea6157f14..6050a14d78a3f75e593739b2c664e326894c232b 100644 (file)
@@ -1,7 +1,7 @@
 This file is shopt.def, from which is created shopt.c.
 It implements the Bash `shopt' builtin.
 
-Copyright (C) 1994-2009 Free Software Foundation, Inc.
+Copyright (C) 1994-2012 Free Software Foundation, Inc.
 
 This file is part of GNU Bash, the Bourne Again SHell.
 
@@ -61,6 +61,10 @@ $END
 #include "common.h"
 #include "bashgetopt.h"
 
+#if defined (READLINE)
+#  include "../bashline.h"
+#endif
+
 #if defined (HISTORY)
 #  include "../bashhist.h"
 #endif
@@ -84,6 +88,8 @@ extern int gnu_error_format;
 extern int check_jobs_at_exit;
 extern int autocd;
 extern int glob_star;
+extern int glob_asciirange;
+extern int lastpipe_opt;
 
 #if defined (EXTENDED_GLOB)
 extern int extended_glob;
@@ -93,7 +99,8 @@ extern int extended_glob;
 extern int hist_verify, history_reediting, perform_hostname_completion;
 extern int no_empty_command_completion;
 extern int force_fignore;
-extern int dircomplete_spelling;
+extern int dircomplete_spelling, dircomplete_expand;
+extern int complete_fullquote;
 
 extern int enable_hostname_completion __P((int));
 #endif
@@ -112,19 +119,26 @@ extern int debugging_mode;
 
 static void shopt_error __P((char *));
 
-static int set_shellopts_after_change __P((int));
-
-static int set_compatibility_level __P((int));
+static int set_shellopts_after_change __P((char *, int));
+static int shopt_enable_hostname_completion __P((char *, int));
+static int set_compatibility_level __P((char *, int));
 
 #if defined (RESTRICTED_SHELL)
-static int set_restricted_shell __P((int));
+static int set_restricted_shell __P((char *, int));
+#endif
+
+#if defined (READLINE)
+static int shopt_set_complete_direxpand __P((char *, int));
 #endif
 
 static int shopt_login_shell;
 static int shopt_compat31;
 static int shopt_compat32;
+static int shopt_compat40;
+static int shopt_compat41;
+static int shopt_compat42;
 
-typedef int shopt_set_func_t __P((int));
+typedef int shopt_set_func_t __P((char *, int));
 
 static struct {
   char *name;
@@ -144,7 +158,12 @@ static struct {
 #endif
   { "compat31", &shopt_compat31, set_compatibility_level },
   { "compat32", &shopt_compat32, set_compatibility_level },
+  { "compat40", &shopt_compat40, set_compatibility_level },
+  { "compat41", &shopt_compat41, set_compatibility_level },
+  { "compat42", &shopt_compat41, set_compatibility_level },
 #if defined (READLINE)
+  { "complete_fullquote", &complete_fullquote, (shopt_set_func_t *)NULL},
+  { "direxpand", &dircomplete_expand, shopt_set_complete_direxpand },
   { "dirspell", &dircomplete_spelling, (shopt_set_func_t *)NULL },
 #endif
   { "dotglob", &glob_dot_filenames, (shopt_set_func_t *)NULL },
@@ -162,6 +181,7 @@ static struct {
   { "force_fignore", &force_fignore, (shopt_set_func_t *)NULL },
 #endif
   { "globstar", &glob_star, (shopt_set_func_t *)NULL },
+  { "globasciiranges", &glob_asciirange, (shopt_set_func_t *)NULL },
   { "gnu_errfmt", &gnu_error_format, (shopt_set_func_t *)NULL },
 #if defined (HISTORY)
   { "histappend", &force_append_history, (shopt_set_func_t *)NULL },
@@ -169,10 +189,11 @@ static struct {
 #if defined (READLINE)
   { "histreedit", &history_reediting, (shopt_set_func_t *)NULL },
   { "histverify", &hist_verify, (shopt_set_func_t *)NULL },
-  { "hostcomplete", &perform_hostname_completion, enable_hostname_completion },
+  { "hostcomplete", &perform_hostname_completion, shopt_enable_hostname_completion },
 #endif
   { "huponexit", &hup_on_exit, (shopt_set_func_t *)NULL },
   { "interactive_comments", &interactive_comments, set_shellopts_after_change },
+  { "lastpipe", &lastpipe_opt, (shopt_set_func_t *)NULL },
 #if defined (HISTORY)
   { "lithist", &literal_history, (shopt_set_func_t *)NULL },
 #endif
@@ -197,6 +218,10 @@ static struct {
   { (char *)0, (int *)0, (shopt_set_func_t *)NULL }
 };
 
+#define N_SHOPT_OPTIONS                (sizeof (shopt_vars) / sizeof (shopt_vars[0]))
+
+#define GET_SHOPT_OPTION_VALUE(i)      (*shopt_vars[i].value)
+
 static const char * const on = "on";
 static const char * const off = "off";
 
@@ -279,10 +304,12 @@ reset_shopt_options ()
   allow_null_glob_expansion = glob_dot_filenames = 0;
   cdable_vars = mail_warning = 0;
   no_exit_on_failed_exec = print_shift_error = 0;
-  check_hashed_filenames = cdspelling = expand_aliases = check_window_size = 0;
+  check_hashed_filenames = cdspelling = expand_aliases = 0;
 
   source_uses_path = promptvars = 1;
 
+  check_window_size = CHECKWINSIZE_DEFAULT;
+
 #if defined (EXTENDED_GLOB)
   extended_glob = 0;
 #endif
@@ -340,9 +367,11 @@ toggle_shopts (mode, list, quiet)
        {
          *shopt_vars[ind].value = mode;        /* 1 for set, 0 for unset */
          if (shopt_vars[ind].set_func)
-           (*shopt_vars[ind].set_func) (mode);
+           (*shopt_vars[ind].set_func) (shopt_vars[ind].name, mode);
        }
     }
+
+  set_bashopts ();
   return (rval);
 }
 
@@ -479,7 +508,8 @@ set_shopt_o_options (mode, list, quiet)
 /* If we set or unset interactive_comments with shopt, make sure the
    change is reflected in $SHELLOPTS. */
 static int
-set_shellopts_after_change (mode)
+set_shellopts_after_change (option_name, mode)
+     char *option_name;
      int mode;
 {
   set_shellopts ();
@@ -487,24 +517,88 @@ set_shellopts_after_change (mode)
 }
 
 static int
-set_compatibility_level (mode)
+shopt_enable_hostname_completion (option_name, mode)
+     char *option_name;
      int mode;
 {
-  /* Need to change logic here as we add more compatibility levels */
+  return (enable_hostname_completion (mode));
+}
+
+static int
+set_compatibility_level (option_name, mode)
+     char *option_name;
+     int mode;
+{
+  int ind;
+
+  /* If we're setting something, redo some of the work we did above in
+     toggle_shopt().  Unset everything and reset the appropriate option
+     based on OPTION_NAME. */
+  if (mode)
+    {
+      shopt_compat31 = shopt_compat32 = 0;
+      shopt_compat40 = shopt_compat41 = shopt_compat42 = 0;
+      ind = find_shopt (option_name);
+      *shopt_vars[ind].value = mode;
+    }
+
+  /* Then set shell_compatibility_level based on what remains */
   if (shopt_compat31)
     shell_compatibility_level = 31;
   else if (shopt_compat32)
     shell_compatibility_level = 32;
+  else if (shopt_compat40)
+    shell_compatibility_level = 40;
+  else if (shopt_compat41)
+    shell_compatibility_level = 41;
+  else if (shopt_compat42)
+    shell_compatibility_level = 42;
   else
     shell_compatibility_level = DEFAULT_COMPAT_LEVEL;
+
   return 0;
 }
 
+/* Set and unset the various compatibility options from the value of
+   shell_compatibility_level; used by sv_shcompat */
+void
+set_compatibility_opts ()
+{
+  shopt_compat31 = shopt_compat32 = shopt_compat40 = shopt_compat41 = shopt_compat42 = 0;
+  switch (shell_compatibility_level)
+    {
+      case DEFAULT_COMPAT_LEVEL:
+       break;
+      case 42:
+       shopt_compat42 = 1; break;
+      case 41:
+       shopt_compat41 = 1; break;
+      case 40:
+       shopt_compat40 = 1; break;
+      case 32:
+       shopt_compat32 = 1; break;
+      case 31:
+       shopt_compat31 = 1; break;
+    }
+}
+
+#if defined (READLINE)
+static int
+shopt_set_complete_direxpand (option_name, mode)
+     char *option_name;
+     int mode;
+{
+  set_directory_hook ();
+  return 0;
+}
+#endif
+
 #if defined (RESTRICTED_SHELL)
 /* Don't allow the value of restricted_shell to be modified. */
 
 static int
-set_restricted_shell (mode)
+set_restricted_shell (option_name, mode)
+     char *option_name;
      int mode;
 {
   static int save_restricted = -1;
@@ -519,7 +613,8 @@ set_restricted_shell (mode)
 
 /* Not static so shell.c can call it to initialize shopt_login_shell */
 int
-set_login_shell (mode)
+set_login_shell (option_name, mode)
+     char *option_name;
      int mode;
 {
   shopt_login_shell = login_shell != 0;
@@ -579,3 +674,104 @@ shopt_listopt (name, reusable)
   print_shopt (name, *shopt_vars[i].value, reusable ? PFLAG : 0);
   return (sh_chkwrite (EXECUTION_SUCCESS));
 }
+
+void
+set_bashopts ()
+{
+  char *value;
+  char tflag[N_SHOPT_OPTIONS];
+  int vsize, i, vptr, *ip, exported;
+  SHELL_VAR *v;
+
+  for (vsize = i = 0; shopt_vars[i].name; i++)
+    {
+      tflag[i] = 0;
+      if (GET_SHOPT_OPTION_VALUE (i))
+       {
+         vsize += strlen (shopt_vars[i].name) + 1;
+         tflag[i] = 1;
+       }
+    }
+
+  value = (char *)xmalloc (vsize + 1);
+
+  for (i = vptr = 0; shopt_vars[i].name; i++)
+    {
+      if (tflag[i])
+       {
+         strcpy (value + vptr, shopt_vars[i].name);
+         vptr += strlen (shopt_vars[i].name);
+         value[vptr++] = ':';
+       }
+    }
+
+  if (vptr)
+    vptr--;                    /* cut off trailing colon */
+  value[vptr] = '\0';
+
+  v = find_variable ("BASHOPTS");
+
+  /* Turn off the read-only attribute so we can bind the new value, and
+     note whether or not the variable was exported. */
+  if (v)
+    {
+      VUNSETATTR (v, att_readonly);
+      exported = exported_p (v);
+    }
+  else
+    exported = 0;
+
+  v = bind_variable ("BASHOPTS", 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
+     exported before we bound the new value. */
+  VSETATTR (v, att_readonly);
+  if (mark_modified_vars && exported == 0 && exported_p (v))
+    VUNSETATTR (v, att_exported);
+
+  free (value);
+}
+
+void
+parse_bashopts (value)
+     char *value;
+{
+  char *vname;
+  int vptr, ind;
+
+  vptr = 0;
+  while (vname = extract_colon_unit (value, &vptr))
+    {
+      ind = find_shopt (vname);
+      if (ind >= 0)
+        *shopt_vars[ind].value = 1;
+      free (vname);
+    }
+}
+
+void
+initialize_bashopts (no_bashopts)
+     int no_bashopts;
+{
+  char *temp;
+  SHELL_VAR *var;
+
+  if (no_bashopts == 0)
+    {
+      var = find_variable ("BASHOPTS");
+      /* set up any shell options we may have inherited. */
+      if (var && imported_p (var))
+       {
+         temp = (array_p (var) || assoc_p (var)) ? (char *)NULL : savestring (value_cell (var));
+         if (temp)
+           {
+             parse_bashopts (temp);
+             free (temp);
+           }
+       }
+    }
+
+  /* Set up the $BASHOPTS variable. */
+  set_bashopts ();
+}