github.com/afumu/libc@v0.0.6/musl/src/ctype/towctrans.c (about)

     1  #include <wctype.h>
     2  
     3  static const unsigned char tab[];
     4  
     5  static const unsigned char rulebases[512];
     6  static const int rules[];
     7  
     8  static const unsigned char exceptions[][2];
     9  
    10  #include "casemap.h"
    11  
    12  static int casemap(unsigned c, int dir)
    13  {
    14  	unsigned b, x, y, v, rt, xb, xn;
    15  	int r, rd, c0 = c;
    16  
    17  	if (c >= 0x20000) return c;
    18  
    19  	b = c>>8;
    20  	c &= 255;
    21  	x = c/3;
    22  	y = c%3;
    23  
    24  	/* lookup entry in two-level base-6 table */
    25  	v = tab[tab[b]*86+x];
    26  	static const int mt[] = { 2048, 342, 57 };
    27  	v = (v*mt[y]>>11)%6;
    28  
    29  	/* use the bit vector out of the tables as an index into
    30  	 * a block-specific set of rules and decode the rule into
    31  	 * a type and a case-mapping delta. */
    32  	r = rules[rulebases[b]+v];
    33  	rt = r & 255;
    34  	rd = r >> 8;
    35  
    36  	/* rules 0/1 are simple lower/upper case with a delta.
    37  	 * apply according to desired mapping direction. */
    38  	if (rt < 2) return c0 + (rd & -(rt^dir));
    39  
    40  	/* binary search. endpoints of the binary search for
    41  	 * this block are stored in the rule delta field. */
    42  	xn = rd & 0xff;
    43  	xb = (unsigned)rd >> 8;
    44  	while (xn) {
    45  		unsigned try = exceptions[xb+xn/2][0];
    46  		if (try == c) {
    47  			r = rules[exceptions[xb+xn/2][1]];
    48  			rt = r & 255;
    49  			rd = r >> 8;
    50  			if (rt < 2) return c0 + (rd & -(rt^dir));
    51  			/* Hard-coded for the four exceptional titlecase */
    52  			return c0 + (dir ? -1 : 1);
    53  		} else if (try > c) {
    54  			xn /= 2;
    55  		} else {
    56  			xb += xn/2;
    57  			xn -= xn/2;
    58  		}
    59  	}
    60  	return c0;
    61  }
    62  
    63  wint_t towlower(wint_t wc)
    64  {
    65  	return casemap(wc, 0);
    66  }
    67  
    68  wint_t towupper(wint_t wc)
    69  {
    70  	return casemap(wc, 1);
    71  }
    72  
    73  wint_t __towupper_l(wint_t c, locale_t l)
    74  {
    75  	return towupper(c);
    76  }
    77  
    78  wint_t __towlower_l(wint_t c, locale_t l)
    79  {
    80  	return towlower(c);
    81  }
    82  
    83  weak_alias(__towupper_l, towupper_l);
    84  weak_alias(__towlower_l, towlower_l);