#include <xterm.h>
#include <charclass.h>
#if OPT_WIDE_CHARS
static struct classentry {
int cclass;
int first;
int last;
} *classtab;
int
SetCharacterClassRange(int low, int high, int value)
{
if (high < low)
return -1;
if (classtab[0].last > classtab[0].cclass - 2) {
classtab[0].cclass += 5 + classtab[0].cclass / 4;
classtab = TypeRealloc(struct classentry, (unsigned) classtab[0].cclass, classtab);
if (!classtab)
abort();
}
classtab[0].last++;
classtab[classtab[0].last].first = low;
classtab[classtab[0].last].last = high;
classtab[classtab[0].last].cclass = value;
return 0;
}
typedef enum {
IDENT = -1,
ALNUM = 48,
CNTRL = 1,
BLANK = 32
} Classes;
void
init_classtab(void)
{
const int size = 50;
classtab = TypeMallocN(struct classentry, size);
if (!classtab)
abort();
classtab[0].cclass = size;
classtab[0].first = 1;
classtab[0].last = 0;
SetCharacterClassRange(0, 0, BLANK);
SetCharacterClassRange(1, 31, CNTRL);
SetCharacterClassRange('\t', '\t', BLANK);
SetCharacterClassRange('0', '9', ALNUM);
SetCharacterClassRange('A', 'Z', ALNUM);
SetCharacterClassRange('_', '_', ALNUM);
SetCharacterClassRange('a', 'z', ALNUM);
SetCharacterClassRange(127, 159, CNTRL);
SetCharacterClassRange(160, 191, IDENT);
SetCharacterClassRange(192, 255, ALNUM);
SetCharacterClassRange(215, 215, IDENT);
SetCharacterClassRange(247, 247, IDENT);
SetCharacterClassRange(0x0100, 0xffdf, ALNUM);
SetCharacterClassRange(0x037e, 0x037e, IDENT);
SetCharacterClassRange(0x0387, 0x0387, IDENT);
SetCharacterClassRange(0x055a, 0x055f, IDENT);
SetCharacterClassRange(0x0589, 0x0589, IDENT);
SetCharacterClassRange(0x0700, 0x070d, IDENT);
SetCharacterClassRange(0x104a, 0x104f, IDENT);
SetCharacterClassRange(0x10fb, 0x10fb, IDENT);
SetCharacterClassRange(0x1361, 0x1368, IDENT);
SetCharacterClassRange(0x166d, 0x166e, IDENT);
SetCharacterClassRange(0x17d4, 0x17dc, IDENT);
SetCharacterClassRange(0x1800, 0x180a, IDENT);
SetCharacterClassRange(0x2000, 0x200a, BLANK);
SetCharacterClassRange(0x200b, 0x27ff, IDENT);
SetCharacterClassRange(0x2070, 0x207f, 0x2070);
SetCharacterClassRange(0x2080, 0x208f, 0x2080);
SetCharacterClassRange(0x3000, 0x3000, BLANK);
SetCharacterClassRange(0x3001, 0x3020, IDENT);
SetCharacterClassRange(0x3040, 0x309f, 0x3040);
SetCharacterClassRange(0x30a0, 0x30ff, 0x30a0);
SetCharacterClassRange(0x3300, 0x9fff, 0x4e00);
SetCharacterClassRange(0xac00, 0xd7a3, 0xac00);
SetCharacterClassRange(0xf900, 0xfaff, 0x4e00);
SetCharacterClassRange(0xfe30, 0xfe6b, IDENT);
SetCharacterClassRange(0xff00, 0xff0f, IDENT);
SetCharacterClassRange(0xff1a, 0xff20, IDENT);
SetCharacterClassRange(0xff3b, 0xff40, IDENT);
SetCharacterClassRange(0xff5b, 0xff64, IDENT);
return;
}
int
CharacterClass(int c)
{
int i, cclass = IDENT;
for (i = classtab[0].first; i <= classtab[0].last; i++)
if (classtab[i].first <= c && classtab[i].last >= c)
cclass = classtab[i].cclass;
if (cclass < 0)
cclass = c;
return cclass;
}
#ifdef NO_LEAKS
void
noleaks_CharacterClass(void)
{
if (classtab != 0) {
free(classtab);
classtab = 0;
}
}
#endif
#endif