1const builtin = @import("builtin");
2const std = @import("std");
3const symbol = @import("../c.zig").symbol;
4
5comptime {
6 if (builtin.target.isMuslLibC() or builtin.target.isWasiLibC()) {
7 // Functions specific to musl and wasi-libc.
8 symbol(&isalnum, "isalnum");
9 symbol(&isalpha, "isalpha");
10 symbol(&isblank, "isblank");
11 symbol(&iscntrl, "iscntrl");
12 symbol(&isdigit, "isdigit");
13 symbol(&isgraph, "isgraph");
14 symbol(&islower, "islower");
15 symbol(&isprint, "isprint");
16 symbol(&ispunct, "ispunct");
17 symbol(&isspace, "isspace");
18 symbol(&isupper, "isupper");
19 symbol(&isxdigit, "isxdigit");
20 symbol(&tolower, "tolower");
21 symbol(&toupper, "toupper");
22
23 symbol(&__isalnum_l, "__isalnum_l");
24 symbol(&__isalpha_l, "__isalpha_l");
25 symbol(&__isblank_l, "__isblank_l");
26 symbol(&__iscntrl_l, "__iscntrl_l");
27 symbol(&__isdigit_l, "__isdigit_l");
28 symbol(&__isgraph_l, "__isgraph_l");
29 symbol(&__islower_l, "__islower_l");
30 symbol(&__isprint_l, "__isprint_l");
31 symbol(&__ispunct_l, "__ispunct_l");
32 symbol(&__isspace_l, "__isspace_l");
33 symbol(&__isupper_l, "__isupper_l");
34 symbol(&__isxdigit_l, "__isxdigit_l");
35 symbol(&__tolower_l, "__tolower_l");
36 symbol(&__toupper_l, "__toupper_l");
37
38 symbol(&__isalnum_l, "isalnum_l");
39 symbol(&__isalpha_l, "isalpha_l");
40 symbol(&__isblank_l, "isblank_l");
41 symbol(&__iscntrl_l, "iscntrl_l");
42 symbol(&__isdigit_l, "isdigit_l");
43 symbol(&__isgraph_l, "isgraph_l");
44 symbol(&__islower_l, "islower_l");
45 symbol(&__isprint_l, "isprint_l");
46 symbol(&__ispunct_l, "ispunct_l");
47 symbol(&__isspace_l, "isspace_l");
48 symbol(&__isupper_l, "isupper_l");
49 symbol(&__isxdigit_l, "isxdigit_l");
50 symbol(&__tolower_l, "tolower_l");
51 symbol(&__toupper_l, "toupper_l");
52
53 symbol(&isascii, "isascii");
54 symbol(&toascii, "toascii");
55 }
56}
57
58// NOTE: If the input is not representable as an unsigned char or is not EOF (which is a negative integer value) the behaviour is undefined.
59
60fn isalnum(c: c_int) callconv(.c) c_int {
61 return @intFromBool(std.ascii.isAlphanumeric(@truncate(@as(c_uint, @bitCast(c))))); // @truncate instead of @intCast as we have to handle EOF
62}
63
64fn __isalnum_l(c: c_int, locale: *anyopaque) callconv(.c) c_int {
65 _ = locale;
66 return isalnum(c);
67}
68
69fn isalpha(c: c_int) callconv(.c) c_int {
70 return @intFromBool(std.ascii.isAlphabetic(@truncate(@as(c_uint, @bitCast(c)))));
71}
72
73fn __isalpha_l(c: c_int, locale: *anyopaque) callconv(.c) c_int {
74 _ = locale;
75 return isalpha(c);
76}
77
78fn isblank(c: c_int) callconv(.c) c_int {
79 return @intFromBool(c == ' ' or c == '\t');
80}
81
82fn __isblank_l(c: c_int, locale: *anyopaque) callconv(.c) c_int {
83 _ = locale;
84 return isblank(c);
85}
86
87fn iscntrl(c: c_int) callconv(.c) c_int {
88 return @intFromBool(std.ascii.isControl(@truncate(@as(c_uint, @bitCast(c)))));
89}
90
91fn __iscntrl_l(c: c_int, locale: *anyopaque) callconv(.c) c_int {
92 _ = locale;
93 return iscntrl(c);
94}
95
96fn isdigit(c: c_int) callconv(.c) c_int {
97 return @intFromBool(std.ascii.isDigit(@truncate(@as(c_uint, @bitCast(c)))));
98}
99
100fn __isdigit_l(c: c_int, locale: *anyopaque) callconv(.c) c_int {
101 _ = locale;
102 return isdigit(c);
103}
104
105fn isgraph(c: c_int) callconv(.c) c_int {
106 return @intFromBool(std.ascii.isGraphical(@truncate(@as(c_uint, @bitCast(c)))));
107}
108
109fn __isgraph_l(c: c_int, locale: *anyopaque) callconv(.c) c_int {
110 _ = locale;
111 return isgraph(c);
112}
113
114fn islower(c: c_int) callconv(.c) c_int {
115 return @intFromBool(std.ascii.isLower(@truncate(@as(c_uint, @bitCast(c)))));
116}
117
118fn __islower_l(c: c_int, locale: *anyopaque) callconv(.c) c_int {
119 _ = locale;
120 return islower(c);
121}
122
123fn isprint(c: c_int) callconv(.c) c_int {
124 return @intFromBool(std.ascii.isPrint(@truncate(@as(c_uint, @bitCast(c)))));
125}
126
127fn __isprint_l(c: c_int, locale: *anyopaque) callconv(.c) c_int {
128 _ = locale;
129 return isprint(c);
130}
131
132fn ispunct(c: c_int) callconv(.c) c_int {
133 return @intFromBool(std.ascii.isPunctuation(@truncate(@as(c_uint, @bitCast(c)))));
134}
135
136fn __ispunct_l(c: c_int, locale: *anyopaque) callconv(.c) c_int {
137 _ = locale;
138 return ispunct(c);
139}
140
141fn isspace(c: c_int) callconv(.c) c_int {
142 return @intFromBool(std.ascii.isWhitespace(@truncate(@as(c_uint, @bitCast(c)))));
143}
144
145fn __isspace_l(c: c_int, locale: *anyopaque) callconv(.c) c_int {
146 _ = locale;
147 return isspace(c);
148}
149
150fn isupper(c: c_int) callconv(.c) c_int {
151 return @intFromBool(std.ascii.isUpper(@truncate(@as(c_uint, @bitCast(c)))));
152}
153
154fn __isupper_l(c: c_int, locale: *anyopaque) callconv(.c) c_int {
155 _ = locale;
156 return isupper(c);
157}
158
159fn isxdigit(c: c_int) callconv(.c) c_int {
160 return @intFromBool(std.ascii.isHex(@truncate(@as(c_uint, @bitCast(c)))));
161}
162
163fn __isxdigit_l(c: c_int, locale: *anyopaque) callconv(.c) c_int {
164 _ = locale;
165 return isxdigit(c);
166}
167
168fn tolower(c: c_int) callconv(.c) c_int {
169 return std.ascii.toLower(@truncate(@as(c_uint, @bitCast(c))));
170}
171
172fn __tolower_l(c: c_int, locale: *anyopaque) callconv(.c) c_int {
173 _ = locale;
174 return tolower(c);
175}
176
177fn toupper(c: c_int) callconv(.c) c_int {
178 return std.ascii.toUpper(@truncate(@as(c_uint, @bitCast(c))));
179}
180
181fn __toupper_l(c: c_int, locale: *anyopaque) callconv(.c) c_int {
182 _ = locale;
183 return toupper(c);
184}
185
186fn isascii(c: c_int) callconv(.c) c_int {
187 return @intFromBool(std.ascii.isAscii(@truncate(@as(c_uint, @bitCast(c)))));
188}
189
190fn toascii(c: c_int) callconv(.c) c_int {
191 return c & 0x7F;
192}