diff options
author | Jari Aalto <jari.aalto@cante.net> | 1996-08-26 18:22:31 +0000 |
---|---|---|
committer | Jari Aalto <jari.aalto@cante.net> | 2009-09-12 16:46:49 +0000 |
commit | 726f63884db0132f01745f1fb4465e6621088ccf (patch) | |
tree | 6c2f7765a890a97e0e513cb539df43283a8f7c4d /builtins/declare.def | |
download | bash-726f63884db0132f01745f1fb4465e6621088ccf.tar.gz |
Imported from ../bash-1.14.7.tar.gz.
Diffstat (limited to 'builtins/declare.def')
-rw-r--r-- | builtins/declare.def | 290 |
1 files changed, 290 insertions, 0 deletions
diff --git a/builtins/declare.def b/builtins/declare.def new file mode 100644 index 00000000..17b7ea2d --- /dev/null +++ b/builtins/declare.def @@ -0,0 +1,290 @@ +This file is declare.def, from which is created declare.c. +It implements the builtins "declare" and "local" in Bash. + +Copyright (C) 1987, 1989, 1991 Free Software Foundation, Inc. + +This file is part of GNU Bash, the Bourne Again SHell. + +Bash is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 1, or (at your option) any later +version. + +Bash is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License along +with Bash; see the file COPYING. If not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + +$PRODUCES declare.c + +$BUILTIN declare +$FUNCTION declare_builtin +$SHORT_DOC declare [-[frxi]] name[=value] ... +Declare variables and/or give them attributes. If no NAMEs are +given, then display the values of variables instead. + +The flags are: + + -f to select from among function names only, + -r to make NAMEs readonly, + -x to make NAMEs export, + -i to make NAMEs have the `integer' attribute set. + +Variables with the integer attribute have arithmetic evaluation (see +`let') done when the variable is assigned to. + +Using `+' instead of `-' turns off the given attribute instead. When +used in a function, makes NAMEs local, as with the `local' command. +$END + +$BUILTIN typeset +$FUNCTION declare_builtin +$SHORT_DOC typeset [-[frxi]] name[=value] ... +Obsolete. See `declare'. +$END + +#include <stdio.h> + +#if defined (HAVE_STRING_H) +# include <string.h> +#else /* !HAVE_STRING_H */ +# include <strings.h> +#endif /* !HAVE_STRING_H */ + +#include "../shell.h" + +extern int variable_context, array_needs_making; + +static int declare_internal (); + +/* Declare or change variable attributes. */ +int +declare_builtin (list) + register WORD_LIST *list; +{ + return (declare_internal (list, 0)); +} + +$BUILTIN local +$FUNCTION local_builtin +$SHORT_DOC local name[=value] ... +Create a local variable called NAME, and give it VALUE. LOCAL +can only be used within a function; it makes the variable NAME +have a visible scope restricted to that function and its children. +$END +int +local_builtin (list) + register WORD_LIST *list; +{ + if (variable_context) + return (declare_internal (list, 1)); + else + { + builtin_error ("Can only be used in a function"); + return (EXECUTION_FAILURE); + } +} + +/* The workhorse function. */ +static int +declare_internal (list, local_var) + register WORD_LIST *list; + int local_var; +{ + int flags_on = 0, flags_off = 0; + int any_failed = 0; + + while (list) + { + register char *t = list->word->word; + int *flags; + + if (t[0] == '-' && t[1] == '-' && t[2] == '\0') + { + list = list->next; + break; + } + + if (*t != '+' && *t != '-') + break; + + if (*t == '+') + flags = &flags_off; + else + flags = &flags_on; + + t++; + + while (*t) + { + if (*t == 'f') + *flags |= att_function, t++; + else if (*t == 'x') + *flags |= att_exported, t++, array_needs_making = 1; + else if (*t == 'r') + *flags |= att_readonly, t++; + else if (*t == 'i') + *flags |= att_integer, t++; + else + { + builtin_error ("unknown option: `-%c'", *t); + return (EX_USAGE); + } + } + + list = list->next; + } + + /* If there are no more arguments left, then we just want to show + some variables. */ + if (!list) + { + /* Show local variables defined at this context level if this is + the `local' builtin. */ + if (local_var) + { + register SHELL_VAR **vlist; + register int i; + + vlist = map_over (variable_in_context, shell_variables); + + if (vlist) + { + for (i = 0; vlist[i]; i++) + print_assignment (vlist[i]); + + free (vlist); + } + } + else + { + if (!flags_on) + set_builtin ((WORD_LIST *)NULL); + else + set_or_show_attributes ((WORD_LIST *)NULL, flags_on); + } + + fflush (stdout); + return (EXECUTION_SUCCESS); + } + +#define NEXT_VARIABLE() free (name); list = list->next; continue + + /* There are arguments left, so we are making variables. */ + while (list) + { + char *value, *name = savestring (list->word->word); + int offset = assignment (name); + + if (offset) + { + name[offset] = '\0'; + value = name + offset + 1; + } + else + value = ""; + + if (legal_identifier (name) == 0) + { + builtin_error ("%s: not a legal variable name", name); + any_failed++; + NEXT_VARIABLE (); + } + + /* If VARIABLE_CONTEXT has a non-zero value, then we are executing + inside of a function. This means we should make local variables, + not global ones. */ + + if (variable_context) + make_local_variable (name); + + /* If we are declaring a function, then complain about it in some way. + We don't let people make functions by saying `typeset -f foo=bar'. */ + + /* There should be a way, however, to let people look at a particular + function definition by saying `typeset -f foo'. */ + + if (flags_on & att_function) + { + if (offset) + { + builtin_error ("Can't use `-f' to make functions"); + return (EXECUTION_FAILURE); + } + else + { + SHELL_VAR *find_function (), *funvar; + + funvar = find_function (name); + + if (funvar) + { + if (readonly_p (funvar) && (flags_off & att_readonly)) + { + builtin_error ("%s: readonly function", name); + any_failed++; + NEXT_VARIABLE (); + } + + if (flags_on == att_function && flags_off == 0) + { + char *result = named_function_string + (name, (COMMAND *)function_cell (funvar), 1); + printf ("%s\n", result); + } + else + { + funvar->attributes |= flags_on; + funvar->attributes &= ~flags_off; + } + } + else + any_failed++; + NEXT_VARIABLE (); + } + } + else + { + SHELL_VAR *var; + + var = find_variable (name); + + if (!var) + var = bind_variable (name, ""); + + if (readonly_p (var) && (flags_off & att_readonly)) + { + builtin_error ("%s: readonly variable", name); + any_failed++; + NEXT_VARIABLE (); + } + + var->attributes |= flags_on; + var->attributes &= ~flags_off; + + if (offset) + { + free (var->value); + if (integer_p (var)) + { + long val, evalexp (); + char *itos (); + + val = evalexp (value); + var->value = itos ((int)val); + } + else + var->value = savestring (value); + } + } + + stupidly_hack_special_variables (name); + + NEXT_VARIABLE (); + } + return (any_failed ? EXECUTION_FAILURE : EXECUTION_SUCCESS); +} |