regc_locale.c

来自「A*算法 A*算法 A*算法 A*算法A*算法A*算法」· C语言 代码 · 共 1,179 行 · 第 1/4 页

C
1,179
字号

#else   /* wxUSE_UNICODE */

#include <locale.h>

typedef int (*isfunc_t)(int);

/* ASCII character-class table */
static struct cclass {
    char *name;
    char *chars;
    int hasch;
    isfunc_t isfunc;
} cclasses[] = {
    {"alnum",   "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\
0123456789",                1,  isalnum},
    {"alpha",   "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",
                    1,  isalpha},
    {"blank",   " \t",      0,  NULL},
    {"cntrl",   "\007\b\t\n\v\f\r\1\2\3\4\5\6\16\17\20\21\22\23\24\
\25\26\27\30\31\32\33\34\35\36\37\177", 0, iscntrl},
    {"digit",   "0123456789",   0,  isdigit},
    {"graph",   "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\
0123456789!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~",
                    1,  isgraph},
    {"lower",   "abcdefghijklmnopqrstuvwxyz",
                    1,  islower},
    {"print",   "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\
0123456789!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~ ",
                    1,  isprint},
    {"punct",   "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~",
                    0,  ispunct},
    {"space",   "\t\n\v\f\r ",  0,  isspace},
    {"upper",   "ABCDEFGHIJKLMNOPQRSTUVWXYZ",
                    0,  isupper},
    {"xdigit",  "0123456789ABCDEFabcdef",
                    0,  isxdigit},
    {NULL,      0,      0, NULL}
};

/*
 * Supply implementations for some tcl functions that this module depends on
 * to make it self contained
 */

#define Tcl_UniChar wxChar
Tcl_UniChar Tcl_UniCharToUpper(int ch) { return wxToupper(ch); }
Tcl_UniChar Tcl_UniCharToLower(int ch) { return wxTolower(ch); }
Tcl_UniChar Tcl_UniCharToTitle(int ch) { return wxToupper(ch); }

#endif  /* !wxUSE_UNICODE */

#define	CH	NOCELT

/*
 - nmcces - how many distinct MCCEs are there?
 ^ static int nmcces(struct vars *);
 */
static int
nmcces(v)
    struct vars *v;			/* context */
{
    /*
     * No multi-character collating elements defined at the moment.
     */
    return 0;
}

/*
 - nleaders - how many chrs can be first chrs of MCCEs?
 ^ static int nleaders(struct vars *);
 */
static int
nleaders(v)
    struct vars *v;			/* context */
{
    return 0;
}

/*
 - allmcces - return a cvec with all the MCCEs of the locale
 ^ static struct cvec *allmcces(struct vars *, struct cvec *);
 */
static struct cvec *
allmcces(v, cv)
    struct vars *v;			/* context */
    struct cvec *cv;			/* this is supposed to have enough room */
{
    return clearcvec(cv);
}

/*
 - element - map collating-element name to celt
 ^ static celt element(struct vars *, chr *, chr *);
 */
static celt
element(v, startp, endp)
    struct vars *v;			/* context */
    chr *startp;			/* points to start of name */
    chr *endp;				/* points just past end of name */
{
    struct cname *cn;
    size_t len;

    /* generic:  one-chr names stand for themselves */
    assert(startp < endp);
    len = endp - startp;
    if (len == 1) {
	return *startp;
    }

    NOTE(REG_ULOCALE);

    /* search table */
    for (cn=cnames; cn->name!=NULL; cn++) {
	if (wxStrlen_(cn->name)==len && wxStrncmp(cn->name, startp, len)==0) {
	    break;			/* NOTE BREAK OUT */
	}
    }
    if (cn->name != NULL) {
	return CHR(cn->code);
    }

    /* couldn't find it */
    ERR(REG_ECOLLATE);
    return 0;
}

/*
 - range - supply cvec for a range, including legality check
 ^ static struct cvec *range(struct vars *, celt, celt, int);
 */
