#include <sys/ctype.h>

/* Lookup table for character classification (7-bit ASCII) */
static const unsigned char ctype_table[128] = {
    /* 0x00 */ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
    /* 0x08 */ 0x20, 0x28, 0x28, 0x28, 0x28, 0x28, 0x20, 0x20,
    /* 0x10 */ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
    /* 0x18 */ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
    /* 0x20 */ 0x48, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
    /* 0x28 */ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
    /* 0x30 */ 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
    /* 0x38 */ 0x84, 0x84, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
    /* 0x40 */ 0x10, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x01,
    /* 0x48 */ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
    /* 0x50 */ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
    /* 0x58 */ 0x01, 0x01, 0x01, 0x10, 0x10, 0x10, 0x10, 0x10,
    /* 0x60 */ 0x10, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x02,
    /* 0x68 */ 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
    /* 0x70 */ 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
    /* 0x78 */ 0x02, 0x02, 0x02, 0x10, 0x10, 0x10, 0x10, 0x20
};

/* Bitmask definitions for the lookup table */
#define CT_UP    0x01  /* Upper case */
#define CT_LOW   0x02  /* Lower case */
#define CT_DIG   0x04  /* Digit */
#define CT_CTL   0x08  /* Control */
#define CT_PUN   0x10  /* Punctuation */
#define CT_WHT   0x20  /* White space (space/cr/lf/tab) */
#define CT_HEX   0x40  /* Hex digit */
#define CT_SP    0x80  /* Hard space (0x20) */

int isalnum(int c) {
    return (c >= 0 && c < 128) && (ctype_table[c] & (CT_UP | CT_LOW | CT_DIG));
}

int isalpha(int c) {
    return (c >= 0 && c < 128) && (ctype_table[c] & (CT_UP | CT_LOW));
}

int isblank(int c) {
    return (c == ' ' || c == '\t');
}

int iscntrl(int c) {
    return (c >= 0 && c < 32) || c == 127;
}

int isdigit(int c) {
    return (c >= '0' && c <= '9');
}

int isgraph(int c) {
    return (c >= 0 && c < 128) && (ctype_table[c] & (CT_UP | CT_LOW | CT_DIG | CT_PUN));
}

int islower(int c) {
    return (c >= 'a' && c <= 'z');
}

int isprint(int c) {
    return (c >= 32 && c < 127);
}

int ispunct(int c) {
    return (c >= 0 && c < 128) && (ctype_table[c] & CT_PUN);
}

int isspace(int c) {
    return (c == ' ' || c == '\t' || c == '\n' || 
            c == '\r' || c == '\f' || c == '\v');
}

int isupper(int c) {
    return (c >= 'A' && c <= 'Z');
}

int isxdigit(int c) {
    return isdigit(c) || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F');
}

int tolower(int c) {
    if (isupper(c)) {
        return c + ('a' - 'A');
    }
    return c;
}

int toupper(int c) {
    if (islower(c)) {
        return c - ('a' - 'A');
    }
    return c;
}

/* POSIX extensions */
int isascii(int c) {
    return (c >= 0 && c <= 127);
}

int toascii(int c) {
    return (c & 0x7F);
}
