diff --git a/apps/app_macro.c b/apps/app_macro.c index 8fe59634ea457ca3c59644a9ff1d66fe68972382..ce65bef25da58a8e40840fa20c3f3a95d6cb933a 100644 --- a/apps/app_macro.c +++ b/apps/app_macro.c @@ -37,67 +37,124 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") #include "asterisk/utils.h" #include "asterisk/lock.h" +/*** DOCUMENTATION + <application name="Macro" language="en_US"> + <synopsis> + Macro Implementation. + </synopsis> + <syntax> + <parameter name="name" required="true"> + <para>The name of the macro</para> + </parameter> + <parameter name="args"> + <argument name="arg1" required="true" /> + <argument name="arg2" multiple="true" /> + </parameter> + </syntax> + <description> + <para>Executes a macro using the context macro-<replaceable>name</replaceable>, + jumping to the <literal>s</literal> extension of that context and executing each step, + then returning when the steps end.</para> + <para>The calling extension, context, and priority are stored in <variable>MACRO_EXTEN</variable>, + <variable>MACRO_CONTEXT</variable> and <variable>MACRO_PRIORITY</variable> respectively. Arguments + become <variable>ARG1</variable>, <variable>ARG2</variable>, etc in the macro context.</para> + <para>If you Goto out of the Macro context, the Macro will terminate and control will be returned + at the location of the Goto.</para> + <para>If <variable>MACRO_OFFSET</variable> is set at termination, Macro will attempt to continue + at priority MACRO_OFFSET + N + 1 if such a step exists, and N + 1 otherwise.</para> + <para>Extensions: While a macro is being executed, it becomes the current context. This means that if + a hangup occurs, for instance, that the macro will be searched for an <literal>h</literal> extension, + NOT the context from which the macro was called. So, make sure to define all appropriate extensions + in your macro! (Note: AEL does not use macros)</para> + <warning><para>Because of the way Macro is implemented (it executes the priorities contained within + it via sub-engine), and a fixed per-thread memory stack allowance, macros are limited to 7 levels + of nesting (macro calling macro calling macro, etc.); It may be possible that stack-intensive + applications in deeply nested macros could cause asterisk to crash earlier than this limit. + It is advised that if you need to deeply nest macro calls, that you use the Gosub application + (now allows arguments like a Macro) with explict Return() calls instead.</para></warning> + </description> + <see-also> + <ref type="application">MacroExit</ref> + <ref type="application">Goto</ref> + <ref type="application">Gosub</ref> + </see-also> + </application> + <application name="MacroIf" language="en_US"> + <synopsis> + Conditional Macro implementation. + </synopsis> + <syntax argsep="?"> + <parameter name="expr" required="true" /> + <parameter name="destination" required="true" argsep=":"> + <argument name="macroiftrue" required="true"> + <argument name="macroiftrue" required="true" /> + <argument name="arg1" multiple="true" /> + </argument> + <argument name="macroiffalse"> + <argument name="macroiffalse" required="true" /> + <argument name="arg1" multiple="true" /> + </argument> + </parameter> + </syntax> + <description> + <para>Executes macro defined in <replaceable>macroiftrue</replaceable> if + <replaceable>expr</replaceable> is true (otherwise <replaceable>macroiffalse</replaceable> + if provided)</para> + <para>Arguments and return values as in application Macro()</para> + </description> + <see-also> + <ref type="application">GotoIf</ref> + <ref type="application">GosubIf</ref> + <ref type="function">IF</ref> + </see-also> + </application> + <application name="MacroExclusive" language="en_US"> + <synopsis> + Exclusive Macro Implementation. + </synopsis> + <syntax> + <parameter name="name" required="true"> + <para>The name of the macro</para> + </parameter> + <parameter name="arg1" /> + <parameter name="arg2" multiple="true" /> + </syntax> + <description> + <para>Executes macro defined in the context macro-<replaceable>name</replaceable>. + Only one call at a time may run the macro. (we'll wait if another call is busy + executing in the Macro)</para> + <para>Arguments and return values as in application Macro()</para> + </description> + <see-also> + <ref type="application">Macro</ref> + </see-also> + </application> + <application name="MacroExit" language="en_US"> + <synopsis> + Exit from Macro. + </synopsis> + <syntax /> + <description> + <para>Causes the currently running macro to exit as if it had + ended normally by running out of priorities to execute. + If used outside a macro, will likely cause unexpected behavior.</para> + </description> + <see-also> + <ref type="application">Macro</ref> + </see-also> + </application> + ***/ + #define MAX_ARGS 80 /* special result value used to force macro exit */ #define MACRO_EXIT_RESULT 1024 -static char *descrip = -" Macro(macroname,arg1,arg2...): Executes a macro using the context\n" -"'macro-<macroname>', jumping to the 's' extension of that context and\n" -"executing each step, then returning when the steps end. \n" -"The calling extension, context, and priority are stored in ${MACRO_EXTEN}, \n" -"${MACRO_CONTEXT} and ${MACRO_PRIORITY} respectively. Arguments become\n" -"${ARG1}, ${ARG2}, etc in the macro context.\n" -"If you Goto out of the Macro context, the Macro will terminate and control\n" -"will be returned at the location of the Goto.\n" -"If ${MACRO_OFFSET} is set at termination, Macro will attempt to continue\n" -"at priority MACRO_OFFSET + N + 1 if such a step exists, and N + 1 otherwise.\n" -"Extensions: While a macro is being executed, it becomes the current context.\n" -" This means that if a hangup occurs, for instance, that the macro\n" -" will be searched for an 'h' extension, NOT the context from which\n" -" the macro was called. So, make sure to define all appropriate\n" -" extensions in your macro! (Note: AEL does not use macros)\n" -"WARNING: Because of the way Macro is implemented (it executes the priorities\n" -" contained within it via sub-engine), and a fixed per-thread\n" -" memory stack allowance, macros are limited to 7 levels\n" -" of nesting (macro calling macro calling macro, etc.); It\n" -" may be possible that stack-intensive applications in deeply nested macros\n" -" could cause asterisk to crash earlier than this limit. It is advised that\n" -" if you need to deeply nest macro calls, that you use the Gosub application\n" -" (now allows arguments like a Macro) with explict Return() calls instead.\n"; - -static char *if_descrip = -" MacroIf(<expr>?macroname_a[,arg1][:macroname_b[,arg1]])\n" -"Executes macro defined in <macroname_a> if <expr> is true\n" -"(otherwise <macroname_b> if provided)\n" -"Arguments and return values as in application Macro()\n"; - -static char *exclusive_descrip = -" MacroExclusive(macroname,arg1,arg2...):\n" -"Executes macro defined in the context 'macro-macroname'\n" -"Only one call at a time may run the macro.\n" -"(we'll wait if another call is busy executing in the Macro)\n" -"Arguments and return values as in application Macro()\n"; - -static char *exit_descrip = -" MacroExit():\n" -"Causes the currently running macro to exit as if it had\n" -"ended normally by running out of priorities to execute.\n" -"If used outside a macro, will likely cause unexpected\n" -"behavior.\n"; - static char *app = "Macro"; static char *if_app = "MacroIf"; static char *exclusive_app = "MacroExclusive"; static char *exit_app = "MacroExit"; -static char *synopsis = "Macro Implementation"; -static char *if_synopsis = "Conditional Macro Implementation"; -static char *exclusive_synopsis = "Exclusive Macro Implementation"; -static char *exit_synopsis = "Exit From Macro"; - - static struct ast_exten *find_matching_priority(struct ast_context *c, const char *exten, int priority, const char *callerid) { struct ast_exten *e; @@ -524,10 +581,10 @@ static int load_module(void) { int res; - res = ast_register_application(exit_app, macro_exit_exec, exit_synopsis, exit_descrip); - res |= ast_register_application(if_app, macroif_exec, if_synopsis, if_descrip); - res |= ast_register_application(exclusive_app, macroexclusive_exec, exclusive_synopsis, exclusive_descrip); - res |= ast_register_application(app, macro_exec, synopsis, descrip); + res = ast_register_application_xml(exit_app, macro_exit_exec); + res |= ast_register_application_xml(if_app, macroif_exec); + res |= ast_register_application_xml(exclusive_app, macroexclusive_exec); + res |= ast_register_application_xml(app, macro_exec); return res; }