mirror of
https://github.com/asterisk/asterisk.git
synced 2025-10-12 15:45:18 +00:00
Merge "sorcery/res_pjsip: Refactor for realtime performance" into 13
This commit is contained in:
@@ -723,6 +723,96 @@ const char *ast_variable_find(const struct ast_category *category, const char *v
|
||||
return ast_variable_find_in_list(category->root, variable);
|
||||
}
|
||||
|
||||
const struct ast_variable *ast_variable_find_variable_in_list(const struct ast_variable *list, const char *variable_name)
|
||||
{
|
||||
const struct ast_variable *v;
|
||||
|
||||
for (v = list; v; v = v->next) {
|
||||
if (!strcasecmp(variable_name, v->name)) {
|
||||
return v;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int ast_variables_match(const struct ast_variable *left, const struct ast_variable *right)
|
||||
{
|
||||
char *op;
|
||||
|
||||
if (left == right) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!(left && right)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
op = strrchr(right->name, ' ');
|
||||
if (op) {
|
||||
op++;
|
||||
}
|
||||
|
||||
return ast_strings_match(left->value, op ? ast_strdupa(op) : NULL, right->value);
|
||||
}
|
||||
|
||||
int ast_variable_lists_match(const struct ast_variable *left, const struct ast_variable *right, int exact_match)
|
||||
{
|
||||
const struct ast_variable *field;
|
||||
int right_count = 0;
|
||||
int left_count = 0;
|
||||
|
||||
if (left == right) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!(left && right)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (field = right; field; field = field->next) {
|
||||
char *space = strrchr(field->name, ' ');
|
||||
const struct ast_variable *old;
|
||||
char * name = (char *)field->name;
|
||||
|
||||
if (space) {
|
||||
name = ast_strdup(field->name);
|
||||
if (!name) {
|
||||
return 0;
|
||||
}
|
||||
name[space - field->name] = '\0';
|
||||
}
|
||||
|
||||
old = ast_variable_find_variable_in_list(left, name);
|
||||
if (name != field->name) {
|
||||
ast_free(name);
|
||||
}
|
||||
|
||||
if (exact_match) {
|
||||
if (!old || strcmp(old->value, field->value)) {
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
if (!ast_variables_match(old, field)) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
right_count++;
|
||||
}
|
||||
|
||||
if (exact_match) {
|
||||
for (field = left; field; field = field->next) {
|
||||
left_count++;
|
||||
}
|
||||
|
||||
if (right_count != left_count) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
const char *ast_variable_find_in_list(const struct ast_variable *list, const char *variable)
|
||||
{
|
||||
const struct ast_variable *v;
|
||||
|
127
main/strings.c
127
main/strings.c
@@ -39,6 +39,7 @@
|
||||
|
||||
ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
|
||||
|
||||
#include <regex.h>
|
||||
#include "asterisk/strings.h"
|
||||
#include "asterisk/pbx.h"
|
||||
|
||||
@@ -228,3 +229,129 @@ char *ast_generate_random_string(char *buf, size_t size)
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
int ast_strings_match(const char *left, const char *op, const char *right)
|
||||
{
|
||||
char *internal_op = (char *)op;
|
||||
char *internal_right = (char *)right;
|
||||
float left_num;
|
||||
float right_num;
|
||||
int scan_numeric = 0;
|
||||
|
||||
if (!(left && right)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ast_strlen_zero(op)) {
|
||||
if (ast_strlen_zero(left) && ast_strlen_zero(right)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (strlen(right) >= 2 && right[0] == '/' && right[strlen(right) - 1] == '/') {
|
||||
internal_op = "regex";
|
||||
internal_right = ast_strdupa(right);
|
||||
/* strip the leading and trailing '/' */
|
||||
internal_right++;
|
||||
internal_right[strlen(internal_right) - 1] = '\0';
|
||||
goto regex;
|
||||
} else {
|
||||
internal_op = "=";
|
||||
goto equals;
|
||||
}
|
||||
}
|
||||
|
||||
if (!strcasecmp(op, "like")) {
|
||||
char *tok;
|
||||
struct ast_str *buffer = ast_str_alloca(128);
|
||||
|
||||
if (!strchr(right, '%')) {
|
||||
return !strcmp(left, right);
|
||||
} else {
|
||||
internal_op = "regex";
|
||||
internal_right = ast_strdupa(right);
|
||||
tok = strsep(&internal_right, "%");
|
||||
ast_str_set(&buffer, 0, "^%s", tok);
|
||||
|
||||
while ((tok = strsep(&internal_right, "%"))) {
|
||||
ast_str_append(&buffer, 0, ".*%s", tok);
|
||||
}
|
||||
ast_str_append(&buffer, 0, "%s", "$");
|
||||
|
||||
internal_right = ast_str_buffer(buffer);
|
||||
/* fall through to regex */
|
||||
}
|
||||
}
|
||||
|
||||
regex:
|
||||
if (!strcasecmp(internal_op, "regex")) {
|
||||
regex_t expression;
|
||||
int rc;
|
||||
|
||||
if (regcomp(&expression, internal_right, REG_EXTENDED | REG_NOSUB)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
rc = regexec(&expression, left, 0, NULL, 0);
|
||||
regfree(&expression);
|
||||
return !rc;
|
||||
}
|
||||
|
||||
equals:
|
||||
scan_numeric = (sscanf(left, "%f", &left_num) && sscanf(internal_right, "%f", &right_num));
|
||||
|
||||
if (internal_op[0] == '=') {
|
||||
if (ast_strlen_zero(left) && ast_strlen_zero(internal_right)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (scan_numeric) {
|
||||
return (left_num == right_num);
|
||||
} else {
|
||||
return (!strcmp(left, internal_right));
|
||||
}
|
||||
}
|
||||
|
||||
if (internal_op[0] == '!' && internal_op[1] == '=') {
|
||||
if (scan_numeric) {
|
||||
return (left_num != right_num);
|
||||
} else {
|
||||
return !!strcmp(left, internal_right);
|
||||
}
|
||||
}
|
||||
|
||||
if (internal_op[0] == '<') {
|
||||
if (scan_numeric) {
|
||||
if (internal_op[1] == '=') {
|
||||
return (left_num <= right_num);
|
||||
} else {
|
||||
return (left_num < right_num);
|
||||
}
|
||||
} else {
|
||||
if (internal_op[1] == '=') {
|
||||
return strcmp(left, internal_right) <= 0;
|
||||
} else {
|
||||
return strcmp(left, internal_right) < 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (internal_op[0] == '>') {
|
||||
if (scan_numeric) {
|
||||
if (internal_op[1] == '=') {
|
||||
return (left_num >= right_num);
|
||||
} else {
|
||||
return (left_num > right_num);
|
||||
}
|
||||
} else {
|
||||
if (internal_op[1] == '=') {
|
||||
return strcmp(left, internal_right) >= 0;
|
||||
} else {
|
||||
return strcmp(left, internal_right) > 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user