rubycc 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/CHANGELOG.md +56 -0
- data/LICENSE.txt +21 -0
- data/NOTICE +52 -0
- data/README.md +208 -0
- data/data/README.md +117 -0
- data/data/r10_corpus_scan.json +4082 -0
- data/data/r10_manual_classification.json +5342 -0
- data/data/r10_verification_m4a.json +1531 -0
- data/data/r10_verification_m4b.json +1818 -0
- data/data/r10_verification_m4c.json +1489 -0
- data/data/r10_verification_m4d.json +318 -0
- data/data/r10_verification_rbs.json +192 -0
- data/data/verified_gems.json +397 -0
- data/exe/rmake +16 -0
- data/exe/rubycc +9 -0
- data/exe/rubycc-ar +114 -0
- data/exe/rubycc-doctor +14 -0
- data/exe/rubycc-pkgconf +8 -0
- data/include/float.h +87 -0
- data/include/iso646.h +18 -0
- data/include/libc/alloca.h +18 -0
- data/include/libc/arpa/inet.h +61 -0
- data/include/libc/assert.h +43 -0
- data/include/libc/dirent.h +72 -0
- data/include/libc/dlfcn.h +58 -0
- data/include/libc/features.h +205 -0
- data/include/libc/glibc/aarch64/ctype.h +108 -0
- data/include/libc/glibc/aarch64/endian.h +54 -0
- data/include/libc/glibc/aarch64/errno.h +154 -0
- data/include/libc/glibc/aarch64/fcntl.h +144 -0
- data/include/libc/glibc/aarch64/inttypes.h +182 -0
- data/include/libc/glibc/aarch64/limits.h +63 -0
- data/include/libc/glibc/aarch64/pthread.h +131 -0
- data/include/libc/glibc/aarch64/setjmp.h +84 -0
- data/include/libc/glibc/aarch64/stdint.h +174 -0
- data/include/libc/glibc/aarch64/sys/epoll.h +88 -0
- data/include/libc/glibc/aarch64/sys/fcntl.h +19 -0
- data/include/libc/glibc/aarch64/sys/select.h +75 -0
- data/include/libc/glibc/aarch64/sys/stat.h +136 -0
- data/include/libc/glibc/aarch64/sys/syscall.h +167 -0
- data/include/libc/glibc/aarch64/sys/time.h +74 -0
- data/include/libc/glibc/aarch64/sys/types.h +127 -0
- data/include/libc/glibc/aarch64/time.h +113 -0
- data/include/libc/glibc/x86_64/ctype.h +108 -0
- data/include/libc/glibc/x86_64/endian.h +54 -0
- data/include/libc/glibc/x86_64/errno.h +154 -0
- data/include/libc/glibc/x86_64/fcntl.h +134 -0
- data/include/libc/glibc/x86_64/inttypes.h +182 -0
- data/include/libc/glibc/x86_64/limits.h +61 -0
- data/include/libc/glibc/x86_64/pthread.h +111 -0
- data/include/libc/glibc/x86_64/setjmp.h +82 -0
- data/include/libc/glibc/x86_64/stdint.h +163 -0
- data/include/libc/glibc/x86_64/sys/epoll.h +91 -0
- data/include/libc/glibc/x86_64/sys/fcntl.h +19 -0
- data/include/libc/glibc/x86_64/sys/select.h +75 -0
- data/include/libc/glibc/x86_64/sys/stat.h +130 -0
- data/include/libc/glibc/x86_64/sys/syscall.h +188 -0
- data/include/libc/glibc/x86_64/sys/time.h +74 -0
- data/include/libc/glibc/x86_64/sys/types.h +123 -0
- data/include/libc/glibc/x86_64/time.h +113 -0
- data/include/libc/grp.h +50 -0
- data/include/libc/langinfo.h +126 -0
- data/include/libc/link.h +18 -0
- data/include/libc/locale.h +83 -0
- data/include/libc/math.h +191 -0
- data/include/libc/netinet/in.h +126 -0
- data/include/libc/netinet/tcp.h +44 -0
- data/include/libc/poll.h +46 -0
- data/include/libc/pwd.h +58 -0
- data/include/libc/regex.h +53 -0
- data/include/libc/sched.h +35 -0
- data/include/libc/signal.h +204 -0
- data/include/libc/stdio.h +157 -0
- data/include/libc/stdlib.h +92 -0
- data/include/libc/string.h +74 -0
- data/include/libc/strings.h +25 -0
- data/include/libc/sys/cdefs.h +126 -0
- data/include/libc/sys/inotify.h +111 -0
- data/include/libc/sys/ioctl.h +36 -0
- data/include/libc/sys/mman.h +65 -0
- data/include/libc/sys/param.h +41 -0
- data/include/libc/sys/resource.h +109 -0
- data/include/libc/sys/socket.h +167 -0
- data/include/libc/sys/statfs.h +82 -0
- data/include/libc/sys/timerfd.h +55 -0
- data/include/libc/sys/uio.h +40 -0
- data/include/libc/sys/un.h +25 -0
- data/include/libc/sys/utsname.h +35 -0
- data/include/libc/sys/wait.h +135 -0
- data/include/libc/termios.h +179 -0
- data/include/libc/unistd.h +194 -0
- data/include/stdalign.h +16 -0
- data/include/stdarg.h +31 -0
- data/include/stdatomic.h +158 -0
- data/include/stdbool.h +15 -0
- data/include/stdckdint.h +28 -0
- data/include/stddef.h +60 -0
- data/include/stdnoreturn.h +18 -0
- data/include/x86intrin.h +16 -0
- data/lib/rubycc/backend/aarch64.rb +1724 -0
- data/lib/rubycc/backend/x86_64.rb +1369 -0
- data/lib/rubycc/compile_error.rb +36 -0
- data/lib/rubycc/compiler.rb +305 -0
- data/lib/rubycc/doctor/builder.rb +151 -0
- data/lib/rubycc/doctor/cli.rb +190 -0
- data/lib/rubycc/doctor/fetcher.rb +84 -0
- data/lib/rubycc/doctor/gemfile.rb +115 -0
- data/lib/rubycc/doctor/verified_gems.rb +114 -0
- data/lib/rubycc/doctor.rb +16 -0
- data/lib/rubycc/driver.rb +463 -0
- data/lib/rubycc/front/ast.rb +528 -0
- data/lib/rubycc/front/constant_evaluator.rb +631 -0
- data/lib/rubycc/front/initializer_resolver.rb +592 -0
- data/lib/rubycc/front/lexeme_reader.rb +460 -0
- data/lib/rubycc/front/lexer.rb +232 -0
- data/lib/rubycc/front/parser.rb +4122 -0
- data/lib/rubycc/front/token.rb +49 -0
- data/lib/rubycc/ir/call_convention.rb +486 -0
- data/lib/rubycc/ir/generator.rb +6036 -0
- data/lib/rubycc/ir/ir.rb +417 -0
- data/lib/rubycc/link/compat_runtime.rb +89 -0
- data/lib/rubycc/link/errors.rb +13 -0
- data/lib/rubycc/link/executable_linker.rb +405 -0
- data/lib/rubycc/link/library_resolver.rb +437 -0
- data/lib/rubycc/link/partial_linker.rb +546 -0
- data/lib/rubycc/link/shared_linker.rb +1732 -0
- data/lib/rubycc/mkmf_shim.rb +83 -0
- data/lib/rubycc/objfile/ar_archive.rb +437 -0
- data/lib/rubycc/objfile/elf_reader.rb +646 -0
- data/lib/rubycc/objfile/elf_writer.rb +891 -0
- data/lib/rubycc/objfile/relocatable_writer.rb +376 -0
- data/lib/rubycc/pkgconf/cli.rb +139 -0
- data/lib/rubycc/pkgconf/errors.rb +39 -0
- data/lib/rubycc/pkgconf/model.rb +28 -0
- data/lib/rubycc/pkgconf/parser.rb +109 -0
- data/lib/rubycc/pkgconf/pkgconf.rb +15 -0
- data/lib/rubycc/pkgconf/resolver.rb +70 -0
- data/lib/rubycc/pkgconf/search_path.rb +38 -0
- data/lib/rubycc/pkgconf/system_path_filter.rb +131 -0
- data/lib/rubycc/preprocess/constant_expression.rb +219 -0
- data/lib/rubycc/preprocess/glibc_version.rb +124 -0
- data/lib/rubycc/preprocess/pp_token.rb +62 -0
- data/lib/rubycc/preprocess/preprocessor.rb +2020 -0
- data/lib/rubycc/preprocess/scanner.rb +290 -0
- data/lib/rubycc/preprocess/token_converter.rb +157 -0
- data/lib/rubycc/rmake/cli.rb +143 -0
- data/lib/rubycc/rmake/errors.rb +71 -0
- data/lib/rubycc/rmake/executor.rb +818 -0
- data/lib/rubycc/rmake/expander.rb +251 -0
- data/lib/rubycc/rmake/makefile.rb +352 -0
- data/lib/rubycc/rmake/model.rb +137 -0
- data/lib/rubycc/rmake/parser.rb +226 -0
- data/lib/rubycc/rmake/rmake.rb +15 -0
- data/lib/rubycc/type.rb +1236 -0
- data/lib/rubycc/version.rb +5 -0
- data/lib/rubycc.rb +36 -0
- data/lib/rubygems_plugin.rb +102 -0
- metadata +219 -0
data/include/float.h
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/* rubycc freestanding <float.h>: floating-type characteristics (ISO C 7.7).
|
|
2
|
+
float is IEEE 754 binary32 and double is binary64 on every target rubycc
|
|
3
|
+
supports, so those are unconditional. `long double` is not: x86-64 gives it
|
|
4
|
+
the x87 80-bit extended format, aarch64 the IEEE 754 binary128 quad. This
|
|
5
|
+
file is the freestanding layer -- one file for every machine, unlike
|
|
6
|
+
include/libc/glibc/<arch>/ -- so the machine split is carried inline, on the
|
|
7
|
+
arch macro the preprocessor predefines per target.
|
|
8
|
+
|
|
9
|
+
That split was missing until Step 200: this header handed x87's numbers to
|
|
10
|
+
aarch64 too. It went unnoticed because the aarch64 ABI harness covered only
|
|
11
|
+
the arch-layer headers, on the assumption that a freestanding header has
|
|
12
|
+
nothing arch-specific in it -- an assumption this file disproves. All the
|
|
13
|
+
values below were measured with each target's own gcc (the x86-64 column
|
|
14
|
+
reproduces this file's previous contents exactly, which is what validates
|
|
15
|
+
the method). */
|
|
16
|
+
|
|
17
|
+
#ifndef _RUBYCC_FLOAT_H
|
|
18
|
+
#define _RUBYCC_FLOAT_H
|
|
19
|
+
|
|
20
|
+
/* Common to every floating type. */
|
|
21
|
+
#define FLT_RADIX 2
|
|
22
|
+
#define FLT_ROUNDS 1
|
|
23
|
+
#define FLT_EVAL_METHOD 0
|
|
24
|
+
#if defined(__aarch64__)
|
|
25
|
+
#define DECIMAL_DIG 36
|
|
26
|
+
#else
|
|
27
|
+
#define DECIMAL_DIG 21
|
|
28
|
+
#endif
|
|
29
|
+
|
|
30
|
+
/* float (IEEE 754 binary32). */
|
|
31
|
+
#define FLT_MANT_DIG 24
|
|
32
|
+
#define FLT_DIG 6
|
|
33
|
+
#define FLT_DECIMAL_DIG 9
|
|
34
|
+
#define FLT_MIN_EXP (-125)
|
|
35
|
+
#define FLT_MIN_10_EXP (-37)
|
|
36
|
+
#define FLT_MAX_EXP 128
|
|
37
|
+
#define FLT_MAX_10_EXP 38
|
|
38
|
+
#define FLT_MAX 3.40282347e+38F
|
|
39
|
+
#define FLT_MIN 1.17549435e-38F
|
|
40
|
+
#define FLT_EPSILON 1.19209290e-7F
|
|
41
|
+
#define FLT_TRUE_MIN 1.40129846e-45F
|
|
42
|
+
#define FLT_HAS_SUBNORM 1
|
|
43
|
+
|
|
44
|
+
/* double (IEEE 754 binary64). */
|
|
45
|
+
#define DBL_MANT_DIG 53
|
|
46
|
+
#define DBL_DIG 15
|
|
47
|
+
#define DBL_DECIMAL_DIG 17
|
|
48
|
+
#define DBL_MIN_EXP (-1021)
|
|
49
|
+
#define DBL_MIN_10_EXP (-307)
|
|
50
|
+
#define DBL_MAX_EXP 1024
|
|
51
|
+
#define DBL_MAX_10_EXP 308
|
|
52
|
+
#define DBL_MAX 1.7976931348623157e+308
|
|
53
|
+
#define DBL_MIN 2.2250738585072014e-308
|
|
54
|
+
#define DBL_EPSILON 2.2204460492503131e-16
|
|
55
|
+
#define DBL_TRUE_MIN 4.9406564584124654e-324
|
|
56
|
+
#define DBL_HAS_SUBNORM 1
|
|
57
|
+
|
|
58
|
+
/* long double. The exponent range is the same either way -- both formats carry
|
|
59
|
+
15 exponent bits -- so only the precision-derived macros and the magnitudes
|
|
60
|
+
that depend on the mantissa width differ. */
|
|
61
|
+
#define LDBL_MIN_EXP (-16381)
|
|
62
|
+
#define LDBL_MIN_10_EXP (-4931)
|
|
63
|
+
#define LDBL_MAX_EXP 16384
|
|
64
|
+
#define LDBL_MAX_10_EXP 4932
|
|
65
|
+
#define LDBL_HAS_SUBNORM 1
|
|
66
|
+
|
|
67
|
+
#if defined(__aarch64__)
|
|
68
|
+
/* IEEE 754 binary128 ("quad"): a 113-bit significand. */
|
|
69
|
+
#define LDBL_MANT_DIG 113
|
|
70
|
+
#define LDBL_DIG 33
|
|
71
|
+
#define LDBL_DECIMAL_DIG 36
|
|
72
|
+
#define LDBL_MAX 1.18973149535723176508575932662800702e+4932L
|
|
73
|
+
#define LDBL_MIN 3.36210314311209350626267781732175260e-4932L
|
|
74
|
+
#define LDBL_EPSILON 1.92592994438723585305597794258492732e-34L
|
|
75
|
+
#define LDBL_TRUE_MIN 6.47517511943802511092443895822764655e-4966L
|
|
76
|
+
#else
|
|
77
|
+
/* x87 80-bit extended: a 64-bit significand. */
|
|
78
|
+
#define LDBL_MANT_DIG 64
|
|
79
|
+
#define LDBL_DIG 18
|
|
80
|
+
#define LDBL_DECIMAL_DIG 21
|
|
81
|
+
#define LDBL_MAX 1.18973149535723176502e+4932L
|
|
82
|
+
#define LDBL_MIN 3.36210314311209350626e-4932L
|
|
83
|
+
#define LDBL_EPSILON 1.08420217248550443401e-19L
|
|
84
|
+
#define LDBL_TRUE_MIN 3.64519953188247460253e-4951L
|
|
85
|
+
#endif
|
|
86
|
+
|
|
87
|
+
#endif
|
data/include/iso646.h
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/* rubycc freestanding <iso646.h>: alternative operator spellings (ISO C 7.9). */
|
|
2
|
+
|
|
3
|
+
#ifndef _RUBYCC_ISO646_H
|
|
4
|
+
#define _RUBYCC_ISO646_H
|
|
5
|
+
|
|
6
|
+
#define and &&
|
|
7
|
+
#define and_eq &=
|
|
8
|
+
#define bitand &
|
|
9
|
+
#define bitor |
|
|
10
|
+
#define compl ~
|
|
11
|
+
#define not !
|
|
12
|
+
#define not_eq !=
|
|
13
|
+
#define or ||
|
|
14
|
+
#define or_eq |=
|
|
15
|
+
#define xor ^
|
|
16
|
+
#define xor_eq ^=
|
|
17
|
+
|
|
18
|
+
#endif
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/* rubycc bundled <alloca.h>: the alloca declaration, mapped onto the compiler
|
|
2
|
+
builtin (glibc/BSD extension). Derived from musl's <alloca.h> shape. Common
|
|
3
|
+
layer: the builtin mapping is the same on any target. */
|
|
4
|
+
|
|
5
|
+
#ifndef _RUBYCC_ALLOCA_H
|
|
6
|
+
#define _RUBYCC_ALLOCA_H
|
|
7
|
+
|
|
8
|
+
#ifndef _RUBYCC_SIZE_T
|
|
9
|
+
#define _RUBYCC_SIZE_T
|
|
10
|
+
typedef unsigned long size_t;
|
|
11
|
+
#endif
|
|
12
|
+
|
|
13
|
+
extern void *alloca(size_t __size);
|
|
14
|
+
|
|
15
|
+
#undef alloca
|
|
16
|
+
#define alloca(size) __builtin_alloca(size)
|
|
17
|
+
|
|
18
|
+
#endif /* _RUBYCC_ALLOCA_H */
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/* rubycc bundled <arpa/inet.h>: the Internet address-manipulation declarations
|
|
2
|
+
(POSIX) -- the host<->network byte-order conversions and the inet_* address
|
|
3
|
+
conversions. Derived from musl's <arpa/inet.h> declaration set; the byte-order
|
|
4
|
+
direction is taken from <endian.h> (arch specific) and the address types are
|
|
5
|
+
fixed width, so this header itself carries nothing arch specific. Common layer.
|
|
6
|
+
|
|
7
|
+
Measured need (Step 64): msgpack's sysdep_endian.h includes this header solely
|
|
8
|
+
for __BYTE_ORDER / __LITTLE_ENDIAN and the ntohs/ntohl functions. glibc's real
|
|
9
|
+
<arpa/inet.h> fans out into the whole socket + kernel-UAPI chain (netinet/in.h,
|
|
10
|
+
sys/socket.h and the asm/asm-generic socket headers); the bundled header
|
|
11
|
+
collapses that -- no target gem uses sockets, so the socket UAPI surface is
|
|
12
|
+
deliberately not reproduced (measurement-driven, per the B7 plan). */
|
|
13
|
+
|
|
14
|
+
#ifndef _RUBYCC_ARPA_INET_H
|
|
15
|
+
#define _RUBYCC_ARPA_INET_H
|
|
16
|
+
|
|
17
|
+
#include <stdint.h>
|
|
18
|
+
#include <endian.h>
|
|
19
|
+
|
|
20
|
+
#ifndef _RUBYCC_SOCKLEN_T
|
|
21
|
+
#define _RUBYCC_SOCKLEN_T
|
|
22
|
+
typedef unsigned int socklen_t;
|
|
23
|
+
#endif
|
|
24
|
+
|
|
25
|
+
#ifndef _RUBYCC_IN_ADDR_T
|
|
26
|
+
#define _RUBYCC_IN_ADDR_T
|
|
27
|
+
typedef uint32_t in_addr_t;
|
|
28
|
+
#endif
|
|
29
|
+
|
|
30
|
+
#ifndef _RUBYCC_IN_PORT_T
|
|
31
|
+
#define _RUBYCC_IN_PORT_T
|
|
32
|
+
typedef uint16_t in_port_t;
|
|
33
|
+
#endif
|
|
34
|
+
|
|
35
|
+
/* IPv4 address: a single network-order 32-bit word, the same one-field layout
|
|
36
|
+
glibc/musl commit to (sizeof 4, s_addr at offset 0). */
|
|
37
|
+
#ifndef _RUBYCC_STRUCT_IN_ADDR
|
|
38
|
+
#define _RUBYCC_STRUCT_IN_ADDR
|
|
39
|
+
struct in_addr { in_addr_t s_addr; };
|
|
40
|
+
#endif
|
|
41
|
+
|
|
42
|
+
/* Host<->network byte-order conversions (network order is big-endian). Declared
|
|
43
|
+
as plain out-of-line functions resolving from the host libc, matching glibc's
|
|
44
|
+
real symbols; on a little-endian host each swaps its argument's bytes. */
|
|
45
|
+
uint32_t htonl(uint32_t __hostlong);
|
|
46
|
+
uint16_t htons(uint16_t __hostshort);
|
|
47
|
+
uint32_t ntohl(uint32_t __netlong);
|
|
48
|
+
uint16_t ntohs(uint16_t __netshort);
|
|
49
|
+
|
|
50
|
+
/* IPv4 / IPv6 address conversions. */
|
|
51
|
+
in_addr_t inet_addr(const char *__cp);
|
|
52
|
+
in_addr_t inet_network(const char *__cp);
|
|
53
|
+
struct in_addr inet_makeaddr(in_addr_t __net, in_addr_t __host);
|
|
54
|
+
in_addr_t inet_lnaof(struct in_addr __in);
|
|
55
|
+
in_addr_t inet_netof(struct in_addr __in);
|
|
56
|
+
int inet_aton(const char *__cp, struct in_addr *__inp);
|
|
57
|
+
char *inet_ntoa(struct in_addr __in);
|
|
58
|
+
int inet_pton(int __af, const char *__cp, void *__buf);
|
|
59
|
+
const char *inet_ntop(int __af, const void *__cp, char *__buf, socklen_t __len);
|
|
60
|
+
|
|
61
|
+
#endif /* _RUBYCC_ARPA_INET_H */
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/* rubycc bundled <assert.h>: the assert macro and its __assert_fail hook (ISO C
|
|
2
|
+
7.2). Written clean room against the standard idiom (musl's <assert.h> was the
|
|
3
|
+
shape reference); the __assert_fail prototype matches glibc's so the macro
|
|
4
|
+
links against the host libc when present. Common layer. Deliberately has no
|
|
5
|
+
whole-file include guard: the standard requires assert to be redefined per the
|
|
6
|
+
current NDEBUG on every inclusion. */
|
|
7
|
+
|
|
8
|
+
#include <features.h>
|
|
9
|
+
|
|
10
|
+
#undef assert
|
|
11
|
+
|
|
12
|
+
#ifdef NDEBUG
|
|
13
|
+
# define assert(expr) ((void) 0)
|
|
14
|
+
#else
|
|
15
|
+
|
|
16
|
+
extern void __assert_fail(const char *__assertion, const char *__file,
|
|
17
|
+
unsigned int __line, const char *__function)
|
|
18
|
+
__attribute__((__noreturn__));
|
|
19
|
+
|
|
20
|
+
/* The enclosing function's name. C99's __func__ is the portable spelling, but
|
|
21
|
+
rubycc does not provide it, so under rubycc the (informational) function slot
|
|
22
|
+
is passed as a null pointer instead. */
|
|
23
|
+
# if defined __RUBYCC__
|
|
24
|
+
# define __ASSERT_FUNCTION ((const char *) 0)
|
|
25
|
+
# else
|
|
26
|
+
# define __ASSERT_FUNCTION __func__
|
|
27
|
+
# endif
|
|
28
|
+
|
|
29
|
+
# define assert(expr) \
|
|
30
|
+
((void) ((expr) ? 0 : \
|
|
31
|
+
(__assert_fail(#expr, __FILE__, __LINE__, __ASSERT_FUNCTION), 0)))
|
|
32
|
+
|
|
33
|
+
#endif /* NDEBUG */
|
|
34
|
+
|
|
35
|
+
#ifndef _RUBYCC_ASSERT_H
|
|
36
|
+
#define _RUBYCC_ASSERT_H
|
|
37
|
+
|
|
38
|
+
/* static_assert: the C11 keyword, exposed under its library spelling. */
|
|
39
|
+
#if !defined __cplusplus && (!defined __STDC_VERSION__ || __STDC_VERSION__ < 202311L)
|
|
40
|
+
# define static_assert _Static_assert
|
|
41
|
+
#endif
|
|
42
|
+
|
|
43
|
+
#endif /* _RUBYCC_ASSERT_H */
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/* rubycc bundled <dirent.h>: directory stream access (POSIX.1). Provenance:
|
|
2
|
+
clean room against the POSIX public interface and the glibc/Linux ABI.
|
|
3
|
+
DIR is glibc's own public spelling `typedef struct __dirstream DIR;' with
|
|
4
|
+
struct __dirstream left incomplete -- glibc itself never defines it in a
|
|
5
|
+
public header (its fields are libio-internal), and every caller only ever
|
|
6
|
+
holds a `DIR *' returned by opendir/fdopendir, never a `DIR' by value, so
|
|
7
|
+
there is nothing to size or reproduce; following the same public spelling
|
|
8
|
+
is a POSIX/glibc interoperability fact, not glibc source copied.
|
|
9
|
+
struct dirent, unlike DIR, is a struct callers read members out of
|
|
10
|
+
directly, so it cannot be an opaque byte blob. Its member order
|
|
11
|
+
(d_ino, d_off, d_reclen, d_type, d_name) and the d_reclen/d_type slots
|
|
12
|
+
ahead of d_name are glibc/Linux ABI, not POSIX (POSIX only guarantees
|
|
13
|
+
d_name), the same way sys/stat.h's field order is a kernel ABI fact rather
|
|
14
|
+
than a POSIX one; the struct's size (280, with d_name[256]) and every
|
|
15
|
+
member's offset were measured against the glibc oracle on both x86-64 and
|
|
16
|
+
aarch64 (see test/test_header_abi.rb's DIRENT case) and the two agreed
|
|
17
|
+
exactly (ino_t/off_t are both 8-byte and d_reclen/d_type/d_name have no
|
|
18
|
+
arch-dependent width on either LP64 target), so this header lives in the
|
|
19
|
+
common layer. ino_t/off_t reuse the shared _RUBYCC_* guards sys/stat.h and
|
|
20
|
+
sys/types.h also carry. The DT_* file-type constants are the standard
|
|
21
|
+
Linux/glibc values (measured, both arches agree).
|
|
22
|
+
opendir/readdir/closedir/rewinddir/readdir_r/fdopendir/dirfd are POSIX
|
|
23
|
+
declarations whose bodies resolve from the host libc at link time
|
|
24
|
+
(Step 123, M5 H2). */
|
|
25
|
+
|
|
26
|
+
#ifndef _RUBYCC_DIRENT_H
|
|
27
|
+
#define _RUBYCC_DIRENT_H
|
|
28
|
+
|
|
29
|
+
#ifndef _RUBYCC_INO_T
|
|
30
|
+
#define _RUBYCC_INO_T
|
|
31
|
+
typedef unsigned long ino_t;
|
|
32
|
+
#endif
|
|
33
|
+
#ifndef _RUBYCC_OFF_T
|
|
34
|
+
#define _RUBYCC_OFF_T
|
|
35
|
+
typedef long off_t;
|
|
36
|
+
#endif
|
|
37
|
+
|
|
38
|
+
/* Opaque directory-stream handle. Only ever used through a `DIR *'; struct
|
|
39
|
+
__dirstream is intentionally left incomplete, the same way glibc's own
|
|
40
|
+
public header leaves it. */
|
|
41
|
+
typedef struct __dirstream DIR;
|
|
42
|
+
|
|
43
|
+
/* struct dirent: 280 bytes, 8-byte aligned (measured, both arches). */
|
|
44
|
+
struct dirent {
|
|
45
|
+
ino_t d_ino; /* offset 0: inode number */
|
|
46
|
+
off_t d_off; /* offset 8: offset to the next dirent */
|
|
47
|
+
unsigned short d_reclen; /* offset 16: length of this record */
|
|
48
|
+
unsigned char d_type; /* offset 18: file type (DT_*) */
|
|
49
|
+
char d_name[256]; /* offset 19: null-terminated filename */
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
/* File-type values for d_type (measured, both arches agree). */
|
|
53
|
+
#define DT_UNKNOWN 0
|
|
54
|
+
#define DT_FIFO 1
|
|
55
|
+
#define DT_CHR 2
|
|
56
|
+
#define DT_DIR 4
|
|
57
|
+
#define DT_BLK 6
|
|
58
|
+
#define DT_REG 8
|
|
59
|
+
#define DT_LNK 10
|
|
60
|
+
#define DT_SOCK 12
|
|
61
|
+
#define DT_WHT 14
|
|
62
|
+
|
|
63
|
+
DIR *opendir(const char *__name);
|
|
64
|
+
DIR *fdopendir(int __fd);
|
|
65
|
+
struct dirent *readdir(DIR *__dirp);
|
|
66
|
+
int readdir_r(DIR *__restrict __dirp, struct dirent *__restrict __entry,
|
|
67
|
+
struct dirent **__restrict __result);
|
|
68
|
+
int closedir(DIR *__dirp);
|
|
69
|
+
void rewinddir(DIR *__dirp);
|
|
70
|
+
int dirfd(DIR *__dirp);
|
|
71
|
+
|
|
72
|
+
#endif /* _RUBYCC_DIRENT_H */
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/* rubycc bundled <dlfcn.h>: the dynamic-loading calls and the RTLD_* mode flags
|
|
2
|
+
(POSIX plus glibc extensions). Provenance: clean room against glibc's public
|
|
3
|
+
dynamic-linking ABI (bits/dlfcn.h), not derived from musl -- and not a kernel
|
|
4
|
+
UAPI, since dlopen is not a system-call interface. The RTLD_* values are that
|
|
5
|
+
ABI reproduced as measured integer constants (an ABI fact, not copied text --
|
|
6
|
+
see docs/HEADER-LICENSING.md); dlopen, dlsym, dlclose and dlerror are POSIX
|
|
7
|
+
declarations whose bodies resolve from the host libc at link time (the same
|
|
8
|
+
way errno.h's __errno_location does). Common layer: every RTLD_* value is
|
|
9
|
+
identical on x86-64 and aarch64. */
|
|
10
|
+
|
|
11
|
+
#ifndef _RUBYCC_DLFCN_H
|
|
12
|
+
#define _RUBYCC_DLFCN_H
|
|
13
|
+
|
|
14
|
+
/* Binding modes (POSIX): one of these is required in the dlopen mode. */
|
|
15
|
+
#define RTLD_LAZY 0x00001
|
|
16
|
+
#define RTLD_NOW 0x00002
|
|
17
|
+
|
|
18
|
+
/* Symbol visibility of the loaded object (POSIX). RTLD_LOCAL is the zero
|
|
19
|
+
default -- the absence of RTLD_GLOBAL. */
|
|
20
|
+
#define RTLD_GLOBAL 0x00100
|
|
21
|
+
#define RTLD_LOCAL 0
|
|
22
|
+
|
|
23
|
+
/* glibc extensions to the dlopen mode. */
|
|
24
|
+
#define RTLD_NOLOAD 0x00004
|
|
25
|
+
#define RTLD_DEEPBIND 0x00008
|
|
26
|
+
#define RTLD_NODELETE 0x01000
|
|
27
|
+
|
|
28
|
+
/* Pseudo-handles for dlsym (glibc extensions): the next object after this one
|
|
29
|
+
in the search order, and the global default scope. */
|
|
30
|
+
#define RTLD_NEXT ((void *) -1l)
|
|
31
|
+
#define RTLD_DEFAULT ((void *) 0)
|
|
32
|
+
|
|
33
|
+
void *dlopen(const char *__file, int __mode);
|
|
34
|
+
void *dlsym(void *__handle, const char *__name);
|
|
35
|
+
int dlclose(void *__handle);
|
|
36
|
+
char *dlerror(void);
|
|
37
|
+
|
|
38
|
+
/* Requests accepted by the glibc dlinfo extension. They are enum constants
|
|
39
|
+
in the system header (rather than preprocessor macros), so extensions that
|
|
40
|
+
probe them with mkmf's have_const can see the same interface here. */
|
|
41
|
+
enum {
|
|
42
|
+
RTLD_DI_LMID = 1,
|
|
43
|
+
RTLD_DI_LINKMAP = 2,
|
|
44
|
+
RTLD_DI_CONFIGADDR = 3,
|
|
45
|
+
RTLD_DI_SERINFO = 4,
|
|
46
|
+
RTLD_DI_SERINFOSIZE = 5,
|
|
47
|
+
RTLD_DI_ORIGIN = 6,
|
|
48
|
+
RTLD_DI_PROFILENAME = 7,
|
|
49
|
+
RTLD_DI_PROFILEOUT = 8,
|
|
50
|
+
RTLD_DI_TLS_MODID = 9,
|
|
51
|
+
RTLD_DI_TLS_DATA = 10,
|
|
52
|
+
RTLD_DI_PHDR = 11,
|
|
53
|
+
RTLD_DI_MAX = 11
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
int dlinfo(void *__handle, int __request, void *__arg);
|
|
57
|
+
|
|
58
|
+
#endif /* _RUBYCC_DLFCN_H */
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
/* rubycc bundled <features.h>: the feature-test-macro reduction glibc's headers
|
|
2
|
+
consume. Clean room against the published POSIX/glibc feature-test protocol
|
|
3
|
+
(musl's own <features.h> was the shape reference; the __USE_* result set and
|
|
4
|
+
the glibc version macros are the glibc ABI, measured on the reference
|
|
5
|
+
platform). It maps the caller's request macros (_GNU_SOURCE, _POSIX_C_SOURCE,
|
|
6
|
+
_DEFAULT_SOURCE, __STRICT_ANSI__, ...) onto the __USE_* macros glibc headers
|
|
7
|
+
branch on. Common layer: the mapping is libc-defined, not arch-specific. */
|
|
8
|
+
|
|
9
|
+
#ifndef _RUBYCC_FEATURES_H
|
|
10
|
+
#define _RUBYCC_FEATURES_H
|
|
11
|
+
|
|
12
|
+
/* glibc's guard, so a host <features.h> reached later is a no-op. */
|
|
13
|
+
#ifndef _FEATURES_H
|
|
14
|
+
#define _FEATURES_H 1
|
|
15
|
+
|
|
16
|
+
/* _GNU_SOURCE turns on every feature set. */
|
|
17
|
+
#if defined _GNU_SOURCE
|
|
18
|
+
# undef _ISOC95_SOURCE
|
|
19
|
+
# define _ISOC95_SOURCE 1
|
|
20
|
+
# undef _ISOC99_SOURCE
|
|
21
|
+
# define _ISOC99_SOURCE 1
|
|
22
|
+
# undef _ISOC11_SOURCE
|
|
23
|
+
# define _ISOC11_SOURCE 1
|
|
24
|
+
# undef _POSIX_SOURCE
|
|
25
|
+
# define _POSIX_SOURCE 1
|
|
26
|
+
# undef _POSIX_C_SOURCE
|
|
27
|
+
# define _POSIX_C_SOURCE 200809L
|
|
28
|
+
# undef _XOPEN_SOURCE
|
|
29
|
+
# define _XOPEN_SOURCE 700
|
|
30
|
+
# undef _XOPEN_SOURCE_EXTENDED
|
|
31
|
+
# define _XOPEN_SOURCE_EXTENDED 1
|
|
32
|
+
# undef _LARGEFILE64_SOURCE
|
|
33
|
+
# define _LARGEFILE64_SOURCE 1
|
|
34
|
+
# undef _DEFAULT_SOURCE
|
|
35
|
+
# define _DEFAULT_SOURCE 1
|
|
36
|
+
# undef _ATFILE_SOURCE
|
|
37
|
+
# define _ATFILE_SOURCE 1
|
|
38
|
+
#endif
|
|
39
|
+
|
|
40
|
+
/* With nothing requested and not in strict-ANSI mode, glibc turns on its default
|
|
41
|
+
(BSD/SVID/POSIX) surface. */
|
|
42
|
+
#if (!defined __STRICT_ANSI__ \
|
|
43
|
+
&& !defined _ISOC99_SOURCE && !defined _ISOC11_SOURCE \
|
|
44
|
+
&& !defined _POSIX_SOURCE && !defined _POSIX_C_SOURCE \
|
|
45
|
+
&& !defined _XOPEN_SOURCE && !defined _DEFAULT_SOURCE)
|
|
46
|
+
# define _DEFAULT_SOURCE 1
|
|
47
|
+
#endif
|
|
48
|
+
|
|
49
|
+
/* _DEFAULT_SOURCE implies POSIX.1-2008 plus the misc/BSD extensions. POSIX is
|
|
50
|
+
only turned on *implicitly* here when the caller did not request it; that
|
|
51
|
+
distinction is exactly what __USE_POSIX_IMPLICITLY records (so _GNU_SOURCE,
|
|
52
|
+
which sets POSIX explicitly above, does not get it). */
|
|
53
|
+
#ifdef _DEFAULT_SOURCE
|
|
54
|
+
# if !defined _POSIX_SOURCE && !defined _POSIX_C_SOURCE
|
|
55
|
+
# define __USE_POSIX_IMPLICITLY 1
|
|
56
|
+
# define _POSIX_SOURCE 1
|
|
57
|
+
# define _POSIX_C_SOURCE 200809L
|
|
58
|
+
# endif
|
|
59
|
+
# ifndef _ATFILE_SOURCE
|
|
60
|
+
# define _ATFILE_SOURCE 1
|
|
61
|
+
# endif
|
|
62
|
+
#endif
|
|
63
|
+
|
|
64
|
+
/* ISO C selections. */
|
|
65
|
+
#if defined _ISOC11_SOURCE || (defined __STDC_VERSION__ && __STDC_VERSION__ >= 201112L)
|
|
66
|
+
# define __USE_ISOC11 1
|
|
67
|
+
#endif
|
|
68
|
+
#if defined _ISOC99_SOURCE || defined _ISOC11_SOURCE \
|
|
69
|
+
|| (defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L)
|
|
70
|
+
# define __USE_ISOC99 1
|
|
71
|
+
#endif
|
|
72
|
+
#if defined _ISOC95_SOURCE || defined _ISOC99_SOURCE || defined _ISOC11_SOURCE \
|
|
73
|
+
|| (defined __STDC_VERSION__ && __STDC_VERSION__ >= 199409L)
|
|
74
|
+
# define __USE_ISOC95 1
|
|
75
|
+
#endif
|
|
76
|
+
|
|
77
|
+
/* POSIX selections, keyed off _POSIX_C_SOURCE's level. */
|
|
78
|
+
#ifdef _POSIX_SOURCE
|
|
79
|
+
# define __USE_POSIX 1
|
|
80
|
+
#endif
|
|
81
|
+
#if defined _POSIX_C_SOURCE && _POSIX_C_SOURCE >= 2
|
|
82
|
+
# define __USE_POSIX2 1
|
|
83
|
+
#endif
|
|
84
|
+
#if defined _POSIX_C_SOURCE && _POSIX_C_SOURCE >= 199309L
|
|
85
|
+
# define __USE_POSIX199309 1
|
|
86
|
+
#endif
|
|
87
|
+
#if defined _POSIX_C_SOURCE && _POSIX_C_SOURCE >= 199506L
|
|
88
|
+
# define __USE_POSIX199506 1
|
|
89
|
+
#endif
|
|
90
|
+
#if defined _POSIX_C_SOURCE && _POSIX_C_SOURCE >= 200112L
|
|
91
|
+
# define __USE_XOPEN2K 1
|
|
92
|
+
# undef __USE_ISOC95
|
|
93
|
+
# define __USE_ISOC95 1
|
|
94
|
+
# undef __USE_ISOC99
|
|
95
|
+
# define __USE_ISOC99 1
|
|
96
|
+
#endif
|
|
97
|
+
#if defined _POSIX_C_SOURCE && _POSIX_C_SOURCE >= 200809L
|
|
98
|
+
# define __USE_XOPEN2K8 1
|
|
99
|
+
# ifdef _ATFILE_SOURCE
|
|
100
|
+
# define __USE_ATFILE 1
|
|
101
|
+
# endif
|
|
102
|
+
#endif
|
|
103
|
+
|
|
104
|
+
/* X/Open selections. */
|
|
105
|
+
#ifdef _XOPEN_SOURCE
|
|
106
|
+
# define __USE_XOPEN 1
|
|
107
|
+
# if _XOPEN_SOURCE >= 500
|
|
108
|
+
# define __USE_XOPEN_EXTENDED 1
|
|
109
|
+
# define __USE_UNIX98 1
|
|
110
|
+
# undef _LARGEFILE_SOURCE
|
|
111
|
+
# define _LARGEFILE_SOURCE 1
|
|
112
|
+
# if _XOPEN_SOURCE >= 600
|
|
113
|
+
# if _XOPEN_SOURCE >= 700
|
|
114
|
+
# define __USE_XOPEN2K8 1
|
|
115
|
+
# define __USE_XOPEN2K8XSI 1
|
|
116
|
+
# endif
|
|
117
|
+
# define __USE_XOPEN2K 1
|
|
118
|
+
# define __USE_XOPEN2KXSI 1
|
|
119
|
+
# undef __USE_ISOC95
|
|
120
|
+
# define __USE_ISOC95 1
|
|
121
|
+
# undef __USE_ISOC99
|
|
122
|
+
# define __USE_ISOC99 1
|
|
123
|
+
# endif
|
|
124
|
+
# else
|
|
125
|
+
# ifdef _XOPEN_SOURCE_EXTENDED
|
|
126
|
+
# define __USE_XOPEN_EXTENDED 1
|
|
127
|
+
# endif
|
|
128
|
+
# endif
|
|
129
|
+
#endif
|
|
130
|
+
|
|
131
|
+
#ifdef _LARGEFILE_SOURCE
|
|
132
|
+
# define __USE_LARGEFILE 1
|
|
133
|
+
#endif
|
|
134
|
+
#ifdef _LARGEFILE64_SOURCE
|
|
135
|
+
# define __USE_LARGEFILE64 1
|
|
136
|
+
#endif
|
|
137
|
+
#if defined _FILE_OFFSET_BITS && _FILE_OFFSET_BITS == 64
|
|
138
|
+
# define __USE_FILE_OFFSET64 1
|
|
139
|
+
#endif
|
|
140
|
+
|
|
141
|
+
#ifdef _DEFAULT_SOURCE
|
|
142
|
+
# define __USE_MISC 1
|
|
143
|
+
#endif
|
|
144
|
+
|
|
145
|
+
#ifdef _ATFILE_SOURCE
|
|
146
|
+
# define __USE_ATFILE 1
|
|
147
|
+
#endif
|
|
148
|
+
|
|
149
|
+
#ifdef _GNU_SOURCE
|
|
150
|
+
# define __USE_GNU 1
|
|
151
|
+
# define __USE_DYNAMIC_STACK_SIZE 1
|
|
152
|
+
#endif
|
|
153
|
+
|
|
154
|
+
/* No fortification by default. */
|
|
155
|
+
#ifndef __USE_FORTIFY_LEVEL
|
|
156
|
+
# define __USE_FORTIFY_LEVEL 0
|
|
157
|
+
#endif
|
|
158
|
+
|
|
159
|
+
/* rubycc presents the glibc ABI; report a version so version-gated header code
|
|
160
|
+
takes the same branch it does under glibc. Which version that is cannot be
|
|
161
|
+
written into a header set shipped to every host: on a host whose glibc is
|
|
162
|
+
older than the number below, a gate like "#if __GLIBC_PREREQ (2, 38)" would
|
|
163
|
+
select a branch whose symbols the local C library does not have (docs/GAPS.md
|
|
164
|
+
gap U). rubycc therefore measures the version from the C library the compile
|
|
165
|
+
will link against and predefines __GLIBC__ / __GLIBC_MINOR__ itself
|
|
166
|
+
(Preprocess::GlibcVersion), which is why each is defined here only when it is
|
|
167
|
+
absent. The values below are the fallback for the cases where no measurement
|
|
168
|
+
reached this header: the reference platform this header set was measured on
|
|
169
|
+
(glibc 2.39), a musl target (where the whole file is glibc's surface anyway,
|
|
170
|
+
and where these macros keep the values they have always had here), and a read
|
|
171
|
+
of this header by some other compiler. __GLIBC_PREREQ is not measured and not
|
|
172
|
+
guarded: it is a pure function of the two macros above. */
|
|
173
|
+
#define __GNU_LIBRARY__ 6
|
|
174
|
+
#ifndef __GLIBC__
|
|
175
|
+
# define __GLIBC__ 2
|
|
176
|
+
#endif
|
|
177
|
+
#ifndef __GLIBC_MINOR__
|
|
178
|
+
# define __GLIBC_MINOR__ 39
|
|
179
|
+
#endif
|
|
180
|
+
#define __GLIBC_PREREQ(maj, min) \
|
|
181
|
+
((__GLIBC__ << 16) + __GLIBC_MINOR__ >= ((maj) << 16) + (min))
|
|
182
|
+
|
|
183
|
+
#define __GLIBC_USE(F) __GLIBC_USE_ ## F
|
|
184
|
+
#define __GLIBC_USE_DEPRECATED_GETS 0
|
|
185
|
+
#define __GLIBC_USE_DEPRECATED_SCANF 0
|
|
186
|
+
#define __GLIBC_USE_C2X_STRTOL 0
|
|
187
|
+
#define __GLIBC_USE_ISOC2X 0
|
|
188
|
+
#define __GLIBC_USE_LIB_EXT2 0
|
|
189
|
+
#define __GLIBC_USE_IEC_60559_BFP_EXT 0
|
|
190
|
+
#define __GLIBC_USE_IEC_60559_BFP_EXT_C2X 0
|
|
191
|
+
#define __GLIBC_USE_IEC_60559_EXT 0
|
|
192
|
+
#define __GLIBC_USE_IEC_60559_FUNCS_EXT 0
|
|
193
|
+
#define __GLIBC_USE_IEC_60559_FUNCS_EXT_C2X 0
|
|
194
|
+
#define __GLIBC_USE_IEC_60559_TYPES_EXT 0
|
|
195
|
+
|
|
196
|
+
/* rubycc ships its own <stdc-predef.h>-level knowledge; glibc's headers expect
|
|
197
|
+
__KERNEL_STRICT_NAMES cleared so the kernel-UAPI compatibility names appear. */
|
|
198
|
+
#undef __KERNEL_STRICT_NAMES
|
|
199
|
+
|
|
200
|
+
/* The compiler-abstraction macros live here, exactly as glibc's <features.h>
|
|
201
|
+
pulls in <sys/cdefs.h>. */
|
|
202
|
+
#include <sys/cdefs.h>
|
|
203
|
+
|
|
204
|
+
#endif /* !_FEATURES_H */
|
|
205
|
+
#endif /* _RUBYCC_FEATURES_H */
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
/* rubycc bundled <ctype.h>: character classification (ISO C 7.4). glibc does
|
|
2
|
+
not return a bare 0/1 from isalpha() and kin -- it returns the masked bits of
|
|
3
|
+
a per-locale classification table reached through __ctype_b_loc(), so the
|
|
4
|
+
result values are part of its ABI. This header reproduces that mechanism clean
|
|
5
|
+
room from the published _ISbit formula and accessor signatures (not copied
|
|
6
|
+
from glibc, not derived from musl, whose ctype returns 0/1); the accessor
|
|
7
|
+
functions themselves are resolved from the host libc at link time. The whole
|
|
8
|
+
mechanism is glibc's, so under __RUBYCC_LIBC_MUSL__ (see the preprocessor's
|
|
9
|
+
LIBCS) the classification macros are switched off and the plain function
|
|
10
|
+
calls stand instead -- see the note above them. Placed in the glibc layer
|
|
11
|
+
because that is where the arch-switched headers live; the values themselves
|
|
12
|
+
are arch independent. */
|
|
13
|
+
|
|
14
|
+
#ifndef _RUBYCC_CTYPE_H
|
|
15
|
+
#define _RUBYCC_CTYPE_H
|
|
16
|
+
|
|
17
|
+
/* The classification bit for each property, as glibc lays them out in the table
|
|
18
|
+
entry: properties 0-7 occupy the high byte, 8-11 the low byte. */
|
|
19
|
+
#ifndef _ISbit
|
|
20
|
+
# define _ISbit(bit) ((bit) < 8 ? ((1 << (bit)) << 8) : ((1 << (bit)) >> 8))
|
|
21
|
+
#endif
|
|
22
|
+
|
|
23
|
+
enum {
|
|
24
|
+
_ISupper = _ISbit(0),
|
|
25
|
+
_ISlower = _ISbit(1),
|
|
26
|
+
_ISalpha = _ISbit(2),
|
|
27
|
+
_ISdigit = _ISbit(3),
|
|
28
|
+
_ISxdigit = _ISbit(4),
|
|
29
|
+
_ISspace = _ISbit(5),
|
|
30
|
+
_ISprint = _ISbit(6),
|
|
31
|
+
_ISgraph = _ISbit(7),
|
|
32
|
+
_ISblank = _ISbit(8),
|
|
33
|
+
_IScntrl = _ISbit(9),
|
|
34
|
+
_ISpunct = _ISbit(10),
|
|
35
|
+
_ISalnum = _ISbit(11)
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
extern const unsigned short int **__ctype_b_loc(void);
|
|
39
|
+
extern const int **__ctype_tolower_loc(void);
|
|
40
|
+
extern const int **__ctype_toupper_loc(void);
|
|
41
|
+
|
|
42
|
+
/* The out-of-line entry points (declared so code taking their address still
|
|
43
|
+
links); the macros below inline the common case. */
|
|
44
|
+
extern int isalnum(int __c);
|
|
45
|
+
extern int isalpha(int __c);
|
|
46
|
+
extern int iscntrl(int __c);
|
|
47
|
+
extern int isdigit(int __c);
|
|
48
|
+
extern int islower(int __c);
|
|
49
|
+
extern int isgraph(int __c);
|
|
50
|
+
extern int isprint(int __c);
|
|
51
|
+
extern int ispunct(int __c);
|
|
52
|
+
extern int isspace(int __c);
|
|
53
|
+
extern int isupper(int __c);
|
|
54
|
+
extern int isxdigit(int __c);
|
|
55
|
+
extern int isblank(int __c);
|
|
56
|
+
extern int tolower(int __c);
|
|
57
|
+
extern int toupper(int __c);
|
|
58
|
+
extern int isascii(int __c);
|
|
59
|
+
extern int toascii(int __c);
|
|
60
|
+
|
|
61
|
+
/* The classification macros are glibc's mechanism and glibc's result values,
|
|
62
|
+
so on musl they must not be used at all: the two libraries differ in the
|
|
63
|
+
*shape* of the answer, not merely in a constant. glibc's isalpha('a') is the
|
|
64
|
+
masked table entry (measured 1024, and 2048/8192/... for the other
|
|
65
|
+
properties) while musl's is a bare 1; and musl has no __ctype_b_loc() /
|
|
66
|
+
__ctype_tolower_loc() / __ctype_toupper_loc() to reach a table through in the
|
|
67
|
+
first place, so a table-lookup macro would not even link there. Both
|
|
68
|
+
behaviours measured with the ABI harness, glibc's on this host and musl's on
|
|
69
|
+
the CI aarch64 musl run (docs/STEPS.md Step 202). Under musl the macros are
|
|
70
|
+
therefore left undefined and every classifier resolves to the out-of-line
|
|
71
|
+
function declared above, which is what returns musl's 0/1. The accessor
|
|
72
|
+
prototypes and the _IS* enumerators stay declared on both: a prototype that
|
|
73
|
+
is never called emits nothing, and code that does call one is asking for
|
|
74
|
+
glibc's own interface by name. */
|
|
75
|
+
#if !defined(__RUBYCC_LIBC_MUSL__)
|
|
76
|
+
|
|
77
|
+
#define __isctype(c, type) ((*__ctype_b_loc())[(int)(c)] & (unsigned short int)(type))
|
|
78
|
+
|
|
79
|
+
#define isalnum(c) __isctype((c), _ISalnum)
|
|
80
|
+
#define isalpha(c) __isctype((c), _ISalpha)
|
|
81
|
+
#define iscntrl(c) __isctype((c), _IScntrl)
|
|
82
|
+
#define isdigit(c) __isctype((c), _ISdigit)
|
|
83
|
+
#define islower(c) __isctype((c), _ISlower)
|
|
84
|
+
#define isgraph(c) __isctype((c), _ISgraph)
|
|
85
|
+
#define isprint(c) __isctype((c), _ISprint)
|
|
86
|
+
#define ispunct(c) __isctype((c), _ISpunct)
|
|
87
|
+
#define isspace(c) __isctype((c), _ISspace)
|
|
88
|
+
#define isupper(c) __isctype((c), _ISupper)
|
|
89
|
+
#define isxdigit(c) __isctype((c), _ISxdigit)
|
|
90
|
+
#define isblank(c) __isctype((c), _ISblank)
|
|
91
|
+
|
|
92
|
+
#define tolower(c) ((int) (*__ctype_tolower_loc())[(int)(c)])
|
|
93
|
+
#define toupper(c) ((int) (*__ctype_toupper_loc())[(int)(c)])
|
|
94
|
+
|
|
95
|
+
#endif /* !__RUBYCC_LIBC_MUSL__ */
|
|
96
|
+
|
|
97
|
+
/* isascii/toascii: glibc declares these under __USE_MISC || __USE_XOPEN and
|
|
98
|
+
defines them as pure bit tests (no locale classification table), so the
|
|
99
|
+
inline value matches glibc's out-of-line result exactly -- no ABI subtlety
|
|
100
|
+
like the isalpha() family above. Real sources (e.g. redcarpet's html.c) call
|
|
101
|
+
isascii() with only <ctype.h> included. They stay macros under either C
|
|
102
|
+
library: the probed values (isascii of 'a'/200/0/127, toascii of 0x1FF/'A')
|
|
103
|
+
measured identical on glibc and musl (docs/STEPS.md Step 202), which is why
|
|
104
|
+
they sit outside the branch above. */
|
|
105
|
+
#define isascii(c) (((c) & ~0x7f) == 0)
|
|
106
|
+
#define toascii(c) ((c) & 0x7f)
|
|
107
|
+
|
|
108
|
+
#endif /* _RUBYCC_CTYPE_H */
|