#pragma weak _regex = regex
#include "lint.h"
#include "regex.h"
#include "mtlib.h"
#include <limits.h>
#include <stdarg.h>
#include <stdlib.h>
#include <thread.h>
#include <widec.h>
#include "tsd.h"
#define ADD_256_TO_GROUP_LENGTH 0x1
#define ADD_512_TO_GROUP_LENGTH 0x2
#define ADD_768_TO_GROUP_LENGTH 0x3
#define ADDED_LENGTH_BITS 0x3
#define SINGLE_BYTE_MASK 0xff
#define STRINGP_STACK_SIZE 50
typedef enum {
NOT_IN_CLASS = 0,
IN_CLASS
} char_test_condition_t;
typedef enum {
TESTING_CHAR = 0,
CONDITION_TRUE,
CONDITION_FALSE,
CHAR_TEST_ERROR
} char_test_result_t;
static mutex_t regex_lock = DEFAULTMUTEX;
static int return_arg_number[NSUBSTRINGS];
static const char *substring_endp[NSUBSTRINGS];
static const char *substring_startp[NSUBSTRINGS];
static const char *stringp_stack[STRINGP_STACK_SIZE];
static const char **stringp_stackp;
static int get_wchar(wchar_t *wcharp, const char *stringp);
static void get_match_counts(int *nmust_matchp, int *nextra_matches_allowedp,
const char *count_stringp);
static boolean_t in_wchar_range(wchar_t test_char, wchar_t lower_char,
wchar_t upper_char);
static const char *pop_stringp(void);
static const char *previous_charp(const char *current_charp);
static const char *push_stringp(const char *stringp);
static char_test_result_t test_char_against_ascii_class(char test_char,
const char *classp, char_test_condition_t test_condition);
static char_test_result_t test_char_against_multibyte_class(wchar_t test_char,
const char *classp, char_test_condition_t test_condition);
static char_test_result_t test_char_against_old_ascii_class(char test_char,
const char *classp, char_test_condition_t test_condition);
static const char *test_repeated_ascii_char(const char *repeat_startp,
const char *stringp, const char *regexp);
static const char *test_repeated_multibyte_char(const char *repeat_startp,
const char *stringp, const char *regexp);
static const char *test_repeated_group(const char *repeat_startp,
const char *stringp, const char *regexp);
static const char *test_string(const char *stringp, const char *regexp);
char *__loc1;
char **
____loc1(void)
{
if (thr_main())
return (&__loc1);
return ((char **)tsdalloc(_T_REGEX_LOC1, sizeof (char *), NULL));
}
#define __loc1 (*(____loc1()))
extern char *
regex(const char *regexp, const char *stringp, ...)
{
va_list arg_listp;
int char_size;
const char *end_of_matchp;
wchar_t regex_wchar;
char *return_argp[NSUBSTRINGS];
char *returned_substringp;
int substringn;
const char *substringp;
wchar_t string_wchar;
if (____loc1() == (char **)0) {
return ((char *)0);
} else {
lmutex_lock(®ex_lock);
__loc1 = (char *)0;
}
if ((stringp == (char *)0) || (regexp == (char *)0)) {
lmutex_unlock(®ex_lock);
return ((char *)0);
}
substringn = 0;
va_start(arg_listp, stringp);
while (substringn < NSUBSTRINGS) {
return_argp[substringn] = va_arg(arg_listp, char *);
substring_startp[substringn] = (char *)0;
return_arg_number[substringn] = -1;
substringn++;
}
va_end(arg_listp);
end_of_matchp = (char *)0;
stringp_stackp = &stringp_stack[STRINGP_STACK_SIZE];
if ((int)*regexp == (int)START_OF_STRING_MARK) {
__loc1 = (char *)stringp;
regexp++;
end_of_matchp = test_string(stringp, regexp);
} else if ((int)*regexp == (int)ASCII_CHAR) {
while ((*stringp != *(regexp + 1)) && (*stringp != '\0')) {
stringp++;
}
while ((end_of_matchp == (char *)0) && (*stringp != '\0')) {
end_of_matchp = test_string(stringp, regexp);
if (end_of_matchp != (char *)0) {
__loc1 = (char *)stringp;
} else {
stringp++;
while ((*stringp != *(regexp + 1)) &&
(*stringp != '\0')) {
stringp++;
}
}
}
} else if (!multibyte) {
end_of_matchp = test_string(stringp, regexp);
while ((end_of_matchp == (char *)0) && (*stringp != '\0')) {
stringp++;
end_of_matchp = test_string(stringp, regexp);
}
if (end_of_matchp != (char *)0) {
__loc1 = (char *)stringp;
}
} else if ((int)*regexp == (int)MULTIBYTE_CHAR) {
(void) get_wchar(®ex_wchar, regexp + 1);
char_size = get_wchar(&string_wchar, stringp);
while ((string_wchar != regex_wchar) && (char_size > 0)) {
stringp += char_size;
char_size = get_wchar(&string_wchar, stringp);
}
while ((end_of_matchp == (char *)0) && (char_size > 0)) {
end_of_matchp = test_string(stringp, regexp);
if (end_of_matchp != (char *)0) {
__loc1 = (char *)stringp;
} else {
stringp += char_size;
char_size = get_wchar(&string_wchar, stringp);
while ((string_wchar != regex_wchar) &&
(char_size > 0)) {
stringp += char_size;
char_size = get_wchar(&string_wchar,
stringp);
}
}
}
} else {
end_of_matchp = test_string(stringp, regexp);
char_size = get_wchar(&string_wchar, stringp);
while ((end_of_matchp == (char *)0) && (char_size > 0)) {
stringp += char_size;
end_of_matchp = test_string(stringp, regexp);
char_size = get_wchar(&string_wchar, stringp);
}
if (end_of_matchp != (char *)0) {
__loc1 = (char *)stringp;
}
}
substringn = 0;
while (substringn < NSUBSTRINGS) {
substringp = substring_startp[substringn];
if ((substringp != (char *)0) &&
(return_arg_number[substringn] >= 0)) {
returned_substringp =
return_argp[return_arg_number[substringn]];
if (returned_substringp != (char *)0) {
while (substringp <
substring_endp[substringn]) {
*returned_substringp =
(char)*substringp;
returned_substringp++;
substringp++;
}
*returned_substringp = '\0';
}
}
substringn++;
}
lmutex_unlock(®ex_lock);
return ((char *)end_of_matchp);
}
static int
get_wchar(wchar_t *wcharp, const char *stringp)
{
int char_size;
if (stringp == (char *)0) {
char_size = 0;
*wcharp = (wchar_t)((unsigned int)'\0');
} else if (*stringp == '\0') {
char_size = 0;
*wcharp = (wchar_t)((unsigned int)*stringp);
} else if ((unsigned char)*stringp <= (unsigned char)0x7f) {
char_size = 1;
*wcharp = (wchar_t)((unsigned int)*stringp);
} else {
char_size = mbtowc(wcharp, stringp, MB_LEN_MAX);
}
return (char_size);
}
static void
get_match_counts(int *nmust_matchp, int *nextra_matches_allowedp,
const char *count_stringp)
{
int minimum_match_count;
int maximum_match_count;
minimum_match_count =
(int)((unsigned int)*count_stringp & SINGLE_BYTE_MASK);
*nmust_matchp = minimum_match_count;
count_stringp++;
maximum_match_count =
(int)((unsigned int)*count_stringp & SINGLE_BYTE_MASK);
if (maximum_match_count == (int)UNLIMITED) {
*nextra_matches_allowedp = (int)UNLIMITED;
} else {
*nextra_matches_allowedp =
maximum_match_count - minimum_match_count;
}
return;
}
static boolean_t
in_wchar_range(wchar_t test_char, wchar_t lower_char, wchar_t upper_char)
{
return (((lower_char <= 0x7f) && (upper_char <= 0x7f) &&
(lower_char <= test_char) && (test_char <= upper_char)) ||
(((test_char & WCHAR_CSMASK) == (lower_char & WCHAR_CSMASK)) &&
((test_char & WCHAR_CSMASK) == (upper_char & WCHAR_CSMASK)) &&
(lower_char <= test_char) && (test_char <= upper_char)));
}
static const char *
pop_stringp(void)
{
const char *stringp;
if (stringp_stackp >= &stringp_stack[STRINGP_STACK_SIZE]) {
return ((char *)0);
} else {
stringp = *stringp_stackp;
stringp_stackp++;
return (stringp);
}
}
static const char *
previous_charp(const char *current_charp)
{
const char *prev_cs0 = current_charp - 1;
const char *prev_cs1 = current_charp - eucw1;
const char *prev_cs2 = current_charp - eucw2 - 1;
const char *prev_cs3 = current_charp - eucw3 - 1;
const char *prev_charp;
if ((unsigned char)*prev_cs0 <= 0x7f) {
prev_charp = prev_cs0;
} else if ((unsigned char)*prev_cs2 == SS2) {
prev_charp = prev_cs2;
} else if ((unsigned char)*prev_cs3 == SS3) {
prev_charp = prev_cs3;
} else {
prev_charp = prev_cs1;
}
return (prev_charp);
}
static const char *
push_stringp(const char *stringp)
{
if (stringp_stackp <= &stringp_stack[0]) {
return ((char *)0);
} else {
stringp_stackp--;
*stringp_stackp = stringp;
return (stringp);
}
}
static char_test_result_t
test_char_against_ascii_class(char test_char, const char *classp,
char_test_condition_t test_condition)
{
int nbytes_to_check;
nbytes_to_check = (int)*classp;
classp++;
nbytes_to_check--;
while (nbytes_to_check > 0) {
if (test_char == *classp) {
if (test_condition == IN_CLASS)
return (CONDITION_TRUE);
else
return (CONDITION_FALSE);
} else if (*classp == THRU) {
if ((*(classp - 1) <= test_char) &&
(test_char <= *(classp + 1))) {
if (test_condition == IN_CLASS)
return (CONDITION_TRUE);
else
return (CONDITION_FALSE);
} else {
classp += 2;
nbytes_to_check -= 2;
}
} else {
classp++;
nbytes_to_check--;
}
}
if (test_condition == NOT_IN_CLASS) {
return (CONDITION_TRUE);
} else {
return (CONDITION_FALSE);
}
}
static char_test_result_t
test_char_against_multibyte_class(wchar_t test_char, const char *classp,
char_test_condition_t test_condition)
{
int char_size;
wchar_t current_char;
int nbytes_to_check;
wchar_t previous_char;
nbytes_to_check = (int)*classp;
classp++;
nbytes_to_check--;
char_size = get_wchar(¤t_char, classp);
if (char_size <= 0) {
return (CHAR_TEST_ERROR);
} else if (test_char == current_char) {
if (test_condition == IN_CLASS) {
return (CONDITION_TRUE);
} else {
return (CONDITION_FALSE);
}
} else {
classp += char_size;
nbytes_to_check -= char_size;
}
while (nbytes_to_check > 0) {
previous_char = current_char;
char_size = get_wchar(¤t_char, classp);
if (char_size <= 0) {
return (CHAR_TEST_ERROR);
} else if (test_char == current_char) {
if (test_condition == IN_CLASS) {
return (CONDITION_TRUE);
} else {
return (CONDITION_FALSE);
}
} else if (current_char == THRU) {
classp += char_size;
nbytes_to_check -= char_size;
char_size = get_wchar(¤t_char, classp);
if (char_size <= 0) {
return (CHAR_TEST_ERROR);
} else if (in_wchar_range(test_char, previous_char,
current_char)) {
if (test_condition == IN_CLASS) {
return (CONDITION_TRUE);
} else {
return (CONDITION_FALSE);
}
} else {
classp += char_size;
nbytes_to_check -= char_size;
}
} else {
classp += char_size;
nbytes_to_check -= char_size;
}
}
if (test_condition == NOT_IN_CLASS) {
return (CONDITION_TRUE);
} else {
return (CONDITION_FALSE);
}
}
static char_test_result_t
test_char_against_old_ascii_class(char test_char, const char *classp,
char_test_condition_t test_condition)
{
int nbytes_to_check;
nbytes_to_check = (int)*classp;
classp++;
nbytes_to_check--;
while (nbytes_to_check > 0) {
if (test_char == *classp) {
if (test_condition == IN_CLASS) {
return (CONDITION_TRUE);
} else {
return (CONDITION_FALSE);
}
} else if (*classp == THRU) {
if ((*(classp + 1) <= test_char) &&
(test_char <= *(classp + 2))) {
if (test_condition == IN_CLASS) {
return (CONDITION_TRUE);
} else {
return (CONDITION_FALSE);
}
} else {
classp += 3;
nbytes_to_check -= 3;
}
} else {
classp++;
nbytes_to_check--;
}
}
if (test_condition == NOT_IN_CLASS) {
return (CONDITION_TRUE);
} else {
return (CONDITION_FALSE);
}
}
static const char *
test_repeated_ascii_char(const char *repeat_startp, const char *stringp,
const char *regexp)
{
const char *end_of_matchp;
end_of_matchp = test_string(stringp, regexp);
while ((end_of_matchp == (char *)0) &&
(stringp > repeat_startp)) {
stringp--;
end_of_matchp = test_string(stringp, regexp);
}
return (end_of_matchp);
}
static const char *
test_repeated_multibyte_char(const char *repeat_startp, const char *stringp,
const char *regexp)
{
const char *end_of_matchp;
end_of_matchp = test_string(stringp, regexp);
while ((end_of_matchp == (char *)0) &&
(stringp > repeat_startp)) {
stringp = previous_charp(stringp);
end_of_matchp = test_string(stringp, regexp);
}
return (end_of_matchp);
}
static const char *
test_repeated_group(const char *repeat_startp, const char *stringp,
const char *regexp)
{
const char *end_of_matchp;
end_of_matchp = test_string(stringp, regexp);
while ((end_of_matchp == (char *)0) &&
(stringp > repeat_startp)) {
stringp = pop_stringp();
if (stringp == (char *)0) {
return ((char *)0);
}
end_of_matchp = test_string(stringp, regexp);
}
return (end_of_matchp);
}
static const char *
test_string(const char *stringp, const char *regexp)
{
unsigned int group_length;
int nextra_matches_allowed;
int nmust_match;
wchar_t regex_wchar;
int regex_char_size;
const char *repeat_startp;
unsigned int return_argn;
wchar_t string_wchar;
int string_char_size;
unsigned int substringn;
char_test_condition_t test_condition;
const char *test_stringp;
for (;;) {
switch ((int)*regexp) {
case ASCII_CHAR:
regexp++;
if (*regexp == *stringp) {
regexp++;
stringp++;
} else {
return ((char *)0);
}
break;
case MULTIBYTE_CHAR:
regexp++;
regex_char_size = get_wchar(®ex_wchar, regexp);
string_char_size = get_wchar(&string_wchar, stringp);
if ((string_char_size <= 0) ||
(string_wchar != regex_wchar)) {
return ((char *)0);
} else {
regexp += regex_char_size;
stringp += string_char_size;
}
break;
case ANY_CHAR:
if (!multibyte) {
if (*stringp == '\0') {
return ((char *)0);
} else {
regexp++;
stringp++;
}
} else {
string_char_size =
get_wchar(&string_wchar, stringp);
if (string_char_size <= 0) {
return ((char *)0);
} else {
regexp++;
stringp += string_char_size;
}
}
break;
case IN_ASCII_CHAR_CLASS:
case NOT_IN_ASCII_CHAR_CLASS:
if ((int)*regexp == (int)IN_ASCII_CHAR_CLASS) {
test_condition = IN_CLASS;
} else {
test_condition = NOT_IN_CLASS;
}
regexp++;
if ((*stringp != '\0') &&
(test_char_against_ascii_class(*stringp, regexp,
test_condition) == CONDITION_TRUE)) {
regexp += (int)*regexp;
stringp++;
} else {
return ((char *)0);
}
break;
case IN_MULTIBYTE_CHAR_CLASS:
case NOT_IN_MULTIBYTE_CHAR_CLASS:
if ((int)*regexp == (int)IN_MULTIBYTE_CHAR_CLASS) {
test_condition = IN_CLASS;
} else {
test_condition = NOT_IN_CLASS;
}
regexp++;
string_char_size = get_wchar(&string_wchar, stringp);
if ((string_char_size > 0) &&
(test_char_against_multibyte_class(string_wchar,
regexp, test_condition) == CONDITION_TRUE)) {
regexp += (int)*regexp;
stringp += string_char_size;
} else {
return ((char *)0);
}
break;
case IN_OLD_ASCII_CHAR_CLASS:
case NOT_IN_OLD_ASCII_CHAR_CLASS:
if ((int)*regexp == (int)IN_OLD_ASCII_CHAR_CLASS) {
test_condition = IN_CLASS;
} else {
test_condition = NOT_IN_CLASS;
}
regexp++;
if ((*stringp != '\0') &&
(test_char_against_old_ascii_class(*stringp, regexp,
test_condition) == CONDITION_TRUE)) {
regexp += (int)*regexp;
stringp++;
} else {
return ((char *)0);
}
break;
case SIMPLE_GROUP:
regexp += 2;
break;
case END_GROUP:
regexp += 2;
break;
case SAVED_GROUP:
regexp++;
substringn = (unsigned int)*regexp;
if (substringn >= NSUBSTRINGS)
return ((char *)0);
substring_startp[substringn] = stringp;
regexp++;
break;
case END_SAVED_GROUP:
regexp++;
substringn = (unsigned int)*regexp;
if (substringn >= NSUBSTRINGS)
return ((char *)0);
substring_endp[substringn] = stringp;
regexp++;
return_argn = (unsigned int)*regexp;
if (return_argn >= NSUBSTRINGS)
return ((char *)0);
return_arg_number[substringn] = return_argn;
regexp++;
break;
case ASCII_CHAR|ZERO_OR_MORE:
regexp++;
repeat_startp = stringp;
while (*stringp == *regexp) {
stringp++;
}
regexp++;
return (test_repeated_ascii_char(repeat_startp,
stringp, regexp));
case ASCII_CHAR|ONE_OR_MORE:
regexp++;
if (*stringp != *regexp) {
return ((char *)0);
} else {
stringp++;
repeat_startp = stringp;
while (*stringp == *regexp) {
stringp++;
}
regexp++;
return (test_repeated_ascii_char(repeat_startp,
stringp, regexp));
}
case ASCII_CHAR|COUNT:
regexp++;
get_match_counts(&nmust_match, &nextra_matches_allowed,
regexp + 1);
while ((*stringp == *regexp) && (nmust_match > 0)) {
nmust_match--;
stringp++;
}
if (nmust_match > 0) {
return ((char *)0);
} else if (nextra_matches_allowed == UNLIMITED) {
repeat_startp = stringp;
while (*stringp == *regexp) {
stringp++;
}
regexp += 3;
return (test_repeated_ascii_char(repeat_startp,
stringp, regexp));
} else {
repeat_startp = stringp;
while ((*stringp == *regexp) &&
(nextra_matches_allowed > 0)) {
nextra_matches_allowed--;
stringp++;
}
regexp += 3;
return (test_repeated_ascii_char(repeat_startp,
stringp, regexp));
}
case MULTIBYTE_CHAR|ZERO_OR_MORE:
regexp++;
regex_char_size = get_wchar(®ex_wchar, regexp);
repeat_startp = stringp;
string_char_size = get_wchar(&string_wchar, stringp);
while ((string_char_size > 0) &&
(string_wchar == regex_wchar)) {
stringp += string_char_size;
string_char_size =
get_wchar(&string_wchar, stringp);
}
regexp += regex_char_size;
return (test_repeated_multibyte_char(repeat_startp,
stringp, regexp));
case MULTIBYTE_CHAR|ONE_OR_MORE:
regexp++;
regex_char_size = get_wchar(®ex_wchar, regexp);
string_char_size = get_wchar(&string_wchar, stringp);
if ((string_char_size <= 0) ||
(string_wchar != regex_wchar)) {
return ((char *)0);
} else {
stringp += string_char_size;
repeat_startp = stringp;
string_char_size =
get_wchar(&string_wchar, stringp);
while ((string_char_size > 0) &&
(string_wchar == regex_wchar)) {
stringp += string_char_size;
string_char_size =
get_wchar(&string_wchar, stringp);
}
regexp += regex_char_size;
return (test_repeated_multibyte_char(
repeat_startp, stringp, regexp));
}
case MULTIBYTE_CHAR|COUNT:
regexp++;
regex_char_size = get_wchar(®ex_wchar, regexp);
get_match_counts(&nmust_match, &nextra_matches_allowed,
regexp + regex_char_size);
string_char_size = get_wchar(&string_wchar, stringp);
while ((string_char_size > 0) &&
(string_wchar == regex_wchar) &&
(nmust_match > 0)) {
nmust_match--;
stringp += string_char_size;
string_char_size =
get_wchar(&string_wchar, stringp);
}
if (nmust_match > 0) {
return ((char *)0);
} else if (nextra_matches_allowed == UNLIMITED) {
repeat_startp = stringp;
while ((string_char_size > 0) &&
(string_wchar == regex_wchar)) {
stringp += string_char_size;
string_char_size =
get_wchar(&string_wchar, stringp);
}
regexp += regex_char_size + 2;
return (test_repeated_multibyte_char(
repeat_startp, stringp, regexp));
} else {
repeat_startp = stringp;
while ((string_char_size > 0) &&
(string_wchar == regex_wchar) &&
(nextra_matches_allowed > 0)) {
nextra_matches_allowed--;
stringp += string_char_size;
string_char_size =
get_wchar(&string_wchar, stringp);
}
regexp += regex_char_size + 2;
return (test_repeated_multibyte_char(
repeat_startp, stringp, regexp));
}
case ANY_CHAR|ZERO_OR_MORE:
repeat_startp = stringp;
if (!multibyte) {
while (*stringp != '\0') {
stringp++;
}
regexp++;
return (test_repeated_ascii_char(repeat_startp,
stringp, regexp));
} else {
string_char_size =
get_wchar(&string_wchar, stringp);
while (string_char_size > 0) {
stringp += string_char_size;
string_char_size =
get_wchar(&string_wchar, stringp);
}
regexp++;
return (test_repeated_multibyte_char(
repeat_startp, stringp, regexp));
}
case ANY_CHAR|ONE_OR_MORE:
if (!multibyte) {
if (*stringp == '\0') {
return ((char *)0);
} else {
stringp++;
repeat_startp = stringp;
while (*stringp != '\0') {
stringp++;
}
regexp++;
return (test_repeated_ascii_char(
repeat_startp, stringp, regexp));
}
} else {
string_char_size =
get_wchar(&string_wchar, stringp);
if (string_char_size <= 0) {
return ((char *)0);
} else {
stringp += string_char_size;
repeat_startp = stringp;
string_char_size =
get_wchar(&string_wchar, stringp);
while (string_char_size > 0) {
stringp += string_char_size;
string_char_size =
get_wchar(&string_wchar,
stringp);
}
regexp++;
return (test_repeated_multibyte_char(
repeat_startp, stringp, regexp));
}
}
case ANY_CHAR|COUNT:
get_match_counts(&nmust_match, &nextra_matches_allowed,
regexp + 1);
if (!multibyte) {
while ((*stringp != '\0') &&
(nmust_match > 0)) {
nmust_match--;
stringp++;
}
if (nmust_match > 0) {
return ((char *)0);
} else if (nextra_matches_allowed ==
UNLIMITED) {
repeat_startp = stringp;
while (*stringp != '\0') {
stringp++;
}
regexp += 3;
return (test_repeated_ascii_char(
repeat_startp, stringp, regexp));
} else {
repeat_startp = stringp;
while ((*stringp != '\0') &&
(nextra_matches_allowed > 0)) {
nextra_matches_allowed--;
stringp++;
}
regexp += 3;
return (test_repeated_ascii_char(
repeat_startp, stringp, regexp));
}
} else {
string_char_size =
get_wchar(&string_wchar, stringp);
while ((string_char_size > 0) &&
(nmust_match > 0)) {
nmust_match--;
stringp += string_char_size;
string_char_size =
get_wchar(&string_wchar, stringp);
}
if (nmust_match > 0) {
return ((char *)0);
} else if (nextra_matches_allowed ==
UNLIMITED) {
repeat_startp = stringp;
while (string_char_size > 0) {
stringp += string_char_size;
string_char_size =
get_wchar(&string_wchar,
stringp);
}
regexp += 3;
return (test_repeated_multibyte_char(
repeat_startp, stringp, regexp));
} else {
repeat_startp = stringp;
while ((string_char_size > 0) &&
(nextra_matches_allowed > 0)) {
nextra_matches_allowed--;
stringp += string_char_size;
string_char_size =
get_wchar(&string_wchar,
stringp);
}
regexp += 3;
return (test_repeated_multibyte_char(
repeat_startp, stringp, regexp));
}
}
case IN_ASCII_CHAR_CLASS|ZERO_OR_MORE:
case NOT_IN_ASCII_CHAR_CLASS|ZERO_OR_MORE:
if ((int)*regexp == (int)(IN_ASCII_CHAR_CLASS|ZERO_OR_MORE)) {
test_condition = IN_CLASS;
} else {
test_condition = NOT_IN_CLASS;
}
regexp++;
repeat_startp = stringp;
while ((*stringp != '\0') &&
(test_char_against_ascii_class(*stringp, regexp,
test_condition) == CONDITION_TRUE)) {
stringp++;
}
regexp += (int)*regexp;
return (test_repeated_ascii_char(repeat_startp, stringp,
regexp));
case IN_ASCII_CHAR_CLASS|ONE_OR_MORE:
case NOT_IN_ASCII_CHAR_CLASS|ONE_OR_MORE:
if ((int)*regexp ==
(int)(IN_ASCII_CHAR_CLASS|ONE_OR_MORE)) {
test_condition = IN_CLASS;
} else {
test_condition = NOT_IN_CLASS;
}
regexp++;
if ((*stringp == '\0') ||
(test_char_against_ascii_class(*stringp, regexp,
test_condition) != CONDITION_TRUE)) {
return ((char *)0);
} else {
stringp++;
repeat_startp = stringp;
while ((*stringp != '\0') &&
(test_char_against_ascii_class(*stringp,
regexp, test_condition) ==
CONDITION_TRUE)) {
stringp++;
}
regexp += (int)*regexp;
return (test_repeated_ascii_char(repeat_startp,
stringp, regexp));
}
case IN_ASCII_CHAR_CLASS | COUNT:
case NOT_IN_ASCII_CHAR_CLASS | COUNT:
if ((int)*regexp == (int)(IN_ASCII_CHAR_CLASS|COUNT)) {
test_condition = IN_CLASS;
} else {
test_condition = NOT_IN_CLASS;
}
regexp++;
get_match_counts(&nmust_match, &nextra_matches_allowed,
regexp + (int)*regexp);
while ((*stringp != '\0') &&
(test_char_against_ascii_class(*stringp, regexp,
test_condition) == CONDITION_TRUE) &&
(nmust_match > 0)) {
nmust_match--;
stringp++;
}
if (nmust_match > 0) {
return ((char *)0);
} else if (nextra_matches_allowed == UNLIMITED) {
repeat_startp = stringp;
while ((*stringp != '\0') &&
(test_char_against_ascii_class(*stringp,
regexp, test_condition) ==
CONDITION_TRUE)) {
stringp++;
}
regexp += (int)*regexp + 2;
return (test_repeated_ascii_char(repeat_startp,
stringp, regexp));
} else {
repeat_startp = stringp;
while ((*stringp != '\0') &&
(test_char_against_ascii_class(*stringp,
regexp, test_condition) ==
CONDITION_TRUE) &&
(nextra_matches_allowed > 0)) {
nextra_matches_allowed--;
stringp++;
}
regexp += (int)*regexp + 2;
return (test_repeated_ascii_char(repeat_startp,
stringp, regexp));
}
case IN_MULTIBYTE_CHAR_CLASS|ZERO_OR_MORE:
case NOT_IN_MULTIBYTE_CHAR_CLASS|ZERO_OR_MORE:
if ((int)*regexp ==
(int)(IN_MULTIBYTE_CHAR_CLASS|ZERO_OR_MORE)) {
test_condition = IN_CLASS;
} else {
test_condition = NOT_IN_CLASS;
}
regexp++;
repeat_startp = stringp;
string_char_size = get_wchar(&string_wchar, stringp);
while ((string_char_size > 0) &&
(test_char_against_multibyte_class(string_wchar,
regexp, test_condition) == CONDITION_TRUE)) {
stringp += string_char_size;
string_char_size =
get_wchar(&string_wchar, stringp);
}
regexp += (int)*regexp;
return (test_repeated_multibyte_char(repeat_startp,
stringp, regexp));
case IN_MULTIBYTE_CHAR_CLASS|ONE_OR_MORE:
case NOT_IN_MULTIBYTE_CHAR_CLASS|ONE_OR_MORE:
if ((int)*regexp ==
(int)(IN_MULTIBYTE_CHAR_CLASS|ONE_OR_MORE)) {
test_condition = IN_CLASS;
} else {
test_condition = NOT_IN_CLASS;
}
regexp++;
string_char_size = get_wchar(&string_wchar, stringp);
if ((string_char_size <= 0) ||
(test_char_against_multibyte_class(string_wchar,
regexp, test_condition) != CONDITION_TRUE)) {
return ((char *)0);
} else {
stringp += string_char_size;
repeat_startp = stringp;
string_char_size =
get_wchar(&string_wchar, stringp);
while ((string_char_size > 0) &&
(test_char_against_multibyte_class(
string_wchar, regexp, test_condition) ==
CONDITION_TRUE)) {
stringp += string_char_size;
string_char_size =
get_wchar(&string_wchar, stringp);
}
regexp += (int)*regexp;
return (test_repeated_multibyte_char(
repeat_startp, stringp, regexp));
}
case IN_MULTIBYTE_CHAR_CLASS|COUNT:
case NOT_IN_MULTIBYTE_CHAR_CLASS|COUNT:
if ((int)*regexp ==
(int)(IN_MULTIBYTE_CHAR_CLASS|COUNT)) {
test_condition = IN_CLASS;
} else {
test_condition = NOT_IN_CLASS;
}
regexp++;
get_match_counts(&nmust_match, &nextra_matches_allowed,
regexp + (int)*regexp);
string_char_size = get_wchar(&string_wchar, stringp);
while ((string_char_size > 0) &&
(test_char_against_multibyte_class(string_wchar,
regexp, test_condition) == CONDITION_TRUE) &&
(nmust_match > 0)) {
nmust_match--;
stringp += string_char_size;
string_char_size =
get_wchar(&string_wchar, stringp);
}
if (nmust_match > 0) {
return ((char *)0);
} else if (nextra_matches_allowed == UNLIMITED) {
repeat_startp = stringp;
while ((string_char_size > 0) &&
(test_char_against_multibyte_class(
string_wchar, regexp, test_condition) ==
CONDITION_TRUE)) {
stringp += string_char_size;
string_char_size =
get_wchar(&string_wchar, stringp);
}
regexp += (int)*regexp + 2;
return (test_repeated_multibyte_char(
repeat_startp, stringp, regexp));
} else {
repeat_startp = stringp;
while ((string_char_size > 0) &&
(test_char_against_multibyte_class(
string_wchar, regexp, test_condition) ==
CONDITION_TRUE) &&
(nextra_matches_allowed > 0)) {
nextra_matches_allowed--;
stringp += string_char_size;
string_char_size =
get_wchar(&string_wchar, stringp);
}
regexp += (int)*regexp + 2;
return (test_repeated_multibyte_char(
repeat_startp, stringp, regexp));
}
case IN_OLD_ASCII_CHAR_CLASS|ZERO_OR_MORE:
case NOT_IN_OLD_ASCII_CHAR_CLASS|ZERO_OR_MORE:
if ((int)*regexp ==
(int)(IN_OLD_ASCII_CHAR_CLASS|ZERO_OR_MORE)) {
test_condition = IN_CLASS;
} else {
test_condition = NOT_IN_CLASS;
}
regexp++;
repeat_startp = stringp;
while ((*stringp != '\0') &&
(test_char_against_old_ascii_class(*stringp, regexp,
test_condition) == CONDITION_TRUE)) {
stringp++;
}
regexp += (int)*regexp;
return (test_repeated_ascii_char(repeat_startp, stringp,
regexp));
case IN_OLD_ASCII_CHAR_CLASS|ONE_OR_MORE:
case NOT_IN_OLD_ASCII_CHAR_CLASS|ONE_OR_MORE:
if ((int)*regexp ==
(int)(IN_OLD_ASCII_CHAR_CLASS|ONE_OR_MORE)) {
test_condition = IN_CLASS;
} else {
test_condition = NOT_IN_CLASS;
}
regexp++;
if ((*stringp == '\0') ||
(test_char_against_old_ascii_class(*stringp, regexp,
test_condition) != CONDITION_TRUE)) {
return ((char *)0);
} else {
stringp++;
repeat_startp = stringp;
while ((*stringp != '\0') &&
(test_char_against_old_ascii_class(*stringp,
regexp, test_condition) ==
CONDITION_TRUE)) {
stringp++;
}
regexp += (int)*regexp;
return (test_repeated_ascii_char(repeat_startp,
stringp, regexp));
}
case IN_OLD_ASCII_CHAR_CLASS|COUNT:
case NOT_IN_OLD_ASCII_CHAR_CLASS|COUNT:
if ((int)*regexp ==
(int)(IN_OLD_ASCII_CHAR_CLASS|COUNT)) {
test_condition = IN_CLASS;
} else {
test_condition = NOT_IN_CLASS;
}
regexp++;
get_match_counts(&nmust_match, &nextra_matches_allowed,
regexp + (int)*regexp);
while ((*stringp != '\0') &&
(test_char_against_old_ascii_class(*stringp, regexp,
test_condition) == CONDITION_TRUE) &&
(nmust_match > 0)) {
nmust_match--;
stringp++;
}
if (nmust_match > 0) {
return ((char *)0);
} else if (nextra_matches_allowed == UNLIMITED) {
repeat_startp = stringp;
while ((*stringp != '\0') &&
(test_char_against_old_ascii_class(*stringp,
regexp,
test_condition) == CONDITION_TRUE)) {
stringp++;
}
regexp += (int)*regexp + 2;
return (test_repeated_ascii_char(repeat_startp,
stringp, regexp));
} else {
repeat_startp = stringp;
while ((*stringp != '\0') &&
(test_char_against_old_ascii_class(*stringp,
regexp,
test_condition) == CONDITION_TRUE) &&
(nextra_matches_allowed > 0)) {
nextra_matches_allowed--;
stringp++;
}
regexp += (int)*regexp + 2;
return (test_repeated_ascii_char(repeat_startp,
stringp, regexp));
}
case ZERO_OR_MORE_GROUP:
case ZERO_OR_MORE_GROUP|ADD_256_TO_GROUP_LENGTH:
case ZERO_OR_MORE_GROUP|ADD_512_TO_GROUP_LENGTH:
case ZERO_OR_MORE_GROUP|ADD_768_TO_GROUP_LENGTH:
group_length =
(((unsigned int)*regexp & ADDED_LENGTH_BITS) <<
TIMES_256_SHIFT);
regexp++;
group_length += (unsigned int)*regexp;
regexp++;
repeat_startp = stringp;
test_stringp = test_string(stringp, regexp);
while (test_stringp != (char *)0) {
if (push_stringp(stringp) == (char *)0)
return ((char *)0);
stringp = test_stringp;
test_stringp = test_string(stringp, regexp);
}
regexp += group_length;
return (test_repeated_group(repeat_startp, stringp,
regexp));
case END_GROUP|ZERO_OR_MORE:
return ((char *)stringp);
case ONE_OR_MORE_GROUP:
case ONE_OR_MORE_GROUP|ADD_256_TO_GROUP_LENGTH:
case ONE_OR_MORE_GROUP|ADD_512_TO_GROUP_LENGTH:
case ONE_OR_MORE_GROUP|ADD_768_TO_GROUP_LENGTH:
group_length =
(((unsigned int)*regexp & ADDED_LENGTH_BITS) <<
TIMES_256_SHIFT);
regexp++;
group_length += (unsigned int)*regexp;
regexp++;
stringp = test_string(stringp, regexp);
if (stringp == (char *)0)
return ((char *)0);
repeat_startp = stringp;
test_stringp = test_string(stringp, regexp);
while (test_stringp != (char *)0) {
if (push_stringp(stringp) == (char *)0)
return ((char *)0);
stringp = test_stringp;
test_stringp = test_string(stringp, regexp);
}
regexp += group_length;
return (test_repeated_group(repeat_startp, stringp,
regexp));
case END_GROUP|ONE_OR_MORE:
return ((char *)stringp);
case COUNTED_GROUP:
case COUNTED_GROUP|ADD_256_TO_GROUP_LENGTH:
case COUNTED_GROUP|ADD_512_TO_GROUP_LENGTH:
case COUNTED_GROUP|ADD_768_TO_GROUP_LENGTH:
group_length =
(((unsigned int)*regexp & ADDED_LENGTH_BITS) <<
TIMES_256_SHIFT);
regexp++;
group_length += (unsigned int)*regexp;
regexp++;
get_match_counts(&nmust_match, &nextra_matches_allowed,
regexp + group_length);
test_stringp = test_string(stringp, regexp);
while ((test_stringp != NULL) && (nmust_match > 0)) {
stringp = test_stringp;
nmust_match--;
test_stringp = test_string(stringp, regexp);
}
if (nmust_match > 0) {
return ((char *)0);
} else if (nextra_matches_allowed == UNLIMITED) {
repeat_startp = stringp;
while (test_stringp != (char *)0) {
if (push_stringp(stringp) == (char *)0)
return ((char *)0);
stringp = test_stringp;
test_stringp = test_string(stringp,
regexp);
}
regexp += group_length + 2;
return (test_repeated_group(repeat_startp,
stringp, regexp));
} else {
repeat_startp = stringp;
while ((test_stringp != (char *)0) &&
(nextra_matches_allowed > 0)) {
nextra_matches_allowed--;
if (push_stringp(stringp) == (char *)0)
return ((char *)0);
stringp = test_stringp;
test_stringp =
test_string(stringp, regexp);
}
regexp += group_length + 2;
return (test_repeated_group(repeat_startp,
stringp, regexp));
}
case END_GROUP|COUNT:
return (stringp);
case END_OF_STRING_MARK:
if (*stringp == '\0') {
regexp++;
} else {
return ((char *)0);
}
break;
case END_REGEX:
return (stringp);
default:
return ((char *)0);
}
}
}