|
|
|
@ -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;
|
|
|
|
|
}
|
|
|
|
|