Rev 63512 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed
/*tre-match-utils.h - TRE matcher helper definitionsThis software is released under a BSD-style license.See the file LICENSE for details and copyright.*/#define str_source ((const tre_str_source*)string)#ifdef TRE_WCHAR#ifdef TRE_MULTIBYTE/* Wide character and multibyte support. */#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, (size_t)max, &mbstate); \if (w == (size_t)-1 || w == (size_t)-2) \return REG_NOMATCH; \if (w == 0 && len >= 0) \{ \pos_add_next = 1; \next_c = 0; \str_byte++; \} \else \{ \pos_add_next = (unsigned int)w; \str_byte += w; \} \} \} \} \else if (type == STR_USER) \{ \pos += pos_add_next; \str_user_end = str_source->get_next_char(&next_c, &pos_add_next, \str_source->context); \} \} while(/*CONSTCOND*/(void)0,0)#else /* !TRE_MULTIBYTE *//* Wide character support, no multibyte support. */#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_USER) \{ \pos += pos_add_next; \str_user_end = str_source->get_next_char(&next_c, &pos_add_next, \str_source->context); \} \} while(/*CONSTCOND*/(void)0,0)#endif /* !TRE_MULTIBYTE */#else /* !TRE_WCHAR *//* No wide character or multibyte support. */#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_USER) \{ \pos += pos_add_next; \str_user_end = str_source->get_next_char(&next_c, &pos_add_next, \str_source->context); \} \} while(/*CONSTCOND*/(void)0,0)#endif /* !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) \&& (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))))#define CHECK_CHAR_CLASSES(trans_i, tnfa, eflags) \(((trans_i->assertions & ASSERT_CHAR_CLASS) \&& !(tnfa->cflags & REG_ICASE) \&& !tre_isctype((tre_cint_t)prev_c, trans_i->u.class)) \|| ((trans_i->assertions & ASSERT_CHAR_CLASS) \&& (tnfa->cflags & REG_ICASE) \&& !tre_isctype(tre_tolower((tre_cint_t)prev_c),trans_i->u.class) \&& !tre_isctype(tre_toupper((tre_cint_t)prev_c),trans_i->u.class)) \|| ((trans_i->assertions & ASSERT_CHAR_CLASS_NEG) \&& tre_neg_char_classes_match(trans_i->neg_classes,(tre_cint_t)prev_c,\tnfa->cflags & REG_ICASE)))/* Returns 1 if `t1' wins `t2', 0 otherwise. */inline static inttre_tag_order(int num_tags, tre_tag_direction_t *tag_directions,int *t1, int *t2){int i;for (i = 0; i < num_tags; i++){if (tag_directions[i] == TRE_TAG_MINIMIZE){if (t1[i] < t2[i])return 1;if (t1[i] > t2[i])return 0;}else{if (t1[i] > t2[i])return 1;if (t1[i] < t2[i])return 0;}}/* assert(0);*/return 0;}inline static inttre_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. */elseclasses++;return 0; /* No match. */}