diff options
author | tilghman <tilghman@f38db490-d61c-443f-a65b-d21fe96a405b> | 2008-12-02 18:39:12 +0000 |
---|---|---|
committer | tilghman <tilghman@f38db490-d61c-443f-a65b-d21fe96a405b> | 2008-12-02 18:39:12 +0000 |
commit | 2682703b3ed8ddf182f5f91fa2858c9e50d5adad (patch) | |
tree | c8fdb1d5abfe00b35a477a8241a7dc7cccc50094 /apps/app_stack.c | |
parent | 7d9ae222612600c4a6f57e44186c22d58eb625aa (diff) |
Add LOCAL_PEEK function, as requested by lmadsen.
git-svn-id: http://svn.digium.com/svn/asterisk/trunk@160344 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'apps/app_stack.c')
-rw-r--r-- | apps/app_stack.c | 59 |
1 files changed, 59 insertions, 0 deletions
diff --git a/apps/app_stack.c b/apps/app_stack.c index 0a911e5ec..1311bad77 100644 --- a/apps/app_stack.c +++ b/apps/app_stack.c @@ -142,6 +142,27 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") <ref type="application">Return</ref> </see-also> </function> + <function name="LOCAL_PEEK" language="en_US"> + <synopsis> + Retrieve variables hidden by the local gosub stack frame. + </synopsis> + <syntax> + <parameter name="n" required="true" /> + <parameter name="varname" required="true" /> + </syntax> + <description> + <para>Read a variable <replaceable>varname</replaceable> hidden by + <replaceable>n</replaceable> levels of gosub stack frames. Note that ${LOCAL_PEEK(0,foo)} + is the same as ${foo}, since the value of <replaceable>n</replaceable> peeks under 0 levels of + stack frames; in other words, 0 is the current level. If <replaceable>n</replaceable> exceeds + the available number of stack frames, then an empty string is returned.</para> + </description> + <see-also> + <ref type="application">Gosub</ref> + <ref type="application">GosubIf</ref> + <ref type="application">Return</ref> + </see-also> + </function> ***/ static const char *app_gosub = "Gosub"; @@ -471,6 +492,42 @@ static struct ast_custom_function local_function = { .read = local_read, }; +static int peek_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len) +{ + int found = 0, n; + struct ast_var_t *variables; + AST_DECLARE_APP_ARGS(args, + AST_APP_ARG(n); + AST_APP_ARG(name); + ); + + if (!chan) { + ast_log(LOG_ERROR, "LOCAL_PEEK must be called on an active channel\n"); + return -1; + } + + AST_STANDARD_APP_ARGS(args, data); + n = atoi(args.n); + *buf = '\0'; + + ast_channel_lock(chan); + AST_LIST_TRAVERSE(&chan->varshead, variables, entries) { + if (!strcmp(args.name, ast_var_name(variables)) && ++found > n) { + ast_copy_string(buf, ast_var_value(variables), len); + break; + } + } + ast_channel_unlock(chan); + return 0; +} + +static struct ast_custom_function peek_function = { + .name = "LOCAL_PEEK", + .synopsis = "Peeks at variables within the variable stack", + .syntax = "LOCAL_PEEK(<n>|<varname>)", + .read = peek_read, +}; + static int handle_gosub(struct ast_channel *chan, AGI *agi, int argc, char **argv) { int old_priority, priority; @@ -585,6 +642,7 @@ static int unload_module(void) ast_unregister_application(app_gosubif); ast_unregister_application(app_gosub); ast_custom_function_unregister(&local_function); + ast_custom_function_unregister(&peek_function); return 0; } @@ -607,6 +665,7 @@ static int load_module(void) ast_register_application_xml(app_gosubif, gosubif_exec); ast_register_application_xml(app_gosub, gosub_exec); ast_custom_function_register(&local_function); + ast_custom_function_register(&peek_function); return 0; } |