]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
mod_rayo: tweak to allow duplicate <tag> for SISR
authorChris Rienzo <chris.rienzo@grasshopper.com>
Fri, 30 Aug 2013 22:17:43 +0000 (18:17 -0400)
committerChris Rienzo <chris.rienzo@grasshopper.com>
Fri, 30 Aug 2013 22:17:43 +0000 (18:17 -0400)
src/mod/event_handlers/mod_rayo/srgs.c
src/mod/event_handlers/mod_rayo/test_srgs/main.c

index 30c662724b381dc780162b557ccd0ffdb250a853..86cf825635e23507b11b8b0e61f42302354f2f68 100644 (file)
@@ -112,7 +112,7 @@ struct item_value {
        int repeat_min;
        int repeat_max;
        const char *weight;
-       char *tag;
+       int tag;
 };
 
 /**
@@ -164,7 +164,7 @@ struct srgs_grammar {
        /** rule names mapped to node */
        switch_hash_t *rules;
        /** possible matching tags */
-       const char *tags[MAX_TAGS];
+       const char *tags[MAX_TAGS + 1];
        /** number of tags */
        int tag_count;
        /** grammar encoding */
@@ -725,11 +725,13 @@ static int process_cdata_tag(struct srgs_grammar *grammar, char *data, size_t le
 {
        struct srgs_node *item = grammar->cur->parent;
        if (item && item->type == SNT_ITEM) {
-               item->value.item.tag = switch_core_alloc(grammar->pool, sizeof(char) * (len + 1));
-               item->value.item.tag[len] = '\0';
-               strncpy(item->value.item.tag, data, len);
                if (grammar->tag_count < MAX_TAGS) {
-                       grammar->tags[grammar->tag_count++] = item->value.item.tag;
+                       /* grammar gets the tag name, item gets the unique tag number */
+                       char *tag = switch_core_alloc(grammar->pool, sizeof(char) * (len + 1));
+                       tag[len] = '\0';
+                       strncpy(tag, data, len);
+                       grammar->tags[++grammar->tag_count] = tag;
+                       item->value.item.tag = grammar->tag_count;
                } else {
                        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "too many <tag>s\n");
                        return IKS_BADXML;
@@ -986,11 +988,11 @@ static int create_regexes(struct srgs_grammar *grammar, struct srgs_node *node,
                case SNT_ITEM:
                        if (node->child) {
                                struct srgs_node *item = node->child;
-                               if (node->value.item.repeat_min != 1 || node->value.item.repeat_max != 1 || !zstr(node->value.item.tag)) {
-                                       if (zstr(node->value.item.tag)) {
-                                               stream->write_function(stream, "%s", "(?:");
+                               if (node->value.item.repeat_min != 1 || node->value.item.repeat_max != 1 || node->value.item.tag) {
+                                       if (node->value.item.tag) {
+                                               stream->write_function(stream, "(?P<%d>", node->value.item.tag);
                                        } else {
-                                               stream->write_function(stream, "(?P<%s>", node->value.item.tag);
+                                               stream->write_function(stream, "%s", "(?:");
                                        }
                                }
                                for(; item; item = item->next) {
@@ -1014,7 +1016,7 @@ static int create_regexes(struct srgs_grammar *grammar, struct srgs_node *node,
                                        } else {
                                                stream->write_function(stream, "){%i}", node->value.item.repeat_min);
                                        }
-                               } else if (!zstr(node->value.item.tag)) {
+                               } else if (node->value.item.tag) {
                                        stream->write_function(stream, "%s", ")");
                                }
                        }
@@ -1282,9 +1284,11 @@ enum srgs_match_type srgs_grammar_match(struct srgs_grammar *grammar, const char
                buffer[MAX_INPUT_SIZE] = '\0';
 
                /* find matching instance... */
-               for (i = 0; i < grammar->tag_count; i++) {
+               for (i = 1; i <= grammar->tag_count; i++) {
+                       char substring_name[16] = { 0 };
                        buffer[0] = '\0';
-                       if (pcre_copy_named_substring(compiled_regex, input, ovector, result, grammar->tags[i], buffer, MAX_INPUT_SIZE) != PCRE_ERROR_NOSUBSTRING && !zstr_buf(buffer)) {
+                       snprintf(substring_name, 16, "%d", i);
+                       if (pcre_copy_named_substring(compiled_regex, input, ovector, result, substring_name, buffer, MAX_INPUT_SIZE) != PCRE_ERROR_NOSUBSTRING && !zstr_buf(buffer)) {
                                *interpretation = grammar->tags[i];
                                break;
                        }
index f97559297df4f6d064d9377468c1674e6fe27d79..2a102e89396ab045741b81df1a4890b46f379ee7 100644 (file)
@@ -65,6 +65,66 @@ static void test_match_adhearsion_menu_grammar(void)
        srgs_parser_destroy(parser);
 }
 
+static const char *duplicate_tag_grammar =
+       "<grammar xmlns=\"http://www.w3.org/2001/06/grammar\" version=\"1.0\" xml:lang=\"en-US\" mode=\"dtmf\" root=\"options\" tag-format=\"semantics/1.0-literals\">"
+       "  <rule id=\"options\" scope=\"public\">\n"
+       "    <one-of>\n"
+       "      <item><tag>2</tag>1</item>\n"
+       "      <item><tag>2</tag>5</item>\n"
+       "      <item><tag>4</tag>7</item>\n"
+       "      <item><tag>4</tag>9</item>\n"
+       "    </one-of>\n"
+       "  </rule>\n"
+       "</grammar>\n";
+
+/**
+ * Test matching with duplicate tags
+ */
+static void test_match_duplicate_tag_grammar(void)
+{
+       struct srgs_parser *parser;
+       struct srgs_grammar *grammar;
+       const char *interpretation;
+
+       parser = srgs_parser_new("1234");
+       ASSERT_NOT_NULL((grammar = srgs_parse(parser, duplicate_tag_grammar)));
+
+       ASSERT_EQUALS(SMT_NO_MATCH, srgs_grammar_match(grammar, "0", &interpretation));
+       ASSERT_NULL(interpretation);
+       ASSERT_EQUALS(SMT_MATCH_END, srgs_grammar_match(grammar, "1", &interpretation));
+       ASSERT_STRING_EQUALS("2", interpretation);
+       ASSERT_EQUALS(SMT_NO_MATCH, srgs_grammar_match(grammar, "2", &interpretation));
+       ASSERT_NULL(interpretation);
+       ASSERT_EQUALS(SMT_NO_MATCH, srgs_grammar_match(grammar, "3", &interpretation));
+       ASSERT_NULL(interpretation);
+       ASSERT_EQUALS(SMT_NO_MATCH, srgs_grammar_match(grammar, "4", &interpretation));
+       ASSERT_NULL(interpretation);
+       ASSERT_EQUALS(SMT_MATCH_END, srgs_grammar_match(grammar, "5", &interpretation));
+       ASSERT_STRING_EQUALS("2", interpretation);
+       ASSERT_EQUALS(SMT_NO_MATCH, srgs_grammar_match(grammar, "6", &interpretation));
+       ASSERT_NULL(interpretation);
+       ASSERT_EQUALS(SMT_MATCH_END, srgs_grammar_match(grammar, "7", &interpretation));
+       ASSERT_STRING_EQUALS("4", interpretation);
+       ASSERT_EQUALS(SMT_NO_MATCH, srgs_grammar_match(grammar, "8", &interpretation));
+       ASSERT_NULL(interpretation);
+       ASSERT_EQUALS(SMT_MATCH_END, srgs_grammar_match(grammar, "9", &interpretation));
+       ASSERT_STRING_EQUALS("4", interpretation);
+       ASSERT_EQUALS(SMT_NO_MATCH, srgs_grammar_match(grammar, "#", &interpretation));
+       ASSERT_NULL(interpretation);
+       ASSERT_EQUALS(SMT_NO_MATCH, srgs_grammar_match(grammar, "*", &interpretation));
+       ASSERT_NULL(interpretation);
+       ASSERT_EQUALS(SMT_NO_MATCH, srgs_grammar_match(grammar, "A", &interpretation));
+       ASSERT_NULL(interpretation);
+       ASSERT_EQUALS(SMT_NO_MATCH, srgs_grammar_match(grammar, "27", &interpretation));
+       ASSERT_NULL(interpretation);
+       ASSERT_EQUALS(SMT_NO_MATCH, srgs_grammar_match(grammar, "223", &interpretation));
+       ASSERT_NULL(interpretation);
+       ASSERT_EQUALS(SMT_NO_MATCH, srgs_grammar_match(grammar, "0123456789*#", &interpretation));
+       ASSERT_NULL(interpretation);
+
+       srgs_parser_destroy(parser);
+}
+
 
 static const char *adhearsion_ask_grammar =
        "<grammar xmlns=\"http://www.w3.org/2001/06/grammar\" version=\"1.0\" xml:lang=\"en-US\" mode=\"dtmf\" root=\"inputdigits\">"
@@ -1025,6 +1085,7 @@ int main(int argc, char **argv)
        srgs_init();
        TEST(test_parse_grammar);
        TEST(test_match_adhearsion_menu_grammar);
+       TEST(test_match_duplicate_tag_grammar);
        TEST(test_match_adhearsion_ask_grammar);
        TEST(test_match_multi_digit_grammar);
        TEST(test_match_multi_rule_grammar);