Imported from ../bash-2.03.tar.gz.
[platform/upstream/bash.git] / variables.c
1 /* variables.c -- Functions for hacking shell variables. */
2
3 /* Copyright (C) 1987,1989 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 1, 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
20
21 #include "config.h"
22
23 #include "bashtypes.h"
24 #include "posixstat.h"
25
26 #if defined (qnx)
27 #  include <sys/vc.h>
28 #endif
29
30 #if defined (HAVE_UNISTD_H)
31 #  include <unistd.h>
32 #endif
33
34 #include <stdio.h>
35 #include <ctype.h>
36 #include <pwd.h>
37 #include "bashansi.h"
38
39 #include "shell.h"
40 #include "flags.h"
41 #include "execute_cmd.h"
42 #include "findcmd.h"
43 #include "mailcheck.h"
44 #include "input.h"
45
46 #include "builtins/getopt.h"
47 #include "builtins/common.h"
48
49 #if defined (READLINE)
50 #  include "bashline.h"
51 #  include <readline/readline.h>
52 #else
53 #  include <tilde/tilde.h>
54 #endif
55
56 #if defined (HISTORY)
57 #  include "bashhist.h"
58 #  include <readline/history.h>
59 #endif /* HISTORY */
60
61 /* Variables used here and defined in other files. */
62 extern int posixly_correct;
63 extern int variable_context, line_number;
64 extern int interactive, interactive_shell, login_shell;
65 extern int subshell_environment, indirection_level;
66 extern int build_version, patch_level;
67 extern char *dist_version, *release_status;
68 extern char *shell_name;
69 extern char *primary_prompt, *secondary_prompt;
70 extern char *current_host_name;
71 extern Function *this_shell_builtin;
72 extern char *this_command_name;
73 extern time_t shell_start_time;
74
75 /* The list of shell variables that the user has created, or that came from
76    the environment. */
77 HASH_TABLE *shell_variables = (HASH_TABLE *)NULL;
78
79 /* The list of shell functions that the user has created, or that came from
80    the environment. */
81 HASH_TABLE *shell_functions = (HASH_TABLE *)NULL;
82
83 /* The current variable context.  This is really a count of how deep into
84    executing functions we are. */
85 int variable_context = 0;
86
87 /* The array of shell assignments which are made only in the environment
88    for a single command. */
89 char **temporary_env = (char **)NULL;
90
91 /* The array of shell assignments which are in the environment for the
92    execution of a shell function. */
93 char **function_env = (char **)NULL;
94
95 /* The array of shell assignments which are made only in the environment
96    for the execution of a shell builtin command which may cause more than
97    one command to be executed (e.g., "source"). */
98 char **builtin_env = (char **)NULL;
99
100 /* Some funky variables which are known about specially.  Here is where
101    "$*", "$1", and all the cruft is kept. */
102 char *dollar_vars[10];
103 WORD_LIST *rest_of_args = (WORD_LIST *)NULL;
104
105 /* The value of $$. */
106 int dollar_dollar_pid;
107
108 /* An array which is passed to commands as their environment.  It is
109    manufactured from the union of the initial environment and the
110    shell variables that are marked for export. */
111 char **export_env = (char **)NULL;
112 static int export_env_index;
113 static int export_env_size;
114
115 /* Non-zero means that we have to remake EXPORT_ENV. */
116 int array_needs_making = 1;
117
118 /* The number of times BASH has been executed.  This is set
119    by initialize_variables (). */
120 int shell_level = 0;
121
122 static char *have_local_variables;
123 static int local_variable_stack_size;
124
125 /* Some forward declarations. */
126 static void set_home_var ();
127 static void set_shell_var ();
128 static char *get_bash_name ();
129 static void initialize_shell_level ();
130 static void uidset ();
131 static void initialize_dynamic_variables ();
132 static void make_vers_array ();
133 static void sbrand ();          /* set bash random number generator. */
134 static int qsort_var_comp ();
135
136 /* Make VAR be auto-exported.  VAR is a pointer to a SHELL_VAR. */
137 #define set_auto_export(var) \
138   do { var->attributes |= att_exported; array_needs_making = 1; } while (0)
139
140 /* Initialize the shell variables from the current environment.
141    If PRIVMODE is nonzero, don't import functions from ENV or
142    parse $SHELLOPTS. */
143 void
144 initialize_shell_variables (env, privmode)
145      char **env;
146      int privmode;
147 {
148   char *name, *string, *temp_string;
149   int c, char_index, string_index, string_length;
150   SHELL_VAR *temp_var;
151
152   if (shell_variables == 0)
153     shell_variables = make_hash_table (0);
154
155   if (shell_functions == 0)
156     shell_functions = make_hash_table (0);
157
158   for (string_index = 0; string = env[string_index++]; )
159     {
160       char_index = 0;
161       name = string;
162       while ((c = *string++) && c != '=')
163         ;
164       if (string[-1] == '=')
165         char_index = string - name - 1;
166
167       /* If there are weird things in the environment, like `=xxx' or a
168          string without an `=', just skip them. */
169       if (char_index == 0)
170         continue;
171
172       /* ASSERT(name[char_index] == '=') */
173       name[char_index] = '\0';
174       /* Now, name = env variable name, string = env variable value, and
175          char_index == strlen (name) */
176
177       /* If exported function, define it now. */
178       if (privmode == 0 && STREQN ("() {", string, 4))
179         {
180           string_length = strlen (string);
181           temp_string = xmalloc (3 + string_length + char_index);
182 #if 1
183           strcpy (temp_string, name);
184           temp_string[char_index] = ' ';
185           strcpy (temp_string + char_index + 1, string);
186 #else
187           sprintf (temp_string, "%s %s", name, string);
188 #endif
189
190           parse_and_execute (temp_string, name, SEVAL_NONINT|SEVAL_NOHIST);
191
192           /* Ancient backwards compatibility.  Old versions of bash exported
193              functions like name()=() {...} */
194           if (name[char_index - 1] == ')' && name[char_index - 2] == '(')
195             name[char_index - 2] = '\0';
196
197           if (temp_var = find_function (name))
198             {
199               temp_var->attributes |= (att_exported | att_imported);
200               array_needs_making = 1;
201             }
202           else
203             report_error ("error importing function definition for `%s'", name);
204
205           if (name[char_index - 1] == ')' && name[char_index - 2] == '\0')
206             name[char_index - 2] = '(';
207         }
208 #if defined (ARRAY_VARS)
209 #  if 0
210       /* Array variables may not yet be exported. */
211       else if (*string == '(' && string[1] == '[' && strchr (string, ')'))
212         {
213           string_length = 1;
214           temp_string = extract_array_assignment_list (string, &string_length);
215           temp_var = assign_array_from_string (name, temp_string);
216           FREE (temp_string);
217           temp_var->attributes |= (att_exported | att_imported);
218           array_needs_making = 1;
219         }
220 #  endif
221 #endif
222       else
223         {
224           temp_var = bind_variable (name, string);
225           temp_var->attributes |= (att_exported | att_imported);
226           array_needs_making = 1;
227         }
228
229       name[char_index] = '=';
230     }
231
232   /* If we got PWD from the environment, update our idea of the current
233      working directory.  In any case, make sure that PWD exists before
234      checking it.  It is possible for getcwd () to fail on shell startup,
235      and in that case, PWD would be undefined. */
236   temp_var = find_variable ("PWD");
237   if (temp_var && imported_p (temp_var) &&
238       (temp_string = value_cell (temp_var)) &&
239       same_file (temp_string, ".", (struct stat *)NULL, (struct stat *)NULL))
240     set_working_directory (temp_string);
241   else
242     {
243       temp_string = get_working_directory ("shell-init");
244       if (temp_string)
245         {
246           temp_var = bind_variable ("PWD", temp_string);
247           set_auto_export (temp_var);
248           free (temp_string);
249         }
250     }
251
252   /* According to the Single Unix Specification, v2, $OLDPWD is an
253      `environment variable' and therefore should be auto-exported.
254      Make a dummy invisible variable for OLDPWD, and mark it as exported. */
255   temp_var = bind_variable ("OLDPWD", (char *)NULL);
256   temp_var->attributes |= (att_exported | att_invisible);
257
258   /* Set up initial value of $_ */
259   temp_var = bind_variable ("_", dollar_vars[0]);
260
261   /* Remember this pid. */
262   dollar_dollar_pid = (int)getpid ();
263
264   /* Now make our own defaults in case the vars that we think are
265      important are missing. */
266   temp_var = set_if_not ("PATH", DEFAULT_PATH_VALUE);
267   set_auto_export (temp_var);
268
269   temp_var = set_if_not ("TERM", "dumb");
270   set_auto_export (temp_var);
271
272 #if defined (qnx)
273   /* set node id -- don't import it from the environment */
274   {
275     char node_name[22];
276     qnx_nidtostr (getnid (), node_name, sizeof (node_name));
277     temp_var = bind_variable ("NODE", node_name);
278     set_auto_export (temp_var);
279   }
280 #endif
281
282   /* set up the prompts. */
283   if (interactive_shell)
284     {
285 #if defined (PROMPT_STRING_DECODE)
286       set_if_not ("PS1", primary_prompt);
287 #else
288       if (current_user.uid == -1)
289         get_current_user_info ();
290       set_if_not ("PS1", current_user.euid == 0 ? "# " : primary_prompt);
291 #endif
292       set_if_not ("PS2", secondary_prompt);
293     }
294   set_if_not ("PS4", "+ ");
295
296   /* Don't allow IFS to be imported from the environment. */
297   temp_var = bind_variable ("IFS", " \t\n");
298
299   /* Magic machine types.  Pretty convenient. */
300   temp_var = bind_variable ("HOSTTYPE", HOSTTYPE);
301   set_auto_export (temp_var);
302   temp_var = bind_variable ("OSTYPE", OSTYPE);
303   set_auto_export (temp_var);
304   temp_var = bind_variable ("MACHTYPE", MACHTYPE);
305   set_auto_export (temp_var);
306   temp_var = bind_variable ("HOSTNAME", current_host_name);
307   set_auto_export (temp_var);
308
309   /* Default MAILCHECK for interactive shells.  Defer the creation of a
310      default MAILPATH until the startup files are read, because MAIL
311      names a mail file if MAILCHECK is not set, and we should provide a
312      default only if neither is set. */
313   if (interactive_shell)
314     set_if_not ("MAILCHECK", "60");
315
316   /* Do some things with shell level. */
317   initialize_shell_level ();
318
319   set_ppid ();
320
321   /* Initialize the `getopts' stuff. */
322   bind_variable ("OPTIND", "1");
323   getopts_reset (0);
324   bind_variable ("OPTERR", "1");
325   sh_opterr = 1;
326
327   if (login_shell == 1)
328     set_home_var ();
329
330   /* Get the full pathname to THIS shell, and set the BASH variable
331      to it. */
332   name = get_bash_name ();
333   temp_var = bind_variable ("BASH", name);
334   free (name);
335
336   /* Make the exported environment variable SHELL be the user's login
337      shell.  Note that the `tset' command looks at this variable
338      to determine what style of commands to output; if it ends in "csh",
339      then C-shell commands are output, else Bourne shell commands. */
340   set_shell_var ();
341
342   /* Make a variable called BASH_VERSION which contains the version info. */
343   bind_variable ("BASH_VERSION", shell_version_string ());
344 #if defined (ARRAY_VARS)
345   make_vers_array ();
346 #endif
347
348   /* Find out if we're supposed to be in Posix.2 mode via an
349      environment variable. */
350   temp_var = find_variable ("POSIXLY_CORRECT");
351   if (!temp_var)
352     temp_var = find_variable ("POSIX_PEDANTIC");
353   if (temp_var && imported_p (temp_var))
354     sv_strict_posix (temp_var->name);
355
356 #if defined (HISTORY)
357   /* Set history variables to defaults, and then do whatever we would
358      do if the variable had just been set.  Do this only in the case
359      that we are remembering commands on the history list. */
360   if (remember_on_history)
361     {
362       name = bash_tilde_expand (posixly_correct ? "~/.sh_history" : "~/.bash_history");
363
364       set_if_not ("HISTFILE", name);
365       free (name);
366
367       set_if_not ("HISTSIZE", "500");
368       sv_histsize ("HISTSIZE");
369     }
370 #endif /* HISTORY */
371
372   /* Seed the random number generator. */
373   sbrand (dollar_dollar_pid + (long)shell_start_time);
374
375   /* Handle some "special" variables that we may have inherited from a
376      parent shell. */
377   if (interactive_shell)
378     {
379       temp_var = find_variable ("IGNOREEOF");
380       if (!temp_var)
381         temp_var = find_variable ("ignoreeof");
382       if (temp_var && imported_p (temp_var))
383         sv_ignoreeof (temp_var->name);
384     }
385
386 #if defined (HISTORY)
387   if (interactive_shell && remember_on_history)
388     {
389       sv_history_control ("HISTCONTROL");
390       sv_histignore ("HISTIGNORE");
391     }
392 #endif /* HISTORY */
393
394   /* Get the user's real and effective user ids. */
395   uidset ();
396
397   /* Initialize the dynamic variables, and seed their values. */
398   initialize_dynamic_variables ();
399 }
400
401 /* Set $HOME to the information in the password file if we didn't get
402    it from the environment. */
403
404 /* This function is not static so the tilde and readline libraries can
405    use it. */
406 char *
407 get_home_dir ()
408 {
409   if (current_user.home_dir == 0)
410     get_current_user_info ();
411   return current_user.home_dir;
412 }
413
414 static void
415 set_home_var ()
416 {
417   SHELL_VAR *temp_var;
418
419   temp_var = find_variable ("HOME");
420   if (temp_var == 0)
421     temp_var = bind_variable ("HOME", get_home_dir ());
422   temp_var->attributes |= att_exported;
423 }
424
425 /* Set $SHELL to the user's login shell if it is not already set.  Call
426    get_current_user_info if we haven't already fetched the shell. */
427 static void
428 set_shell_var ()
429 {
430   SHELL_VAR *temp_var;
431
432   temp_var = find_variable ("SHELL");
433   if (temp_var == 0)
434     {
435       if (current_user.shell == 0)
436         get_current_user_info ();
437       temp_var = bind_variable ("SHELL", current_user.shell);
438     }
439   temp_var->attributes |= att_exported;
440 }
441
442 static char *
443 get_bash_name ()
444 {
445   char *name;
446
447   if ((login_shell == 1) && (*shell_name != '/'))
448     {
449       if (current_user.shell == 0)
450         get_current_user_info ();
451       name = savestring (current_user.shell);
452     }
453   else if (*shell_name == '/')
454     name = savestring (shell_name);
455   else if (shell_name[0] == '.' && shell_name[1] == '/')
456     {
457       /* Fast path for common case. */
458       char *cdir;
459       int len;
460
461       cdir = get_string_value ("PWD");
462       len = strlen (cdir);
463       name = xmalloc (len + strlen (shell_name) + 1);
464       strcpy (name, cdir);
465       strcpy (name + len, shell_name + 1);
466     }
467   else
468     {
469       char *tname;
470       int s;
471
472       tname = find_user_command (shell_name);
473
474       if (tname == 0)
475         {
476           /* Try the current directory.  If there is not an executable
477              there, just punt and use the login shell. */
478           s = file_status (shell_name);
479           if (s & FS_EXECABLE)
480             {
481               tname = make_absolute (shell_name, get_string_value ("PWD"));
482               if (*shell_name == '.')
483                 {
484                   name = canonicalize_pathname (tname);
485                   if (name == 0)
486                     name = tname;
487                   else
488                     free (tname);
489                 }
490              else
491                 name = tname;
492             }
493           else
494             {
495               if (current_user.shell == 0)
496                 get_current_user_info ();
497               name = savestring (current_user.shell);
498             }
499         }
500       else
501         {
502           name = full_pathname (tname);
503           free (tname);
504         }
505     }
506
507   return (name);
508 }
509
510 void
511 adjust_shell_level (change)
512      int change;
513 {
514   char new_level[5], *old_SHLVL;
515   int old_level;
516   SHELL_VAR *temp_var;
517
518   old_SHLVL = get_string_value ("SHLVL");
519   old_level = old_SHLVL ? atoi (old_SHLVL) : 0;
520
521   shell_level = old_level + change;
522   if (shell_level < 0)
523     shell_level = 0;
524   else if (shell_level > 1000)
525     {
526       internal_warning ("shell level (%d) too high, resetting to 1", shell_level);
527       shell_level = 1;
528     }
529
530   /* We don't need the full generality of itos here. */
531   if (shell_level < 10)
532     {
533       new_level[0] = shell_level + '0';
534       new_level[1] = '\0';
535     }
536   else if (shell_level < 100)
537     {
538       new_level[0] = (shell_level / 10) + '0';
539       new_level[1] = (shell_level % 10) + '0';
540       new_level[2] = '\0';
541     }
542   else if (shell_level < 1000)
543     {
544       new_level[0] = (shell_level / 100) + '0';
545       old_level = shell_level % 100;
546       new_level[1] = (old_level / 10) + '0';
547       new_level[2] = (old_level % 10) + '0';
548       new_level[3] = '\0';
549     }
550
551   temp_var = bind_variable ("SHLVL", new_level);
552   set_auto_export (temp_var);
553 }
554
555 static void
556 initialize_shell_level ()
557 {
558 #if 0
559   SHELL_VAR *temp_var;
560
561   temp_var = set_if_not ("SHLVL", "0");
562   set_auto_export (temp_var);
563 #endif
564   adjust_shell_level (1);
565 }
566
567 /* Make a variable $PPID, which holds the pid of the shell's parent.  */
568 void
569 set_ppid ()
570 {
571   char namebuf[32], *name;
572   SHELL_VAR *temp_var;
573
574   name = inttostr ((int) getppid (), namebuf, sizeof(namebuf));
575   temp_var = find_variable ("PPID");
576   if (temp_var)
577     temp_var->attributes &= ~(att_readonly | att_exported);
578   temp_var = bind_variable ("PPID", name);
579   temp_var->attributes |= (att_readonly | att_integer);
580 }
581
582 static void
583 uidset ()
584 {
585   char buff[32], *b;
586   register SHELL_VAR *v;
587
588   b = inttostr (current_user.uid, buff, sizeof (buff));
589   v = find_variable ("UID");
590   if (v)
591     v->attributes &= ~att_readonly;
592
593   v = bind_variable ("UID", b);
594   v->attributes |= (att_readonly | att_integer);
595
596   if (current_user.euid != current_user.uid)
597     b = inttostr (current_user.euid, buff, sizeof (buff));
598
599   v = find_variable ("EUID");
600   if (v)
601     v->attributes &= ~att_readonly;
602
603   v = bind_variable ("EUID", b);
604   v->attributes |= (att_readonly | att_integer);
605 }
606
607 #if defined (ARRAY_VARS)
608 static void
609 make_vers_array ()
610 {
611   SHELL_VAR *vv;
612   ARRAY *av;
613   char *s, d[32];
614
615   makunbound ("BASH_VERSINFO", shell_variables);
616
617   vv = make_new_array_variable ("BASH_VERSINFO");
618   av = array_cell (vv);
619   strcpy (d, dist_version);
620   s = strchr (d, '.');
621   if (s)
622     *s++ = '\0';
623   array_add_element (av, 0, d);
624   array_add_element (av, 1, s);
625   s = inttostr (patch_level, d, sizeof (d));
626   array_add_element (av, 2, s);
627   s = inttostr (build_version, d, sizeof (d));
628   array_add_element (av, 3, s);
629   array_add_element (av, 4, release_status);
630   array_add_element (av, 5, MACHTYPE);
631
632   vv->attributes |= att_readonly;
633 }
634 #endif /* ARRAY_VARS */
635
636 /* Set the environment variables $LINES and $COLUMNS in response to
637    a window size change. */
638 void
639 set_lines_and_columns (lines, cols)
640      int lines, cols;
641 {
642   char val[32], *v;
643
644   v = inttostr (lines, val, sizeof (val));
645   bind_variable ("LINES", v);
646
647   v = inttostr (cols, val, sizeof (val));
648   bind_variable ("COLUMNS", v);
649 }
650
651 /* Set NAME to VALUE if NAME has no value. */
652 SHELL_VAR *
653 set_if_not (name, value)
654      char *name, *value;
655 {
656   SHELL_VAR *v;
657
658   v = find_variable (name);
659   if (v == 0)
660     v = bind_variable (name, value);
661   return (v);
662 }
663
664 /* Map FUNCTION over the variables in VARIABLES.  Return an array of the
665    variables for which FUNCTION returns a non-zero value.  A NULL value
666    for FUNCTION means to use all variables. */
667 SHELL_VAR **
668 map_over (function, var_hash_table)
669      Function *function;
670      HASH_TABLE* var_hash_table;
671 {
672   register int i;
673   register BUCKET_CONTENTS *tlist;
674   SHELL_VAR *var, **list;
675   int list_index, list_size;
676
677   list = (SHELL_VAR **)NULL;
678   for (i = list_index = list_size = 0; i < var_hash_table->nbuckets; i++)
679     {
680       tlist = get_hash_bucket (i, var_hash_table);
681
682       while (tlist)
683         {
684           var = (SHELL_VAR *)tlist->data;
685
686           if (!function || (*function) (var))
687             {
688               if (list_index + 1 >= list_size)
689                 list = (SHELL_VAR **)
690                   xrealloc (list, (list_size += 20) * sizeof (SHELL_VAR *));
691
692               list[list_index++] = var;
693               list[list_index] = (SHELL_VAR *)NULL;
694             }
695           tlist = tlist->next;
696         }
697     }
698   return (list);
699 }
700
701 void
702 sort_variables (array)
703      SHELL_VAR **array;
704 {
705   qsort (array, array_len ((char **)array), sizeof (SHELL_VAR *), qsort_var_comp);
706 }
707
708 static int
709 qsort_var_comp (var1, var2)
710      SHELL_VAR **var1, **var2;
711 {
712   int result;
713
714   if ((result = (*var1)->name[0] - (*var2)->name[0]) == 0)
715     result = strcmp ((*var1)->name, (*var2)->name);
716
717   return (result);
718 }
719
720 /* Create a NULL terminated array of all the shell variables in TABLE. */
721 static SHELL_VAR **
722 all_vars (table)
723      HASH_TABLE *table;
724 {
725   SHELL_VAR **list;
726
727   list = map_over ((Function *)NULL, table);
728   if (list /* && posixly_correct */)
729     sort_variables (list);
730   return (list);
731 }
732
733 /* Create a NULL terminated array of all the shell variables. */
734 SHELL_VAR **
735 all_shell_variables ()
736 {
737   return (all_vars (shell_variables));
738 }
739
740 /* Create a NULL terminated array of all the shell functions. */
741 SHELL_VAR **
742 all_shell_functions ()
743 {
744   return (all_vars (shell_functions));
745 }
746
747 /* Print VARS to stdout in such a way that they can be read back in. */
748 void
749 print_var_list (list)
750      register SHELL_VAR **list;
751 {
752   register int i;
753   register SHELL_VAR *var;
754
755   for (i = 0; list && (var = list[i]); i++)
756     if (!invisible_p (var))
757       print_assignment (var);
758 }
759
760 #if defined (NOTDEF)
761 /* Print LIST (a linked list of shell variables) to stdout
762    by printing the names, without the values.  Used to support the
763    `set +' command. */
764 void
765 print_vars_no_values (list)
766      register SHELL_VAR **list;
767 {
768   register int i;
769   register SHELL_VAR *var;
770
771   for (i = 0; list && (var = list[i]); i++)
772     if (!invisible_p (var))
773       printf ("%s\n", var->name);
774 }
775 #endif
776
777 /* Print the value of a single SHELL_VAR.  No newline is
778    output, but the variable is printed in such a way that
779    it can be read back in. */
780 void
781 print_assignment (var)
782      SHELL_VAR *var;
783 {
784   if (function_p (var) && var->value)
785     {
786       printf ("%s=", var->name);
787       print_var_function (var);
788       printf ("\n");
789     }
790 #if defined (ARRAY_VARS)
791   else if (array_p (var) && var->value)
792     print_array_assignment (var, 0);
793 #endif /* ARRAY_VARS */
794   else if (var->value)
795     {
796       printf ("%s=", var->name);
797       print_var_value (var, 1);
798       printf ("\n");
799     }
800 }
801
802 /* Print the value cell of VAR, a shell variable.  Do not print
803    the name, nor leading/trailing newline.  If QUOTE is non-zero,
804    and the value contains shell metacharacters, quote the value
805    in such a way that it can be read back in. */
806 void
807 print_var_value (var, quote)
808      SHELL_VAR *var;
809      int quote;
810 {
811   char *t;
812
813   if (var->value)
814     {
815       if (quote && contains_shell_metas (var->value))
816         {
817           t = single_quote (var->value);
818           printf ("%s", t);
819           free (t);
820         }
821       else
822         printf ("%s", var->value);
823     }
824 }
825
826 /* Print the function cell of VAR, a shell variable.  Do not
827    print the name, nor leading/trailing newline. */
828 void
829 print_var_function (var)
830      SHELL_VAR *var;
831 {
832   if (function_p (var) && var->value)
833     printf ("%s", named_function_string ((char *)NULL, function_cell(var), 1));
834 }
835
836 #if defined (ARRAY_VARS)
837 void
838 print_array_assignment (var, quoted)
839      SHELL_VAR *var;
840      int quoted;
841 {
842   char *vstr;
843
844   if (quoted)
845     vstr = quoted_array_assignment_string (array_cell (var));
846   else
847     vstr = array_to_assignment_string (array_cell (var));
848
849   if (vstr == 0)
850     printf ("%s=%s\n", var->name, quoted ? "'()'" : "()");
851   else
852     {
853       printf ("%s=%s\n", var->name, vstr);
854       free (vstr);
855     }
856 }
857 #endif /* ARRAY_VARS */
858
859 /* **************************************************************** */
860 /*                                                                  */
861 /*               Dynamic Variable Extension                         */
862 /*                                                                  */
863 /* **************************************************************** */
864
865 /* DYNAMIC VARIABLES
866
867    These are variables whose values are generated anew each time they are
868    referenced.  These are implemented using a pair of function pointers
869    in the struct variable: assign_func, which is called from bind_variable,
870    and dynamic_value, which is called from find_variable.
871
872    assign_func is called from bind_variable, if bind_variable discovers
873    that the variable being assigned to has such a function.  The function
874    is called as
875         SHELL_VAR *temp = (*(entry->assign_func)) (entry, value)
876    and the (SHELL_VAR *)temp is returned as the value of bind_variable.  It
877    is usually ENTRY (self).
878
879    dynamic_value is called from find_variable to return a `new' value for
880    the specified dynamic varible.  If this function is NULL, the variable
881    is treated as a `normal' shell variable.  If it is not, however, then
882    this function is called like this:
883         tempvar = (*(var->dynamic_value)) (var);
884
885    Sometimes `tempvar' will replace the value of `var'.  Other times, the
886    shell will simply use the string value.  Pretty object-oriented, huh?
887
888    Be warned, though: if you `unset' a special variable, it loses its
889    special meaning, even if you subsequently set it.
890
891    The special assignment code would probably have been better put in
892    subst.c: do_assignment, in the same style as
893    stupidly_hack_special_variables, but I wanted the changes as
894    localized as possible.  */
895
896 /* The value of $SECONDS.  This is the number of seconds since shell
897    invocation, or, the number of seconds since the last assignment + the
898    value of the last assignment. */
899 static long seconds_value_assigned;
900
901 static SHELL_VAR *
902 assign_seconds (self, value)
903      SHELL_VAR *self;
904      char *value;
905 {
906   seconds_value_assigned = strtol (value, (char **)NULL, 10);
907   shell_start_time = NOW;
908   return (self);
909 }
910
911 static SHELL_VAR *
912 get_seconds (var)
913      SHELL_VAR *var;
914 {
915   time_t time_since_start;
916   char *p;
917
918   time_since_start = NOW - shell_start_time;
919   p = itos((int) seconds_value_assigned + time_since_start);
920
921   FREE (var->value);
922
923   var->attributes |= att_integer;
924   var->value = p;
925   return (var);
926 }
927
928 /* The random number seed.  You can change this by setting RANDOM. */
929 static unsigned long rseed = 1;
930 static unsigned long last_random_value;
931
932 /* A linear congruential random number generator based on the ANSI
933    C standard.  This one isn't very good (the values are alternately
934    odd and even, for example), but a more complicated one is overkill.  */
935
936 /* Returns a pseudo-random number between 0 and 32767. */
937 static int
938 brand ()
939 {
940   rseed = rseed * 1103515245 + 12345;
941   return ((unsigned int)(rseed & 32767));       /* was % 32768 */
942 }
943
944 /* Set the random number generator seed to SEED. */
945 static void
946 sbrand (seed)
947      int seed;
948 {
949   rseed = seed;
950   last_random_value = 0;
951 }
952
953 static SHELL_VAR *
954 assign_random (self, value)
955      SHELL_VAR *self;
956      char *value;
957 {
958   sbrand (atoi (value));
959   return (self);
960 }
961
962 static SHELL_VAR *
963 get_random (var)
964      SHELL_VAR *var;
965 {
966   int rv;
967   char *p;
968
969   /* Reset for command and process substitution. */
970   if (subshell_environment)
971     sbrand (rseed + (int)(getpid() + NOW));
972
973   do
974     rv = brand ();
975   while (rv == (int)last_random_value);
976
977   last_random_value = rv;
978   p = itos ((int)rv);
979
980   FREE (var->value);
981
982   var->attributes |= att_integer;
983   var->value = p;
984   return (var);
985 }
986
987 /* Function which returns the current line number. */
988 static SHELL_VAR *
989 get_lineno (var)
990      SHELL_VAR *var;
991 {
992   char *p;
993   int ln;
994
995   ln = executing_line_number ();
996   p = itos (ln);
997   FREE (var->value);
998   var->value = p;
999   return (var);
1000 }
1001
1002 static SHELL_VAR *
1003 assign_lineno (var, value)
1004      SHELL_VAR *var;
1005      char *value;
1006 {
1007   line_number = atoi (value);
1008   return var;
1009 }
1010
1011 #if defined (HISTORY)
1012 static SHELL_VAR *
1013 get_histcmd (var)
1014      SHELL_VAR *var;
1015 {
1016   char *p;
1017
1018   p = itos (history_number ());
1019   FREE (var->value);
1020   var->value = p;
1021   return (var);
1022 }
1023 #endif
1024
1025 #if defined (PUSHD_AND_POPD) && defined (ARRAY_VARS)
1026 static SHELL_VAR *
1027 get_dirstack (self)
1028      SHELL_VAR *self;
1029 {
1030   ARRAY *a;
1031   WORD_LIST *l;
1032
1033   l = get_directory_stack ();
1034   a = word_list_to_array (l);
1035   dispose_array (array_cell (self));
1036   dispose_words (l);
1037   self->value = (char *)a;
1038   return self;
1039 }
1040
1041 static  SHELL_VAR *
1042 assign_dirstack (self, ind, value)
1043      SHELL_VAR *self;
1044      int ind;
1045      char *value;
1046 {
1047   set_dirstack_element (ind, 1, value);
1048   return self;
1049 }
1050 #endif /* PUSHD AND POPD && ARRAY_VARS */
1051
1052 #if defined (ARRAY_VARS)
1053 /* We don't want to initialize the group set with a call to getgroups()
1054    unless we're asked to, but we only want to do it once. */
1055 static SHELL_VAR *
1056 get_groupset (self)
1057      SHELL_VAR *self;
1058 {
1059   register int i;
1060   int ng;
1061   ARRAY *a;
1062   static char **group_set = (char **)NULL;
1063
1064   if (group_set == 0)
1065     {
1066       group_set = get_group_list (&ng);
1067       a = array_cell (self);
1068       for (i = 0; i < ng; i++)
1069         array_add_element (a, i, group_set[i]);
1070     }
1071   return (self);
1072 }
1073 #endif /* ARRAY_VARS */
1074   
1075 static void
1076 initialize_dynamic_variables ()
1077 {
1078   SHELL_VAR *v;
1079
1080   v = bind_variable ("SECONDS", (char *)NULL);
1081   v->dynamic_value = get_seconds;
1082   v->assign_func = assign_seconds;
1083
1084   v = bind_variable ("RANDOM", (char *)NULL);
1085   v->dynamic_value = get_random;
1086   v->assign_func = assign_random;
1087
1088   v = bind_variable ("LINENO", (char *)NULL);
1089   v->dynamic_value = get_lineno;
1090   v->assign_func = assign_lineno;
1091
1092 #if defined (HISTORY)
1093   v = bind_variable ("HISTCMD", (char *)NULL);
1094   v->dynamic_value = get_histcmd;
1095   v->assign_func = (DYNAMIC_FUNC *)NULL;
1096 #endif
1097
1098 #if defined (PUSHD_AND_POPD) && defined (ARRAY_VARS)
1099   v = make_new_array_variable ("DIRSTACK");
1100   v->dynamic_value = get_dirstack;
1101   v->assign_func = assign_dirstack;
1102 #endif /* PUSHD_AND_POPD && ARRAY_VARS */
1103
1104 #if defined (ARRAY_VARS)
1105   v = make_new_array_variable ("GROUPS");
1106   v->dynamic_value = get_groupset;
1107   v->assign_func = (DYNAMIC_FUNC *)NULL;
1108   v->attributes |= att_readonly;
1109 #endif
1110 }
1111
1112 /* How to get a pointer to the shell variable or function named NAME.
1113    HASHED_VARS is a pointer to the hash table containing the list
1114    of interest (either variables or functions). */
1115 SHELL_VAR *
1116 var_lookup (name, hashed_vars)
1117      char *name;
1118      HASH_TABLE *hashed_vars;
1119 {
1120   BUCKET_CONTENTS *bucket;
1121
1122   bucket = find_hash_item (name, hashed_vars);
1123   return (bucket ? (SHELL_VAR *)bucket->data : (SHELL_VAR *)NULL);
1124 }
1125
1126 /* Look up the variable entry named NAME.  If SEARCH_TEMPENV is non-zero,
1127    then also search the temporarily built list of exported variables. */
1128 SHELL_VAR *
1129 find_variable_internal (name, search_tempenv)
1130      char *name;
1131      int search_tempenv;
1132 {
1133   SHELL_VAR *var = (SHELL_VAR *)NULL;
1134
1135   /* If explicitly requested, first look in the temporary environment for
1136      the variable.  This allows constructs such as "foo=x eval 'echo $foo'"
1137      to get the `exported' value of $foo.  This happens if we are executing
1138      a function or builtin, or if we are looking up a variable in a
1139      "subshell environment". */
1140   if ((search_tempenv || subshell_environment) &&
1141       (temporary_env || builtin_env || function_env))
1142     var = find_tempenv_variable (name);
1143
1144   if (!var)
1145     var = var_lookup (name, shell_variables);
1146
1147   if (!var)
1148     return ((SHELL_VAR *)NULL);
1149
1150   return (var->dynamic_value ? (*(var->dynamic_value)) (var) : var);
1151 }
1152
1153 /* Look up the variable entry named NAME.  Returns the entry or NULL. */
1154 SHELL_VAR *
1155 find_variable (name)
1156      char *name;
1157 {
1158   return (find_variable_internal
1159           (name, (variable_context || this_shell_builtin || builtin_env)));
1160 }
1161
1162 /* Look up the function entry whose name matches STRING.
1163    Returns the entry or NULL. */
1164 SHELL_VAR *
1165 find_function (name)
1166      char *name;
1167 {
1168   return (var_lookup (name, shell_functions));
1169 }
1170
1171 /* Return the string value of a variable.  Return NULL if the variable
1172    doesn't exist, or only has a function as a value.  Don't cons a new
1173    string.  This is a potential memory leak if the variable is found
1174    in the temporary environment. */
1175 char *
1176 get_string_value (var_name)
1177      char *var_name;
1178 {
1179   SHELL_VAR *var;
1180
1181   var = find_variable (var_name);
1182
1183   if (!var)
1184     return (char *)NULL;
1185 #if defined (ARRAY_VARS)
1186   else if (array_p (var))
1187     return (array_reference (array_cell (var), 0));
1188 #endif
1189   else
1190     return (var->value);
1191 }
1192
1193 /* This is present for use by the tilde and readline libraries. */
1194 char *
1195 get_env_value (v)
1196      char *v;
1197 {
1198   return get_string_value (v);
1199 }
1200
1201 /* Create a local variable referenced by NAME. */
1202 SHELL_VAR *
1203 make_local_variable (name)
1204      char *name;
1205 {
1206   SHELL_VAR *new_var, *old_var;
1207   BUCKET_CONTENTS *elt;
1208
1209   /* local foo; local foo;  is a no-op. */
1210   old_var = find_variable (name);
1211   if (old_var && old_var->context == variable_context)
1212     return (old_var);
1213
1214   elt = remove_hash_item (name, shell_variables);
1215   if (elt)
1216     {
1217       old_var = (SHELL_VAR *)elt->data;
1218       free (elt->key);
1219       free (elt);
1220     }
1221   else
1222     old_var = (SHELL_VAR *)NULL;
1223
1224   /* If a variable does not already exist with this name, then
1225      just make a new one. */
1226   if (old_var == 0)
1227     new_var = bind_variable (name, "");
1228   else
1229     {
1230       new_var = (SHELL_VAR *)xmalloc (sizeof (SHELL_VAR));
1231
1232       new_var->name = savestring (name);
1233       new_var->value = xmalloc (1);
1234       new_var->value[0] = '\0';
1235
1236       new_var->dynamic_value = (DYNAMIC_FUNC *)NULL;
1237       new_var->assign_func = (DYNAMIC_FUNC *)NULL;
1238
1239       new_var->attributes = exported_p (old_var) ? att_exported : 0;
1240
1241       new_var->prev_context = old_var;
1242       elt = add_hash_item (savestring (name), shell_variables);
1243       elt->data = (char *)new_var;
1244     }
1245
1246   new_var->context = variable_context;
1247   new_var->attributes |= att_local;
1248
1249   /* XXX */
1250   if (variable_context >= local_variable_stack_size)
1251     {
1252       int old_size = local_variable_stack_size;
1253       RESIZE_MALLOCED_BUFFER (have_local_variables, variable_context, 1,
1254                               local_variable_stack_size, 8);
1255       bzero ((char *)have_local_variables + old_size,
1256              local_variable_stack_size - old_size);
1257     }
1258   have_local_variables[variable_context] = 1;           /* XXX */
1259
1260   return (new_var);
1261 }
1262
1263 #if defined (ARRAY_VARS)
1264 SHELL_VAR *
1265 make_local_array_variable (name)
1266      char *name;
1267 {
1268   SHELL_VAR *var;
1269   ARRAY *array;
1270
1271   var = make_local_variable (name);
1272   array = new_array ();
1273
1274   FREE (value_cell(var));
1275   var->value = (char *)array;
1276   var->attributes |= att_array;
1277   return var;
1278 }
1279 #endif /* ARRAY_VARS */
1280
1281 /* Create a new shell variable with name NAME and add it to the hash table
1282    of shell variables. */
1283 static
1284 SHELL_VAR *
1285 make_new_variable (name)
1286      char *name;
1287 {
1288   SHELL_VAR *entry;
1289   BUCKET_CONTENTS *elt;
1290
1291   entry = (SHELL_VAR *)xmalloc (sizeof (SHELL_VAR));
1292
1293   entry->attributes = 0;
1294   entry->name = savestring (name);
1295   entry->value = (char *)NULL;
1296
1297   entry->dynamic_value = (DYNAMIC_FUNC *)NULL;
1298   entry->assign_func = (DYNAMIC_FUNC *)NULL;
1299
1300   /* Always assume variables are to be made at toplevel!
1301      make_local_variable has the responsibilty of changing the
1302      variable context. */
1303   entry->context = 0;
1304   entry->prev_context = (SHELL_VAR *)NULL;
1305
1306   elt = add_hash_item (savestring (name), shell_variables);
1307   elt->data = (char *)entry;
1308
1309   return entry;
1310 }
1311
1312 #if defined (ARRAY_VARS)
1313 SHELL_VAR *
1314 make_new_array_variable (name)
1315      char *name;
1316 {
1317   SHELL_VAR *entry;
1318   ARRAY *array;
1319
1320   entry = make_new_variable (name);
1321   array = new_array ();
1322   entry->value = (char *)array;
1323   entry->attributes |= att_array;
1324   return entry;
1325 }
1326 #endif
1327
1328 char *
1329 make_variable_value (var, value)
1330      SHELL_VAR *var;
1331      char *value;
1332 {
1333   char *retval;
1334   long lval;
1335   int expok;
1336
1337   /* If this variable has had its type set to integer (via `declare -i'),
1338      then do expression evaluation on it and store the result.  The
1339      functions in expr.c (evalexp and bind_int_variable) are responsible
1340      for turning off the integer flag if they don't want further
1341      evaluation done. */
1342   if (integer_p (var))
1343     {
1344       lval = evalexp (value, &expok);
1345       if (expok == 0)
1346         jump_to_top_level (DISCARD);
1347       retval = itos (lval);
1348     }
1349   else if (value)
1350     {
1351       if (*value)
1352         retval = savestring (value);
1353       else
1354         {
1355           retval = xmalloc (1);
1356           retval[0] = '\0';
1357         }
1358     }
1359   else
1360     retval = (char *)NULL;
1361
1362   return retval;
1363 }
1364
1365 /* Bind a variable NAME to VALUE.  This conses up the name
1366    and value strings. */
1367 SHELL_VAR *
1368 bind_variable (name, value)
1369      char *name, *value;
1370 {
1371   char *newval;
1372   SHELL_VAR *entry;
1373
1374   entry = var_lookup (name, shell_variables);
1375
1376   if (entry == 0)
1377     {
1378       entry = make_new_variable (name);
1379       entry->value = make_variable_value (entry, value);
1380     }
1381 #if defined (ARRAY_VARS)
1382   else if (entry->assign_func && array_p (entry) == 0)
1383 #else
1384   else if (entry->assign_func)
1385 #endif
1386     return ((*(entry->assign_func)) (entry, value));
1387   else
1388     {
1389       if (readonly_p (entry))
1390         {
1391           report_error ("%s: readonly variable", name);
1392           return (entry);
1393         }
1394
1395       /* Variables which are bound are visible. */
1396       entry->attributes &= ~att_invisible;
1397
1398       newval = make_variable_value (entry, value);
1399
1400 #if defined (ARRAY_VARS)
1401       /* XXX -- this bears looking at again -- XXX */
1402       /* If an existing array variable x is being assigned to with x=b or
1403          `read x' or something of that nature, silently convert it to
1404          x[0]=b or `read x[0]'. */
1405       if (array_p (entry))
1406         {
1407           array_add_element (array_cell (entry), 0, newval);
1408           free (newval);
1409         }
1410       else
1411         {
1412           FREE (entry->value);
1413           entry->value = newval;
1414         }
1415 #else
1416       FREE (entry->value);
1417       entry->value = newval;
1418 #endif
1419     }
1420
1421   if (mark_modified_vars)
1422     entry->attributes |= att_exported;
1423
1424   if (exported_p (entry))
1425     array_needs_making = 1;
1426
1427   return (entry);
1428 }
1429
1430 #if defined (ARRAY_VARS)
1431 /* Convert a shell variable to an array variable.  The original value is
1432    saved as array[0]. */
1433 SHELL_VAR *
1434 convert_var_to_array (var)
1435      SHELL_VAR *var;
1436 {
1437   char *oldval;
1438   ARRAY *array;
1439
1440   oldval = value_cell (var);
1441   array = new_array ();
1442   array_add_element (array, 0, oldval);
1443   FREE (value_cell (var));
1444   var->value = (char *)array;
1445   var->attributes |= att_array;
1446   var->attributes &= ~att_invisible;
1447
1448   return var;
1449 }
1450
1451 /* Perform an array assignment name[ind]=value.  If NAME already exists and
1452    is not an array, and IND is 0, perform name=value instead.  If NAME exists
1453    and is not an array, and IND is not 0, convert it into an array with the
1454    existing value as name[0].
1455
1456    If NAME does not exist, just create an array variable, no matter what
1457    IND's value may be. */
1458 SHELL_VAR *
1459 bind_array_variable (name, ind, value)
1460      char *name;
1461      int ind;
1462      char *value;
1463 {
1464   SHELL_VAR *entry;
1465   char *newval;
1466
1467   entry = var_lookup (name, shell_variables);
1468
1469   if (entry == (SHELL_VAR *) 0)
1470     entry = make_new_array_variable (name);
1471   else if (readonly_p (entry))
1472     {
1473       report_error ("%s: readonly variable", name);
1474       return (entry);
1475     }
1476   else if (array_p (entry) == 0)
1477     entry = convert_var_to_array (entry);
1478
1479   /* ENTRY is an array variable, and ARRAY points to the value. */
1480   newval = make_variable_value (entry, value);
1481   if (entry->assign_func)
1482     (*entry->assign_func) (entry, ind, newval);
1483   else
1484     array_add_element (array_cell (entry), ind, newval);
1485   FREE (newval);
1486
1487   return (entry);
1488 }
1489
1490 /* Perform a compound assignment statement for array NAME, where VALUE is
1491    the text between the parens:  NAME=( VALUE ) */
1492 SHELL_VAR *
1493 assign_array_from_string (name, value)
1494      char *name, *value;
1495 {
1496   SHELL_VAR *var;
1497
1498   var = find_variable (name);
1499   if (var == 0)
1500     var = make_new_array_variable (name);
1501   else if (readonly_p (var))
1502     {
1503       report_error ("%s: readonly variable", name);
1504       return ((SHELL_VAR *)NULL);
1505     }
1506   else if (array_p (var) == 0)
1507     var = convert_var_to_array (var);
1508
1509   return (assign_array_var_from_string (var, value));
1510 }
1511
1512 SHELL_VAR *
1513 assign_array_var_from_word_list (var, list)
1514      SHELL_VAR *var;
1515      WORD_LIST *list;
1516 {
1517   register int i;
1518   register WORD_LIST *l;
1519   ARRAY *a;
1520
1521   for (a = array_cell (var), l = list, i = 0; l; l = l->next, i++)
1522     if (var->assign_func)
1523       (*var->assign_func) (var, i, l->word->word);
1524     else
1525       array_add_element (a, i, l->word->word);
1526   return var;
1527 }
1528
1529 /* Perform a compound array assignment:  VAR->name=( VALUE ).  The
1530    VALUE has already had the parentheses stripped. */
1531 SHELL_VAR *
1532 assign_array_var_from_string (var, value)
1533      SHELL_VAR *var;
1534      char *value;
1535 {
1536   ARRAY *a;
1537   WORD_LIST *list, *nlist;
1538   char *w, *val, *nval;
1539   int ni, len, ind, last_ind;
1540
1541   if (value == 0)
1542     return var;
1543
1544   /* If this is called from declare_builtin, value[0] == '(' and
1545      strchr(value, ')') != 0.  In this case, we need to extract
1546      the value from between the parens before going on. */
1547   if (*value == '(')    /*)*/
1548     {
1549       ni = 1;
1550       val = extract_array_assignment_list (value, &ni);
1551       if (val == 0)
1552         return var;
1553     }
1554   else
1555     val = value;
1556
1557   /* Expand the value string into a list of words, performing all the
1558      shell expansions including pathname generation and word splitting. */
1559   /* First we split the string on whitespace, using the shell parser
1560      (ksh93 seems to do this). */
1561   list = parse_string_to_word_list (val, "array assign");
1562   /* Now that we've split it, perform the shell expansions on each
1563      word in the list. */
1564 #if 0
1565   nlist = list ? expand_words_shellexp (list) : (WORD_LIST *)NULL;
1566 #else
1567   nlist = list ? expand_words_no_vars (list) : (WORD_LIST *)NULL;
1568 #endif
1569
1570   dispose_words (list);
1571
1572   if (val != value)
1573     free (val);
1574
1575   a = array_cell (var);
1576
1577   /* Now that we are ready to assign values to the array, kill the existing
1578      value. */
1579   if (a)
1580     empty_array (a);
1581
1582   for (last_ind = 0, list = nlist; list; list = list->next)
1583     {
1584       w = list->word->word;
1585
1586       /* We have a word of the form [ind]=value */
1587       if (w[0] == '[')
1588         {
1589           len = skipsubscript (w, 0);
1590
1591           if (w[len] != ']' || w[len+1] != '=')
1592             {
1593               nval = make_variable_value (var, w);
1594               if (var->assign_func)
1595                 (*var->assign_func) (var, last_ind, nval);
1596               else
1597                 array_add_element (a, last_ind, nval);
1598               FREE (nval);
1599               last_ind++;
1600               continue;
1601             }
1602
1603           if (len == 1)
1604             {
1605               report_error ("%s: bad array subscript", w);
1606               continue;
1607             }
1608
1609           if (ALL_ELEMENT_SUB (w[1]) && len == 2)
1610             {
1611               report_error ("%s: cannot assign to non-numeric index", w);
1612               continue;
1613             }
1614
1615           ind = array_expand_index (w + 1, len);
1616           if (ind < 0)
1617             {
1618               report_error ("%s: bad array subscript", w);
1619               continue;
1620             }
1621           last_ind = ind;
1622           val = w + len + 2;
1623         }
1624       else              /* No [ind]=value, just a stray `=' */
1625         {
1626           ind = last_ind;
1627           val = w;
1628         }
1629
1630       if (integer_p (var))
1631         this_command_name = (char *)NULL;       /* no command name for errors */
1632       nval = make_variable_value (var, val);
1633       if (var->assign_func)
1634         (*var->assign_func) (var, ind, nval);
1635       else
1636         array_add_element (a, ind, nval);
1637       FREE (nval);
1638       last_ind++;
1639     }
1640
1641   dispose_words (nlist);
1642   return (var);
1643 }
1644 #endif /* ARRAY_VARS */
1645
1646 /* Dispose of the information attached to VAR. */
1647 void
1648 dispose_variable (var)
1649      SHELL_VAR *var;
1650 {
1651   if (!var)
1652     return;
1653
1654   if (function_p (var))
1655     dispose_command (function_cell (var));
1656 #if defined (ARRAY_VARS)
1657   else if (array_p (var))
1658     dispose_array (array_cell (var));
1659 #endif
1660   else
1661     FREE (value_cell (var));
1662
1663   free (var->name);
1664
1665   if (exported_p (var))
1666     array_needs_making = 1;
1667
1668   free (var);
1669 }
1670
1671 #if defined (ARRAY_VARS)
1672 /* This function is called with SUB pointing to just after the beginning
1673    `[' of an array subscript. */
1674 int
1675 unbind_array_element (var, sub)
1676      SHELL_VAR *var;
1677      char *sub;
1678 {
1679   int len, ind;
1680   ARRAY_ELEMENT *ae;
1681
1682   len = skipsubscript (sub, 0);
1683   if (sub[len] != ']' || len == 0)
1684     {
1685       builtin_error ("%s[%s: bad array subscript", var->name, sub);
1686       return -1;
1687     }
1688   sub[len] = '\0';
1689
1690   if (ALL_ELEMENT_SUB (sub[0]) && sub[1] == 0)
1691     {
1692       makunbound (var->name, shell_variables);
1693       return (0);
1694     }
1695   ind = array_expand_index (sub, len+1);
1696   if (ind < 0)
1697     {
1698       builtin_error ("[%s]: bad array subscript", sub);
1699       return -1;
1700     }
1701   ae = array_delete_element (array_cell (var), ind);
1702   if (ae)
1703     destroy_array_element (ae);
1704   return 0;
1705 }
1706 #endif
1707
1708 /* Unset the variable referenced by NAME. */
1709 int
1710 unbind_variable (name)
1711      char *name;
1712 {
1713   SHELL_VAR *var;
1714
1715   var = find_variable (name);
1716   if (!var)
1717     return (-1);
1718
1719   /* This function should never be called with an array variable name. */
1720 #if defined (ARRAY_VARS)
1721   if (array_p (var) == 0 && var->value)
1722 #else
1723   if (var->value)
1724 #endif
1725     {
1726       free (var->value);
1727       var->value = (char *)NULL;
1728     }
1729
1730   makunbound (name, shell_variables);
1731
1732   return (0);
1733 }
1734
1735 /* Make the variable associated with NAME go away.  HASH_LIST is the
1736    hash table from which this variable should be deleted (either
1737    shell_variables or shell_functions).
1738    Returns non-zero if the variable couldn't be found. */
1739 int
1740 makunbound (name, hash_list)
1741      char *name;
1742      HASH_TABLE *hash_list;
1743 {
1744   BUCKET_CONTENTS *elt, *new_elt;
1745   SHELL_VAR *old_var, *new_var;
1746   char *t;
1747
1748   elt = remove_hash_item (name, hash_list);
1749
1750   if (elt == 0)
1751     return (-1);
1752
1753   old_var = (SHELL_VAR *)elt->data;
1754   new_var = old_var->prev_context;
1755
1756   if (old_var && exported_p (old_var))
1757     array_needs_making++;
1758
1759   /* If we're unsetting a local variable and we're still executing inside
1760      the function, just mark the variable as invisible.
1761      kill_all_local_variables will clean it up later.  This must be done
1762      so that if the variable is subsequently assigned a new value inside
1763      the function, the `local' attribute is still present.  We also need
1764      to add it back into the correct hash table. */
1765   if (old_var && local_p (old_var) && variable_context == old_var->context)
1766     {
1767       old_var->attributes |= att_invisible;
1768       new_elt = add_hash_item (savestring (old_var->name), hash_list);
1769       new_elt->data = (char *)old_var;
1770       stupidly_hack_special_variables (old_var->name);
1771       free (elt->key);
1772       free (elt);
1773       return (0);
1774     }
1775
1776   if (new_var)
1777     {
1778       /* Has to be a variable, functions don't have previous contexts. */
1779       new_elt = add_hash_item (savestring (new_var->name), hash_list);
1780       new_elt->data = (char *)new_var;
1781
1782       if (exported_p (new_var))
1783         set_auto_export (new_var);
1784     }
1785
1786   /* Have to save a copy of name here, because it might refer to
1787      old_var->name.  If so, stupidly_hack_special_variables will
1788      reference freed memory. */
1789   t = savestring (name);
1790
1791   free (elt->key);
1792   free (elt);
1793
1794   dispose_variable (old_var);
1795   stupidly_hack_special_variables (t);
1796   free (t);
1797   return (0);
1798 }
1799
1800 #ifdef INCLUDE_UNUSED
1801 /* Remove the variable with NAME if it is a local variable in the
1802    current context. */
1803 int
1804 kill_local_variable (name)
1805      char *name;
1806 {
1807   SHELL_VAR *temp;
1808
1809   temp = find_variable (name);
1810   if (temp && temp->context == variable_context)
1811     {
1812       makunbound (name, shell_variables);
1813       return (0);
1814     }
1815   return (-1);
1816 }
1817 #endif
1818
1819 /* Get rid of all of the variables in the current context. */
1820 int
1821 variable_in_context (var)
1822      SHELL_VAR *var;
1823 {
1824   return (var && var->context == variable_context);
1825 }
1826
1827 void
1828 kill_all_local_variables ()
1829 {
1830   register int i, pass;
1831   register SHELL_VAR *var, **list;
1832   HASH_TABLE *varlist;
1833
1834   /* If HAVE_LOCAL_VARIABLES == 0, it means that we don't have any local
1835      variables at all.  If VARIABLE_CONTEXT >= LOCAL_VARIABLE_STACK_SIZE,
1836      it means that we have some local variables, but not in this variable
1837      context (level of function nesting).  Also, if
1838      HAVE_LOCAL_VARIABLES[VARIABLE_CONTEXT] == 0, we have no local variables
1839      at this context. */
1840   if (have_local_variables == 0 ||
1841       variable_context >= local_variable_stack_size ||
1842       have_local_variables[variable_context] == 0)
1843     return;
1844
1845   for (pass = 0; pass < 2; pass++)
1846     {
1847       varlist = pass ? shell_functions : shell_variables;
1848
1849       list = map_over (variable_in_context, varlist);
1850
1851       if (list)
1852         {
1853           for (i = 0; var = list[i]; i++)
1854             {
1855               var->attributes &= ~att_local;
1856               makunbound (var->name, varlist);
1857             }
1858           free (list);
1859         }
1860     }
1861
1862   have_local_variables[variable_context] = 0;           /* XXX */
1863 }
1864
1865 static void
1866 free_variable_hash_data (data)
1867      char *data;
1868 {
1869   SHELL_VAR *var, *prev;
1870
1871   var = (SHELL_VAR *)data;
1872   while (var)
1873     {
1874       prev = var->prev_context;
1875       dispose_variable (var);
1876       var = prev;
1877     }
1878 }
1879
1880 /* Delete the entire contents of the hash table. */
1881 void
1882 delete_all_variables (hashed_vars)
1883      HASH_TABLE *hashed_vars;
1884 {
1885   flush_hash_table (hashed_vars, free_variable_hash_data);
1886 }
1887
1888 static SHELL_VAR *
1889 new_shell_variable (name)
1890      char *name;
1891 {
1892   SHELL_VAR *var;
1893
1894   var = (SHELL_VAR *)xmalloc (sizeof (SHELL_VAR));
1895
1896   bzero ((char *)var, sizeof (SHELL_VAR));
1897   var->name = savestring (name);
1898   return (var);
1899 }
1900
1901 /* Do a function binding to a variable.  You pass the name and
1902    the command to bind to.  This conses the name and command. */
1903 SHELL_VAR *
1904 bind_function (name, value)
1905      char *name;
1906      COMMAND *value;
1907 {
1908   SHELL_VAR *entry;
1909
1910   entry = find_function (name);
1911   if (!entry)
1912     {
1913       BUCKET_CONTENTS *elt;
1914
1915       elt = add_hash_item (savestring (name), shell_functions);
1916
1917       elt->data = (char *)new_shell_variable (name);
1918       entry = (SHELL_VAR *)elt->data;
1919       entry->dynamic_value = entry->assign_func = (DYNAMIC_FUNC *)NULL;
1920
1921       /* Functions are always made at the top level.  This allows a
1922          function to define another function (like autoload). */
1923       entry->context = 0;
1924     }
1925
1926   if (entry->value)
1927     dispose_command ((COMMAND *)entry->value);
1928
1929   entry->value = value ? (char *)copy_command (value) : (char *)NULL;
1930   entry->attributes |= att_function;
1931
1932   if (mark_modified_vars)
1933     entry->attributes |= att_exported;
1934
1935   entry->attributes &= ~att_invisible;  /* Just to be sure */
1936
1937   if (exported_p (entry))
1938     array_needs_making = 1;
1939
1940   return (entry);
1941 }
1942
1943 #ifdef INCLUDE_UNUSED
1944 /* Copy VAR to a new data structure and return that structure. */
1945 SHELL_VAR *
1946 copy_variable (var)
1947      SHELL_VAR *var;
1948 {
1949   SHELL_VAR *copy = (SHELL_VAR *)NULL;
1950
1951   if (var)
1952     {
1953       copy = (SHELL_VAR *)xmalloc (sizeof (SHELL_VAR));
1954
1955       copy->attributes = var->attributes;
1956       copy->name = savestring (var->name);
1957
1958       if (function_p (var))
1959         copy->value = (char *)copy_command (function_cell (var));
1960 #if defined (ARRAY_VARS)
1961       else if (array_p (var))
1962         copy->value = (char *)dup_array (array_cell (var));
1963 #endif
1964       else if (value_cell (var))
1965         copy->value = savestring (value_cell (var));
1966       else
1967         copy->value = (char *)NULL;
1968
1969       copy->dynamic_value = var->dynamic_value;
1970       copy->assign_func = var->assign_func;
1971
1972       copy->context = var->context;
1973
1974       /* Don't bother copying previous contexts along with this variable. */
1975       copy->prev_context = (SHELL_VAR *)NULL;
1976     }
1977   return (copy);
1978 }
1979 #endif
1980
1981 #define FIND_OR_MAKE_VARIABLE(name, entry) \
1982   do \
1983     { \
1984       entry = find_variable (name); \
1985       if (!entry) \
1986         { \
1987           entry = bind_variable (name, ""); \
1988           if (!no_invisible_vars) entry->attributes |= att_invisible; \
1989         } \
1990     } \
1991   while (0)
1992
1993 /* Make the variable associated with NAME be readonly.
1994    If NAME does not exist yet, create it. */
1995 void
1996 set_var_read_only (name)
1997      char *name;
1998 {
1999   SHELL_VAR *entry;
2000
2001   FIND_OR_MAKE_VARIABLE (name, entry);
2002   entry->attributes |= att_readonly;
2003 }
2004
2005 #ifdef INCLUDE_UNUSED
2006 /* Make the function associated with NAME be readonly.
2007    If NAME does not exist, we just punt, like auto_export code below. */
2008 void
2009 set_func_read_only (name)
2010      char *name;
2011 {
2012   SHELL_VAR *entry;
2013
2014   entry = find_function (name);
2015   if (entry)
2016     entry->attributes |= att_readonly;
2017 }
2018
2019 /* Make the variable associated with NAME be auto-exported.
2020    If NAME does not exist yet, create it. */
2021 void
2022 set_var_auto_export (name)
2023      char *name;
2024 {
2025   SHELL_VAR *entry;
2026
2027   FIND_OR_MAKE_VARIABLE (name, entry);
2028   set_auto_export (entry);
2029 }
2030
2031 /* Make the function associated with NAME be auto-exported. */
2032 void
2033 set_func_auto_export (name)
2034      char *name;
2035 {
2036   SHELL_VAR *entry;
2037
2038   entry = find_function (name);
2039   if (entry)
2040     set_auto_export (entry);
2041 }
2042 #endif
2043
2044 #if defined (ARRAY_VARS)
2045 /* This function assumes s[i] == '['; returns with s[ret] == ']' if
2046    an array subscript is correctly parsed. */
2047 int
2048 skipsubscript (s, i)
2049      char *s;
2050      int i;
2051 {
2052   int count, c;
2053
2054   for (count = 1; count && (c = s[++i]); )
2055     {
2056       if (c == '[')
2057         count++;
2058       else if (c == ']')
2059         count--;
2060     }
2061   return i;
2062 }
2063 #endif /* ARRAY_VARS */
2064
2065 /* Returns non-zero if STRING is an assignment statement.  The returned value
2066    is the index of the `=' sign. */
2067 int
2068 assignment (string)
2069      char *string;
2070 {
2071   register int c, newi, indx;
2072
2073   c = string[indx = 0];
2074
2075   if (legal_variable_starter (c) == 0)
2076     return (0);
2077
2078   while (c = string[indx])
2079     {
2080       /* The following is safe.  Note that '=' at the start of a word
2081          is not an assignment statement. */
2082       if (c == '=')
2083         return (indx);
2084
2085 #if defined (ARRAY_VARS)
2086       if (c == '[')
2087         {
2088           newi = skipsubscript (string, indx);
2089           if (string[newi++] != ']')
2090             return (0);
2091           return ((string[newi] == '=') ? newi : 0);
2092         }
2093 #endif /* ARRAY_VARS */
2094
2095       /* Variable names in assignment statements may contain only letters,
2096          digits, and `_'. */
2097       if (legal_variable_char (c) == 0)
2098         return (0);
2099
2100       indx++;
2101     }
2102   return (0);
2103 }
2104
2105 #ifdef READLINE
2106
2107 static int
2108 visible_var (var)
2109      SHELL_VAR *var;
2110 {
2111   return (invisible_p (var) == 0);
2112 }
2113
2114 static SHELL_VAR **
2115 _visible_names (table)
2116      HASH_TABLE *table;
2117 {
2118   SHELL_VAR **list;
2119
2120   list = map_over (visible_var, table);
2121
2122   if (list /* && posixly_correct */)
2123     sort_variables (list);
2124
2125   return (list);
2126 }
2127
2128 SHELL_VAR **
2129 all_visible_variables ()
2130 {
2131   return (_visible_names (shell_variables));
2132 }
2133
2134 SHELL_VAR **
2135 all_visible_functions ()
2136 {
2137   return (_visible_names (shell_functions));
2138 }
2139
2140 #endif /* READLINE */
2141
2142 /* Return non-zero if the variable VAR is visible and exported.  Array
2143    variables cannot be exported. */
2144 static int
2145 visible_and_exported (var)
2146      SHELL_VAR *var;
2147 {
2148   return (invisible_p (var) == 0 && exported_p (var));
2149 }
2150
2151 /* Make an array of assignment statements from the hash table
2152    HASHED_VARS which contains SHELL_VARs.  Only visible, exported
2153    variables are eligible. */
2154 char **
2155 make_var_array (hashed_vars)
2156      HASH_TABLE *hashed_vars;
2157 {
2158   register int i, list_index;
2159   register SHELL_VAR *var;
2160   char **list, *value;
2161   SHELL_VAR **vars;
2162
2163   vars = map_over (visible_and_exported, hashed_vars);
2164
2165   if (vars == 0)
2166     return (char **)NULL;
2167
2168   list = (char **)xmalloc ((1 + array_len ((char **)vars)) * sizeof (char *));
2169
2170   for (i = 0, list_index = 0; var = vars[i]; i++)
2171     {
2172       if (function_p (var))
2173         value = named_function_string ((char *)NULL, function_cell (var), 0);
2174 #if defined (ARRAY_VARS)
2175       else if (array_p (var))
2176 #  if 0
2177         value = array_to_assignment_string (array_cell (var));
2178 #  else
2179         continue;       /* XXX array vars cannot yet be exported */
2180 #  endif
2181 #endif
2182       else
2183         value = value_cell (var);
2184
2185       if (value)
2186         {
2187           int name_len, value_len;
2188           char  *p;
2189
2190           name_len = strlen (var->name);
2191           value_len = strlen (value);
2192           p = list[list_index] = xmalloc (2 + name_len + value_len);
2193           strcpy (p, var->name);
2194           p[name_len] = '=';
2195           strcpy (p + name_len + 1, value);
2196           list_index++;
2197 #if defined (ARRAY_VARS)
2198           if (array_p (var))
2199             free (value);
2200 #endif
2201         }
2202     }
2203
2204   free (vars);
2205   list[list_index] = (char *)NULL;
2206   return (list);
2207 }
2208
2209 /* Add STRING to the array of foo=bar strings that we already
2210    have to add to the environment.  */
2211 int
2212 assign_in_env (string)
2213      char *string;
2214 {
2215   int size, offset;
2216   char *name, *temp, *value;
2217   int nlen, vlen;
2218   WORD_LIST *list;
2219   SHELL_VAR *var;
2220
2221   offset = assignment (string);
2222   name = savestring (string);
2223   value = (char *)NULL;
2224
2225   if (name[offset] == '=')
2226     {
2227       name[offset] = 0;
2228
2229       var = find_variable (name);
2230       if (var && readonly_p (var))
2231         {
2232           report_error ("%s: readonly variable", name);
2233           free (name);
2234           return (0);
2235         }
2236       temp = name + offset + 1;
2237       temp = (strchr (temp, '~') != 0) ? bash_tilde_expand (temp) : savestring (temp);
2238
2239       list = expand_string_unsplit (temp, 0);
2240       value = string_list (list);
2241
2242       if (list)
2243         dispose_words (list);
2244
2245       free (temp);
2246     }
2247
2248   nlen = strlen (name);
2249   vlen = value ? strlen (value) : 0;
2250   temp = xmalloc (2 + nlen + vlen);
2251   strcpy (temp, name);
2252   temp[nlen] = '=';
2253   temp[nlen + 1] = '\0';
2254   if (value)
2255     {
2256       if (*value)
2257         strcpy (temp + nlen + 1, value);
2258       free (value);
2259     }
2260   free (name);
2261
2262   if (temporary_env == 0)
2263     {
2264       temporary_env = (char **)xmalloc (sizeof (char *));
2265       temporary_env [0] = (char *)NULL;
2266     }
2267
2268   size = array_len (temporary_env);
2269   temporary_env = (char **)
2270     xrealloc (temporary_env, (size + 2) * (sizeof (char *)));
2271
2272   temporary_env[size] = temp;
2273   temporary_env[size + 1] = (char *)NULL;
2274   array_needs_making = 1;
2275
2276   if (echo_command_at_execute)
2277     {
2278       /* The Korn shell prints the `+ ' in front of assignment statements,
2279          so we do too. */
2280       fprintf (stderr, "%s%s\n", indirection_level_string (), temp);
2281       fflush (stderr);
2282     }
2283
2284   return 1;
2285 }
2286
2287 /* Search for NAME in ARRAY, an array of strings in the same format as the
2288    environment array (i.e, name=value).  If NAME is present, make a new
2289    variable and return it.  Otherwise, return NULL. */
2290 static SHELL_VAR *
2291 find_name_in_env_array (name, array)
2292      char *name;
2293      char **array;
2294 {
2295   register int i, l;
2296
2297   if (array == 0)
2298     return ((SHELL_VAR *)NULL);
2299
2300   for (i = 0, l = strlen (name); array[i]; i++)
2301     {
2302       if (STREQN (array[i], name, l) && array[i][l] == '=')
2303         {
2304           SHELL_VAR *temp;
2305           char *w;
2306
2307           /* This is a potential memory leak.  The code should really save
2308              the created variables in some auxiliary data structure, which
2309              can be disposed of at the appropriate time. */
2310           temp = new_shell_variable (name);
2311           w = array[i] + l + 1;
2312
2313           temp->value = *w ? savestring (w) : (char *)NULL;
2314
2315           temp->attributes = att_exported|att_tempvar;
2316           temp->context = 0;
2317           temp->prev_context = (SHELL_VAR *)NULL;
2318
2319           temp->dynamic_value = temp->assign_func = (DYNAMIC_FUNC *)NULL;
2320
2321           return (temp);
2322         }
2323     }
2324   return ((SHELL_VAR *)NULL);
2325 }
2326
2327 /* Find a variable in the temporary environment that is named NAME.
2328    The temporary environment can be either the environment provided
2329    to a simple command, or the environment provided to a shell function.
2330    We only search the function environment if we are currently executing
2331    a shell function body (variable_context > 0).  Return a consed variable,
2332    or NULL if not found. */
2333 SHELL_VAR *
2334 find_tempenv_variable (name)
2335      char *name;
2336 {
2337   SHELL_VAR *var;
2338
2339   var = (SHELL_VAR *)NULL;
2340
2341   if (temporary_env)
2342     var = find_name_in_env_array (name, temporary_env);
2343
2344   /* We don't check this_shell_builtin because the command that needs the
2345      value from builtin_env may be a disk command run inside a script run
2346      with `.' and a temporary env. */
2347   if (!var && builtin_env)
2348     var = find_name_in_env_array (name, builtin_env);
2349
2350   if (!var && variable_context && function_env)
2351     var = find_name_in_env_array (name, function_env);
2352
2353   return (var);
2354 }
2355
2356 /* Free the storage allocated to the string array pointed to by ARRAYP, and
2357    make that variable have a null pointer as a value. */
2358 static void
2359 dispose_temporary_vars (arrayp)
2360      char ***arrayp;
2361 {
2362   if (!*arrayp)
2363     return;
2364
2365   free_array (*arrayp);
2366   *arrayp = (char **)NULL;
2367   array_needs_making = 1;
2368 }
2369
2370 /* Free the storage used in the variable array for temporary
2371    environment variables. */
2372 void
2373 dispose_used_env_vars ()
2374 {
2375   dispose_temporary_vars (&temporary_env);
2376 }
2377
2378 /* Free the storage used for temporary environment variables given to
2379    commands when executing inside of a function body. */
2380 void
2381 dispose_function_env ()
2382 {
2383   dispose_temporary_vars (&function_env);
2384 }
2385
2386 /* Free the storage used for temporary environment variables given to
2387    commands when executing a builtin command such as "source". */
2388 void
2389 dispose_builtin_env ()
2390 {
2391   dispose_temporary_vars (&builtin_env);
2392 }
2393
2394 /* Take all of the shell variables in ENV_ARRAY and make shell variables
2395    from them at the current variable context. */
2396 static void
2397 merge_env_array (env_array)
2398      char **env_array;
2399 {
2400   register int i, l;
2401   SHELL_VAR *temp;
2402   char *val, *name;
2403
2404   if (env_array == 0)
2405     return;
2406
2407   for (i = 0; env_array[i]; i++)
2408     {
2409       l = assignment (env_array[i]);
2410       name = env_array[i];
2411       val = env_array[i] + l + 1;
2412       name[l] = '\0';
2413       temp = bind_variable (name, val);
2414       name[l] = '=';
2415     }
2416 }
2417
2418 void
2419 merge_temporary_env ()
2420 {
2421   merge_env_array (temporary_env);
2422 }
2423
2424 void
2425 merge_builtin_env ()
2426 {
2427   merge_env_array (builtin_env);
2428 }
2429
2430 /* Add ENVSTR to the end of the exported environment, EXPORT_ENV. */
2431 #define add_to_export_env(envstr,do_alloc) \
2432 do \
2433   { \
2434     if (export_env_index >= (export_env_size - 1)) \
2435       { \
2436         export_env_size += 16; \
2437         export_env = (char **)xrealloc (export_env, export_env_size * sizeof (char *)); \
2438       } \
2439     export_env[export_env_index++] = (do_alloc) ? savestring (envstr) : envstr; \
2440     export_env[export_env_index] = (char *)NULL; \
2441   } while (0)
2442
2443 #define ISFUNCTION(s, o) ((s[o + 1] == '(')  && (s[o + 2] == ')'))
2444
2445 /* Add ASSIGN to EXPORT_ENV, or supercede a previous assignment in the
2446    array with the same left-hand side.  Return the new EXPORT_ENV. */
2447 char **
2448 add_or_supercede_exported_var (assign, do_alloc)
2449      char *assign;
2450      int do_alloc;
2451 {
2452   register int i;
2453   int equal_offset;
2454
2455   equal_offset = assignment (assign);
2456   if (equal_offset == 0)
2457     return (export_env);
2458
2459   /* If this is a function, then only supercede the function definition.
2460      We do this by including the `=(' in the comparison.  */
2461   if (assign[equal_offset + 1] == '(')
2462     equal_offset++;
2463
2464   for (i = 0; i < export_env_index; i++)
2465     {
2466       if (STREQN (assign, export_env[i], equal_offset + 1))
2467         {
2468           free (export_env[i]);
2469           export_env[i] = do_alloc ? savestring (assign) : assign;
2470           return (export_env);
2471         }
2472     }
2473   add_to_export_env (assign, do_alloc);
2474   return (export_env);
2475 }
2476
2477 /* Make the environment array for the command about to be executed, if the
2478    array needs making.  Otherwise, do nothing.  If a shell action could
2479    change the array that commands receive for their environment, then the
2480    code should `array_needs_making++'. */
2481 void
2482 maybe_make_export_env ()
2483 {
2484   register int i;
2485   register char **temp_array;
2486   int new_size;
2487
2488   if (array_needs_making)
2489     {
2490       if (export_env)
2491         free_array_members (export_env);
2492
2493       /* Make a guess based on how many shell variables and functions we
2494          have.  Since there will always be array variables, and array
2495          variables are not (yet) exported, this will always be big enough
2496          for the exported variables and functions, without any temporary
2497          or function environments. */
2498       new_size = shell_variables->nentries + shell_functions->nentries + 1;
2499       if (new_size > export_env_size)
2500         {
2501           export_env_size = new_size;
2502           export_env = (char **)xrealloc (export_env, export_env_size * sizeof (char *));
2503         }
2504       export_env[export_env_index = 0] = (char *)NULL;
2505
2506       temp_array = make_var_array (shell_variables);
2507       if (temp_array)
2508         {
2509           for (i = 0; temp_array[i]; i++)
2510             add_to_export_env (temp_array[i], 0);
2511           free (temp_array);
2512         }
2513
2514       temp_array = make_var_array (shell_functions);
2515       if (temp_array)
2516         {
2517           for (i = 0; temp_array[i]; i++)
2518             add_to_export_env (temp_array[i], 0);
2519           free (temp_array);
2520         }
2521
2522       if (function_env)
2523         for (i = 0; function_env[i]; i++)
2524           export_env = add_or_supercede_exported_var (function_env[i], 1);
2525
2526       if (temporary_env)
2527         for (i = 0; temporary_env[i]; i++)
2528           export_env = add_or_supercede_exported_var (temporary_env[i], 1);
2529
2530 #if 0
2531       /* If we changed the array, then sort it alphabetically. */
2532       if (posixly_correct == 0 && (temporary_env || function_env))
2533         sort_char_array (export_env);
2534 #endif
2535
2536       array_needs_making = 0;
2537     }
2538 }
2539
2540 /* This is an efficiency hack.  PWD and OLDPWD are auto-exported, so
2541    we will need to remake the exported environment every time we
2542    change directories.  `_' is always put into the environment for
2543    every external command, so without special treatment it will always
2544    cause the environment to be remade.
2545
2546    If there is no other reason to make the exported environment, we can
2547    just update the variables in place and mark the exported environment
2548    as no longer needing a remake. */
2549 void
2550 update_export_env_inplace (env_prefix, preflen, value)
2551      char *env_prefix;
2552      int preflen;
2553      char *value;
2554 {
2555   char *evar;
2556
2557   evar = xmalloc (STRLEN (value) + preflen + 1);
2558   strcpy (evar, env_prefix);
2559   if (value)
2560     strcpy (evar + preflen, value);
2561   export_env = add_or_supercede_exported_var (evar, 0);
2562 }
2563
2564 /* We always put _ in the environment as the name of this command. */
2565 void
2566 put_command_name_into_env (command_name)
2567      char *command_name;
2568 {
2569   update_export_env_inplace ("_=", 2, command_name);
2570 }
2571
2572 #if 0   /* UNUSED -- it caused too many problems */
2573 void
2574 put_gnu_argv_flags_into_env (pid, flags_string)
2575      int pid;
2576      char *flags_string;
2577 {
2578   char *dummy, *pbuf;
2579   int l, fl;
2580
2581   pbuf = itos (pid);
2582   l = strlen (pbuf);
2583
2584   fl = strlen (flags_string);
2585
2586   dummy = xmalloc (l + fl + 30);
2587   dummy[0] = '_';
2588   strcpy (dummy + 1, pbuf);
2589   strcpy (dummy + 1 + l, "_GNU_nonoption_argv_flags_");
2590   dummy[l + 27] = '=';
2591   strcpy (dummy + l + 28, flags_string);
2592
2593   free (pbuf);
2594
2595   export_env = add_or_supercede_exported_var (dummy, 0);
2596 }
2597 #endif
2598
2599 /* Return a string denoting what our indirection level is. */
2600 static char indirection_string[100];
2601
2602 char *
2603 indirection_level_string ()
2604 {
2605   register int i, j;
2606   char *ps4;
2607
2608   indirection_string[0] = '\0';
2609   ps4 = get_string_value ("PS4");
2610
2611   if (ps4 == 0 || *ps4 == '\0')
2612     return (indirection_string);
2613
2614   ps4 = decode_prompt_string (ps4);
2615
2616   for (i = 0; *ps4 && i < indirection_level && i < 99; i++)
2617     indirection_string[i] = *ps4;
2618
2619   for (j = 1; *ps4 && ps4[j] && i < 99; i++, j++)
2620     indirection_string[i] = ps4[j];
2621
2622   indirection_string[i] = '\0';
2623   free (ps4);
2624   return (indirection_string);
2625 }
2626
2627 /*************************************************
2628  *                                               *
2629  *      Functions to manage special variables    *
2630  *                                               *
2631  *************************************************/
2632
2633 /* Extern declarations for variables this code has to manage. */
2634 extern int eof_encountered, eof_encountered_limit, ignoreeof;
2635
2636 #if defined (READLINE)
2637 extern int no_line_editing;
2638 extern int hostname_list_initialized;
2639 #endif
2640
2641 /* An alist of name.function for each special variable.  Most of the
2642    functions don't do much, and in fact, this would be faster with a
2643    switch statement, but by the end of this file, I am sick of switch
2644    statements. */
2645
2646 #define SET_INT_VAR(name, intvar)  intvar = find_variable (name) != 0
2647
2648 struct name_and_function {
2649   char *name;
2650   VFunction *function;
2651 } special_vars[] = {
2652   { "PATH", sv_path },
2653   { "MAIL", sv_mail },
2654   { "MAILPATH", sv_mail },
2655   { "MAILCHECK", sv_mail },
2656
2657   { "POSIXLY_CORRECT", sv_strict_posix },
2658   { "GLOBIGNORE", sv_globignore },
2659
2660   /* Variables which only do something special when READLINE is defined. */
2661 #if defined (READLINE)
2662   { "TERM", sv_terminal },
2663   { "TERMCAP", sv_terminal },
2664   { "TERMINFO", sv_terminal },
2665   { "HOSTFILE", sv_hostfile },
2666 #endif /* READLINE */
2667
2668   /* Variables which only do something special when HISTORY is defined. */
2669 #if defined (HISTORY)
2670   { "HISTIGNORE", sv_histignore },
2671   { "HISTSIZE", sv_histsize },
2672   { "HISTFILESIZE", sv_histsize },
2673   { "HISTCONTROL", sv_history_control },
2674 #  if defined (BANG_HISTORY)
2675   { "histchars", sv_histchars },
2676 #  endif /* BANG_HISTORY */
2677 #endif /* HISTORY */
2678
2679   { "IGNOREEOF", sv_ignoreeof },
2680   { "ignoreeof", sv_ignoreeof },
2681
2682   { "OPTIND", sv_optind },
2683   { "OPTERR", sv_opterr },
2684
2685   { "TEXTDOMAIN", sv_locale },
2686   { "TEXTDOMAINDIR", sv_locale },
2687   { "LC_ALL", sv_locale },
2688   { "LC_COLLATE", sv_locale },
2689   { "LC_CTYPE", sv_locale },
2690   { "LC_MESSAGES", sv_locale },
2691   { "LANG", sv_locale },
2692
2693 #if defined (HAVE_TZSET) && defined (PROMPT_STRING_DECODE)
2694   { "TZ", sv_tz },
2695 #endif
2696
2697   { (char *)0, (VFunction *)0 }
2698 };
2699
2700 /* The variable in NAME has just had its state changed.  Check to see if it
2701    is one of the special ones where something special happens. */
2702 void
2703 stupidly_hack_special_variables (name)
2704      char *name;
2705 {
2706   int i;
2707
2708   for (i = 0; special_vars[i].name; i++)
2709     {
2710       if (STREQ (special_vars[i].name, name))
2711         {
2712           (*(special_vars[i].function)) (name);
2713           return;
2714         }
2715     }
2716 }
2717
2718 /* What to do just after the PATH variable has changed. */
2719 void
2720 sv_path (name)
2721      char *name;
2722 {
2723   /* hash -r */
2724   flush_hashed_filenames ();
2725 }
2726
2727 /* What to do just after one of the MAILxxxx variables has changed.  NAME
2728    is the name of the variable.  This is called with NAME set to one of
2729    MAIL, MAILCHECK, or MAILPATH.  */
2730 void
2731 sv_mail (name)
2732      char *name;
2733 {
2734   /* If the time interval for checking the files has changed, then
2735      reset the mail timer.  Otherwise, one of the pathname vars
2736      to the users mailbox has changed, so rebuild the array of
2737      filenames. */
2738   if (name[4] == 'C')  /* if (strcmp (name, "MAILCHECK") == 0) */
2739     reset_mail_timer ();
2740   else
2741     {
2742       free_mail_files ();
2743       remember_mail_dates ();
2744     }
2745 }
2746
2747 /* What to do when GLOBIGNORE changes. */
2748 void
2749 sv_globignore (name)
2750      char *name;
2751 {
2752   setup_glob_ignore (name);
2753 }
2754
2755 #if defined (READLINE)
2756 /* What to do just after one of the TERMxxx variables has changed.
2757    If we are an interactive shell, then try to reset the terminal
2758    information in readline. */
2759 void
2760 sv_terminal (name)
2761      char *name;
2762 {
2763   if (interactive_shell && no_line_editing == 0)
2764     rl_reset_terminal (get_string_value ("TERM"));
2765 }
2766
2767 void
2768 sv_hostfile (name)
2769      char *name;
2770 {
2771   hostname_list_initialized = 0;
2772 }
2773 #endif /* READLINE */
2774
2775 #if defined (HISTORY)
2776 /* What to do after the HISTSIZE or HISTFILESIZE variables change.
2777    If there is a value for this HISTSIZE (and it is numeric), then stifle
2778    the history.  Otherwise, if there is NO value for this variable,
2779    unstifle the history.  If name is HISTFILESIZE, and its value is
2780    numeric, truncate the history file to hold no more than that many
2781    lines. */
2782 void
2783 sv_histsize (name)
2784      char *name;
2785 {
2786   char *temp;
2787   long num;
2788
2789   temp = get_string_value (name);
2790
2791   if (temp && *temp)
2792     {
2793       if (legal_number (temp, &num))
2794         {
2795           if (name[4] == 'S')
2796             {
2797               stifle_history (num);
2798               num = where_history ();
2799               if (history_lines_this_session > num)
2800                 history_lines_this_session = num;
2801             }
2802           else
2803             {
2804               history_truncate_file (get_string_value ("HISTFILE"), (int)num);
2805               if (num <= history_lines_in_file)
2806                 history_lines_in_file = num;
2807             }
2808         }
2809     }
2810   else if (name[4] == 'S')
2811     unstifle_history ();
2812 }
2813
2814 /* What to do after the HISTIGNORE variable changes. */
2815 void
2816 sv_histignore (name)
2817      char *name;
2818 {
2819   setup_history_ignore (name);
2820 }
2821
2822 /* What to do after the HISTCONTROL variable changes. */
2823 void
2824 sv_history_control (name)
2825      char *name;
2826 {
2827   char *temp;
2828
2829   history_control = 0;
2830   temp = get_string_value (name);
2831
2832   if (temp && *temp && STREQN (temp, "ignore", 6))
2833     {
2834       if (temp[6] == 's')       /* ignorespace */
2835         history_control = 1;
2836       else if (temp[6] == 'd')  /* ignoredups */
2837         history_control = 2;
2838       else if (temp[6] == 'b')  /* ignoreboth */
2839         history_control = 3;
2840     }
2841 }
2842
2843 #if defined (BANG_HISTORY)
2844 /* Setting/unsetting of the history expansion character. */
2845 void
2846 sv_histchars (name)
2847      char *name;
2848 {
2849   char *temp;
2850
2851   temp = get_string_value (name);
2852   if (temp)
2853     {
2854       history_expansion_char = *temp;
2855       if (temp[0] && temp[1])
2856         {
2857           history_subst_char = temp[1];
2858           if (temp[2])
2859               history_comment_char = temp[2];
2860         }
2861     }
2862   else
2863     {
2864       history_expansion_char = '!';
2865       history_subst_char = '^';
2866       history_comment_char = '#';
2867     }
2868 }
2869 #endif /* BANG_HISTORY */
2870 #endif /* HISTORY */
2871
2872 #if defined (HAVE_TZSET) && defined (PROMPT_STRING_DECODE)
2873 void
2874 sv_tz (name)
2875      char *name;
2876 {
2877   tzset ();
2878 }
2879 #endif
2880
2881 /* If the variable exists, then the value of it can be the number
2882    of times we actually ignore the EOF.  The default is small,
2883    (smaller than csh, anyway). */
2884 void
2885 sv_ignoreeof (name)
2886      char *name;
2887 {
2888   SHELL_VAR *tmp_var;
2889   char *temp;
2890
2891   eof_encountered = 0;
2892
2893   tmp_var = find_variable (name);
2894   ignoreeof = tmp_var != 0;
2895   temp = tmp_var ? value_cell (tmp_var) : (char *)NULL;
2896   if (temp)
2897     eof_encountered_limit = (*temp && all_digits (temp)) ? atoi (temp) : 10;
2898   set_shellopts ();     /* make sure `ignoreeof' is/is not in $SHELLOPTS */
2899 }
2900
2901 void
2902 sv_optind (name)
2903      char *name;
2904 {
2905   char *tt;
2906   int s;
2907
2908   tt = get_string_value ("OPTIND");
2909   if (tt && *tt)
2910     {
2911       s = atoi (tt);
2912
2913       /* According to POSIX, setting OPTIND=1 resets the internal state
2914          of getopt (). */
2915       if (s < 0 || s == 1)
2916         s = 0;
2917     }
2918   else
2919     s = 0;
2920   getopts_reset (s);
2921 }
2922
2923 void
2924 sv_opterr (name)
2925      char *name;
2926 {
2927   char *tt;
2928
2929   tt = get_string_value ("OPTERR");
2930   sh_opterr = (tt && *tt) ? atoi (tt) : 1;
2931 }
2932
2933 void
2934 sv_strict_posix (name)
2935      char *name;
2936 {
2937   SET_INT_VAR (name, posixly_correct);
2938   posix_initialize (posixly_correct);
2939 #if defined (READLINE)
2940   if (interactive_shell)
2941     posix_readline_initialize (posixly_correct);
2942 #endif /* READLINE */
2943   set_shellopts ();     /* make sure `posix' is/is not in $SHELLOPTS */
2944 }
2945
2946 void
2947 sv_locale (name)
2948      char *name;
2949 {
2950   char *v;
2951
2952   v = get_string_value (name);
2953   if (name[0] == 'L' && name[1] == 'A') /* LANG */
2954     set_lang (name, v);
2955   else
2956     set_locale_var (name, v);           /* LC_*, TEXTDOMAIN* */
2957 }
2958
2959 #if defined (ARRAY_VARS)
2960 void
2961 set_pipestatus_array (ps)
2962      int *ps;
2963 {
2964   SHELL_VAR *v;
2965   ARRAY *a;
2966   register int i;
2967   char *t, tbuf[16];
2968
2969   v = find_variable ("PIPESTATUS");
2970   if (v == 0)
2971     v = make_new_array_variable ("PIPESTATUS");
2972   if (array_p (v) == 0)
2973     return;             /* Do nothing if not an array variable. */
2974   a = array_cell (v);
2975   if (a)
2976     empty_array (a);
2977   for (i = 0; ps[i] != -1; i++)
2978     {
2979       t = inttostr (ps[i], tbuf, sizeof (tbuf));
2980       array_add_element (a, i, t);
2981     }
2982 }
2983 #endif
2984
2985 void
2986 set_pipestatus_from_exit (s)
2987      int s;
2988 {
2989 #if defined (ARRAY_VARS)
2990   static int v[2] = { 0, -1 };
2991
2992   v[0] = s;
2993   set_pipestatus_array (v);
2994 #endif
2995 }