📄 variables.c
字号:
else printf ("%s", value_cell (var));}/* Print the function cell of VAR, a shell variable. Do not print the name, nor leading/trailing newline. */voidprint_var_function (var) SHELL_VAR *var;{ char *x; if (function_p (var) && var_isset (var)) { x = named_function_string ((char *)NULL, function_cell(var), FUNC_MULTILINE|FUNC_EXTERNAL); printf ("%s", x); }}/* **************************************************************** *//* *//* Dynamic Variables *//* *//* **************************************************************** *//* DYNAMIC VARIABLES These are variables whose values are generated anew each time they are referenced. These are implemented using a pair of function pointers in the struct variable: assign_func, which is called from bind_variable and, if arrays are compiled into the shell, some of the functions in arrayfunc.c, and dynamic_value, which is called from find_variable. assign_func is called from bind_variable_internal, if bind_variable_internal discovers that the variable being assigned to has such a function. The function is called as SHELL_VAR *temp = (*(entry->assign_func)) (entry, value, ind) and the (SHELL_VAR *)temp is returned as the value of bind_variable. It is usually ENTRY (self). IND is an index for an array variable, and unused otherwise. dynamic_value is called from find_variable_internal to return a `new' value for the specified dynamic varible. If this function is NULL, the variable is treated as a `normal' shell variable. If it is not, however, then this function is called like this: tempvar = (*(var->dynamic_value)) (var); Sometimes `tempvar' will replace the value of `var'. Other times, the shell will simply use the string value. Pretty object-oriented, huh? Be warned, though: if you `unset' a special variable, it loses its special meaning, even if you subsequently set it. The special assignment code would probably have been better put in subst.c: do_assignment_internal, in the same style as stupidly_hack_special_variables, but I wanted the changes as localized as possible. */#define INIT_DYNAMIC_VAR(var, val, gfunc, afunc) \ do \ { \ v = bind_variable (var, (val), 0); \ v->dynamic_value = gfunc; \ v->assign_func = afunc; \ } \ while (0)#define INIT_DYNAMIC_ARRAY_VAR(var, gfunc, afunc) \ do \ { \ v = make_new_array_variable (var); \ v->dynamic_value = gfunc; \ v->assign_func = afunc; \ } \ while (0)#define INIT_DYNAMIC_ASSOC_VAR(var, gfunc, afunc) \ do \ { \ v = make_new_assoc_variable (var); \ v->dynamic_value = gfunc; \ v->assign_func = afunc; \ } \ while (0)static SHELL_VAR *null_assign (self, value, unused, key) SHELL_VAR *self; char *value; arrayind_t unused; char *key;{ return (self);}#if defined (ARRAY_VARS)static SHELL_VAR *null_array_assign (self, value, ind, key) SHELL_VAR *self; char *value; arrayind_t ind; char *key;{ return (self);}#endif/* Degenerate `dynamic_value' function; just returns what's passed without manipulation. */static SHELL_VAR *get_self (self) SHELL_VAR *self;{ return (self);}#if defined (ARRAY_VARS)/* A generic dynamic array variable initializer. Intialize array variable NAME with dynamic value function GETFUNC and assignment function SETFUNC. */static SHELL_VAR *init_dynamic_array_var (name, getfunc, setfunc, attrs) char *name; sh_var_value_func_t *getfunc; sh_var_assign_func_t *setfunc; int attrs;{ SHELL_VAR *v; v = find_variable (name); if (v) return (v); INIT_DYNAMIC_ARRAY_VAR (name, getfunc, setfunc); if (attrs) VSETATTR (v, attrs); return v;}static SHELL_VAR *init_dynamic_assoc_var (name, getfunc, setfunc, attrs) char *name; sh_var_value_func_t *getfunc; sh_var_assign_func_t *setfunc; int attrs;{ SHELL_VAR *v; v = find_variable (name); if (v) return (v); INIT_DYNAMIC_ASSOC_VAR (name, getfunc, setfunc); if (attrs) VSETATTR (v, attrs); return v;}#endif/* The value of $SECONDS. This is the number of seconds since shell invocation, or, the number of seconds since the last assignment + the value of the last assignment. */static intmax_t seconds_value_assigned;static SHELL_VAR *assign_seconds (self, value, unused, key) SHELL_VAR *self; char *value; arrayind_t unused; char *key;{ if (legal_number (value, &seconds_value_assigned) == 0) seconds_value_assigned = 0; shell_start_time = NOW; return (self);}static SHELL_VAR *get_seconds (var) SHELL_VAR *var;{ time_t time_since_start; char *p; time_since_start = NOW - shell_start_time; p = itos(seconds_value_assigned + time_since_start); FREE (value_cell (var)); VSETATTR (var, att_integer); var_setvalue (var, p); return (var);}static SHELL_VAR *init_seconds_var (){ SHELL_VAR *v; v = find_variable ("SECONDS"); if (v) { if (legal_number (value_cell(v), &seconds_value_assigned) == 0) seconds_value_assigned = 0; } INIT_DYNAMIC_VAR ("SECONDS", (v ? value_cell (v) : (char *)NULL), get_seconds, assign_seconds); return v; } /* The random number seed. You can change this by setting RANDOM. */static unsigned long rseed = 1;static int last_random_value;static int seeded_subshell = 0;/* A linear congruential random number generator based on the example one in the ANSI C standard. This one isn't very good, but a more complicated one is overkill. *//* Returns a pseudo-random number between 0 and 32767. */static intbrand (){ /* From "Random number generators: good ones are hard to find", Park and Miller, Communications of the ACM, vol. 31, no. 10, October 1988, p. 1195. filtered through FreeBSD */ long h, l; /* Can't seed with 0. */ if (rseed == 0) rseed = 123459876; h = rseed / 127773; l = rseed % 127773; rseed = 16807 * l - 2836 * h;#if 0 if (rseed < 0) rseed += 0x7fffffff;#endif return ((unsigned int)(rseed & 32767)); /* was % 32768 */}/* Set the random number generator seed to SEED. */static voidsbrand (seed) unsigned long seed;{ rseed = seed; last_random_value = 0;}static voidseedrand (){ struct timeval tv; gettimeofday (&tv, NULL); sbrand (tv.tv_sec ^ tv.tv_usec ^ getpid ());}static SHELL_VAR *assign_random (self, value, unused, key) SHELL_VAR *self; char *value; arrayind_t unused; char *key;{ sbrand (strtoul (value, (char **)NULL, 10)); if (subshell_environment) seeded_subshell = getpid (); return (self);}intget_random_number (){ int rv, pid; /* Reset for command and process substitution. */ pid = getpid (); if (subshell_environment && seeded_subshell != pid) { seedrand (); seeded_subshell = pid; } do rv = brand (); while (rv == last_random_value); return rv;}static SHELL_VAR *get_random (var) SHELL_VAR *var;{ int rv; char *p; rv = get_random_number (); last_random_value = rv; p = itos (rv); FREE (value_cell (var)); VSETATTR (var, att_integer); var_setvalue (var, p); return (var);}static SHELL_VAR *assign_lineno (var, value, unused, key) SHELL_VAR *var; char *value; arrayind_t unused; char *key;{ intmax_t new_value; if (value == 0 || *value == '\0' || legal_number (value, &new_value) == 0) new_value = 0; line_number = line_number_base = new_value; return var;}/* Function which returns the current line number. */static SHELL_VAR *get_lineno (var) SHELL_VAR *var;{ char *p; int ln; ln = executing_line_number (); p = itos (ln); FREE (value_cell (var)); var_setvalue (var, p); return (var);}static SHELL_VAR *assign_subshell (var, value, unused, key) SHELL_VAR *var; char *value; arrayind_t unused; char *key;{ intmax_t new_value; if (value == 0 || *value == '\0' || legal_number (value, &new_value) == 0) new_value = 0; subshell_level = new_value; return var;}static SHELL_VAR *get_subshell (var) SHELL_VAR *var;{ char *p; p = itos (subshell_level); FREE (value_cell (var)); var_setvalue (var, p); return (var);}static SHELL_VAR *get_bashpid (var) SHELL_VAR *var;{ int pid; char *p; pid = getpid (); p = itos (pid); FREE (value_cell (var)); VSETATTR (var, att_integer|att_readonly); var_setvalue (var, p); return (var);}static SHELL_VAR *get_bash_command (var) SHELL_VAR *var;{ char *p; if (the_printed_command_except_trap) p = savestring (the_printed_command_except_trap); else { p = (char *)xmalloc (1); p[0] = '\0'; } FREE (value_cell (var)); var_setvalue (var, p); return (var);}#if defined (HISTORY)static SHELL_VAR *get_histcmd (var) SHELL_VAR *var;{ char *p; p = itos (history_number ()); FREE (value_cell (var)); var_setvalue (var, p); return (var);}#endif#if defined (READLINE)/* When this function returns, VAR->value points to malloced memory. */static SHELL_VAR *get_comp_wordbreaks (var) SHELL_VAR *var;{ /* If we don't have anything yet, assign a default value. */ if (rl_completer_word_break_characters == 0 && bash_readline_initialized == 0) enable_hostname_completion (perform_hostname_completion); FREE (value_cell (var)); var_setvalue (var, savestring (rl_completer_word_break_characters)); return (var);}/* When this function returns, rl_completer_word_break_characters points to malloced memory. */static SHELL_VAR *assign_comp_wordbreaks (self, value, unused, key) SHELL_VAR *self; char *value; arrayind_t unused; char *key;{ if (rl_completer_word_break_characters && rl_completer_word_break_characters != rl_basic_word_break_characters) free (rl_completer_word_break_characters); rl_completer_word_break_characters = savestring (value); return self;}#endif /* READLINE */#if defined (PUSHD_AND_POPD) && defined (ARRAY_VARS)static SHELL_VAR *assign_dirstack (self, value, ind, key) SHELL_VAR *self; char *value; arrayind_t ind; char *key;{ set_dirstack_element (ind, 1, value); return self;}static SHELL_VAR *get_dirstack (self) SHELL_VAR *self;{ ARRAY *a; WORD_LIST *l; l = get_directory_stack (0); a = array_from_word_list (l); array_dispose (array_cell (self)); dispose_words (l); var_setarray (self, a); return self;}#endif /* PUSHD AND POPD && ARRAY_VARS */#if defined (ARRAY_VARS)/* We don't want to initialize the group set with a call to getgroups() unless we're asked to, but we only want to do it once. */static SHELL_VAR *get_groupset (self) SHELL_VAR *self;{ register int i; int ng; ARRAY *a; static char **group_set = (char **)NULL; if (group_set == 0) { group_set = get_group_list (&ng); a = array_cell (self); for (i = 0; i < ng; i++) array_insert (a, i, group_set[i]); } return (self);}static SHELL_VAR *build_hashcmd (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 (hashed_filenames == 0 || HASH_ENTRIES (hashed_filenames) == 0) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -