Skip to content
Snippets Groups Projects
func_strings.c 68.1 KiB
Newer Older
  • Learn to ignore specific revisions
  • 	int i, res = AST_TEST_PASS;
    	struct ast_channel *chan;
    	struct ast_str *str;
    	char expression[256];
    	struct {
    		const char *test_string;
    		const char *find_chars;
    		const char *replace_char;
    		const char *expected;
    	} test_args[] = {
    		{"abc,def", "\\,", "-", "abc-def"},
    		{"abc,abc", "bc",  "a", "aaa,aaa"},
    		{"abc,def", "x",   "?", "abc,def"},
    		{"abc,def", "\\,", "",  "abcdef"}
    	};
    
    	switch (cmd) {
    	case TEST_INIT:
    		info->name = "func_REPLACE_test";
    		info->category = "/funcs/func_strings/";
    		info->summary = "Test REPLACE function";
    		info->description = "Verify REPLACE behavior";
    		return AST_TEST_NOT_RUN;
    	case TEST_EXECUTE:
    		break;
    	}
    
    	if (!(chan = ast_dummy_channel_alloc())) {
    		ast_test_status_update(test, "Unable to allocate dummy channel\n");
    		return AST_TEST_FAIL;
    	}
    
    	if (!(str = ast_str_create(16))) {
    		ast_test_status_update(test, "Unable to allocate dynamic string buffer\n");
    		ast_channel_release(chan);
    		return AST_TEST_FAIL;
    	}
    
    	for (i = 0; i < ARRAY_LEN(test_args); i++) {
    		struct ast_var_t *var = ast_var_assign("TEST_STRING", test_args[i].test_string);
    		if (!var) {
    			ast_test_status_update(test, "Out of memory\n");
    			res = AST_TEST_FAIL;
    			break;
    		}
    
    		AST_LIST_INSERT_HEAD(ast_channel_varshead(chan), var, entries);
    
    		snprintf(expression, sizeof(expression), "${REPLACE(%s,%s,%s)}", var->name, test_args[i].find_chars, test_args[i].replace_char);
    		ast_str_substitute_variables(&str, 0, chan, expression);
    
    		AST_LIST_REMOVE(ast_channel_varshead(chan), var, entries);
    		ast_var_delete(var);
    
    		if (strcasecmp(ast_str_buffer(str), test_args[i].expected)) {
    			ast_test_status_update(test, "Evaluation of '%s' returned '%s' instead of the expected value '%s'\n",
    				expression, ast_str_buffer(str), test_args[i].expected);
    			res = AST_TEST_FAIL;
    			break;
    		}
    	}
    
    	ast_free(str);
    	ast_channel_release(chan);
    
    	return res;
    }
    
    
    AST_TEST_DEFINE(test_FILTER)
    {
    	int i, res = AST_TEST_PASS;
    	const char *test_strings[][2] = {
    		{"A-R",            "DAHDI"},
    		{"A\\-R",          "A"},
    		{"\\x41-R",        "DAHDI"},
    		{"0-9A-Ca-c",      "0042133333A12212"},
    		{"0-9a-cA-C_+\\-", "0042133333A12212"},
    		{NULL,             NULL},
    	};
    
    	switch (cmd) {
    	case TEST_INIT:
    		info->name = "func_FILTER_test";
    
    		info->summary = "Test FILTER function";
    		info->description = "Verify FILTER behavior";
    		return AST_TEST_NOT_RUN;
    	case TEST_EXECUTE:
    		break;
    	}
    
    	for (i = 0; test_strings[i][0]; i++) {
    		char tmp[256], tmp2[256] = "";
    		snprintf(tmp, sizeof(tmp), "${FILTER(%s,0042133333&DAHDI/g1/2212)}", test_strings[i][0]);
    		pbx_substitute_variables_helper(NULL, tmp, tmp2, sizeof(tmp2) - 1);
    		if (strcmp(test_strings[i][1], tmp2)) {
    			ast_test_status_update(test, "Format string '%s' substituted to '%s'.  Expected '%s'.\n", test_strings[i][0], tmp2, test_strings[i][1]);
    			res = AST_TEST_FAIL;
    		}
    	}
    	return res;
    }
    
    Jonathan Rose's avatar
    Jonathan Rose committed
    
    AST_TEST_DEFINE(test_STRREPLACE)
    {
    	int i, res = AST_TEST_PASS;
    	struct ast_channel *chan; /* dummy channel */
    	struct ast_str *str; /* fancy string for holding comparing value */
    
    	const char *test_strings[][5] = {
    		{"Weasels have eaten my telephone system", "have eaten my", "are eating our", "", "Weasels are eating our telephone system"}, /*Test normal conditions */
    		{"Did you know twenty plus two is twenty-two?", "twenty", "thirty", NULL, "Did you know thirty plus two is thirty-two?"}, /* Test no third comma */
    
    		{"foofoofoofoofoofoofoo", "foofoo", "bar", NULL, "barbarbarfoo"}, /* Found string within previous match */
    
    Jonathan Rose's avatar
    Jonathan Rose committed
    		{"My pet dog once ate a dog who sat on a dog while eating a corndog.", "dog", "cat", "3", "My pet cat once ate a cat who sat on a cat while eating a corndog."},
    		{"One and one and one is three", "and", "plus", "1", "One plus one and one is three"}, /* Test <max-replacements> = 1*/
    		{"", "fhqwagads", "spelunker", NULL, ""}, /* Empty primary string */
    		{"Part of this string is missing.", "missing", NULL, NULL, "Part of this string is ."}, /* Empty replace string */
    		{"'Accidentally' left off a bunch of stuff.", NULL, NULL, NULL, ""}, /* Deliberate error test from too few args */
    		{"This test will also error.", "", "", "", ""}, /* Deliberate error test from blank find string */
    		{"This is an \"escape character\" test.", "\\\"escape character\\\"", "evil", NULL, "This is an evil test."}
    	};
    
    	switch (cmd) {
    	case TEST_INIT:
    		info->name = "func_STRREPLACE_test";
    		info->category = "/funcs/func_strings/";
    		info->summary = "Test STRREPLACE function";
    		info->description = "Verify STRREPLACE behavior";
    		return AST_TEST_NOT_RUN;
    	case TEST_EXECUTE:
    		break;
    	}
    
    	if (!(chan = ast_dummy_channel_alloc())) {
    		ast_test_status_update(test, "Unable to allocate dummy channel\n");
    		return AST_TEST_FAIL;
    	}
    
    	if (!(str = ast_str_create(64))) {
    		ast_test_status_update(test, "Unable to allocate dynamic string buffer\n");
    		ast_channel_release(chan);
    		return AST_TEST_FAIL;
    	}
    
    	for (i = 0; i < ARRAY_LEN(test_strings); i++) {
    		char tmp[512], tmp2[512] = "";
    
    		struct ast_var_t *var = ast_var_assign("test_string", test_strings[i][0]);
    
    		if (!var) {
    			ast_test_status_update(test, "Unable to allocate variable\n");
    			ast_free(str);
    			ast_channel_release(chan);
    			return AST_TEST_FAIL;
    		}
    
    		AST_LIST_INSERT_HEAD(ast_channel_varshead(chan), var, entries);
    
    Jonathan Rose's avatar
    Jonathan Rose committed
    
    		if (test_strings[i][3]) {
    			snprintf(tmp, sizeof(tmp), "${STRREPLACE(%s,%s,%s,%s)}", "test_string", test_strings[i][1], test_strings[i][2], test_strings[i][3]);
    		} else if (test_strings[i][2]) {
    			snprintf(tmp, sizeof(tmp), "${STRREPLACE(%s,%s,%s)}", "test_string", test_strings[i][1], test_strings[i][2]);
    		} else if (test_strings[i][1]) {
    			snprintf(tmp, sizeof(tmp), "${STRREPLACE(%s,%s)}", "test_string", test_strings[i][1]);
    		} else {
    			snprintf(tmp, sizeof(tmp), "${STRREPLACE(%s)}", "test_string");
    		}
    		ast_str_substitute_variables(&str, 0, chan, tmp);
    		if (strcmp(test_strings[i][4], ast_str_buffer(str))) {
    			ast_test_status_update(test, "Format string '%s' substituted to '%s'.  Expected '%s'.\n", test_strings[i][0], tmp2, test_strings[i][4]);
    			res = AST_TEST_FAIL;
    		}
    	}
    
    	ast_free(str);
    	ast_channel_release(chan);
    
    	return res;
    }
    
    
    AST_TEST_DEFINE(test_STRBETWEEN)
    {
    	int i, res = AST_TEST_PASS;
    	struct ast_channel *chan; /* dummy channel */
    	struct ast_str *str; /* fancy string for holding comparing value */
    
    	const char *test_strings[][5] = {
    		{"0", "w", "0"},
    		{"30", "w", "3w0"},
    		{"212", "w", "2w1w2"},
    		{"212", "55", "2551552"},
    		{"212", " ", "2 1 2"},
    		{"", "w", ""},
    		{"555", "", "555"},
    		{"abcdefg", "_", "a_b_c_d_e_f_g"},
    		{"A", "A", "A"},
    		{"AA", "B", "ABA"},
    		{"AAA", "B", "ABABA"},
    	};
    
    	switch (cmd) {
    	case TEST_INIT:
    		info->name = "func_STRBETWEEN";
    		info->category = "/funcs/func_strings/";
    		info->summary = "Test STRBETWEEN function";
    		info->description = "Verify STRBETWEEN behavior";
    		return AST_TEST_NOT_RUN;
    	case TEST_EXECUTE:
    		break;
    	}
    
    	if (!(chan = ast_dummy_channel_alloc())) {
    		ast_test_status_update(test, "Unable to allocate dummy channel\n");
    		return AST_TEST_FAIL;
    	}
    
    	if (!(str = ast_str_create(64))) {
    		ast_test_status_update(test, "Unable to allocate dynamic string buffer\n");
    		ast_channel_release(chan);
    		return AST_TEST_FAIL;
    	}
    
    	for (i = 0; i < ARRAY_LEN(test_strings); i++) {
    		char tmp[512], tmp2[512] = "";
    
    		struct ast_var_t *var = ast_var_assign("test_string", test_strings[i][0]);
    		if (!var) {
    			ast_test_status_update(test, "Unable to allocate variable\n");
    			ast_free(str);
    			ast_channel_release(chan);
    			return AST_TEST_FAIL;
    		}
    
    		AST_LIST_INSERT_HEAD(ast_channel_varshead(chan), var, entries);
    
    		if (test_strings[i][1]) {
    			snprintf(tmp, sizeof(tmp), "${STRBETWEEN(%s,%s)}", "test_string", test_strings[i][1]);
    		} else {
    			snprintf(tmp, sizeof(tmp), "${STRBETWEEN(%s)}", "test_string");
    		}
    		ast_str_substitute_variables(&str, 0, chan, tmp);
    		if (strcmp(test_strings[i][2], ast_str_buffer(str))) {
    			ast_test_status_update(test, "Format string '%s' substituted to '%s'.  Expected '%s'.\n", test_strings[i][0], tmp2, test_strings[i][2]);
    			res = AST_TEST_FAIL;
    		}
    	}
    
    	ast_free(str);
    	ast_channel_release(chan);
    
    	return res;
    }
    
    
    AST_TEST_DEFINE(test_TRIM)
    {
    	int i, res = AST_TEST_PASS;
    	struct ast_channel *chan; /* dummy channel */
    	struct ast_str *str; /* fancy string for holding comparing value */
    
    	const char *test_strings[][5] = {
    		{"TRIM", "  abcd ", "abcd"},
    		{"LTRIM", " abcd ", "abcd "},
    		{"RTRIM", " abcd ", " abcd"},
    		{"TRIM", "abcd", "abcd"},
    		{"TRIM", " a b c d ", "a b c d"},
    	};
    
    	switch (cmd) {
    	case TEST_INIT:
    		info->name = "func_TRIM";
    		info->category = "/funcs/func_strings/";
    		info->summary = "Test TRIM functions";
    		info->description = "Verify TRIM behavior";
    		return AST_TEST_NOT_RUN;
    	case TEST_EXECUTE:
    		break;
    	}
    
    	if (!(chan = ast_dummy_channel_alloc())) {
    		ast_test_status_update(test, "Unable to allocate dummy channel\n");
    		return AST_TEST_FAIL;
    	}
    
    	if (!(str = ast_str_create(64))) {
    		ast_test_status_update(test, "Unable to allocate dynamic string buffer\n");
    		ast_channel_release(chan);
    		return AST_TEST_FAIL;
    	}
    
    	for (i = 0; i < ARRAY_LEN(test_strings); i++) {
    		char tmp[512], tmp2[512] = "";
    
    		snprintf(tmp, sizeof(tmp), "${%s(%s)}", test_strings[i][0], test_strings[i][1]);
    		ast_str_substitute_variables(&str, 0, chan, tmp);
    		if (strcmp(test_strings[i][2], ast_str_buffer(str))) {
    			ast_test_status_update(test, "Format string '%s' substituted to '%s'.  Expected '%s'.\n", test_strings[i][0], tmp2, test_strings[i][2]);
    			res = AST_TEST_FAIL;
    		}
    	}
    
    	ast_free(str);
    	ast_channel_release(chan);
    
    	return res;
    }
    
    static int unload_module(void)
    
    	AST_TEST_UNREGISTER(test_FIELDNUM);
    
    	AST_TEST_UNREGISTER(test_REPLACE);
    
    	AST_TEST_UNREGISTER(test_FILTER);
    
    Jonathan Rose's avatar
    Jonathan Rose committed
    	AST_TEST_UNREGISTER(test_STRREPLACE);
    
    	AST_TEST_UNREGISTER(test_STRBETWEEN);
    
    	AST_TEST_UNREGISTER(test_TRIM);
    
    	res |= ast_custom_function_unregister(&fieldqty_function);
    
    	res |= ast_custom_function_unregister(&fieldnum_function);
    
    	res |= ast_custom_function_unregister(&filter_function);
    
    	res |= ast_custom_function_unregister(&replace_function);
    
    Jonathan Rose's avatar
    Jonathan Rose committed
    	res |= ast_custom_function_unregister(&strreplace_function);
    
    	res |= ast_custom_function_unregister(&strbetween_function);
    
    	res |= ast_custom_function_unregister(&listfilter_function);
    
    	res |= ast_custom_function_unregister(&regex_function);
    	res |= ast_custom_function_unregister(&array_function);
    
    	res |= ast_custom_function_unregister(&quote_function);
    
    	res |= ast_custom_function_unregister(&csv_quote_function);
    
    	res |= ast_custom_function_unregister(&len_function);
    	res |= ast_custom_function_unregister(&strftime_function);
    	res |= ast_custom_function_unregister(&strptime_function);
    	res |= ast_custom_function_unregister(&eval_function);
    
    	res |= ast_custom_function_unregister(&keypadhash_function);
    
    	res |= ast_custom_function_unregister(&hashkeys_function);
    	res |= ast_custom_function_unregister(&hash_function);
    	res |= ast_unregister_application(app_clearhash);
    
    	res |= ast_custom_function_unregister(&toupper_function);
    	res |= ast_custom_function_unregister(&tolower_function);
    
    	res |= ast_custom_function_unregister(&shift_function);
    	res |= ast_custom_function_unregister(&pop_function);
    	res |= ast_custom_function_unregister(&push_function);
    	res |= ast_custom_function_unregister(&unshift_function);
    
    	res |= ast_custom_function_unregister(&passthru_function);
    
    	res |= ast_custom_function_unregister(&trim_function);
    	res |= ast_custom_function_unregister(&ltrim_function);
    	res |= ast_custom_function_unregister(&rtrim_function);
    
    static int load_module(void)
    
    	AST_TEST_REGISTER(test_FIELDNUM);
    
    	AST_TEST_REGISTER(test_FILTER);
    
    Jonathan Rose's avatar
    Jonathan Rose committed
    	AST_TEST_REGISTER(test_STRREPLACE);
    
    	AST_TEST_REGISTER(test_STRBETWEEN);
    
    	AST_TEST_REGISTER(test_TRIM);
    
    	res |= ast_custom_function_register(&fieldqty_function);
    
    	res |= ast_custom_function_register(&fieldnum_function);
    
    	res |= ast_custom_function_register(&filter_function);
    
    	res |= ast_custom_function_register(&replace_function);
    
    Jonathan Rose's avatar
    Jonathan Rose committed
    	res |= ast_custom_function_register(&strreplace_function);
    
    	res |= ast_custom_function_register(&strbetween_function);
    
    	res |= ast_custom_function_register(&listfilter_function);
    
    	res |= ast_custom_function_register(&regex_function);
    	res |= ast_custom_function_register(&array_function);
    
    	res |= ast_custom_function_register(&quote_function);
    
    	res |= ast_custom_function_register(&csv_quote_function);
    
    	res |= ast_custom_function_register(&len_function);
    	res |= ast_custom_function_register(&strftime_function);
    	res |= ast_custom_function_register(&strptime_function);
    	res |= ast_custom_function_register(&eval_function);
    
    	res |= ast_custom_function_register(&keypadhash_function);
    
    	res |= ast_custom_function_register(&hashkeys_function);
    	res |= ast_custom_function_register(&hash_function);
    
    	res |= ast_register_application_xml(app_clearhash, exec_clearhash);
    
    	res |= ast_custom_function_register(&toupper_function);
    	res |= ast_custom_function_register(&tolower_function);
    
    	res |= ast_custom_function_register(&shift_function);
    	res |= ast_custom_function_register(&pop_function);
    	res |= ast_custom_function_register(&push_function);
    	res |= ast_custom_function_register(&unshift_function);
    
    	res |= ast_custom_function_register(&passthru_function);
    
    	res |= ast_custom_function_register(&trim_function);
    	res |= ast_custom_function_register(&ltrim_function);
    	res |= ast_custom_function_register(&rtrim_function);
    
    AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "String handling dialplan functions");