diff options
Diffstat (limited to 'builtins/caller.def')
-rw-r--r-- | builtins/caller.def | 156 |
1 files changed, 156 insertions, 0 deletions
diff --git a/builtins/caller.def b/builtins/caller.def new file mode 100644 index 0000000..bf5eb96 --- /dev/null +++ b/builtins/caller.def @@ -0,0 +1,156 @@ +This file is caller.def, from which is created caller.c. It implements the +builtin "caller" in Bash. + +Copyright (C) 2002-2008 Rocky Bernstein for Free Software Foundation, Inc. +Copyright (C) 2008-2013 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 3 of the License, 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. If not, see <http://www.gnu.org/licenses/>. + +$PRODUCES caller.c + +$BUILTIN caller +$FUNCTION caller_builtin +$DEPENDS_ON DEBUGGER +$SHORT_DOC caller [expr] +Return the context of the current subroutine call. + +Without EXPR, returns "$line $filename". With EXPR, returns +"$line $subroutine $filename"; this extra information can be used to +provide a stack trace. + +The value of EXPR indicates how many call frames to go back before the +current one; the top frame is frame 0. + +Exit Status: +Returns 0 unless the shell is not executing a shell function or EXPR +is invalid. +$END + +#include <config.h> +#include <stdio.h> +#include "chartypes.h" +#include "bashtypes.h" + +#if defined (HAVE_UNISTD_H) +# ifdef _MINIX +# include <sys/types.h> +# endif +# include <unistd.h> +#endif + +#include <errno.h> + +#include "../bashintl.h" + +#include "../shell.h" +#include "common.h" +#include "builtext.h" +#include "bashgetopt.h" + +#ifdef LOADABLE_BUILTIN +# include "builtins.h" +#endif + +#if !defined (errno) +extern int errno; +#endif /* !errno */ + +int +caller_builtin (list) + WORD_LIST *list; +{ +#if !defined (ARRAY_VARS) + printf ("1 NULL\n"); + return (EXECUTION_FAILURE); +#else + SHELL_VAR *funcname_v, *bash_source_v, *bash_lineno_v; + ARRAY *funcname_a, *bash_source_a, *bash_lineno_a; + char *funcname_s, *source_s, *lineno_s; + intmax_t num; + + CHECK_HELPOPT (list); + + GET_ARRAY_FROM_VAR ("FUNCNAME", funcname_v, funcname_a); + GET_ARRAY_FROM_VAR ("BASH_SOURCE", bash_source_v, bash_source_a); + GET_ARRAY_FROM_VAR ("BASH_LINENO", bash_lineno_v, bash_lineno_a); + + if (bash_lineno_a == 0 || array_empty (bash_lineno_a)) + return (EXECUTION_FAILURE); + + if (bash_source_a == 0 || array_empty (bash_source_a)) + return (EXECUTION_FAILURE); + + if (no_options (list)) + return (EX_USAGE); + list = loptend; /* skip over possible `--' */ + + /* If there is no argument list, then give short form: line filename. */ + if (list == 0) + { + lineno_s = array_reference (bash_lineno_a, 0); + source_s = array_reference (bash_source_a, 1); + printf("%s %s\n", lineno_s ? lineno_s : "NULL", source_s ? source_s : "NULL"); + return (EXECUTION_SUCCESS); + } + + if (funcname_a == 0 || array_empty (funcname_a)) + return (EXECUTION_FAILURE); + + if (legal_number (list->word->word, &num)) + { + lineno_s = array_reference (bash_lineno_a, num); + source_s = array_reference (bash_source_a, num+1); + funcname_s = array_reference (funcname_a, num+1); + + if (lineno_s == NULL|| source_s == NULL || funcname_s == NULL) + return (EXECUTION_FAILURE); + + printf("%s %s %s\n", lineno_s, funcname_s, source_s); + } + else + { + sh_invalidnum (list->word->word); + builtin_usage (); + return (EX_USAGE); + } + + return (EXECUTION_SUCCESS); +#endif +} + +#ifdef LOADABLE_BUILTIN +static char *caller_doc[] = { +N_("Returns the context of the current subroutine call.\n\ + \n\ + Without EXPR, returns "$line $filename". With EXPR, returns\n\ + "$line $subroutine $filename"; this extra information can be used to\n\ + provide a stack trace.\n\ + \n\ + The value of EXPR indicates how many call frames to go back before the\n\ + current one; the top frame is frame 0."), + (char *)NULL +}; + +struct builtin caller_struct = { + "caller", + caller_builtin, + BUILTIN_ENABLED, + caller_doc, + "caller [EXPR]", + 0 +}; + +#endif /* LOADABLE_BUILTIN */ |