[3228] | 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_ */
|
---|