024c05fe85ac5c0e072d8ed16a99b2769dfb4453
[platform/upstream/bash.git] / variables.c
1 /* variables.c -- Functions for hacking shell variables. */
2
3 /* Copyright (C) 1987-2004 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 it
8    under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2, or (at your option)
10    any later version.
11
12    Bash is distributed in the hope that it will be useful, but WITHOUT
13    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14    or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
15    License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with Bash; see the file COPYING.  If not, write to the Free
19    Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
20
21 #include "config.h"
22
23 #include "bashtypes.h"
24 #include "posixstat.h"
25 #include "posixtime.h"
26
27 #if defined (qnx)
28 #  include <sys/vc.h>
29 #endif
30
31 #if defined (HAVE_UNISTD_H)
32 #  include <unistd.h>
33 #endif
34
35 #include <stdio.h>
36 #include "chartypes.h"
37 #include <pwd.h>
38 #include "bashansi.h"
39 #include "bashintl.h"
40
41 #include "shell.h"
42 #include "flags.h"
43 #include "execute_cmd.h"
44 #include "findcmd.h"
45 #include "mailcheck.h"
46 #include "input.h"
47 #include "hashcmd.h"
48 #include "pathexp.h"
49
50 #include "builtins/getopt.h"
51 #include "builtins/common.h"
52
53 #if defined (READLINE)
54 #  include "bashline.h"
55 #  include <readline/readline.h>
56 #else
57 #  include <tilde/tilde.h>
58 #endif
59
60 #if defined (HISTORY)
61 #  include "bashhist.h"
62 #  include <readline/history.h>
63 #endif /* HISTORY */
64
65 #if defined (PROGRAMMABLE_COMPLETION)
66 #  include "pcomplete.h"
67 #endif
68
69 #define TEMPENV_HASH_BUCKETS    4       /* must be power of two */
70
71 #define ifsname(s)      ((s)[0] == 'I' && (s)[1] == 'F' && (s)[2] == 'S' && (s)[3] == '\0')
72
73 /* Variables used here and defined in other files. */
74 extern int posixly_correct;
75 extern int line_number;
76 extern int subshell_environment, indirection_level, subshell_level;
77 extern int build_version, patch_level;
78 extern int expanding_redir;
79 extern char *dist_version, *release_status;
80 extern char *shell_name;
81 extern char *primary_prompt, *secondary_prompt;
82 extern char *current_host_name;
83 extern sh_builtin_func_t *this_shell_builtin;
84 extern SHELL_VAR *this_shell_function;
85 extern char *the_printed_command_except_trap;
86 extern char *this_command_name;
87 extern char *command_execution_string;
88 extern time_t shell_start_time;
89
90 #if defined (READLINE)
91 extern int perform_hostname_completion;
92 #endif
93
94 /* The list of shell variables that the user has created at the global
95    scope, or that came from the environment. */
96 VAR_CONTEXT *global_variables = (VAR_CONTEXT *)NULL;
97
98 /* The current list of shell variables, including function scopes */
99 VAR_CONTEXT *shell_variables = (VAR_CONTEXT *)NULL;
100
101 /* The list of shell functions that the user has created, or that came from
102    the environment. */
103 HASH_TABLE *shell_functions = (HASH_TABLE *)NULL;
104
105 #if defined (DEBUGGER)
106 /* The table of shell function definitions that the user defined or that
107    came from the environment. */
108 HASH_TABLE *shell_function_defs = (HASH_TABLE *)NULL;
109 #endif
110
111 /* The current variable context.  This is really a count of how deep into
112    executing functions we are. */
113 int variable_context = 0;
114
115 /* The set of shell assignments which are made only in the environment
116    for a single command. */
117 HASH_TABLE *temporary_env = (HASH_TABLE *)NULL;
118
119 /* Set to non-zero if an assignment error occurs while putting variables
120    into the temporary environment. */
121 int tempenv_assign_error;
122
123 /* Some funky variables which are known about specially.  Here is where
124    "$*", "$1", and all the cruft is kept. */
125 char *dollar_vars[10];
126 WORD_LIST *rest_of_args = (WORD_LIST *)NULL;
127
128 /* The value of $$. */
129 pid_t dollar_dollar_pid;
130
131 /* An array which is passed to commands as their environment.  It is
132    manufactured from the union of the initial environment and the
133    shell variables that are marked for export. */
134 char **export_env = (char **)NULL;
135 static int export_env_index;
136 static int export_env_size;
137
138 /* Non-zero means that we have to remake EXPORT_ENV. */
139 int array_needs_making = 1;
140
141 /* The number of times BASH has been executed.  This is set
142    by initialize_variables (). */
143 int shell_level = 0;
144
145 /* Some forward declarations. */
146 static void set_machine_vars __P((void));
147 static void set_home_var __P((void));
148 static void set_shell_var __P((void));
149 static char *get_bash_name __P((void));
150 static void initialize_shell_level __P((void));
151 static void uidset __P((void));
152 #if defined (ARRAY_VARS)
153 static void make_vers_array __P((void));
154 #endif
155
156 static SHELL_VAR *null_assign __P((SHELL_VAR *, char *, arrayind_t));
157 #if defined (ARRAY_VARS)
158 static SHELL_VAR *null_array_assign __P((SHELL_VAR *, char *, arrayind_t));
159 #endif
160 static SHELL_VAR *get_self __P((SHELL_VAR *));
161
162 #if defined (ARRAY_VARS)
163 static SHELL_VAR *init_dynamic_array_var __P((char *, sh_var_value_func_t *, sh_var_assign_func_t *, int));
164 #endif
165
166 static SHELL_VAR *assign_seconds __P((SHELL_VAR *, char *, arrayind_t));
167 static SHELL_VAR *get_seconds __P((SHELL_VAR *));
168 static SHELL_VAR *init_seconds_var __P((void));
169
170 static int brand __P((void));
171 static void sbrand __P((unsigned long));                /* set bash random number generator. */
172 static SHELL_VAR *assign_random __P((SHELL_VAR *, char *, arrayind_t));
173 static SHELL_VAR *get_random __P((SHELL_VAR *));
174
175 static SHELL_VAR *assign_lineno __P((SHELL_VAR *, char *, arrayind_t));
176 static SHELL_VAR *get_lineno __P((SHELL_VAR *));
177
178 static SHELL_VAR *assign_subshell __P((SHELL_VAR *, char *, arrayind_t));
179 static SHELL_VAR *get_subshell __P((SHELL_VAR *));
180
181 #if defined (HISTORY)
182 static SHELL_VAR *get_histcmd __P((SHELL_VAR *));
183 #endif
184
185 #if defined (PUSHD_AND_POPD) && defined (ARRAY_VARS)
186 static SHELL_VAR *assign_dirstack __P((SHELL_VAR *, char *, arrayind_t));
187 static SHELL_VAR *get_dirstack __P((SHELL_VAR *));
188 #endif
189
190 #if defined (ARRAY_VARS)
191 static SHELL_VAR *get_groupset __P((SHELL_VAR *));
192 #endif
193
194 static SHELL_VAR *get_funcname __P((SHELL_VAR *));
195 static SHELL_VAR *init_funcname_var __P((void));
196
197 static void initialize_dynamic_variables __P((void));
198
199 static SHELL_VAR *hash_lookup __P((const char *, HASH_TABLE *));
200 static SHELL_VAR *new_shell_variable __P((const char *));
201 static SHELL_VAR *make_new_variable __P((const char *, HASH_TABLE *));
202 static SHELL_VAR *bind_variable_internal __P((const char *, char *, HASH_TABLE *, int));
203
204 static void free_variable_hash_data __P((PTR_T));
205
206 static VARLIST *vlist_alloc __P((int));
207 static VARLIST *vlist_realloc __P((VARLIST *, int));
208 static void vlist_add __P((VARLIST *, SHELL_VAR *, int));
209
210 static void flatten __P((HASH_TABLE *, sh_var_map_func_t *, VARLIST *, int));
211
212 static int qsort_var_comp __P((SHELL_VAR **, SHELL_VAR **));
213
214 static SHELL_VAR **vapply __P((sh_var_map_func_t *));
215 static SHELL_VAR **fapply __P((sh_var_map_func_t *));
216
217 static int visible_var __P((SHELL_VAR *));
218 static int visible_and_exported __P((SHELL_VAR *));
219 static int local_and_exported __P((SHELL_VAR *));
220 static int variable_in_context __P((SHELL_VAR *));
221 #if defined (ARRAY_VARS)
222 static int visible_array_vars __P((SHELL_VAR *));
223 #endif
224
225 static SHELL_VAR *bind_tempenv_variable __P((const char *, char *));
226 static void push_temp_var __P((PTR_T));
227 static void propagate_temp_var __P((PTR_T));
228 static void dispose_temporary_env __P((sh_free_func_t *));     
229
230 static inline char *mk_env_string __P((const char *, const char *));
231 static char **make_env_array_from_var_list __P((SHELL_VAR **));
232 static char **make_var_export_array __P((VAR_CONTEXT *));
233 static char **make_func_export_array __P((void));
234 static void add_temp_array_to_env __P((char **, int, int));
235
236 static int n_shell_variables __P((void));
237 static int set_context __P((SHELL_VAR *));
238
239 static void push_func_var __P((PTR_T));
240 static void push_exported_var __P((PTR_T));
241
242 static inline int find_special_var __P((const char *));
243                
244 /* Initialize the shell variables from the current environment.
245    If PRIVMODE is nonzero, don't import functions from ENV or
246    parse $SHELLOPTS. */
247 void
248 initialize_shell_variables (env, privmode)
249      char **env;
250      int privmode;
251 {
252   char *name, *string, *temp_string;
253   int c, char_index, string_index, string_length;
254   SHELL_VAR *temp_var;
255
256   if (shell_variables == 0)
257     {
258       shell_variables = global_variables = new_var_context ((char *)NULL, 0);
259       shell_variables->scope = 0;
260       shell_variables->table = hash_create (0);
261     }
262
263   if (shell_functions == 0)
264     shell_functions = hash_create (0);
265
266 #if defined (DEBUGGER)
267   if (shell_function_defs == 0)
268     shell_function_defs = hash_create (0);
269 #endif
270
271   for (string_index = 0; string = env[string_index++]; )
272     {
273       char_index = 0;
274       name = string;
275       while ((c = *string++) && c != '=')
276         ;
277       if (string[-1] == '=')
278         char_index = string - name - 1;
279
280       /* If there are weird things in the environment, like `=xxx' or a
281          string without an `=', just skip them. */
282       if (char_index == 0)
283         continue;
284
285       /* ASSERT(name[char_index] == '=') */
286       name[char_index] = '\0';
287       /* Now, name = env variable name, string = env variable value, and
288          char_index == strlen (name) */
289
290       /* If exported function, define it now.  Don't import functions from
291          the environment in privileged mode. */
292       if (privmode == 0 && read_but_dont_execute == 0 && STREQN ("() {", string, 4))
293         {
294           string_length = strlen (string);
295           temp_string = (char *)xmalloc (3 + string_length + char_index);
296
297           strcpy (temp_string, name);
298           temp_string[char_index] = ' ';
299           strcpy (temp_string + char_index + 1, string);
300
301           parse_and_execute (temp_string, name, SEVAL_NONINT|SEVAL_NOHIST);
302
303           /* Ancient backwards compatibility.  Old versions of bash exported
304              functions like name()=() {...} */
305           if (name[char_index - 1] == ')' && name[char_index - 2] == '(')
306             name[char_index - 2] = '\0';
307
308           if (temp_var = find_function (name))
309             {
310               VSETATTR (temp_var, (att_exported|att_imported));
311               array_needs_making = 1;
312             }
313           else
314             report_error (_("error importing function definition for `%s'"), name);
315
316           /* ( */
317           if (name[char_index - 1] == ')' && name[char_index - 2] == '\0')
318             name[char_index - 2] = '(';         /* ) */
319         }
320 #if defined (ARRAY_VARS)
321 #  if 0
322       /* Array variables may not yet be exported. */
323       else if (*string == '(' && string[1] == '[' && xstrchr (string, ')'))
324         {
325           string_length = 1;
326           temp_string = extract_array_assignment_list (string, &string_length);
327           temp_var = assign_array_from_string (name, temp_string);
328           FREE (temp_string);
329           VSETATTR (temp_var, (att_exported | att_imported));
330           array_needs_making = 1;
331         }
332 #  endif
333 #endif
334       else
335         {
336           temp_var = bind_variable (name, string);
337           VSETATTR (temp_var, (att_exported | att_imported));
338           array_needs_making = 1;
339         }
340
341       name[char_index] = '=';
342       /* temp_var can be NULL if it was an exported function with a syntax
343          error (a different bug, but it still shouldn't dump core). */
344       if (temp_var && function_p (temp_var) == 0)       /* XXX not yet */
345         {
346           CACHE_IMPORTSTR (temp_var, name);
347         }
348     }
349
350   set_pwd ();
351
352   /* Set up initial value of $_ */
353   temp_var = bind_variable ("_", dollar_vars[0]);
354
355   /* Remember this pid. */
356   dollar_dollar_pid = getpid ();
357
358   /* Now make our own defaults in case the vars that we think are
359      important are missing. */
360   temp_var = set_if_not ("PATH", DEFAULT_PATH_VALUE);
361 #if 0
362   set_auto_export (temp_var);   /* XXX */
363 #endif
364
365   temp_var = set_if_not ("TERM", "dumb");
366 #if 0
367   set_auto_export (temp_var);   /* XXX */
368 #endif
369
370 #if defined (qnx)
371   /* set node id -- don't import it from the environment */
372   {
373     char node_name[22];
374     qnx_nidtostr (getnid (), node_name, sizeof (node_name));
375     temp_var = bind_variable ("NODE", node_name);
376     set_auto_export (temp_var);
377   }
378 #endif
379
380   /* set up the prompts. */
381   if (interactive_shell)
382     {
383 #if defined (PROMPT_STRING_DECODE)
384       set_if_not ("PS1", primary_prompt);
385 #else
386       if (current_user.uid == -1)
387         get_current_user_info ();
388       set_if_not ("PS1", current_user.euid == 0 ? "# " : primary_prompt);
389 #endif
390       set_if_not ("PS2", secondary_prompt);
391     }
392   set_if_not ("PS4", "+ ");
393
394   /* Don't allow IFS to be imported from the environment. */
395   temp_var = bind_variable ("IFS", " \t\n");
396   setifs (temp_var);
397
398   /* Magic machine types.  Pretty convenient. */
399   set_machine_vars ();
400
401   /* Default MAILCHECK for interactive shells.  Defer the creation of a
402      default MAILPATH until the startup files are read, because MAIL
403      names a mail file if MAILPATH is not set, and we should provide a
404      default only if neither is set. */
405   if (interactive_shell)
406     set_if_not ("MAILCHECK", posixly_correct ? "600" : "60");
407
408   /* Do some things with shell level. */
409   initialize_shell_level ();
410
411   set_ppid ();
412
413   /* Initialize the `getopts' stuff. */
414   bind_variable ("OPTIND", "1");
415   getopts_reset (0);
416   bind_variable ("OPTERR", "1");
417   sh_opterr = 1;
418
419   if (login_shell == 1)
420     set_home_var ();
421
422   /* Get the full pathname to THIS shell, and set the BASH variable
423      to it. */
424   name = get_bash_name ();
425   temp_var = bind_variable ("BASH", name);
426   free (name);
427
428   /* Make the exported environment variable SHELL be the user's login
429      shell.  Note that the `tset' command looks at this variable
430      to determine what style of commands to output; if it ends in "csh",
431      then C-shell commands are output, else Bourne shell commands. */
432   set_shell_var ();
433
434   /* Make a variable called BASH_VERSION which contains the version info. */
435   bind_variable ("BASH_VERSION", shell_version_string ());
436 #if defined (ARRAY_VARS)
437   make_vers_array ();
438 #endif
439
440   if (command_execution_string)
441     bind_variable ("BASH_EXECUTION_STRING", command_execution_string);
442
443   /* Find out if we're supposed to be in Posix.2 mode via an
444      environment variable. */
445   temp_var = find_variable ("POSIXLY_CORRECT");
446   if (!temp_var)
447     temp_var = find_variable ("POSIX_PEDANTIC");
448   if (temp_var && imported_p (temp_var))
449     sv_strict_posix (temp_var->name);
450
451 #if defined (HISTORY)
452   /* Set history variables to defaults, and then do whatever we would
453      do if the variable had just been set.  Do this only in the case
454      that we are remembering commands on the history list. */
455   if (remember_on_history)
456     {
457       name = bash_tilde_expand (posixly_correct ? "~/.sh_history" : "~/.bash_history", 0);
458
459       set_if_not ("HISTFILE", name);
460       free (name);
461
462       set_if_not ("HISTSIZE", "500");
463       sv_histsize ("HISTSIZE");
464     }
465 #endif /* HISTORY */
466
467   /* Seed the random number generator. */
468   sbrand (dollar_dollar_pid + shell_start_time);
469
470   /* Handle some "special" variables that we may have inherited from a
471      parent shell. */
472   if (interactive_shell)
473     {
474       temp_var = find_variable ("IGNOREEOF");
475       if (!temp_var)
476         temp_var = find_variable ("ignoreeof");
477       if (temp_var && imported_p (temp_var))
478         sv_ignoreeof (temp_var->name);
479     }
480
481 #if defined (HISTORY)
482   if (interactive_shell && remember_on_history)
483     {
484       sv_history_control ("HISTCONTROL");
485       sv_histignore ("HISTIGNORE");
486     }
487 #endif /* HISTORY */
488
489      /*
490       * 24 October 2001
491       *
492       * I'm tired of the arguing and bug reports.  Bash now leaves SSH_CLIENT
493       * and SSH2_CLIENT alone.  I'm going to rely on the shell_level check in
494       * isnetconn() to avoid running the startup files more often than wanted.
495       * That will, of course, only work if the user's login shell is bash, so
496       * I've made that behavior conditional on SSH_SOURCE_BASHRC being defined
497       * in config-top.h.
498       */
499 #if 0
500   temp_var = find_variable ("SSH_CLIENT");
501   if (temp_var && imported_p (temp_var))
502     {
503       VUNSETATTR (temp_var, att_exported);
504       array_needs_making = 1;
505     }
506   temp_var = find_variable ("SSH2_CLIENT");
507   if (temp_var && imported_p (temp_var))
508     {
509       VUNSETATTR (temp_var, att_exported);
510       array_needs_making = 1;
511     }
512 #endif
513
514   /* Get the user's real and effective user ids. */
515   uidset ();
516
517   /* Initialize the dynamic variables, and seed their values. */
518   initialize_dynamic_variables ();
519 }
520
521 /* **************************************************************** */
522 /*                                                                  */
523 /*           Setting values for special shell variables             */
524 /*                                                                  */
525 /* **************************************************************** */
526
527 static void
528 set_machine_vars ()
529 {
530   SHELL_VAR *temp_var;
531
532   temp_var = set_if_not ("HOSTTYPE", HOSTTYPE);
533   temp_var = set_if_not ("OSTYPE", OSTYPE);
534   temp_var = set_if_not ("MACHTYPE", MACHTYPE);
535
536   temp_var = set_if_not ("HOSTNAME", current_host_name);
537 }
538
539 /* Set $HOME to the information in the password file if we didn't get
540    it from the environment. */
541
542 /* This function is not static so the tilde and readline libraries can
543    use it. */
544 char *
545 sh_get_home_dir ()
546 {
547   if (current_user.home_dir == 0)
548     get_current_user_info ();
549   return current_user.home_dir;
550 }
551
552 static void
553 set_home_var ()
554 {
555   SHELL_VAR *temp_var;
556
557   temp_var = find_variable ("HOME");
558   if (temp_var == 0)
559     temp_var = bind_variable ("HOME", sh_get_home_dir ());
560 #if 0
561   VSETATTR (temp_var, att_exported);
562 #endif
563 }
564
565 /* Set $SHELL to the user's login shell if it is not already set.  Call
566    get_current_user_info if we haven't already fetched the shell. */
567 static void
568 set_shell_var ()
569 {
570   SHELL_VAR *temp_var;
571
572   temp_var = find_variable ("SHELL");
573   if (temp_var == 0)
574     {
575       if (current_user.shell == 0)
576         get_current_user_info ();
577       temp_var = bind_variable ("SHELL", current_user.shell);
578     }
579 #if 0
580   VSETATTR (temp_var, att_exported);
581 #endif
582 }
583
584 static char *
585 get_bash_name ()
586 {
587   char *name;
588
589   if ((login_shell == 1) && RELPATH(shell_name))
590     {
591       if (current_user.shell == 0)
592         get_current_user_info ();
593       name = savestring (current_user.shell);
594     }
595   else if (ABSPATH(shell_name))
596     name = savestring (shell_name);
597   else if (shell_name[0] == '.' && shell_name[1] == '/')
598     {
599       /* Fast path for common case. */
600       char *cdir;
601       int len;
602
603       cdir = get_string_value ("PWD");
604       if (cdir)
605         {
606           len = strlen (cdir);
607           name = (char *)xmalloc (len + strlen (shell_name) + 1);
608           strcpy (name, cdir);
609           strcpy (name + len, shell_name + 1);
610         }
611       else
612         name = savestring (shell_name);
613     }
614   else
615     {
616       char *tname;
617       int s;
618
619       tname = find_user_command (shell_name);
620
621       if (tname == 0)
622         {
623           /* Try the current directory.  If there is not an executable
624              there, just punt and use the login shell. */
625           s = file_status (shell_name);
626           if (s & FS_EXECABLE)
627             {
628               tname = make_absolute (shell_name, get_string_value ("PWD"));
629               if (*shell_name == '.')
630                 {
631                   name = sh_canonpath (tname, PATH_CHECKDOTDOT|PATH_CHECKEXISTS);
632                   if (name == 0)
633                     name = tname;
634                   else
635                     free (tname);
636                 }
637              else
638                 name = tname;
639             }
640           else
641             {
642               if (current_user.shell == 0)
643                 get_current_user_info ();
644               name = savestring (current_user.shell);
645             }
646         }
647       else
648         {
649           name = full_pathname (tname);
650           free (tname);
651         }
652     }
653
654   return (name);
655 }
656
657 void
658 adjust_shell_level (change)
659      int change;
660 {
661   char new_level[5], *old_SHLVL;
662   intmax_t old_level;
663   SHELL_VAR *temp_var;
664
665   old_SHLVL = get_string_value ("SHLVL");
666   if (old_SHLVL == 0 || *old_SHLVL == '\0' || legal_number (old_SHLVL, &old_level) == 0)
667     old_level = 0;
668
669   shell_level = old_level + change;
670   if (shell_level < 0)
671     shell_level = 0;
672   else if (shell_level > 1000)
673     {
674       internal_warning (_("shell level (%d) too high, resetting to 1"), shell_level);
675       shell_level = 1;
676     }
677
678   /* We don't need the full generality of itos here. */
679   if (shell_level < 10)
680     {
681       new_level[0] = shell_level + '0';
682       new_level[1] = '\0';
683     }
684   else if (shell_level < 100)
685     {
686       new_level[0] = (shell_level / 10) + '0';
687       new_level[1] = (shell_level % 10) + '0';
688       new_level[2] = '\0';
689     }
690   else if (shell_level < 1000)
691     {
692       new_level[0] = (shell_level / 100) + '0';
693       old_level = shell_level % 100;
694       new_level[1] = (old_level / 10) + '0';
695       new_level[2] = (old_level % 10) + '0';
696       new_level[3] = '\0';
697     }
698
699   temp_var = bind_variable ("SHLVL", new_level);
700   set_auto_export (temp_var);
701 }
702
703 static void
704 initialize_shell_level ()
705 {
706   adjust_shell_level (1);
707 }
708
709 /* If we got PWD from the environment, update our idea of the current
710    working directory.  In any case, make sure that PWD exists before
711    checking it.  It is possible for getcwd () to fail on shell startup,
712    and in that case, PWD would be undefined.  If this is an interactive
713    login shell, see if $HOME is the current working directory, and if
714    that's not the same string as $PWD, set PWD=$HOME. */
715
716 void
717 set_pwd ()
718 {
719   SHELL_VAR *temp_var, *home_var;
720   char *temp_string, *home_string;
721
722   home_var = find_variable ("HOME");
723   home_string = home_var ? value_cell (home_var) : (char *)NULL;
724
725   temp_var = find_variable ("PWD");
726   if (temp_var && imported_p (temp_var) &&
727       (temp_string = value_cell (temp_var)) &&
728       same_file (temp_string, ".", (struct stat *)NULL, (struct stat *)NULL))
729     set_working_directory (temp_string);
730   else if (home_string && interactive_shell && login_shell &&
731            same_file (home_string, ".", (struct stat *)NULL, (struct stat *)NULL))
732     {
733       set_working_directory (home_string);
734       temp_var = bind_variable ("PWD", home_string);
735       set_auto_export (temp_var);
736     }
737   else
738     {
739       temp_string = get_working_directory ("shell-init");
740       if (temp_string)
741         {
742           temp_var = bind_variable ("PWD", temp_string);
743           set_auto_export (temp_var);
744           free (temp_string);
745         }
746     }
747
748   /* According to the Single Unix Specification, v2, $OLDPWD is an
749      `environment variable' and therefore should be auto-exported.
750      Make a dummy invisible variable for OLDPWD, and mark it as exported. */
751   temp_var = bind_variable ("OLDPWD", (char *)NULL);
752   VSETATTR (temp_var, (att_exported | att_invisible));
753 }
754
755 /* Make a variable $PPID, which holds the pid of the shell's parent.  */
756 void
757 set_ppid ()
758 {
759   char namebuf[INT_STRLEN_BOUND(pid_t) + 1], *name;
760   SHELL_VAR *temp_var;
761
762   name = inttostr (getppid (), namebuf, sizeof(namebuf));
763   temp_var = find_variable ("PPID");
764   if (temp_var)
765     VUNSETATTR (temp_var, (att_readonly | att_exported));
766   temp_var = bind_variable ("PPID", name);
767   VSETATTR (temp_var, (att_readonly | att_integer));
768 }
769
770 static void
771 uidset ()
772 {
773   char buff[INT_STRLEN_BOUND(uid_t) + 1], *b;
774   register SHELL_VAR *v;
775
776   b = inttostr (current_user.uid, buff, sizeof (buff));
777   v = find_variable ("UID");
778   if (v == 0)
779     {
780       v = bind_variable ("UID", b);
781       VSETATTR (v, (att_readonly | att_integer));
782     }
783
784   if (current_user.euid != current_user.uid)
785     b = inttostr (current_user.euid, buff, sizeof (buff));
786
787   v = find_variable ("EUID");
788   if (v == 0)
789     {
790       v = bind_variable ("EUID", b);
791       VSETATTR (v, (att_readonly | att_integer));
792     }
793 }
794
795 #if defined (ARRAY_VARS)
796 static void
797 make_vers_array ()
798 {
799   SHELL_VAR *vv;
800   ARRAY *av;
801   char *s, d[32], b[INT_STRLEN_BOUND(int) + 1];
802
803   unbind_variable ("BASH_VERSINFO");
804
805   vv = make_new_array_variable ("BASH_VERSINFO");
806   av = array_cell (vv);
807   strcpy (d, dist_version);
808   s = xstrchr (d, '.');
809   if (s)
810     *s++ = '\0';
811   array_insert (av, 0, d);
812   array_insert (av, 1, s);
813   s = inttostr (patch_level, b, sizeof (b));
814   array_insert (av, 2, s);
815   s = inttostr (build_version, b, sizeof (b));
816   array_insert (av, 3, s);
817   array_insert (av, 4, release_status);
818   array_insert (av, 5, MACHTYPE);
819
820   VSETATTR (vv, att_readonly);
821 }
822 #endif /* ARRAY_VARS */
823
824 /* Set the environment variables $LINES and $COLUMNS in response to
825    a window size change. */
826 void
827 sh_set_lines_and_columns (lines, cols)
828      int lines, cols;
829 {
830   char val[INT_STRLEN_BOUND(int) + 1], *v;
831
832   v = inttostr (lines, val, sizeof (val));
833   bind_variable ("LINES", v);
834
835   v = inttostr (cols, val, sizeof (val));
836   bind_variable ("COLUMNS", v);
837 }
838
839 /* **************************************************************** */
840 /*                                                                  */
841 /*                 Printing variables and values                    */
842 /*                                                                  */
843 /* **************************************************************** */
844
845 /* Print LIST (a list of shell variables) to stdout in such a way that
846    they can be read back in. */
847 void
848 print_var_list (list)
849      register SHELL_VAR **list;
850 {
851   register int i;
852   register SHELL_VAR *var;
853
854   for (i = 0; list && (var = list[i]); i++)
855     if (invisible_p (var) == 0)
856       print_assignment (var);
857 }
858
859 /* Print LIST (a list of shell functions) to stdout in such a way that
860    they can be read back in. */
861 void
862 print_func_list (list)
863      register SHELL_VAR **list;
864 {
865   register int i;
866   register SHELL_VAR *var;
867
868   for (i = 0; list && (var = list[i]); i++)
869     {
870       printf ("%s ", var->name);
871       print_var_function (var);
872       printf ("\n");
873     }
874 }
875       
876 /* Print the value of a single SHELL_VAR.  No newline is
877    output, but the variable is printed in such a way that
878    it can be read back in. */
879 void
880 print_assignment (var)
881      SHELL_VAR *var;
882 {
883   if (var_isset (var) == 0)
884     return;
885
886   if (function_p (var))
887     {
888       printf ("%s", var->name);
889       print_var_function (var);
890       printf ("\n");
891     }
892 #if defined (ARRAY_VARS)
893   else if (array_p (var))
894     print_array_assignment (var, 0);
895 #endif /* ARRAY_VARS */
896   else
897     {
898       printf ("%s=", var->name);
899       print_var_value (var, 1);
900       printf ("\n");
901     }
902 }
903
904 /* Print the value cell of VAR, a shell variable.  Do not print
905    the name, nor leading/trailing newline.  If QUOTE is non-zero,
906    and the value contains shell metacharacters, quote the value
907    in such a way that it can be read back in. */
908 void
909 print_var_value (var, quote)
910      SHELL_VAR *var;
911      int quote;
912 {
913   char *t;
914
915   if (var_isset (var) == 0)
916     return;
917
918   if (quote && posixly_correct == 0 && ansic_shouldquote (value_cell (var)))
919     {
920       t = ansic_quote (value_cell (var), 0, (int *)0);
921       printf ("%s", t);
922       free (t);
923     }
924   else if (quote && sh_contains_shell_metas (value_cell (var)))
925     {
926       t = sh_single_quote (value_cell (var));
927       printf ("%s", t);
928       free (t);
929     }
930   else
931     printf ("%s", value_cell (var));
932 }
933
934 /* Print the function cell of VAR, a shell variable.  Do not
935    print the name, nor leading/trailing newline. */
936 void
937 print_var_function (var)
938      SHELL_VAR *var;
939 {
940   if (function_p (var) && var_isset (var))
941     printf ("%s", named_function_string ((char *)NULL, function_cell(var), 1));
942 }
943
944 /* **************************************************************** */
945 /*                                                                  */
946 /*                      Dynamic Variables                           */
947 /*                                                                  */
948 /* **************************************************************** */
949
950 /* DYNAMIC VARIABLES
951
952    These are variables whose values are generated anew each time they are
953    referenced.  These are implemented using a pair of function pointers
954    in the struct variable: assign_func, which is called from bind_variable
955    and, if arrays are compiled into the shell, some of the functions in
956    arrayfunc.c, and dynamic_value, which is called from find_variable.
957
958    assign_func is called from bind_variable_internal, if
959    bind_variable_internal discovers that the variable being assigned to
960    has such a function.  The function is called as
961         SHELL_VAR *temp = (*(entry->assign_func)) (entry, value, ind)
962    and the (SHELL_VAR *)temp is returned as the value of bind_variable.  It
963    is usually ENTRY (self).  IND is an index for an array variable, and
964    unused otherwise.
965
966    dynamic_value is called from find_variable_internal to return a `new'
967    value for the specified dynamic varible.  If this function is NULL,
968    the variable is treated as a `normal' shell variable.  If it is not,
969    however, then this function is called like this:
970         tempvar = (*(var->dynamic_value)) (var);
971
972    Sometimes `tempvar' will replace the value of `var'.  Other times, the
973    shell will simply use the string value.  Pretty object-oriented, huh?
974
975    Be warned, though: if you `unset' a special variable, it loses its
976    special meaning, even if you subsequently set it.
977
978    The special assignment code would probably have been better put in
979    subst.c: do_assignment_internal, in the same style as
980    stupidly_hack_special_variables, but I wanted the changes as
981    localized as possible.  */
982
983 #define INIT_DYNAMIC_VAR(var, val, gfunc, afunc) \
984   do \
985     { \
986       v = bind_variable (var, (val)); \
987       v->dynamic_value = gfunc; \
988       v->assign_func = afunc; \
989     } \
990   while (0)
991
992 #define INIT_DYNAMIC_ARRAY_VAR(var, gfunc, afunc) \
993   do \
994     { \
995       v = make_new_array_variable (var); \
996       v->dynamic_value = gfunc; \
997       v->assign_func = afunc; \
998     } \
999   while (0)
1000
1001 static SHELL_VAR *
1002 null_assign (self, value, unused)
1003      SHELL_VAR *self;
1004      char *value;
1005      arrayind_t unused;
1006 {
1007   return (self);
1008 }
1009
1010 #if defined (ARRAY_VARS)
1011 static SHELL_VAR *
1012 null_array_assign (self, value, ind)
1013      SHELL_VAR *self;
1014      char *value;
1015      arrayind_t ind;
1016 {
1017   return (self);
1018 }
1019 #endif
1020
1021 /* Degenerate `dynamic_value' function; just returns what's passed without
1022    manipulation. */
1023 static SHELL_VAR *
1024 get_self (self)
1025      SHELL_VAR *self;
1026 {
1027   return (self);
1028 }
1029
1030 #if defined (ARRAY_VARS)
1031 /* A generic dynamic array variable initializer.  Intialize array variable
1032    NAME with dynamic value function GETFUNC and assignment function SETFUNC. */
1033 static SHELL_VAR *
1034 init_dynamic_array_var (name, getfunc, setfunc, attrs)
1035      char *name;
1036      sh_var_value_func_t *getfunc;
1037      sh_var_assign_func_t *setfunc;
1038      int attrs;
1039 {
1040   SHELL_VAR *v;
1041
1042   v = find_variable (name);
1043   if (v)
1044     return (v);
1045   INIT_DYNAMIC_ARRAY_VAR (name, getfunc, setfunc);
1046   if (attrs)
1047     VSETATTR (v, attrs);
1048   return v;
1049 }
1050 #endif
1051
1052
1053 /* The value of $SECONDS.  This is the number of seconds since shell
1054    invocation, or, the number of seconds since the last assignment + the
1055    value of the last assignment. */
1056 static intmax_t seconds_value_assigned;
1057
1058 static SHELL_VAR *
1059 assign_seconds (self, value, unused)
1060      SHELL_VAR *self;
1061      char *value;
1062      arrayind_t unused;
1063 {
1064   if (legal_number (value, &seconds_value_assigned) == 0)
1065     seconds_value_assigned = 0;
1066   shell_start_time = NOW;
1067   return (self);
1068 }
1069
1070 static SHELL_VAR *
1071 get_seconds (var)
1072      SHELL_VAR *var;
1073 {
1074   time_t time_since_start;
1075   char *p;
1076
1077   time_since_start = NOW - shell_start_time;
1078   p = itos(seconds_value_assigned + time_since_start);
1079
1080   FREE (value_cell (var));
1081
1082   VSETATTR (var, att_integer);
1083   var_setvalue (var, p);
1084   return (var);
1085 }
1086
1087 static SHELL_VAR *
1088 init_seconds_var ()
1089 {
1090   SHELL_VAR *v;
1091
1092   v = find_variable ("SECONDS");
1093   if (v)
1094     {
1095       if (legal_number (value_cell(v), &seconds_value_assigned) == 0)
1096         seconds_value_assigned = 0;
1097     }
1098   INIT_DYNAMIC_VAR ("SECONDS", (v ? value_cell (v) : (char *)NULL), get_seconds, assign_seconds);
1099   return v;      
1100 }
1101      
1102 /* The random number seed.  You can change this by setting RANDOM. */
1103 static unsigned long rseed = 1;
1104 static int last_random_value;
1105
1106 /* A linear congruential random number generator based on the example
1107    one in the ANSI C standard.  This one isn't very good, but a more
1108    complicated one is overkill. */
1109
1110 /* Returns a pseudo-random number between 0 and 32767. */
1111 static int
1112 brand ()
1113 {
1114   rseed = rseed * 1103515245 + 12345;
1115   return ((unsigned int)((rseed >> 16) & 32767));       /* was % 32768 */
1116 }
1117
1118 /* Set the random number generator seed to SEED. */
1119 static void
1120 sbrand (seed)
1121      unsigned long seed;
1122 {
1123   rseed = seed;
1124   last_random_value = 0;
1125 }
1126
1127 static SHELL_VAR *
1128 assign_random (self, value, unused)
1129      SHELL_VAR *self;
1130      char *value;
1131      arrayind_t unused;
1132 {
1133   sbrand (strtoul (value, (char **)NULL, 10));
1134   return (self);
1135 }
1136
1137 int
1138 get_random_number ()
1139 {
1140   int rv;
1141
1142   /* Reset for command and process substitution. */
1143   if (subshell_environment)
1144     sbrand (rseed + getpid() + NOW);
1145
1146   do
1147     rv = brand ();
1148   while (rv == last_random_value);
1149   return rv;
1150 }
1151
1152 static SHELL_VAR *
1153 get_random (var)
1154      SHELL_VAR *var;
1155 {
1156   int rv;
1157   char *p;
1158
1159   rv = get_random_number ();
1160   last_random_value = rv;
1161   p = itos (rv);
1162
1163   FREE (value_cell (var));
1164
1165   VSETATTR (var, att_integer);
1166   var_setvalue (var, p);
1167   return (var);
1168 }
1169
1170 static SHELL_VAR *
1171 assign_lineno (var, value, unused)
1172      SHELL_VAR *var;
1173      char *value;
1174      arrayind_t unused;
1175 {
1176   intmax_t new_value;
1177
1178   if (value == 0 || *value == '\0' || legal_number (value, &new_value) == 0)
1179     new_value = 0;
1180   line_number = new_value;
1181   return var;
1182 }
1183
1184 /* Function which returns the current line number. */
1185 static SHELL_VAR *
1186 get_lineno (var)
1187      SHELL_VAR *var;
1188 {
1189   char *p;
1190   int ln;
1191
1192   ln = executing_line_number ();
1193   p = itos (ln);
1194   FREE (value_cell (var));
1195   var_setvalue (var, p);
1196   return (var);
1197 }
1198
1199 static SHELL_VAR *
1200 assign_subshell (var, value, unused)
1201      SHELL_VAR *var;
1202      char *value;
1203      arrayind_t unused;
1204 {
1205   intmax_t new_value;
1206
1207   if (value == 0 || *value == '\0' || legal_number (value, &new_value) == 0)
1208     new_value = 0;
1209   subshell_level = new_value;
1210   return var;
1211 }
1212
1213 static SHELL_VAR *
1214 get_subshell (var)
1215      SHELL_VAR *var;
1216 {
1217   char *p;
1218
1219   p = itos (subshell_level);
1220   FREE (value_cell (var));
1221   var_setvalue (var, p);
1222   return (var);
1223 }
1224
1225 static SHELL_VAR *
1226 get_bash_command (var)
1227      SHELL_VAR *var;
1228 {
1229   char *p;
1230
1231   p = savestring (the_printed_command_except_trap);
1232   FREE (value_cell (var));
1233   var_setvalue (var, p);
1234   return (var);
1235 }
1236
1237 #if defined (HISTORY)
1238 static SHELL_VAR *
1239 get_histcmd (var)
1240      SHELL_VAR *var;
1241 {
1242   char *p;
1243
1244   p = itos (history_number ());
1245   FREE (value_cell (var));
1246   var_setvalue (var, p);
1247   return (var);
1248 }
1249 #endif
1250
1251 #if defined (READLINE)
1252 /* When this function returns, VAR->value points to malloced memory. */
1253 static SHELL_VAR *
1254 get_comp_wordbreaks (var)
1255      SHELL_VAR *var;
1256 {
1257   char *p;
1258
1259   /* If we don't have anything yet, assign a default value. */
1260   if (rl_completer_word_break_characters == 0 && bash_readline_initialized == 0)
1261     enable_hostname_completion (perform_hostname_completion);
1262
1263 #if 0
1264   FREE (value_cell (var));
1265   p = savestring (rl_completer_word_break_characters);
1266   
1267   var_setvalue (var, p);
1268 #else
1269   var_setvalue (var, rl_completer_word_break_characters);
1270 #endif
1271
1272   return (var);
1273 }
1274
1275 /* When this function returns, rl_completer_word_break_characters points to
1276    malloced memory. */
1277 static SHELL_VAR *
1278 assign_comp_wordbreaks (self, value, unused)
1279      SHELL_VAR *self;
1280      char *value;
1281      arrayind_t unused;
1282 {
1283   if (rl_completer_word_break_characters &&
1284       rl_completer_word_break_characters != rl_basic_word_break_characters)
1285     free (rl_completer_word_break_characters);
1286
1287   rl_completer_word_break_characters = savestring (value);
1288   return self;
1289 }
1290 #endif /* READLINE */
1291
1292 #if defined (PUSHD_AND_POPD) && defined (ARRAY_VARS)
1293 static SHELL_VAR *
1294 assign_dirstack (self, value, ind)
1295      SHELL_VAR *self;
1296      char *value;
1297      arrayind_t ind;
1298 {
1299   set_dirstack_element (ind, 1, value);
1300   return self;
1301 }
1302
1303 static SHELL_VAR *
1304 get_dirstack (self)
1305      SHELL_VAR *self;
1306 {
1307   ARRAY *a;
1308   WORD_LIST *l;
1309
1310   l = get_directory_stack ();
1311   a = array_from_word_list (l);
1312   array_dispose (array_cell (self));
1313   dispose_words (l);
1314   var_setarray (self, a);
1315   return self;
1316 }
1317 #endif /* PUSHD AND POPD && ARRAY_VARS */
1318
1319 #if defined (ARRAY_VARS)
1320 /* We don't want to initialize the group set with a call to getgroups()
1321    unless we're asked to, but we only want to do it once. */
1322 static SHELL_VAR *
1323 get_groupset (self)
1324      SHELL_VAR *self;
1325 {
1326   register int i;
1327   int ng;
1328   ARRAY *a;
1329   static char **group_set = (char **)NULL;
1330
1331   if (group_set == 0)
1332     {
1333       group_set = get_group_list (&ng);
1334       a = array_cell (self);
1335       for (i = 0; i < ng; i++)
1336         array_insert (a, i, group_set[i]);
1337     }
1338   return (self);
1339 }
1340 #endif /* ARRAY_VARS */
1341
1342 /* If ARRAY_VARS is not defined, this just returns the name of any
1343    currently-executing function.  If we have arrays, it's a call stack. */
1344 static SHELL_VAR *
1345 get_funcname (self)
1346      SHELL_VAR *self;
1347 {
1348 #if ! defined (ARRAY_VARS)
1349   char *t;
1350   if (variable_context && this_shell_function)
1351     {
1352       FREE (value_cell (self));
1353       t = savestring (this_shell_function->name);
1354       var_setvalue (self, t);
1355     }
1356 #endif
1357   return (self);
1358 }
1359
1360 void
1361 make_funcname_visible (on_or_off)
1362      int on_or_off;
1363 {
1364   SHELL_VAR *v;
1365
1366   v = find_variable ("FUNCNAME");
1367   if (v == 0 || v->dynamic_value == 0)
1368     return;
1369
1370   if (on_or_off)
1371     VUNSETATTR (v, att_invisible);
1372   else
1373     VSETATTR (v, att_invisible);
1374 }
1375
1376 static SHELL_VAR *
1377 init_funcname_var ()
1378 {
1379   SHELL_VAR *v;
1380
1381   v = find_variable ("FUNCNAME");
1382   if (v)
1383     return v;
1384 #if defined (ARRAY_VARS)
1385   INIT_DYNAMIC_ARRAY_VAR ("FUNCNAME", get_funcname, null_array_assign);
1386 #else
1387   INIT_DYNAMIC_VAR ("FUNCNAME", (char *)NULL, get_funcname, null_assign);
1388 #endif
1389   VSETATTR (v, att_invisible|att_noassign);
1390   return v;
1391 }
1392
1393 static void
1394 initialize_dynamic_variables ()
1395 {
1396   SHELL_VAR *v;
1397
1398   v = init_seconds_var ();
1399
1400   INIT_DYNAMIC_VAR ("BASH_COMMAND", (char *)NULL, get_bash_command, (sh_var_assign_func_t *)NULL);
1401   INIT_DYNAMIC_VAR ("BASH_SUBSHELL", (char *)NULL, get_subshell, assign_subshell);
1402
1403   INIT_DYNAMIC_VAR ("RANDOM", (char *)NULL, get_random, assign_random);
1404   INIT_DYNAMIC_VAR ("LINENO", (char *)NULL, get_lineno, assign_lineno);
1405
1406 #if defined (HISTORY)
1407   INIT_DYNAMIC_VAR ("HISTCMD", (char *)NULL, get_histcmd, (sh_var_assign_func_t *)NULL);
1408 #endif
1409
1410 #if defined (READLINE)
1411   INIT_DYNAMIC_VAR ("COMP_WORDBREAKS", (char *)NULL, get_comp_wordbreaks, assign_comp_wordbreaks);
1412 #endif
1413
1414 #if defined (PUSHD_AND_POPD) && defined (ARRAY_VARS)
1415   v = init_dynamic_array_var ("DIRSTACK", get_dirstack, assign_dirstack, 0);
1416 #endif /* PUSHD_AND_POPD && ARRAY_VARS */
1417
1418 #if defined (ARRAY_VARS)
1419   v = init_dynamic_array_var ("GROUPS", get_groupset, null_array_assign, att_noassign);
1420
1421 #  if defined (DEBUGGER)
1422   v = init_dynamic_array_var ("BASH_ARGC", get_self, null_array_assign, att_noassign);
1423   v = init_dynamic_array_var ("BASH_ARGV", get_self, null_array_assign, att_noassign);
1424 #  endif /* DEBUGGER */
1425   v = init_dynamic_array_var ("BASH_SOURCE", get_self, null_array_assign, att_noassign);
1426   v = init_dynamic_array_var ("BASH_LINENO", get_self, null_array_assign, att_noassign);
1427 #endif
1428
1429   v = init_funcname_var ();
1430 }
1431
1432 /* **************************************************************** */
1433 /*                                                                  */
1434 /*              Retrieving variables and values                     */
1435 /*                                                                  */
1436 /* **************************************************************** */
1437
1438 /* How to get a pointer to the shell variable or function named NAME.
1439    HASHED_VARS is a pointer to the hash table containing the list
1440    of interest (either variables or functions). */
1441
1442 static SHELL_VAR *
1443 hash_lookup (name, hashed_vars)
1444      const char *name;
1445      HASH_TABLE *hashed_vars;
1446 {
1447   BUCKET_CONTENTS *bucket;
1448
1449   bucket = hash_search (name, hashed_vars, 0);
1450   return (bucket ? (SHELL_VAR *)bucket->data : (SHELL_VAR *)NULL);
1451 }
1452
1453 SHELL_VAR *
1454 var_lookup (name, vcontext)
1455      const char *name;
1456      VAR_CONTEXT *vcontext;
1457 {
1458   VAR_CONTEXT *vc;
1459   SHELL_VAR *v;
1460
1461   v = (SHELL_VAR *)NULL;
1462   for (vc = vcontext; vc; vc = vc->down)
1463     if (v = hash_lookup (name, vc->table))
1464       break;
1465
1466   return v;
1467 }
1468
1469 /* Look up the variable entry named NAME.  If SEARCH_TEMPENV is non-zero,
1470    then also search the temporarily built list of exported variables.
1471    The lookup order is:
1472         temporary_env
1473         shell_variables list
1474 */
1475
1476 SHELL_VAR *
1477 find_variable_internal (name, force_tempenv)
1478      const char *name;
1479      int force_tempenv;
1480 {
1481   SHELL_VAR *var;
1482   int search_tempenv;
1483
1484   var = (SHELL_VAR *)NULL;
1485
1486   /* If explicitly requested, first look in the temporary environment for
1487      the variable.  This allows constructs such as "foo=x eval 'echo $foo'"
1488      to get the `exported' value of $foo.  This happens if we are executing
1489      a function or builtin, or if we are looking up a variable in a
1490      "subshell environment". */
1491   search_tempenv = force_tempenv || (expanding_redir == 0 && subshell_environment);
1492
1493   if (search_tempenv && temporary_env)          
1494     var = hash_lookup (name, temporary_env);
1495
1496   if (var == 0)
1497     var = var_lookup (name, shell_variables);
1498
1499   if (var == 0)
1500     return ((SHELL_VAR *)NULL);
1501
1502   return (var->dynamic_value ? (*(var->dynamic_value)) (var) : var);
1503 }
1504
1505 /* Look up the variable entry named NAME.  Returns the entry or NULL. */
1506 SHELL_VAR *
1507 find_variable (name)
1508      const char *name;
1509 {
1510   return (find_variable_internal (name, (expanding_redir == 0 && this_shell_builtin != 0)));
1511 }
1512
1513 /* Look up the function entry whose name matches STRING.
1514    Returns the entry or NULL. */
1515 SHELL_VAR *
1516 find_function (name)
1517      const char *name;
1518 {
1519   return (hash_lookup (name, shell_functions));
1520 }
1521
1522 /* Find the function definition for the shell function named NAME.  Returns
1523    the entry or NULL. */
1524 FUNCTION_DEF *
1525 find_function_def (name)
1526      const char *name;
1527 {
1528   return ((FUNCTION_DEF *)hash_lookup (name, shell_function_defs));
1529 }
1530
1531 /* Return the value of VAR.  VAR is assumed to have been the result of a
1532    lookup without any subscript, if arrays are compiled into the shell. */
1533 char *
1534 get_variable_value (var)
1535      SHELL_VAR *var;
1536 {
1537   if (var == 0)
1538     return ((char *)NULL);
1539 #if defined (ARRAY_VARS)
1540   else if (array_p (var))
1541     return (array_reference (array_cell (var), 0));
1542 #endif
1543   else
1544     return (value_cell (var));
1545 }
1546
1547 /* Return the string value of a variable.  Return NULL if the variable
1548    doesn't exist.  Don't cons a new string.  This is a potential memory
1549    leak if the variable is found in the temporary environment.  Since
1550    functions and variables have separate name spaces, returns NULL if
1551    var_name is a shell function only. */
1552 char *
1553 get_string_value (var_name)
1554      const char *var_name;
1555 {
1556   SHELL_VAR *var;
1557
1558   var = find_variable (var_name);
1559   return ((var) ? get_variable_value (var) : (char *)NULL);
1560 }
1561
1562 /* This is present for use by the tilde and readline libraries. */
1563 char *
1564 sh_get_env_value (v)
1565      const char *v;
1566 {
1567   return get_string_value (v);
1568 }
1569
1570 /* **************************************************************** */
1571 /*                                                                  */
1572 /*                Creating and setting variables                    */
1573 /*                                                                  */
1574 /* **************************************************************** */
1575
1576 /* Set NAME to VALUE if NAME has no value. */
1577 SHELL_VAR *
1578 set_if_not (name, value)
1579      char *name, *value;
1580 {
1581   SHELL_VAR *v;
1582
1583   v = find_variable (name);
1584   if (v == 0)
1585     v = bind_variable_internal (name, value, global_variables->table, HASH_NOSRCH);
1586   return (v);
1587 }
1588
1589 /* Create a local variable referenced by NAME. */
1590 SHELL_VAR *
1591 make_local_variable (name)
1592      const char *name;
1593 {
1594   SHELL_VAR *new_var, *old_var;
1595   VAR_CONTEXT *vc;
1596   int was_tmpvar;
1597   char *tmp_value;
1598
1599   /* local foo; local foo;  is a no-op. */
1600   old_var = find_variable (name);
1601   if (old_var && local_p (old_var) && old_var->context == variable_context)
1602     {
1603       VUNSETATTR (old_var, att_invisible);
1604       return (old_var);
1605     }
1606
1607   was_tmpvar = old_var && tempvar_p (old_var);
1608   if (was_tmpvar)
1609     tmp_value = value_cell (old_var);
1610
1611   for (vc = shell_variables; vc; vc = vc->down)
1612     if (vc_isfuncenv (vc) && vc->scope == variable_context)
1613       break;
1614
1615   if (vc == 0)
1616     {
1617       internal_error (_("make_local_variable: no function context at current scope"));
1618       return ((SHELL_VAR *)NULL);
1619     }
1620   else if (vc->table == 0)
1621     vc->table = hash_create (TEMPENV_HASH_BUCKETS);
1622
1623   /* Since this is called only from the local/declare/typeset code, we can
1624      call builtin_error here without worry (of course, it will also work
1625      for anything that sets this_command_name).  Variables with the `noassign'
1626      attribute may not be made local.  The test against old_var's context
1627      level is to disallow local copies of readonly global variables (since I
1628      believe that this could be a security hole).  Readonly copies of calling
1629      function local variables are OK. */
1630   if (old_var && (noassign_p (old_var) ||
1631                  (readonly_p (old_var) && old_var->context == 0)))
1632     {
1633       if (readonly_p (old_var))
1634         sh_readonly (name);
1635       return ((SHELL_VAR *)NULL);
1636     }
1637
1638   if (old_var == 0)
1639     new_var = bind_variable_internal (name, "", vc->table, HASH_NOSRCH);
1640   else
1641     {
1642       new_var = make_new_variable (name, vc->table);
1643
1644       /* If we found this variable in one of the temporary environments,
1645          inherit its value.  Watch to see if this causes problems with
1646          things like `x=4 local x'. */
1647       if (was_tmpvar)
1648         var_setvalue (new_var, savestring (tmp_value));
1649
1650       new_var->attributes = exported_p (old_var) ? att_exported : 0;
1651     }
1652
1653   vc->flags |= VC_HASLOCAL;
1654
1655   new_var->context = variable_context;
1656   VSETATTR (new_var, att_local);
1657
1658   if (ifsname (name))
1659     setifs (new_var);
1660
1661   return (new_var);
1662 }
1663
1664 #if defined (ARRAY_VARS)
1665 SHELL_VAR *
1666 make_local_array_variable (name)
1667      char *name;
1668 {
1669   SHELL_VAR *var;
1670   ARRAY *array;
1671
1672   var = make_local_variable (name);
1673   if (var == 0 || array_p (var))
1674     return var;
1675
1676   array = array_create ();
1677
1678   FREE (value_cell(var));
1679   var_setarray (var, array);
1680   VSETATTR (var, att_array);
1681   return var;
1682 }
1683 #endif /* ARRAY_VARS */
1684
1685 /* Create a new shell variable with name NAME. */
1686 static SHELL_VAR *
1687 new_shell_variable (name)
1688      const char *name;
1689 {
1690   SHELL_VAR *entry;
1691
1692   entry = (SHELL_VAR *)xmalloc (sizeof (SHELL_VAR));
1693
1694   entry->name = savestring (name);
1695   var_setvalue (entry, (char *)NULL);
1696   CLEAR_EXPORTSTR (entry);
1697
1698   entry->dynamic_value = (sh_var_value_func_t *)NULL;
1699   entry->assign_func = (sh_var_assign_func_t *)NULL;
1700
1701   entry->attributes = 0;
1702
1703   /* Always assume variables are to be made at toplevel!
1704      make_local_variable has the responsibilty of changing the
1705      variable context. */
1706   entry->context = 0;
1707
1708   return (entry);
1709 }
1710
1711 /* Create a new shell variable with name NAME and add it to the hash table
1712    TABLE. */
1713 static SHELL_VAR *
1714 make_new_variable (name, table)
1715      const char *name;
1716      HASH_TABLE *table;
1717 {
1718   SHELL_VAR *entry;
1719   BUCKET_CONTENTS *elt;
1720
1721   entry = new_shell_variable (name);
1722
1723   /* Make sure we have a shell_variables hash table to add to. */
1724   if (shell_variables == 0)
1725     {
1726       shell_variables = global_variables = new_var_context ((char *)NULL, 0);
1727       shell_variables->scope = 0;
1728       shell_variables->table = hash_create (0);
1729     }
1730
1731   elt = hash_insert (savestring (name), table, HASH_NOSRCH);
1732   elt->data = (PTR_T)entry;
1733
1734   return entry;
1735 }
1736
1737 #if defined (ARRAY_VARS)
1738 SHELL_VAR *
1739 make_new_array_variable (name)
1740      char *name;
1741 {
1742   SHELL_VAR *entry;
1743   ARRAY *array;
1744
1745   entry = make_new_variable (name, global_variables->table);
1746   array = array_create ();
1747   var_setarray (entry, array);
1748   VSETATTR (entry, att_array);
1749   return entry;
1750 }
1751 #endif
1752
1753 char *
1754 make_variable_value (var, value)
1755      SHELL_VAR *var;
1756      char *value;
1757 {
1758   char *retval;
1759   intmax_t lval;
1760   int expok;
1761
1762   /* If this variable has had its type set to integer (via `declare -i'),
1763      then do expression evaluation on it and store the result.  The
1764      functions in expr.c (evalexp()) and bind_int_variable() are responsible
1765      for turning off the integer flag if they don't want further
1766      evaluation done. */
1767   if (integer_p (var))
1768     {
1769       lval = evalexp (value, &expok);
1770       if (expok == 0)
1771         jump_to_top_level (DISCARD);
1772       retval = itos (lval);
1773     }
1774   else if (value)
1775     {
1776       if (*value)
1777         retval = savestring (value);
1778       else
1779         {
1780           retval = (char *)xmalloc (1);
1781           retval[0] = '\0';
1782         }
1783     }
1784   else
1785     retval = (char *)NULL;
1786
1787   return retval;
1788 }
1789
1790 /* Bind a variable NAME to VALUE in the HASH_TABLE TABLE, which may be the
1791    temporary environment (but usually is not). */
1792 static SHELL_VAR *
1793 bind_variable_internal (name, value, table, hflags)
1794      const char *name;
1795      char *value;
1796      HASH_TABLE *table;
1797      int hflags;
1798 {
1799   char *newval;
1800   SHELL_VAR *entry;
1801
1802   entry = (hflags & HASH_NOSRCH) ? (SHELL_VAR *)NULL : hash_lookup (name, table);
1803
1804   if (entry == 0)
1805     {
1806       entry = make_new_variable (name, table);
1807       var_setvalue (entry, make_variable_value (entry, value));
1808     }
1809   else if (entry->assign_func)  /* array vars have assign functions now */
1810     {
1811       INVALIDATE_EXPORTSTR (entry);
1812       return ((*(entry->assign_func)) (entry, value, -1));
1813     }
1814   else
1815     {
1816       if (readonly_p (entry) || noassign_p (entry))
1817         {
1818           if (readonly_p (entry))
1819             err_readonly (name);
1820           return (entry);
1821         }
1822
1823       /* Variables which are bound are visible. */
1824       VUNSETATTR (entry, att_invisible);
1825
1826       newval = make_variable_value (entry, value);
1827
1828       /* Invalidate any cached export string */
1829       INVALIDATE_EXPORTSTR (entry);
1830
1831 #if defined (ARRAY_VARS)
1832       /* XXX -- this bears looking at again -- XXX */
1833       /* If an existing array variable x is being assigned to with x=b or
1834          `read x' or something of that nature, silently convert it to
1835          x[0]=b or `read x[0]'. */
1836       if (array_p (entry))
1837         {
1838           array_insert (array_cell (entry), 0, newval);
1839           free (newval);
1840         }
1841       else
1842 #endif
1843         {
1844           FREE (value_cell (entry));
1845           var_setvalue (entry, newval);
1846         }
1847     }
1848
1849   if (mark_modified_vars)
1850     VSETATTR (entry, att_exported);
1851
1852   if (exported_p (entry))
1853     array_needs_making = 1;
1854
1855   return (entry);
1856 }
1857         
1858 /* Bind a variable NAME to VALUE.  This conses up the name
1859    and value strings.  If we have a temporary environment, we bind there
1860    first, then we bind into shell_variables. */
1861
1862 SHELL_VAR *
1863 bind_variable (name, value)
1864      const char *name;
1865      char *value;
1866 {
1867   SHELL_VAR *v;
1868   VAR_CONTEXT *vc;
1869
1870   if (shell_variables == 0)
1871     {
1872       shell_variables = global_variables = new_var_context ((char *)NULL, 0);
1873       shell_variables->scope = 0;
1874       shell_variables->table = hash_create (0);
1875     }
1876
1877   /* If we have a temporary environment, look there first for the variable,
1878      and, if found, modify the value there before modifying it in the
1879      shell_variables table.  This allows sourced scripts to modify values
1880      given to them in a temporary environment while modifying the variable
1881      value that the caller sees. */
1882   if (temporary_env)
1883     bind_tempenv_variable (name, value);
1884
1885   /* XXX -- handle local variables here. */
1886   for (vc = shell_variables; vc; vc = vc->down)
1887     {
1888       if (vc_isfuncenv (vc) || vc_isbltnenv (vc))
1889         {
1890           v = hash_lookup (name, vc->table);
1891           if (v)
1892             return (bind_variable_internal (name, value, vc->table, 0));
1893         }
1894     }
1895   return (bind_variable_internal (name, value, global_variables->table, 0));
1896 }
1897
1898 /* Make VAR, a simple shell variable, have value VALUE.  Once assigned a
1899    value, variables are no longer invisible.  This is a duplicate of part
1900    of the internals of bind_variable.  If the variable is exported, or
1901    all modified variables should be exported, mark the variable for export
1902    and note that the export environment needs to be recreated. */
1903 SHELL_VAR *
1904 bind_variable_value (var, value)
1905      SHELL_VAR *var;
1906      char *value;
1907 {
1908   char *t;
1909
1910   VUNSETATTR (var, att_invisible);
1911
1912   t = make_variable_value (var, value);
1913   FREE (value_cell (var));
1914   var_setvalue (var, t);
1915
1916   INVALIDATE_EXPORTSTR (var);
1917
1918   if (mark_modified_vars)
1919     VSETATTR (var, att_exported);
1920
1921   if (exported_p (var))
1922     array_needs_making = 1;
1923
1924   return (var);
1925 }
1926
1927 /* Bind/create a shell variable with the name LHS to the RHS.
1928    This creates or modifies a variable such that it is an integer.
1929
1930    This used to be in expr.c, but it is here so that all of the
1931    variable binding stuff is localized.  Since we don't want any
1932    recursive evaluation from bind_variable() (possible without this code,
1933    since bind_variable() calls the evaluator for variables with the integer
1934    attribute set), we temporarily turn off the integer attribute for each
1935    variable we set here, then turn it back on after binding as necessary. */
1936
1937 SHELL_VAR *
1938 bind_int_variable (lhs, rhs)
1939      char *lhs, *rhs;
1940 {
1941   register SHELL_VAR *v;
1942   char *t;
1943   int isint, isarr;
1944
1945   isint = isarr = 0;
1946 #if defined (ARRAY_VARS)
1947 #  if 0
1948   if (t = xstrchr (lhs, '['))   /*]*/
1949 #  else
1950   if (valid_array_reference (lhs))
1951 #  endif
1952     {
1953       isarr = 1;
1954       v = array_variable_part (lhs, (char **)0, (int *)0);
1955     }
1956   else
1957 #endif
1958     v = find_variable (lhs);
1959
1960   if (v)
1961     {
1962       isint = integer_p (v);
1963       VUNSETATTR (v, att_integer);
1964     }
1965
1966 #if defined (ARRAY_VARS)
1967   if (isarr)
1968     v = assign_array_element (lhs, rhs);
1969   else
1970 #endif
1971     v = bind_variable (lhs, rhs);
1972
1973   if (isint)
1974     VSETATTR (v, att_integer);
1975
1976   return (v);
1977 }
1978
1979 SHELL_VAR *
1980 bind_var_to_int (var, val)
1981      char *var;
1982      intmax_t val;
1983 {
1984   char ibuf[INT_STRLEN_BOUND (intmax_t) + 1], *p;
1985
1986   p = fmtulong (val, 10, ibuf, sizeof (ibuf), 0);
1987   return (bind_int_variable (var, p));
1988 }
1989
1990 /* Do a function binding to a variable.  You pass the name and
1991    the command to bind to.  This conses the name and command. */
1992 SHELL_VAR *
1993 bind_function (name, value)
1994      const char *name;
1995      COMMAND *value;
1996 {
1997   SHELL_VAR *entry;
1998
1999   entry = find_function (name);
2000   if (entry == 0)
2001     {
2002       BUCKET_CONTENTS *elt;
2003
2004       elt = hash_insert (savestring (name), shell_functions, HASH_NOSRCH);
2005       entry = new_shell_variable (name);
2006       elt->data = (PTR_T)entry;
2007     }
2008   else
2009     INVALIDATE_EXPORTSTR (entry);
2010
2011   if (var_isset (entry))
2012     dispose_command (function_cell (entry));
2013
2014   if (value)
2015     var_setfunc (entry, copy_command (value));
2016   else
2017     var_setfunc (entry, 0);
2018
2019   VSETATTR (entry, att_function);
2020
2021   if (mark_modified_vars)
2022     VSETATTR (entry, att_exported);
2023
2024   VUNSETATTR (entry, att_invisible);            /* Just to be sure */
2025
2026   if (exported_p (entry))
2027     array_needs_making = 1;
2028
2029 #if defined (PROGRAMMABLE_COMPLETION)
2030   set_itemlist_dirty (&it_functions);
2031 #endif
2032
2033   return (entry);
2034 }
2035
2036 /* Bind a function definition, which includes source file and line number
2037    information in addition to the command, into the FUNCTION_DEF hash table.*/
2038 void
2039 bind_function_def (name, value)
2040      const char *name;
2041      FUNCTION_DEF *value;
2042 {
2043   FUNCTION_DEF *entry;
2044   BUCKET_CONTENTS *elt;
2045   COMMAND *cmd;
2046
2047   entry = find_function_def (name);
2048   if (entry)
2049     {
2050       dispose_function_def_contents (entry);
2051       entry = copy_function_def_contents (value, entry);
2052     }
2053   else
2054     {
2055       cmd = value->command;
2056       value->command = 0;
2057       entry = copy_function_def (value);
2058       value->command = cmd;
2059
2060       elt = hash_insert (savestring (name), shell_function_defs, HASH_NOSRCH);
2061       elt->data = (PTR_T *)entry;
2062     }
2063 }
2064
2065 /* Add STRING, which is of the form foo=bar, to the temporary environment
2066    HASH_TABLE (temporary_env).  The functions in execute_cmd.c are
2067    responsible for moving the main temporary env to one of the other
2068    temporary environments.  The expansion code in subst.c calls this. */
2069 int
2070 assign_in_env (string)
2071      const char *string;
2072 {
2073   int offset;
2074   char *name, *temp, *value;
2075   SHELL_VAR *var;
2076
2077   offset = assignment (string, 0);
2078   name = savestring (string);
2079   value = (char *)NULL;
2080
2081   if (name[offset] == '=')
2082     {
2083       name[offset] = 0;
2084
2085       var = find_variable (name);
2086       if (var && (readonly_p (var) || noassign_p (var)))
2087         {
2088           if (readonly_p (var))
2089             err_readonly (name);
2090           free (name);
2091           return (0);
2092         }
2093
2094       temp = name + offset + 1;
2095       temp = (xstrchr (temp, '~') != 0) ? bash_tilde_expand (temp, 1) : savestring (temp);
2096
2097       value = expand_string_unsplit_to_string (temp, 0);
2098       free (temp);
2099     }
2100
2101   if (temporary_env == 0)
2102     temporary_env = hash_create (TEMPENV_HASH_BUCKETS);
2103
2104   var = hash_lookup (name, temporary_env);
2105   if (var == 0)
2106     var = make_new_variable (name, temporary_env);
2107   else
2108     FREE (value_cell (var));
2109
2110   if (value == 0)
2111     {
2112       value = (char *)xmalloc (1);      /* like do_assignment_internal */
2113       value[0] = '\0';
2114     }
2115
2116   var_setvalue (var, value);
2117   var->attributes |= (att_exported|att_tempvar);
2118   var->context = variable_context;      /* XXX */
2119
2120   INVALIDATE_EXPORTSTR (var);
2121   var->exportstr = mk_env_string (name, value);
2122
2123   array_needs_making = 1;
2124
2125   if (ifsname (name))
2126     setifs (var);
2127
2128   if (echo_command_at_execute)
2129     /* The Korn shell prints the `+ ' in front of assignment statements,
2130         so we do too. */
2131     xtrace_print_assignment (name, value, 0, 1);
2132
2133   free (name);
2134   return 1;
2135 }
2136
2137 /* **************************************************************** */
2138 /*                                                                  */
2139 /*                      Copying variables                           */
2140 /*                                                                  */
2141 /* **************************************************************** */
2142
2143 #ifdef INCLUDE_UNUSED
2144 /* Copy VAR to a new data structure and return that structure. */
2145 SHELL_VAR *
2146 copy_variable (var)
2147      SHELL_VAR *var;
2148 {
2149   SHELL_VAR *copy = (SHELL_VAR *)NULL;
2150
2151   if (var)
2152     {
2153       copy = (SHELL_VAR *)xmalloc (sizeof (SHELL_VAR));
2154
2155       copy->attributes = var->attributes;
2156       copy->name = savestring (var->name);
2157
2158       if (function_p (var))
2159         var_setfunc (copy, copy_command (function_cell (var)));
2160 #if defined (ARRAY_VARS)
2161       else if (array_p (var))
2162         var_setarray (copy, dup_array (array_cell (var)));
2163 #endif
2164       else if (value_cell (var))
2165         var_setvalue (copy, savestring (value_cell (var)));
2166       else
2167         var_setvalue (copy, (char *)NULL);
2168
2169       copy->dynamic_value = var->dynamic_value;
2170       copy->assign_func = var->assign_func;
2171
2172       copy->exportstr = COPY_EXPORTSTR (var);
2173
2174       copy->context = var->context;
2175     }
2176   return (copy);
2177 }
2178 #endif
2179
2180 /* **************************************************************** */
2181 /*                                                                  */
2182 /*                Deleting and unsetting variables                  */
2183 /*                                                                  */
2184 /* **************************************************************** */
2185
2186 /* Dispose of the information attached to VAR. */
2187 void
2188 dispose_variable (var)
2189      SHELL_VAR *var;
2190 {
2191   if (var == 0)
2192     return;
2193
2194   if (function_p (var))
2195     dispose_command (function_cell (var));
2196 #if defined (ARRAY_VARS)
2197   else if (array_p (var))
2198     array_dispose (array_cell (var));
2199 #endif
2200   else
2201     FREE (value_cell (var));
2202
2203   FREE_EXPORTSTR (var);
2204
2205   free (var->name);
2206
2207   if (exported_p (var))
2208     array_needs_making = 1;
2209
2210   free (var);
2211 }
2212
2213 /* Unset the shell variable referenced by NAME. */
2214 int
2215 unbind_variable (name)
2216      const char *name;
2217 {
2218   return makunbound (name, shell_variables);
2219 }
2220
2221 /* Unset the shell function named NAME. */
2222 int
2223 unbind_func (name)
2224      const char *name;
2225 {
2226   BUCKET_CONTENTS *elt;
2227   SHELL_VAR *func;
2228
2229   elt = hash_remove (name, shell_functions, 0);
2230
2231   if (elt == 0)
2232     return -1;
2233
2234 #if defined (PROGRAMMABLE_COMPLETION)
2235   set_itemlist_dirty (&it_functions);
2236 #endif
2237
2238   func = (SHELL_VAR *)elt->data;
2239   if (func)
2240     {
2241       if (exported_p (func))
2242         array_needs_making++;
2243       dispose_variable (func);
2244     }
2245
2246   free (elt->key);
2247   free (elt);
2248
2249   return 0;  
2250 }
2251
2252 int
2253 unbind_function_def (name)
2254      const char *name;
2255 {
2256   BUCKET_CONTENTS *elt;
2257   FUNCTION_DEF *funcdef;
2258
2259   elt = hash_remove (name, shell_function_defs, 0);
2260
2261   if (elt == 0)
2262     return -1;
2263
2264   funcdef = (FUNCTION_DEF *)elt->data;
2265   if (funcdef)
2266     dispose_function_def (funcdef);
2267
2268   free (elt->key);
2269   free (elt);
2270
2271   return 0;  
2272 }
2273
2274 /* Make the variable associated with NAME go away.  HASH_LIST is the
2275    hash table from which this variable should be deleted (either
2276    shell_variables or shell_functions).
2277    Returns non-zero if the variable couldn't be found. */
2278 int
2279 makunbound (name, vc)
2280      const char *name;
2281      VAR_CONTEXT *vc;
2282 {
2283   BUCKET_CONTENTS *elt, *new_elt;
2284   SHELL_VAR *old_var;
2285   VAR_CONTEXT *v;
2286   char *t;
2287
2288   for (elt = (BUCKET_CONTENTS *)NULL, v = vc; v; v = v->down)
2289     if (elt = hash_remove (name, v->table, 0))
2290       break;
2291
2292   if (elt == 0)
2293     return (-1);
2294
2295   old_var = (SHELL_VAR *)elt->data;
2296
2297   if (old_var && exported_p (old_var))
2298     array_needs_making++;
2299
2300   /* If we're unsetting a local variable and we're still executing inside
2301      the function, just mark the variable as invisible.  The function
2302      eventually called by pop_var_context() will clean it up later.  This
2303      must be done so that if the variable is subsequently assigned a new
2304      value inside the function, the `local' attribute is still present.
2305      We also need to add it back into the correct hash table. */
2306   if (old_var && local_p (old_var) && variable_context == old_var->context)
2307     {
2308       /* Reset the attributes.  Preserve the export attribute if the variable
2309          came from a temporary environment.  Make sure it stays local, and
2310          make it invisible. */ 
2311       old_var->attributes = (exported_p (old_var) && tempvar_p (old_var)) ? att_exported : 0;
2312       VSETATTR (old_var, att_local);
2313       VSETATTR (old_var, att_invisible);
2314       FREE (value_cell (old_var));
2315       var_setvalue (old_var, (char *)NULL);
2316       INVALIDATE_EXPORTSTR (old_var);
2317
2318       new_elt = hash_insert (savestring (old_var->name), v->table, 0);
2319       new_elt->data = (PTR_T)old_var;
2320       stupidly_hack_special_variables (old_var->name);
2321
2322       free (elt->key);
2323       free (elt);
2324       return (0);
2325     }
2326
2327   /* Have to save a copy of name here, because it might refer to
2328      old_var->name.  If so, stupidly_hack_special_variables will
2329      reference freed memory. */
2330   t = savestring (name);
2331
2332   free (elt->key);
2333   free (elt);
2334
2335   dispose_variable (old_var);
2336   stupidly_hack_special_variables (t);
2337   free (t);
2338
2339   return (0);
2340 }
2341
2342 /* Get rid of all of the variables in the current context. */
2343 void
2344 kill_all_local_variables ()
2345 {
2346   VAR_CONTEXT *vc;
2347
2348   for (vc = shell_variables; vc; vc = vc->down)
2349     if (vc_isfuncenv (vc) && vc->scope == variable_context)
2350       break;
2351   if (vc == 0)
2352     return;             /* XXX */
2353
2354   if (vc->table && vc_haslocals (vc))
2355     {
2356       delete_all_variables (vc->table);
2357       hash_dispose (vc->table);
2358     }
2359   vc->table = (HASH_TABLE *)NULL;
2360 }
2361
2362 static void
2363 free_variable_hash_data (data)
2364      PTR_T data;
2365 {
2366   SHELL_VAR *var;
2367
2368   var = (SHELL_VAR *)data;
2369   dispose_variable (var);
2370 }
2371
2372 /* Delete the entire contents of the hash table. */
2373 void
2374 delete_all_variables (hashed_vars)
2375      HASH_TABLE *hashed_vars;
2376 {
2377   hash_flush (hashed_vars, free_variable_hash_data);
2378 }
2379
2380 /* **************************************************************** */
2381 /*                                                                  */
2382 /*                   Setting variable attributes                    */
2383 /*                                                                  */
2384 /* **************************************************************** */
2385
2386 #define FIND_OR_MAKE_VARIABLE(name, entry) \
2387   do \
2388     { \
2389       entry = find_variable (name); \
2390       if (!entry) \
2391         { \
2392           entry = bind_variable (name, ""); \
2393           if (!no_invisible_vars) entry->attributes |= att_invisible; \
2394         } \
2395     } \
2396   while (0)
2397
2398 /* Make the variable associated with NAME be readonly.
2399    If NAME does not exist yet, create it. */
2400 void
2401 set_var_read_only (name)
2402      char *name;
2403 {
2404   SHELL_VAR *entry;
2405
2406   FIND_OR_MAKE_VARIABLE (name, entry);
2407   VSETATTR (entry, att_readonly);
2408 }
2409
2410 #ifdef INCLUDE_UNUSED
2411 /* Make the function associated with NAME be readonly.
2412    If NAME does not exist, we just punt, like auto_export code below. */
2413 void
2414 set_func_read_only (name)
2415      const char *name;
2416 {
2417   SHELL_VAR *entry;
2418
2419   entry = find_function (name);
2420   if (entry)
2421     VSETATTR (entry, att_readonly);
2422 }
2423
2424 /* Make the variable associated with NAME be auto-exported.
2425    If NAME does not exist yet, create it. */
2426 void
2427 set_var_auto_export (name)
2428      char *name;
2429 {
2430   SHELL_VAR *entry;
2431
2432   FIND_OR_MAKE_VARIABLE (name, entry);
2433   set_auto_export (entry);
2434 }
2435
2436 /* Make the function associated with NAME be auto-exported. */
2437 void
2438 set_func_auto_export (name)
2439      const char *name;
2440 {
2441   SHELL_VAR *entry;
2442
2443   entry = find_function (name);
2444   if (entry)
2445     set_auto_export (entry);
2446 }
2447 #endif
2448
2449 /* **************************************************************** */
2450 /*                                                                  */
2451 /*                   Creating lists of variables                    */
2452 /*                                                                  */
2453 /* **************************************************************** */
2454
2455 static VARLIST *
2456 vlist_alloc (nentries)
2457      int nentries;
2458 {
2459   VARLIST  *vlist;
2460
2461   vlist = (VARLIST *)xmalloc (sizeof (VARLIST));
2462   vlist->list = (SHELL_VAR **)xmalloc ((nentries + 1) * sizeof (SHELL_VAR *));
2463   vlist->list_size = nentries;
2464   vlist->list_len = 0;
2465   vlist->list[0] = (SHELL_VAR *)NULL;
2466
2467   return vlist;
2468 }
2469
2470 static VARLIST *
2471 vlist_realloc (vlist, n)
2472      VARLIST *vlist;
2473      int n;
2474 {
2475   if (vlist == 0)
2476     return (vlist = vlist_alloc (n));
2477   if (n > vlist->list_size)
2478     {
2479       vlist->list_size = n;
2480       vlist->list = (SHELL_VAR **)xrealloc (vlist->list, (vlist->list_size + 1) * sizeof (SHELL_VAR *));
2481     }
2482   return vlist;
2483 }
2484
2485 static void
2486 vlist_add (vlist, var, flags)
2487      VARLIST *vlist;
2488      SHELL_VAR *var;
2489      int flags;
2490 {
2491   register int i;
2492
2493   for (i = 0; i < vlist->list_len; i++)
2494     if (STREQ (var->name, vlist->list[i]->name))
2495       break;
2496   if (i < vlist->list_len)
2497     return;
2498
2499   if (i >= vlist->list_size)
2500     vlist = vlist_realloc (vlist, vlist->list_size + 16);
2501
2502   vlist->list[vlist->list_len++] = var;
2503   vlist->list[vlist->list_len] = (SHELL_VAR *)NULL;
2504 }
2505
2506 /* Map FUNCTION over the variables in VAR_HASH_TABLE.  Return an array of the
2507    variables for which FUNCTION returns a non-zero value.  A NULL value
2508    for FUNCTION means to use all variables. */
2509 SHELL_VAR **
2510 map_over (function, vc)
2511      sh_var_map_func_t *function;
2512      VAR_CONTEXT *vc;
2513 {
2514   VAR_CONTEXT *v;
2515   VARLIST *vlist;
2516   SHELL_VAR **ret;
2517   int nentries;
2518
2519   for (nentries = 0, v = vc; v; v = v->down)
2520     nentries += HASH_ENTRIES (v->table);
2521
2522   if (nentries == 0)
2523     return (SHELL_VAR **)NULL;
2524
2525   vlist = vlist_alloc (nentries);
2526
2527   for (v = vc; v; v = v->down)
2528     flatten (v->table, function, vlist, 0);
2529
2530   ret = vlist->list;
2531   free (vlist);
2532   return ret;
2533 }
2534
2535 SHELL_VAR **
2536 map_over_funcs (function)
2537      sh_var_map_func_t *function;
2538 {
2539   VARLIST *vlist;
2540   SHELL_VAR **ret;
2541
2542   if (shell_functions == 0 || HASH_ENTRIES (shell_functions) == 0)
2543     return ((SHELL_VAR **)NULL);
2544
2545   vlist = vlist_alloc (HASH_ENTRIES (shell_functions));
2546
2547   flatten (shell_functions, function, vlist, 0);
2548
2549   ret = vlist->list;
2550   free (vlist);
2551   return ret;
2552 }
2553
2554 /* Flatten VAR_HASH_TABLE, applying FUNC to each member and adding those
2555    elements for which FUNC succeeds to VLIST->list.  FLAGS is reserved
2556    for future use.  Only unique names are added to VLIST.  If FUNC is
2557    NULL, each variable in VAR_HASH_TABLE is added to VLIST.  If VLIST is
2558    NULL, FUNC is applied to each SHELL_VAR in VAR_HASH_TABLE.  If VLIST
2559    and FUNC are both NULL, nothing happens. */
2560 static void
2561 flatten (var_hash_table, func, vlist, flags)
2562      HASH_TABLE *var_hash_table;
2563      sh_var_map_func_t *func;
2564      VARLIST *vlist;
2565      int flags;
2566 {
2567   register int i;
2568   register BUCKET_CONTENTS *tlist;
2569   int r;
2570   SHELL_VAR *var;
2571
2572   if (var_hash_table == 0 || (HASH_ENTRIES (var_hash_table) == 0) || (vlist == 0 && func == 0))
2573     return;
2574
2575   for (i = 0; i < var_hash_table->nbuckets; i++)
2576     {
2577       for (tlist = hash_items (i, var_hash_table); tlist; tlist = tlist->next)
2578         {
2579           var = (SHELL_VAR *)tlist->data;
2580
2581           r = func ? (*func) (var) : 1;
2582           if (r && vlist)
2583             vlist_add (vlist, var, flags);
2584         }
2585     }
2586 }
2587
2588 void
2589 sort_variables (array)
2590      SHELL_VAR **array;
2591 {
2592   qsort (array, strvec_len ((char **)array), sizeof (SHELL_VAR *), (QSFUNC *)qsort_var_comp);
2593 }
2594
2595 static int
2596 qsort_var_comp (var1, var2)
2597      SHELL_VAR **var1, **var2;
2598 {
2599   int result;
2600
2601   if ((result = (*var1)->name[0] - (*var2)->name[0]) == 0)
2602     result = strcmp ((*var1)->name, (*var2)->name);
2603
2604   return (result);
2605 }
2606
2607 /* Apply FUNC to each variable in SHELL_VARIABLES, adding each one for
2608    which FUNC succeeds to an array of SHELL_VAR *s.  Returns the array. */
2609 static SHELL_VAR **
2610 vapply (func)
2611      sh_var_map_func_t *func;
2612 {
2613   SHELL_VAR **list;
2614
2615   list = map_over (func, shell_variables);
2616   if (list /* && posixly_correct */)
2617     sort_variables (list);
2618   return (list);
2619 }
2620
2621 /* Apply FUNC to each variable in SHELL_FUNCTIONS, adding each one for
2622    which FUNC succeeds to an array of SHELL_VAR *s.  Returns the array. */
2623 static SHELL_VAR **
2624 fapply (func)
2625      sh_var_map_func_t *func;
2626 {
2627   SHELL_VAR **list;
2628
2629   list = map_over_funcs (func);
2630   if (list /* && posixly_correct */)
2631     sort_variables (list);
2632   return (list);
2633 }
2634
2635 /* Create a NULL terminated array of all the shell variables. */
2636 SHELL_VAR **
2637 all_shell_variables ()
2638 {
2639   return (vapply ((sh_var_map_func_t *)NULL));
2640 }
2641
2642 /* Create a NULL terminated array of all the shell functions. */
2643 SHELL_VAR **
2644 all_shell_functions ()
2645 {
2646   return (fapply ((sh_var_map_func_t *)NULL));
2647 }
2648
2649 static int
2650 visible_var (var)
2651      SHELL_VAR *var;
2652 {
2653   return (invisible_p (var) == 0);
2654 }
2655
2656 SHELL_VAR **
2657 all_visible_functions ()
2658 {
2659   return (fapply (visible_var));
2660 }
2661
2662 SHELL_VAR **
2663 all_visible_variables ()
2664 {
2665   return (vapply (visible_var));
2666 }
2667
2668 /* Return non-zero if the variable VAR is visible and exported.  Array
2669    variables cannot be exported. */
2670 static int
2671 visible_and_exported (var)
2672      SHELL_VAR *var;
2673 {
2674   return (invisible_p (var) == 0 && exported_p (var));
2675 }
2676
2677 /* Return non-zero if VAR is a local variable in the current context and
2678    is exported. */
2679 static int
2680 local_and_exported (var)
2681      SHELL_VAR *var;
2682 {
2683   return (invisible_p (var) == 0 && local_p (var) && var->context == variable_context && exported_p (var));
2684 }
2685
2686 SHELL_VAR **
2687 all_exported_variables ()
2688 {
2689   return (vapply (visible_and_exported));
2690 }
2691
2692 SHELL_VAR **
2693 local_exported_variables ()
2694 {
2695   return (vapply (local_and_exported));
2696 }
2697
2698 static int
2699 variable_in_context (var)
2700      SHELL_VAR *var;
2701 {
2702   return (invisible_p (var) == 0 && local_p (var) && var->context == variable_context);
2703 }
2704
2705 SHELL_VAR **
2706 all_local_variables ()
2707 {
2708   VARLIST *vlist;
2709   SHELL_VAR **ret;
2710   VAR_CONTEXT *vc;
2711
2712   vc = shell_variables;
2713   for (vc = shell_variables; vc; vc = vc->down)
2714     if (vc_isfuncenv (vc) && vc->scope == variable_context)
2715       break;
2716
2717   if (vc == 0)
2718     {
2719       internal_error (_("all_local_variables: no function context at current scope"));
2720       return (SHELL_VAR **)NULL;
2721     }
2722   if (vc->table == 0 || HASH_ENTRIES (vc->table) == 0 || vc_haslocals (vc) == 0)
2723     return (SHELL_VAR **)NULL;
2724     
2725   vlist = vlist_alloc (HASH_ENTRIES (vc->table));
2726
2727   flatten (vc->table, variable_in_context, vlist, 0);
2728
2729   ret = vlist->list;
2730   free (vlist);
2731   if (ret)
2732     sort_variables (ret);
2733   return ret;
2734 }
2735
2736 #if defined (ARRAY_VARS)
2737 /* Return non-zero if the variable VAR is visible and an array. */
2738 static int
2739 visible_array_vars (var)
2740      SHELL_VAR *var;
2741 {
2742   return (invisible_p (var) == 0 && array_p (var));
2743 }
2744
2745 SHELL_VAR **
2746 all_array_variables ()
2747 {
2748   return (vapply (visible_array_vars));
2749 }
2750 #endif /* ARRAY_VARS */
2751
2752 char **
2753 all_variables_matching_prefix (prefix)
2754      const char *prefix;
2755 {
2756   SHELL_VAR **varlist;
2757   char **rlist;
2758   int vind, rind, plen;
2759
2760   plen = STRLEN (prefix);
2761   varlist = all_visible_variables ();
2762   for (vind = 0; varlist && varlist[vind]; vind++)
2763     ;
2764   if (varlist == 0 || vind == 0)
2765     return ((char **)NULL);
2766   rlist = strvec_create (vind + 1);
2767   for (vind = rind = 0; varlist[vind]; vind++)
2768     {
2769       if (plen == 0 || STREQN (prefix, varlist[vind]->name, plen))
2770         rlist[rind++] = savestring (varlist[vind]->name);
2771     }
2772   rlist[rind] = (char *)0;
2773   free (varlist);
2774
2775   return rlist;
2776 }
2777
2778 /* **************************************************************** */
2779 /*                                                                  */
2780 /*               Managing temporary variable scopes                 */
2781 /*                                                                  */
2782 /* **************************************************************** */
2783
2784 /* Make variable NAME have VALUE in the temporary environment. */
2785 static SHELL_VAR *
2786 bind_tempenv_variable (name, value)
2787      const char *name;
2788      char *value;
2789 {
2790   SHELL_VAR *var;
2791
2792   var = temporary_env ? hash_lookup (name, temporary_env) : (SHELL_VAR *)NULL;
2793
2794   if (var)
2795     {
2796       FREE (value_cell (var));
2797       var_setvalue (var, savestring (value));
2798       INVALIDATE_EXPORTSTR (var);
2799     }
2800
2801   return (var);
2802 }
2803
2804 /* Find a variable in the temporary environment that is named NAME.
2805    Return the SHELL_VAR *, or NULL if not found. */
2806 SHELL_VAR *
2807 find_tempenv_variable (name)
2808      const char *name;
2809 {
2810   return (temporary_env ? hash_lookup (name, temporary_env) : (SHELL_VAR *)NULL);
2811 }
2812
2813 /* Push the variable described by (SHELL_VAR *)DATA down to the next
2814    variable context from the temporary environment. */
2815 static void
2816 push_temp_var (data)
2817      PTR_T data;
2818 {
2819   SHELL_VAR *var, *v;
2820   HASH_TABLE *binding_table;
2821
2822   var = (SHELL_VAR *)data;
2823
2824   binding_table = shell_variables->table;
2825   if (binding_table == 0)
2826     {
2827       if (shell_variables == global_variables)
2828         /* shouldn't happen */
2829         binding_table = shell_variables->table = global_variables->table = hash_create (0);
2830       else
2831         binding_table = shell_variables->table = hash_create (TEMPENV_HASH_BUCKETS);
2832     }
2833
2834   v = bind_variable_internal (var->name, value_cell (var), binding_table, 0);
2835
2836   /* XXX - should we set the context here?  It shouldn't matter because of how
2837      assign_in_env works, but might want to check. */
2838   if (binding_table == global_variables->table)         /* XXX */
2839     var->attributes &= ~(att_tempvar|att_propagate);
2840   else
2841     {
2842       var->attributes |= att_propagate;
2843       if  (binding_table == shell_variables->table)
2844         shell_variables->flags |= VC_HASTMPVAR;
2845     }
2846   v->attributes |= var->attributes;
2847
2848   dispose_variable (var);
2849 }
2850
2851 static void
2852 propagate_temp_var (data)
2853      PTR_T data;
2854 {
2855   SHELL_VAR *var;
2856
2857   var = (SHELL_VAR *)data;
2858   if (tempvar_p (var) && (var->attributes & att_propagate))
2859     push_temp_var (data);
2860   else
2861     dispose_variable (var);
2862 }
2863
2864 /* Free the storage used in the hash table for temporary
2865    environment variables.  PUSHF is a function to be called
2866    to free each hash table entry.  It takes care of pushing variables
2867    to previous scopes if appropriate. */
2868 static void
2869 dispose_temporary_env (pushf)
2870      sh_free_func_t *pushf;
2871 {
2872   hash_flush (temporary_env, pushf);
2873   hash_dispose (temporary_env);
2874   temporary_env  = (HASH_TABLE *)NULL;
2875
2876   array_needs_making = 1;
2877
2878   sv_ifs ("IFS");               /* XXX here for now */
2879 }
2880
2881 void
2882 dispose_used_env_vars ()
2883 {
2884   if (temporary_env)
2885     dispose_temporary_env (propagate_temp_var);
2886 }
2887
2888 /* Take all of the shell variables in the temporary environment HASH_TABLE
2889    and make shell variables from them at the current variable context. */
2890 void
2891 merge_temporary_env ()
2892 {
2893   if (temporary_env)
2894     dispose_temporary_env (push_temp_var);
2895 }
2896
2897 /* **************************************************************** */
2898 /*                                                                  */
2899 /*           Creating and manipulating the environment              */
2900 /*                                                                  */
2901 /* **************************************************************** */
2902
2903 static inline char *
2904 mk_env_string (name, value)
2905      const char *name, *value;
2906 {
2907   int name_len, value_len;
2908   char  *p;
2909
2910   name_len = strlen (name);
2911   value_len = STRLEN (value);
2912   p = (char *)xmalloc (2 + name_len + value_len);
2913   strcpy (p, name);
2914   p[name_len] = '=';
2915   if (value && *value)
2916     strcpy (p + name_len + 1, value);
2917   else
2918     p[name_len + 1] = '\0';
2919   return (p);
2920 }
2921
2922 #ifdef DEBUG
2923 /* Debugging */
2924 static int
2925 valid_exportstr (v)
2926      SHELL_VAR *v;
2927 {
2928   char *s;
2929
2930   s = v->exportstr;
2931   if (legal_variable_starter ((unsigned char)*s) == 0)
2932     {
2933       internal_error (_("invalid character %d in exportstr for %s"), *s, v->name);
2934       return (0);
2935     }
2936   for (s = v->exportstr + 1; s && *s; s++)
2937     {
2938       if (*s == '=')
2939         break;
2940       if (legal_variable_char ((unsigned char)*s) == 0)
2941         {
2942           internal_error (_("invalid character %d in exportstr for %s"), *s, v->name);
2943           return (0);
2944         }
2945     }
2946   if (*s != '=')
2947     {
2948       internal_error (_("no `=' in exportstr for %s"), v->name);
2949       return (0);
2950     }
2951   return (1);
2952 }
2953 #endif
2954
2955 static char **
2956 make_env_array_from_var_list (vars)
2957      SHELL_VAR **vars;
2958 {
2959   register int i, list_index;
2960   register SHELL_VAR *var;
2961   char **list, *value;
2962
2963   list = strvec_create ((1 + strvec_len ((char **)vars)));
2964
2965 #define USE_EXPORTSTR (value == var->exportstr)
2966
2967   for (i = 0, list_index = 0; var = vars[i]; i++)
2968     {
2969 #if defined (__CYGWIN__)
2970       /* We don't use the exportstr stuff on Cygwin at all. */
2971       INVALIDATE_EXPORTSTR (var);
2972 #endif
2973       if (var->exportstr)
2974         value = var->exportstr;
2975       else if (function_p (var))
2976         value = named_function_string ((char *)NULL, function_cell (var), 0);
2977 #if defined (ARRAY_VARS)
2978       else if (array_p (var))
2979 #  if 0
2980         value = array_to_assignment_string (array_cell (var));
2981 #  else
2982         continue;       /* XXX array vars cannot yet be exported */
2983 #  endif
2984 #endif
2985       else
2986         value = value_cell (var);
2987
2988       if (value)
2989         {
2990           /* Gee, I'd like to get away with not using savestring() if we're
2991              using the cached exportstr... */
2992           list[list_index] = USE_EXPORTSTR ? savestring (value)
2993                                            : mk_env_string (var->name, value);
2994
2995           if (USE_EXPORTSTR == 0)
2996             SAVE_EXPORTSTR (var, list[list_index]);
2997
2998           list_index++;
2999 #undef USE_EXPORTSTR
3000
3001 #if 0   /* not yet */
3002 #if defined (ARRAY_VARS)
3003           if (array_p (var))
3004             free (value);
3005 #endif
3006 #endif
3007         }
3008     }
3009
3010   list[list_index] = (char *)NULL;
3011   return (list);
3012 }
3013
3014 /* Make an array of assignment statements from the hash table
3015    HASHED_VARS which contains SHELL_VARs.  Only visible, exported
3016    variables are eligible. */
3017 static char **
3018 make_var_export_array (vcxt)
3019      VAR_CONTEXT *vcxt;
3020 {
3021   char **list;
3022   SHELL_VAR **vars;
3023
3024   vars = map_over (visible_and_exported, vcxt);
3025
3026   if (vars == 0)
3027     return (char **)NULL;
3028
3029   list = make_env_array_from_var_list (vars);
3030
3031   free (vars);
3032   return (list);
3033 }
3034
3035 static char **
3036 make_func_export_array ()
3037 {
3038   char **list;
3039   SHELL_VAR **vars;
3040
3041   vars = map_over_funcs (visible_and_exported);
3042   if (vars == 0)
3043     return (char **)NULL;
3044
3045   list = make_env_array_from_var_list (vars);
3046
3047   free (vars);
3048   return (list);
3049 }
3050
3051 /* Add ENVSTR to the end of the exported environment, EXPORT_ENV. */
3052 #define add_to_export_env(envstr,do_alloc) \
3053 do \
3054   { \
3055     if (export_env_index >= (export_env_size - 1)) \
3056       { \
3057         export_env_size += 16; \
3058         export_env = strvec_resize (export_env, export_env_size); \
3059       } \
3060     export_env[export_env_index++] = (do_alloc) ? savestring (envstr) : envstr; \
3061     export_env[export_env_index] = (char *)NULL; \
3062   } while (0)
3063
3064 /* Add ASSIGN to EXPORT_ENV, or supercede a previous assignment in the
3065    array with the same left-hand side.  Return the new EXPORT_ENV. */
3066 char **
3067 add_or_supercede_exported_var (assign, do_alloc)
3068      char *assign;
3069      int do_alloc;
3070 {
3071   register int i;
3072   int equal_offset;
3073
3074   equal_offset = assignment (assign, 0);
3075   if (equal_offset == 0)
3076     return (export_env);
3077
3078   /* If this is a function, then only supersede the function definition.
3079      We do this by including the `=() {' in the comparison, like
3080      initialize_shell_variables does. */
3081   if (assign[equal_offset + 1] == '(' &&
3082      strncmp (assign + equal_offset + 2, ") {", 3) == 0)                /* } */
3083     equal_offset += 4;
3084
3085   for (i = 0; i < export_env_index; i++)
3086     {
3087       if (STREQN (assign, export_env[i], equal_offset + 1))
3088         {
3089           free (export_env[i]);
3090           export_env[i] = do_alloc ? savestring (assign) : assign;
3091           return (export_env);
3092         }
3093     }
3094   add_to_export_env (assign, do_alloc);
3095   return (export_env);
3096 }
3097
3098 static void
3099 add_temp_array_to_env (temp_array, do_alloc, do_supercede)
3100      char **temp_array;
3101      int do_alloc, do_supercede;
3102 {
3103   register int i;
3104
3105   if (temp_array == 0)
3106     return;
3107
3108   for (i = 0; temp_array[i]; i++)
3109     {
3110       if (do_supercede)
3111         export_env = add_or_supercede_exported_var (temp_array[i], do_alloc);
3112       else
3113         add_to_export_env (temp_array[i], do_alloc);
3114     }
3115
3116   free (temp_array);
3117 }
3118
3119 /* Make the environment array for the command about to be executed, if the
3120    array needs making.  Otherwise, do nothing.  If a shell action could
3121    change the array that commands receive for their environment, then the
3122    code should `array_needs_making++'.
3123
3124    The order to add to the array is:
3125         temporary_env
3126         list of var contexts whose head is shell_variables
3127         shell_functions
3128
3129   This is the shell variable lookup order.  We add only new variable
3130   names at each step, which allows local variables and variables in
3131   the temporary environments to shadow variables in the global (or
3132   any previous) scope.
3133 */
3134
3135 static int
3136 n_shell_variables ()
3137 {
3138   VAR_CONTEXT *vc;
3139   int n;
3140
3141   for (n = 0, vc = shell_variables; vc; vc = vc->down)
3142     n += HASH_ENTRIES (vc->table);
3143   return n;
3144 }
3145
3146 void
3147 maybe_make_export_env ()
3148 {
3149   register char **temp_array;
3150   int new_size;
3151   VAR_CONTEXT *tcxt;
3152
3153   if (array_needs_making)
3154     {
3155       if (export_env)
3156         strvec_flush (export_env);
3157
3158       /* Make a guess based on how many shell variables and functions we
3159          have.  Since there will always be array variables, and array
3160          variables are not (yet) exported, this will always be big enough
3161          for the exported variables and functions. */
3162       new_size = n_shell_variables () + HASH_ENTRIES (shell_functions) + 1 +
3163                  HASH_ENTRIES (temporary_env);
3164       if (new_size > export_env_size)
3165         {
3166           export_env_size = new_size;
3167           export_env = strvec_resize (export_env, export_env_size);
3168         }
3169       export_env[export_env_index = 0] = (char *)NULL;
3170
3171       /* Make a dummy variable context from the  temporary_env, stick it on
3172          the front of shell_variables, call make_var_export_array on the
3173          whole thing to flatten it, and convert the list of SHELL_VAR *s
3174          to the form needed by the environment. */
3175       if (temporary_env)
3176         {
3177           tcxt = new_var_context ((char *)NULL, 0);
3178           tcxt->table = temporary_env;
3179           tcxt->down = shell_variables;
3180         }
3181       else
3182         tcxt = shell_variables;
3183       
3184       temp_array = make_var_export_array (tcxt);
3185       if (temp_array)
3186         add_temp_array_to_env (temp_array, 0, 0);
3187
3188       if (tcxt != shell_variables)
3189         free (tcxt);
3190
3191 #if defined (RESTRICTED_SHELL)
3192       /* Restricted shells may not export shell functions. */
3193       temp_array = restricted ? (char **)0 : make_func_export_array ();
3194 #else
3195       temp_array = make_func_export_array ();
3196 #endif
3197       if (temp_array)
3198         add_temp_array_to_env (temp_array, 0, 0);
3199
3200       array_needs_making = 0;
3201     }
3202 }
3203
3204 /* This is an efficiency hack.  PWD and OLDPWD are auto-exported, so
3205    we will need to remake the exported environment every time we
3206    change directories.  `_' is always put into the environment for
3207    every external command, so without special treatment it will always
3208    cause the environment to be remade.
3209
3210    If there is no other reason to make the exported environment, we can
3211    just update the variables in place and mark the exported environment
3212    as no longer needing a remake. */
3213 void
3214 update_export_env_inplace (env_prefix, preflen, value)
3215      char *env_prefix;
3216      int preflen;
3217      char *value;
3218 {
3219   char *evar;
3220
3221   evar = (char *)xmalloc (STRLEN (value) + preflen + 1);
3222   strcpy (evar, env_prefix);
3223   if (value)
3224     strcpy (evar + preflen, value);
3225   export_env = add_or_supercede_exported_var (evar, 0);
3226 }
3227
3228 /* We always put _ in the environment as the name of this command. */
3229 void
3230 put_command_name_into_env (command_name)
3231      char *command_name;
3232 {
3233   update_export_env_inplace ("_=", 2, command_name);
3234 }
3235
3236 #if 0   /* UNUSED -- it caused too many problems */
3237 void
3238 put_gnu_argv_flags_into_env (pid, flags_string)
3239      intmax_t pid;
3240      char *flags_string;
3241 {
3242   char *dummy, *pbuf;
3243   int l, fl;
3244
3245   pbuf = itos (pid);
3246   l = strlen (pbuf);
3247
3248   fl = strlen (flags_string);
3249
3250   dummy = (char *)xmalloc (l + fl + 30);
3251   dummy[0] = '_';
3252   strcpy (dummy + 1, pbuf);
3253   strcpy (dummy + 1 + l, "_GNU_nonoption_argv_flags_");
3254   dummy[l + 27] = '=';
3255   strcpy (dummy + l + 28, flags_string);
3256
3257   free (pbuf);
3258
3259   export_env = add_or_supercede_exported_var (dummy, 0);
3260 }
3261 #endif
3262
3263 /* **************************************************************** */
3264 /*                                                                  */
3265 /*                    Managing variable contexts                    */
3266 /*                                                                  */
3267 /* **************************************************************** */
3268
3269 /* Allocate and return a new variable context with NAME and FLAGS.
3270    NAME can be NULL. */
3271
3272 VAR_CONTEXT *
3273 new_var_context (name, flags)
3274      char *name;
3275      int flags;
3276 {
3277   VAR_CONTEXT *vc;
3278
3279   vc = (VAR_CONTEXT *)xmalloc (sizeof (VAR_CONTEXT));
3280   vc->name = name ? savestring (name) : (char *)NULL;
3281   vc->scope = variable_context;
3282   vc->flags = flags;
3283
3284   vc->up = vc->down = (VAR_CONTEXT *)NULL;
3285   vc->table = (HASH_TABLE *)NULL;
3286
3287   return vc;
3288 }
3289
3290 /* Free a variable context and its data, including the hash table.  Dispose
3291    all of the variables. */
3292 void
3293 dispose_var_context (vc)
3294      VAR_CONTEXT *vc;
3295 {
3296   FREE (vc->name);
3297
3298   if (vc->table)
3299     {
3300       delete_all_variables (vc->table);
3301       hash_dispose (vc->table);
3302     }
3303
3304   free (vc);
3305 }
3306
3307 /* Set VAR's scope level to the current variable context. */
3308 static int
3309 set_context (var)
3310      SHELL_VAR *var;
3311 {
3312   return (var->context = variable_context);
3313 }
3314
3315 /* Make a new variable context with NAME and FLAGS and a HASH_TABLE of
3316    temporary variables, and push it onto shell_variables.  This is
3317    for shell functions. */
3318 VAR_CONTEXT *
3319 push_var_context (name, flags, tempvars)
3320      char *name;
3321      int flags;
3322      HASH_TABLE *tempvars;
3323 {
3324   VAR_CONTEXT *vc;
3325
3326   vc = new_var_context (name, flags);
3327   vc->table = tempvars;
3328   if (tempvars)
3329     {
3330       /* Have to do this because the temp environment was created before
3331          variable_context was incremented. */
3332       flatten (tempvars, set_context, (VARLIST *)NULL, 0);
3333       vc->flags |= VC_HASTMPVAR;
3334     }
3335   vc->down = shell_variables;
3336   shell_variables->up = vc;
3337
3338   return (shell_variables = vc);
3339 }
3340
3341 static void
3342 push_func_var (data)
3343      PTR_T data;
3344 {
3345   SHELL_VAR *var, *v;
3346
3347   var = (SHELL_VAR *)data;
3348
3349   if (tempvar_p (var) && (posixly_correct || (var->attributes & att_propagate)))
3350     {
3351       /* XXX - should we set v->context here? */
3352       v = bind_variable_internal (var->name, value_cell (var), shell_variables->table, 0);
3353       if (shell_variables == global_variables)
3354         var->attributes &= ~(att_tempvar|att_propagate);
3355       else
3356         shell_variables->flags |= VC_HASTMPVAR;
3357       v->attributes |= var->attributes;
3358     }
3359
3360   dispose_variable (var);
3361 }
3362
3363 /* Pop the top context off of VCXT and dispose of it, returning the rest of
3364    the stack. */
3365 void
3366 pop_var_context ()
3367 {
3368   VAR_CONTEXT *ret, *vcxt;
3369
3370   vcxt = shell_variables;
3371   if (vc_isfuncenv (vcxt) == 0)
3372     {
3373       internal_error (_("pop_var_context: head of shell_variables not a function context"));
3374       return;
3375     }
3376
3377   if (ret = vcxt->down)
3378     {
3379       ret->up = (VAR_CONTEXT *)NULL;
3380       shell_variables = ret;
3381       if (vcxt->table)
3382         hash_flush (vcxt->table, push_func_var);
3383       dispose_var_context (vcxt);
3384     }
3385   else
3386     internal_error (_("pop_var_context: no global_variables context"));
3387 }
3388
3389 /* Delete the HASH_TABLEs for all variable contexts beginning at VCXT, and
3390    all of the VAR_CONTEXTs except GLOBAL_VARIABLES. */
3391 void
3392 delete_all_contexts (vcxt)
3393      VAR_CONTEXT *vcxt;
3394 {
3395   VAR_CONTEXT *v, *t;
3396
3397   for (v = vcxt; v != global_variables; v = t)
3398     {
3399       t = v->down;
3400       dispose_var_context (v);
3401     }            
3402
3403   delete_all_variables (global_variables->table);
3404   shell_variables = global_variables;
3405 }
3406
3407 /* **************************************************************** */
3408 /*                                                                  */
3409 /*         Pushing and Popping temporary variable scopes            */
3410 /*                                                                  */
3411 /* **************************************************************** */
3412
3413 VAR_CONTEXT *
3414 push_scope (flags, tmpvars)
3415      int flags;
3416      HASH_TABLE *tmpvars;
3417 {
3418   return (push_var_context ((char *)NULL, flags, tmpvars));
3419 }
3420
3421 static void
3422 push_exported_var (data)
3423      PTR_T data;
3424 {
3425   SHELL_VAR *var, *v;
3426
3427   var = (SHELL_VAR *)data;
3428
3429   /* If a temp var had its export attribute set, or it's marked to be
3430      propagated, bind it in the previous scope before disposing it. */
3431   if (exported_p (var) || (var->attributes & att_propagate))
3432     {
3433       var->attributes &= ~att_tempvar;          /* XXX */
3434       v = bind_variable_internal (var->name, value_cell (var), shell_variables->table, 0);
3435       if (shell_variables == global_variables)
3436         var->attributes &= ~att_propagate;
3437       v->attributes |= var->attributes;
3438     }
3439
3440   dispose_variable (var);
3441 }
3442
3443 void
3444 pop_scope (is_special)
3445      int is_special;
3446 {
3447   VAR_CONTEXT *vcxt, *ret;
3448
3449   vcxt = shell_variables;
3450   if (vc_istempscope (vcxt) == 0)
3451     {
3452       internal_error (_("pop_scope: head of shell_variables not a temporary environment scope"));
3453       return;
3454     }
3455
3456   ret = vcxt->down;
3457   if (ret)
3458     ret->up = (VAR_CONTEXT *)NULL;
3459
3460   shell_variables = ret;
3461
3462   /* Now we can take care of merging variables in VCXT into set of scopes
3463      whose head is RET (shell_variables). */
3464   FREE (vcxt->name);
3465   if (vcxt->table)
3466     {
3467       if (is_special)
3468         hash_flush (vcxt->table, push_func_var);
3469       else
3470         hash_flush (vcxt->table, push_exported_var);
3471       hash_dispose (vcxt->table);
3472     }
3473   free (vcxt);
3474
3475   sv_ifs ("IFS");       /* XXX here for now */
3476 }
3477
3478 /* **************************************************************** */
3479 /*                                                                  */
3480 /*               Pushing and Popping function contexts              */
3481 /*                                                                  */
3482 /* **************************************************************** */
3483
3484 static WORD_LIST **dollar_arg_stack = (WORD_LIST **)NULL;
3485 static int dollar_arg_stack_slots;
3486 static int dollar_arg_stack_index;
3487
3488 /* XXX - we might want to consider pushing and popping the `getopts' state
3489    when we modify the positional parameters. */
3490 void
3491 push_context (name, is_subshell, tempvars)
3492      char *name;        /* function name */
3493      int is_subshell;
3494      HASH_TABLE *tempvars;
3495 {
3496   if (is_subshell == 0)
3497     push_dollar_vars ();
3498   variable_context++;
3499   push_var_context (name, VC_FUNCENV, tempvars);
3500 }
3501
3502 /* Only called when subshell == 0, so we don't need to check, and can
3503    unconditionally pop the dollar vars off the stack. */
3504 void
3505 pop_context ()
3506 {
3507   pop_dollar_vars ();
3508   variable_context--;
3509   pop_var_context ();
3510
3511   sv_ifs ("IFS");               /* XXX here for now */
3512 }
3513
3514 /* Save the existing positional parameters on a stack. */
3515 void
3516 push_dollar_vars ()
3517 {
3518   if (dollar_arg_stack_index + 2 > dollar_arg_stack_slots)
3519     {
3520       dollar_arg_stack = (WORD_LIST **)
3521         xrealloc (dollar_arg_stack, (dollar_arg_stack_slots += 10)
3522                   * sizeof (WORD_LIST **));
3523     }
3524   dollar_arg_stack[dollar_arg_stack_index++] = list_rest_of_args ();
3525   dollar_arg_stack[dollar_arg_stack_index] = (WORD_LIST *)NULL;
3526 }
3527
3528 /* Restore the positional parameters from our stack. */
3529 void
3530 pop_dollar_vars ()
3531 {
3532   if (!dollar_arg_stack || dollar_arg_stack_index == 0)
3533     return;
3534
3535   remember_args (dollar_arg_stack[--dollar_arg_stack_index], 1);
3536   dispose_words (dollar_arg_stack[dollar_arg_stack_index]);
3537   dollar_arg_stack[dollar_arg_stack_index] = (WORD_LIST *)NULL;
3538   set_dollar_vars_unchanged ();
3539 }
3540
3541 void
3542 dispose_saved_dollar_vars ()
3543 {
3544   if (!dollar_arg_stack || dollar_arg_stack_index == 0)
3545     return;
3546
3547   dispose_words (dollar_arg_stack[dollar_arg_stack_index]);
3548   dollar_arg_stack[dollar_arg_stack_index] = (WORD_LIST *)NULL;
3549 }
3550
3551 /* Manipulate the special BASH_ARGV and BASH_ARGC variables. */
3552
3553 void
3554 push_args (list)
3555      WORD_LIST *list;
3556 {
3557 #if defined (ARRAY_VARS) && defined (DEBUGGER)
3558   SHELL_VAR *bash_argv_v, *bash_argc_v;
3559   ARRAY *bash_argv_a, *bash_argc_a;
3560   WORD_LIST *l;
3561   arrayind_t i;
3562   char *t;
3563
3564   GET_ARRAY_FROM_VAR ("BASH_ARGV", bash_argv_v, bash_argv_a);
3565   GET_ARRAY_FROM_VAR ("BASH_ARGC", bash_argc_v, bash_argc_a);
3566
3567   for (l = list, i = 0; l; l = l->next, i++)
3568     array_push (bash_argv_a, l->word->word);
3569
3570   t = itos (i);
3571   array_push (bash_argc_a, t);
3572   free (t);
3573 #endif /* ARRAY_VARS && DEBUGGER */
3574 }
3575
3576 /* Remove arguments from BASH_ARGV array.  Pop top element off BASH_ARGC
3577    array and use that value as the count of elements to remove from
3578    BASH_ARGV. */
3579 void
3580 pop_args ()
3581 {
3582 #if defined (ARRAY_VARS) && defined (DEBUGGER)
3583   SHELL_VAR *bash_argv_v, *bash_argc_v;
3584   ARRAY *bash_argv_a, *bash_argc_a;
3585   ARRAY_ELEMENT *ce;
3586   intmax_t i;
3587
3588   GET_ARRAY_FROM_VAR ("BASH_ARGV", bash_argv_v, bash_argv_a);
3589   GET_ARRAY_FROM_VAR ("BASH_ARGC", bash_argc_v, bash_argc_a);
3590
3591   ce = array_shift (bash_argc_a, 1, 0);
3592   if (ce == 0 || legal_number (element_value (ce), &i) == 0)
3593     i = 0;
3594
3595   for ( ; i > 0; i--)
3596     array_pop (bash_argv_a);
3597   array_dispose_element (ce);
3598 #endif /* ARRAY_VARS && DEBUGGER */
3599 }
3600
3601 /*************************************************
3602  *                                               *
3603  *      Functions to manage special variables    *
3604  *                                               *
3605  *************************************************/
3606
3607 /* Extern declarations for variables this code has to manage. */
3608 extern int eof_encountered, eof_encountered_limit, ignoreeof;
3609
3610 #if defined (READLINE)
3611 extern int no_line_editing;
3612 extern int hostname_list_initialized;
3613 #endif
3614
3615 /* An alist of name.function for each special variable.  Most of the
3616    functions don't do much, and in fact, this would be faster with a
3617    switch statement, but by the end of this file, I am sick of switch
3618    statements. */
3619
3620 #define SET_INT_VAR(name, intvar)  intvar = find_variable (name) != 0
3621
3622 /* This table will be sorted with qsort() the first time it's accessed. */
3623 struct name_and_function {
3624   char *name;
3625   sh_sv_func_t *function;
3626 };
3627
3628 static struct name_and_function special_vars[] = {
3629   { "GLOBIGNORE", sv_globignore },
3630
3631 #if defined (HISTORY)
3632   { "HISTCONTROL", sv_history_control },
3633   { "HISTFILESIZE", sv_histsize },
3634   { "HISTIGNORE", sv_histignore },
3635   { "HISTSIZE", sv_histsize },
3636   { "HISTTIMEFORMAT", sv_histtimefmt },
3637 #endif
3638
3639 #if defined (READLINE)
3640   { "HOSTFILE", sv_hostfile },
3641 #endif
3642
3643   { "IFS", sv_ifs },
3644   { "IGNOREEOF", sv_ignoreeof },
3645
3646   { "LANG", sv_locale },
3647   { "LC_ALL", sv_locale },
3648   { "LC_COLLATE", sv_locale },
3649   { "LC_CTYPE", sv_locale },
3650   { "LC_MESSAGES", sv_locale },
3651   { "LC_NUMERIC", sv_locale },
3652
3653   { "MAIL", sv_mail },
3654   { "MAILCHECK", sv_mail },
3655   { "MAILPATH", sv_mail },
3656
3657   { "OPTERR", sv_opterr },
3658   { "OPTIND", sv_optind },
3659
3660   { "PATH", sv_path },
3661   { "POSIXLY_CORRECT", sv_strict_posix },
3662
3663 #if defined (READLINE)
3664   { "TERM", sv_terminal },
3665   { "TERMCAP", sv_terminal },
3666   { "TERMINFO", sv_terminal },
3667 #endif /* READLINE */
3668
3669   { "TEXTDOMAIN", sv_locale },
3670   { "TEXTDOMAINDIR", sv_locale },
3671
3672 #if defined (HAVE_TZSET) && defined (PROMPT_STRING_DECODE)
3673   { "TZ", sv_tz },
3674 #endif
3675
3676 #if defined (HISTORY) && defined (BANG_HISTORY)
3677   { "histchars", sv_histchars },
3678 #endif /* HISTORY && BANG_HISTORY */
3679
3680   { "ignoreeof", sv_ignoreeof },
3681
3682   { (char *)0, (sh_sv_func_t *)0 }
3683 };
3684
3685 #define N_SPECIAL_VARS  (sizeof (special_vars) / sizeof (special_vars[0]) - 1)
3686
3687 static int
3688 sv_compare (sv1, sv2)
3689      struct name_and_function *sv1, *sv2;
3690 {
3691   int r;
3692
3693   if ((r = sv1->name[0] - sv2->name[0]) == 0)
3694     r = strcmp (sv1->name, sv2->name);
3695   return r;
3696 }
3697
3698 static inline int
3699 find_special_var (name)
3700      const char *name;
3701 {
3702   register int i, r;
3703
3704   for (i = 0; special_vars[i].name; i++)
3705     {
3706       r = special_vars[i].name[0] - name[0];
3707       if (r == 0)
3708         r = strcmp (special_vars[i].name, name);
3709       if (r == 0)
3710         return i;
3711       else if (r > 0)
3712         /* Can't match any of rest of elements in sorted list.  Take this out
3713            if it causes problems in certain environments. */
3714         break;
3715     }
3716   return -1;
3717 }
3718
3719 /* The variable in NAME has just had its state changed.  Check to see if it
3720    is one of the special ones where something special happens. */
3721 void
3722 stupidly_hack_special_variables (name)
3723      char *name;
3724 {
3725   static int sv_sorted = 0;
3726   int i;
3727
3728   if (sv_sorted == 0)   /* shouldn't need, but it's fairly cheap. */
3729     {
3730       qsort (special_vars, N_SPECIAL_VARS, sizeof (special_vars[0]),
3731                 (QSFUNC *)sv_compare);
3732       sv_sorted = 1;
3733     }
3734
3735   i = find_special_var (name);
3736   if (i != -1)
3737     (*(special_vars[i].function)) (name);
3738 }
3739
3740 void
3741 sv_ifs (name)
3742      char *name;
3743 {
3744   SHELL_VAR *v;
3745
3746   v = find_variable ("IFS");
3747   setifs (v);
3748 }
3749
3750 /* What to do just after the PATH variable has changed. */
3751 void
3752 sv_path (name)
3753      char *name;
3754 {
3755   /* hash -r */
3756   phash_flush ();
3757 }
3758
3759 /* What to do just after one of the MAILxxxx variables has changed.  NAME
3760    is the name of the variable.  This is called with NAME set to one of
3761    MAIL, MAILCHECK, or MAILPATH.  */
3762 void
3763 sv_mail (name)
3764      char *name;
3765 {
3766   /* If the time interval for checking the files has changed, then
3767      reset the mail timer.  Otherwise, one of the pathname vars
3768      to the users mailbox has changed, so rebuild the array of
3769      filenames. */
3770   if (name[4] == 'C')  /* if (strcmp (name, "MAILCHECK") == 0) */
3771     reset_mail_timer ();
3772   else
3773     {
3774       free_mail_files ();
3775       remember_mail_dates ();
3776     }
3777 }
3778
3779 /* What to do when GLOBIGNORE changes. */
3780 void
3781 sv_globignore (name)
3782      char *name;
3783 {
3784   setup_glob_ignore (name);
3785 }
3786
3787 #if defined (READLINE)
3788 /* What to do just after one of the TERMxxx variables has changed.
3789    If we are an interactive shell, then try to reset the terminal
3790    information in readline. */
3791 void
3792 sv_terminal (name)
3793      char *name;
3794 {
3795   if (interactive_shell && no_line_editing == 0)
3796     rl_reset_terminal (get_string_value ("TERM"));
3797 }
3798
3799 void
3800 sv_hostfile (name)
3801      char *name;
3802 {
3803   SHELL_VAR *v;
3804
3805   v = find_variable (name);
3806   if (v == 0)
3807     clear_hostname_list ();
3808   else
3809     hostname_list_initialized = 0;
3810 }
3811 #endif /* READLINE */
3812
3813 #if defined (HISTORY)
3814 /* What to do after the HISTSIZE or HISTFILESIZE variables change.
3815    If there is a value for this HISTSIZE (and it is numeric), then stifle
3816    the history.  Otherwise, if there is NO value for this variable,
3817    unstifle the history.  If name is HISTFILESIZE, and its value is
3818    numeric, truncate the history file to hold no more than that many
3819    lines. */
3820 void
3821 sv_histsize (name)
3822      char *name;
3823 {
3824   char *temp;
3825   intmax_t num;
3826
3827   temp = get_string_value (name);
3828
3829   if (temp && *temp)
3830     {
3831       if (legal_number (temp, &num))
3832         {
3833           if (name[4] == 'S')
3834             {
3835               stifle_history (num);
3836               num = where_history ();
3837               if (history_lines_this_session > num)
3838                 history_lines_this_session = num;
3839             }
3840           else
3841             {
3842               history_truncate_file (get_string_value ("HISTFILE"), (int)num);
3843               if (num <= history_lines_in_file)
3844                 history_lines_in_file = num;
3845             }
3846         }
3847     }
3848   else if (name[4] == 'S')
3849     unstifle_history ();
3850 }
3851
3852 /* What to do after the HISTIGNORE variable changes. */
3853 void
3854 sv_histignore (name)
3855      char *name;
3856 {
3857   setup_history_ignore (name);
3858 }
3859
3860 /* What to do after the HISTCONTROL variable changes. */
3861 void
3862 sv_history_control (name)
3863      char *name;
3864 {
3865   char *temp;
3866   char *val;
3867   int tptr;
3868
3869   history_control = 0;
3870   temp = get_string_value (name);
3871
3872   if (temp == 0 || *temp == 0)
3873     return;
3874
3875   tptr = 0;
3876   while (val = extract_colon_unit (temp, &tptr))
3877     {
3878       if (STREQ (val, "ignorespace"))
3879         history_control |= HC_IGNSPACE;
3880       else if (STREQ (val, "ignoredups"))
3881         history_control |= HC_IGNDUPS;
3882       else if (STREQ (val, "ignoreboth"))
3883         history_control |= HC_IGNBOTH;
3884       else if (STREQ (val, "erasedups"))
3885         history_control |= HC_ERASEDUPS;
3886
3887       free (val);
3888     }
3889 }
3890
3891 #if defined (BANG_HISTORY)
3892 /* Setting/unsetting of the history expansion character. */
3893 void
3894 sv_histchars (name)
3895      char *name;
3896 {
3897   char *temp;
3898
3899   temp = get_string_value (name);
3900   if (temp)
3901     {
3902       history_expansion_char = *temp;
3903       if (temp[0] && temp[1])
3904         {
3905           history_subst_char = temp[1];
3906           if (temp[2])
3907               history_comment_char = temp[2];
3908         }
3909     }
3910   else
3911     {
3912       history_expansion_char = '!';
3913       history_subst_char = '^';
3914       history_comment_char = '#';
3915     }
3916 }
3917 #endif /* BANG_HISTORY */
3918
3919 void
3920 sv_histtimefmt (name)
3921      char *name;
3922 {
3923   SHELL_VAR *v;
3924
3925   v = find_variable (name);
3926   history_write_timestamps = (v != 0);
3927 }
3928 #endif /* HISTORY */
3929
3930 #if defined (HAVE_TZSET) && defined (PROMPT_STRING_DECODE)
3931 void
3932 sv_tz (name)
3933      char *name;
3934 {
3935   tzset ();
3936 }
3937 #endif
3938
3939 /* If the variable exists, then the value of it can be the number
3940    of times we actually ignore the EOF.  The default is small,
3941    (smaller than csh, anyway). */
3942 void
3943 sv_ignoreeof (name)
3944      char *name;
3945 {
3946   SHELL_VAR *tmp_var;
3947   char *temp;
3948
3949   eof_encountered = 0;
3950
3951   tmp_var = find_variable (name);
3952   ignoreeof = tmp_var != 0;
3953   temp = tmp_var ? value_cell (tmp_var) : (char *)NULL;
3954   if (temp)
3955     eof_encountered_limit = (*temp && all_digits (temp)) ? atoi (temp) : 10;
3956   set_shellopts ();     /* make sure `ignoreeof' is/is not in $SHELLOPTS */
3957 }
3958
3959 void
3960 sv_optind (name)
3961      char *name;
3962 {
3963   char *tt;
3964   int s;
3965
3966   tt = get_string_value ("OPTIND");
3967   if (tt && *tt)
3968     {
3969       s = atoi (tt);
3970
3971       /* According to POSIX, setting OPTIND=1 resets the internal state
3972          of getopt (). */
3973       if (s < 0 || s == 1)
3974         s = 0;
3975     }
3976   else
3977     s = 0;
3978   getopts_reset (s);
3979 }
3980
3981 void
3982 sv_opterr (name)
3983      char *name;
3984 {
3985   char *tt;
3986
3987   tt = get_string_value ("OPTERR");
3988   sh_opterr = (tt && *tt) ? atoi (tt) : 1;
3989 }
3990
3991 void
3992 sv_strict_posix (name)
3993      char *name;
3994 {
3995   SET_INT_VAR (name, posixly_correct);
3996   posix_initialize (posixly_correct);
3997 #if defined (READLINE)
3998   if (interactive_shell)
3999     posix_readline_initialize (posixly_correct);
4000 #endif /* READLINE */
4001   set_shellopts ();     /* make sure `posix' is/is not in $SHELLOPTS */
4002 }
4003
4004 void
4005 sv_locale (name)
4006      char *name;
4007 {
4008   char *v;
4009
4010   v = get_string_value (name);
4011   if (name[0] == 'L' && name[1] == 'A') /* LANG */
4012     set_lang (name, v);
4013   else
4014     set_locale_var (name, v);           /* LC_*, TEXTDOMAIN* */
4015 }
4016
4017 #if defined (ARRAY_VARS)
4018 void
4019 set_pipestatus_array (ps, nproc)
4020      int *ps;
4021      int nproc;
4022 {
4023   SHELL_VAR *v;
4024   ARRAY *a;
4025   ARRAY_ELEMENT *ae;
4026   register int i;
4027   char *t, tbuf[INT_STRLEN_BOUND(int) + 1];
4028
4029   v = find_variable ("PIPESTATUS");
4030   if (v == 0)
4031     v = make_new_array_variable ("PIPESTATUS");
4032   if (array_p (v) == 0)
4033     return;             /* Do nothing if not an array variable. */
4034   a = array_cell (v);
4035
4036   if (a == 0 || array_num_elements (a) == 0)
4037     {
4038       for (i = 0; i < nproc; i++)       /* was ps[i] != -1, not i < nproc */
4039         {
4040           t = inttostr (ps[i], tbuf, sizeof (tbuf));
4041           array_insert (a, i, t);
4042         }
4043       return;
4044     }
4045
4046   /* Fast case */
4047   if (array_num_elements (a) == nproc && nproc == 1)
4048     {
4049       ae = element_forw (a->head);
4050       free (element_value (ae));
4051       ae->value = itos (ps[0]);
4052     }
4053   else if (array_num_elements (a) <= nproc)
4054     {
4055       /* modify in array_num_elements members in place, then add */
4056       ae = a->head;
4057       for (i = 0; i < array_num_elements (a); i++)
4058         {
4059           ae = element_forw (ae);
4060           free (element_value (ae));
4061           ae->value = itos (ps[i]);
4062         }
4063       /* add any more */
4064       for ( ; i < nproc; i++)
4065         {
4066           t = inttostr (ps[i], tbuf, sizeof (tbuf));
4067           array_insert (a, i, t);
4068         }
4069     }
4070   else
4071     {
4072       /* deleting elements.  it's faster to rebuild the array. */         
4073       array_flush (a);
4074       for (i = 0; ps[i] != -1; i++)
4075         {
4076           t = inttostr (ps[i], tbuf, sizeof (tbuf));
4077           array_insert (a, i, t);
4078         }
4079     }
4080 }
4081 #endif
4082
4083 void
4084 set_pipestatus_from_exit (s)
4085      int s;
4086 {
4087 #if defined (ARRAY_VARS)
4088   static int v[2] = { 0, -1 };
4089
4090   v[0] = s;
4091   set_pipestatus_array (v, 1);
4092 #endif
4093 }