-
Notifications
You must be signed in to change notification settings - Fork 0
/
tcharconst.c
129 lines (103 loc) · 3.12 KB
/
tcharconst.c
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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
#include <assert.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
typedef uint32_t my_wchar_t;
/*
* examine the assembler output to see how these are managed
*/
#if __GNUC_PREREQ__(4, 4) /* xxx #ifdef __CHAR32_TYPE__ */
# if ((__STDC_VERSION__ - 0) >= 199901L) /* i.e. supports Universal Character Names */
# ifndef __STRICT_ANSI__
typeof(U'x') foo_U = U'☎';
# endif
unsigned long sizeof_U = sizeof(U'☎');
# ifndef __STRICT_ANSI__
typeof(L'\u20AC') foo_L = L'\u20AC';
# endif
unsigned long sizeof_L = sizeof(L'\u20AC');
# ifndef __STRICT_ANSI__
typeof(L'\U0001F6F8') foo_Lw = L'\U0001F6F8';
# endif
unsigned long sizeof_Lw = sizeof(L'\U0001F6F8');
# endif /* c99 */
#elif __GNUC_PREREQ__(3, 4) /* xxx #ifdef __WCHAR_TYPE__ */
# ifndef __STRICT_ANSI__
typeof(L'x') foo_L = L'☎';
# endif
unsigned long sizeof_L = sizeof(L'☎');
#else /* GCC < 3.4 */
/*
* no cigar... err, black telephone
*
* C89 allows wide character constants like L'x', but will barf on, or do the
* wrong thing with, UTF-8 encoding where three or more bytes are needed for a
* character.
*/
wchar_t wc = L'x';
unsigned long sizeof_wchar = sizeof(L'x');
#endif
int
main(void)
{
signed int si = 0x7fffffff;
unsigned int ui = 0xffffffff;
unsigned short short_var = 0xffff;
unsigned char char_var = 0xff;
/*
* UTF-8 "wide" character constants
*
* e.g.: '€' 8364, #o20254, #x20ac (UTF-8: #xE2 #x82 #xAC)
* or: '☎' 9742, #o23016, #x260e (UTF-8: #xE2 #x98 #x8E)
*
* too bad ☎ wasn't \u0A28 (2600 base 10), or even \u2600
*/
/*
* Note none of this works for decomposed characters of course, i.e. a
* character plus one or more "combining marks", since those are multiple
* code points.
*
* Conversely if any pre-composed characters are used for a constant then
* they won't compare to code points from a string which has the
* decomposed character and combining mark (unless the string is first
* "normalized" to use the pre-composed form, e.g. using NFC or NFKC
* normalization). (perhaps https://julialang.org/utf8proc/)
*/
#if __GNUC_PREREQ__(4, 4) /* xxx #ifdef __CHAR32_TYPE__ */
my_wchar_t c8 = U'☎';
# define WC(x) U##x /* U'x' has the type __CHAR32_TYPE__ (char32_t) */
#elif __GNUC_PREREQ__(3, 4) /* xxx #ifdef __WCHAR_TYPE__ */
my_wchar_t c8 = L'☎';
# define WC(x) L##x /* L'x' has the type __WCHAR_TYPE__ (wchar_t) */
#else /* GCC < 3.4 */
/* no cigar... err, black telephone */
#endif
unsigned char c1 = 'a';
#ifdef WC
my_wchar_t c8w = WC('☎');
my_wchar_t c8ucn = WC('\u260E');
# if __GNUC_PREREQ__(4, 4)
my_wchar_t c9w = WC('\U0001F6F8'); /* FLYING SAUCER */
assert(c9w == 0x1F6F8);
# endif
assert(c1 == WC('a'));
assert(c8 == c8ucn);
assert(c8 == 0x260e);
assert(c8w == c8);
switch(c8ucn) {
case WC('☎'):
break;
default:
assert(false);
break;
}
#endif /* WC */
exit(0);
}
/*
* Local Variables:
* eval: (make-local-variable 'compile-command)
* compile-command: (let ((fn (file-name-sans-extension (file-name-nondirectory (buffer-file-name))))) (concat "rm -f " fn "; " (default-value 'compile-command) " CSTD='gnu99' " fn " && ./" fn))
* End:
*/