chiark / gitweb /
Commit Debian 3.0 (quilt) metadata
[bash.git] / variables.c
1 /* variables.c -- Functions for hacking shell variables. */
2
3 /* Copyright (C) 1987-2013 Free Software Foundation, Inc.
4
5    This file is part of GNU Bash, the Bourne Again SHell.
6
7    Bash is free software: you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation, either version 3 of the License, or
10    (at your option) any later version.
11
12    Bash is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with Bash.  If not, see <http://www.gnu.org/licenses/>.
19 */
20
21 #include "config.h"
22
23 #include "bashtypes.h"
24 #include "posixstat.h"
25 #include "posixtime.h"
26
27 #if defined (__QNX__)
28 #  if defined (__QNXNTO__)
29 #    include <sys/netmgr.h>
30 #  else
31 #    include <sys/vc.h>
32 #  endif /* !__QNXNTO__ */
33 #endif /* __QNX__ */
34
35 #if defined (HAVE_UNISTD_H)
36 #  include <unistd.h>
37 #endif
38
39 #include <stdio.h>
40 #include "chartypes.h"
41 #if defined (HAVE_PWD_H)
42 #  include <pwd.h>
43 #endif
44 #include "bashansi.h"
45 #include "bashintl.h"
46
47 #define NEED_XTRACE_SET_DECL
48
49 #include "shell.h"
50 #include "flags.h"
51 #include "execute_cmd.h"
52 #include "findcmd.h"
53 #include "mailcheck.h"
54 #include "input.h"
55 #include "hashcmd.h"
56 #include "pathexp.h"
57 #include "alias.h"
58 #include "jobs.h"
59
60 #include "version.h"
61
62 #include "builtins/getopt.h"
63 #include "builtins/common.h"
64 #include "builtins/builtext.h"
65
66 #if defined (READLINE)
67 #  include "bashline.h"
68 #  include <readline/readline.h>
69 #else
70 #  include <tilde/tilde.h>
71 #endif
72
73 #if defined (HISTORY)
74 #  include "bashhist.h"
75 #  include <readline/history.h>
76 #endif /* HISTORY */
77
78 #if defined (PROGRAMMABLE_COMPLETION)
79 #  include "pcomplete.h"
80 #endif
81
82 #define TEMPENV_HASH_BUCKETS    4       /* must be power of two */
83
84 #define ifsname(s)      ((s)[0] == 'I' && (s)[1] == 'F' && (s)[2] == 'S' && (s)[3] == '\0')
85
86 extern char **environ;
87
88 /* Variables used here and defined in other files. */
89 extern int posixly_correct;
90 extern int line_number, line_number_base;
91 extern int subshell_environment, indirection_level, subshell_level;
92 extern int build_version, patch_level;
93 extern int expanding_redir;
94 extern int last_command_exit_value;
95 extern char *dist_version, *release_status;
96 extern char *shell_name;
97 extern char *primary_prompt, *secondary_prompt;
98 extern char *current_host_name;
99 extern sh_builtin_func_t *this_shell_builtin;
100 extern SHELL_VAR *this_shell_function;
101 extern char *the_printed_command_except_trap;
102 extern char *this_command_name;
103 extern char *command_execution_string;
104 extern time_t shell_start_time;
105 extern int assigning_in_environment;
106 extern int executing_builtin;
107 extern int funcnest_max;
108
109 #if defined (READLINE)
110 extern int no_line_editing;
111 extern int perform_hostname_completion;
112 #endif
113
114 /* The list of shell variables that the user has created at the global
115    scope, or that came from the environment. */
116 VAR_CONTEXT *global_variables = (VAR_CONTEXT *)NULL;
117
118 /* The current list of shell variables, including function scopes */
119 VAR_CONTEXT *shell_variables = (VAR_CONTEXT *)NULL;
120
121 /* The list of shell functions that the user has created, or that came from
122    the environment. */
123 HASH_TABLE *shell_functions = (HASH_TABLE *)NULL;
124
125 #if defined (DEBUGGER)
126 /* The table of shell function definitions that the user defined or that
127    came from the environment. */
128 HASH_TABLE *shell_function_defs = (HASH_TABLE *)NULL;
129 #endif
130
131 /* The current variable context.  This is really a count of how deep into
132    executing functions we are. */
133 int variable_context = 0;
134
135 /* The set of shell assignments which are made only in the environment
136    for a single command. */
137 HASH_TABLE *temporary_env = (HASH_TABLE *)NULL;
138
139 /* Set to non-zero if an assignment error occurs while putting variables
140    into the temporary environment. */
141 int tempenv_assign_error;
142
143 /* Some funky variables which are known about specially.  Here is where
144    "$*", "$1", and all the cruft is kept. */
145 char *dollar_vars[10];
146 WORD_LIST *rest_of_args = (WORD_LIST *)NULL;
147
148 /* The value of $$. */
149 pid_t dollar_dollar_pid;
150
151 /* Non-zero means that we have to remake EXPORT_ENV. */
152 int array_needs_making = 1;
153
154 /* The number of times BASH has been executed.  This is set
155    by initialize_variables (). */
156 int shell_level = 0;
157
158 /* An array which is passed to commands as their environment.  It is
159    manufactured from the union of the initial environment and the
160    shell variables that are marked for export. */
161 char **export_env = (char **)NULL;
162 static int export_env_index;
163 static int export_env_size;
164
165 #if defined (READLINE)
166 static int winsize_assignment;          /* currently assigning to LINES or COLUMNS */
167 #endif
168
169 static HASH_TABLE *last_table_searched; /* hash_lookup sets this */
170
171 /* Some forward declarations. */
172 static void create_variable_tables __P((void));
173
174 static void set_machine_vars __P((void));
175 static void set_home_var __P((void));
176 static void set_shell_var __P((void));
177 static char *get_bash_name __P((void));
178 static void initialize_shell_level __P((void));
179 static void uidset __P((void));
180 #if defined (ARRAY_VARS)
181 static void make_vers_array __P((void));
182 #endif
183
184 static SHELL_VAR *null_assign __P((SHELL_VAR *, char *, arrayind_t, char *));
185 #if defined (ARRAY_VARS)
186 static SHELL_VAR *null_array_assign __P((SHELL_VAR *, char *, arrayind_t, char *));
187 #endif
188 static SHELL_VAR *get_self __P((SHELL_VAR *));
189
190 #if defined (ARRAY_VARS)
191 static SHELL_VAR *init_dynamic_array_var __P((char *, sh_var_value_func_t *, sh_var_assign_func_t *, int));
192 static SHELL_VAR *init_dynamic_assoc_var __P((char *, sh_var_value_func_t *, sh_var_assign_func_t *, int));
193 #endif
194
195 static SHELL_VAR *assign_seconds __P((SHELL_VAR *, char *, arrayind_t, char *));
196 static SHELL_VAR *get_seconds __P((SHELL_VAR *));
197 static SHELL_VAR *init_seconds_var __P((void));
198
199 static int brand __P((void));
200 static void sbrand __P((unsigned long));                /* set bash random number generator. */
201 static void seedrand __P((void));                       /* seed generator randomly */
202 static SHELL_VAR *assign_random __P((SHELL_VAR *, char *, arrayind_t, char *));
203 static SHELL_VAR *get_random __P((SHELL_VAR *));
204
205 static SHELL_VAR *assign_lineno __P((SHELL_VAR *, char *, arrayind_t, char *));
206 static SHELL_VAR *get_lineno __P((SHELL_VAR *));
207
208 static SHELL_VAR *assign_subshell __P((SHELL_VAR *, char *, arrayind_t, char *));
209 static SHELL_VAR *get_subshell __P((SHELL_VAR *));
210
211 static SHELL_VAR *get_bashpid __P((SHELL_VAR *));
212
213 #if defined (HISTORY)
214 static SHELL_VAR *get_histcmd __P((SHELL_VAR *));
215 #endif
216
217 #if defined (READLINE)
218 static SHELL_VAR *get_comp_wordbreaks __P((SHELL_VAR *));
219 static SHELL_VAR *assign_comp_wordbreaks __P((SHELL_VAR *, char *, arrayind_t, char *));
220 #endif
221
222 #if defined (PUSHD_AND_POPD) && defined (ARRAY_VARS)
223 static SHELL_VAR *assign_dirstack __P((SHELL_VAR *, char *, arrayind_t, char *));
224 static SHELL_VAR *get_dirstack __P((SHELL_VAR *));
225 #endif
226
227 #if defined (ARRAY_VARS)
228 static SHELL_VAR *get_groupset __P((SHELL_VAR *));
229
230 static SHELL_VAR *build_hashcmd __P((SHELL_VAR *));
231 static SHELL_VAR *get_hashcmd __P((SHELL_VAR *));
232 static SHELL_VAR *assign_hashcmd __P((SHELL_VAR *,  char *, arrayind_t, char *));
233 #  if defined (ALIAS)
234 static SHELL_VAR *build_aliasvar __P((SHELL_VAR *));
235 static SHELL_VAR *get_aliasvar __P((SHELL_VAR *));
236 static SHELL_VAR *assign_aliasvar __P((SHELL_VAR *,  char *, arrayind_t, char *));
237 #  endif
238 #endif
239
240 static SHELL_VAR *get_funcname __P((SHELL_VAR *));
241 static SHELL_VAR *init_funcname_var __P((void));
242
243 static void initialize_dynamic_variables __P((void));
244
245 static SHELL_VAR *hash_lookup __P((const char *, HASH_TABLE *));
246 static SHELL_VAR *new_shell_variable __P((const char *));
247 static SHELL_VAR *make_new_variable __P((const char *, HASH_TABLE *));
248 static SHELL_VAR *bind_variable_internal __P((const char *, char *, HASH_TABLE *, int, int));
249
250 static void dispose_variable_value __P((SHELL_VAR *));
251 static void free_variable_hash_data __P((PTR_T));
252
253 static VARLIST *vlist_alloc __P((int));
254 static VARLIST *vlist_realloc __P((VARLIST *, int));
255 static void vlist_add __P((VARLIST *, SHELL_VAR *, int));
256
257 static void flatten __P((HASH_TABLE *, sh_var_map_func_t *, VARLIST *, int));
258
259 static int qsort_var_comp __P((SHELL_VAR **, SHELL_VAR **));
260
261 static SHELL_VAR **vapply __P((sh_var_map_func_t *));
262 static SHELL_VAR **fapply __P((sh_var_map_func_t *));
263
264 static int visible_var __P((SHELL_VAR *));
265 static int visible_and_exported __P((SHELL_VAR *));
266 static int export_environment_candidate __P((SHELL_VAR *));
267 static int local_and_exported __P((SHELL_VAR *));
268 static int variable_in_context __P((SHELL_VAR *));
269 #if defined (ARRAY_VARS)
270 static int visible_array_vars __P((SHELL_VAR *));
271 #endif
272
273 static SHELL_VAR *find_nameref_at_context __P((SHELL_VAR *, VAR_CONTEXT *));
274 static SHELL_VAR *find_variable_nameref_context __P((SHELL_VAR *, VAR_CONTEXT *, VAR_CONTEXT **));
275 static SHELL_VAR *find_variable_last_nameref_context __P((SHELL_VAR *, VAR_CONTEXT *, VAR_CONTEXT **));
276
277 static SHELL_VAR *bind_tempenv_variable __P((const char *, char *));
278 static void push_temp_var __P((PTR_T));
279 static void propagate_temp_var __P((PTR_T));
280 static void dispose_temporary_env __P((sh_free_func_t *));     
281
282 static inline char *mk_env_string __P((const char *, const char *));
283 static char **make_env_array_from_var_list __P((SHELL_VAR **));
284 static char **make_var_export_array __P((VAR_CONTEXT *));
285 static char **make_func_export_array __P((void));
286 static void add_temp_array_to_env __P((char **, int, int));
287
288 static int n_shell_variables __P((void));
289 static int set_context __P((SHELL_VAR *));
290
291 static void push_func_var __P((PTR_T));
292 static void push_exported_var __P((PTR_T));
293
294 static inline int find_special_var __P((const char *));
295
296 static void
297 create_variable_tables ()
298 {
299   if (shell_variables == 0)
300     {
301       shell_variables = global_variables = new_var_context ((char *)NULL, 0);
302       shell_variables->scope = 0;
303       shell_variables->table = hash_create (0);
304     }
305
306   if (shell_functions == 0)
307     shell_functions = hash_create (0);
308
309 #if defined (DEBUGGER)
310   if (shell_function_defs == 0)
311     shell_function_defs = hash_create (0);
312 #endif
313 }
314
315 /* Initialize the shell variables from the current environment.
316    If PRIVMODE is nonzero, don't import functions from ENV or
317    parse $SHELLOPTS. */
318 void
319 initialize_shell_variables (env, privmode)
320      char **env;
321      int privmode;
322 {
323   char *name, *string, *temp_string;
324   int c, char_index, string_index, string_length, ro;
325   SHELL_VAR *temp_var;
326
327   create_variable_tables ();
328
329   for (string_index = 0; string = env[string_index++]; )
330     {
331       char_index = 0;
332       name = string;
333       while ((c = *string++) && c != '=')
334         ;
335       if (string[-1] == '=')
336         char_index = string - name - 1;
337
338       /* If there are weird things in the environment, like `=xxx' or a
339          string without an `=', just skip them. */
340       if (char_index == 0)
341         continue;
342
343       /* ASSERT(name[char_index] == '=') */
344       name[char_index] = '\0';
345       /* Now, name = env variable name, string = env variable value, and
346          char_index == strlen (name) */
347
348       temp_var = (SHELL_VAR *)NULL;
349
350 #if 0 /* Disable exporting shell functions because they are mad. */
351       /* If exported function, define it now.  Don't import functions from
352          the environment in privileged mode. */
353       if (privmode == 0 && read_but_dont_execute == 0 && STREQN ("() {", string, 4))
354         {
355           string_length = strlen (string);
356           temp_string = (char *)xmalloc (3 + string_length + char_index);
357
358           strcpy (temp_string, name);
359           temp_string[char_index] = ' ';
360           strcpy (temp_string + char_index + 1, string);
361
362           /* Don't import function names that are invalid identifiers from the
363              environment, though we still allow them to be defined as shell
364              variables. */
365           if (legal_identifier (name))
366             parse_and_execute (temp_string, name, SEVAL_NONINT|SEVAL_NOHIST|SEVAL_FUNCDEF|SEVAL_ONECMD);
367
368           if (temp_var = find_function (name))
369             {
370               VSETATTR (temp_var, (att_exported|att_imported));
371               array_needs_making = 1;
372             }
373           else
374             {
375               if (temp_var = bind_variable (name, string, 0))
376                 {
377                   VSETATTR (temp_var, (att_exported | att_imported | att_invisible));
378                   array_needs_making = 1;
379                 }
380               last_command_exit_value = 1;
381               report_error (_("error importing function definition for `%s'"), name);
382             }
383         }
384 #else
385       if (0) ; /* needed for syntax */
386 #endif
387 #if defined (ARRAY_VARS)
388 #  if ARRAY_EXPORT
389       /* Array variables may not yet be exported. */
390       else if (*string == '(' && string[1] == '[' && string[strlen (string) - 1] == ')')
391         {
392           string_length = 1;
393           temp_string = extract_array_assignment_list (string, &string_length);
394           temp_var = assign_array_from_string (name, temp_string);
395           FREE (temp_string);
396           VSETATTR (temp_var, (att_exported | att_imported));
397           array_needs_making = 1;
398         }
399 #  endif /* ARRAY_EXPORT */
400 #endif
401 #if 0
402       else if (legal_identifier (name))
403 #else
404       else
405 #endif
406         {
407           ro = 0;
408           if (posixly_correct && STREQ (name, "SHELLOPTS"))
409             {
410               temp_var = find_variable ("SHELLOPTS");
411               ro = temp_var && readonly_p (temp_var);
412               if (temp_var)
413                 VUNSETATTR (temp_var, att_readonly);
414             }
415           temp_var = bind_variable (name, string, 0);
416           if (temp_var)
417             {
418               if (legal_identifier (name))
419                 VSETATTR (temp_var, (att_exported | att_imported));
420               else
421                 VSETATTR (temp_var, (att_exported | att_imported | att_invisible));
422               if (ro)
423                 VSETATTR (temp_var, att_readonly);
424               array_needs_making = 1;
425             }
426         }
427
428       name[char_index] = '=';
429       /* temp_var can be NULL if it was an exported function with a syntax
430          error (a different bug, but it still shouldn't dump core). */
431       if (temp_var && function_p (temp_var) == 0)       /* XXX not yet */
432         {
433           CACHE_IMPORTSTR (temp_var, name);
434         }
435     }
436
437   set_pwd ();
438
439   /* Set up initial value of $_ */
440   temp_var = set_if_not ("_", dollar_vars[0]);
441
442   /* Remember this pid. */
443   dollar_dollar_pid = getpid ();
444
445   /* Now make our own defaults in case the vars that we think are
446      important are missing. */
447   temp_var = set_if_not ("PATH", DEFAULT_PATH_VALUE);
448 #if 0
449   set_auto_export (temp_var);   /* XXX */
450 #endif
451
452   temp_var = set_if_not ("TERM", "dumb");
453 #if 0
454   set_auto_export (temp_var);   /* XXX */
455 #endif
456
457 #if defined (__QNX__)
458   /* set node id -- don't import it from the environment */
459   {
460     char node_name[22];
461 #  if defined (__QNXNTO__)
462     netmgr_ndtostr(ND2S_LOCAL_STR, ND_LOCAL_NODE, node_name, sizeof(node_name));
463 #  else
464     qnx_nidtostr (getnid (), node_name, sizeof (node_name));
465 #  endif
466     temp_var = bind_variable ("NODE", node_name, 0);
467     set_auto_export (temp_var);
468   }
469 #endif
470
471   /* set up the prompts. */
472   if (interactive_shell)
473     {
474 #if defined (PROMPT_STRING_DECODE)
475       set_if_not ("PS1", primary_prompt);
476 #else
477       if (current_user.uid == -1)
478         get_current_user_info ();
479       set_if_not ("PS1", current_user.euid == 0 ? "# " : primary_prompt);
480 #endif
481       set_if_not ("PS2", secondary_prompt);
482     }
483   set_if_not ("PS4", "+ ");
484
485   /* Don't allow IFS to be imported from the environment. */
486   temp_var = bind_variable ("IFS", " \t\n", 0);
487   setifs (temp_var);
488
489   /* Magic machine types.  Pretty convenient. */
490   set_machine_vars ();
491
492   /* Default MAILCHECK for interactive shells.  Defer the creation of a
493      default MAILPATH until the startup files are read, because MAIL
494      names a mail file if MAILPATH is not set, and we should provide a
495      default only if neither is set. */
496   if (interactive_shell)
497     {
498       temp_var = set_if_not ("MAILCHECK", posixly_correct ? "600" : "60");
499       VSETATTR (temp_var, att_integer);
500     }
501
502   /* Do some things with shell level. */
503   initialize_shell_level ();
504
505   set_ppid ();
506
507   /* Initialize the `getopts' stuff. */
508   temp_var = bind_variable ("OPTIND", "1", 0);
509   VSETATTR (temp_var, att_integer);
510   getopts_reset (0);
511   bind_variable ("OPTERR", "1", 0);
512   sh_opterr = 1;
513
514   if (login_shell == 1 && posixly_correct == 0)
515     set_home_var ();
516
517   /* Get the full pathname to THIS shell, and set the BASH variable
518      to it. */
519   name = get_bash_name ();
520   temp_var = bind_variable ("BASH", name, 0);
521   free (name);
522
523   /* Make the exported environment variable SHELL be the user's login
524      shell.  Note that the `tset' command looks at this variable
525      to determine what style of commands to output; if it ends in "csh",
526      then C-shell commands are output, else Bourne shell commands. */
527   set_shell_var ();
528
529   /* Make a variable called BASH_VERSION which contains the version info. */
530   bind_variable ("BASH_VERSION", shell_version_string (), 0);
531 #if defined (ARRAY_VARS)
532   make_vers_array ();
533 #endif
534
535   if (command_execution_string)
536     bind_variable ("BASH_EXECUTION_STRING", command_execution_string, 0);
537
538   /* Find out if we're supposed to be in Posix.2 mode via an
539      environment variable. */
540   temp_var = find_variable ("POSIXLY_CORRECT");
541   if (!temp_var)
542     temp_var = find_variable ("POSIX_PEDANTIC");
543   if (temp_var && imported_p (temp_var))
544     sv_strict_posix (temp_var->name);
545
546 #if defined (HISTORY)
547   /* Set history variables to defaults, and then do whatever we would
548      do if the variable had just been set.  Do this only in the case
549      that we are remembering commands on the history list. */
550   if (remember_on_history)
551     {
552       name = bash_tilde_expand (posixly_correct ? "~/.sh_history" : "~/.bash_history", 0);
553
554       set_if_not ("HISTFILE", name);
555       free (name);
556     }
557 #endif /* HISTORY */
558
559   /* Seed the random number generator. */
560   seedrand ();
561
562   /* Handle some "special" variables that we may have inherited from a
563      parent shell. */
564   if (interactive_shell)
565     {
566       temp_var = find_variable ("IGNOREEOF");
567       if (!temp_var)
568         temp_var = find_variable ("ignoreeof");
569       if (temp_var && imported_p (temp_var))
570         sv_ignoreeof (temp_var->name);
571     }
572
573 #if defined (HISTORY)
574   if (interactive_shell && remember_on_history)
575     {
576       sv_history_control ("HISTCONTROL");
577       sv_histignore ("HISTIGNORE");
578       sv_histtimefmt ("HISTTIMEFORMAT");
579     }
580 #endif /* HISTORY */
581
582 #if defined (READLINE) && defined (STRICT_POSIX)
583   /* POSIXLY_CORRECT will only be 1 here if the shell was compiled
584      -DSTRICT_POSIX */
585   if (interactive_shell && posixly_correct && no_line_editing == 0)
586     rl_prefer_env_winsize = 1;
587 #endif /* READLINE && STRICT_POSIX */
588
589      /*
590       * 24 October 2001
591       *
592       * I'm tired of the arguing and bug reports.  Bash now leaves SSH_CLIENT
593       * and SSH2_CLIENT alone.  I'm going to rely on the shell_level check in
594       * isnetconn() to avoid running the startup files more often than wanted.
595       * That will, of course, only work if the user's login shell is bash, so
596       * I've made that behavior conditional on SSH_SOURCE_BASHRC being defined
597       * in config-top.h.
598       */
599 #if 0
600   temp_var = find_variable ("SSH_CLIENT");
601   if (temp_var && imported_p (temp_var))
602     {
603       VUNSETATTR (temp_var, att_exported);
604       array_needs_making = 1;
605     }
606   temp_var = find_variable ("SSH2_CLIENT");
607   if (temp_var && imported_p (temp_var))
608     {
609       VUNSETATTR (temp_var, att_exported);
610       array_needs_making = 1;
611     }
612 #endif
613
614   /* Get the user's real and effective user ids. */
615   uidset ();
616
617   temp_var = find_variable ("BASH_XTRACEFD");
618   if (temp_var && imported_p (temp_var))
619     sv_xtracefd (temp_var->name);
620
621   /* Initialize the dynamic variables, and seed their values. */
622   initialize_dynamic_variables ();
623 }
624
625 /* **************************************************************** */
626 /*                                                                  */
627 /*           Setting values for special shell variables             */
628 /*                                                                  */
629 /* **************************************************************** */
630
631 static void
632 set_machine_vars ()
633 {
634   SHELL_VAR *temp_var;
635
636   temp_var = set_if_not ("HOSTTYPE", HOSTTYPE);
637   temp_var = set_if_not ("OSTYPE", OSTYPE);
638   temp_var = set_if_not ("MACHTYPE", MACHTYPE);
639
640   temp_var = set_if_not ("HOSTNAME", current_host_name);
641 }
642
643 /* Set $HOME to the information in the password file if we didn't get
644    it from the environment. */
645
646 /* This function is not static so the tilde and readline libraries can
647    use it. */
648 char *
649 sh_get_home_dir ()
650 {
651   if (current_user.home_dir == 0)
652     get_current_user_info ();
653   return current_user.home_dir;
654 }
655
656 static void
657 set_home_var ()
658 {
659   SHELL_VAR *temp_var;
660
661   temp_var = find_variable ("HOME");
662   if (temp_var == 0)
663     temp_var = bind_variable ("HOME", sh_get_home_dir (), 0);
664 #if 0
665   VSETATTR (temp_var, att_exported);
666 #endif
667 }
668
669 /* Set $SHELL to the user's login shell if it is not already set.  Call
670    get_current_user_info if we haven't already fetched the shell. */
671 static void
672 set_shell_var ()
673 {
674   SHELL_VAR *temp_var;
675
676   temp_var = find_variable ("SHELL");
677   if (temp_var == 0)
678     {
679       if (current_user.shell == 0)
680         get_current_user_info ();
681       temp_var = bind_variable ("SHELL", current_user.shell, 0);
682     }
683 #if 0
684   VSETATTR (temp_var, att_exported);
685 #endif
686 }
687
688 static char *
689 get_bash_name ()
690 {
691   char *name;
692
693   if ((login_shell == 1) && RELPATH(shell_name))
694     {
695       if (current_user.shell == 0)
696         get_current_user_info ();
697       name = savestring (current_user.shell);
698     }
699   else if (ABSPATH(shell_name))
700     name = savestring (shell_name);
701   else if (shell_name[0] == '.' && shell_name[1] == '/')
702     {
703       /* Fast path for common case. */
704       char *cdir;
705       int len;
706
707       cdir = get_string_value ("PWD");
708       if (cdir)
709         {
710           len = strlen (cdir);
711           name = (char *)xmalloc (len + strlen (shell_name) + 1);
712           strcpy (name, cdir);
713           strcpy (name + len, shell_name + 1);
714         }
715       else
716         name = savestring (shell_name);
717     }
718   else
719     {
720       char *tname;
721       int s;
722
723       tname = find_user_command (shell_name);
724
725       if (tname == 0)
726         {
727           /* Try the current directory.  If there is not an executable
728              there, just punt and use the login shell. */
729           s = file_status (shell_name);
730           if (s & FS_EXECABLE)
731             {
732               tname = make_absolute (shell_name, get_string_value ("PWD"));
733               if (*shell_name == '.')
734                 {
735                   name = sh_canonpath (tname, PATH_CHECKDOTDOT|PATH_CHECKEXISTS);
736                   if (name == 0)
737                     name = tname;
738                   else
739                     free (tname);
740                 }
741              else
742                 name = tname;
743             }
744           else
745             {
746               if (current_user.shell == 0)
747                 get_current_user_info ();
748               name = savestring (current_user.shell);
749             }
750         }
751       else
752         {
753           name = full_pathname (tname);
754           free (tname);
755         }
756     }
757
758   return (name);
759 }
760
761 void
762 adjust_shell_level (change)
763      int change;
764 {
765   char new_level[5], *old_SHLVL;
766   intmax_t old_level;
767   SHELL_VAR *temp_var;
768
769   old_SHLVL = get_string_value ("SHLVL");
770   if (old_SHLVL == 0 || *old_SHLVL == '\0' || legal_number (old_SHLVL, &old_level) == 0)
771     old_level = 0;
772
773   shell_level = old_level + change;
774   if (shell_level < 0)
775     shell_level = 0;
776   else if (shell_level > 1000)
777     {
778       internal_warning (_("shell level (%d) too high, resetting to 1"), shell_level);
779       shell_level = 1;
780     }
781
782   /* We don't need the full generality of itos here. */
783   if (shell_level < 10)
784     {
785       new_level[0] = shell_level + '0';
786       new_level[1] = '\0';
787     }
788   else if (shell_level < 100)
789     {
790       new_level[0] = (shell_level / 10) + '0';
791       new_level[1] = (shell_level % 10) + '0';
792       new_level[2] = '\0';
793     }
794   else if (shell_level < 1000)
795     {
796       new_level[0] = (shell_level / 100) + '0';
797       old_level = shell_level % 100;
798       new_level[1] = (old_level / 10) + '0';
799       new_level[2] = (old_level % 10) + '0';
800       new_level[3] = '\0';
801     }
802
803   temp_var = bind_variable ("SHLVL", new_level, 0);
804   set_auto_export (temp_var);
805 }
806
807 static void
808 initialize_shell_level ()
809 {
810   adjust_shell_level (1);
811 }
812
813 /* If we got PWD from the environment, update our idea of the current
814    working directory.  In any case, make sure that PWD exists before
815    checking it.  It is possible for getcwd () to fail on shell startup,
816    and in that case, PWD would be undefined.  If this is an interactive
817    login shell, see if $HOME is the current working directory, and if
818    that's not the same string as $PWD, set PWD=$HOME. */
819
820 void
821 set_pwd ()
822 {
823   SHELL_VAR *temp_var, *home_var;
824   char *temp_string, *home_string;
825
826   home_var = find_variable ("HOME");
827   home_string = home_var ? value_cell (home_var) : (char *)NULL;
828
829   temp_var = find_variable ("PWD");
830   if (temp_var && imported_p (temp_var) &&
831       (temp_string = value_cell (temp_var)) &&
832       same_file (temp_string, ".", (struct stat *)NULL, (struct stat *)NULL))
833     set_working_directory (temp_string);
834   else if (home_string && interactive_shell && login_shell &&
835            same_file (home_string, ".", (struct stat *)NULL, (struct stat *)NULL))
836     {
837       set_working_directory (home_string);
838       temp_var = bind_variable ("PWD", home_string, 0);
839       set_auto_export (temp_var);
840     }
841   else
842     {
843       temp_string = get_working_directory ("shell-init");
844       if (temp_string)
845         {
846           temp_var = bind_variable ("PWD", temp_string, 0);
847           set_auto_export (temp_var);
848           free (temp_string);
849         }
850     }
851
852   /* According to the Single Unix Specification, v2, $OLDPWD is an
853      `environment variable' and therefore should be auto-exported.
854      Make a dummy invisible variable for OLDPWD, and mark it as exported. */
855   temp_var = bind_variable ("OLDPWD", (char *)NULL, 0);
856   VSETATTR (temp_var, (att_exported | att_invisible));
857 }
858
859 /* Make a variable $PPID, which holds the pid of the shell's parent.  */
860 void
861 set_ppid ()
862 {
863   char namebuf[INT_STRLEN_BOUND(pid_t) + 1], *name;
864   SHELL_VAR *temp_var;
865
866   name = inttostr (getppid (), namebuf, sizeof(namebuf));
867   temp_var = find_variable ("PPID");
868   if (temp_var)
869     VUNSETATTR (temp_var, (att_readonly | att_exported));
870   temp_var = bind_variable ("PPID", name, 0);
871   VSETATTR (temp_var, (att_readonly | att_integer));
872 }
873
874 static void
875 uidset ()
876 {
877   char buff[INT_STRLEN_BOUND(uid_t) + 1], *b;
878   register SHELL_VAR *v;
879
880   b = inttostr (current_user.uid, buff, sizeof (buff));
881   v = find_variable ("UID");
882   if (v == 0)
883     {
884       v = bind_variable ("UID", b, 0);
885       VSETATTR (v, (att_readonly | att_integer));
886     }
887
888   if (current_user.euid != current_user.uid)
889     b = inttostr (current_user.euid, buff, sizeof (buff));
890
891   v = find_variable ("EUID");
892   if (v == 0)
893     {
894       v = bind_variable ("EUID", b, 0);
895       VSETATTR (v, (att_readonly | att_integer));
896     }
897 }
898
899 #if defined (ARRAY_VARS)
900 static void
901 make_vers_array ()
902 {
903   SHELL_VAR *vv;
904   ARRAY *av;
905   char *s, d[32], b[INT_STRLEN_BOUND(int) + 1];
906
907   unbind_variable ("BASH_VERSINFO");
908
909   vv = make_new_array_variable ("BASH_VERSINFO");
910   av = array_cell (vv);
911   strcpy (d, dist_version);
912   s = strchr (d, '.');
913   if (s)
914     *s++ = '\0';
915   array_insert (av, 0, d);
916   array_insert (av, 1, s);
917   s = inttostr (patch_level, b, sizeof (b));
918   array_insert (av, 2, s);
919   s = inttostr (build_version, b, sizeof (b));
920   array_insert (av, 3, s);
921   array_insert (av, 4, release_status);
922   array_insert (av, 5, MACHTYPE);
923
924   VSETATTR (vv, att_readonly);
925 }
926 #endif /* ARRAY_VARS */
927
928 /* Set the environment variables $LINES and $COLUMNS in response to
929    a window size change. */
930 void
931 sh_set_lines_and_columns (lines, cols)
932      int lines, cols;
933 {
934   char val[INT_STRLEN_BOUND(int) + 1], *v;
935
936 #if defined (READLINE)
937   /* If we are currently assigning to LINES or COLUMNS, don't do anything. */
938   if (winsize_assignment)
939     return;
940 #endif
941
942   v = inttostr (lines, val, sizeof (val));
943   bind_variable ("LINES", v, 0);
944
945   v = inttostr (cols, val, sizeof (val));
946   bind_variable ("COLUMNS", v, 0);
947 }
948
949 /* **************************************************************** */
950 /*                                                                  */
951 /*                 Printing variables and values                    */
952 /*                                                                  */
953 /* **************************************************************** */
954
955 /* Print LIST (a list of shell variables) to stdout in such a way that
956    they can be read back in. */
957 void
958 print_var_list (list)
959      register SHELL_VAR **list;
960 {
961   register int i;
962   register SHELL_VAR *var;
963
964   for (i = 0; list && (var = list[i]); i++)
965     if (invisible_p (var) == 0)
966       print_assignment (var);
967 }
968
969 /* Print LIST (a list of shell functions) to stdout in such a way that
970    they can be read back in. */
971 void
972 print_func_list (list)
973      register SHELL_VAR **list;
974 {
975   register int i;
976   register SHELL_VAR *var;
977
978   for (i = 0; list && (var = list[i]); i++)
979     {
980       printf ("%s ", var->name);
981       print_var_function (var);
982       printf ("\n");
983     }
984 }
985       
986 /* Print the value of a single SHELL_VAR.  No newline is
987    output, but the variable is printed in such a way that
988    it can be read back in. */
989 void
990 print_assignment (var)
991      SHELL_VAR *var;
992 {
993   if (var_isset (var) == 0)
994     return;
995
996   if (function_p (var))
997     {
998       printf ("%s", var->name);
999       print_var_function (var);
1000       printf ("\n");
1001     }
1002 #if defined (ARRAY_VARS)
1003   else if (array_p (var))
1004     print_array_assignment (var, 0);
1005   else if (assoc_p (var))
1006     print_assoc_assignment (var, 0);
1007 #endif /* ARRAY_VARS */
1008   else
1009     {
1010       printf ("%s=", var->name);
1011       print_var_value (var, 1);
1012       printf ("\n");
1013     }
1014 }
1015
1016 /* Print the value cell of VAR, a shell variable.  Do not print
1017    the name, nor leading/trailing newline.  If QUOTE is non-zero,
1018    and the value contains shell metacharacters, quote the value
1019    in such a way that it can be read back in. */
1020 void
1021 print_var_value (var, quote)
1022      SHELL_VAR *var;
1023      int quote;
1024 {
1025   char *t;
1026
1027   if (var_isset (var) == 0)
1028     return;
1029
1030   if (quote && posixly_correct == 0 && ansic_shouldquote (value_cell (var)))
1031     {
1032       t = ansic_quote (value_cell (var), 0, (int *)0);
1033       printf ("%s", t);
1034       free (t);
1035     }
1036   else if (quote && sh_contains_shell_metas (value_cell (var)))
1037     {
1038       t = sh_single_quote (value_cell (var));
1039       printf ("%s", t);
1040       free (t);
1041     }
1042   else
1043     printf ("%s", value_cell (var));
1044 }
1045
1046 /* Print the function cell of VAR, a shell variable.  Do not
1047    print the name, nor leading/trailing newline. */
1048 void
1049 print_var_function (var)
1050      SHELL_VAR *var;
1051 {
1052   char *x;
1053
1054   if (function_p (var) && var_isset (var))
1055     {
1056       x = named_function_string ((char *)NULL, function_cell(var), FUNC_MULTILINE|FUNC_EXTERNAL);
1057       printf ("%s", x);
1058     }
1059 }
1060
1061 /* **************************************************************** */
1062 /*                                                                  */
1063 /*                      Dynamic Variables                           */
1064 /*                                                                  */
1065 /* **************************************************************** */
1066
1067 /* DYNAMIC VARIABLES
1068
1069    These are variables whose values are generated anew each time they are
1070    referenced.  These are implemented using a pair of function pointers
1071    in the struct variable: assign_func, which is called from bind_variable
1072    and, if arrays are compiled into the shell, some of the functions in
1073    arrayfunc.c, and dynamic_value, which is called from find_variable.
1074
1075    assign_func is called from bind_variable_internal, if
1076    bind_variable_internal discovers that the variable being assigned to
1077    has such a function.  The function is called as
1078         SHELL_VAR *temp = (*(entry->assign_func)) (entry, value, ind)
1079    and the (SHELL_VAR *)temp is returned as the value of bind_variable.  It
1080    is usually ENTRY (self).  IND is an index for an array variable, and
1081    unused otherwise.
1082
1083    dynamic_value is called from find_variable_internal to return a `new'
1084    value for the specified dynamic varible.  If this function is NULL,
1085    the variable is treated as a `normal' shell variable.  If it is not,
1086    however, then this function is called like this:
1087         tempvar = (*(var->dynamic_value)) (var);
1088
1089    Sometimes `tempvar' will replace the value of `var'.  Other times, the
1090    shell will simply use the string value.  Pretty object-oriented, huh?
1091
1092    Be warned, though: if you `unset' a special variable, it loses its
1093    special meaning, even if you subsequently set it.
1094
1095    The special assignment code would probably have been better put in
1096    subst.c: do_assignment_internal, in the same style as
1097    stupidly_hack_special_variables, but I wanted the changes as
1098    localized as possible.  */
1099
1100 #define INIT_DYNAMIC_VAR(var, val, gfunc, afunc) \
1101   do \
1102     { \
1103       v = bind_variable (var, (val), 0); \
1104       v->dynamic_value = gfunc; \
1105       v->assign_func = afunc; \
1106     } \
1107   while (0)
1108
1109 #define INIT_DYNAMIC_ARRAY_VAR(var, gfunc, afunc) \
1110   do \
1111     { \
1112       v = make_new_array_variable (var); \
1113       v->dynamic_value = gfunc; \
1114       v->assign_func = afunc; \
1115     } \
1116   while (0)
1117
1118 #define INIT_DYNAMIC_ASSOC_VAR(var, gfunc, afunc) \
1119   do \
1120     { \
1121       v = make_new_assoc_variable (var); \
1122       v->dynamic_value = gfunc; \
1123       v->assign_func = afunc; \
1124     } \
1125   while (0)
1126
1127 static SHELL_VAR *
1128 null_assign (self, value, unused, key)
1129      SHELL_VAR *self;
1130      char *value;
1131      arrayind_t unused;
1132      char *key;
1133 {
1134   return (self);
1135 }
1136
1137 #if defined (ARRAY_VARS)
1138 static SHELL_VAR *
1139 null_array_assign (self, value, ind, key)
1140      SHELL_VAR *self;
1141      char *value;
1142      arrayind_t ind;
1143      char *key;
1144 {
1145   return (self);
1146 }
1147 #endif
1148
1149 /* Degenerate `dynamic_value' function; just returns what's passed without
1150    manipulation. */
1151 static SHELL_VAR *
1152 get_self (self)
1153      SHELL_VAR *self;
1154 {
1155   return (self);
1156 }
1157
1158 #if defined (ARRAY_VARS)
1159 /* A generic dynamic array variable initializer.  Initialize array variable
1160    NAME with dynamic value function GETFUNC and assignment function SETFUNC. */
1161 static SHELL_VAR *
1162 init_dynamic_array_var (name, getfunc, setfunc, attrs)
1163      char *name;
1164      sh_var_value_func_t *getfunc;
1165      sh_var_assign_func_t *setfunc;
1166      int attrs;
1167 {
1168   SHELL_VAR *v;
1169
1170   v = find_variable (name);
1171   if (v)
1172     return (v);
1173   INIT_DYNAMIC_ARRAY_VAR (name, getfunc, setfunc);
1174   if (attrs)
1175     VSETATTR (v, attrs);
1176   return v;
1177 }
1178
1179 static SHELL_VAR *
1180 init_dynamic_assoc_var (name, getfunc, setfunc, attrs)
1181      char *name;
1182      sh_var_value_func_t *getfunc;
1183      sh_var_assign_func_t *setfunc;
1184      int attrs;
1185 {
1186   SHELL_VAR *v;
1187
1188   v = find_variable (name);
1189   if (v)
1190     return (v);
1191   INIT_DYNAMIC_ASSOC_VAR (name, getfunc, setfunc);
1192   if (attrs)
1193     VSETATTR (v, attrs);
1194   return v;
1195 }
1196 #endif
1197
1198 /* The value of $SECONDS.  This is the number of seconds since shell
1199    invocation, or, the number of seconds since the last assignment + the
1200    value of the last assignment. */
1201 static intmax_t seconds_value_assigned;
1202
1203 static SHELL_VAR *
1204 assign_seconds (self, value, unused, key)
1205      SHELL_VAR *self;
1206      char *value;
1207      arrayind_t unused;
1208      char *key;
1209 {
1210   if (legal_number (value, &seconds_value_assigned) == 0)
1211     seconds_value_assigned = 0;
1212   shell_start_time = NOW;
1213   return (self);
1214 }
1215
1216 static SHELL_VAR *
1217 get_seconds (var)
1218      SHELL_VAR *var;
1219 {
1220   time_t time_since_start;
1221   char *p;
1222
1223   time_since_start = NOW - shell_start_time;
1224   p = itos(seconds_value_assigned + time_since_start);
1225
1226   FREE (value_cell (var));
1227
1228   VSETATTR (var, att_integer);
1229   var_setvalue (var, p);
1230   return (var);
1231 }
1232
1233 static SHELL_VAR *
1234 init_seconds_var ()
1235 {
1236   SHELL_VAR *v;
1237
1238   v = find_variable ("SECONDS");
1239   if (v)
1240     {
1241       if (legal_number (value_cell(v), &seconds_value_assigned) == 0)
1242         seconds_value_assigned = 0;
1243     }
1244   INIT_DYNAMIC_VAR ("SECONDS", (v ? value_cell (v) : (char *)NULL), get_seconds, assign_seconds);
1245   return v;      
1246 }
1247      
1248 /* The random number seed.  You can change this by setting RANDOM. */
1249 static unsigned long rseed = 1;
1250 static int last_random_value;
1251 static int seeded_subshell = 0;
1252
1253 /* A linear congruential random number generator based on the example
1254    one in the ANSI C standard.  This one isn't very good, but a more
1255    complicated one is overkill. */
1256
1257 /* Returns a pseudo-random number between 0 and 32767. */
1258 static int
1259 brand ()
1260 {
1261   /* From "Random number generators: good ones are hard to find",
1262      Park and Miller, Communications of the ACM, vol. 31, no. 10,
1263      October 1988, p. 1195. filtered through FreeBSD */
1264   long h, l;
1265
1266   /* Can't seed with 0. */
1267   if (rseed == 0)
1268     rseed = 123459876;
1269   h = rseed / 127773;
1270   l = rseed % 127773;
1271   rseed = 16807 * l - 2836 * h;
1272 #if 0
1273   if (rseed < 0)
1274     rseed += 0x7fffffff;
1275 #endif
1276   return ((unsigned int)(rseed & 32767));       /* was % 32768 */
1277 }
1278
1279 /* Set the random number generator seed to SEED. */
1280 static void
1281 sbrand (seed)
1282      unsigned long seed;
1283 {
1284   rseed = seed;
1285   last_random_value = 0;
1286 }
1287
1288 static void
1289 seedrand ()
1290 {
1291   struct timeval tv;
1292
1293   gettimeofday (&tv, NULL);
1294   sbrand (tv.tv_sec ^ tv.tv_usec ^ getpid ());
1295 }
1296
1297 static SHELL_VAR *
1298 assign_random (self, value, unused, key)
1299      SHELL_VAR *self;
1300      char *value;
1301      arrayind_t unused;
1302      char *key;
1303 {
1304   sbrand (strtoul (value, (char **)NULL, 10));
1305   if (subshell_environment)
1306     seeded_subshell = getpid ();
1307   return (self);
1308 }
1309
1310 int
1311 get_random_number ()
1312 {
1313   int rv, pid;
1314
1315   /* Reset for command and process substitution. */
1316   pid = getpid ();
1317   if (subshell_environment && seeded_subshell != pid)
1318     {
1319       seedrand ();
1320       seeded_subshell = pid;
1321     }
1322
1323   do
1324     rv = brand ();
1325   while (rv == last_random_value);
1326   return rv;
1327 }
1328
1329 static SHELL_VAR *
1330 get_random (var)
1331      SHELL_VAR *var;
1332 {
1333   int rv;
1334   char *p;
1335
1336   rv = get_random_number ();
1337   last_random_value = rv;
1338   p = itos (rv);
1339
1340   FREE (value_cell (var));
1341
1342   VSETATTR (var, att_integer);
1343   var_setvalue (var, p);
1344   return (var);
1345 }
1346
1347 static SHELL_VAR *
1348 assign_lineno (var, value, unused, key)
1349      SHELL_VAR *var;
1350      char *value;
1351      arrayind_t unused;
1352      char *key;
1353 {
1354   intmax_t new_value;
1355
1356   if (value == 0 || *value == '\0' || legal_number (value, &new_value) == 0)
1357     new_value = 0;
1358   line_number = line_number_base = new_value;
1359   return var;
1360 }
1361
1362 /* Function which returns the current line number. */
1363 static SHELL_VAR *
1364 get_lineno (var)
1365      SHELL_VAR *var;
1366 {
1367   char *p;
1368   int ln;
1369
1370   ln = executing_line_number ();
1371   p = itos (ln);
1372   FREE (value_cell (var));
1373   var_setvalue (var, p);
1374   return (var);
1375 }
1376
1377 static SHELL_VAR *
1378 assign_subshell (var, value, unused, key)
1379      SHELL_VAR *var;
1380      char *value;
1381      arrayind_t unused;
1382      char *key;
1383 {
1384   intmax_t new_value;
1385
1386   if (value == 0 || *value == '\0' || legal_number (value, &new_value) == 0)
1387     new_value = 0;
1388   subshell_level = new_value;
1389   return var;
1390 }
1391
1392 static SHELL_VAR *
1393 get_subshell (var)
1394      SHELL_VAR *var;
1395 {
1396   char *p;
1397
1398   p = itos (subshell_level);
1399   FREE (value_cell (var));
1400   var_setvalue (var, p);
1401   return (var);
1402 }
1403
1404 static SHELL_VAR *
1405 get_bashpid (var)
1406      SHELL_VAR *var;
1407 {
1408   int pid;
1409   char *p;
1410
1411   pid = getpid ();
1412   p = itos (pid);
1413
1414   FREE (value_cell (var));
1415   VSETATTR (var, att_integer|att_readonly);
1416   var_setvalue (var, p);
1417   return (var);
1418 }
1419
1420 static SHELL_VAR *
1421 get_bash_command (var)
1422      SHELL_VAR *var;
1423 {
1424   char *p;
1425
1426   if (the_printed_command_except_trap)
1427     p = savestring (the_printed_command_except_trap);
1428   else
1429     {
1430       p = (char *)xmalloc (1);
1431       p[0] = '\0';
1432     }
1433   FREE (value_cell (var));
1434   var_setvalue (var, p);
1435   return (var);
1436 }
1437
1438 #if defined (HISTORY)
1439 static SHELL_VAR *
1440 get_histcmd (var)
1441      SHELL_VAR *var;
1442 {
1443   char *p;
1444
1445   p = itos (history_number ());
1446   FREE (value_cell (var));
1447   var_setvalue (var, p);
1448   return (var);
1449 }
1450 #endif
1451
1452 #if defined (READLINE)
1453 /* When this function returns, VAR->value points to malloced memory. */
1454 static SHELL_VAR *
1455 get_comp_wordbreaks (var)
1456      SHELL_VAR *var;
1457 {
1458   /* If we don't have anything yet, assign a default value. */
1459   if (rl_completer_word_break_characters == 0 && bash_readline_initialized == 0)
1460     enable_hostname_completion (perform_hostname_completion);
1461
1462   FREE (value_cell (var));
1463   var_setvalue (var, savestring (rl_completer_word_break_characters));
1464
1465   return (var);
1466 }
1467
1468 /* When this function returns, rl_completer_word_break_characters points to
1469    malloced memory. */
1470 static SHELL_VAR *
1471 assign_comp_wordbreaks (self, value, unused, key)
1472      SHELL_VAR *self;
1473      char *value;
1474      arrayind_t unused;
1475      char *key;
1476 {
1477   if (rl_completer_word_break_characters &&
1478       rl_completer_word_break_characters != rl_basic_word_break_characters)
1479     free (rl_completer_word_break_characters);
1480
1481   rl_completer_word_break_characters = savestring (value);
1482   return self;
1483 }
1484 #endif /* READLINE */
1485
1486 #if defined (PUSHD_AND_POPD) && defined (ARRAY_VARS)
1487 static SHELL_VAR *
1488 assign_dirstack (self, value, ind, key)
1489      SHELL_VAR *self;
1490      char *value;
1491      arrayind_t ind;
1492      char *key;
1493 {
1494   set_dirstack_element (ind, 1, value);
1495   return self;
1496 }
1497
1498 static SHELL_VAR *
1499 get_dirstack (self)
1500      SHELL_VAR *self;
1501 {
1502   ARRAY *a;
1503   WORD_LIST *l;
1504
1505   l = get_directory_stack (0);
1506   a = array_from_word_list (l);
1507   array_dispose (array_cell (self));
1508   dispose_words (l);
1509   var_setarray (self, a);
1510   return self;
1511 }
1512 #endif /* PUSHD AND POPD && ARRAY_VARS */
1513
1514 #if defined (ARRAY_VARS)
1515 /* We don't want to initialize the group set with a call to getgroups()
1516    unless we're asked to, but we only want to do it once. */
1517 static SHELL_VAR *
1518 get_groupset (self)
1519      SHELL_VAR *self;
1520 {
1521   register int i;
1522   int ng;
1523   ARRAY *a;
1524   static char **group_set = (char **)NULL;
1525
1526   if (group_set == 0)
1527     {
1528       group_set = get_group_list (&ng);
1529       a = array_cell (self);
1530       for (i = 0; i < ng; i++)
1531         array_insert (a, i, group_set[i]);
1532     }
1533   return (self);
1534 }
1535
1536 static SHELL_VAR *
1537 build_hashcmd (self)
1538      SHELL_VAR *self;
1539 {
1540   HASH_TABLE *h;
1541   int i;
1542   char *k, *v;
1543   BUCKET_CONTENTS *item;
1544
1545   h = assoc_cell (self);
1546   if (h)
1547     assoc_dispose (h);
1548
1549   if (hashed_filenames == 0 || HASH_ENTRIES (hashed_filenames) == 0)
1550     {
1551       var_setvalue (self, (char *)NULL);
1552       return self;
1553     }
1554
1555   h = assoc_create (hashed_filenames->nbuckets);
1556   for (i = 0; i < hashed_filenames->nbuckets; i++)
1557     {
1558       for (item = hash_items (i, hashed_filenames); item; item = item->next)
1559         {
1560           k = savestring (item->key);
1561           v = pathdata(item)->path;
1562           assoc_insert (h, k, v);
1563         }
1564     }
1565
1566   var_setvalue (self, (char *)h);
1567   return self;
1568 }
1569
1570 static SHELL_VAR *
1571 get_hashcmd (self)
1572      SHELL_VAR *self;
1573 {
1574   build_hashcmd (self);
1575   return (self);
1576 }
1577
1578 static SHELL_VAR *
1579 assign_hashcmd (self, value, ind, key)
1580      SHELL_VAR *self;
1581      char *value;
1582      arrayind_t ind;
1583      char *key;
1584 {
1585   phash_insert (key, value, 0, 0);
1586   return (build_hashcmd (self));
1587 }
1588
1589 #if defined (ALIAS)
1590 static SHELL_VAR *
1591 build_aliasvar (self)
1592      SHELL_VAR *self;
1593 {
1594   HASH_TABLE *h;
1595   int i;
1596   char *k, *v;
1597   BUCKET_CONTENTS *item;
1598
1599   h = assoc_cell (self);
1600   if (h)
1601     assoc_dispose (h);
1602
1603   if (aliases == 0 || HASH_ENTRIES (aliases) == 0)
1604     {
1605       var_setvalue (self, (char *)NULL);
1606       return self;
1607     }
1608
1609   h = assoc_create (aliases->nbuckets);
1610   for (i = 0; i < aliases->nbuckets; i++)
1611     {
1612       for (item = hash_items (i, aliases); item; item = item->next)
1613         {
1614           k = savestring (item->key);
1615           v = ((alias_t *)(item->data))->value;
1616           assoc_insert (h, k, v);
1617         }
1618     }
1619
1620   var_setvalue (self, (char *)h);
1621   return self;
1622 }
1623
1624 static SHELL_VAR *
1625 get_aliasvar (self)
1626      SHELL_VAR *self;
1627 {
1628   build_aliasvar (self);
1629   return (self);
1630 }
1631
1632 static SHELL_VAR *
1633 assign_aliasvar (self, value, ind, key)
1634      SHELL_VAR *self;
1635      char *value;
1636      arrayind_t ind;
1637      char *key;
1638 {
1639   add_alias (key, value);
1640   return (build_aliasvar (self));
1641 }
1642 #endif /* ALIAS */
1643
1644 #endif /* ARRAY_VARS */
1645
1646 /* If ARRAY_VARS is not defined, this just returns the name of any
1647    currently-executing function.  If we have arrays, it's a call stack. */
1648 static SHELL_VAR *
1649 get_funcname (self)
1650      SHELL_VAR *self;
1651 {
1652 #if ! defined (ARRAY_VARS)
1653   char *t;
1654   if (variable_context && this_shell_function)
1655     {
1656       FREE (value_cell (self));
1657       t = savestring (this_shell_function->name);
1658       var_setvalue (self, t);
1659     }
1660 #endif
1661   return (self);
1662 }
1663
1664 void
1665 make_funcname_visible (on_or_off)
1666      int on_or_off;
1667 {
1668   SHELL_VAR *v;
1669
1670   v = find_variable ("FUNCNAME");
1671   if (v == 0 || v->dynamic_value == 0)
1672     return;
1673
1674   if (on_or_off)
1675     VUNSETATTR (v, att_invisible);
1676   else
1677     VSETATTR (v, att_invisible);
1678 }
1679
1680 static SHELL_VAR *
1681 init_funcname_var ()
1682 {
1683   SHELL_VAR *v;
1684
1685   v = find_variable ("FUNCNAME");
1686   if (v)
1687     return v;
1688 #if defined (ARRAY_VARS)
1689   INIT_DYNAMIC_ARRAY_VAR ("FUNCNAME", get_funcname, null_array_assign);
1690 #else
1691   INIT_DYNAMIC_VAR ("FUNCNAME", (char *)NULL, get_funcname, null_assign);
1692 #endif
1693   VSETATTR (v, att_invisible|att_noassign);
1694   return v;
1695 }
1696
1697 static void
1698 initialize_dynamic_variables ()
1699 {
1700   SHELL_VAR *v;
1701
1702   v = init_seconds_var ();
1703
1704   INIT_DYNAMIC_VAR ("BASH_COMMAND", (char *)NULL, get_bash_command, (sh_var_assign_func_t *)NULL);
1705   INIT_DYNAMIC_VAR ("BASH_SUBSHELL", (char *)NULL, get_subshell, assign_subshell);
1706
1707   INIT_DYNAMIC_VAR ("RANDOM", (char *)NULL, get_random, assign_random);
1708   VSETATTR (v, att_integer);
1709   INIT_DYNAMIC_VAR ("LINENO", (char *)NULL, get_lineno, assign_lineno);
1710   VSETATTR (v, att_integer);
1711
1712   INIT_DYNAMIC_VAR ("BASHPID", (char *)NULL, get_bashpid, null_assign);
1713   VSETATTR (v, att_integer|att_readonly);
1714
1715 #if defined (HISTORY)
1716   INIT_DYNAMIC_VAR ("HISTCMD", (char *)NULL, get_histcmd, (sh_var_assign_func_t *)NULL);
1717   VSETATTR (v, att_integer);
1718 #endif
1719
1720 #if defined (READLINE)
1721   INIT_DYNAMIC_VAR ("COMP_WORDBREAKS", (char *)NULL, get_comp_wordbreaks, assign_comp_wordbreaks);
1722 #endif
1723
1724 #if defined (PUSHD_AND_POPD) && defined (ARRAY_VARS)
1725   v = init_dynamic_array_var ("DIRSTACK", get_dirstack, assign_dirstack, 0);
1726 #endif /* PUSHD_AND_POPD && ARRAY_VARS */
1727
1728 #if defined (ARRAY_VARS)
1729   v = init_dynamic_array_var ("GROUPS", get_groupset, null_array_assign, att_noassign);
1730
1731 #  if defined (DEBUGGER)
1732   v = init_dynamic_array_var ("BASH_ARGC", get_self, null_array_assign, att_noassign|att_nounset);
1733   v = init_dynamic_array_var ("BASH_ARGV", get_self, null_array_assign, att_noassign|att_nounset);
1734 #  endif /* DEBUGGER */
1735   v = init_dynamic_array_var ("BASH_SOURCE", get_self, null_array_assign, att_noassign|att_nounset);
1736   v = init_dynamic_array_var ("BASH_LINENO", get_self, null_array_assign, att_noassign|att_nounset);
1737
1738   v = init_dynamic_assoc_var ("BASH_CMDS", get_hashcmd, assign_hashcmd, att_nofree);
1739 #  if defined (ALIAS)
1740   v = init_dynamic_assoc_var ("BASH_ALIASES", get_aliasvar, assign_aliasvar, att_nofree);
1741 #  endif
1742 #endif
1743
1744   v = init_funcname_var ();
1745 }
1746
1747 /* **************************************************************** */
1748 /*                                                                  */
1749 /*              Retrieving variables and values                     */
1750 /*                                                                  */
1751 /* **************************************************************** */
1752
1753 /* How to get a pointer to the shell variable or function named NAME.
1754    HASHED_VARS is a pointer to the hash table containing the list
1755    of interest (either variables or functions). */
1756
1757 static SHELL_VAR *
1758 hash_lookup (name, hashed_vars)
1759      const char *name;
1760      HASH_TABLE *hashed_vars;
1761 {
1762   BUCKET_CONTENTS *bucket;
1763
1764   bucket = hash_search (name, hashed_vars, 0);
1765   /* If we find the name in HASHED_VARS, set LAST_TABLE_SEARCHED to that
1766      table. */
1767   if (bucket)
1768     last_table_searched = hashed_vars;
1769   return (bucket ? (SHELL_VAR *)bucket->data : (SHELL_VAR *)NULL);
1770 }
1771
1772 SHELL_VAR *
1773 var_lookup (name, vcontext)
1774      const char *name;
1775      VAR_CONTEXT *vcontext;
1776 {
1777   VAR_CONTEXT *vc;
1778   SHELL_VAR *v;
1779
1780   v = (SHELL_VAR *)NULL;
1781   for (vc = vcontext; vc; vc = vc->down)
1782     if (v = hash_lookup (name, vc->table))
1783       break;
1784
1785   return v;
1786 }
1787
1788 /* Look up the variable entry named NAME.  If SEARCH_TEMPENV is non-zero,
1789    then also search the temporarily built list of exported variables.
1790    The lookup order is:
1791         temporary_env
1792         shell_variables list
1793 */
1794
1795 SHELL_VAR *
1796 find_variable_internal (name, force_tempenv)
1797      const char *name;
1798      int force_tempenv;
1799 {
1800   SHELL_VAR *var;
1801   int search_tempenv;
1802   VAR_CONTEXT *vc;
1803
1804   var = (SHELL_VAR *)NULL;
1805
1806   /* If explicitly requested, first look in the temporary environment for
1807      the variable.  This allows constructs such as "foo=x eval 'echo $foo'"
1808      to get the `exported' value of $foo.  This happens if we are executing
1809      a function or builtin, or if we are looking up a variable in a
1810      "subshell environment". */
1811   search_tempenv = force_tempenv || (expanding_redir == 0 && subshell_environment);
1812
1813   if (search_tempenv && temporary_env)          
1814     var = hash_lookup (name, temporary_env);
1815
1816   vc = shell_variables;
1817 #if 0
1818 if (search_tempenv == 0 && /* (subshell_environment & SUBSHELL_COMSUB) && */
1819     expanding_redir &&
1820     (this_shell_builtin == eval_builtin || this_shell_builtin == command_builtin))
1821   {
1822   itrace("find_variable_internal: search_tempenv == 0: skipping VC_BLTNENV");
1823   while (vc && (vc->flags & VC_BLTNENV))
1824     vc = vc->down;
1825   if (vc == 0)
1826     vc = shell_variables;
1827   }
1828 #endif
1829
1830   if (var == 0)
1831     var = var_lookup (name, vc);
1832
1833   if (var == 0)
1834     return ((SHELL_VAR *)NULL);
1835
1836   return (var->dynamic_value ? (*(var->dynamic_value)) (var) : var);
1837 }
1838
1839 /* Look up and resolve the chain of nameref variables starting at V all the
1840    way to NULL or non-nameref. */
1841 SHELL_VAR *
1842 find_variable_nameref (v)
1843      SHELL_VAR *v;
1844 {
1845   int level;
1846   char *newname;
1847   SHELL_VAR *orig, *oldv;
1848
1849   level = 0;
1850   orig = v;
1851   while (v && nameref_p (v))
1852     {
1853       level++;
1854       if (level > NAMEREF_MAX)
1855         return ((SHELL_VAR *)0);        /* error message here? */
1856       newname = nameref_cell (v);
1857       if (newname == 0 || *newname == '\0')
1858         return ((SHELL_VAR *)0);
1859       oldv = v;
1860       v = find_variable_internal (newname, (expanding_redir == 0 && (assigning_in_environment || executing_builtin)));
1861       if (v == orig || v == oldv)
1862         {
1863           internal_warning (_("%s: circular name reference"), orig->name);
1864           return ((SHELL_VAR *)0);
1865         }
1866     }
1867   return v;
1868 }
1869
1870 /* Resolve the chain of nameref variables for NAME.  XXX - could change later */
1871 SHELL_VAR *
1872 find_variable_last_nameref (name)
1873      const char *name;
1874 {
1875   SHELL_VAR *v, *nv;
1876   char *newname;
1877   int level;
1878
1879   nv = v = find_variable_noref (name);
1880   level = 0;
1881   while (v && nameref_p (v))
1882     {
1883       level++;
1884       if (level > NAMEREF_MAX)
1885         return ((SHELL_VAR *)0);        /* error message here? */
1886       newname = nameref_cell (v);
1887       if (newname == 0 || *newname == '\0')
1888         return ((SHELL_VAR *)0);
1889       nv = v;
1890       v = find_variable_internal (newname, (expanding_redir == 0 && (assigning_in_environment || executing_builtin)));
1891     }
1892   return nv;
1893 }
1894
1895 /* Resolve the chain of nameref variables for NAME.  XXX - could change later */
1896 SHELL_VAR *
1897 find_global_variable_last_nameref (name)
1898      const char *name;
1899 {
1900   SHELL_VAR *v, *nv;
1901   char *newname;
1902   int level;
1903
1904   nv = v = find_global_variable_noref (name);
1905   level = 0;
1906   while (v && nameref_p (v))
1907     {
1908       level++;
1909       if (level > NAMEREF_MAX)
1910         return ((SHELL_VAR *)0);        /* error message here? */
1911       newname = nameref_cell (v);
1912       if (newname == 0 || *newname == '\0')
1913         return ((SHELL_VAR *)0);
1914       nv = v;
1915       v = find_global_variable_noref (newname);
1916     }
1917   return nv;
1918 }
1919
1920 static SHELL_VAR *
1921 find_nameref_at_context (v, vc)
1922      SHELL_VAR *v;
1923      VAR_CONTEXT *vc;
1924 {
1925   SHELL_VAR *nv, *nv2;
1926   VAR_CONTEXT *nvc;
1927   char *newname;
1928   int level;
1929
1930   nv = v;
1931   level = 1;
1932   while (nv && nameref_p (nv))
1933     {
1934       level++;
1935       if (level > NAMEREF_MAX)
1936         return ((SHELL_VAR *)NULL);
1937       newname = nameref_cell (nv);
1938       if (newname == 0 || *newname == '\0')
1939         return ((SHELL_VAR *)NULL);      
1940       nv2 = hash_lookup (newname, vc->table);
1941       if (nv2 == 0)
1942         break;
1943       nv = nv2;
1944     }
1945   return nv;
1946 }
1947
1948 /* Do nameref resolution from the VC, which is the local context for some
1949    function or builtin, `up' the chain to the global variables context.  If
1950    NVCP is not NULL, return the variable context where we finally ended the
1951    nameref resolution (so the bind_variable_internal can use the correct
1952    variable context and hash table). */
1953 static SHELL_VAR *
1954 find_variable_nameref_context (v, vc, nvcp)
1955      SHELL_VAR *v;
1956      VAR_CONTEXT *vc;
1957      VAR_CONTEXT **nvcp;
1958 {
1959   SHELL_VAR *nv, *nv2;
1960   VAR_CONTEXT *nvc;
1961
1962   /* Look starting at the current context all the way `up' */
1963   for (nv = v, nvc = vc; nvc; nvc = nvc->down)
1964     {
1965       nv2 = find_nameref_at_context (nv, nvc);
1966       if (nv2 == 0)
1967         continue;
1968       nv = nv2;
1969       if (*nvcp)
1970         *nvcp = nvc;
1971       if (nameref_p (nv) == 0)
1972         break;
1973     }
1974   return (nameref_p (nv) ? (SHELL_VAR *)NULL : nv);
1975 }
1976
1977 /* Do nameref resolution from the VC, which is the local context for some
1978    function or builtin, `up' the chain to the global variables context.  If
1979    NVCP is not NULL, return the variable context where we finally ended the
1980    nameref resolution (so the bind_variable_internal can use the correct
1981    variable context and hash table). */
1982 static SHELL_VAR *
1983 find_variable_last_nameref_context (v, vc, nvcp)
1984      SHELL_VAR *v;
1985      VAR_CONTEXT *vc;
1986      VAR_CONTEXT **nvcp;
1987 {
1988   SHELL_VAR *nv, *nv2;
1989   VAR_CONTEXT *nvc;
1990
1991   /* Look starting at the current context all the way `up' */
1992   for (nv = v, nvc = vc; nvc; nvc = nvc->down)
1993     {
1994       nv2 = find_nameref_at_context (nv, nvc);
1995       if (nv2 == 0)
1996         continue;
1997       nv = nv2;
1998       if (*nvcp)
1999         *nvcp = nvc;
2000     }
2001   return (nameref_p (nv) ? nv : (SHELL_VAR *)NULL);
2002 }
2003
2004 /* Find a variable, forcing a search of the temporary environment first */
2005 SHELL_VAR *
2006 find_variable_tempenv (name)
2007      const char *name;
2008 {
2009   SHELL_VAR *var;
2010
2011   var = find_variable_internal (name, 1);
2012   if (var && nameref_p (var))
2013     var = find_variable_nameref (var);
2014   return (var);
2015 }
2016
2017 /* Find a variable, not forcing a search of the temporary environment first */
2018 SHELL_VAR *
2019 find_variable_notempenv (name)
2020      const char *name;
2021 {
2022   SHELL_VAR *var;
2023
2024   var = find_variable_internal (name, 0);
2025   if (var && nameref_p (var))
2026     var = find_variable_nameref (var);
2027   return (var);
2028 }
2029
2030 SHELL_VAR *
2031 find_global_variable (name)
2032      const char *name;
2033 {
2034   SHELL_VAR *var;
2035
2036   var = var_lookup (name, global_variables);
2037   if (var && nameref_p (var))
2038     var = find_variable_nameref (var);
2039
2040   if (var == 0)
2041     return ((SHELL_VAR *)NULL);
2042
2043   return (var->dynamic_value ? (*(var->dynamic_value)) (var) : var);
2044 }
2045
2046 SHELL_VAR *
2047 find_global_variable_noref (name)
2048      const char *name;
2049 {
2050   SHELL_VAR *var;
2051
2052   var = var_lookup (name, global_variables);
2053
2054   if (var == 0)
2055     return ((SHELL_VAR *)NULL);
2056
2057   return (var->dynamic_value ? (*(var->dynamic_value)) (var) : var);
2058 }
2059
2060 SHELL_VAR *
2061 find_shell_variable (name)
2062      const char *name;
2063 {
2064   SHELL_VAR *var;
2065
2066   var = var_lookup (name, shell_variables);
2067   if (var && nameref_p (var))
2068     var = find_variable_nameref (var);
2069
2070   if (var == 0)
2071     return ((SHELL_VAR *)NULL);
2072
2073   return (var->dynamic_value ? (*(var->dynamic_value)) (var) : var);
2074 }
2075
2076 /* Look up the variable entry named NAME.  Returns the entry or NULL. */
2077 SHELL_VAR *
2078 find_variable (name)
2079      const char *name;
2080 {
2081   SHELL_VAR *v;
2082
2083   last_table_searched = 0;
2084   v = find_variable_internal (name, (expanding_redir == 0 && (assigning_in_environment || executing_builtin)));
2085   if (v && nameref_p (v))
2086     v = find_variable_nameref (v);
2087   return v;
2088 }
2089
2090 SHELL_VAR *
2091 find_variable_noref (name)
2092      const char *name;
2093 {
2094   SHELL_VAR *v;
2095
2096   v = find_variable_internal (name, (expanding_redir == 0 && (assigning_in_environment || executing_builtin)));
2097   return v;
2098 }
2099
2100 /* Look up the function entry whose name matches STRING.
2101    Returns the entry or NULL. */
2102 SHELL_VAR *
2103 find_function (name)
2104      const char *name;
2105 {
2106   return (hash_lookup (name, shell_functions));
2107 }
2108
2109 /* Find the function definition for the shell function named NAME.  Returns
2110    the entry or NULL. */
2111 FUNCTION_DEF *
2112 find_function_def (name)
2113      const char *name;
2114 {
2115 #if defined (DEBUGGER)
2116   return ((FUNCTION_DEF *)hash_lookup (name, shell_function_defs));
2117 #else
2118   return ((FUNCTION_DEF *)0);
2119 #endif
2120 }
2121
2122 /* Return the value of VAR.  VAR is assumed to have been the result of a
2123    lookup without any subscript, if arrays are compiled into the shell. */
2124 char *
2125 get_variable_value (var)
2126      SHELL_VAR *var;
2127 {
2128   if (var == 0)
2129     return ((char *)NULL);
2130 #if defined (ARRAY_VARS)
2131   else if (array_p (var))
2132     return (array_reference (array_cell (var), 0));
2133   else if (assoc_p (var))
2134     return (assoc_reference (assoc_cell (var), "0"));
2135 #endif
2136   else
2137     return (value_cell (var));
2138 }
2139
2140 /* Return the string value of a variable.  Return NULL if the variable
2141    doesn't exist.  Don't cons a new string.  This is a potential memory
2142    leak if the variable is found in the temporary environment.  Since
2143    functions and variables have separate name spaces, returns NULL if
2144    var_name is a shell function only. */
2145 char *
2146 get_string_value (var_name)
2147      const char *var_name;
2148 {
2149   SHELL_VAR *var;
2150
2151   var = find_variable (var_name);
2152   return ((var) ? get_variable_value (var) : (char *)NULL);
2153 }
2154
2155 /* This is present for use by the tilde and readline libraries. */
2156 char *
2157 sh_get_env_value (v)
2158      const char *v;
2159 {
2160   return get_string_value (v);
2161 }
2162
2163 /* **************************************************************** */
2164 /*                                                                  */
2165 /*                Creating and setting variables                    */
2166 /*                                                                  */
2167 /* **************************************************************** */
2168
2169 /* Set NAME to VALUE if NAME has no value. */
2170 SHELL_VAR *
2171 set_if_not (name, value)
2172      char *name, *value;
2173 {
2174   SHELL_VAR *v;
2175
2176   if (shell_variables == 0)
2177     create_variable_tables ();
2178
2179   v = find_variable (name);
2180   if (v == 0)
2181     v = bind_variable_internal (name, value, global_variables->table, HASH_NOSRCH, 0);
2182   return (v);
2183 }
2184
2185 /* Create a local variable referenced by NAME. */
2186 SHELL_VAR *
2187 make_local_variable (name)
2188      const char *name;
2189 {
2190   SHELL_VAR *new_var, *old_var;
2191   VAR_CONTEXT *vc;
2192   int was_tmpvar;
2193   char *tmp_value;
2194
2195   /* local foo; local foo;  is a no-op. */
2196   old_var = find_variable (name);
2197   if (old_var && local_p (old_var) && old_var->context == variable_context)
2198     return (old_var);
2199
2200   was_tmpvar = old_var && tempvar_p (old_var);
2201   /* If we're making a local variable in a shell function, the temporary env
2202      has already been merged into the function's variable context stack.  We
2203      can assume that a temporary var in the same context appears in the same
2204      VAR_CONTEXT and can safely be returned without creating a new variable
2205      (which results in duplicate names in the same VAR_CONTEXT->table */
2206   /* We can't just test tmpvar_p because variables in the temporary env given
2207      to a shell function appear in the function's local variable VAR_CONTEXT
2208      but retain their tempvar attribute.  We want temporary variables that are
2209      found in temporary_env, hence the test for last_table_searched, which is
2210      set in hash_lookup and only (so far) checked here. */
2211   if (was_tmpvar && old_var->context == variable_context && last_table_searched != temporary_env)
2212     {
2213       VUNSETATTR (old_var, att_invisible);
2214       return (old_var);
2215     }
2216   if (was_tmpvar)
2217     tmp_value = value_cell (old_var);
2218
2219   for (vc = shell_variables; vc; vc = vc->down)
2220     if (vc_isfuncenv (vc) && vc->scope == variable_context)
2221       break;
2222
2223   if (vc == 0)
2224     {
2225       internal_error (_("make_local_variable: no function context at current scope"));
2226       return ((SHELL_VAR *)NULL);
2227     }
2228   else if (vc->table == 0)
2229     vc->table = hash_create (TEMPENV_HASH_BUCKETS);
2230
2231   /* Since this is called only from the local/declare/typeset code, we can
2232      call builtin_error here without worry (of course, it will also work
2233      for anything that sets this_command_name).  Variables with the `noassign'
2234      attribute may not be made local.  The test against old_var's context
2235      level is to disallow local copies of readonly global variables (since I
2236      believe that this could be a security hole).  Readonly copies of calling
2237      function local variables are OK. */
2238   if (old_var && (noassign_p (old_var) ||
2239                  (readonly_p (old_var) && old_var->context == 0)))
2240     {
2241       if (readonly_p (old_var))
2242         sh_readonly (name);
2243       else if (noassign_p (old_var))
2244         builtin_error (_("%s: variable may not be assigned value"), name);
2245 #if 0
2246       /* Let noassign variables through with a warning */
2247       if (readonly_p (old_var))
2248 #endif
2249         return ((SHELL_VAR *)NULL);
2250     }
2251
2252   if (old_var == 0)
2253     new_var = make_new_variable (name, vc->table);
2254   else
2255     {
2256       new_var = make_new_variable (name, vc->table);
2257
2258       /* If we found this variable in one of the temporary environments,
2259          inherit its value.  Watch to see if this causes problems with
2260          things like `x=4 local x'. XXX - see above for temporary env
2261          variables with the same context level as variable_context */
2262       /* XXX - we should only do this if the variable is not an array. */
2263       if (was_tmpvar)
2264         var_setvalue (new_var, savestring (tmp_value));
2265
2266       new_var->attributes = exported_p (old_var) ? att_exported : 0;
2267     }
2268
2269   vc->flags |= VC_HASLOCAL;
2270
2271   new_var->context = variable_context;
2272   VSETATTR (new_var, att_local);
2273
2274   if (ifsname (name))
2275     setifs (new_var);
2276
2277   if (was_tmpvar == 0)
2278     VSETATTR (new_var, att_invisible);  /* XXX */
2279   return (new_var);
2280 }
2281
2282 /* Create a new shell variable with name NAME. */
2283 static SHELL_VAR *
2284 new_shell_variable (name)
2285      const char *name;
2286 {
2287   SHELL_VAR *entry;
2288
2289   entry = (SHELL_VAR *)xmalloc (sizeof (SHELL_VAR));
2290
2291   entry->name = savestring (name);
2292   var_setvalue (entry, (char *)NULL);
2293   CLEAR_EXPORTSTR (entry);
2294
2295   entry->dynamic_value = (sh_var_value_func_t *)NULL;
2296   entry->assign_func = (sh_var_assign_func_t *)NULL;
2297
2298   entry->attributes = 0;
2299
2300   /* Always assume variables are to be made at toplevel!
2301      make_local_variable has the responsibility of changing the
2302      variable context. */
2303   entry->context = 0;
2304
2305   return (entry);
2306 }
2307
2308 /* Create a new shell variable with name NAME and add it to the hash table
2309    TABLE. */
2310 static SHELL_VAR *
2311 make_new_variable (name, table)
2312      const char *name;
2313      HASH_TABLE *table;
2314 {
2315   SHELL_VAR *entry;
2316   BUCKET_CONTENTS *elt;
2317
2318   entry = new_shell_variable (name);
2319
2320   /* Make sure we have a shell_variables hash table to add to. */
2321   if (shell_variables == 0)
2322     create_variable_tables ();
2323
2324   elt = hash_insert (savestring (name), table, HASH_NOSRCH);
2325   elt->data = (PTR_T)entry;
2326
2327   return entry;
2328 }
2329
2330 #if defined (ARRAY_VARS)
2331 SHELL_VAR *
2332 make_new_array_variable (name)
2333      char *name;
2334 {
2335   SHELL_VAR *entry;
2336   ARRAY *array;
2337
2338   entry = make_new_variable (name, global_variables->table);
2339   array = array_create ();
2340
2341   var_setarray (entry, array);
2342   VSETATTR (entry, att_array);
2343   return entry;
2344 }
2345
2346 SHELL_VAR *
2347 make_local_array_variable (name, assoc_ok)
2348      char *name;
2349      int assoc_ok;
2350 {
2351   SHELL_VAR *var;
2352   ARRAY *array;
2353
2354   var = make_local_variable (name);
2355   if (var == 0 || array_p (var) || (assoc_ok && assoc_p (var)))
2356     return var;
2357
2358   array = array_create ();
2359
2360   dispose_variable_value (var);
2361   var_setarray (var, array);
2362   VSETATTR (var, att_array);
2363   return var;
2364 }
2365
2366 SHELL_VAR *
2367 make_new_assoc_variable (name)
2368      char *name;
2369 {
2370   SHELL_VAR *entry;
2371   HASH_TABLE *hash;
2372
2373   entry = make_new_variable (name, global_variables->table);
2374   hash = assoc_create (0);
2375
2376   var_setassoc (entry, hash);
2377   VSETATTR (entry, att_assoc);
2378   return entry;
2379 }
2380
2381 SHELL_VAR *
2382 make_local_assoc_variable (name)
2383      char *name;
2384 {
2385   SHELL_VAR *var;
2386   HASH_TABLE *hash;
2387
2388   var = make_local_variable (name);
2389   if (var == 0 || assoc_p (var))
2390     return var;
2391
2392   dispose_variable_value (var);
2393   hash = assoc_create (0);
2394
2395   var_setassoc (var, hash);
2396   VSETATTR (var, att_assoc);
2397   return var;
2398 }
2399 #endif
2400
2401 char *
2402 make_variable_value (var, value, flags)
2403      SHELL_VAR *var;
2404      char *value;
2405      int flags;
2406 {
2407   char *retval, *oval;
2408   intmax_t lval, rval;
2409   int expok, olen, op;
2410
2411   /* If this variable has had its type set to integer (via `declare -i'),
2412      then do expression evaluation on it and store the result.  The
2413      functions in expr.c (evalexp()) and bind_int_variable() are responsible
2414      for turning off the integer flag if they don't want further
2415      evaluation done. */
2416   if (integer_p (var))
2417     {
2418       if (flags & ASS_APPEND)
2419         {
2420           oval = value_cell (var);
2421           lval = evalexp (oval, &expok);        /* ksh93 seems to do this */
2422           if (expok == 0)
2423             {
2424               top_level_cleanup ();
2425               jump_to_top_level (DISCARD);
2426             }
2427         }
2428       rval = evalexp (value, &expok);
2429       if (expok == 0)
2430         {
2431           top_level_cleanup ();
2432           jump_to_top_level (DISCARD);
2433         }
2434       /* This can be fooled if the variable's value changes while evaluating
2435          `rval'.  We can change it if we move the evaluation of lval to here. */
2436       if (flags & ASS_APPEND)
2437         rval += lval;
2438       retval = itos (rval);
2439     }
2440 #if defined (CASEMOD_ATTRS)
2441   else if (capcase_p (var) || uppercase_p (var) || lowercase_p (var))
2442     {
2443       if (flags & ASS_APPEND)
2444         {
2445           oval = get_variable_value (var);
2446           if (oval == 0)        /* paranoia */
2447             oval = "";
2448           olen = STRLEN (oval);
2449           retval = (char *)xmalloc (olen + (value ? STRLEN (value) : 0) + 1);
2450           strcpy (retval, oval);
2451           if (value)
2452             strcpy (retval+olen, value);
2453         }
2454       else if (*value)
2455         retval = savestring (value);
2456       else
2457         {
2458           retval = (char *)xmalloc (1);
2459           retval[0] = '\0';
2460         }
2461       op = capcase_p (var) ? CASE_CAPITALIZE
2462                          : (uppercase_p (var) ? CASE_UPPER : CASE_LOWER);
2463       oval = sh_modcase (retval, (char *)0, op);
2464       free (retval);
2465       retval = oval;
2466     }
2467 #endif /* CASEMOD_ATTRS */
2468   else if (value)
2469     {
2470       if (flags & ASS_APPEND)
2471         {
2472           oval = get_variable_value (var);
2473           if (oval == 0)        /* paranoia */
2474             oval = "";
2475           olen = STRLEN (oval);
2476           retval = (char *)xmalloc (olen + (value ? STRLEN (value) : 0) + 1);
2477           strcpy (retval, oval);
2478           if (value)
2479             strcpy (retval+olen, value);
2480         }
2481       else if (*value)
2482         retval = savestring (value);
2483       else
2484         {
2485           retval = (char *)xmalloc (1);
2486           retval[0] = '\0';
2487         }
2488     }
2489   else
2490     retval = (char *)NULL;
2491
2492   return retval;
2493 }
2494
2495 /* Bind a variable NAME to VALUE in the HASH_TABLE TABLE, which may be the
2496    temporary environment (but usually is not). */
2497 static SHELL_VAR *
2498 bind_variable_internal (name, value, table, hflags, aflags)
2499      const char *name;
2500      char *value;
2501      HASH_TABLE *table;
2502      int hflags, aflags;
2503 {
2504   char *newval;
2505   SHELL_VAR *entry;
2506
2507   entry = (hflags & HASH_NOSRCH) ? (SHELL_VAR *)NULL : hash_lookup (name, table);
2508   /* Follow the nameref chain here if this is the global variables table */
2509   if (entry && nameref_p (entry) && (invisible_p (entry) == 0) && table == global_variables->table)
2510     {
2511       entry = find_global_variable (entry->name);
2512       /* Let's see if we have a nameref referencing a variable that hasn't yet
2513          been created. */
2514       if (entry == 0)
2515         entry = find_variable_last_nameref (name);      /* XXX */
2516       if (entry == 0)                                   /* just in case */
2517         return (entry);
2518     }
2519
2520   /* The first clause handles `declare -n ref; ref=x;' */
2521   if (entry && invisible_p (entry) && nameref_p (entry))
2522     goto assign_value;
2523   else if (entry && nameref_p (entry))
2524     {
2525       newval = nameref_cell (entry);
2526 #if defined (ARRAY_VARS)
2527       /* declare -n foo=x[2] */
2528       if (valid_array_reference (newval))
2529         /* XXX - should it be aflags? */
2530         entry = assign_array_element (newval, make_variable_value (entry, value, 0), aflags);
2531       else
2532 #endif
2533       {
2534       entry = make_new_variable (newval, table);
2535       var_setvalue (entry, make_variable_value (entry, value, 0));
2536       }
2537     }
2538   else if (entry == 0)
2539     {
2540       entry = make_new_variable (name, table);
2541       var_setvalue (entry, make_variable_value (entry, value, 0)); /* XXX */
2542     }
2543   else if (entry->assign_func)  /* array vars have assign functions now */
2544     {
2545       INVALIDATE_EXPORTSTR (entry);
2546       newval = (aflags & ASS_APPEND) ? make_variable_value (entry, value, aflags) : value;
2547       if (assoc_p (entry))
2548         entry = (*(entry->assign_func)) (entry, newval, -1, savestring ("0"));
2549       else if (array_p (entry))
2550         entry = (*(entry->assign_func)) (entry, newval, 0, 0);
2551       else
2552         entry = (*(entry->assign_func)) (entry, newval, -1, 0);
2553       if (newval != value)
2554         free (newval);
2555       return (entry);
2556     }
2557   else
2558     {
2559 assign_value:
2560       if (readonly_p (entry) || noassign_p (entry))
2561         {
2562           if (readonly_p (entry))
2563             err_readonly (name);
2564           return (entry);
2565         }
2566
2567       /* Variables which are bound are visible. */
2568       VUNSETATTR (entry, att_invisible);
2569
2570 #if defined (ARRAY_VARS)
2571       if (assoc_p (entry) || array_p (entry))
2572         newval = make_array_variable_value (entry, 0, "0", value, aflags);
2573       else
2574 #endif
2575
2576       newval = make_variable_value (entry, value, aflags);      /* XXX */
2577
2578       /* Invalidate any cached export string */
2579       INVALIDATE_EXPORTSTR (entry);
2580
2581 #if defined (ARRAY_VARS)
2582       /* XXX -- this bears looking at again -- XXX */
2583       /* If an existing array variable x is being assigned to with x=b or
2584          `read x' or something of that nature, silently convert it to
2585          x[0]=b or `read x[0]'. */
2586       if (assoc_p (entry))
2587         {
2588           assoc_insert (assoc_cell (entry), savestring ("0"), newval);
2589           free (newval);
2590         }
2591       else if (array_p (entry))
2592         {
2593           array_insert (array_cell (entry), 0, newval);
2594           free (newval);
2595         }
2596       else
2597 #endif
2598         {
2599           FREE (value_cell (entry));
2600           var_setvalue (entry, newval);
2601         }
2602     }
2603
2604   if (mark_modified_vars)
2605     VSETATTR (entry, att_exported);
2606
2607   if (exported_p (entry))
2608     array_needs_making = 1;
2609
2610   return (entry);
2611 }
2612         
2613 /* Bind a variable NAME to VALUE.  This conses up the name
2614    and value strings.  If we have a temporary environment, we bind there
2615    first, then we bind into shell_variables. */
2616
2617 SHELL_VAR *
2618 bind_variable (name, value, flags)
2619      const char *name;
2620      char *value;
2621      int flags;
2622 {
2623   SHELL_VAR *v, *nv;
2624   VAR_CONTEXT *vc, *nvc;
2625   int level;
2626
2627   if (shell_variables == 0)
2628     create_variable_tables ();
2629
2630   /* If we have a temporary environment, look there first for the variable,
2631      and, if found, modify the value there before modifying it in the
2632      shell_variables table.  This allows sourced scripts to modify values
2633      given to them in a temporary environment while modifying the variable
2634      value that the caller sees. */
2635   if (temporary_env)
2636     bind_tempenv_variable (name, value);
2637
2638   /* XXX -- handle local variables here. */
2639   for (vc = shell_variables; vc; vc = vc->down)
2640     {
2641       if (vc_isfuncenv (vc) || vc_isbltnenv (vc))
2642         {
2643           v = hash_lookup (name, vc->table);
2644           nvc = vc;
2645           if (v && nameref_p (v))
2646             {
2647               nv = find_variable_nameref_context (v, vc, &nvc);
2648               if (nv == 0)
2649                 {
2650                   nv = find_variable_last_nameref_context (v, vc, &nvc);
2651                   if (nv && nameref_p (nv))
2652                     {
2653                       /* If this nameref variable doesn't have a value yet,
2654                          set the value.  Otherwise, assign using the value as
2655                          normal. */
2656                       if (nameref_cell (nv) == 0)
2657                         return (bind_variable_internal (nv->name, value, nvc->table, 0, flags));
2658                       return (bind_variable_internal (nameref_cell (nv), value, nvc->table, 0, flags));
2659                     }
2660                   else
2661                     v = nv;
2662                 }
2663               else
2664                 v = nv;
2665             }
2666           if (v)
2667             return (bind_variable_internal (v->name, value, nvc->table, 0, flags));
2668         }
2669     }
2670   /* bind_variable_internal will handle nameref resolution in this case */
2671   return (bind_variable_internal (name, value, global_variables->table, 0, flags));
2672 }
2673
2674 SHELL_VAR *
2675 bind_global_variable (name, value, flags)
2676      const char *name;
2677      char *value;
2678      int flags;
2679 {
2680   SHELL_VAR *v, *nv;
2681   VAR_CONTEXT *vc, *nvc;
2682   int level;
2683
2684   if (shell_variables == 0)
2685     create_variable_tables ();
2686
2687   /* bind_variable_internal will handle nameref resolution in this case */
2688   return (bind_variable_internal (name, value, global_variables->table, 0, flags));
2689 }
2690
2691 /* Make VAR, a simple shell variable, have value VALUE.  Once assigned a
2692    value, variables are no longer invisible.  This is a duplicate of part
2693    of the internals of bind_variable.  If the variable is exported, or
2694    all modified variables should be exported, mark the variable for export
2695    and note that the export environment needs to be recreated. */
2696 SHELL_VAR *
2697 bind_variable_value (var, value, aflags)
2698      SHELL_VAR *var;
2699      char *value;
2700      int aflags;
2701 {
2702   char *t;
2703   int invis;
2704
2705   invis = invisible_p (var);
2706   VUNSETATTR (var, att_invisible);
2707
2708   if (var->assign_func)
2709     {
2710       /* If we're appending, we need the old value, so use
2711          make_variable_value */
2712       t = (aflags & ASS_APPEND) ? make_variable_value (var, value, aflags) : value;
2713       (*(var->assign_func)) (var, t, -1, 0);
2714       if (t != value && t)
2715         free (t);      
2716     }
2717   else
2718     {
2719       t = make_variable_value (var, value, aflags);
2720 #if defined (ARRAY_VARS)
2721       if ((aflags & ASS_NAMEREF) && (t == 0 || *t == 0 || (legal_identifier (t) == 0 && valid_array_reference (t) == 0)))
2722 #else
2723       if ((aflags & ASS_NAMEREF) && (t == 0 || *t == 0 || legal_identifier (t) == 0))
2724 #endif
2725         {
2726           free (t);
2727           if (invis)
2728             VSETATTR (var, att_invisible);      /* XXX */
2729           return ((SHELL_VAR *)NULL);
2730         }
2731       FREE (value_cell (var));
2732       var_setvalue (var, t);
2733     }
2734
2735   INVALIDATE_EXPORTSTR (var);
2736
2737   if (mark_modified_vars)
2738     VSETATTR (var, att_exported);
2739
2740   if (exported_p (var))
2741     array_needs_making = 1;
2742
2743   return (var);
2744 }
2745
2746 /* Bind/create a shell variable with the name LHS to the RHS.
2747    This creates or modifies a variable such that it is an integer.
2748
2749    This used to be in expr.c, but it is here so that all of the
2750    variable binding stuff is localized.  Since we don't want any
2751    recursive evaluation from bind_variable() (possible without this code,
2752    since bind_variable() calls the evaluator for variables with the integer
2753    attribute set), we temporarily turn off the integer attribute for each
2754    variable we set here, then turn it back on after binding as necessary. */
2755
2756 SHELL_VAR *
2757 bind_int_variable (lhs, rhs)
2758      char *lhs, *rhs;
2759 {
2760   register SHELL_VAR *v;
2761   int isint, isarr, implicitarray;
2762
2763   isint = isarr = implicitarray = 0;
2764 #if defined (ARRAY_VARS)
2765   if (valid_array_reference (lhs))
2766     {
2767       isarr = 1;
2768       v = array_variable_part (lhs, (char **)0, (int *)0);
2769     }
2770   else
2771 #endif
2772     v = find_variable (lhs);
2773
2774   if (v)
2775     {
2776       isint = integer_p (v);
2777       VUNSETATTR (v, att_integer);
2778 #if defined (ARRAY_VARS)
2779       if (array_p (v) && isarr == 0)
2780         implicitarray = 1;
2781 #endif
2782     }
2783
2784 #if defined (ARRAY_VARS)
2785   if (isarr)
2786     v = assign_array_element (lhs, rhs, 0);
2787   else if (implicitarray)
2788     v = bind_array_variable (lhs, 0, rhs, 0);
2789   else
2790 #endif
2791     v = bind_variable (lhs, rhs, 0);
2792
2793   if (v && isint)
2794     VSETATTR (v, att_integer);
2795
2796   VUNSETATTR (v, att_invisible);
2797
2798   return (v);
2799 }
2800
2801 SHELL_VAR *
2802 bind_var_to_int (var, val)
2803      char *var;
2804      intmax_t val;
2805 {
2806   char ibuf[INT_STRLEN_BOUND (intmax_t) + 1], *p;
2807
2808   p = fmtulong (val, 10, ibuf, sizeof (ibuf), 0);
2809   return (bind_int_variable (var, p));
2810 }
2811
2812 /* Do a function binding to a variable.  You pass the name and
2813    the command to bind to.  This conses the name and command. */
2814 SHELL_VAR *
2815 bind_function (name, value)
2816      const char *name;
2817      COMMAND *value;
2818 {
2819   SHELL_VAR *entry;
2820
2821   entry = find_function (name);
2822   if (entry == 0)
2823     {
2824       BUCKET_CONTENTS *elt;
2825
2826       elt = hash_insert (savestring (name), shell_functions, HASH_NOSRCH);
2827       entry = new_shell_variable (name);
2828       elt->data = (PTR_T)entry;
2829     }
2830   else
2831     INVALIDATE_EXPORTSTR (entry);
2832
2833   if (var_isset (entry))
2834     dispose_command (function_cell (entry));
2835
2836   if (value)
2837     var_setfunc (entry, copy_command (value));
2838   else
2839     var_setfunc (entry, 0);
2840
2841   VSETATTR (entry, att_function);
2842
2843   if (mark_modified_vars)
2844     VSETATTR (entry, att_exported);
2845
2846   VUNSETATTR (entry, att_invisible);            /* Just to be sure */
2847
2848   if (exported_p (entry))
2849     array_needs_making = 1;
2850
2851 #if defined (PROGRAMMABLE_COMPLETION)
2852   set_itemlist_dirty (&it_functions);
2853 #endif
2854
2855   return (entry);
2856 }
2857
2858 #if defined (DEBUGGER)
2859 /* Bind a function definition, which includes source file and line number
2860    information in addition to the command, into the FUNCTION_DEF hash table.*/
2861 void
2862 bind_function_def (name, value)
2863      const char *name;
2864      FUNCTION_DEF *value;
2865 {
2866   FUNCTION_DEF *entry;
2867   BUCKET_CONTENTS *elt;
2868   COMMAND *cmd;
2869
2870   entry = find_function_def (name);
2871   if (entry)
2872     {
2873       dispose_function_def_contents (entry);
2874       entry = copy_function_def_contents (value, entry);
2875     }
2876   else
2877     {
2878       cmd = value->command;
2879       value->command = 0;
2880       entry = copy_function_def (value);
2881       value->command = cmd;
2882
2883       elt = hash_insert (savestring (name), shell_function_defs, HASH_NOSRCH);
2884       elt->data = (PTR_T *)entry;
2885     }
2886 }
2887 #endif /* DEBUGGER */
2888
2889 /* Add STRING, which is of the form foo=bar, to the temporary environment
2890    HASH_TABLE (temporary_env).  The functions in execute_cmd.c are
2891    responsible for moving the main temporary env to one of the other
2892    temporary environments.  The expansion code in subst.c calls this. */
2893 int
2894 assign_in_env (word, flags)
2895      WORD_DESC *word;
2896      int flags;
2897 {
2898   int offset, aflags;
2899   char *name, *temp, *value;
2900   SHELL_VAR *var;
2901   const char *string;
2902
2903   string = word->word;
2904
2905   aflags = 0;
2906   offset = assignment (string, 0);
2907   name = savestring (string);
2908   value = (char *)NULL;
2909
2910   if (name[offset] == '=')
2911     {
2912       name[offset] = 0;
2913
2914       /* don't ignore the `+' when assigning temporary environment */
2915       if (name[offset - 1] == '+')
2916         {
2917           name[offset - 1] = '\0';
2918           aflags |= ASS_APPEND;
2919         }
2920
2921       var = find_variable (name);
2922       if (var && (readonly_p (var) || noassign_p (var)))
2923         {
2924           if (readonly_p (var))
2925             err_readonly (name);
2926           free (name);
2927           return (0);
2928         }
2929
2930       temp = name + offset + 1;
2931       value = expand_assignment_string_to_string (temp, 0);
2932
2933       if (var && (aflags & ASS_APPEND))
2934         {
2935           temp = make_variable_value (var, value, aflags);
2936           FREE (value);
2937           value = temp;
2938         }
2939     }
2940
2941   if (temporary_env == 0)
2942     temporary_env = hash_create (TEMPENV_HASH_BUCKETS);
2943
2944   var = hash_lookup (name, temporary_env);
2945   if (var == 0)
2946     var = make_new_variable (name, temporary_env);
2947   else
2948     FREE (value_cell (var));
2949
2950   if (value == 0)
2951     {
2952       value = (char *)xmalloc (1);      /* like do_assignment_internal */
2953       value[0] = '\0';
2954     }
2955
2956   var_setvalue (var, value);
2957   var->attributes |= (att_exported|att_tempvar);
2958   var->context = variable_context;      /* XXX */
2959
2960   INVALIDATE_EXPORTSTR (var);
2961   var->exportstr = mk_env_string (name, value);
2962
2963   array_needs_making = 1;
2964
2965   if (flags)
2966     stupidly_hack_special_variables (name);
2967
2968   if (echo_command_at_execute)
2969     /* The Korn shell prints the `+ ' in front of assignment statements,
2970         so we do too. */
2971     xtrace_print_assignment (name, value, 0, 1);
2972
2973   free (name);
2974   return 1;
2975 }
2976
2977 /* **************************************************************** */
2978 /*                                                                  */
2979 /*                      Copying variables                           */
2980 /*                                                                  */
2981 /* **************************************************************** */
2982
2983 #ifdef INCLUDE_UNUSED
2984 /* Copy VAR to a new data structure and return that structure. */
2985 SHELL_VAR *
2986 copy_variable (var)
2987      SHELL_VAR *var;
2988 {
2989   SHELL_VAR *copy = (SHELL_VAR *)NULL;
2990
2991   if (var)
2992     {
2993       copy = (SHELL_VAR *)xmalloc (sizeof (SHELL_VAR));
2994
2995       copy->attributes = var->attributes;
2996       copy->name = savestring (var->name);
2997
2998       if (function_p (var))
2999         var_setfunc (copy, copy_command (function_cell (var)));
3000 #if defined (ARRAY_VARS)
3001       else if (array_p (var))
3002         var_setarray (copy, array_copy (array_cell (var)));
3003       else if (assoc_p (var))
3004         var_setassoc (copy, assoc_copy (assoc_cell (var)));
3005 #endif
3006       else if (nameref_cell (var))      /* XXX - nameref */
3007         var_setref (copy, savestring (nameref_cell (var)));
3008       else if (value_cell (var))        /* XXX - nameref */
3009         var_setvalue (copy, savestring (value_cell (var)));
3010       else
3011         var_setvalue (copy, (char *)NULL);
3012
3013       copy->dynamic_value = var->dynamic_value;
3014       copy->assign_func = var->assign_func;
3015
3016       copy->exportstr = COPY_EXPORTSTR (var);
3017
3018       copy->context = var->context;
3019     }
3020   return (copy);
3021 }
3022 #endif
3023
3024 /* **************************************************************** */
3025 /*                                                                  */
3026 /*                Deleting and unsetting variables                  */
3027 /*                                                                  */
3028 /* **************************************************************** */
3029
3030 /* Dispose of the information attached to VAR. */
3031 static void
3032 dispose_variable_value (var)
3033      SHELL_VAR *var;
3034 {
3035   if (function_p (var))
3036     dispose_command (function_cell (var));
3037 #if defined (ARRAY_VARS)
3038   else if (array_p (var))
3039     array_dispose (array_cell (var));
3040   else if (assoc_p (var))
3041     assoc_dispose (assoc_cell (var));
3042 #endif
3043   else if (nameref_p (var))
3044     FREE (nameref_cell (var));
3045   else
3046     FREE (value_cell (var));
3047 }
3048
3049 void
3050 dispose_variable (var)
3051      SHELL_VAR *var;
3052 {
3053   if (var == 0)
3054     return;
3055
3056   if (nofree_p (var) == 0)
3057     dispose_variable_value (var);
3058
3059   FREE_EXPORTSTR (var);
3060
3061   free (var->name);
3062
3063   if (exported_p (var))
3064     array_needs_making = 1;
3065
3066   free (var);
3067 }
3068
3069 /* Unset the shell variable referenced by NAME.  Unsetting a nameref variable
3070    unsets the variable it resolves to but leaves the nameref alone. */
3071 int
3072 unbind_variable (name)
3073      const char *name;
3074 {
3075   SHELL_VAR *v, *nv;
3076   int r;
3077
3078   v = var_lookup (name, shell_variables);
3079   nv = (v && nameref_p (v)) ? find_variable_nameref (v) : (SHELL_VAR *)NULL;
3080
3081   r = nv ? makunbound (nv->name, shell_variables) : makunbound (name, shell_variables);
3082   return r;
3083 }
3084
3085 /* Unbind NAME, where NAME is assumed to be a nameref variable */
3086 int
3087 unbind_nameref (name)
3088      const char *name;
3089 {
3090   SHELL_VAR *v;
3091
3092   v = var_lookup (name, shell_variables);
3093   if (v && nameref_p (v))
3094     return makunbound (name, shell_variables);
3095   return 0;
3096 }
3097
3098 /* Unset the shell function named NAME. */
3099 int
3100 unbind_func (name)
3101      const char *name;
3102 {
3103   BUCKET_CONTENTS *elt;
3104   SHELL_VAR *func;
3105
3106   elt = hash_remove (name, shell_functions, 0);
3107
3108   if (elt == 0)
3109     return -1;
3110
3111 #if defined (PROGRAMMABLE_COMPLETION)
3112   set_itemlist_dirty (&it_functions);
3113 #endif
3114
3115   func = (SHELL_VAR *)elt->data;
3116   if (func)
3117     {
3118       if (exported_p (func))
3119         array_needs_making++;
3120       dispose_variable (func);
3121     }
3122
3123   free (elt->key);
3124   free (elt);
3125
3126   return 0;  
3127 }
3128
3129 #if defined (DEBUGGER)
3130 int
3131 unbind_function_def (name)
3132      const char *name;
3133 {
3134   BUCKET_CONTENTS *elt;
3135   FUNCTION_DEF *funcdef;
3136
3137   elt = hash_remove (name, shell_function_defs, 0);
3138
3139   if (elt == 0)
3140     return -1;
3141
3142   funcdef = (FUNCTION_DEF *)elt->data;
3143   if (funcdef)
3144     dispose_function_def (funcdef);
3145
3146   free (elt->key);
3147   free (elt);
3148
3149   return 0;  
3150 }
3151 #endif /* DEBUGGER */
3152
3153 int
3154 delete_var (name, vc)
3155      const char *name;
3156      VAR_CONTEXT *vc;
3157 {
3158   BUCKET_CONTENTS *elt;
3159   SHELL_VAR *old_var;
3160   VAR_CONTEXT *v;
3161
3162   for (elt = (BUCKET_CONTENTS *)NULL, v = vc; v; v = v->down)
3163     if (elt = hash_remove (name, v->table, 0))
3164       break;
3165
3166   if (elt == 0)
3167     return (-1);
3168
3169   old_var = (SHELL_VAR *)elt->data;
3170   free (elt->key);
3171   free (elt);
3172
3173   dispose_variable (old_var);
3174   return (0);
3175 }
3176
3177 /* Make the variable associated with NAME go away.  HASH_LIST is the
3178    hash table from which this variable should be deleted (either
3179    shell_variables or shell_functions).
3180    Returns non-zero if the variable couldn't be found. */
3181 int
3182 makunbound (name, vc)
3183      const char *name;
3184      VAR_CONTEXT *vc;
3185 {
3186   BUCKET_CONTENTS *elt, *new_elt;
3187   SHELL_VAR *old_var;
3188   VAR_CONTEXT *v;
3189   char *t;
3190
3191   for (elt = (BUCKET_CONTENTS *)NULL, v = vc; v; v = v->down)
3192     if (elt = hash_remove (name, v->table, 0))
3193       break;
3194
3195   if (elt == 0)
3196     return (-1);
3197
3198   old_var = (SHELL_VAR *)elt->data;
3199
3200   if (old_var && exported_p (old_var))
3201     array_needs_making++;
3202
3203   /* If we're unsetting a local variable and we're still executing inside
3204      the function, just mark the variable as invisible.  The function
3205      eventually called by pop_var_context() will clean it up later.  This
3206      must be done so that if the variable is subsequently assigned a new
3207      value inside the function, the `local' attribute is still present.
3208      We also need to add it back into the correct hash table. */
3209   if (old_var && local_p (old_var) && variable_context == old_var->context)
3210     {
3211       if (nofree_p (old_var))
3212         var_setvalue (old_var, (char *)NULL);
3213 #if defined (ARRAY_VARS)
3214       else if (array_p (old_var))
3215         array_dispose (array_cell (old_var));
3216       else if (assoc_p (old_var))
3217         assoc_dispose (assoc_cell (old_var));
3218 #endif
3219       else if (nameref_p (old_var))
3220         FREE (nameref_cell (old_var));
3221       else
3222         FREE (value_cell (old_var));
3223       /* Reset the attributes.  Preserve the export attribute if the variable
3224          came from a temporary environment.  Make sure it stays local, and
3225          make it invisible. */ 
3226       old_var->attributes = (exported_p (old_var) && tempvar_p (old_var)) ? att_exported : 0;
3227       VSETATTR (old_var, att_local);
3228       VSETATTR (old_var, att_invisible);
3229       var_setvalue (old_var, (char *)NULL);
3230       INVALIDATE_EXPORTSTR (old_var);
3231
3232       new_elt = hash_insert (savestring (old_var->name), v->table, 0);
3233       new_elt->data = (PTR_T)old_var;
3234       stupidly_hack_special_variables (old_var->name);
3235
3236       free (elt->key);
3237       free (elt);
3238       return (0);
3239     }
3240
3241   /* Have to save a copy of name here, because it might refer to
3242      old_var->name.  If so, stupidly_hack_special_variables will
3243      reference freed memory. */
3244   t = savestring (name);
3245
3246   free (elt->key);
3247   free (elt);
3248
3249   dispose_variable (old_var);
3250   stupidly_hack_special_variables (t);
3251   free (t);
3252
3253   return (0);
3254 }
3255
3256 /* Get rid of all of the variables in the current context. */
3257 void
3258 kill_all_local_variables ()
3259 {
3260   VAR_CONTEXT *vc;
3261
3262   for (vc = shell_variables; vc; vc = vc->down)
3263     if (vc_isfuncenv (vc) && vc->scope == variable_context)
3264       break;
3265   if (vc == 0)
3266     return;             /* XXX */
3267
3268   if (vc->table && vc_haslocals (vc))
3269     {
3270       delete_all_variables (vc->table);
3271       hash_dispose (vc->table);
3272     }
3273   vc->table = (HASH_TABLE *)NULL;
3274 }
3275
3276 static void
3277 free_variable_hash_data (data)
3278      PTR_T data;
3279 {
3280   SHELL_VAR *var;
3281
3282   var = (SHELL_VAR *)data;
3283   dispose_variable (var);
3284 }
3285
3286 /* Delete the entire contents of the hash table. */
3287 void
3288 delete_all_variables (hashed_vars)
3289      HASH_TABLE *hashed_vars;
3290 {
3291   hash_flush (hashed_vars, free_variable_hash_data);
3292 }
3293
3294 /* **************************************************************** */
3295 /*                                                                  */
3296 /*                   Setting variable attributes                    */
3297 /*                                                                  */
3298 /* **************************************************************** */
3299
3300 #define FIND_OR_MAKE_VARIABLE(name, entry) \
3301   do \
3302     { \
3303       entry = find_variable (name); \
3304       if (!entry) \
3305         { \
3306           entry = bind_variable (name, "", 0); \
3307           if (!no_invisible_vars && entry) entry->attributes |= att_invisible; \
3308         } \
3309     } \
3310   while (0)
3311
3312 /* Make the variable associated with NAME be readonly.
3313    If NAME does not exist yet, create it. */
3314 void
3315 set_var_read_only (name)
3316      char *name;
3317 {
3318   SHELL_VAR *entry;
3319
3320   FIND_OR_MAKE_VARIABLE (name, entry);
3321   VSETATTR (entry, att_readonly);
3322 }
3323
3324 #ifdef INCLUDE_UNUSED
3325 /* Make the function associated with NAME be readonly.
3326    If NAME does not exist, we just punt, like auto_export code below. */
3327 void
3328 set_func_read_only (name)
3329      const char *name;
3330 {
3331   SHELL_VAR *entry;
3332
3333   entry = find_function (name);
3334   if (entry)
3335     VSETATTR (entry, att_readonly);
3336 }
3337
3338 /* Make the variable associated with NAME be auto-exported.
3339    If NAME does not exist yet, create it. */
3340 void
3341 set_var_auto_export (name)
3342      char *name;
3343 {
3344   SHELL_VAR *entry;
3345
3346   FIND_OR_MAKE_VARIABLE (name, entry);
3347   set_auto_export (entry);
3348 }
3349
3350 /* Make the function associated with NAME be auto-exported. */
3351 void
3352 set_func_auto_export (name)
3353      const char *name;
3354 {
3355   SHELL_VAR *entry;
3356
3357   entry = find_function (name);
3358   if (entry)
3359     set_auto_export (entry);
3360 }
3361 #endif
3362
3363 /* **************************************************************** */
3364 /*                                                                  */
3365 /*                   Creating lists of variables                    */
3366 /*                                                                  */
3367 /* **************************************************************** */
3368
3369 static VARLIST *
3370 vlist_alloc (nentries)
3371      int nentries;
3372 {
3373   VARLIST  *vlist;
3374
3375   vlist = (VARLIST *)xmalloc (sizeof (VARLIST));
3376   vlist->list = (SHELL_VAR **)xmalloc ((nentries + 1) * sizeof (SHELL_VAR *));
3377   vlist->list_size = nentries;
3378   vlist->list_len = 0;
3379   vlist->list[0] = (SHELL_VAR *)NULL;
3380
3381   return vlist;
3382 }
3383
3384 static VARLIST *
3385 vlist_realloc (vlist, n)
3386      VARLIST *vlist;
3387      int n;
3388 {
3389   if (vlist == 0)
3390     return (vlist = vlist_alloc (n));
3391   if (n > vlist->list_size)
3392     {
3393       vlist->list_size = n;
3394       vlist->list = (SHELL_VAR **)xrealloc (vlist->list, (vlist->list_size + 1) * sizeof (SHELL_VAR *));
3395     }
3396   return vlist;
3397 }
3398
3399 static void
3400 vlist_add (vlist, var, flags)
3401      VARLIST *vlist;
3402      SHELL_VAR *var;
3403      int flags;
3404 {
3405   register int i;
3406
3407   for (i = 0; i < vlist->list_len; i++)
3408     if (STREQ (var->name, vlist->list[i]->name))
3409       break;
3410   if (i < vlist->list_len)
3411     return;
3412
3413   if (i >= vlist->list_size)
3414     vlist = vlist_realloc (vlist, vlist->list_size + 16);
3415
3416   vlist->list[vlist->list_len++] = var;
3417   vlist->list[vlist->list_len] = (SHELL_VAR *)NULL;
3418 }
3419
3420 /* Map FUNCTION over the variables in VAR_HASH_TABLE.  Return an array of the
3421    variables for which FUNCTION returns a non-zero value.  A NULL value
3422    for FUNCTION means to use all variables. */
3423 SHELL_VAR **
3424 map_over (function, vc)
3425      sh_var_map_func_t *function;
3426      VAR_CONTEXT *vc;
3427 {
3428   VAR_CONTEXT *v;
3429   VARLIST *vlist;
3430   SHELL_VAR **ret;
3431   int nentries;
3432
3433   for (nentries = 0, v = vc; v; v = v->down)
3434     nentries += HASH_ENTRIES (v->table);
3435
3436   if (nentries == 0)
3437     return (SHELL_VAR **)NULL;
3438
3439   vlist = vlist_alloc (nentries);
3440
3441   for (v = vc; v; v = v->down)
3442     flatten (v->table, function, vlist, 0);
3443
3444   ret = vlist->list;
3445   free (vlist);
3446   return ret;
3447 }
3448
3449 SHELL_VAR **
3450 map_over_funcs (function)
3451      sh_var_map_func_t *function;
3452 {
3453   VARLIST *vlist;
3454   SHELL_VAR **ret;
3455
3456   if (shell_functions == 0 || HASH_ENTRIES (shell_functions) == 0)
3457     return ((SHELL_VAR **)NULL);
3458
3459   vlist = vlist_alloc (HASH_ENTRIES (shell_functions));
3460
3461   flatten (shell_functions, function, vlist, 0);
3462
3463   ret = vlist->list;
3464   free (vlist);
3465   return ret;
3466 }
3467
3468 /* Flatten VAR_HASH_TABLE, applying FUNC to each member and adding those
3469    elements for which FUNC succeeds to VLIST->list.  FLAGS is reserved
3470    for future use.  Only unique names are added to VLIST.  If FUNC is
3471    NULL, each variable in VAR_HASH_TABLE is added to VLIST.  If VLIST is
3472    NULL, FUNC is applied to each SHELL_VAR in VAR_HASH_TABLE.  If VLIST
3473    and FUNC are both NULL, nothing happens. */
3474 static void
3475 flatten (var_hash_table, func, vlist, flags)
3476      HASH_TABLE *var_hash_table;
3477      sh_var_map_func_t *func;
3478      VARLIST *vlist;
3479      int flags;
3480 {
3481   register int i;
3482   register BUCKET_CONTENTS *tlist;
3483   int r;
3484   SHELL_VAR *var;
3485
3486   if (var_hash_table == 0 || (HASH_ENTRIES (var_hash_table) == 0) || (vlist == 0 && func == 0))
3487     return;
3488
3489   for (i = 0; i < var_hash_table->nbuckets; i++)
3490     {
3491       for (tlist = hash_items (i, var_hash_table); tlist; tlist = tlist->next)
3492         {
3493           var = (SHELL_VAR *)tlist->data;
3494
3495           r = func ? (*func) (var) : 1;
3496           if (r && vlist)
3497             vlist_add (vlist, var, flags);
3498         }
3499     }
3500 }
3501
3502 void
3503 sort_variables (array)
3504      SHELL_VAR **array;
3505 {
3506   qsort (array, strvec_len ((char **)array), sizeof (SHELL_VAR *), (QSFUNC *)qsort_var_comp);
3507 }
3508
3509 static int
3510 qsort_var_comp (var1, var2)
3511      SHELL_VAR **var1, **var2;
3512 {
3513   int result;
3514
3515   if ((result = (*var1)->name[0] - (*var2)->name[0]) == 0)
3516     result = strcmp ((*var1)->name, (*var2)->name);
3517
3518   return (result);
3519 }
3520
3521 /* Apply FUNC to each variable in SHELL_VARIABLES, adding each one for
3522    which FUNC succeeds to an array of SHELL_VAR *s.  Returns the array. */
3523 static SHELL_VAR **
3524 vapply (func)
3525      sh_var_map_func_t *func;
3526 {
3527   SHELL_VAR **list;
3528
3529   list = map_over (func, shell_variables);
3530   if (list /* && posixly_correct */)
3531     sort_variables (list);
3532   return (list);
3533 }
3534
3535 /* Apply FUNC to each variable in SHELL_FUNCTIONS, adding each one for
3536    which FUNC succeeds to an array of SHELL_VAR *s.  Returns the array. */
3537 static SHELL_VAR **
3538 fapply (func)
3539      sh_var_map_func_t *func;
3540 {
3541   SHELL_VAR **list;
3542
3543   list = map_over_funcs (func);
3544   if (list /* && posixly_correct */)
3545     sort_variables (list);
3546   return (list);
3547 }
3548
3549 /* Create a NULL terminated array of all the shell variables. */
3550 SHELL_VAR **
3551 all_shell_variables ()
3552 {
3553   return (vapply ((sh_var_map_func_t *)NULL));
3554 }
3555
3556 /* Create a NULL terminated array of all the shell functions. */
3557 SHELL_VAR **
3558 all_shell_functions ()
3559 {
3560   return (fapply ((sh_var_map_func_t *)NULL));
3561 }
3562
3563 static int
3564 visible_var (var)
3565      SHELL_VAR *var;
3566 {
3567   return (invisible_p (var) == 0);
3568 }
3569
3570 SHELL_VAR **
3571 all_visible_functions ()
3572 {
3573   return (fapply (visible_var));
3574 }
3575
3576 SHELL_VAR **
3577 all_visible_variables ()
3578 {
3579   return (vapply (visible_var));
3580 }
3581
3582 /* Return non-zero if the variable VAR is visible and exported.  Array
3583    variables cannot be exported. */
3584 static int
3585 visible_and_exported (var)
3586      SHELL_VAR *var;
3587 {
3588   return (invisible_p (var) == 0 && exported_p (var));
3589 }
3590
3591 /* Candidate variables for the export environment are either valid variables
3592    with the export attribute or invalid variables inherited from the initial
3593    environment and simply passed through. */
3594 static int
3595 export_environment_candidate (var)
3596      SHELL_VAR *var;
3597 {
3598   return (exported_p (var) && (invisible_p (var) == 0 || imported_p (var)));
3599 }
3600
3601 /* Return non-zero if VAR is a local variable in the current context and
3602    is exported. */
3603 static int
3604 local_and_exported (var)
3605      SHELL_VAR *var;
3606 {
3607   return (invisible_p (var) == 0 && local_p (var) && var->context == variable_context && exported_p (var));
3608 }
3609
3610 SHELL_VAR **
3611 all_exported_variables ()
3612 {
3613   return (vapply (visible_and_exported));
3614 }
3615
3616 SHELL_VAR **
3617 local_exported_variables ()
3618 {
3619   return (vapply (local_and_exported));
3620 }
3621
3622 static int
3623 variable_in_context (var)
3624      SHELL_VAR *var;
3625 {
3626   return (invisible_p (var) == 0 && local_p (var) && var->context == variable_context);
3627 }
3628
3629 SHELL_VAR **
3630 all_local_variables ()
3631 {
3632   VARLIST *vlist;
3633   SHELL_VAR **ret;
3634   VAR_CONTEXT *vc;
3635
3636   vc = shell_variables;
3637   for (vc = shell_variables; vc; vc = vc->down)
3638     if (vc_isfuncenv (vc) && vc->scope == variable_context)
3639       break;
3640
3641   if (vc == 0)
3642     {
3643       internal_error (_("all_local_variables: no function context at current scope"));
3644       return (SHELL_VAR **)NULL;
3645     }
3646   if (vc->table == 0 || HASH_ENTRIES (vc->table) == 0 || vc_haslocals (vc) == 0)
3647     return (SHELL_VAR **)NULL;
3648     
3649   vlist = vlist_alloc (HASH_ENTRIES (vc->table));
3650
3651   flatten (vc->table, variable_in_context, vlist, 0);
3652
3653   ret = vlist->list;
3654   free (vlist);
3655   if (ret)
3656     sort_variables (ret);
3657   return ret;
3658 }
3659
3660 #if defined (ARRAY_VARS)
3661 /* Return non-zero if the variable VAR is visible and an array. */
3662 static int
3663 visible_array_vars (var)
3664      SHELL_VAR *var;
3665 {
3666   return (invisible_p (var) == 0 && array_p (var));
3667 }
3668
3669 SHELL_VAR **
3670 all_array_variables ()
3671 {
3672   return (vapply (visible_array_vars));
3673 }
3674 #endif /* ARRAY_VARS */
3675
3676 char **
3677 all_variables_matching_prefix (prefix)
3678      const char *prefix;
3679 {
3680   SHELL_VAR **varlist;
3681   char **rlist;
3682   int vind, rind, plen;
3683
3684   plen = STRLEN (prefix);
3685   varlist = all_visible_variables ();
3686   for (vind = 0; varlist && varlist[vind]; vind++)
3687     ;
3688   if (varlist == 0 || vind == 0)
3689     return ((char **)NULL);
3690   rlist = strvec_create (vind + 1);
3691   for (vind = rind = 0; varlist[vind]; vind++)
3692     {
3693       if (plen == 0 || STREQN (prefix, varlist[vind]->name, plen))
3694         rlist[rind++] = savestring (varlist[vind]->name);
3695     }
3696   rlist[rind] = (char *)0;
3697   free (varlist);
3698
3699   return rlist;
3700 }
3701
3702 /* **************************************************************** */
3703 /*                                                                  */
3704 /*               Managing temporary variable scopes                 */
3705 /*                                                                  */
3706 /* **************************************************************** */
3707
3708 /* Make variable NAME have VALUE in the temporary environment. */
3709 static SHELL_VAR *
3710 bind_tempenv_variable (name, value)
3711      const char *name;
3712      char *value;
3713 {
3714   SHELL_VAR *var;
3715
3716   var = temporary_env ? hash_lookup (name, temporary_env) : (SHELL_VAR *)NULL;
3717
3718   if (var)
3719     {
3720       FREE (value_cell (var));
3721       var_setvalue (var, savestring (value));
3722       INVALIDATE_EXPORTSTR (var);
3723     }
3724
3725   return (var);
3726 }
3727
3728 /* Find a variable in the temporary environment that is named NAME.
3729    Return the SHELL_VAR *, or NULL if not found. */
3730 SHELL_VAR *
3731 find_tempenv_variable (name)
3732      const char *name;
3733 {
3734   return (temporary_env ? hash_lookup (name, temporary_env) : (SHELL_VAR *)NULL);
3735 }
3736
3737 char **tempvar_list;
3738 int tvlist_ind;
3739
3740 /* Push the variable described by (SHELL_VAR *)DATA down to the next
3741    variable context from the temporary environment. */
3742 static void
3743 push_temp_var (data)
3744      PTR_T data;
3745 {
3746   SHELL_VAR *var, *v;
3747   HASH_TABLE *binding_table;
3748
3749   var = (SHELL_VAR *)data;
3750
3751   binding_table = shell_variables->table;
3752   if (binding_table == 0)
3753     {
3754       if (shell_variables == global_variables)
3755         /* shouldn't happen */
3756         binding_table = shell_variables->table = global_variables->table = hash_create (0);
3757       else
3758         binding_table = shell_variables->table = hash_create (TEMPENV_HASH_BUCKETS);
3759     }
3760
3761   v = bind_variable_internal (var->name, value_cell (var), binding_table, 0, 0);
3762
3763   /* XXX - should we set the context here?  It shouldn't matter because of how
3764      assign_in_env works, but might want to check. */
3765   if (binding_table == global_variables->table)         /* XXX */
3766     var->attributes &= ~(att_tempvar|att_propagate);
3767   else
3768     {
3769       var->attributes |= att_propagate;
3770       if  (binding_table == shell_variables->table)
3771         shell_variables->flags |= VC_HASTMPVAR;
3772     }
3773   v->attributes |= var->attributes;
3774
3775   if (find_special_var (var->name) >= 0)
3776     tempvar_list[tvlist_ind++] = savestring (var->name);
3777
3778   dispose_variable (var);
3779 }
3780
3781 static void
3782 propagate_temp_var (data)
3783      PTR_T data;
3784 {
3785   SHELL_VAR *var;
3786
3787   var = (SHELL_VAR *)data;
3788   if (tempvar_p (var) && (var->attributes & att_propagate))
3789     push_temp_var (data);
3790   else
3791     {
3792       if (find_special_var (var->name) >= 0)
3793         tempvar_list[tvlist_ind++] = savestring (var->name);
3794       dispose_variable (var);
3795     }
3796 }
3797
3798 /* Free the storage used in the hash table for temporary
3799    environment variables.  PUSHF is a function to be called
3800    to free each hash table entry.  It takes care of pushing variables
3801    to previous scopes if appropriate.  PUSHF stores names of variables
3802    that require special handling (e.g., IFS) on tempvar_list, so this
3803    function can call stupidly_hack_special_variables on all the
3804    variables in the list when the temporary hash table is destroyed. */
3805 static void
3806 dispose_temporary_env (pushf)
3807      sh_free_func_t *pushf;
3808 {
3809   int i;
3810
3811   tempvar_list = strvec_create (HASH_ENTRIES (temporary_env) + 1);
3812   tempvar_list[tvlist_ind = 0] = 0;
3813     
3814   hash_flush (temporary_env, pushf);
3815   hash_dispose (temporary_env);
3816   temporary_env = (HASH_TABLE *)NULL;
3817
3818   tempvar_list[tvlist_ind] = 0;
3819
3820   array_needs_making = 1;
3821
3822 #if 0
3823   sv_ifs ("IFS");               /* XXX here for now -- check setifs in assign_in_env */  
3824 #endif
3825   for (i = 0; i < tvlist_ind; i++)
3826     stupidly_hack_special_variables (tempvar_list[i]);
3827
3828   strvec_dispose (tempvar_list);
3829   tempvar_list = 0;
3830   tvlist_ind = 0;
3831 }
3832
3833 void
3834 dispose_used_env_vars ()
3835 {
3836   if (temporary_env)
3837     {
3838       dispose_temporary_env (propagate_temp_var);
3839       maybe_make_export_env ();
3840     }
3841 }
3842
3843 /* Take all of the shell variables in the temporary environment HASH_TABLE
3844    and make shell variables from them at the current variable context. */
3845 void
3846 merge_temporary_env ()
3847 {
3848   if (temporary_env)
3849     dispose_temporary_env (push_temp_var);
3850 }
3851
3852 /* **************************************************************** */
3853 /*                                                                  */
3854 /*           Creating and manipulating the environment              */
3855 /*                                                                  */
3856 /* **************************************************************** */
3857
3858 static inline char *
3859 mk_env_string (name, value)
3860      const char *name, *value;
3861 {
3862   int name_len, value_len;
3863   char  *p;
3864
3865   name_len = strlen (name);
3866   value_len = STRLEN (value);
3867   p = (char *)xmalloc (2 + name_len + value_len);
3868   strcpy (p, name);
3869   p[name_len] = '=';
3870   if (value && *value)
3871     strcpy (p + name_len + 1, value);
3872   else
3873     p[name_len + 1] = '\0';
3874   return (p);
3875 }
3876
3877 #ifdef DEBUG
3878 /* Debugging */
3879 static int
3880 valid_exportstr (v)
3881      SHELL_VAR *v;
3882 {
3883   char *s;
3884
3885   s = v->exportstr;
3886   if (s == 0)
3887     {
3888       internal_error (_("%s has null exportstr"), v->name);
3889       return (0);
3890     }
3891   if (legal_variable_starter ((unsigned char)*s) == 0)
3892     {
3893       internal_error (_("invalid character %d in exportstr for %s"), *s, v->name);
3894       return (0);
3895     }
3896   for (s = v->exportstr + 1; s && *s; s++)
3897     {
3898       if (*s == '=')
3899         break;
3900       if (legal_variable_char ((unsigned char)*s) == 0)
3901         {
3902           internal_error (_("invalid character %d in exportstr for %s"), *s, v->name);
3903           return (0);
3904         }
3905     }
3906   if (*s != '=')
3907     {
3908       internal_error (_("no `=' in exportstr for %s"), v->name);
3909       return (0);
3910     }
3911   return (1);
3912 }
3913 #endif
3914
3915 static char **
3916 make_env_array_from_var_list (vars)
3917      SHELL_VAR **vars;
3918 {
3919   register int i, list_index;
3920   register SHELL_VAR *var;
3921   char **list, *value;
3922
3923   list = strvec_create ((1 + strvec_len ((char **)vars)));
3924
3925 #define USE_EXPORTSTR (value == var->exportstr)
3926
3927   for (i = 0, list_index = 0; var = vars[i]; i++)
3928     {
3929 #if defined (__CYGWIN__)
3930       /* We don't use the exportstr stuff on Cygwin at all. */
3931       INVALIDATE_EXPORTSTR (var);
3932 #endif
3933       if (var->exportstr)
3934         value = var->exportstr;
3935       else if (function_p (var))
3936         value = named_function_string ((char *)NULL, function_cell (var), 0);
3937 #if defined (ARRAY_VARS)
3938       else if (array_p (var))
3939 #  if ARRAY_EXPORT
3940         value = array_to_assignment_string (array_cell (var));
3941 #  else
3942         continue;       /* XXX array vars cannot yet be exported */
3943 #  endif /* ARRAY_EXPORT */
3944       else if (assoc_p (var))
3945 #  if 0
3946         value = assoc_to_assignment_string (assoc_cell (var));
3947 #  else
3948         continue;       /* XXX associative array vars cannot yet be exported */
3949 #  endif
3950 #endif
3951       else
3952         value = value_cell (var);
3953
3954       if (value)
3955         {
3956           /* Gee, I'd like to get away with not using savestring() if we're
3957              using the cached exportstr... */
3958           list[list_index] = USE_EXPORTSTR ? savestring (value)
3959                                            : mk_env_string (var->name, value);
3960
3961           if (USE_EXPORTSTR == 0)
3962             SAVE_EXPORTSTR (var, list[list_index]);
3963
3964           list_index++;
3965 #undef USE_EXPORTSTR
3966
3967 #if 0   /* not yet */
3968 #if defined (ARRAY_VARS)
3969           if (array_p (var) || assoc_p (var))
3970             free (value);
3971 #endif
3972 #endif
3973         }
3974     }
3975
3976   list[list_index] = (char *)NULL;
3977   return (list);
3978 }
3979
3980 /* Make an array of assignment statements from the hash table
3981    HASHED_VARS which contains SHELL_VARs.  Only visible, exported
3982    variables are eligible. */
3983 static char **
3984 make_var_export_array (vcxt)
3985      VAR_CONTEXT *vcxt;
3986 {
3987   char **list;
3988   SHELL_VAR **vars;
3989
3990 #if 0
3991   vars = map_over (visible_and_exported, vcxt);
3992 #else
3993   vars = map_over (export_environment_candidate, vcxt);
3994 #endif
3995
3996   if (vars == 0)
3997     return (char **)NULL;
3998
3999   list = make_env_array_from_var_list (vars);
4000
4001   free (vars);
4002   return (list);
4003 }
4004
4005 static char **
4006 make_func_export_array ()
4007 {
4008   char **list;
4009   SHELL_VAR **vars;
4010
4011   vars = map_over_funcs (visible_and_exported);
4012   if (vars == 0)
4013     return (char **)NULL;
4014
4015   list = make_env_array_from_var_list (vars);
4016
4017   free (vars);
4018   return (list);
4019 }
4020
4021 /* Add ENVSTR to the end of the exported environment, EXPORT_ENV. */
4022 #define add_to_export_env(envstr,do_alloc) \
4023 do \
4024   { \
4025     if (export_env_index >= (export_env_size - 1)) \
4026       { \
4027         export_env_size += 16; \
4028         export_env = strvec_resize (export_env, export_env_size); \
4029         environ = export_env; \
4030       } \
4031     export_env[export_env_index++] = (do_alloc) ? savestring (envstr) : envstr; \
4032     export_env[export_env_index] = (char *)NULL; \
4033   } while (0)
4034
4035 /* Add ASSIGN to EXPORT_ENV, or supercede a previous assignment in the
4036    array with the same left-hand side.  Return the new EXPORT_ENV. */
4037 char **
4038 add_or_supercede_exported_var (assign, do_alloc)
4039      char *assign;
4040      int do_alloc;
4041 {
4042   register int i;
4043   int equal_offset;
4044
4045   equal_offset = assignment (assign, 0);
4046   if (equal_offset == 0)
4047     return (export_env);
4048
4049   /* If this is a function, then only supersede the function definition.
4050      We do this by including the `=() {' in the comparison, like
4051      initialize_shell_variables does. */
4052   if (assign[equal_offset + 1] == '(' &&
4053      strncmp (assign + equal_offset + 2, ") {", 3) == 0)                /* } */
4054     equal_offset += 4;
4055
4056   for (i = 0; i < export_env_index; i++)
4057     {
4058       if (STREQN (assign, export_env[i], equal_offset + 1))
4059         {
4060           free (export_env[i]);
4061           export_env[i] = do_alloc ? savestring (assign) : assign;
4062           return (export_env);
4063         }
4064     }
4065   add_to_export_env (assign, do_alloc);
4066   return (export_env);
4067 }
4068
4069 static void
4070 add_temp_array_to_env (temp_array, do_alloc, do_supercede)
4071      char **temp_array;
4072      int do_alloc, do_supercede;
4073 {
4074   register int i;
4075
4076   if (temp_array == 0)
4077     return;
4078
4079   for (i = 0; temp_array[i]; i++)
4080     {
4081       if (do_supercede)
4082         export_env = add_or_supercede_exported_var (temp_array[i], do_alloc);
4083       else
4084         add_to_export_env (temp_array[i], do_alloc);
4085     }
4086
4087   free (temp_array);
4088 }
4089
4090 /* Make the environment array for the command about to be executed, if the
4091    array needs making.  Otherwise, do nothing.  If a shell action could
4092    change the array that commands receive for their environment, then the
4093    code should `array_needs_making++'.
4094
4095    The order to add to the array is:
4096         temporary_env
4097         list of var contexts whose head is shell_variables
4098         shell_functions
4099
4100   This is the shell variable lookup order.  We add only new variable
4101   names at each step, which allows local variables and variables in
4102   the temporary environments to shadow variables in the global (or
4103   any previous) scope.
4104 */
4105
4106 static int
4107 n_shell_variables ()
4108 {
4109   VAR_CONTEXT *vc;
4110   int n;
4111
4112   for (n = 0, vc = shell_variables; vc; vc = vc->down)
4113     n += HASH_ENTRIES (vc->table);
4114   return n;
4115 }
4116
4117 int
4118 chkexport (name)
4119      char *name;
4120 {
4121   SHELL_VAR *v;
4122
4123   v = find_variable (name);
4124   if (v && exported_p (v))
4125     {
4126       array_needs_making = 1;
4127       maybe_make_export_env ();
4128       return 1;
4129     }
4130   return 0;
4131 }
4132
4133 void
4134 maybe_make_export_env ()
4135 {
4136   register char **temp_array;
4137   int new_size;
4138   VAR_CONTEXT *tcxt;
4139
4140   if (array_needs_making)
4141     {
4142       if (export_env)
4143         strvec_flush (export_env);
4144
4145       /* Make a guess based on how many shell variables and functions we
4146          have.  Since there will always be array variables, and array
4147          variables are not (yet) exported, this will always be big enough
4148          for the exported variables and functions. */
4149       new_size = n_shell_variables () + HASH_ENTRIES (shell_functions) + 1 +
4150                  HASH_ENTRIES (temporary_env);
4151       if (new_size > export_env_size)
4152         {
4153           export_env_size = new_size;
4154           export_env = strvec_resize (export_env, export_env_size);
4155           environ = export_env;
4156         }
4157       export_env[export_env_index = 0] = (char *)NULL;
4158
4159       /* Make a dummy variable context from the temporary_env, stick it on
4160          the front of shell_variables, call make_var_export_array on the
4161          whole thing to flatten it, and convert the list of SHELL_VAR *s
4162          to the form needed by the environment. */
4163       if (temporary_env)
4164         {
4165           tcxt = new_var_context ((char *)NULL, 0);
4166           tcxt->table = temporary_env;
4167           tcxt->down = shell_variables;
4168         }
4169       else
4170         tcxt = shell_variables;
4171       
4172       temp_array = make_var_export_array (tcxt);
4173       if (temp_array)
4174         add_temp_array_to_env (temp_array, 0, 0);
4175
4176       if (tcxt != shell_variables)
4177         free (tcxt);
4178
4179 #if defined (RESTRICTED_SHELL)
4180       /* Restricted shells may not export shell functions. */
4181       temp_array = restricted ? (char **)0 : make_func_export_array ();
4182 #else
4183       temp_array = make_func_export_array ();
4184 #endif
4185       if (temp_array)
4186         add_temp_array_to_env (temp_array, 0, 0);
4187
4188       array_needs_making = 0;
4189     }
4190 }
4191
4192 /* This is an efficiency hack.  PWD and OLDPWD are auto-exported, so
4193    we will need to remake the exported environment every time we
4194    change directories.  `_' is always put into the environment for
4195    every external command, so without special treatment it will always
4196    cause the environment to be remade.
4197
4198    If there is no other reason to make the exported environment, we can
4199    just update the variables in place and mark the exported environment
4200    as no longer needing a remake. */
4201 void
4202 update_export_env_inplace (env_prefix, preflen, value)
4203      char *env_prefix;
4204      int preflen;
4205      char *value;
4206 {
4207   char *evar;
4208
4209   evar = (char *)xmalloc (STRLEN (value) + preflen + 1);
4210   strcpy (evar, env_prefix);
4211   if (value)
4212     strcpy (evar + preflen, value);
4213   export_env = add_or_supercede_exported_var (evar, 0);
4214 }
4215
4216 /* We always put _ in the environment as the name of this command. */
4217 void
4218 put_command_name_into_env (command_name)
4219      char *command_name;
4220 {
4221   update_export_env_inplace ("_=", 2, command_name);
4222 }
4223
4224 /* **************************************************************** */
4225 /*                                                                  */
4226 /*                    Managing variable contexts                    */
4227 /*                                                                  */
4228 /* **************************************************************** */
4229
4230 /* Allocate and return a new variable context with NAME and FLAGS.
4231    NAME can be NULL. */
4232
4233 VAR_CONTEXT *
4234 new_var_context (name, flags)
4235      char *name;
4236      int flags;
4237 {
4238   VAR_CONTEXT *vc;
4239
4240   vc = (VAR_CONTEXT *)xmalloc (sizeof (VAR_CONTEXT));
4241   vc->name = name ? savestring (name) : (char *)NULL;
4242   vc->scope = variable_context;
4243   vc->flags = flags;
4244
4245   vc->up = vc->down = (VAR_CONTEXT *)NULL;
4246   vc->table = (HASH_TABLE *)NULL;
4247
4248   return vc;
4249 }
4250
4251 /* Free a variable context and its data, including the hash table.  Dispose
4252    all of the variables. */
4253 void
4254 dispose_var_context (vc)
4255      VAR_CONTEXT *vc;
4256 {
4257   FREE (vc->name);
4258
4259   if (vc->table)
4260     {
4261       delete_all_variables (vc->table);
4262       hash_dispose (vc->table);
4263     }
4264
4265   free (vc);
4266 }
4267
4268 /* Set VAR's scope level to the current variable context. */
4269 static int
4270 set_context (var)
4271      SHELL_VAR *var;
4272 {
4273   return (var->context = variable_context);
4274 }
4275
4276 /* Make a new variable context with NAME and FLAGS and a HASH_TABLE of
4277    temporary variables, and push it onto shell_variables.  This is
4278    for shell functions. */
4279 VAR_CONTEXT *
4280 push_var_context (name, flags, tempvars)
4281      char *name;
4282      int flags;
4283      HASH_TABLE *tempvars;
4284 {
4285   VAR_CONTEXT *vc;
4286
4287   vc = new_var_context (name, flags);
4288   vc->table = tempvars;
4289   if (tempvars)
4290     {
4291       /* Have to do this because the temp environment was created before
4292          variable_context was incremented. */
4293       flatten (tempvars, set_context, (VARLIST *)NULL, 0);
4294       vc->flags |= VC_HASTMPVAR;
4295     }
4296   vc->down = shell_variables;
4297   shell_variables->up = vc;
4298
4299   return (shell_variables = vc);
4300 }
4301
4302 static void
4303 push_func_var (data)
4304      PTR_T data;
4305 {
4306   SHELL_VAR *var, *v;
4307
4308   var = (SHELL_VAR *)data;
4309
4310   if (tempvar_p (var) && (posixly_correct || (var->attributes & att_propagate)))
4311     {
4312       /* Make sure we have a hash table to store the variable in while it is
4313          being propagated down to the global variables table.  Create one if
4314          we have to */
4315       if ((vc_isfuncenv (shell_variables) || vc_istempenv (shell_variables)) && shell_variables->table == 0)
4316         shell_variables->table = hash_create (0);
4317       /* XXX - should we set v->context here? */
4318       v = bind_variable_internal (var->name, value_cell (var), shell_variables->table, 0, 0);
4319       if (shell_variables == global_variables)
4320         var->attributes &= ~(att_tempvar|att_propagate);
4321       else
4322         shell_variables->flags |= VC_HASTMPVAR;
4323       v->attributes |= var->attributes;
4324     }
4325   else
4326     stupidly_hack_special_variables (var->name);        /* XXX */
4327
4328   dispose_variable (var);
4329 }
4330
4331 /* Pop the top context off of VCXT and dispose of it, returning the rest of
4332    the stack. */
4333 void
4334 pop_var_context ()
4335 {
4336   VAR_CONTEXT *ret, *vcxt;
4337
4338   vcxt = shell_variables;
4339   if (vc_isfuncenv (vcxt) == 0)
4340     {
4341       internal_error (_("pop_var_context: head of shell_variables not a function context"));
4342       return;
4343     }
4344
4345   if (ret = vcxt->down)
4346     {
4347       ret->up = (VAR_CONTEXT *)NULL;
4348       shell_variables = ret;
4349       if (vcxt->table)
4350         hash_flush (vcxt->table, push_func_var);
4351       dispose_var_context (vcxt);
4352     }
4353   else
4354     internal_error (_("pop_var_context: no global_variables context"));
4355 }
4356
4357 /* Delete the HASH_TABLEs for all variable contexts beginning at VCXT, and
4358    all of the VAR_CONTEXTs except GLOBAL_VARIABLES. */
4359 void
4360 delete_all_contexts (vcxt)
4361      VAR_CONTEXT *vcxt;
4362 {
4363   VAR_CONTEXT *v, *t;
4364
4365   for (v = vcxt; v != global_variables; v = t)
4366     {
4367       t = v->down;
4368       dispose_var_context (v);
4369     }    
4370
4371   delete_all_variables (global_variables->table);
4372   shell_variables = global_variables;
4373 }
4374
4375 /* **************************************************************** */
4376 /*                                                                  */
4377 /*         Pushing and Popping temporary variable scopes            */
4378 /*                                                                  */
4379 /* **************************************************************** */
4380
4381 VAR_CONTEXT *
4382 push_scope (flags, tmpvars)
4383      int flags;
4384      HASH_TABLE *tmpvars;
4385 {
4386   return (push_var_context ((char *)NULL, flags, tmpvars));
4387 }
4388
4389 static void
4390 push_exported_var (data)
4391      PTR_T data;
4392 {
4393   SHELL_VAR *var, *v;
4394
4395   var = (SHELL_VAR *)data;
4396
4397   /* If a temp var had its export attribute set, or it's marked to be
4398      propagated, bind it in the previous scope before disposing it. */
4399   /* XXX - This isn't exactly right, because all tempenv variables have the
4400     export attribute set. */
4401 #if 0
4402   if (exported_p (var) || (var->attributes & att_propagate))
4403 #else
4404   if (tempvar_p (var) && exported_p (var) && (var->attributes & att_propagate))
4405 #endif
4406     {
4407       var->attributes &= ~att_tempvar;          /* XXX */
4408       v = bind_variable_internal (var->name, value_cell (var), shell_variables->table, 0, 0);
4409       if (shell_variables == global_variables)
4410         var->attributes &= ~att_propagate;
4411       v->attributes |= var->attributes;
4412     }
4413   else
4414     stupidly_hack_special_variables (var->name);        /* XXX */
4415
4416   dispose_variable (var);
4417 }
4418
4419 void
4420 pop_scope (is_special)
4421      int is_special;
4422 {
4423   VAR_CONTEXT *vcxt, *ret;
4424
4425   vcxt = shell_variables;
4426   if (vc_istempscope (vcxt) == 0)
4427     {
4428       internal_error (_("pop_scope: head of shell_variables not a temporary environment scope"));
4429       return;
4430     }
4431
4432   ret = vcxt->down;
4433   if (ret)
4434     ret->up = (VAR_CONTEXT *)NULL;
4435
4436   shell_variables = ret;
4437
4438   /* Now we can take care of merging variables in VCXT into set of scopes
4439      whose head is RET (shell_variables). */
4440   FREE (vcxt->name);
4441   if (vcxt->table)
4442     {
4443       if (is_special)
4444         hash_flush (vcxt->table, push_func_var);
4445       else
4446         hash_flush (vcxt->table, push_exported_var);
4447       hash_dispose (vcxt->table);
4448     }
4449   free (vcxt);
4450
4451   sv_ifs ("IFS");       /* XXX here for now */
4452 }
4453
4454 /* **************************************************************** */
4455 /*                                                                  */
4456 /*               Pushing and Popping function contexts              */
4457 /*                                                                  */
4458 /* **************************************************************** */
4459
4460 static WORD_LIST **dollar_arg_stack = (WORD_LIST **)NULL;
4461 static int dollar_arg_stack_slots;
4462 static int dollar_arg_stack_index;
4463
4464 /* XXX - we might want to consider pushing and popping the `getopts' state
4465    when we modify the positional parameters. */
4466 void
4467 push_context (name, is_subshell, tempvars)
4468      char *name;        /* function name */
4469      int is_subshell;
4470      HASH_TABLE *tempvars;
4471 {
4472   if (is_subshell == 0)
4473     push_dollar_vars ();
4474   variable_context++;
4475   push_var_context (name, VC_FUNCENV, tempvars);
4476 }
4477
4478 /* Only called when subshell == 0, so we don't need to check, and can
4479    unconditionally pop the dollar vars off the stack. */
4480 void
4481 pop_context ()
4482 {
4483   pop_dollar_vars ();
4484   variable_context--;
4485   pop_var_context ();
4486
4487   sv_ifs ("IFS");               /* XXX here for now */
4488 }
4489
4490 /* Save the existing positional parameters on a stack. */
4491 void
4492 push_dollar_vars ()
4493 {
4494   if (dollar_arg_stack_index + 2 > dollar_arg_stack_slots)
4495     {
4496       dollar_arg_stack = (WORD_LIST **)
4497         xrealloc (dollar_arg_stack, (dollar_arg_stack_slots += 10)
4498                   * sizeof (WORD_LIST *));
4499     }
4500   dollar_arg_stack[dollar_arg_stack_index++] = list_rest_of_args ();
4501   dollar_arg_stack[dollar_arg_stack_index] = (WORD_LIST *)NULL;
4502 }
4503
4504 /* Restore the positional parameters from our stack. */
4505 void
4506 pop_dollar_vars ()
4507 {
4508   if (!dollar_arg_stack || dollar_arg_stack_index == 0)
4509     return;
4510
4511   remember_args (dollar_arg_stack[--dollar_arg_stack_index], 1);
4512   dispose_words (dollar_arg_stack[dollar_arg_stack_index]);
4513   dollar_arg_stack[dollar_arg_stack_index] = (WORD_LIST *)NULL;
4514   set_dollar_vars_unchanged ();
4515 }
4516
4517 void
4518 dispose_saved_dollar_vars ()
4519 {
4520   if (!dollar_arg_stack || dollar_arg_stack_index == 0)
4521     return;
4522
4523   dispose_words (dollar_arg_stack[dollar_arg_stack_index]);
4524   dollar_arg_stack[dollar_arg_stack_index] = (WORD_LIST *)NULL;
4525 }
4526
4527 /* Manipulate the special BASH_ARGV and BASH_ARGC variables. */
4528
4529 void
4530 push_args (list)
4531      WORD_LIST *list;
4532 {
4533 #if defined (ARRAY_VARS) && defined (DEBUGGER)
4534   SHELL_VAR *bash_argv_v, *bash_argc_v;
4535   ARRAY *bash_argv_a, *bash_argc_a;
4536   WORD_LIST *l;
4537   arrayind_t i;
4538   char *t;
4539
4540   GET_ARRAY_FROM_VAR ("BASH_ARGV", bash_argv_v, bash_argv_a);
4541   GET_ARRAY_FROM_VAR ("BASH_ARGC", bash_argc_v, bash_argc_a);
4542
4543   for (l = list, i = 0; l; l = l->next, i++)
4544     array_push (bash_argv_a, l->word->word);
4545
4546   t = itos (i);
4547   array_push (bash_argc_a, t);
4548   free (t);
4549 #endif /* ARRAY_VARS && DEBUGGER */
4550 }
4551
4552 /* Remove arguments from BASH_ARGV array.  Pop top element off BASH_ARGC
4553    array and use that value as the count of elements to remove from
4554    BASH_ARGV. */
4555 void
4556 pop_args ()
4557 {
4558 #if defined (ARRAY_VARS) && defined (DEBUGGER)
4559   SHELL_VAR *bash_argv_v, *bash_argc_v;
4560   ARRAY *bash_argv_a, *bash_argc_a;
4561   ARRAY_ELEMENT *ce;
4562   intmax_t i;
4563
4564   GET_ARRAY_FROM_VAR ("BASH_ARGV", bash_argv_v, bash_argv_a);
4565   GET_ARRAY_FROM_VAR ("BASH_ARGC", bash_argc_v, bash_argc_a);
4566
4567   ce = array_shift (bash_argc_a, 1, 0);
4568   if (ce == 0 || legal_number (element_value (ce), &i) == 0)
4569     i = 0;
4570
4571   for ( ; i > 0; i--)
4572     array_pop (bash_argv_a);
4573   array_dispose_element (ce);
4574 #endif /* ARRAY_VARS && DEBUGGER */
4575 }
4576
4577 /*************************************************
4578  *                                               *
4579  *      Functions to manage special variables    *
4580  *                                               *
4581  *************************************************/
4582
4583 /* Extern declarations for variables this code has to manage. */
4584 extern int eof_encountered, eof_encountered_limit, ignoreeof;
4585
4586 #if defined (READLINE)
4587 extern int hostname_list_initialized;
4588 #endif
4589
4590 /* An alist of name.function for each special variable.  Most of the
4591    functions don't do much, and in fact, this would be faster with a
4592    switch statement, but by the end of this file, I am sick of switch
4593    statements. */
4594
4595 #define SET_INT_VAR(name, intvar)  intvar = find_variable (name) != 0
4596
4597 /* This table will be sorted with qsort() the first time it's accessed. */
4598 struct name_and_function {
4599   char *name;
4600   sh_sv_func_t *function;
4601 };
4602
4603 static struct name_and_function special_vars[] = {
4604   { "BASH_COMPAT", sv_shcompat },
4605   { "BASH_XTRACEFD", sv_xtracefd },
4606
4607 #if defined (JOB_CONTROL)
4608   { "CHILD_MAX", sv_childmax },
4609 #endif
4610
4611 #if defined (READLINE)
4612 #  if defined (STRICT_POSIX)
4613   { "COLUMNS", sv_winsize },
4614 #  endif
4615   { "COMP_WORDBREAKS", sv_comp_wordbreaks },
4616 #endif
4617
4618   { "FUNCNEST", sv_funcnest },
4619
4620   { "GLOBIGNORE", sv_globignore },
4621
4622 #if defined (HISTORY)
4623   { "HISTCONTROL", sv_history_control },
4624   { "HISTFILESIZE", sv_histsize },
4625   { "HISTIGNORE", sv_histignore },
4626   { "HISTSIZE", sv_histsize },
4627   { "HISTTIMEFORMAT", sv_histtimefmt },
4628 #endif
4629
4630 #if defined (__CYGWIN__)
4631   { "HOME", sv_home },
4632 #endif
4633
4634 #if defined (READLINE)
4635   { "HOSTFILE", sv_hostfile },
4636 #endif
4637
4638   { "IFS", sv_ifs },
4639   { "IGNOREEOF", sv_ignoreeof },
4640
4641   { "LANG", sv_locale },
4642   { "LC_ALL", sv_locale },
4643   { "LC_COLLATE", sv_locale },
4644   { "LC_CTYPE", sv_locale },
4645   { "LC_MESSAGES", sv_locale },
4646   { "LC_NUMERIC", sv_locale },
4647   { "LC_TIME", sv_locale },
4648
4649 #if defined (READLINE) && defined (STRICT_POSIX)
4650   { "LINES", sv_winsize },
4651 #endif
4652
4653   { "MAIL", sv_mail },
4654   { "MAILCHECK", sv_mail },
4655   { "MAILPATH", sv_mail },
4656
4657   { "OPTERR", sv_opterr },
4658   { "OPTIND", sv_optind },
4659
4660   { "PATH", sv_path },
4661   { "POSIXLY_CORRECT", sv_strict_posix },
4662
4663 #if defined (READLINE)
4664   { "TERM", sv_terminal },
4665   { "TERMCAP", sv_terminal },
4666   { "TERMINFO", sv_terminal },
4667 #endif /* READLINE */
4668
4669   { "TEXTDOMAIN", sv_locale },
4670   { "TEXTDOMAINDIR", sv_locale },
4671
4672 #if defined (HAVE_TZSET)
4673   { "TZ", sv_tz },
4674 #endif
4675
4676 #if defined (HISTORY) && defined (BANG_HISTORY)
4677   { "histchars", sv_histchars },
4678 #endif /* HISTORY && BANG_HISTORY */
4679
4680   { "ignoreeof", sv_ignoreeof },
4681
4682   { (char *)0, (sh_sv_func_t *)0 }
4683 };
4684
4685 #define N_SPECIAL_VARS  (sizeof (special_vars) / sizeof (special_vars[0]) - 1)
4686
4687 static int
4688 sv_compare (sv1, sv2)
4689      struct name_and_function *sv1, *sv2;
4690 {
4691   int r;
4692
4693   if ((r = sv1->name[0] - sv2->name[0]) == 0)
4694     r = strcmp (sv1->name, sv2->name);
4695   return r;
4696 }
4697
4698 static inline int
4699 find_special_var (name)
4700      const char *name;
4701 {
4702   register int i, r;
4703
4704   for (i = 0; special_vars[i].name; i++)
4705     {
4706       r = special_vars[i].name[0] - name[0];
4707       if (r == 0)
4708         r = strcmp (special_vars[i].name, name);
4709       if (r == 0)
4710         return i;
4711       else if (r > 0)
4712         /* Can't match any of rest of elements in sorted list.  Take this out
4713            if it causes problems in certain environments. */
4714         break;
4715     }
4716   return -1;
4717 }
4718
4719 /* The variable in NAME has just had its state changed.  Check to see if it
4720    is one of the special ones where something special happens. */
4721 void
4722 stupidly_hack_special_variables (name)
4723      char *name;
4724 {
4725   static int sv_sorted = 0;
4726   int i;
4727
4728   if (sv_sorted == 0)   /* shouldn't need, but it's fairly cheap. */
4729     {
4730       qsort (special_vars, N_SPECIAL_VARS, sizeof (special_vars[0]),
4731                 (QSFUNC *)sv_compare);
4732       sv_sorted = 1;
4733     }
4734
4735   i = find_special_var (name);
4736   if (i != -1)
4737     (*(special_vars[i].function)) (name);
4738 }
4739
4740 /* Special variables that need hooks to be run when they are unset as part
4741    of shell reinitialization should have their sv_ functions run here. */
4742 void
4743 reinit_special_variables ()
4744 {
4745 #if defined (READLINE)
4746   sv_comp_wordbreaks ("COMP_WORDBREAKS");
4747 #endif
4748   sv_globignore ("GLOBIGNORE");
4749   sv_opterr ("OPTERR");
4750 }
4751
4752 void
4753 sv_ifs (name)
4754      char *name;
4755 {
4756   SHELL_VAR *v;
4757
4758   v = find_variable ("IFS");
4759   setifs (v);
4760 }
4761
4762 /* What to do just after the PATH variable has changed. */
4763 void
4764 sv_path (name)
4765      char *name;
4766 {
4767   /* hash -r */
4768   phash_flush ();
4769 }
4770
4771 /* What to do just after one of the MAILxxxx variables has changed.  NAME
4772    is the name of the variable.  This is called with NAME set to one of
4773    MAIL, MAILCHECK, or MAILPATH.  */
4774 void
4775 sv_mail (name)
4776      char *name;
4777 {
4778   /* If the time interval for checking the files has changed, then
4779      reset the mail timer.  Otherwise, one of the pathname vars
4780      to the users mailbox has changed, so rebuild the array of
4781      filenames. */
4782   if (name[4] == 'C')  /* if (strcmp (name, "MAILCHECK") == 0) */
4783     reset_mail_timer ();
4784   else
4785     {
4786       free_mail_files ();
4787       remember_mail_dates ();
4788     }
4789 }
4790
4791 void
4792 sv_funcnest (name)
4793      char *name;
4794 {
4795   SHELL_VAR *v;
4796   intmax_t num;
4797
4798   v = find_variable (name);
4799   if (v == 0)
4800     funcnest_max = 0;
4801   else if (legal_number (value_cell (v), &num) == 0)
4802     funcnest_max = 0;
4803   else
4804     funcnest_max = num;
4805 }
4806
4807 /* What to do when GLOBIGNORE changes. */
4808 void
4809 sv_globignore (name)
4810      char *name;
4811 {
4812   if (privileged_mode == 0)
4813     setup_glob_ignore (name);
4814 }
4815
4816 #if defined (READLINE)
4817 void
4818 sv_comp_wordbreaks (name)
4819      char *name;
4820 {
4821   SHELL_VAR *sv;
4822
4823   sv = find_variable (name);
4824   if (sv == 0)
4825     reset_completer_word_break_chars ();
4826 }
4827
4828 /* What to do just after one of the TERMxxx variables has changed.
4829    If we are an interactive shell, then try to reset the terminal
4830    information in readline. */
4831 void
4832 sv_terminal (name)
4833      char *name;
4834 {
4835   if (interactive_shell && no_line_editing == 0)
4836     rl_reset_terminal (get_string_value ("TERM"));
4837 }
4838
4839 void
4840 sv_hostfile (name)
4841      char *name;
4842 {
4843   SHELL_VAR *v;
4844
4845   v = find_variable (name);
4846   if (v == 0)
4847     clear_hostname_list ();
4848   else
4849     hostname_list_initialized = 0;
4850 }
4851
4852 #if defined (STRICT_POSIX)
4853 /* In strict posix mode, we allow assignments to LINES and COLUMNS (and values
4854    found in the initial environment) to override the terminal size reported by
4855    the kernel. */
4856 void
4857 sv_winsize (name)
4858      char *name;
4859 {
4860   SHELL_VAR *v;
4861   intmax_t xd;
4862   int d;
4863
4864   if (posixly_correct == 0 || interactive_shell == 0 || no_line_editing)
4865     return;
4866
4867   v = find_variable (name);
4868   if (v == 0 || var_isnull (v))
4869     rl_reset_screen_size ();
4870   else
4871     {
4872       if (legal_number (value_cell (v), &xd) == 0)
4873         return;
4874       winsize_assignment = 1;
4875       d = xd;                   /* truncate */
4876       if (name[0] == 'L')       /* LINES */
4877         rl_set_screen_size (d, -1);
4878       else                      /* COLUMNS */
4879         rl_set_screen_size (-1, d);
4880       winsize_assignment = 0;
4881     }
4882 }
4883 #endif /* STRICT_POSIX */
4884 #endif /* READLINE */
4885
4886 /* Update the value of HOME in the export environment so tilde expansion will
4887    work on cygwin. */
4888 #if defined (__CYGWIN__)
4889 sv_home (name)
4890      char *name;
4891 {
4892   array_needs_making = 1;
4893   maybe_make_export_env ();
4894 }
4895 #endif
4896
4897 #if defined (HISTORY)
4898 /* What to do after the HISTSIZE or HISTFILESIZE variables change.
4899    If there is a value for this HISTSIZE (and it is numeric), then stifle
4900    the history.  Otherwise, if there is NO value for this variable,
4901    unstifle the history.  If name is HISTFILESIZE, and its value is
4902    numeric, truncate the history file to hold no more than that many
4903    lines. */
4904 void
4905 sv_histsize (name)
4906      char *name;
4907 {
4908   char *temp;
4909   intmax_t num;
4910   int hmax;
4911
4912   temp = get_string_value (name);
4913
4914   if (temp && *temp)
4915     {
4916       if (legal_number (temp, &num))
4917         {
4918           hmax = num;
4919           if (hmax < 0 && name[4] == 'S')
4920             unstifle_history ();        /* unstifle history if HISTSIZE < 0 */
4921           else if (name[4] == 'S')
4922             {
4923               stifle_history (hmax);
4924               hmax = where_history ();
4925               if (history_lines_this_session > hmax)
4926                 history_lines_this_session = hmax;
4927             }
4928           else if (hmax >= 0)   /* truncate HISTFILE if HISTFILESIZE >= 0 */
4929             {
4930               history_truncate_file (get_string_value ("HISTFILE"), hmax);
4931               if (hmax <= history_lines_in_file)
4932                 history_lines_in_file = hmax;
4933             }
4934         }
4935     }
4936   else if (name[4] == 'S')
4937     unstifle_history ();
4938 }
4939
4940 /* What to do after the HISTIGNORE variable changes. */
4941 void
4942 sv_histignore (name)
4943      char *name;
4944 {
4945   setup_history_ignore (name);
4946 }
4947
4948 /* What to do after the HISTCONTROL variable changes. */
4949 void
4950 sv_history_control (name)
4951      char *name;
4952 {
4953   char *temp;
4954   char *val;
4955   int tptr;
4956
4957   history_control = 0;
4958   temp = get_string_value (name);
4959
4960   if (temp == 0 || *temp == 0)
4961     return;
4962
4963   tptr = 0;
4964   while (val = extract_colon_unit (temp, &tptr))
4965     {
4966       if (STREQ (val, "ignorespace"))
4967         history_control |= HC_IGNSPACE;
4968       else if (STREQ (val, "ignoredups"))
4969         history_control |= HC_IGNDUPS;
4970       else if (STREQ (val, "ignoreboth"))
4971         history_control |= HC_IGNBOTH;
4972       else if (STREQ (val, "erasedups"))
4973         history_control |= HC_ERASEDUPS;
4974
4975       free (val);
4976     }
4977 }
4978
4979 #if defined (BANG_HISTORY)
4980 /* Setting/unsetting of the history expansion character. */
4981 void
4982 sv_histchars (name)
4983      char *name;
4984 {
4985   char *temp;
4986
4987   temp = get_string_value (name);
4988   if (temp)
4989     {
4990       history_expansion_char = *temp;
4991       if (temp[0] && temp[1])
4992         {
4993           history_subst_char = temp[1];
4994           if (temp[2])
4995               history_comment_char = temp[2];
4996         }
4997     }
4998   else
4999     {
5000       history_expansion_char = '!';
5001       history_subst_char = '^';
5002       history_comment_char = '#';
5003     }
5004 }
5005 #endif /* BANG_HISTORY */
5006
5007 void
5008 sv_histtimefmt (name)
5009      char *name;
5010 {
5011   SHELL_VAR *v;
5012
5013   if (v = find_variable (name))
5014     {
5015       if (history_comment_char == 0)
5016         history_comment_char = '#';
5017     }
5018   history_write_timestamps = (v != 0);
5019 }
5020 #endif /* HISTORY */
5021
5022 #if defined (HAVE_TZSET)
5023 void
5024 sv_tz (name)
5025      char *name;
5026 {
5027   if (chkexport (name))
5028     tzset ();
5029 }
5030 #endif
5031
5032 /* If the variable exists, then the value of it can be the number
5033    of times we actually ignore the EOF.  The default is small,
5034    (smaller than csh, anyway). */
5035 void
5036 sv_ignoreeof (name)
5037      char *name;
5038 {
5039   SHELL_VAR *tmp_var;
5040   char *temp;
5041
5042   eof_encountered = 0;
5043
5044   tmp_var = find_variable (name);
5045   ignoreeof = tmp_var != 0;
5046   temp = tmp_var ? value_cell (tmp_var) : (char *)NULL;
5047   if (temp)
5048     eof_encountered_limit = (*temp && all_digits (temp)) ? atoi (temp) : 10;
5049   set_shellopts ();     /* make sure `ignoreeof' is/is not in $SHELLOPTS */
5050 }
5051
5052 void
5053 sv_optind (name)
5054      char *name;
5055 {
5056   char *tt;
5057   int s;
5058
5059   tt = get_string_value ("OPTIND");
5060   if (tt && *tt)
5061     {
5062       s = atoi (tt);
5063
5064       /* According to POSIX, setting OPTIND=1 resets the internal state
5065          of getopt (). */
5066       if (s < 0 || s == 1)
5067         s = 0;
5068     }
5069   else
5070     s = 0;
5071   getopts_reset (s);
5072 }
5073
5074 void
5075 sv_opterr (name)
5076      char *name;
5077 {
5078   char *tt;
5079
5080   tt = get_string_value ("OPTERR");
5081   sh_opterr = (tt && *tt) ? atoi (tt) : 1;
5082 }
5083
5084 void
5085 sv_strict_posix (name)
5086      char *name;
5087 {
5088   SET_INT_VAR (name, posixly_correct);
5089   posix_initialize (posixly_correct);
5090 #if defined (READLINE)
5091   if (interactive_shell)
5092     posix_readline_initialize (posixly_correct);
5093 #endif /* READLINE */
5094   set_shellopts ();     /* make sure `posix' is/is not in $SHELLOPTS */
5095 }
5096
5097 void
5098 sv_locale (name)
5099      char *name;
5100 {
5101   char *v;
5102   int r;
5103
5104   v = get_string_value (name);
5105   if (name[0] == 'L' && name[1] == 'A') /* LANG */
5106     r = set_lang (name, v);
5107   else
5108     r = set_locale_var (name, v);               /* LC_*, TEXTDOMAIN* */
5109
5110 #if 1
5111   if (r == 0 && posixly_correct)
5112     last_command_exit_value = 1;
5113 #endif
5114 }
5115
5116 #if defined (ARRAY_VARS)
5117 void
5118 set_pipestatus_array (ps, nproc)
5119      int *ps;
5120      int nproc;
5121 {
5122   SHELL_VAR *v;
5123   ARRAY *a;
5124   ARRAY_ELEMENT *ae;
5125   register int i;
5126   char *t, tbuf[INT_STRLEN_BOUND(int) + 1];
5127
5128   v = find_variable ("PIPESTATUS");
5129   if (v == 0)
5130     v = make_new_array_variable ("PIPESTATUS");
5131   if (array_p (v) == 0)
5132     return;             /* Do nothing if not an array variable. */
5133   a = array_cell (v);
5134
5135   if (a == 0 || array_num_elements (a) == 0)
5136     {
5137       for (i = 0; i < nproc; i++)       /* was ps[i] != -1, not i < nproc */
5138         {
5139           t = inttostr (ps[i], tbuf, sizeof (tbuf));
5140           array_insert (a, i, t);
5141         }
5142       return;
5143     }
5144
5145   /* Fast case */
5146   if (array_num_elements (a) == nproc && nproc == 1)
5147     {
5148       ae = element_forw (a->head);
5149       free (element_value (ae));
5150       ae->value = itos (ps[0]);
5151     }
5152   else if (array_num_elements (a) <= nproc)
5153     {
5154       /* modify in array_num_elements members in place, then add */
5155       ae = a->head;
5156       for (i = 0; i < array_num_elements (a); i++)
5157         {
5158           ae = element_forw (ae);
5159           free (element_value (ae));
5160           ae->value = itos (ps[i]);
5161         }
5162       /* add any more */
5163       for ( ; i < nproc; i++)
5164         {
5165           t = inttostr (ps[i], tbuf, sizeof (tbuf));
5166           array_insert (a, i, t);
5167         }
5168     }
5169   else
5170     {
5171       /* deleting elements.  it's faster to rebuild the array. */         
5172       array_flush (a);
5173       for (i = 0; ps[i] != -1; i++)
5174         {
5175           t = inttostr (ps[i], tbuf, sizeof (tbuf));
5176           array_insert (a, i, t);
5177         }
5178     }
5179 }
5180
5181 ARRAY *
5182 save_pipestatus_array ()
5183 {
5184   SHELL_VAR *v;
5185   ARRAY *a, *a2;
5186
5187   v = find_variable ("PIPESTATUS");
5188   if (v == 0 || array_p (v) == 0 || array_cell (v) == 0)
5189     return ((ARRAY *)NULL);
5190     
5191   a = array_cell (v);
5192   a2 = array_copy (array_cell (v));
5193
5194   return a2;
5195 }
5196
5197 void
5198 restore_pipestatus_array (a)
5199      ARRAY *a;
5200 {
5201   SHELL_VAR *v;
5202   ARRAY *a2;
5203
5204   v = find_variable ("PIPESTATUS");
5205   /* XXX - should we still assign even if existing value is NULL? */
5206   if (v == 0 || array_p (v) == 0 || array_cell (v) == 0)
5207     return;
5208
5209   a2 = array_cell (v);
5210   var_setarray (v, a); 
5211
5212   array_dispose (a2);
5213 }
5214 #endif
5215
5216 void
5217 set_pipestatus_from_exit (s)
5218      int s;
5219 {
5220 #if defined (ARRAY_VARS)
5221   static int v[2] = { 0, -1 };
5222
5223   v[0] = s;
5224   set_pipestatus_array (v, 1);
5225 #endif
5226 }
5227
5228 void
5229 sv_xtracefd (name)
5230      char *name;
5231 {
5232   SHELL_VAR *v;
5233   char *t, *e;
5234   int fd;
5235   FILE *fp;
5236
5237   v = find_variable (name);
5238   if (v == 0)
5239     {
5240       xtrace_reset ();
5241       return;
5242     }
5243
5244   t = value_cell (v);
5245   if (t == 0 || *t == 0)
5246     xtrace_reset ();
5247   else
5248     {
5249       fd = (int)strtol (t, &e, 10);
5250       if (e != t && *e == '\0' && sh_validfd (fd))
5251         {
5252           fp = fdopen (fd, "w");
5253           if (fp == 0)
5254             internal_error (_("%s: %s: cannot open as FILE"), name, value_cell (v));
5255           else
5256             xtrace_set (fd, fp);
5257         }
5258       else
5259         internal_error (_("%s: %s: invalid value for trace file descriptor"), name, value_cell (v));
5260     }
5261 }
5262
5263 #define MIN_COMPAT_LEVEL 31
5264
5265 void
5266 sv_shcompat (name)
5267      char *name;
5268 {
5269   SHELL_VAR *v;
5270   char *val;
5271   int tens, ones, compatval;
5272
5273   v = find_variable (name);
5274   if (v == 0)
5275     {
5276       shell_compatibility_level = DEFAULT_COMPAT_LEVEL;
5277       set_compatibility_opts ();
5278       return;
5279     }
5280   val = value_cell (v);
5281   if (val == 0 || *val == '\0')
5282     {
5283       shell_compatibility_level = DEFAULT_COMPAT_LEVEL;
5284       set_compatibility_opts ();
5285       return;
5286     }
5287   /* Handle decimal-like compatibility version specifications: 4.2 */
5288   if (isdigit (val[0]) && val[1] == '.' && isdigit (val[2]) && val[3] == 0)
5289     {
5290       tens = val[0] - '0';
5291       ones = val[2] - '0';
5292       compatval = tens*10 + ones;
5293     }
5294   /* Handle integer-like compatibility version specifications: 42 */
5295   else if (isdigit (val[0]) && isdigit (val[1]) && val[2] == 0)
5296     {
5297       tens = val[0] - '0';
5298       ones = val[1] - '0';
5299       compatval = tens*10 + ones;
5300     }
5301   else
5302     {
5303 compat_error:
5304       internal_error (_("%s: %s: compatibility value out of range"), name, val);
5305       shell_compatibility_level = DEFAULT_COMPAT_LEVEL;
5306       set_compatibility_opts ();
5307       return;
5308     }
5309
5310   if (compatval < MIN_COMPAT_LEVEL || compatval > DEFAULT_COMPAT_LEVEL)
5311     goto compat_error;
5312
5313   shell_compatibility_level = compatval;
5314   set_compatibility_opts ();
5315 }
5316
5317 #if defined (JOB_CONTROL)
5318 void
5319 sv_childmax (name)
5320      char *name;
5321 {
5322   char *tt;
5323   int s;
5324
5325   tt = get_string_value (name);
5326   s = (tt && *tt) ? atoi (tt) : 0;
5327   set_maxchild (s);
5328 }
5329 #endif