These changes:
authorSteve Murphy <murf@digium.com>
Tue, 15 Apr 2008 19:59:50 +0000 (19:59 +0000)
committerSteve Murphy <murf@digium.com>
Tue, 15 Apr 2008 19:59:50 +0000 (19:59 +0000)
   a. fix a self-found problem with SPAWN-ing an extension,
      where matches were not being found
   b. correct some wording in a comment
   c. Add some debug for future debugging.

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@114146 65c4cc65-6c06-0410-ace0-fbb531ad65f3

main/pbx.c

index 25a4dbd..7a8923f 100644 (file)
@@ -1001,25 +1001,49 @@ static struct ast_exten *trie_find_next_match(struct match_char *node)
        return NULL;
 }
 
+#ifdef DEBUG_THIS
+static char *action2str(enum ext_match_t action)
+{
+       switch(action)
+       {
+       case E_MATCH:
+               return "MATCH";
+       case E_CANMATCH:
+               return "CANMATCH";
+       case E_MATCHMORE:
+               return "MATCHMORE";
+       case E_FINDLABEL:
+               return "FINDLABEL";
+       case E_SPAWN:
+               return "SPAWN";
+       default:
+               return "?ACTION?";
+       }
+}
+
+#endif
+
 static void new_find_extension(const char *str, struct scoreboard *score, struct match_char *tree, int length, int spec, const char *callerid, enum ext_match_t action)
 {
        struct match_char *p; /* note minimal stack storage requirements */
 #ifdef DEBUG_THIS
        if (tree)
-               ast_log(LOG_NOTICE,"new_find_extension called with %s on (sub)tree %s\n", str, tree->x);
+               ast_log(LOG_NOTICE,"new_find_extension called with %s on (sub)tree %s action=%s\n", str, tree->x, action2str(action));
        else
-               ast_log(LOG_NOTICE,"new_find_extension called with %s on (sub)tree NULL\n", str);
+               ast_log(LOG_NOTICE,"new_find_extension called with %s on (sub)tree NULL action=%s\n", str, action2str(action));
 #endif
        for (p=tree; p; p=p->alt_char) {
                if (p->x[0] == 'N') {
                        if (p->x[1] == 0 && *str >= '2' && *str <= '9' ) {
 #define NEW_MATCHER_CHK_MATCH         \
-                               if (p->exten && !(*(str+1))) { /* if a shorter pattern matches along the way, might as well report it */ \
-                                       if (action == E_MATCH) { /* if in CANMATCH/MATCHMORE, don't let matches get in the way */            \
-                                               update_scoreboard(score, length+1, spec+p->specificity, p->exten,0,callerid, p->deleted, p);     \
-                                               if (!p->deleted)                                                                                                                 \
-                                                       return; /* the first match, by definition, will be the best, because of the sorted tree */   \
-                                       }                                                                                                    \
+                               if (p->exten && !(*(str+1))) { /* if a shorter pattern matches along the way, might as well report it */             \
+                                       if (action == E_MATCH || action == E_SPAWN) { /* if in CANMATCH/MATCHMORE, don't let matches get in the way */   \
+                                               update_scoreboard(score, length+1, spec+p->specificity, p->exten,0,callerid, p->deleted, p);                 \
+                                               if (!p->deleted) {                                                                                           \
+                                                       ast_debug(4,"returning an exact match-- first found-- %s\n", p->exten->exten);                           \
+                                                       return; /* the first match, by definition, will be the best, because of the sorted tree */               \
+                                               }                                                                                                            \
+                                       }                                                                                                                \
                                }
                                
 #define NEW_MATCHER_RECURSE               \
@@ -1027,18 +1051,25 @@ static void new_find_extension(const char *str, struct scoreboard *score, struct
                                                || p->next_char->x[0] == '!')) {                                          \
                                        if (*(str+1) || p->next_char->x[0] == '!') {                                                         \
                                                new_find_extension(str+1, score, p->next_char, length+1, spec+p->specificity, callerid, action); \
-                                               if (score->exten)                                                                                \
+                                               if (score->exten)  {                                                                             \
+                                               ast_debug(4,"returning an exact match-- %s\n", score->exten->exten);                         \
                                                        return; /* the first match is all we need */                                                 \
+                                               }                                                                                                                                                \
                                        } else {                                                                                             \
                                                new_find_extension("/", score, p->next_char, length+1, spec+p->specificity, callerid, action);   \
-                                               if (score->exten || ((action == E_CANMATCH || action == E_MATCHMORE) && score->canmatch))        \
+                                               if (score->exten || ((action == E_CANMATCH || action == E_MATCHMORE) && score->canmatch)) {      \
+                                               ast_debug(4,"returning a (can/more) match--- %s\n", score->exten ? score->exten->exten :     \
+                                       "NULL");                                                                        \
                                                        return; /* the first match is all we need */                                                 \
+                                               }                                                                                                                                                \
                                        }                                                                                                    \
                                } else if (p->next_char && !*(str+1)) {                                                                  \
                                        score->canmatch = 1;                                                                                 \
                                        score->canmatch_exten = get_canmatch_exten(p);                                                       \
-                                       if (action == E_CANMATCH || action == E_MATCHMORE)                                                   \
+                                       if (action == E_CANMATCH || action == E_MATCHMORE) {                                                 \
+                                       ast_debug(4,"returning a canmatch/matchmore--- str=%s\n", str);                                  \
                                                return;                                                                                          \
+                                       }                                                                                                                                                    \
                                }
                                
                                NEW_MATCHER_CHK_MATCH;
@@ -1064,13 +1095,17 @@ static void new_find_extension(const char *str, struct scoreboard *score, struct
                        }
                        if (p->exten && *str2 != '/') {
                                update_scoreboard(score, length+i, spec+(i*p->specificity), p->exten, '.', callerid, p->deleted, p);
-                               if (score->exten)                                                                               \
-                                       return; /* the first match is all we need */            \
+                               if (score->exten) {
+                                       ast_debug(4,"return because scoreboard has a match with '/'--- %s\n", score->exten->exten);
+                                       return; /* the first match is all we need */
+                               }
                        }
                        if (p->next_char && p->next_char->x[0] == '/' && p->next_char->x[1] == 0) {
                                new_find_extension("/", score, p->next_char, length+i, spec+(p->specificity*i), callerid, action);
-                               if (score->exten || ((action == E_CANMATCH || action == E_MATCHMORE) && score->canmatch))
+                               if (score->exten || ((action == E_CANMATCH || action == E_MATCHMORE) && score->canmatch)) {
+                                       ast_debug(4,"return because scoreboard has exact match OR CANMATCH/MATCHMORE & canmatch set--- %s\n", score->exten ? score->exten->exten : "NULL");
                                        return; /* the first match is all we need */
+                               }
                        }
                } else if (p->x[0] == '!' && p->x[1] == 0) {
                        /* how many chars will the . match against? */
@@ -1082,26 +1117,33 @@ static void new_find_extension(const char *str, struct scoreboard *score, struct
                        }
                        if (p->exten && *str2 != '/') {
                                update_scoreboard(score, length+1, spec+(p->specificity*i), p->exten, '!', callerid, p->deleted, p);
-                               if (score->exten)                                                                               \
-                                       return; /* the first match is all we need */            \
+                               if (score->exten) {
+                                       ast_debug(4,"return because scoreboard has a '!' match--- %s\n", score->exten->exten);
+                                       return; /* the first match is all we need */
+                               }
                        }
                        if (p->next_char && p->next_char->x[0] == '/' && p->next_char->x[1] == 0) {
                                new_find_extension("/", score, p->next_char, length+i, spec+(p->specificity*i), callerid, action);
-                               if (score->exten || ((action == E_CANMATCH || action == E_MATCHMORE) && score->canmatch))
+                               if (score->exten || ((action == E_CANMATCH || action == E_MATCHMORE) && score->canmatch)) {
+                                       ast_debug(4,"return because scoreboard has exact match OR CANMATCH/MATCHMORE & canmatch set with '/' and '!'--- %s\n", score->exten ? score->exten->exten : "NULL");
                                        return; /* the first match is all we need */
+                               }
                        }
                } else if (p->x[0] == '/' && p->x[1] == 0) {
                        /* the pattern in the tree includes the cid match! */
                        if (p->next_char && callerid && *callerid) {
                                new_find_extension(callerid, score, p->next_char, length+1, spec, callerid, action);
-                               if (score->exten || ((action == E_CANMATCH || action == E_MATCHMORE) && score->canmatch))
+                               if (score->exten || ((action == E_CANMATCH || action == E_MATCHMORE) && score->canmatch)) {
+                                       ast_debug(4,"return because scoreboard has exact match OR CANMATCH/MATCHMORE & canmatch set with '/'--- %s\n", score->exten ? score->exten->exten : "NULL");
                                        return; /* the first match is all we need */
+                               }
                        }
                } else if (index(p->x, *str)) {
                        NEW_MATCHER_CHK_MATCH;
                        NEW_MATCHER_RECURSE;
                }
        }
+       ast_debug(4,"return at end of func\n");
 }
 
 /* the algorithm for forming the extension pattern tree is also a bit simple; you 
@@ -1117,7 +1159,8 @@ static void new_find_extension(const char *str, struct scoreboard *score, struct
  *
  * I guess forming this pattern tree would be analogous to compiling a regex. Except
  * that a regex only handles 1 pattern, really. This trie holds any number
- * of patterns.
+ * of patterns. Well, really, it **could** be considered a single pattern,
+ * where the "|" (or) operator is allowed, I guess, in a way, sort of...
  */
 
 static struct match_char *already_in_tree(struct match_char *current, char *pat)