diff --git a/apps/app_macro.c b/apps/app_macro.c index 8fe59634ea..ce65bef25d 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 + + + Macro Implementation. + + + + The name of the macro + + + + + + + + Executes a macro using the context macro-name, + jumping to the s extension of that context and executing each step, + then returning when the steps end. + The calling extension, context, and priority are stored in MACRO_EXTEN, + MACRO_CONTEXT and MACRO_PRIORITY respectively. Arguments + become ARG1, ARG2, etc in the macro context. + If you Goto out of the Macro context, the Macro will terminate and control will be returned + at the location of the Goto. + If MACRO_OFFSET is set at termination, Macro will attempt to continue + at priority MACRO_OFFSET + N + 1 if such a step exists, and N + 1 otherwise. + 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 h 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) + 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. + + + MacroExit + Goto + Gosub + + + + + Conditional Macro implementation. + + + + + + + + + + + + + + + + Executes macro defined in macroiftrue if + expr is true (otherwise macroiffalse + if provided) + Arguments and return values as in application Macro() + + + GotoIf + GosubIf + IF + + + + + Exclusive Macro Implementation. + + + + The name of the macro + + + + + + Executes macro defined in the context macro-name. + Only one call at a time may run the macro. (we'll wait if another call is busy + executing in the Macro) + Arguments and return values as in application Macro() + + + Macro + + + + + Exit from Macro. + + + + 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. + + + Macro + + + ***/ + #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-', 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(?macroname_a[,arg1][:macroname_b[,arg1]])\n" -"Executes macro defined in if is true\n" -"(otherwise 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; }