|
2 | 2 |
|
3 | 3 | __BEGIN_DECLS |
4 | 4 |
|
| 5 | +_Pragma("GCC visibility push(hidden)") |
| 6 | + |
5 | 7 | const char *_Nonnull libroot_dyn_get_root_prefix(void); |
6 | 8 | const char *_Nonnull libroot_dyn_get_jbroot_prefix(void); |
7 | 9 | const char *_Nonnull libroot_dyn_get_boot_uuid(void); |
8 | 10 | char *_Nullable libroot_dyn_rootfspath(const char *_Nullable path, char *_Nullable resolvedPath); |
9 | 11 | char *_Nullable libroot_dyn_jbrootpath(const char *_Nullable path, char *_Nullable resolvedPath); |
10 | 12 |
|
| 13 | +_Pragma("GCC visibility pop") |
| 14 | + |
11 | 15 | __END_DECLS |
12 | 16 |
|
| 17 | +#define __CONVERT_PATH_CSTRING(converter, path) ({ \ |
| 18 | + static char outPath[PATH_MAX]; \ |
| 19 | + converter(path, outPath); \ |
| 20 | +}) |
| 21 | + |
| 22 | +#define JBROOT_PATH_CSTRING(path) __CONVERT_PATH_CSTRING(libroot_dyn_jbrootpath, path) |
| 23 | +#define ROOTFS_PATH_CSTRING(path) __CONVERT_PATH_CSTRING(libroot_dyn_rootfspath, path) |
| 24 | + |
| 25 | +#if __has_attribute(overloadable) |
| 26 | +__attribute__((__overloadable__)) |
| 27 | +static inline const char *_Nullable __libroot_convert_path(char *_Nullable (*_Nonnull converter)(const char *_Nonnull, char *_Nullable), const char *_Nullable path, char *_Nonnull buf) { |
| 28 | + return converter(path, buf); |
| 29 | +} |
| 30 | +#endif /* __has_attribute(overloadable) */ |
| 31 | + |
13 | 32 | #ifdef __OBJC__ |
14 | 33 |
|
| 34 | +#import <Foundation/Foundation.h> |
| 35 | + |
15 | 36 | #define __CONVERT_PATH_NSSTRING(converter, path) ({ \ |
16 | 37 | char tmpBuf[PATH_MAX]; \ |
17 | | - [NSString stringWithUTF8String:converter(path.fileSystemRepresentation, tmpBuf)]; \ |
| 38 | + const char *converted = converter(path.fileSystemRepresentation, tmpBuf); \ |
| 39 | + converted ? [NSString stringWithUTF8String:converted] : nil; \ |
18 | 40 | }) |
19 | 41 |
|
20 | 42 | #define JBROOT_PATH_NSSTRING(path) __CONVERT_PATH_NSSTRING(libroot_dyn_jbrootpath, path) |
21 | 43 | #define ROOTFS_PATH_NSSTRING(path) __CONVERT_PATH_NSSTRING(libroot_dyn_rootfspath, path) |
22 | 44 |
|
| 45 | +#if __has_attribute(overloadable) |
| 46 | +__attribute__((__overloadable__)) |
| 47 | +static inline NSString *_Nullable __libroot_convert_path(char *_Nullable (*_Nonnull converter)(const char *_Nonnull, char *_Nullable), NSString *_Nullable path, void *_Nullable const __unused buf) { |
| 48 | + return __CONVERT_PATH_NSSTRING(converter, path); |
| 49 | +} |
| 50 | +#endif /* __has_attribute(overloadable) */ |
| 51 | + |
23 | 52 | #endif /* __OBJC__ */ |
24 | 53 |
|
25 | | -#define __CONVERT_PATH_CSTRING(converter, path) ({ \ |
26 | | - static char outPath[PATH_MAX]; \ |
27 | | - converter(path, outPath); \ |
28 | | -}) |
| 54 | +#if __has_attribute(overloadable) |
29 | 55 |
|
30 | | -#define JBROOT_PATH_CSTRING(path) __CONVERT_PATH_CSTRING(libroot_dyn_jbrootpath, path) |
31 | | -#define ROOTFS_PATH_CSTRING(path) __CONVERT_PATH_CSTRING(libroot_dyn_rootfspath, path) |
| 56 | +#define __BUFFER_FOR_CHAR_P(x) \ |
| 57 | + __builtin_choose_expr( \ |
| 58 | + __builtin_types_compatible_p(__typeof__(*(x)), char), \ |
| 59 | + ({ static char buf[PATH_MAX]; buf; }), \ |
| 60 | + NULL \ |
| 61 | + ) |
| 62 | + |
| 63 | +# define JBROOT_PATH(path) __libroot_convert_path(libroot_dyn_jbrootpath, (path), __BUFFER_FOR_CHAR_P(path)) |
| 64 | +# define ROOTFS_PATH(path) __libroot_convert_path(libroot_dyn_rootfspath, (path), __BUFFER_FOR_CHAR_P(path)) |
| 65 | +#else |
| 66 | +# define JBROOT_PATH(path) _Pragma("GCC error \"JBROOT_PATH is not supported with this compiler, use JBROOT_PATH_CSTRING or JBROOT_PATH_NSSTRING\"") path |
| 67 | +# define ROOTFS_PATH(path) _Pragma("GCC error \"ROOTFS_PATH is not supported with this compiler, use ROOTFS_PATH_CSTRING or ROOTFS_PATH_NSSTRING\"") path |
| 68 | +#endif /* __has_attribute(overloadable) */ |
32 | 69 |
|
33 | 70 | #define JBRAND libroot_dyn_get_boot_uuid() |
0 commit comments