#include "uscanset.h"
static UBool
u_scanf_scanset_add(u_scanf_scanset *scanset,
UChar c)
{
if(scanset->single_count == U_SCANF_MAX_SCANSET_SIZE - 1)
return FALSE;
scanset->singles[scanset->single_count++] = c;
return TRUE;
}
static UBool
u_scanf_scanset_addrange(u_scanf_scanset *scanset,
UChar start,
UChar end)
{
if(scanset->pair_count == U_SCANF_MAX_SCANSET_SIZE - 1)
return FALSE;
if (end < start) {
UChar temp = end;
end = start;
start = temp;
}
scanset->pairs[scanset->pair_count].start = start;
scanset->pairs[scanset->pair_count].end = end;
scanset->pair_count++;
return TRUE;
}
UBool
u_scanf_scanset_init(u_scanf_scanset *scanset,
const UChar *s,
int32_t *len)
{
UChar c;
const UChar *limit;
int32_t count;
UBool result = FALSE;
limit = s + *len;
count = 0;
scanset->single_count = 0;
scanset->pair_count = 0;
scanset->is_inclusive = TRUE;
if(*s == 0x005E) {
scanset->is_inclusive = FALSE;
++s;
++count;
}
else if(*s == 0x005D) {
result = u_scanf_scanset_add(scanset, *s++);
++count;
}
if( ! scanset->is_inclusive && *s == 0x005D) {
result = u_scanf_scanset_add(scanset, *s++);
++count;
}
while(s < limit) {
c = *s++;
if(c == 0x005D)
break;
if(*s == 0x002D && *(s+1) != 0x005D) {
result = u_scanf_scanset_addrange(scanset, c, *(s+1));
s += 2;
count += 2;
}
else {
result = u_scanf_scanset_add(scanset, c);
}
++count;
}
*len = count;
return result;
}
UBool
u_scanf_scanset_in(u_scanf_scanset *scanset,
UChar c)
{
int i;
if(scanset->is_inclusive) {
for(i = 0; i < scanset->single_count; ++i) {
if(c == scanset->singles[i]) {
return TRUE;
}
}
for(i = 0; i < scanset->pair_count; ++i) {
if(c >= scanset->pairs[i].start && c <= scanset->pairs[i].end) {
return TRUE;
}
}
return FALSE;
}
else {
for(i = 0; i < scanset->single_count; ++i) {
if(c == scanset->singles[i]) {
return FALSE;
}
}
for(i = 0; i < scanset->pair_count; ++i) {
if(c >= scanset->pairs[i].start && c <= scanset->pairs[i].end) {
return FALSE;
}
}
return TRUE;
}
}