static struct cvec *
range(v, a, b, cases)
    struct vars *v;			/* context */
    celt a;				/* range start */
    celt b;				/* range end, might equal a */
    int cases;				/* case-independent? */
{
    int nchrs;
    struct cvec *cv;
    celt c, lc, uc, tc;

    if (a != b && !before(a, b)) {
	ERR(REG_ERANGE);
	return NULL;
    }

    if (!cases) {			/* easy version */
	cv = getcvec(v, 0, 1, 0);
	NOERRN();
	addrange(cv, a, b);
	return cv;
    }

    /*
     * When case-independent, it's hard to decide when cvec ranges are
     * usable, so for now at least, we won't try.  We allocate enough
     * space for two case variants plus a little extra for the two
     * title case variants.
     */

    nchrs = (b - a + 1)*2 + 4;

    cv = getcvec(v, nchrs, 0, 0);
    NOERRN();

    for (c=a; c<=b; c++) {
	addchr(cv, c);
	lc = Tcl_UniCharToLower((chr)c);
	uc = Tcl_UniCharToUpper((chr)c);
	tc = Tcl_UniCharToTitle((chr)c);
	if (c != lc) {
	    addchr(cv, lc);
	}
	if (c != uc) {
	    addchr(cv, uc);
	}
	if (c != tc && tc != uc) {
	    addchr(cv, tc);
	}
    }

    return cv;
}

/*
 - before - is celt x before celt y, for purposes of range legality?
 ^ static int before(celt, celt);
 */
static int				/* predicate */
before(x, y)
    celt x, y;				/* collating elements */
{
    /* trivial because no MCCEs */
    if (x < y) {
	return 1;
    }
    return 0;
}

/*
 - eclass - supply cvec for an equivalence class
 * Must include case counterparts on request.
 ^ static struct cvec *eclass(struct vars *, celt, int);
 */
static struct cvec *
eclass(v, c, cases)
    struct vars *v;			/* context */
    celt c;				/* Collating element representing
					 * the equivalence class. */
    int cases;				/* all cases? */
{
    struct cvec *cv;

    /* crude fake equivalence class for testing */
    if ((v->cflags&REG_FAKE) && c == 'x') {
	cv = getcvec(v, 4, 0, 0);
	addchr(cv, (chr)'x');
	addchr(cv, (chr)'y');
	if (cases) {
	    addchr(cv, (chr)'X');
	    addchr(cv, (chr)'Y');
	}
	return cv;
    }

    /* otherwise, none */
    if (cases) {
	return allcases(v, c);
    }
    cv = getcvec(v, 1, 0, 0);
    assert(cv != NULL);
    addchr(cv, (chr)c);
    return cv;
}

#if wxUSE_UNICODE

/*
 - cclass - supply cvec for a character class
 * Must include case counterparts on request.
 ^ static struct cvec *cclass(struct vars *, chr *, chr *, int);
 */
static struct cvec *
cclass(v, startp, endp, cases)
    struct vars *v;			/* context */
    chr *startp;			/* where the name starts */
    chr *endp;				/* just past the end of the name */
    int cases;				/* case-independent? */
{
    size_t len;
    struct cvec *cv = NULL;
    CONST chr *np;
    chr **namePtr;
    int i, index;

    /*
     * The following arrays define the valid character class names.
     */

    static chr *classNames[] = {
	_T("alnum"), _T("alpha"), _T("ascii"), _T("blank"), _T("cntrl"), _T("digit"), _T("graph"),
	_T("lower"), _T("print"), _T("punct"), _T("space"), _T("upper"), _T("xdigit"), NULL
    };

    enum classes {
	CC_ALNUM, CC_ALPHA, CC_ASCII, CC_BLANK, CC_CNTRL, CC_DIGIT, CC_GRAPH,
	CC_LOWER, CC_PRINT, CC_PUNCT, CC_SPACE, CC_UPPER, CC_XDIGIT
    };
    

    /*
     * Extract the class name
     */

    len = endp - startp;
    np = startp;

    /*
     * Remap lower and upper to alpha if the match is case insensitive.
     */

    if (cases && len == 5 && (wxStrncmp(_T("lower"), np, 5) == 0
	    || wxStrncmp(_T("upper"), np, 5) == 0)) {
	np = _T("alpha");
    }

    /*
     * Map the name to the corresponding enumerated value.
     */

    index = -1;
    for (namePtr=classNames,i=0 ; *namePtr!=NULL ; namePtr++,i++) {
	if ((wxStrlen_(*namePtr) == len) && (wxStrncmp(*namePtr, np, len) == 0)) {

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?