--- main_pbx.c 2009-12-21 21:35:53.427492869 +0100 +++ utils_extconf.c 2009-12-21 22:33:14.423125738 +0100 @@ -1,34 +1,3 @@ -/* - * Special characters used in patterns: - * '_' underscore is the leading character of a pattern. - * In other position it is treated as a regular char. - * . one or more of any character. Only allowed at the end of - * a pattern. - * ! zero or more of anything. Also impacts the result of CANMATCH - * and MATCHMORE. Only allowed at the end of a pattern. - * In the core routine, ! causes a match with a return code of 2. - * In turn, depending on the search mode: (XXX check if it is implemented) - * - E_MATCH retuns 1 (does match) - * - E_MATCHMORE returns 0 (no match) - * - E_CANMATCH returns 1 (does match) - * - * / should not appear as it is considered the separator of the CID info. - * XXX at the moment we may stop on this char. - * - * X Z N match ranges 0-9, 1-9, 2-9 respectively. - * [ denotes the start of a set of character. Everything inside - * is considered literally. We can have ranges a-d and individual - * characters. A '[' and '-' can be considered literally if they - * are just before ']'. - * XXX currently there is no way to specify ']' in a range, nor \ is - * considered specially. - * - * When we compare a pattern with a specific extension, all characters in the extension - * itself are considered literally. - * XXX do we want to consider space as a separator as well ? - * XXX do we want to consider the separators in non-patterns as well ? - */ - /*! * \brief helper functions to sort extensions and patterns in the desired way, * so that more specific patterns appear first. @@ -52,37 +21,31 @@ * we could encode the special cases as 0xffXX where XX * is 1, 2, 3, 4 as used above. */ -static int ext_cmp1(const char **p, unsigned char *bitwise) +static int ext_cmp1(const char **p) { + uint32_t chars[8]; int c, cmin = 0xff, count = 0; const char *end; /* load, sign extend and advance pointer until we find * a valid character. */ - c = *(*p)++; - memset(bitwise, 0xff, 32); + while ( (c = *(*p)++) && (c == ' ' || c == '-') ) + ; /* ignore some characters */ /* always return unless we have a set of chars */ - switch (toupper(c)) { + switch (c) { default: /* ordinary character */ return 0x0000 | (c & 0xff); case 'N': /* 2..9 */ - bitwise[6] = 0x01; - bitwise[7] = 0xfe; - return 0x0800 | '2'; + return 0x0700 | '2' ; case 'X': /* 0..9 */ - bitwise[5] = 0x7f; - bitwise[6] = 0x00; - bitwise[7] = 0xfe; - return 0x0A00 | '0'; + return 0x0900 | '0'; case 'Z': /* 1..9 */ - bitwise[6] = 0x00; - bitwise[7] = 0xfe; - return 0x0900 | '1'; + return 0x0800 | '1'; case '.': /* wildcard */ return 0x10000; @@ -105,28 +68,22 @@ return 0x40000; /* XXX make this entry go last... */ } + memset(chars, '\0', sizeof(chars)); /* clear all chars in the set */ for (; *p < end ; (*p)++) { unsigned char c1, c2; /* first-last char in range */ c1 = (unsigned char)((*p)[0]); if (*p + 2 < end && (*p)[1] == '-') { /* this is a range */ c2 = (unsigned char)((*p)[2]); - *p += 2; /* skip a total of 3 chars */ - } else { /* individual character */ + *p += 2; /* skip a total of 3 chars */ + } else /* individual character */ c2 = c1; - } - if (c1 < cmin) { + if (c1 < cmin) cmin = c1; - } for (; c1 <= c2; c1++) { - unsigned char mask = 1 << (c1 % 8); - /* Count the number of characters in the class, discarding duplicates. */ - if ( (bitwise[ c1 / 8 ] & mask) == 1) { + uint32_t mask = 1 << (c1 % 32); + if ( (chars[ c1 / 32 ] & mask) == 0) count += 0x100; - } - /*!\note If two patterns score the same, but one includes '0' (as - * the lowest ASCII value in the given class) and the other does - * not, then the one including '0' will compare as coming first. */ - bitwise[ c1 / 8 ] &= ~mask; + chars[ c1 / 32 ] |= mask; } } (*p)++; @@ -140,9 +97,8 @@ { /* make sure non-patterns come first. * If a is not a pattern, it either comes first or - * we do a more complex pattern comparison. + * we use strcmp to compare the strings. */ - unsigned char bitwise[2][32]; int ret = 0; if (a[0] != '_') @@ -151,18 +107,14 @@ /* Now we know a is a pattern; if b is not, a comes first */ if (b[0] != '_') return 1; - +#if 0 /* old mode for ext matching */ + return strcmp(a, b); +#endif /* ok we need full pattern sorting routine */ - while (!ret && a && b) { - ret = ext_cmp1(&a, bitwise[0]) - ext_cmp1(&b, bitwise[1]); - if (ret == 0) { - /* Are the classes different, even though they score the same? */ - ret = memcmp(bitwise[0], bitwise[1], 32); - } - } - if (ret == 0) { + while (!ret && a && b) + ret = ext_cmp1(&a) - ext_cmp1(&b); + if (ret == 0) return 0; - } else { + else return (ret > 0) ? 1 : -1; - } }