1 | /* variables.h -- data structures for shell variables. */
|
---|
2 |
|
---|
3 | /* Copyright (C) 1987-2005 Free Software Foundation, Inc.
|
---|
4 |
|
---|
5 | This file is part of GNU Bash, the Bourne Again SHell.
|
---|
6 |
|
---|
7 | Bash is free software; you can redistribute it and/or modify it
|
---|
8 | under the terms of the GNU General Public License as published by
|
---|
9 | the Free Software Foundation; either version 2, or (at your option)
|
---|
10 | any later version.
|
---|
11 |
|
---|
12 | Bash is distributed in the hope that it will be useful, but WITHOUT
|
---|
13 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
---|
14 | or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
---|
15 | License for more details.
|
---|
16 |
|
---|
17 | You should have received a copy of the GNU General Public License
|
---|
18 | along with Bash; see the file COPYING. If not, write to the Free
|
---|
19 | Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
|
---|
20 |
|
---|
21 | #if !defined (_VARIABLES_H_)
|
---|
22 | #define _VARIABLES_H_
|
---|
23 |
|
---|
24 | #include "stdc.h"
|
---|
25 | #include "array.h"
|
---|
26 |
|
---|
27 | /* Shell variables and functions are stored in hash tables. */
|
---|
28 | #include "hashlib.h"
|
---|
29 |
|
---|
30 | #include "conftypes.h"
|
---|
31 |
|
---|
32 | /* A variable context. */
|
---|
33 | typedef struct var_context {
|
---|
34 | char *name; /* empty or NULL means global context */
|
---|
35 | int scope; /* 0 means global context */
|
---|
36 | int flags;
|
---|
37 | struct var_context *up; /* previous function calls */
|
---|
38 | struct var_context *down; /* down towards global context */
|
---|
39 | HASH_TABLE *table; /* variables at this scope */
|
---|
40 | } VAR_CONTEXT;
|
---|
41 |
|
---|
42 | /* Flags for var_context->flags */
|
---|
43 | #define VC_HASLOCAL 0x01
|
---|
44 | #define VC_HASTMPVAR 0x02
|
---|
45 | #define VC_FUNCENV 0x04 /* also function if name != NULL */
|
---|
46 | #define VC_BLTNENV 0x08 /* builtin_env */
|
---|
47 | #define VC_TEMPENV 0x10 /* temporary_env */
|
---|
48 |
|
---|
49 | #define VC_TEMPFLAGS (VC_FUNCENV|VC_BLTNENV|VC_TEMPENV)
|
---|
50 |
|
---|
51 | /* Accessing macros */
|
---|
52 | #define vc_isfuncenv(vc) (((vc)->flags & VC_FUNCENV) != 0)
|
---|
53 | #define vc_isbltnenv(vc) (((vc)->flags & VC_BLTNENV) != 0)
|
---|
54 | #define vc_istempenv(vc) (((vc)->flags & (VC_TEMPFLAGS)) == VC_TEMPENV)
|
---|
55 |
|
---|
56 | #define vc_istempscope(vc) (((vc)->flags & (VC_TEMPENV|VC_BLTNENV)) != 0)
|
---|
57 |
|
---|
58 | #define vc_haslocals(vc) (((vc)->flags & VC_HASLOCAL) != 0)
|
---|
59 | #define vc_hastmpvars(vc) (((vc)->flags & VC_HASTMPVAR) != 0)
|
---|
60 |
|
---|
61 | /* What a shell variable looks like. */
|
---|
62 |
|
---|
63 | typedef struct variable *sh_var_value_func_t __P((struct variable *));
|
---|
64 | typedef struct variable *sh_var_assign_func_t __P((struct variable *, char *, arrayind_t));
|
---|
65 |
|
---|
66 | /* For the future */
|
---|
67 | union _value {
|
---|
68 | char *s; /* string value */
|
---|
69 | intmax_t i; /* int value */
|
---|
70 | COMMAND *f; /* function */
|
---|
71 | ARRAY *a; /* array */
|
---|
72 | HASH_TABLE *h; /* associative array */
|
---|
73 | double d; /* floating point number */
|
---|
74 | #if defined (HAVE_LONG_DOUBLE)
|
---|
75 | long double ld; /* long double */
|
---|
76 | #endif
|
---|
77 | struct variable *v; /* possible indirect variable use */
|
---|
78 | void *opaque; /* opaque data for future use */
|
---|
79 | };
|
---|
80 |
|
---|
81 | typedef struct variable {
|
---|
82 | char *name; /* Symbol that the user types. */
|
---|
83 | char *value; /* Value that is returned. */
|
---|
84 | char *exportstr; /* String for the environment. */
|
---|
85 | sh_var_value_func_t *dynamic_value; /* Function called to return a `dynamic'
|
---|
86 | value for a variable, like $SECONDS
|
---|
87 | or $RANDOM. */
|
---|
88 | sh_var_assign_func_t *assign_func; /* Function called when this `special
|
---|
89 | variable' is assigned a value in
|
---|
90 | bind_variable. */
|
---|
91 | int attributes; /* export, readonly, array, invisible... */
|
---|
92 | int context; /* Which context this variable belongs to. */
|
---|
93 | } SHELL_VAR;
|
---|
94 |
|
---|
95 | typedef struct _vlist {
|
---|
96 | SHELL_VAR **list;
|
---|
97 | int list_size; /* allocated size */
|
---|
98 | int list_len; /* current number of entries */
|
---|
99 | } VARLIST;
|
---|
100 |
|
---|
101 | /* The various attributes that a given variable can have. */
|
---|
102 | /* First, the user-visible attributes */
|
---|
103 | #define att_exported 0x0000001 /* export to environment */
|
---|
104 | #define att_readonly 0x0000002 /* cannot change */
|
---|
105 | #define att_array 0x0000004 /* value is an array */
|
---|
106 | #define att_function 0x0000008 /* value is a function */
|
---|
107 | #define att_integer 0x0000010 /* internal representation is int */
|
---|
108 | #define att_local 0x0000020 /* variable is local to a function */
|
---|
109 | #define att_assoc 0x0000040 /* variable is an associative array */
|
---|
110 | #define att_trace 0x0000080 /* function is traced with DEBUG trap */
|
---|
111 |
|
---|
112 | #define attmask_user 0x0000fff
|
---|
113 |
|
---|
114 | /* Internal attributes used for bookkeeping */
|
---|
115 | #define att_invisible 0x0001000 /* cannot see */
|
---|
116 | #define att_nounset 0x0002000 /* cannot unset */
|
---|
117 | #define att_noassign 0x0004000 /* assignment not allowed */
|
---|
118 | #define att_imported 0x0008000 /* came from environment */
|
---|
119 | #define att_special 0x0010000 /* requires special handling */
|
---|
120 |
|
---|
121 | #define attmask_int 0x00ff000
|
---|
122 |
|
---|
123 | /* Internal attributes used for variable scoping. */
|
---|
124 | #define att_tempvar 0x0100000 /* variable came from the temp environment */
|
---|
125 | #define att_propagate 0x0200000 /* propagate to previous scope */
|
---|
126 |
|
---|
127 | #define attmask_scope 0x0f00000
|
---|
128 |
|
---|
129 | #define exported_p(var) ((((var)->attributes) & (att_exported)))
|
---|
130 | #define readonly_p(var) ((((var)->attributes) & (att_readonly)))
|
---|
131 | #define array_p(var) ((((var)->attributes) & (att_array)))
|
---|
132 | #define function_p(var) ((((var)->attributes) & (att_function)))
|
---|
133 | #define integer_p(var) ((((var)->attributes) & (att_integer)))
|
---|
134 | #define local_p(var) ((((var)->attributes) & (att_local)))
|
---|
135 | #define assoc_p(var) ((((var)->attributes) & (att_assoc)))
|
---|
136 | #define trace_p(var) ((((var)->attributes) & (att_trace)))
|
---|
137 |
|
---|
138 | #define invisible_p(var) ((((var)->attributes) & (att_invisible)))
|
---|
139 | #define non_unsettable_p(var) ((((var)->attributes) & (att_nounset)))
|
---|
140 | #define noassign_p(var) ((((var)->attributes) & (att_noassign)))
|
---|
141 | #define imported_p(var) ((((var)->attributes) & (att_imported)))
|
---|
142 | #define specialvar_p(var) ((((var)->attributes) & (att_special)))
|
---|
143 |
|
---|
144 | #define tempvar_p(var) ((((var)->attributes) & (att_tempvar)))
|
---|
145 |
|
---|
146 | /* Acessing variable values: rvalues */
|
---|
147 | #define value_cell(var) ((var)->value)
|
---|
148 | #define function_cell(var) (COMMAND *)((var)->value)
|
---|
149 | #define array_cell(var) (ARRAY *)((var)->value)
|
---|
150 |
|
---|
151 | #define var_isnull(var) ((var)->value == 0)
|
---|
152 | #define var_isset(var) ((var)->value != 0)
|
---|
153 |
|
---|
154 | /* Assigning variable values: lvalues */
|
---|
155 | #define var_setvalue(var, str) ((var)->value = (str))
|
---|
156 | #define var_setfunc(var, func) ((var)->value = (char *)(func))
|
---|
157 | #define var_setarray(var, arr) ((var)->value = (char *)(arr))
|
---|
158 |
|
---|
159 | /* Make VAR be auto-exported. */
|
---|
160 | #define set_auto_export(var) \
|
---|
161 | do { (var)->attributes |= att_exported; array_needs_making = 1; } while (0)
|
---|
162 |
|
---|
163 | #define SETVARATTR(var, attr, undo) \
|
---|
164 | ((undo == 0) ? ((var)->attributes |= (attr)) \
|
---|
165 | : ((var)->attributes &= ~(attr)))
|
---|
166 |
|
---|
167 | #define VSETATTR(var, attr) ((var)->attributes |= (attr))
|
---|
168 | #define VUNSETATTR(var, attr) ((var)->attributes &= ~(attr))
|
---|
169 |
|
---|
170 | #define VGETFLAGS(var) ((var)->attributes)
|
---|
171 |
|
---|
172 | #define VSETFLAGS(var, flags) ((var)->attributes = (flags))
|
---|
173 | #define VCLRFLAGS(var) ((var)->attributes = 0)
|
---|
174 |
|
---|
175 | /* Macros to perform various operations on `exportstr' member of a SHELL_VAR. */
|
---|
176 | #define CLEAR_EXPORTSTR(var) (var)->exportstr = (char *)NULL
|
---|
177 | #define COPY_EXPORTSTR(var) ((var)->exportstr) ? savestring ((var)->exportstr) : (char *)NULL
|
---|
178 | #define SET_EXPORTSTR(var, value) (var)->exportstr = (value)
|
---|
179 | #define SAVE_EXPORTSTR(var, value) (var)->exportstr = (value) ? savestring (value) : (char *)NULL
|
---|
180 |
|
---|
181 | #define FREE_EXPORTSTR(var) \
|
---|
182 | do { if ((var)->exportstr) free ((var)->exportstr); } while (0)
|
---|
183 |
|
---|
184 | #define CACHE_IMPORTSTR(var, value) \
|
---|
185 | (var)->exportstr = savestring (value)
|
---|
186 |
|
---|
187 | #define INVALIDATE_EXPORTSTR(var) \
|
---|
188 | do { \
|
---|
189 | if ((var)->exportstr) \
|
---|
190 | { \
|
---|
191 | free ((var)->exportstr); \
|
---|
192 | (var)->exportstr = (char *)NULL; \
|
---|
193 | } \
|
---|
194 | } while (0)
|
---|
195 |
|
---|
196 | /* Stuff for hacking variables. */
|
---|
197 | typedef int sh_var_map_func_t __P((SHELL_VAR *));
|
---|
198 |
|
---|
199 | /* Where we keep the variables and functions */
|
---|
200 | extern VAR_CONTEXT *global_variables;
|
---|
201 | extern VAR_CONTEXT *shell_variables;
|
---|
202 |
|
---|
203 | extern HASH_TABLE *shell_functions;
|
---|
204 | extern HASH_TABLE *temporary_env;
|
---|
205 |
|
---|
206 | extern int variable_context;
|
---|
207 | extern char *dollar_vars[];
|
---|
208 | extern char **export_env;
|
---|
209 |
|
---|
210 | extern void initialize_shell_variables __P((char **, int));
|
---|
211 | extern SHELL_VAR *set_if_not __P((char *, char *));
|
---|
212 |
|
---|
213 | extern void sh_set_lines_and_columns __P((int, int));
|
---|
214 | extern void set_pwd __P((void));
|
---|
215 | extern void set_ppid __P((void));
|
---|
216 | extern void make_funcname_visible __P((int));
|
---|
217 |
|
---|
218 | extern SHELL_VAR *var_lookup __P((const char *, VAR_CONTEXT *));
|
---|
219 |
|
---|
220 | extern SHELL_VAR *find_function __P((const char *));
|
---|
221 | extern FUNCTION_DEF *find_function_def __P((const char *));
|
---|
222 | extern SHELL_VAR *find_variable __P((const char *));
|
---|
223 | extern SHELL_VAR *find_variable_internal __P((const char *, int));
|
---|
224 | extern SHELL_VAR *find_tempenv_variable __P((const char *));
|
---|
225 | extern SHELL_VAR *copy_variable __P((SHELL_VAR *));
|
---|
226 | extern SHELL_VAR *make_local_variable __P((const char *));
|
---|
227 | extern SHELL_VAR *bind_variable __P((const char *, char *, int));
|
---|
228 | extern SHELL_VAR *bind_function __P((const char *, COMMAND *));
|
---|
229 |
|
---|
230 | extern void bind_function_def __P((const char *, FUNCTION_DEF *));
|
---|
231 |
|
---|
232 | extern SHELL_VAR **map_over __P((sh_var_map_func_t *, VAR_CONTEXT *));
|
---|
233 | SHELL_VAR **map_over_funcs __P((sh_var_map_func_t *));
|
---|
234 |
|
---|
235 | extern SHELL_VAR **all_shell_variables __P((void));
|
---|
236 | extern SHELL_VAR **all_shell_functions __P((void));
|
---|
237 | extern SHELL_VAR **all_visible_variables __P((void));
|
---|
238 | extern SHELL_VAR **all_visible_functions __P((void));
|
---|
239 | extern SHELL_VAR **all_exported_variables __P((void));
|
---|
240 | extern SHELL_VAR **local_exported_variables __P((void));
|
---|
241 | extern SHELL_VAR **all_local_variables __P((void));
|
---|
242 | #if defined (ARRAY_VARS)
|
---|
243 | extern SHELL_VAR **all_array_variables __P((void));
|
---|
244 | #endif
|
---|
245 | extern char **all_variables_matching_prefix __P((const char *));
|
---|
246 |
|
---|
247 | extern char **make_var_array __P((HASH_TABLE *));
|
---|
248 | extern char **add_or_supercede_exported_var __P((char *, int));
|
---|
249 |
|
---|
250 | extern char *get_variable_value __P((SHELL_VAR *));
|
---|
251 | extern char *get_string_value __P((const char *));
|
---|
252 | extern char *sh_get_env_value __P((const char *));
|
---|
253 | extern char *make_variable_value __P((SHELL_VAR *, char *, int));
|
---|
254 |
|
---|
255 | extern SHELL_VAR *bind_variable_value __P((SHELL_VAR *, char *, int));
|
---|
256 | extern SHELL_VAR *bind_int_variable __P((char *, char *));
|
---|
257 | extern SHELL_VAR *bind_var_to_int __P((char *, intmax_t));
|
---|
258 |
|
---|
259 | extern int assign_in_env __P((WORD_DESC *));
|
---|
260 |
|
---|
261 | extern int unbind_variable __P((const char *));
|
---|
262 | extern int unbind_func __P((const char *));
|
---|
263 | extern int unbind_function_def __P((const char *));
|
---|
264 | extern int makunbound __P((const char *, VAR_CONTEXT *));
|
---|
265 | extern int kill_local_variable __P((const char *));
|
---|
266 | extern void delete_all_variables __P((HASH_TABLE *));
|
---|
267 | extern void delete_all_contexts __P((VAR_CONTEXT *));
|
---|
268 |
|
---|
269 | extern VAR_CONTEXT *new_var_context __P((char *, int));
|
---|
270 | extern void dispose_var_context __P((VAR_CONTEXT *));
|
---|
271 | extern VAR_CONTEXT *push_var_context __P((char *, int, HASH_TABLE *));
|
---|
272 | extern void pop_var_context __P((void));
|
---|
273 | extern VAR_CONTEXT *push_scope __P((int, HASH_TABLE *));
|
---|
274 | extern void pop_scope __P((int));
|
---|
275 |
|
---|
276 | extern void push_context __P((char *, int, HASH_TABLE *));
|
---|
277 | extern void pop_context __P((void));
|
---|
278 | extern void push_dollar_vars __P((void));
|
---|
279 | extern void pop_dollar_vars __P((void));
|
---|
280 | extern void dispose_saved_dollar_vars __P((void));
|
---|
281 |
|
---|
282 | extern void push_args __P((WORD_LIST *));
|
---|
283 | extern void pop_args __P((void));
|
---|
284 |
|
---|
285 | extern void adjust_shell_level __P((int));
|
---|
286 | extern void non_unsettable __P((char *));
|
---|
287 | extern void dispose_variable __P((SHELL_VAR *));
|
---|
288 | extern void dispose_used_env_vars __P((void));
|
---|
289 | extern void dispose_function_env __P((void));
|
---|
290 | extern void dispose_builtin_env __P((void));
|
---|
291 | extern void merge_temporary_env __P((void));
|
---|
292 | extern void merge_builtin_env __P((void));
|
---|
293 | extern void kill_all_local_variables __P((void));
|
---|
294 |
|
---|
295 | extern void set_var_read_only __P((char *));
|
---|
296 | extern void set_func_read_only __P((const char *));
|
---|
297 | extern void set_var_auto_export __P((char *));
|
---|
298 | extern void set_func_auto_export __P((const char *));
|
---|
299 |
|
---|
300 | extern void sort_variables __P((SHELL_VAR **));
|
---|
301 |
|
---|
302 | extern void maybe_make_export_env __P((void));
|
---|
303 | extern void update_export_env_inplace __P((char *, int, char *));
|
---|
304 | extern void put_command_name_into_env __P((char *));
|
---|
305 | extern void put_gnu_argv_flags_into_env __P((intmax_t, char *));
|
---|
306 |
|
---|
307 | extern void print_var_list __P((SHELL_VAR **));
|
---|
308 | extern void print_func_list __P((SHELL_VAR **));
|
---|
309 | extern void print_assignment __P((SHELL_VAR *));
|
---|
310 | extern void print_var_value __P((SHELL_VAR *, int));
|
---|
311 | extern void print_var_function __P((SHELL_VAR *));
|
---|
312 |
|
---|
313 | #if defined (ARRAY_VARS)
|
---|
314 | extern SHELL_VAR *make_new_array_variable __P((char *));
|
---|
315 | extern SHELL_VAR *make_local_array_variable __P((char *));
|
---|
316 |
|
---|
317 | extern void set_pipestatus_array __P((int *, int));
|
---|
318 | #endif
|
---|
319 |
|
---|
320 | extern void set_pipestatus_from_exit __P((int));
|
---|
321 |
|
---|
322 | /* The variable in NAME has just had its state changed. Check to see if it
|
---|
323 | is one of the special ones where something special happens. */
|
---|
324 | extern void stupidly_hack_special_variables __P((char *));
|
---|
325 |
|
---|
326 | extern int get_random_number __P((void));
|
---|
327 |
|
---|
328 | /* The `special variable' functions that get called when a particular
|
---|
329 | variable is set. */
|
---|
330 | extern void sv_ifs __P((char *));
|
---|
331 | extern void sv_path __P((char *));
|
---|
332 | extern void sv_mail __P((char *));
|
---|
333 | extern void sv_comp_wordbreaks __P((char *));
|
---|
334 | extern void sv_globignore __P((char *));
|
---|
335 | extern void sv_ignoreeof __P((char *));
|
---|
336 | extern void sv_strict_posix __P((char *));
|
---|
337 | extern void sv_optind __P((char *));
|
---|
338 | extern void sv_opterr __P((char *));
|
---|
339 | extern void sv_locale __P((char *));
|
---|
340 |
|
---|
341 | #if defined (READLINE)
|
---|
342 | extern void sv_comp_wordbreaks __P((char *));
|
---|
343 | extern void sv_terminal __P((char *));
|
---|
344 | extern void sv_hostfile __P((char *));
|
---|
345 | extern void sv_winsize __P((char *));
|
---|
346 | #endif
|
---|
347 |
|
---|
348 | #if defined (__CYGWIN__)
|
---|
349 | extern void sv_home __P((char *));
|
---|
350 | #endif
|
---|
351 |
|
---|
352 | #if defined (HISTORY)
|
---|
353 | extern void sv_histsize __P((char *));
|
---|
354 | extern void sv_histignore __P((char *));
|
---|
355 | extern void sv_history_control __P((char *));
|
---|
356 | # if defined (BANG_HISTORY)
|
---|
357 | extern void sv_histchars __P((char *));
|
---|
358 | # endif
|
---|
359 | extern void sv_histtimefmt __P((char *));
|
---|
360 | #endif /* HISTORY */
|
---|
361 |
|
---|
362 | #if defined (HAVE_TZSET) && defined (PROMPT_STRING_DECODE)
|
---|
363 | extern void sv_tz __P((char *));
|
---|
364 | #endif
|
---|
365 |
|
---|
366 | #endif /* !_VARIABLES_H_ */
|
---|