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