summaryrefslogtreecommitdiff
path: root/nonstd/static/locale.h
blob: e96b0376108b41b9f92a325d008c7b198a18f45e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
#include <limits.h>
#include "nonstd/types.h"

#ifndef LC_GLOBAL_LOCALE
typedef void * locale_t;
#define LC_GLOBAL_LOCALE ((locale_t)(-1))
#endif

static unsigned char *__getmap(int map)
{
	static unsigned char c_attr[UCHAR_MAX + 1] = {0};
	static unsigned char c_lower[UCHAR_MAX + 1] = {0};
	static unsigned char c_upper[UCHAR_MAX + 1] = {0};
	struct __locale_t c;
	struct __locale_t *locale = __libc.per_thread()->locale;

	if (!locale || locale == LC_GLOBAL_LOCALE || !locale->ctype) {
		locale = __libc.locale.global;
	}

	if (!locale || !locale->ctype) {
		unsigned char lower[] = "abcdefghijklmnopqrstuvwxyz";
		unsigned char upper[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
		/* $@` are in ASCII but not 9899 */
		unsigned char punct[] = "!\"#%&'()*+,-./:;<=>?[\\]^_{|}~$@`";
		unsigned char space[] = " \f\n\r\t\v";
		unsigned char xdigit[] = "0123456789abcdefABCDEF";

		locale = &c;
		c.ctattr = c_attr;
		c.ctolower = c_lower;
		c.ctoupper = c_upper;

		if (c_attr['a'] == 0) {
			unsigned int i;
			for (i = 0; i <= UCHAR_MAX; i++) {
				c_attr[i] = 0;
				c_lower[i] = i;
				c_upper[i] = i;
			}

			for (i = 0; i < sizeof(lower); i++) {
				c_attr[lower[i]] = __libc.ctype.lower;
				c_upper[lower[i]] = upper[i];
			}

			for (i = 0; i < sizeof(upper); i++) {
				c_attr[upper[i]] = __libc.ctype.upper;
				c_lower[upper[i]] = lower[i];
			}

			for (i = 0; i < sizeof(xdigit); i++) {
				c_attr[xdigit[i]] |= __libc.ctype.xdigit;
			}

			for (i = 0; i < sizeof(punct); i++) {
				c_attr[punct[i]] = __libc.ctype.punct;
			}

			for (i = 0; i < sizeof(space); i++) {
				c_attr[space[i]] = __libc.ctype.space;
			}

			c_attr[0] = 0;
		}
	}
	
	if (map == __libc.ctype.ctolower) {
		return locale->ctolower;
	} else if (map == __libc.ctype.ctoupper) {
		return locale->ctoupper;
	}

	return locale->ctattr;
}