mirror of
https://github.com/unrealircd/unrealircd.git
synced 2026-07-10 14:03:14 +02:00
173 lines
6.2 KiB
C
173 lines
6.2 KiB
C
/*
|
|
tre-match-utils.h - TRE matcher helper definitions
|
|
|
|
Copyright (C) 2001-2003 Ville Laurikari <vl@iki.fi>.
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License version 2 (June
|
|
1991) as published by the Free Software Foundation.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
|
|
*/
|
|
|
|
|
|
#if defined(TRE_WCHAR) && defined(TRE_MULTIBYTE)
|
|
#define GET_NEXT_WCHAR() \
|
|
do { \
|
|
prev_c = next_c; \
|
|
if (type == STR_BYTE) \
|
|
{ \
|
|
pos++; \
|
|
if (len >= 0 && pos >= len) \
|
|
next_c = '\0'; \
|
|
else \
|
|
next_c = (unsigned char)(*str_byte++); \
|
|
} \
|
|
else if (type == STR_WIDE) \
|
|
{ \
|
|
pos++; \
|
|
if (len >= 0 && pos >= len) \
|
|
next_c = L'\0'; \
|
|
else \
|
|
next_c = *str_wide++; \
|
|
} \
|
|
else if (type == STR_MBS) \
|
|
{ \
|
|
pos += pos_add_next; \
|
|
if (str_byte == NULL) \
|
|
next_c = L'\0'; \
|
|
else \
|
|
{ \
|
|
size_t w; \
|
|
int max; \
|
|
if (len >= 0) \
|
|
max = len - pos; \
|
|
else \
|
|
max = 32; \
|
|
if (max <= 0) \
|
|
{ \
|
|
next_c = L'0'; \
|
|
pos_add_next = 1; \
|
|
} \
|
|
else \
|
|
{ \
|
|
w = tre_mbrtowc(&next_c, str_byte, max, &mbstate); \
|
|
if (w < 0) \
|
|
return REG_NOMATCH; \
|
|
pos_add_next = w; \
|
|
str_byte += w; \
|
|
} \
|
|
} \
|
|
} \
|
|
} while(0)
|
|
#elif defined(TRE_WCHAR)
|
|
#define GET_NEXT_WCHAR() \
|
|
do { \
|
|
prev_c = next_c; \
|
|
if (type == STR_BYTE) \
|
|
{ \
|
|
pos++; \
|
|
if (len >= 0 && pos >= len) \
|
|
next_c = '\0'; \
|
|
else \
|
|
next_c = (unsigned char)(*str_byte++); \
|
|
} \
|
|
else if (type == STR_WIDE) \
|
|
{ \
|
|
pos++; \
|
|
if (len >= 0 && pos >= len) \
|
|
next_c = L'\0'; \
|
|
else \
|
|
next_c = *str_wide++; \
|
|
} \
|
|
} while(0)
|
|
#else
|
|
#define GET_NEXT_WCHAR() \
|
|
do { \
|
|
prev_c = next_c; \
|
|
pos++; \
|
|
if (len >= 0 && pos >= len) \
|
|
next_c = '\0'; \
|
|
else \
|
|
next_c = (unsigned char)(*str_byte++); \
|
|
} while(0)
|
|
#endif /* !defined(TRE_WCHAR) */
|
|
|
|
#define IS_WORD_CHAR(c) ((c) == L'_' || tre_isalnum(c))
|
|
|
|
#define CHECK_ASSERTIONS(assertions) \
|
|
(((assertions & ASSERT_AT_BOL) \
|
|
&& (pos > 0 || reg_notbol) \
|
|
&& (prev_c != L'\n' || !reg_newline)) \
|
|
|| ((assertions & ASSERT_AT_EOL) \
|
|
&& (next_c != L'\0' || reg_noteol) \
|
|
&& (next_c != L'\n' || !reg_newline)) \
|
|
|| ((assertions & ASSERT_AT_BOW) \
|
|
&& (pos > 0 && (IS_WORD_CHAR(prev_c) || !IS_WORD_CHAR(next_c)))) \
|
|
|| ((assertions & ASSERT_AT_EOW) \
|
|
&& (!IS_WORD_CHAR(prev_c) || IS_WORD_CHAR(next_c))) \
|
|
|| ((assertions & ASSERT_AT_WB) \
|
|
&& (pos != 0 && next_c != L'\0' \
|
|
&& IS_WORD_CHAR(prev_c) == IS_WORD_CHAR(next_c))) \
|
|
|| ((assertions & ASSERT_AT_WB_NEG) \
|
|
&& (pos == 0 || next_c == L'\0' \
|
|
|| IS_WORD_CHAR(prev_c) != IS_WORD_CHAR(next_c))))
|
|
|
|
|
|
|
|
/* Returns 1 if `t1' wins `t2', 0 otherwise. */
|
|
inline static int
|
|
tag_order(int num_tags, tre_tag_direction_t *tag_directions, int *t1, int *t2)
|
|
{
|
|
int i;
|
|
/*
|
|
DPRINT(("tag_order\n"));
|
|
DPRINT(("t1[0] = %d, t2[0] = %d\n", *t1, *t2));
|
|
*/
|
|
i = 0;
|
|
while (i < num_tags)
|
|
{
|
|
if (tag_directions[i] == TRE_TAG_MINIMIZE)
|
|
{
|
|
DPRINT(("< t1[%d] = %d, t2[%d] = %d\n", i, t1[i], i, t2[i]));
|
|
if (t1[i] > t2[i])
|
|
return 0;
|
|
if (t1[i] < t2[i])
|
|
return 1;
|
|
}
|
|
else
|
|
{
|
|
DPRINT(("> t1[%d] = %d, t2[%d] = %d\n", i, t1[i], i, t2[i]));
|
|
if (t1[i] > t2[i])
|
|
return 1;
|
|
if (t1[i] < t2[i])
|
|
return 0;
|
|
}
|
|
i++;
|
|
}
|
|
/* assert(0);*/
|
|
return 0;
|
|
}
|
|
|
|
inline static int
|
|
neg_char_classes_match(tre_ctype_t *classes, tre_cint_t wc, int icase)
|
|
{
|
|
DPRINT(("neg_char_classes_test: %p, %d, %d\n", classes, wc, icase));
|
|
while (*classes != (tre_ctype_t)0)
|
|
if ((!icase && tre_isctype(wc, *classes))
|
|
|| (icase && (tre_isctype(tre_toupper(wc), *classes)
|
|
|| tre_isctype(tre_tolower(wc), *classes))))
|
|
return 1; /* Match. */
|
|
else
|
|
classes++;
|
|
return 0; /* No match. */
|
|
}
|