1 /* variables.h -- data structures for shell variables. */
3 /* Copyright (C) 1987-2020 Free Software Foundation, Inc.
5 This file is part of GNU Bush, the Bourne Again SHell.
7 Bush is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
12 Bush is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with Bush. If not, see <http://www.gnu.org/licenses/>.
21 #if !defined (_VARIABLES_H_)
28 /* Shell variables and functions are stored in hash tables. */
31 #include "conftypes.h"
33 /* A variable context. */
34 typedef struct var_context
{
35 char *name
; /* empty or NULL means global context */
36 int scope
; /* 0 means global context */
38 struct var_context
*up
; /* previous function calls */
39 struct var_context
*down
; /* down towards global context */
40 HASH_TABLE
*table
; /* variables at this scope */
43 /* Flags for var_context->flags */
44 #define VC_HASLOCAL 0x01
45 #define VC_HASTMPVAR 0x02
46 #define VC_FUNCENV 0x04 /* also function if name != NULL */
47 #define VC_BLTNENV 0x08 /* builtin_env */
48 #define VC_TEMPENV 0x10 /* temporary_env */
50 #define VC_TEMPFLAGS (VC_FUNCENV|VC_BLTNENV|VC_TEMPENV)
52 /* Accessing macros */
53 #define vc_isfuncenv(vc) (((vc)->flags & VC_FUNCENV) != 0)
54 #define vc_isbltnenv(vc) (((vc)->flags & VC_BLTNENV) != 0)
55 #define vc_istempenv(vc) (((vc)->flags & (VC_TEMPFLAGS)) == VC_TEMPENV)
57 #define vc_istempscope(vc) (((vc)->flags & (VC_TEMPENV|VC_BLTNENV)) != 0)
59 #define vc_haslocals(vc) (((vc)->flags & VC_HASLOCAL) != 0)
60 #define vc_hastmpvars(vc) (((vc)->flags & VC_HASTMPVAR) != 0)
62 /* What a shell variable looks like. */
64 typedef struct variable
*sh_var_value_func_t
PARAMS((struct variable
*));
65 typedef struct variable
*sh_var_assign_func_t
PARAMS((struct variable
*, char *, arrayind_t
, char *));
69 char *s
; /* string value */
70 intmax_t i
; /* int value */
71 COMMAND
*f
; /* function */
73 HASH_TABLE
*h
; /* associative array */
74 double d
; /* floating point number */
75 #if defined (HAVE_LONG_DOUBLE)
76 long double ld
; /* long double */
78 struct variable
*v
; /* possible indirect variable use */
79 void *opaque
; /* opaque data for future use */
82 typedef struct variable
{
83 char *name
; /* Symbol that the user types. */
84 char *value
; /* Value that is returned. */
85 char *exportstr
; /* String for the environment. */
86 sh_var_value_func_t
*dynamic_value
; /* Function called to return a `dynamic'
87 value for a variable, like $SECONDS
89 sh_var_assign_func_t
*assign_func
; /* Function called when this `special
90 variable' is assigned a value in
92 int attributes
; /* export, readonly, array, invisible... */
93 int context
; /* Which context this variable belongs to. */
96 typedef struct _vlist
{
98 int list_size
; /* allocated size */
99 int list_len
; /* current number of entries */
102 /* The various attributes that a given variable can have. */
103 /* First, the user-visible attributes */
104 #define att_exported 0x0000001 /* export to environment */
105 #define att_readonly 0x0000002 /* cannot change */
106 #define att_array 0x0000004 /* value is an array */
107 #define att_function 0x0000008 /* value is a function */
108 #define att_integer 0x0000010 /* internal representation is int */
109 #define att_local 0x0000020 /* variable is local to a function */
110 #define att_assoc 0x0000040 /* variable is an associative array */
111 #define att_trace 0x0000080 /* function is traced with DEBUG trap */
112 #define att_uppercase 0x0000100 /* word converted to uppercase on assignment */
113 #define att_lowercase 0x0000200 /* word converted to lowercase on assignment */
114 #define att_capcase 0x0000400 /* word capitalized on assignment */
115 #define att_nameref 0x0000800 /* word is a name reference */
117 #define user_attrs (att_exported|att_readonly|att_integer|att_local|att_trace|att_uppercase|att_lowercase|att_capcase|att_nameref)
119 #define attmask_user 0x0000fff
121 /* Internal attributes used for bookkeeping */
122 #define att_invisible 0x0001000 /* cannot see */
123 #define att_nounset 0x0002000 /* cannot unset */
124 #define att_noassign 0x0004000 /* assignment not allowed */
125 #define att_imported 0x0008000 /* came from environment */
126 #define att_special 0x0010000 /* requires special handling */
127 #define att_nofree 0x0020000 /* do not free value on unset */
128 #define att_regenerate 0x0040000 /* regenerate when exported */
130 #define attmask_int 0x00ff000
132 /* Internal attributes used for variable scoping. */
133 #define att_tempvar 0x0100000 /* variable came from the temp environment */
134 #define att_propagate 0x0200000 /* propagate to previous scope */
136 #define attmask_scope 0x0f00000
138 #define exported_p(var) ((((var)->attributes) & (att_exported)))
139 #define readonly_p(var) ((((var)->attributes) & (att_readonly)))
140 #define array_p(var) ((((var)->attributes) & (att_array)))
141 #define function_p(var) ((((var)->attributes) & (att_function)))
142 #define integer_p(var) ((((var)->attributes) & (att_integer)))
143 #define local_p(var) ((((var)->attributes) & (att_local)))
144 #define assoc_p(var) ((((var)->attributes) & (att_assoc)))
145 #define trace_p(var) ((((var)->attributes) & (att_trace)))
146 #define uppercase_p(var) ((((var)->attributes) & (att_uppercase)))
147 #define lowercase_p(var) ((((var)->attributes) & (att_lowercase)))
148 #define capcase_p(var) ((((var)->attributes) & (att_capcase)))
149 #define nameref_p(var) ((((var)->attributes) & (att_nameref)))
151 #define invisible_p(var) ((((var)->attributes) & (att_invisible)))
152 #define non_unsettable_p(var) ((((var)->attributes) & (att_nounset)))
153 #define noassign_p(var) ((((var)->attributes) & (att_noassign)))
154 #define imported_p(var) ((((var)->attributes) & (att_imported)))
155 #define specialvar_p(var) ((((var)->attributes) & (att_special)))
156 #define nofree_p(var) ((((var)->attributes) & (att_nofree)))
157 #define regen_p(var) ((((var)->attributes) & (att_regenerate)))
159 #define tempvar_p(var) ((((var)->attributes) & (att_tempvar)))
160 #define propagate_p(var) ((((var)->attributes) & (att_propagate)))
162 /* Variable names: lvalues */
163 #define name_cell(var) ((var)->name)
165 /* Accessing variable values: rvalues */
166 #define value_cell(var) ((var)->value)
167 #define function_cell(var) (COMMAND *)((var)->value)
168 #define array_cell(var) (ARRAY *)((var)->value)
169 #define assoc_cell(var) (HASH_TABLE *)((var)->value)
170 #define nameref_cell(var) ((var)->value) /* so it can change later */
172 #define NAMEREF_MAX 8 /* only 8 levels of nameref indirection */
174 #define var_isset(var) ((var)->value != 0)
175 #define var_isunset(var) ((var)->value == 0)
176 #define var_isnull(var) ((var)->value && *(var)->value == 0)
178 /* Assigning variable values: lvalues */
179 #define var_setvalue(var, str) ((var)->value = (str))
180 #define var_setfunc(var, func) ((var)->value = (char *)(func))
181 #define var_setarray(var, arr) ((var)->value = (char *)(arr))
182 #define var_setassoc(var, arr) ((var)->value = (char *)(arr))
183 #define var_setref(var, str) ((var)->value = (str))
185 /* Make VAR be auto-exported. */
186 #define set_auto_export(var) \
187 do { (var)->attributes |= att_exported; array_needs_making = 1; } while (0)
189 #define SETVARATTR(var, attr, undo) \
190 ((undo == 0) ? ((var)->attributes |= (attr)) \
191 : ((var)->attributes &= ~(attr)))
193 #define VSETATTR(var, attr) ((var)->attributes |= (attr))
194 #define VUNSETATTR(var, attr) ((var)->attributes &= ~(attr))
196 #define VGETFLAGS(var) ((var)->attributes)
198 #define VSETFLAGS(var, flags) ((var)->attributes = (flags))
199 #define VCLRFLAGS(var) ((var)->attributes = 0)
201 /* Macros to perform various operations on `exportstr' member of a SHELL_VAR. */
202 #define CLEAR_EXPORTSTR(var) (var)->exportstr = (char *)NULL
203 #define COPY_EXPORTSTR(var) ((var)->exportstr) ? savestring ((var)->exportstr) : (char *)NULL
204 #define SET_EXPORTSTR(var, value) (var)->exportstr = (value)
205 #define SAVE_EXPORTSTR(var, value) (var)->exportstr = (value) ? savestring (value) : (char *)NULL
207 #define FREE_EXPORTSTR(var) \
208 do { if ((var)->exportstr) free ((var)->exportstr); } while (0)
210 #define CACHE_IMPORTSTR(var, value) \
211 (var)->exportstr = savestring (value)
213 #define INVALIDATE_EXPORTSTR(var) \
215 if ((var)->exportstr) \
217 free ((var)->exportstr); \
218 (var)->exportstr = (char *)NULL; \
222 #define ifsname(s) ((s)[0] == 'I' && (s)[1] == 'F' && (s)[2] == 'S' && (s)[3] == '\0')
224 /* Flag values for make_local_variable and its array counterparts */
225 #define MKLOC_ASSOCOK 0x01
226 #define MKLOC_ARRAYOK 0x02
227 #define MKLOC_INHERIT 0x04
229 /* Special value for nameref with invalid value for creation or assignment */
230 extern SHELL_VAR nameref_invalid_value
;
231 #define INVALID_NAMEREF_VALUE (void *)&nameref_invalid_value
233 /* Stuff for hacking variables. */
234 typedef int sh_var_map_func_t
PARAMS((SHELL_VAR
*));
236 /* Where we keep the variables and functions */
237 extern VAR_CONTEXT
*global_variables
;
238 extern VAR_CONTEXT
*shell_variables
;
240 extern HASH_TABLE
*shell_functions
;
241 extern HASH_TABLE
*temporary_env
;
243 extern int variable_context
;
244 extern char *dollar_vars
[];
245 extern char **export_env
;
247 extern int tempenv_assign_error
;
248 extern int array_needs_making
;
249 extern int shell_level
;
252 extern WORD_LIST
*rest_of_args
;
253 extern int posparam_count
;
254 extern pid_t dollar_dollar_pid
;
256 extern int localvar_inherit
; /* declared in variables.c */
258 extern void initialize_shell_variables
PARAMS((char **, int));
260 extern int validate_inherited_value
PARAMS((SHELL_VAR
*, int));
262 extern SHELL_VAR
*set_if_not
PARAMS((char *, char *));
264 extern void sh_set_lines_and_columns
PARAMS((int, int));
265 extern void set_pwd
PARAMS((void));
266 extern void set_ppid
PARAMS((void));
267 extern void make_funcname_visible
PARAMS((int));
269 extern SHELL_VAR
*var_lookup
PARAMS((const char *, VAR_CONTEXT
*));
271 extern SHELL_VAR
*find_function
PARAMS((const char *));
272 extern FUNCTION_DEF
*find_function_def
PARAMS((const char *));
273 extern SHELL_VAR
*find_variable
PARAMS((const char *));
274 extern SHELL_VAR
*find_variable_noref
PARAMS((const char *));
275 extern SHELL_VAR
*find_variable_last_nameref
PARAMS((const char *, int));
276 extern SHELL_VAR
*find_global_variable_last_nameref
PARAMS((const char *, int));
277 extern SHELL_VAR
*find_variable_nameref
PARAMS((SHELL_VAR
*));
278 extern SHELL_VAR
*find_variable_nameref_for_create
PARAMS((const char *, int));
279 extern SHELL_VAR
*find_variable_nameref_for_assignment
PARAMS((const char *, int));
280 /*extern SHELL_VAR *find_variable_internal PARAMS((const char *, int));*/
281 extern SHELL_VAR
*find_variable_tempenv
PARAMS((const char *));
282 extern SHELL_VAR
*find_variable_notempenv
PARAMS((const char *));
283 extern SHELL_VAR
*find_global_variable
PARAMS((const char *));
284 extern SHELL_VAR
*find_global_variable_noref
PARAMS((const char *));
285 extern SHELL_VAR
*find_shell_variable
PARAMS((const char *));
286 extern SHELL_VAR
*find_tempenv_variable
PARAMS((const char *));
287 extern SHELL_VAR
*find_variable_no_invisible
PARAMS((const char *));
288 extern SHELL_VAR
*find_variable_for_assignment
PARAMS((const char *));
289 extern char *nameref_transform_name
PARAMS((char *, int));
290 extern SHELL_VAR
*copy_variable
PARAMS((SHELL_VAR
*));
291 extern SHELL_VAR
*make_local_variable
PARAMS((const char *, int));
292 extern SHELL_VAR
*bind_variable
PARAMS((const char *, char *, int));
293 extern SHELL_VAR
*bind_global_variable
PARAMS((const char *, char *, int));
294 extern SHELL_VAR
*bind_function
PARAMS((const char *, COMMAND
*));
296 extern void bind_function_def
PARAMS((const char *, FUNCTION_DEF
*, int));
298 extern SHELL_VAR
**map_over
PARAMS((sh_var_map_func_t
*, VAR_CONTEXT
*));
299 SHELL_VAR
**map_over_funcs
PARAMS((sh_var_map_func_t
*));
301 extern SHELL_VAR
**all_shell_variables
PARAMS((void));
302 extern SHELL_VAR
**all_shell_functions
PARAMS((void));
303 extern SHELL_VAR
**all_visible_variables
PARAMS((void));
304 extern SHELL_VAR
**all_visible_functions
PARAMS((void));
305 extern SHELL_VAR
**all_exported_variables
PARAMS((void));
306 extern SHELL_VAR
**local_exported_variables
PARAMS((void));
307 extern SHELL_VAR
**all_local_variables
PARAMS((int));
308 #if defined (ARRAY_VARS)
309 extern SHELL_VAR
**all_array_variables
PARAMS((void));
311 extern char **all_variables_matching_prefix
PARAMS((const char *));
313 extern char **make_var_array
PARAMS((HASH_TABLE
*));
314 extern char **add_or_supercede_exported_var
PARAMS((char *, int));
316 extern char *get_variable_value
PARAMS((SHELL_VAR
*));
317 extern char *get_string_value
PARAMS((const char *));
318 extern char *sh_get_env_value
PARAMS((const char *));
319 extern char *make_variable_value
PARAMS((SHELL_VAR
*, char *, int));
321 extern SHELL_VAR
*bind_variable_value
PARAMS((SHELL_VAR
*, char *, int));
322 extern SHELL_VAR
*bind_int_variable
PARAMS((char *, char *, int));
323 extern SHELL_VAR
*bind_var_to_int
PARAMS((char *, intmax_t));
325 extern int assign_in_env
PARAMS((WORD_DESC
*, int));
327 extern int unbind_variable
PARAMS((const char *));
328 extern int check_unbind_variable
PARAMS((const char *));
329 extern int unbind_nameref
PARAMS((const char *));
330 extern int unbind_variable_noref
PARAMS((const char *));
331 extern int unbind_func
PARAMS((const char *));
332 extern int unbind_function_def
PARAMS((const char *));
333 extern int delete_var
PARAMS((const char *, VAR_CONTEXT
*));
334 extern int makunbound
PARAMS((const char *, VAR_CONTEXT
*));
335 extern int kill_local_variable
PARAMS((const char *));
336 extern void delete_all_variables
PARAMS((HASH_TABLE
*));
337 extern void delete_all_contexts
PARAMS((VAR_CONTEXT
*));
339 extern VAR_CONTEXT
*new_var_context
PARAMS((char *, int));
340 extern void dispose_var_context
PARAMS((VAR_CONTEXT
*));
341 extern VAR_CONTEXT
*push_var_context
PARAMS((char *, int, HASH_TABLE
*));
342 extern void pop_var_context
PARAMS((void));
343 extern VAR_CONTEXT
*push_scope
PARAMS((int, HASH_TABLE
*));
344 extern void pop_scope
PARAMS((int));
346 extern void clear_dollar_vars
PARAMS((void));
348 extern void push_context
PARAMS((char *, int, HASH_TABLE
*));
349 extern void pop_context
PARAMS((void));
350 extern void push_dollar_vars
PARAMS((void));
351 extern void pop_dollar_vars
PARAMS((void));
352 extern void dispose_saved_dollar_vars
PARAMS((void));
354 extern void init_bush_argv
PARAMS((void));
355 extern void save_bush_argv
PARAMS((void));
356 extern void push_args
PARAMS((WORD_LIST
*));
357 extern void pop_args
PARAMS((void));
359 extern void adjust_shell_level
PARAMS((int));
360 extern void non_unsettable
PARAMS((char *));
361 extern void dispose_variable
PARAMS((SHELL_VAR
*));
362 extern void dispose_used_env_vars
PARAMS((void));
363 extern void dispose_function_env
PARAMS((void));
364 extern void dispose_builtin_env
PARAMS((void));
365 extern void merge_temporary_env
PARAMS((void));
366 extern void flush_temporary_env
PARAMS((void));
367 extern void merge_builtin_env
PARAMS((void));
368 extern void kill_all_local_variables
PARAMS((void));
370 extern void set_var_read_only
PARAMS((char *));
371 extern void set_func_read_only
PARAMS((const char *));
372 extern void set_var_auto_export
PARAMS((char *));
373 extern void set_func_auto_export
PARAMS((const char *));
375 extern void sort_variables
PARAMS((SHELL_VAR
**));
377 extern int chkexport
PARAMS((char *));
378 extern void maybe_make_export_env
PARAMS((void));
379 extern void update_export_env_inplace
PARAMS((char *, int, char *));
380 extern void put_command_name_into_env
PARAMS((char *));
381 extern void put_gnu_argv_flags_into_env
PARAMS((intmax_t, char *));
383 extern void print_var_list
PARAMS((SHELL_VAR
**));
384 extern void print_func_list
PARAMS((SHELL_VAR
**));
385 extern void print_assignment
PARAMS((SHELL_VAR
*));
386 extern void print_var_value
PARAMS((SHELL_VAR
*, int));
387 extern void print_var_function
PARAMS((SHELL_VAR
*));
389 #if defined (ARRAY_VARS)
390 extern SHELL_VAR
*make_new_array_variable
PARAMS((char *));
391 extern SHELL_VAR
*make_local_array_variable
PARAMS((char *, int));
393 extern SHELL_VAR
*make_new_assoc_variable
PARAMS((char *));
394 extern SHELL_VAR
*make_local_assoc_variable
PARAMS((char *, int));
396 extern void set_pipestatus_array
PARAMS((int *, int));
397 extern ARRAY
*save_pipestatus_array
PARAMS((void));
398 extern void restore_pipestatus_array
PARAMS((ARRAY
*));
401 extern void set_pipestatus_from_exit
PARAMS((int));
403 /* The variable in NAME has just had its state changed. Check to see if it
404 is one of the special ones where something special happens. */
405 extern void stupidly_hack_special_variables
PARAMS((char *));
407 /* Reinitialize some special variables that have external effects upon unset
408 when the shell reinitializes itself. */
409 extern void reinit_special_variables
PARAMS((void));
411 extern int get_random_number
PARAMS((void));
413 /* The `special variable' functions that get called when a particular
415 extern void sv_ifs
PARAMS((char *));
416 extern void sv_path
PARAMS((char *));
417 extern void sv_mail
PARAMS((char *));
418 extern void sv_funcnest
PARAMS((char *));
419 extern void sv_execignore
PARAMS((char *));
420 extern void sv_globignore
PARAMS((char *));
421 extern void sv_ignoreeof
PARAMS((char *));
422 extern void sv_strict_posix
PARAMS((char *));
423 extern void sv_optind
PARAMS((char *));
424 extern void sv_opterr
PARAMS((char *));
425 extern void sv_locale
PARAMS((char *));
426 extern void sv_xtracefd
PARAMS((char *));
427 extern void sv_shcompat
PARAMS((char *));
429 #if defined (READLINE)
430 extern void sv_comp_wordbreaks
PARAMS((char *));
431 extern void sv_terminal
PARAMS((char *));
432 extern void sv_hostfile
PARAMS((char *));
433 extern void sv_winsize
PARAMS((char *));
436 #if defined (__CYGWIN__)
437 extern void sv_home
PARAMS((char *));
440 #if defined (HISTORY)
441 extern void sv_histsize
PARAMS((char *));
442 extern void sv_histignore
PARAMS((char *));
443 extern void sv_history_control
PARAMS((char *));
444 # if defined (BANG_HISTORY)
445 extern void sv_histchars
PARAMS((char *));
447 extern void sv_histtimefmt
PARAMS((char *));
450 #if defined (HAVE_TZSET)
451 extern void sv_tz
PARAMS((char *));
454 #if defined (JOB_CONTROL)
455 extern void sv_childmax
PARAMS((char *));
458 #endif /* !_VARIABLES_H_ */