📄 variables.c
字号:
var_setvalue (self, (char *)NULL); return self; } h = assoc_create (hashed_filenames->nbuckets); for (i = 0; i < hashed_filenames->nbuckets; i++) { for (item = hash_items (i, hashed_filenames); item; item = item->next) { k = savestring (item->key); v = pathdata(item)->path; assoc_insert (h, k, v); } } var_setvalue (self, (char *)h); return self;}static SHELL_VAR *get_hashcmd (self) SHELL_VAR *self;{ build_hashcmd (self); return (self);}static SHELL_VAR *assign_hashcmd (self, value, ind, key) SHELL_VAR *self; char *value; arrayind_t ind; char *key;{ phash_insert (key, value, 0, 0); return (build_hashcmd (self));}#if defined (ALIAS)static SHELL_VAR *build_aliasvar (self) SHELL_VAR *self;{ HASH_TABLE *h; int i; char *k, *v; BUCKET_CONTENTS *item; h = assoc_cell (self); if (h) assoc_dispose (h); if (aliases == 0 || HASH_ENTRIES (aliases) == 0) { var_setvalue (self, (char *)NULL); return self; } h = assoc_create (aliases->nbuckets); for (i = 0; i < aliases->nbuckets; i++) { for (item = hash_items (i, aliases); item; item = item->next) { k = savestring (item->key); v = ((alias_t *)(item->data))->value; assoc_insert (h, k, v); } } var_setvalue (self, (char *)h); return self;}static SHELL_VAR *get_aliasvar (self) SHELL_VAR *self;{ build_aliasvar (self); return (self);}static SHELL_VAR *assign_aliasvar (self, value, ind, key) SHELL_VAR *self; char *value; arrayind_t ind; char *key;{ add_alias (key, value); return (build_aliasvar (self));}#endif /* ALIAS */#endif /* ARRAY_VARS *//* If ARRAY_VARS is not defined, this just returns the name of any currently-executing function. If we have arrays, it's a call stack. */static SHELL_VAR *get_funcname (self) SHELL_VAR *self;{#if ! defined (ARRAY_VARS) char *t; if (variable_context && this_shell_function) { FREE (value_cell (self)); t = savestring (this_shell_function->name); var_setvalue (self, t); }#endif return (self);}voidmake_funcname_visible (on_or_off) int on_or_off;{ SHELL_VAR *v; v = find_variable ("FUNCNAME"); if (v == 0 || v->dynamic_value == 0) return; if (on_or_off) VUNSETATTR (v, att_invisible); else VSETATTR (v, att_invisible);}static SHELL_VAR *init_funcname_var (){ SHELL_VAR *v; v = find_variable ("FUNCNAME"); if (v) return v;#if defined (ARRAY_VARS) INIT_DYNAMIC_ARRAY_VAR ("FUNCNAME", get_funcname, null_array_assign);#else INIT_DYNAMIC_VAR ("FUNCNAME", (char *)NULL, get_funcname, null_assign);#endif VSETATTR (v, att_invisible|att_noassign); return v;}static voidinitialize_dynamic_variables (){ SHELL_VAR *v; v = init_seconds_var (); INIT_DYNAMIC_VAR ("BASH_COMMAND", (char *)NULL, get_bash_command, (sh_var_assign_func_t *)NULL); INIT_DYNAMIC_VAR ("BASH_SUBSHELL", (char *)NULL, get_subshell, assign_subshell); INIT_DYNAMIC_VAR ("RANDOM", (char *)NULL, get_random, assign_random); VSETATTR (v, att_integer); INIT_DYNAMIC_VAR ("LINENO", (char *)NULL, get_lineno, assign_lineno); VSETATTR (v, att_integer); INIT_DYNAMIC_VAR ("BASHPID", (char *)NULL, get_bashpid, null_assign); VSETATTR (v, att_integer|att_readonly);#if defined (HISTORY) INIT_DYNAMIC_VAR ("HISTCMD", (char *)NULL, get_histcmd, (sh_var_assign_func_t *)NULL); VSETATTR (v, att_integer);#endif#if defined (READLINE) INIT_DYNAMIC_VAR ("COMP_WORDBREAKS", (char *)NULL, get_comp_wordbreaks, assign_comp_wordbreaks);#endif#if defined (PUSHD_AND_POPD) && defined (ARRAY_VARS) v = init_dynamic_array_var ("DIRSTACK", get_dirstack, assign_dirstack, 0);#endif /* PUSHD_AND_POPD && ARRAY_VARS */#if defined (ARRAY_VARS) v = init_dynamic_array_var ("GROUPS", get_groupset, null_array_assign, att_noassign);# if defined (DEBUGGER) v = init_dynamic_array_var ("BASH_ARGC", get_self, null_array_assign, att_noassign|att_nounset); v = init_dynamic_array_var ("BASH_ARGV", get_self, null_array_assign, att_noassign|att_nounset);# endif /* DEBUGGER */ v = init_dynamic_array_var ("BASH_SOURCE", get_self, null_array_assign, att_noassign|att_nounset); v = init_dynamic_array_var ("BASH_LINENO", get_self, null_array_assign, att_noassign|att_nounset); v = init_dynamic_assoc_var ("BASH_CMDS", get_hashcmd, assign_hashcmd, att_nofree);# if defined (ALIAS) v = init_dynamic_assoc_var ("BASH_ALIASES", get_aliasvar, assign_aliasvar, att_nofree);# endif#endif v = init_funcname_var ();}/* **************************************************************** *//* *//* Retrieving variables and values *//* *//* **************************************************************** *//* How to get a pointer to the shell variable or function named NAME. HASHED_VARS is a pointer to the hash table containing the list of interest (either variables or functions). */static SHELL_VAR *hash_lookup (name, hashed_vars) const char *name; HASH_TABLE *hashed_vars;{ BUCKET_CONTENTS *bucket; bucket = hash_search (name, hashed_vars, 0); return (bucket ? (SHELL_VAR *)bucket->data : (SHELL_VAR *)NULL);}SHELL_VAR *var_lookup (name, vcontext) const char *name; VAR_CONTEXT *vcontext;{ VAR_CONTEXT *vc; SHELL_VAR *v; v = (SHELL_VAR *)NULL; for (vc = vcontext; vc; vc = vc->down) if (v = hash_lookup (name, vc->table)) break; return v;}/* Look up the variable entry named NAME. If SEARCH_TEMPENV is non-zero, then also search the temporarily built list of exported variables. The lookup order is: temporary_env shell_variables list*/SHELL_VAR *find_variable_internal (name, force_tempenv) const char *name; int force_tempenv;{ SHELL_VAR *var; int search_tempenv; var = (SHELL_VAR *)NULL; /* If explicitly requested, first look in the temporary environment for the variable. This allows constructs such as "foo=x eval 'echo $foo'" to get the `exported' value of $foo. This happens if we are executing a function or builtin, or if we are looking up a variable in a "subshell environment". */ search_tempenv = force_tempenv || (expanding_redir == 0 && subshell_environment); if (search_tempenv && temporary_env) var = hash_lookup (name, temporary_env); if (var == 0) var = var_lookup (name, shell_variables); if (var == 0) return ((SHELL_VAR *)NULL); return (var->dynamic_value ? (*(var->dynamic_value)) (var) : var);}SHELL_VAR *find_global_variable (name) const char *name;{ SHELL_VAR *var; var = var_lookup (name, global_variables); if (var == 0) return ((SHELL_VAR *)NULL); return (var->dynamic_value ? (*(var->dynamic_value)) (var) : var);}/* Look up the variable entry named NAME. Returns the entry or NULL. */SHELL_VAR *find_variable (name) const char *name;{ return (find_variable_internal (name, (expanding_redir == 0 && (assigning_in_environment || executing_builtin))));}/* Look up the function entry whose name matches STRING. Returns the entry or NULL. */SHELL_VAR *find_function (name) const char *name;{ return (hash_lookup (name, shell_functions));}/* Find the function definition for the shell function named NAME. Returns the entry or NULL. */FUNCTION_DEF *find_function_def (name) const char *name;{#if defined (DEBUGGER) return ((FUNCTION_DEF *)hash_lookup (name, shell_function_defs));#else return ((FUNCTION_DEF *)0);#endif}/* Return the value of VAR. VAR is assumed to have been the result of a lookup without any subscript, if arrays are compiled into the shell. */char *get_variable_value (var) SHELL_VAR *var;{ if (var == 0) return ((char *)NULL);#if defined (ARRAY_VARS) else if (array_p (var)) return (array_reference (array_cell (var), 0)); else if (assoc_p (var)) return (assoc_reference (assoc_cell (var), "0"));#endif else return (value_cell (var));}/* Return the string value of a variable. Return NULL if the variable doesn't exist. Don't cons a new string. This is a potential memory leak if the variable is found in the temporary environment. Since functions and variables have separate name spaces, returns NULL if var_name is a shell function only. */char *get_string_value (var_name) const char *var_name;{ SHELL_VAR *var; var = find_variable (var_name); return ((var) ? get_variable_value (var) : (char *)NULL);}/* This is present for use by the tilde and readline libraries. */char *sh_get_env_value (v) const char *v;{ return get_string_value (v);}/* **************************************************************** *//* *//* Creating and setting variables *//* *//* **************************************************************** *//* Set NAME to VALUE if NAME has no value. */SHELL_VAR *set_if_not (name, value) char *name, *value;{ SHELL_VAR *v; if (shell_variables == 0) create_variable_tables (); v = find_variable (name); if (v == 0) v = bind_variable_internal (name, value, global_variables->table, HASH_NOSRCH, 0); return (v);}/* Create a local variable referenced by NAME. */SHELL_VAR *make_local_variable (name) const char *name;{ SHELL_VAR *new_var, *old_var; VAR_CONTEXT *vc; int was_tmpvar; char *tmp_value; /* local foo; local foo; is a no-op. */ old_var = find_variable (name); if (old_var && local_p (old_var) && old_var->context == variable_context) { VUNSETATTR (old_var, att_invisible); return (old_var); } was_tmpvar = old_var && tempvar_p (old_var); if (was_tmpvar) tmp_value = value_cell (old_var); for (vc = shell_variables; vc; vc = vc->down) if (vc_isfuncenv (vc) && vc->scope == variable_context) break; if (vc == 0) { internal_error (_("make_local_variable: no function context at current scope")); return ((SHELL_VAR *)NULL); } else if (vc->table == 0) vc->table = hash_create (TEMPENV_HASH_BUCKETS); /* Since this is called only from the local/declare/typeset code, we can call builtin_error here without worry (of course, it will also work for anything that sets this_command_name). Variables with the `noassign' attribute may not be made local. The test against old_var's context level is to disallow local copies of readonly global variables (since I believe that this could be a security hole). Readonly copies of calling function local variables are OK. */ if (old_var && (noassign_p (old_var) || (readonly_p (old_var) && old_var->context == 0))) { if (readonly_p (old_var)) sh_readonly (name); return ((SHELL_VAR *)NULL); } if (old_var == 0) new_var = make_new_variable (name, vc->table); else { new_var = make_new_variable (name, vc->table); /* If we found this variable in one of the temporary environments, inherit its value. Watch to see if this causes problems with things like `x=4 local x'. */ if (was_tmpvar) var_setvalue (new_var, savestring (tmp_value)); new_var->attributes = exported_p (old_var) ? att_exported : 0; } vc->flags |= VC_HASLOCAL; new_var->context = variable_context; VSETATTR (new_var, att_local); if (ifsname (name)) setifs (new_var); return (new_var);}/* Create a new shell variable with name NAME. */static SHELL_VAR *new_shell_variable (name) const char *name;{ SHELL_VAR *entry; entry = (SHELL_VAR *)xmalloc (sizeof (SHELL_VAR)); entry->name = savestring (name); var_setvalue (entry, (char *)NULL); CLEAR_EXPORTSTR (entry); entry->dynamic_value = (sh_var_value_func_t *)NULL; entry->assign_func = (sh_var_assign_func_t *)NULL; entry->attributes = 0; /* Always assume variables are to be made at toplevel! make_local_variable has the responsibilty of changing the variable context. */ entry->context = 0; return (entry);}/* Create a new shell variable with name NAME and add it to the hash table TABLE. */static SHELL_VAR *make_new_variable (name, table) const char *name; HASH_TABLE *table;{ SHELL_VAR *entry; BUCKET_CONTENTS *elt; entry = new_shell_variable (name); /* Make sure we have a shell_variables hash table to add to. */ if (shell_variables == 0) create_variable_tables (); elt = hash_insert (savestring (name), table, HASH_NOSRCH); elt->data = (PTR_T)entry; return entry;}#if defined (ARRAY_VARS)SHELL_VAR *make_new_array_variable (name) char *name;{ SHELL_VAR *entry; ARRAY *array; entry = make_new_variable (name, global_variables->table); array = array_create ();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -