[svn-commits] murf: branch murf/utf8-whatif r90037 - in /team/murf/utf8-whatif: include/ast...
SVN commits to the Digium repositories
svn-commits at lists.digium.com
Wed Nov 28 14:03:42 CST 2007
Author: murf
Date: Wed Nov 28 14:03:42 2007
New Revision: 90037
URL: http://svn.digium.com/view/asterisk?view=rev&rev=90037
Log:
Almost done upgrading to utf8 in patterns
Modified:
team/murf/utf8-whatif/include/asterisk/unicode.h
team/murf/utf8-whatif/main/pbx.c
team/murf/utf8-whatif/main/unicode.c
Modified: team/murf/utf8-whatif/include/asterisk/unicode.h
URL: http://svn.digium.com/view/asterisk/team/murf/utf8-whatif/include/asterisk/unicode.h?view=diff&rev=90037&r1=90036&r2=90037
==============================================================================
--- team/murf/utf8-whatif/include/asterisk/unicode.h (original)
+++ team/murf/utf8-whatif/include/asterisk/unicode.h Wed Nov 28 14:03:42 2007
@@ -37,9 +37,11 @@
/* convert a string of 8859-1 chars into a string of ucs4 chars --
mainly just by turning it from 8 bits to 32 bits/char.
+ if a char is found above 0xff in the ucs4 set, error is set, and
+ that char translates as '?'
*/
-ucs4_t *ast_8859_1_to_ucs4(unsigned char *in, ucs4_t *ucs, int outlen, unsigned char **next);
+ucs4_t *ast_8859_1_to_ucs4(unsigned char *in, ucs4_t *ucs, int outlen, unsigned char **next, int *error);
/* convert a string of ucs4 chars into a string of 8859-1 chars --
@@ -48,4 +50,9 @@
unsigned char *ast_ucs4_to_8859_1(ucs4_t *ucs, unsigned char *out, int outlen, ucs4_t **next);
+/* returns -1, 0, or 1 if a is less than, equal to, or greater than b, respectively */
+int ucs4_strcmp(ucs4_t *ustra, ucs4_t *ustrb);
+/* like strdup, but for ucs4_t strings */
+ucs4_t *ucs4_strdup(ucs4_t *ustr);
+
Modified: team/murf/utf8-whatif/main/pbx.c
URL: http://svn.digium.com/view/asterisk/team/murf/utf8-whatif/main/pbx.c?view=diff&rev=90037&r1=90036&r2=90037
==============================================================================
--- team/murf/utf8-whatif/main/pbx.c (original)
+++ team/murf/utf8-whatif/main/pbx.c Wed Nov 28 14:03:42 2007
@@ -56,6 +56,7 @@
#include "asterisk/utils.h"
#include "asterisk/causes.h"
#include "asterisk/musiconhold.h"
+#include "asterisk/unicode.h"
#include "asterisk/app.h"
#include "asterisk/devicestate.h"
#include "asterisk/stringfields.h"
@@ -176,12 +177,22 @@
const char pattern[0];
};
+/*! \brief match_char_range: represent a range of characters in the char classes */
+struct match_char_range
+{
+ ucs4_t start;
+ ucs4_t end;
+ struct match_char_range *next; /* simple linked list */
+};
+
+
/*! \brief match_char: forms a syntax tree for quick matching of extension patterns */
struct match_char
{
int is_pattern; /* the pattern started with '_' */
int deleted; /* if this is set, then... don't return it */
- char *x; /* the pattern itself-- matches a single char */
+ ucs4_t *x; /* the pattern itself, a string of characters-- any one of which could match a single char; in UCS4 format */
+ struct match_char_range *mcr; /* a link list of char ranges in the char class; check these also, as they are part of x */
int specificity; /* simply the strlen of x, or 10 for X, 9 for Z, and 8 for N; and '.' and '!' will add 11 ? */
struct match_char *alt_char;
struct match_char *next_char;
@@ -321,9 +332,9 @@
static int pbx_builtin_importvar(struct ast_channel *, void *);
static void set_ext_pri(struct ast_channel *c, const char *exten, int pri);
static void new_find_extension(const char *str, struct scoreboard *score, struct match_char *tree, int length, int spec, const char *callerid);
-static struct match_char *already_in_tree(struct match_char *current, char *pat);
+static struct match_char *already_in_tree(struct match_char *current, ucs4_t *pat, struct match_char_range *mcr_list);
static struct match_char *add_exten_to_pattern_tree(struct ast_context *con, struct ast_exten *e1, int findonly);
-static struct match_char *add_pattern_node(struct ast_context *con, struct match_char *current, char *pattern, int is_pattern, int already, int specificity);
+static struct match_char *add_pattern_node(struct ast_context *con, struct match_char *current, struct match_char_range *mcr_list, ucs4_t *pattern, int is_pattern, int already, int specificity);
static void create_match_char_tree(struct ast_context *con);
static struct ast_exten *get_canmatch_exten(struct match_char *node);
static void destroy_pattern_tree(struct match_char *pattern_tree);
@@ -853,19 +864,76 @@
}
}
+static char *form_match_string_rep(struct match_char *node, char *buf, int buflen)
+{
+ /* first, copy in the node->x string, converting to utf8; then,
+ the char ranges with the same process */
+ ucs4_t *z;
+ struct match_char_range *w;
+ ast_ucs4_to_utf8(node->x, (unsigned char *)buf, buflen, &z);
+
+ if (*z) {
+ if (strlen(buf) +3 < buflen) {
+ strcat(buf,"...");
+ buflen -= 3;
+ return buf;
+ } else
+ return buf;
+ }
+ if (node->mcr)
+ {
+ char max_range_buffer[1024], *mcrp;
+ ucs4_t ucs4buf[2];
+ ucs4buf[1] = 0;
+ max_range_buffer[0] = '[';
+ max_range_buffer[1] = 0;
+ mcrp = max_range_buffer+1;
+
+ for(w=node->mcr;w;w=w->next)
+ {
+ ucs4buf[0] = w->start;
+ ast_ucs4_to_utf8(ucs4buf, (unsigned char *)mcrp, 1022-(mcrp-max_range_buffer), 0);
+ while (*mcrp)
+ mcrp++;
+ *mcrp++ = '-';
+ ucs4buf[0] = w->end;
+ ast_ucs4_to_utf8(ucs4buf, (unsigned char *)mcrp, 1022-(mcrp-max_range_buffer), 0);
+ while (*mcrp)
+ mcrp++;
+ *mcrp = 0;
+ }
+ strcat(max_range_buffer,"]");
+
+ if (strlen(max_range_buffer) < buflen)
+ {
+ strcat(buf, max_range_buffer);
+ buflen -= mcrp-max_range_buffer;
+ } else {
+ if (buflen > 5) {
+ strcat(buf,"[...]");
+ return buf;
+ } else
+ return buf;
+ }
+ }
+ return buf;
+}
+
+
void log_match_char_tree(struct match_char *node, char *prefix)
{
char my_prefix[1024];
char extenstr[40];
+ char matchstr[25];
+ matchstr[0] = 0;
extenstr[0] = 0;
+
+ form_match_string_rep(node, matchstr, sizeof(matchstr));
+
if (node && node->exten && node->exten)
sprintf(extenstr,"(%p)",node->exten);
-
- if (strlen(node->x) > 1 )
- ast_log(LOG_DEBUG,"%s[%s]:%c:%c:%d:%s%s%s\n", prefix, node->x, node->is_pattern ? 'Y':'N', node->deleted? 'D':'-', node->specificity, node->exten? "EXTEN:":"", node->exten ? node->exten->exten : "", extenstr);
- else
- ast_log(LOG_DEBUG,"%s%s:%c:%c:%d:%s%s%s\n", prefix, node->x, node->is_pattern ? 'Y':'N', node->deleted? 'D':'-', node->specificity, node->exten? "EXTEN:":"", node->exten ? node->exten->exten : "", extenstr);
+ ast_log(LOG_DEBUG,"%s{%s}:%c:%c:%d:%s%s%s\n", prefix, matchstr, node->is_pattern ? 'Y':'N', node->deleted? 'D':'-', node->specificity, node->exten? "EXTEN:":"", node->exten ? node->exten->exten : "", extenstr);
strcpy(my_prefix,prefix);
strcat(my_prefix,"+ ");
if (node->next_char)
@@ -878,15 +946,17 @@
{
char my_prefix[1024];
char extenstr[40];
+ char matchstr[25];
+ matchstr[0] = 0;
extenstr[0] = 0;
+
+ form_match_string_rep(node, matchstr, sizeof(matchstr));
+
if (node && node->exten && node->exten)
sprintf(extenstr,"(%p)",node->exten);
- if (strlen(node->x) > 1)
- ast_cli(fd, "%s[%s]:%c:%c:%d:%s%s%s\n", prefix, node->x, node->is_pattern ? 'Y':'N', node->deleted ? 'D' : '-', node->specificity, node->exten? "EXTEN:":"", node->exten ? node->exten->exten : "", extenstr);
- else
- ast_cli(fd, "%s%s:%c:%c:%d:%s%s%s\n", prefix, node->x, node->is_pattern ? 'Y':'N', node->deleted ? 'D' : '-', node->specificity, node->exten? "EXTEN:":"", node->exten ? node->exten->exten : "", extenstr);
+ ast_cli(fd, "%s{%s}:%c:%c:%d:%s%s%s\n", prefix, matchstr, node->is_pattern ? 'Y':'N', node->deleted ? 'D' : '-', node->specificity, node->exten? "EXTEN:":"", node->exten ? node->exten->exten : "", extenstr);
strcpy(my_prefix,prefix);
strcat(my_prefix,"+ ");
if (node->next_char)
@@ -936,9 +1006,28 @@
return NULL;
}
+static int matches_char_class(struct match_char *node, ucs4_t theChar)
+{
+ struct match_char_range *w;
+ if (ucs4_strchr(node->x, theChar))
+ return 1;
+ for(w=node->mcr; w; w=w->next)
+ {
+ if (theChar >= w->start && theChar <= w->end)
+ return 1;
+ }
+ return 0;
+}
+
+
static void new_find_extension(const char *str, struct scoreboard *score, struct match_char *tree, int length, int spec, const char *callerid)
{
struct match_char *p; /* note minimal stack storage requirements */
+ char *next, *next2;
+ int utf8_err = 0;
+ ucs4_t curr_char = ast_utf8_to_ucs4((unsigned char *)str, (unsigned char **)&next, &utf8_err);
+ ucs4_t next_char = ast_utf8_to_ucs4((unsigned char *)next, (unsigned char **)&next2, &utf8_err);
+
#ifdef DEBUG_THIS
if (tree)
ast_log(LOG_NOTICE,"new_find_extension called with %s on (sub)tree %s\n", str, tree->x);
@@ -946,72 +1035,72 @@
ast_log(LOG_NOTICE,"new_find_extension called with %s on (sub)tree NULL\n", str);
#endif
for (p=tree; p; p=p->alt_char) {
- if (p->x[0] == 'N' && p->x[1] == 0 && *str >= '2' && *str <= '9' ) {
- if (p->exten && !(*(str+1))) /* if a shorter pattern matches along the way, might as well report it */
+ if (p->is_pattern && p->x[0] == 'N' && p->x[1] == 0 && curr_char >= '2' && curr_char <= '9' ) {
+ if (p->exten && !(next_char))
update_scoreboard(score, length+1, spec+p->specificity, p->exten,0,callerid, p->deleted, p);
- if (p->next_char && ( *(str+1) || (p->next_char->x[0] == '/' && p->next_char->x[1] == 0))) {
- if (*(str+1))
- new_find_extension(str+1, score, p->next_char, length+1, spec+p->specificity, callerid);
+ if (p->next_char && ( next_char || (p->next_char->x[0] == '/' && p->next_char->x[1] == 0))) {
+ if (next_char)
+ new_find_extension(next, score, p->next_char, length+1, spec+p->specificity, callerid);
else
new_find_extension("/", score, p->next_char, length+1, spec+p->specificity, callerid);
- } else if (p->next_char && !*(str+1)) {
+ } else if (p->next_char && !next_char) {
score->canmatch = 1;
score->canmatch_exten = get_canmatch_exten(p);
} else {
return;
}
- } else if (p->x[0] == 'Z' && p->x[1] == 0 && *str >= '1' && *str <= '9' ) {
- if (p->exten && !(*(str+1))) /* if a shorter pattern matches along the way, might as well report it */
+ } else if (p->is_pattern && p->x[0] == 'Z' && p->x[1] == 0 && curr_char >= '1' && curr_char <= '9' ) {
+ if (p->exten && !(next_char))
update_scoreboard(score, length+1, spec+p->specificity, p->exten,0,callerid, p->deleted,p);
- if (p->next_char && ( *(str+1) || (p->next_char->x[0] == '/' && p->next_char->x[1] == 0))) {
- if (*(str+1))
- new_find_extension(str+1, score, p->next_char, length+1, spec+p->specificity, callerid);
+ if (p->next_char && ( next_char || (p->next_char->x[0] == '/' && p->next_char->x[1] == 0))) {
+ if (next_char)
+ new_find_extension(next, score, p->next_char, length+1, spec+p->specificity, callerid);
else
new_find_extension("/", score, p->next_char, length+1, spec+p->specificity, callerid);
- } else if (p->next_char && !*(str+1)) {
+ } else if (p->next_char && !next_char) {
score->canmatch = 1;
score->canmatch_exten = get_canmatch_exten(p);
} else {
return;
}
- } else if (p->x[0] == 'X' && p->x[1] == 0 && *str >= '0' && *str <= '9' ) {
- if (p->exten && !(*(str+1))) /* if a shorter pattern matches along the way, might as well report it */
+ } else if (p->is_pattern && p->x[0] == 'X' && p->x[1] == 0 && curr_char >= '0' && curr_char <= '9' ) {
+ if (p->exten && !(next_char))
update_scoreboard(score, length+1, spec+p->specificity, p->exten,0,callerid, p->deleted,p);
- if (p->next_char && ( *(str+1) || (p->next_char->x[0] == '/' && p->next_char->x[1] == 0))) {
- if (*(str+1))
- new_find_extension(str+1, score, p->next_char, length+1, spec+p->specificity, callerid);
+ if (p->next_char && ( next_char || (p->next_char->x[0] == '/' && p->next_char->x[1] == 0))) {
+ if (next_char)
+ new_find_extension(next, score, p->next_char, length+1, spec+p->specificity, callerid);
else
new_find_extension("/", score, p->next_char, length+1, spec+p->specificity, callerid);
- } else if (p->next_char && !*(str+1)) {
+ } else if (p->next_char && !next_char) {
score->canmatch = 1;
score->canmatch_exten = get_canmatch_exten(p);
} else {
return;
}
- } else if (p->x[0] == '.' && p->x[1] == 0) {
+ } else if (p->is_pattern && p->x[0] == '.' && p->x[1] == 0) {
/* how many chars will the . match against? */
int i = 0;
const char *str2 = str;
while (*str2++) {
i++;
}
- if (p->exten && !(*(str+1)))
+ if (p->exten && !(next_char))
update_scoreboard(score, length+i, spec+(i*p->specificity), p->exten, '.', callerid, p->deleted, p);
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);
}
return;
- } else if (p->x[0] == '!' && p->x[1] == 0) {
+ } else if (p->is_pattern && p->x[0] == '!' && p->x[1] == 0) {
/* how many chars will the . match against? */
int i = 0;
const char *str2 = str;
while (*str2++) {
i++;
}
- if (p->exten && !(*(str+1)))
+ if (p->exten && !(next_char))
update_scoreboard(score, length+1, spec+(p->specificity*i), p->exten, '!', callerid, p->deleted, p);
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);
@@ -1022,18 +1111,35 @@
if (p->next_char && callerid && *callerid) {
new_find_extension(callerid, score, p->next_char, length+1, spec, callerid);
}
- } else if (index(p->x, *str)) {
- if (p->exten && !(*(str+1))) /* if a shorter pattern matches along the way, might as well report it */
+ } else if (p->is_pattern && matches_char_class(p, curr_char)) {
+ if (p->exten && !(next_char))
update_scoreboard(score, length+1, spec+p->specificity, p->exten,0,callerid, p->deleted, p);
- if (p->next_char && ( *(str+1) || (p->next_char->x[0] == '/' && p->next_char->x[1] == 0))) {
- if (*(str+1)) {
- new_find_extension(str+1, score, p->next_char, length+1, spec+p->specificity, callerid);
+ if (p->next_char && ( next_char || (p->next_char->x[0] == '/' && p->next_char->x[1] == 0))) {
+ if (next_char) {
+ new_find_extension(next, score, p->next_char, length+1, spec+p->specificity, callerid);
} else {
new_find_extension("/", score, p->next_char, length+1, spec+p->specificity, callerid);
}
- } else if (p->next_char && !*(str+1)) {
+ } else if (p->next_char && !next_char) {
+ score->canmatch = 1;
+ score->canmatch_exten = get_canmatch_exten(p);
+ } else {
+ return;
+ }
+ } else if (!p->is_pattern && curr_char == p->x[0]) {
+ if (p->exten && !(next_char))
+ update_scoreboard(score, length+1, spec+p->specificity, p->exten,0,callerid, p->deleted, p);
+
+
+ if (p->next_char && ( next_char || (p->next_char->x[0] == '/' && p->next_char->x[1] == 0))) {
+ if (next_char) {
+ new_find_extension(next, score, p->next_char, length+1, spec+p->specificity, callerid);
+ } else {
+ new_find_extension("/", score, p->next_char, length+1, spec+p->specificity, callerid);
+ }
+ } else if (p->next_char && !next_char) {
score->canmatch = 1;
score->canmatch_exten = get_canmatch_exten(p);
} else {
@@ -1057,22 +1163,69 @@
* I guess forming this pattern tree would be analogous to compiling a regex.
*/
-static struct match_char *already_in_tree(struct match_char *current, char *pat)
+static void destroy_range_list(struct match_char_range *list)
+{
+ struct match_char_range *lnext;
+
+ while (list) {
+ lnext = list->next;
+ list->next = 0;
+ free(list);
+ list = lnext;
+ }
+}
+
+static struct match_char *already_in_tree(struct match_char *current, ucs4_t *pat, struct match_char_range *mcr_list)
{
struct match_char *t;
+ struct match_char_range *mr,*dr;
if (!current)
return 0;
for (t=current; t; t=t->alt_char) {
- if (strcmp(pat,t->x) == 0) /* uh, we may want to sort exploded [] contents to make matching easy */
- return t;
+ if (ucs4_strcmp(pat,t->x) == 0) { /* uh, we may want to sort exploded [] contents to make matching more reliable. Sort of a cononical representation */
+ /* It's not a match till we verify that the ranges are also equal */
+ if (!t->mcr && !mcr_list)
+ return t;
+ if ((t->mcr && !mcr_list) || (!t->mcr && mcr_list))
+ return 0;
+
+ for (mr = t->mcr; mr; mr=mr->next) {
+ int found = 0;
+ for(dr=mcr_list;dr;dr=dr->next)
+ {
+ if (mr->start == dr->start && mr->end == dr->end) {
+ found = 1;
+ break;
+ }
+ }
+ if (!found)
+ return 0;
+ }
+ /* if we get here, each of the ranges in this node corresponds to one in the proposed node */
+ for (mr = mcr_list; mr; mr=mr->next) {
+ int found = 0;
+ for(dr = t->mcr; dr; dr=dr->next)
+ {
+ if (mr->start == dr->start && mr->end == dr->end) {
+ found = 1;
+ break;
+ }
+ }
+ if (!found)
+ return 0;
+ }
+ /* if we get here, each of the ranges in the proposed node corresponds to one in the this node */
+ return t; /* the char set matches, and so do the ranges. Jackpot */
+ }
}
return 0;
}
-static struct match_char *add_pattern_node(struct ast_context *con, struct match_char *current, char *pattern, int is_pattern, int already, int specificity)
+static struct match_char *add_pattern_node(struct ast_context *con, struct match_char *current, struct match_char_range *mcr_list, ucs4_t *pattern, int is_pattern, int already, int specificity)
{
struct match_char *m = ast_calloc(1,sizeof(struct match_char));
- m->x = ast_strdup(pattern);
+ m->x = ucs4_strdup(pattern);
+ m->mcr = mcr_list;
m->is_pattern = is_pattern;
if (specificity == 1 && is_pattern && pattern[0] == 'N')
m->specificity = 98;
@@ -1111,11 +1264,16 @@
int specif;
int already;
int pattern = 0;
- char buf[256];
char extenbuf[512];
+ ucs4_t buf[256];
+ ucs4_t extenbufu[512];
+ ucs4_t curr_char;
char *s1 = extenbuf;
+ char *s2;
+ char *next_char;
int l1 = strlen(e1->exten) + strlen(e1->cidmatch) + 2;
-
+ int error = 0;
+ struct match_char_range *mcr_list = 0;
strncpy(extenbuf,e1->exten,sizeof(extenbuf));
if (e1->matchcid && l1 <= sizeof(extenbuf)) {
@@ -1130,90 +1288,107 @@
#endif
m1 = con->pattern_tree; /* each pattern starts over at the root of the pattern tree */
already = 1;
-
- if ( *s1 == '_') {
+ curr_char = ast_utf8_to_ucs4((unsigned char *)s1, (unsigned char **)&next_char, &error);
+
+ if ( curr_char == '_') {
pattern = 1;
- s1++;
+ s1 = next_char;
}
while( *s1 ) {
- if (pattern && *s1 == '[' && *(s1-1) != '\\') {
- char *s2 = buf;
+ curr_char = ast_utf8_to_ucs4((unsigned char *)s1, (unsigned char **)&next_char, &error);
+ if (pattern && curr_char == '[' && *(s1-1) != '\\') {
+ ucs4_t *s2 = buf;
+ char *s3u, *s4u;
+ ucs4_t this_char;
+ ucs4_t that_char;
+
buf[0] = 0;
s1++; /* get past the '[' */
while (*s1 != ']' && *(s1-1) != '\\' ) {
- if (*s1 == '\\') {
- if (*(s1+1) == ']') {
+ this_char = ast_utf8_to_ucs4((unsigned char *)s1, (unsigned char **)&s3u, &error);
+ that_char = ast_utf8_to_ucs4((unsigned char *)s3, (unsigned char **)&s4u, &error);
+ if (this_char == '\\') {
+ if (that_char == ']') {
*s2++ = ']';
- s1++;s1++;
- } else if (*(s1+1) == '\\') {
+ s1 = s4u;
+ } else if (that_char == '\\') {
*s2++ = '\\';
- s1++;s1++;
- } else if (*(s1+1) == '-') {
+ s1 = s4u;
+ } else if (that_char == '-') {
*s2++ = '-';
- s1++; s1++;
- } else if (*(s1+1) == '[') {
+ s1 = s4u;
+ } else if (that_char == '[') {
*s2++ = '[';
- s1++; s1++;
+ s1 = s4u;
}
- } else if (*s1 == '-') { /* remember to add some error checking to all this! */
- char s3 = *(s1-1);
- char s4 = *(s1+1);
- for (s3++; s3 <= s4; s3++) {
- *s2++ = s3;
- }
- s1++; s1++;
+ } else if (this_char == '-' ) { /* remember to add some error checking to all this! */
+ struct match_char_range *mcr1 = ast_calloc(sizeof(struct match_char_range));
+ mcr1->start = *(s2-1);
+ s2--; /* remove the begin char from the char class */
+ mcr1->end = that_char;
+ mcr1->next = mcr_list;
+ mcr_list = mcr1;
+
+ s1 = s4u;
} else {
- *s2++ = *s1++;
+ *s2++ = this_char;
+ s1 = s3u;
}
}
- *s2 = 0; /* null terminate the exploded range */
+ *s2 = 0; /* null terminate the character class */
specif = strlen(buf);
} else {
- if (*s1 == '\\') {
- s1++;
- buf[0] = *s1;
+ if (curr_char == '\\') {
+ curr_char = ast_utf8_to_ucs4((unsigned char *)next_char, (unsigned char **)&next_char, &error);
+ buf[0] = curr_char;
+ s1 = next_char;
} else {
if (pattern) {
- if (*s1 == 'n') /* make sure n,x,z patterns are canonicalized to N,X,Z */
- *s1 = 'N';
- else if (*s1 == 'x')
- *s1 = 'X';
- else if (*s1 == 'z')
- *s1 = 'Z';
+ if (curr_char == 'n') /* make sure n,x,z patterns are canonicalized to N,X,Z */
+ curr_char = 'N';
+ else if (curr_char == 'x')
+ curr_char = 'X';
+ else if (curr_char == 'z')
+ curr_char = 'Z';
}
- buf[0] = *s1;
+ buf[0] = curr_char;
}
buf[1] = 0;
specif = 1;
}
m2 = 0;
- if (already && (m2=already_in_tree(m1,buf)) && m2->next_char) {
- if (!(*(s1+1))) { /* if this is the end of the pattern, but not the end of the tree, then mark this node with the exten...
- a shorter pattern might win if the longer one doesn't match */
+ if (already && (m2=already_in_tree(m1,buf,mcr_list)) && m2->next_char) {
+ if (!(*next_char)) { /* if this is the end of the pattern, but not the end of the tree, then mark this node with the exten...
+ a shorter pattern might match a shorter data string... */
m2->exten = e1;
m2->deleted = 0;
}
+ destroy_range_list(mcr_list);
+ mcr_list = 0;
m1 = m2->next_char; /* m1 points to the node to compare against */
} else {
if (m2) {
+ destroy_range_list(mcr_list);
+ mcr_list = 0;
if (findonly)
return m2;
m1 = m2;
} else {
if (findonly)
return m1;
- m1 = add_pattern_node(con, m1, buf, pattern, already,specif); /* m1 is the node just added */
+ m1 = add_pattern_node(con, m1, mcr_list, buf, pattern, already,specif); /* m1 is the node just added */
+ mcr_list = 0; /* it's now hanging off the newly created node */
}
- if (!(*(s1+1))) {
+ if (!(*next_char)) {
m1->deleted = 0;
m1->exten = e1;
}
already = 0;
}
- s1++; /* advance to next char */
+ s1 = next_char; /* advance to next char */
}
return m1;
}
@@ -1239,6 +1414,7 @@
}
ast_hashtab_end_traversal(t1);
}
+
static void destroy_pattern_tree(struct match_char *pattern_tree) /* pattern tree is a simple binary tree, sort of, so the proper way to destroy it is... recursively! */
{
@@ -1328,6 +1504,7 @@
/* always return unless we have a set of chars */
switch (c) {
+
default: /* ordinary character */
return 0x0000 | (c & 0xff);
@@ -7639,8 +7816,8 @@
int ast_parseable_goto(struct ast_channel *chan, const char *goto_string)
{
char *exten, *pri, *context;
- char *stringp;
- int ipri;
+ char *int;
+ stringp ipri;
int mode = 0;
if (ast_strlen_zero(goto_string)) {
Modified: team/murf/utf8-whatif/main/unicode.c
URL: http://svn.digium.com/view/asterisk/team/murf/utf8-whatif/main/unicode.c?view=diff&rev=90037&r1=90036&r2=90037
==============================================================================
--- team/murf/utf8-whatif/main/unicode.c (original)
+++ team/murf/utf8-whatif/main/unicode.c Wed Nov 28 14:03:42 2007
@@ -174,13 +174,17 @@
mainly just by turning it from 32 bits to 8 bits/char.
*/
-unsigned char *ast_ucs4_to_8859_1(ucs4_t *ucs, unsigned char *out, int outlen, ucs4_t **next)
+unsigned char *ast_ucs4_to_8859_1(ucs4_t *ucs, unsigned char *out, int outlen, ucs4_t **next, int *error)
{
unsigned char *buf = out;
-
+ *error = 0;
while (*ucs && outlen > 1)
{
- *buf++ = *ucs++; /* this should lop off all but the lowest 8 bits */
+ if (*ucs > 0xff) {
+ *buf++ = '?';
+ *error = 1;
+ } else
+ *buf++ = *ucs++; /* this should lop off all but the lowest 8 bits */
outlen--;
/* this is pretty brutal, but should be sufficient for simple 8859-1 conversion */
}
@@ -228,5 +232,34 @@
return NULL;
}
-
-
+int ucs4_strcmp(ucs4_t *ustra, ucs4_t *ustrb)
+{
+ if (!ustra || !ustrb)
+ return 1;
+
+ while (*ustra && *ustrb) {
+ if (*ustra < *ustrb)
+ return -1;
+ if (*ustra > *ustrb)
+ return 1;
+ ustra++;
+ ustrb++;
+ }
+ if (*ustra)
+ return 1;
+ else if (*ustrb)
+ return -1;
+ return 0; /* equal length and chars */
+}
+
+ucs4_t *ucs4_strdup(ucs4_t *ustr)
+{
+ int size = 0,i;
+ ucs4_t *p = ustr;
+ while (*p++)
+ size++;
+ p = ast_calloc(size,sizeof(ucs4_t));
+ for (i=0; i<size; i++)
+ p[i] = ustr[i];
+ return p;
+}
More information about the svn-commits
mailing list