summaryrefslogtreecommitdiff
path: root/builtins/declare.def
diff options
context:
space:
mode:
authorJari Aalto <jari.aalto@cante.net>1996-08-26 18:22:31 +0000
committerJari Aalto <jari.aalto@cante.net>2009-09-12 16:46:49 +0000
commit726f63884db0132f01745f1fb4465e6621088ccf (patch)
tree6c2f7765a890a97e0e513cb539df43283a8f7c4d /builtins/declare.def
downloadbash-726f63884db0132f01745f1fb4465e6621088ccf.tar.gz
Imported from ../bash-1.14.7.tar.gz.
Diffstat (limited to 'builtins/declare.def')
-rw-r--r--builtins/declare.def290
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);
+}