Added a warning to the documentation for Macro in response to bug 7776
[asterisk/asterisk.git] / apps / app_macro.c
index 42b32dd..c35208f 100644 (file)
@@ -60,7 +60,15 @@ static char *descrip =
 "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"
 "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";
+"at priority MACRO_OFFSET + N + 1 if such a step exists, and N + 1 otherwise.\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"
 
 static char *if_descrip =
 "  MacroIf(<expr>?macroname_a[|arg1][:macroname_b[|arg1]])\n"
@@ -164,7 +172,8 @@ static int _macro_exec(struct ast_channel *chan, void *data, int exclusive)
 
        /* If we are to run the macro exclusively, take the mutex */
        if (exclusive) {
 
        /* If we are to run the macro exclusively, take the mutex */
        if (exclusive) {
-               ast_log(LOG_DEBUG, "Locking macrolock for '%s'\n", fullmacro);
+               if (option_debug)
+                       ast_log(LOG_DEBUG, "Locking macrolock for '%s'\n", fullmacro);
                ast_autoservice_start(chan);
                if (ast_context_lockmacro(fullmacro)) {
                        ast_log(LOG_WARNING, "Failed to lock macro '%s' as in-use\n", fullmacro);
                ast_autoservice_start(chan);
                if (ast_context_lockmacro(fullmacro)) {
                        ast_log(LOG_WARNING, "Failed to lock macro '%s' as in-use\n", fullmacro);
@@ -228,7 +237,8 @@ static int _macro_exec(struct ast_channel *chan, void *data, int exclusive)
                        if (((res >= '0') && (res <= '9')) || ((res >= 'A') && (res <= 'F')) ||
                        (res == '*') || (res == '#')) {
                                /* Just return result as to the previous application as if it had been dialed */
                        if (((res >= '0') && (res <= '9')) || ((res >= 'A') && (res <= 'F')) ||
                        (res == '*') || (res == '#')) {
                                /* Just return result as to the previous application as if it had been dialed */
-                               ast_log(LOG_DEBUG, "Oooh, got something to jump out with ('%c')!\n", res);
+                               if (option_debug)
+                                       ast_log(LOG_DEBUG, "Oooh, got something to jump out with ('%c')!\n", res);
                                break;
                        }
                        switch(res) {
                                break;
                        }
                        switch(res) {
@@ -238,14 +248,14 @@ static int _macro_exec(struct ast_channel *chan, void *data, int exclusive)
                        case AST_PBX_KEEPALIVE:
                                if (option_debug)
                                        ast_log(LOG_DEBUG, "Spawn extension (%s,%s,%d) exited KEEPALIVE in macro %s on '%s'\n", chan->context, chan->exten, chan->priority, macro, chan->name);
                        case AST_PBX_KEEPALIVE:
                                if (option_debug)
                                        ast_log(LOG_DEBUG, "Spawn extension (%s,%s,%d) exited KEEPALIVE in macro %s on '%s'\n", chan->context, chan->exten, chan->priority, macro, chan->name);
-                               if (option_verbose > 1)
+                               else if (option_verbose > 1)
                                        ast_verbose( VERBOSE_PREFIX_2 "Spawn extension (%s, %s, %d) exited KEEPALIVE in macro '%s' on '%s'\n", chan->context, chan->exten, chan->priority, macro, chan->name);
                                goto out;
                                break;
                        default:
                                if (option_debug)
                                        ast_log(LOG_DEBUG, "Spawn extension (%s,%s,%d) exited non-zero on '%s' in macro '%s'\n", chan->context, chan->exten, chan->priority, chan->name, macro);
                                        ast_verbose( VERBOSE_PREFIX_2 "Spawn extension (%s, %s, %d) exited KEEPALIVE in macro '%s' on '%s'\n", chan->context, chan->exten, chan->priority, macro, chan->name);
                                goto out;
                                break;
                        default:
                                if (option_debug)
                                        ast_log(LOG_DEBUG, "Spawn extension (%s,%s,%d) exited non-zero on '%s' in macro '%s'\n", chan->context, chan->exten, chan->priority, chan->name, macro);
-                               if (option_verbose > 1)
+                               else if (option_verbose > 1)
                                        ast_verbose( VERBOSE_PREFIX_2 "Spawn extension (%s, %s, %d) exited non-zero on '%s' in macro '%s'\n", chan->context, chan->exten, chan->priority, chan->name, macro);
                                dead = 1;
                                goto out;
                                        ast_verbose( VERBOSE_PREFIX_2 "Spawn extension (%s, %s, %d) exited non-zero on '%s' in macro '%s'\n", chan->context, chan->exten, chan->priority, chan->name, macro);
                                dead = 1;
                                goto out;
@@ -258,8 +268,9 @@ static int _macro_exec(struct ast_channel *chan, void *data, int exclusive)
                }
                /* don't stop executing extensions when we're in "h" */
                if (chan->_softhangup && strcasecmp(oldexten,"h") && strcasecmp(chan->macroexten,"h")) {
                }
                /* don't stop executing extensions when we're in "h" */
                if (chan->_softhangup && strcasecmp(oldexten,"h") && strcasecmp(chan->macroexten,"h")) {
-                       ast_log(LOG_DEBUG, "Extension %s, macroexten %s, priority %d returned normally even though call was hung up\n",
-                               chan->exten, chan->macroexten, chan->priority);
+                       if (option_debug)
+                               ast_log(LOG_DEBUG, "Extension %s, macroexten %s, priority %d returned normally even though call was hung up\n",
+                                       chan->exten, chan->macroexten, chan->priority);
                        goto out;
                }
                chan->priority++;
                        goto out;
                }
                chan->priority++;
@@ -330,7 +341,8 @@ static int _macro_exec(struct ast_channel *chan, void *data, int exclusive)
 
        /* Unlock the macro */
        if (exclusive) {
 
        /* Unlock the macro */
        if (exclusive) {
-               ast_log(LOG_DEBUG, "Unlocking macrolock for '%s'\n", fullmacro);
+               if (option_debug)
+                       ast_log(LOG_DEBUG, "Unlocking macrolock for '%s'\n", fullmacro);
                if (ast_context_unlockmacro(fullmacro)) {
                        ast_log(LOG_ERROR, "Failed to unlock macro '%s' - that isn't good\n", fullmacro);
                        res = 0;
                if (ast_context_unlockmacro(fullmacro)) {
                        ast_log(LOG_ERROR, "Failed to unlock macro '%s' - that isn't good\n", fullmacro);
                        res = 0;