From cd16b03cb1ee76308bdc03aaf315cfdb0a36c915 Mon Sep 17 00:00:00 2001 From: Chris Rienzo Date: Fri, 30 Aug 2013 18:17:43 -0400 Subject: [PATCH] mod_rayo: tweak to allow duplicate for SISR --- src/mod/event_handlers/mod_rayo/srgs.c | 30 +++++---- .../event_handlers/mod_rayo/test_srgs/main.c | 61 +++++++++++++++++++ 2 files changed, 78 insertions(+), 13 deletions(-) diff --git a/src/mod/event_handlers/mod_rayo/srgs.c b/src/mod/event_handlers/mod_rayo/srgs.c index 30c662724b..86cf825635 100644 --- a/src/mod/event_handlers/mod_rayo/srgs.c +++ b/src/mod/event_handlers/mod_rayo/srgs.c @@ -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 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; } diff --git a/src/mod/event_handlers/mod_rayo/test_srgs/main.c b/src/mod/event_handlers/mod_rayo/test_srgs/main.c index f97559297d..2a102e8939 100644 --- a/src/mod/event_handlers/mod_rayo/test_srgs/main.c +++ b/src/mod/event_handlers/mod_rayo/test_srgs/main.c @@ -65,6 +65,66 @@ static void test_match_adhearsion_menu_grammar(void) srgs_parser_destroy(parser); } +static const char *duplicate_tag_grammar = + "" + " \n" + " \n" + " 21\n" + " 25\n" + " 47\n" + " 49\n" + " \n" + " \n" + "\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 = "" @@ -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);