commit 381dc2d9509ffeaf60a1775ee0983c7dd1b9e346 (tree)
parent 575a98a0813181c268e86d590b6267583736bafd
Author: Jakub Konka <kubkon@jakubkonka.com>
Date: Sat, 1 Apr 2023 14:22:29 +0200
Merge pull request #15139 from ziglang/macos-13-fixes
Fixes for latest macOS 13.3 SDK release
Diffstat:
7 files changed, 1960 insertions(+), 1794 deletions(-)
diff --git a/lib/libc/darwin/libSystem.13.tbd b/lib/libc/darwin/libSystem.13.tbd
@@ -2,21 +2,8 @@
tbd-version: 4
targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst,
arm64e-macos, arm64e-maccatalyst ]
-uuids:
- - target: x86_64-macos
- value: 085E3D5D-7871-3E9E-A097-AAD940171411
- - target: x86_64-maccatalyst
- value: 085E3D5D-7871-3E9E-A097-AAD940171411
- - target: arm64-macos
- value: 00000000-0000-0000-0000-000000000000
- - target: arm64-maccatalyst
- value: 00000000-0000-0000-0000-000000000000
- - target: arm64e-macos
- value: B54723A8-A25C-3D6C-A51B-2B8BBA733DD3
- - target: arm64e-maccatalyst
- value: B54723A8-A25C-3D6C-A51B-2B8BBA733DD3
install-name: '/usr/lib/libSystem.B.dylib'
-current-version: 1319
+current-version: 1319.100.3
reexported-libraries:
- targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst,
arm64e-macos, arm64e-maccatalyst ]
@@ -57,21 +44,8 @@ exports:
tbd-version: 4
targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst,
arm64e-macos, arm64e-maccatalyst ]
-uuids:
- - target: x86_64-macos
- value: A7D96CB6-7562-3C14-8B54-ED5E484B54E2
- - target: x86_64-maccatalyst
- value: A7D96CB6-7562-3C14-8B54-ED5E484B54E2
- - target: arm64-macos
- value: 00000000-0000-0000-0000-000000000000
- - target: arm64-maccatalyst
- value: 00000000-0000-0000-0000-000000000000
- - target: arm64e-macos
- value: 7A88909B-ED36-360D-ACE9-81107AF0FE14
- - target: arm64e-maccatalyst
- value: 7A88909B-ED36-360D-ACE9-81107AF0FE14
install-name: '/usr/lib/system/libcache.dylib'
-current-version: 90
+current-version: 92
parent-umbrella:
- targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst,
arm64e-macos, arm64e-maccatalyst ]
@@ -95,21 +69,8 @@ exports:
tbd-version: 4
targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst,
arm64e-macos, arm64e-maccatalyst ]
-uuids:
- - target: x86_64-macos
- value: 6E120635-E858-30FE-95F6-64D90E33095D
- - target: x86_64-maccatalyst
- value: 6E120635-E858-30FE-95F6-64D90E33095D
- - target: arm64-macos
- value: 00000000-0000-0000-0000-000000000000
- - target: arm64-maccatalyst
- value: 00000000-0000-0000-0000-000000000000
- - target: arm64e-macos
- value: 452A7C15-97FA-32A0-B514-744E117E2B39
- - target: arm64e-maccatalyst
- value: 452A7C15-97FA-32A0-B514-744E117E2B39
install-name: '/usr/lib/system/libcommonCrypto.dylib'
-current-version: 60198.60.2
+current-version: 65535.100.4
parent-umbrella:
- targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst,
arm64e-macos, arm64e-maccatalyst ]
@@ -189,13 +150,6 @@ exports:
--- !tapi-tbd
tbd-version: 4
targets: [ x86_64-macos, arm64-macos, arm64e-macos ]
-uuids:
- - target: x86_64-macos
- value: E9412018-811C-36B7-9F58-6471398EE465
- - target: arm64-macos
- value: 954CFCC0-97A8-329B-B5AA-FF9046F3E94F
- - target: arm64e-macos
- value: 9F57BC0A-3F18-3F00-B772-40B6A8616E26
install-name: '/usr/lib/system/libcompiler_rt.dylib'
current-version: 103.1
parent-umbrella:
@@ -424,19 +378,6 @@ exports:
tbd-version: 4
targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst,
arm64e-macos, arm64e-maccatalyst ]
-uuids:
- - target: x86_64-macos
- value: F92F30BA-35BE-3ED9-B562-FBEC1B7089B5
- - target: x86_64-maccatalyst
- value: F92F30BA-35BE-3ED9-B562-FBEC1B7089B5
- - target: arm64-macos
- value: 00000000-0000-0000-0000-000000000000
- - target: arm64-maccatalyst
- value: 00000000-0000-0000-0000-000000000000
- - target: arm64e-macos
- value: 3689048E-9EC2-32D9-B833-B5EDE2839092
- - target: arm64e-maccatalyst
- value: 3689048E-9EC2-32D9-B833-B5EDE2839092
install-name: '/usr/lib/system/libcopyfile.dylib'
parent-umbrella:
- targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst,
@@ -452,21 +393,8 @@ exports:
tbd-version: 4
targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst,
arm64e-macos, arm64e-maccatalyst ]
-uuids:
- - target: x86_64-macos
- value: 1A8A8D34-268F-3D42-936A-8A0029817E22
- - target: x86_64-maccatalyst
- value: 1A8A8D34-268F-3D42-936A-8A0029817E22
- - target: arm64-macos
- value: 00000000-0000-0000-0000-000000000000
- - target: arm64-maccatalyst
- value: 00000000-0000-0000-0000-000000000000
- - target: arm64e-macos
- value: E32C0A9B-EDD0-376D-A504-A06C215E89FE
- - target: arm64e-maccatalyst
- value: E32C0A9B-EDD0-376D-A504-A06C215E89FE
install-name: '/usr/lib/system/libcorecrypto.dylib'
-current-version: 1386.60.8
+current-version: 1387.100.43
parent-umbrella:
- targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst,
arm64e-macos, arm64e-maccatalyst ]
@@ -766,21 +694,8 @@ exports:
tbd-version: 4
targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst,
arm64e-macos, arm64e-maccatalyst ]
-uuids:
- - target: x86_64-macos
- value: 6282E528-6A67-334B-ACCF-1F8FD89369BD
- - target: x86_64-maccatalyst
- value: 6282E528-6A67-334B-ACCF-1F8FD89369BD
- - target: arm64-macos
- value: 00000000-0000-0000-0000-000000000000
- - target: arm64-maccatalyst
- value: 00000000-0000-0000-0000-000000000000
- - target: arm64e-macos
- value: 191028D2-0477-3EBC-9EEF-A85ACAFC7193
- - target: arm64e-maccatalyst
- value: 191028D2-0477-3EBC-9EEF-A85ACAFC7193
install-name: '/usr/lib/system/libdispatch.dylib'
-current-version: 1412
+current-version: 1415.100.11
parent-umbrella:
- targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst,
arm64e-macos, arm64e-maccatalyst ]
@@ -942,19 +857,6 @@ exports:
tbd-version: 4
targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst,
arm64e-macos, arm64e-maccatalyst ]
-uuids:
- - target: x86_64-macos
- value: 6F97B8FD-BA81-3779-ADB2-5ECD91F42B75
- - target: x86_64-maccatalyst
- value: 6F97B8FD-BA81-3779-ADB2-5ECD91F42B75
- - target: arm64-macos
- value: 427D321B-B30E-367F-8E2C-1DA6FD2D0962
- - target: arm64-maccatalyst
- value: 427D321B-B30E-367F-8E2C-1DA6FD2D0962
- - target: arm64e-macos
- value: C1700833-CCA0-3BA5-8614-C149347F5503
- - target: arm64e-maccatalyst
- value: C1700833-CCA0-3BA5-8614-C149347F5503
install-name: '/usr/lib/system/libdyld.dylib'
parent-umbrella:
- targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst,
@@ -1040,19 +942,6 @@ exports:
tbd-version: 4
targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst,
arm64e-macos, arm64e-maccatalyst ]
-uuids:
- - target: x86_64-macos
- value: 4C623CBE-6FF4-3731-A647-6EEF7A6F51C7
- - target: x86_64-maccatalyst
- value: 4C623CBE-6FF4-3731-A647-6EEF7A6F51C7
- - target: arm64-macos
- value: 00000000-0000-0000-0000-000000000000
- - target: arm64-maccatalyst
- value: 00000000-0000-0000-0000-000000000000
- - target: arm64e-macos
- value: B63E11DD-4648-3355-A51C-C1B650654C0F
- - target: arm64e-maccatalyst
- value: B63E11DD-4648-3355-A51C-C1B650654C0F
install-name: '/usr/lib/system/libkeymgr.dylib'
current-version: 31
parent-umbrella:
@@ -1070,21 +959,8 @@ exports:
--- !tapi-tbd
tbd-version: 4
targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64e-macos ]
-uuids:
- - target: x86_64-macos
- value: 632C478C-AAF6-3330-AA8E-0D0FCA4C6237
- - target: x86_64-maccatalyst
- value: 632C478C-AAF6-3330-AA8E-0D0FCA4C6237
- - target: arm64-macos
- value: F71DA09E-609F-3C9A-95BF-22B22CFAD5A5
- - target: arm64-maccatalyst
- value: F71DA09E-609F-3C9A-95BF-22B22CFAD5A5
- - target: arm64e-macos
- value: 471DA066-B65F-36B1-93B7-243C71F8838B
- - target: arm64e-maccatalyst
- value: 471DA066-B65F-36B1-93B7-243C71F8838B
install-name: '/usr/lib/system/libmacho.dylib'
-current-version: 1001.2
+current-version: 1005
parent-umbrella:
- targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64e-macos ]
umbrella: System
@@ -1130,21 +1006,8 @@ exports:
tbd-version: 4
targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst,
arm64e-macos, arm64e-maccatalyst ]
-uuids:
- - target: x86_64-macos
- value: 9C3DCECF-ED9C-3F0F-9E9C-28DC842D4D65
- - target: x86_64-maccatalyst
- value: 9C3DCECF-ED9C-3F0F-9E9C-28DC842D4D65
- - target: arm64-macos
- value: 00000000-0000-0000-0000-000000000000
- - target: arm64-maccatalyst
- value: 00000000-0000-0000-0000-000000000000
- - target: arm64e-macos
- value: A052DB52-9ECA-39EC-8DD4-05A0856579B7
- - target: arm64e-maccatalyst
- value: A052DB52-9ECA-39EC-8DD4-05A0856579B7
install-name: '/usr/lib/system/libquarantine.dylib'
-current-version: 146.60.2
+current-version: 147.100.8
parent-umbrella:
- targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst,
arm64e-macos, arm64e-maccatalyst ]
@@ -1188,21 +1051,8 @@ exports:
tbd-version: 4
targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst,
arm64e-macos, arm64e-maccatalyst ]
-uuids:
- - target: x86_64-macos
- value: A7C519E4-A2A5-33E1-B9D6-52951921392F
- - target: x86_64-maccatalyst
- value: A7C519E4-A2A5-33E1-B9D6-52951921392F
- - target: arm64-macos
- value: 00000000-0000-0000-0000-000000000000
- - target: arm64-maccatalyst
- value: 00000000-0000-0000-0000-000000000000
- - target: arm64e-macos
- value: E785FBDF-82C9-3642-A38D-EDB07D118303
- - target: arm64e-maccatalyst
- value: E785FBDF-82C9-3642-A38D-EDB07D118303
install-name: '/usr/lib/system/libremovefile.dylib'
-current-version: 63
+current-version: 68
parent-umbrella:
- targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst,
arm64e-macos, arm64e-maccatalyst ]
@@ -1219,19 +1069,6 @@ exports:
tbd-version: 4
targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst,
arm64e-macos, arm64e-maccatalyst ]
-uuids:
- - target: x86_64-macos
- value: D32DFE04-D5D4-3BD7-B9B5-9ED721B993EE
- - target: x86_64-maccatalyst
- value: D32DFE04-D5D4-3BD7-B9B5-9ED721B993EE
- - target: arm64-macos
- value: 00000000-0000-0000-0000-000000000000
- - target: arm64-maccatalyst
- value: 00000000-0000-0000-0000-000000000000
- - target: arm64e-macos
- value: 1E8F925A-501E-32BD-9BE3-2EE5FDEA8818
- - target: arm64e-maccatalyst
- value: 1E8F925A-501E-32BD-9BE3-2EE5FDEA8818
install-name: '/usr/lib/system/libsystem_asl.dylib'
current-version: 395
parent-umbrella:
@@ -1313,21 +1150,8 @@ exports:
tbd-version: 4
targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst,
arm64e-macos, arm64e-maccatalyst ]
-uuids:
- - target: x86_64-macos
- value: 942C1938-B1BC-3B74-912C-D7E7E2B6DC72
- - target: x86_64-maccatalyst
- value: 942C1938-B1BC-3B74-912C-D7E7E2B6DC72
- - target: arm64-macos
- value: 00000000-0000-0000-0000-000000000000
- - target: arm64-maccatalyst
- value: 00000000-0000-0000-0000-000000000000
- - target: arm64e-macos
- value: B126606C-8D07-3F9D-AD5E-9864CF11D901
- - target: arm64e-maccatalyst
- value: B126606C-8D07-3F9D-AD5E-9864CF11D901
install-name: '/usr/lib/system/libsystem_blocks.dylib'
-current-version: 84
+current-version: 87
parent-umbrella:
- targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst,
arm64e-macos, arm64e-maccatalyst ]
@@ -1345,38 +1169,25 @@ exports:
tbd-version: 4
targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst,
arm64e-macos, arm64e-maccatalyst ]
-uuids:
- - target: x86_64-macos
- value: 376F7CB7-6DD2-3E00-976F-77DD755BDB0D
- - target: x86_64-maccatalyst
- value: 376F7CB7-6DD2-3E00-976F-77DD755BDB0D
- - target: arm64-macos
- value: 00000000-0000-0000-0000-000000000000
- - target: arm64-maccatalyst
- value: 00000000-0000-0000-0000-000000000000
- - target: arm64e-macos
- value: 756CD0D2-3241-3A74-8C59-02632DCEE221
- - target: arm64e-maccatalyst
- value: 756CD0D2-3241-3A74-8C59-02632DCEE221
install-name: '/usr/lib/system/libsystem_c.dylib'
-current-version: 1534.40.2
+current-version: 1534.100.14
parent-umbrella:
- targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst,
arm64e-macos, arm64e-maccatalyst ]
umbrella: System
exports:
- targets: [ x86_64-macos, x86_64-maccatalyst ]
- symbols: [ '___opendir2$INODE64', ___strtopx, '__readdir_unlocked$INODE64',
- '__seekdir$INODE64', '_alphasort$INODE64', '_daemon$1050',
- '_fdopendir$INODE64', _fstatx64_np, '_fstatx_np$INODE64',
- '_fts_children$INODE64', '_fts_close$INODE64', '_fts_open$INODE64',
- '_fts_open_b$INODE64', '_fts_read$INODE64', '_fts_set$INODE64',
- '_ftw$INODE64', '_getmntinfo$INODE64', _getmntinfo64, '_getmntinfo_r_np$INODE64',
- '_glob$INODE64', '_glob_b$INODE64', _lstatx64_np, '_lstatx_np$INODE64',
- '_nftw$INODE64', '_opendir$INODE64', '_readdir$INODE64', '_readdir_r$INODE64',
+ symbols: [ '___opendir2$INODE64', '__readdir_unlocked$INODE64', '__seekdir$INODE64',
+ '_alphasort$INODE64', '_daemon$1050', '_fdopendir$INODE64',
+ _fstatx64_np, '_fstatx_np$INODE64', '_fts_children$INODE64',
+ '_fts_close$INODE64', '_fts_open$INODE64', '_fts_open_b$INODE64',
+ '_fts_read$INODE64', '_fts_set$INODE64', '_ftw$INODE64', '_getmntinfo$INODE64',
+ _getmntinfo64, '_getmntinfo_r_np$INODE64', '_glob$INODE64',
+ '_glob_b$INODE64', _lstatx64_np, '_lstatx_np$INODE64', '_nftw$INODE64',
+ '_opendir$INODE64', '_readdir$INODE64', '_readdir_r$INODE64',
'_rewinddir$INODE64', '_scandir$INODE64', '_scandir_b$INODE64',
- '_seekdir$INODE64', _statx64_np, '_statx_np$INODE64', '_telldir$INODE64',
- mcount ]
+ '_seekdir$INODE64', _statx64_np, '_statx_np$INODE64', _strtoencf80_l,
+ '_telldir$INODE64', mcount ]
- targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst,
arm64e-macos, arm64e-maccatalyst ]
symbols: [ '$ld$weak$os10.11$_basename_r', '$ld$weak$os10.11$_clock_getres',
@@ -1387,26 +1198,24 @@ exports:
__CurrentRuneLocale, __DefaultRuneLocale, __Exit, __NSGetArgc,
__NSGetArgv, __NSGetEnviron, __NSGetMachExecuteHeader, __NSGetProgname,
__PathLocale, __Read_RuneMagi, ___Balloc_D2A, ___Bfree_D2A,
- ___ULtod_D2A, ____mb_cur_max, ____mb_cur_max_l, ____runetype,
- ____runetype_l, ____tolower, ____tolower_l, ____toupper, ____toupper_l,
- ___add_ovflpage, ___addel, ___any_on_D2A, ___assert_rtn, ___b2d_D2A,
- ___big_delete, ___big_insert, ___big_keydata, ___big_return,
- ___big_split, ___bigtens_D2A, ___bt_close, ___bt_cmp, ___bt_defcmp,
- ___bt_defpfx, ___bt_delete, ___bt_dleaf, ___bt_fd, ___bt_free,
- ___bt_get, ___bt_new, ___bt_open, ___bt_pgin, ___bt_pgout,
- ___bt_put, ___bt_ret, ___bt_search, ___bt_seq, ___bt_setcur,
- ___bt_split, ___bt_sync, ___buf_free, ___call_hash, ___cleanup,
- ___cmp_D2A, ___collate_equiv_match, ___collate_load_error,
- ___collate_lookup, ___collate_lookup_l, ___copybits_D2A, ___cxa_atexit,
- ___cxa_finalize, ___cxa_finalize_ranges, ___cxa_thread_atexit,
- ___d2b_D2A, ___dbpanic, ___decrement_D2A, ___default_hash,
- ___default_utx, ___delpair, ___diff_D2A, ___dtoa, ___expand_table,
- ___fflush, ___fgetwc, ___find_bigpair, ___find_last_page,
- ___fix_locale_grouping_str, ___fread, ___free_ovflpage, ___freedtoa,
- ___gdtoa, ___gdtoa_locks, ___get_buf, ___get_page, ___gethex_D2A,
- ___getonlyClocaleconv, ___hash_open, ___hdtoa, ___hexdig_D2A,
- ___hexdig_init_D2A, ___hexnan_D2A, ___hi0bits_D2A, ___hldtoa,
- ___i2b_D2A, ___ibitmap, ___increment_D2A, ___isctype, ___istype,
+ ____mb_cur_max, ____mb_cur_max_l, ____runetype, ____runetype_l,
+ ____tolower, ____tolower_l, ____toupper, ____toupper_l, ___add_ovflpage,
+ ___addel, ___any_on_D2A, ___assert_rtn, ___b2d_D2A, ___big_delete,
+ ___big_insert, ___big_keydata, ___big_return, ___big_split,
+ ___bigtens_D2A, ___bt_close, ___bt_cmp, ___bt_defcmp, ___bt_defpfx,
+ ___bt_delete, ___bt_dleaf, ___bt_fd, ___bt_free, ___bt_get,
+ ___bt_new, ___bt_open, ___bt_pgin, ___bt_pgout, ___bt_put,
+ ___bt_ret, ___bt_search, ___bt_seq, ___bt_setcur, ___bt_split,
+ ___bt_sync, ___buf_free, ___call_hash, ___cleanup, ___cmp_D2A,
+ ___collate_equiv_match, ___collate_load_error, ___collate_lookup,
+ ___collate_lookup_l, ___copybits_D2A, ___cxa_atexit, ___cxa_finalize,
+ ___cxa_finalize_ranges, ___cxa_thread_atexit, ___d2b_D2A,
+ ___dbpanic, ___default_hash, ___default_utx, ___delpair, ___diff_D2A,
+ ___dtoa, ___expand_table, ___fflush, ___fgetwc, ___find_bigpair,
+ ___find_last_page, ___fix_locale_grouping_str, ___fread, ___free_ovflpage,
+ ___freedtoa, ___gdtoa, ___gdtoa_locks, ___get_buf, ___get_page,
+ ___getonlyClocaleconv, ___hash_open, ___hdtoa, ___hi0bits_D2A,
+ ___hldtoa, ___i2b_D2A, ___ibitmap, ___isctype, ___istype,
___istype_l, ___ldtoa, ___libc_init, ___lo0bits_D2A, ___log2,
___lshift_D2A, ___maskrune, ___maskrune_l, ___match_D2A, ___mb_cur_max,
___mb_sb_limit, ___memccpy_chk, ___memcpy_chk, ___memmove_chk,
@@ -1417,53 +1226,54 @@ exports:
___rec_iput, ___rec_open, ___rec_put, ___rec_ret, ___rec_search,
___rec_seq, ___rec_sync, ___rec_vmap, ___rec_vpipe, ___reclaim_buf,
___rshift_D2A, ___rv_alloc_D2A, ___s2b_D2A, ___sF, ___sclose,
- ___sdidinit, ___set_ones_D2A, ___setonlyClocaleconv, ___sflags,
- ___sflush, ___sfp, ___sfvwrite, ___sglue, ___sinit, ___slbexpand,
- ___smakebuf, ___snprintf_chk, ___snprintf_object_size_chk,
- ___split_page, ___sprintf_chk, ___sprintf_object_size_chk,
- ___sread, ___srefill, ___srget, ___sseek, ___stack_chk_fail,
- ___stack_chk_guard, ___stderrp, ___stdinp, ___stdoutp, ___stpcpy_chk,
- ___stpncpy_chk, ___strcat_chk, ___strcp_D2A, ___strcpy_chk,
- ___strlcat_chk, ___strlcpy_chk, ___strncat_chk, ___strncpy_chk,
- ___strtodg, ___strtopdd, ___sum_D2A, ___svfscanf, ___swbuf,
- ___swhatbuf, ___swrite, ___swsetup, ___tens_D2A, ___tinytens_D2A,
- ___tolower, ___tolower_l, ___toupper, ___toupper_l, ___trailz_D2A,
- ___ulp_D2A, ___ungetc, ___ungetwc, ___vsnprintf_chk, ___vsprintf_chk,
- ___wcwidth, ___wcwidth_l, __allocenvstate, __atexit_receipt,
- __c_locale, __cleanup, __closeutx, __copyenv, __cthread_init_routine,
- __deallocenvstate, __endutxent, __flockfile_debug_stub, __fseeko,
- __ftello, __fwalk, __getenvp, __getutxent, __getutxid, __getutxline,
- __inet_aton_check, __init_clock_port, __int_to_time, __libc_fork_child,
- __libc_initializer, __long_to_time, __mkpath_np, __mktemp,
- __openutx, __os_assert_log, __os_assert_log_ctx, __os_assumes_log,
- __os_assumes_log_ctx, __os_avoid_tail_call, __os_crash, __os_crash_callback,
- __os_crash_fmt, __os_crash_msg, __os_debug_log, __os_debug_log_error_offset,
- __os_debug_log_error_str, __putenvp, __pututxline, __rand48_add,
- __rand48_mult, __rand48_seed, __readdir_unlocked, __reclaim_telldir,
- __seekdir, __setenvp, __setutxent, __sigaction_nobind, __sigintr,
- __signal_nobind, __sigvec_nobind, __sread, __sseek, __subsystem_init,
- __swrite, __time32_to_time, __time64_to_time, __time_to_int,
- __time_to_long, __time_to_time32, __time_to_time64, __unsetenvp,
- __utmpxname, _a64l, _abort, _abort_report_np, _abs, _acl_add_flag_np,
- _acl_add_perm, _acl_calc_mask, _acl_clear_flags_np, _acl_clear_perms,
- _acl_copy_entry, _acl_copy_ext, _acl_copy_ext_native, _acl_copy_int,
- _acl_copy_int_native, _acl_create_entry, _acl_create_entry_np,
- _acl_delete_def_file, _acl_delete_entry, _acl_delete_fd_np,
- _acl_delete_file_np, _acl_delete_flag_np, _acl_delete_link_np,
- _acl_delete_perm, _acl_dup, _acl_free, _acl_from_text, _acl_get_entry,
- _acl_get_fd, _acl_get_fd_np, _acl_get_file, _acl_get_flag_np,
- _acl_get_flagset_np, _acl_get_link_np, _acl_get_perm_np, _acl_get_permset,
- _acl_get_permset_mask_np, _acl_get_qualifier, _acl_get_tag_type,
- _acl_init, _acl_maximal_permset_mask_np, _acl_set_fd, _acl_set_fd_np,
- _acl_set_file, _acl_set_flagset_np, _acl_set_link_np, _acl_set_permset,
- _acl_set_permset_mask_np, _acl_set_qualifier, _acl_set_tag_type,
- _acl_size, _acl_to_text, _acl_valid, _acl_valid_fd_np, _acl_valid_file_np,
- _acl_valid_link, _addr2ascii, _alarm, _alphasort, _arc4random,
- _arc4random_addrandom, _arc4random_buf, _arc4random_stir,
- _arc4random_uniform, _ascii2addr, _asctime, _asctime_r, _asprintf,
- _asprintf_l, _asxprintf, _asxprintf_exec, _atexit, _atexit_b,
- _atof, _atof_l, _atoi, _atoi_l, _atol, _atol_l, _atoll, _atoll_l,
- _backtrace, _backtrace_async, _backtrace_from_fp, _backtrace_image_offsets,
+ ___sdidinit, ___setonlyClocaleconv, ___sflags, ___sflush,
+ ___sfp, ___sfvwrite, ___sglue, ___sinit, ___slbexpand, ___smakebuf,
+ ___snprintf_chk, ___snprintf_object_size_chk, ___split_page,
+ ___sprintf_chk, ___sprintf_object_size_chk, ___sread, ___srefill,
+ ___srget, ___sseek, ___stack_chk_fail, ___stack_chk_guard,
+ ___stderrp, ___stdinp, ___stdoutp, ___stpcpy_chk, ___stpncpy_chk,
+ ___strcat_chk, ___strcp_D2A, ___strcpy_chk, ___strlcat_chk,
+ ___strlcpy_chk, ___strncat_chk, ___strncpy_chk, ___sum_D2A,
+ ___svfscanf, ___swbuf, ___swhatbuf, ___swrite, ___swsetup,
+ ___tens_D2A, ___tinytens_D2A, ___tolower, ___tolower_l, ___toupper,
+ ___toupper_l, ___trailz_D2A, ___ulp_D2A, ___ungetc, ___ungetwc,
+ ___vsnprintf_chk, ___vsprintf_chk, ___wcwidth, ___wcwidth_l,
+ __allocenvstate, __atexit_receipt, __c_locale, __cleanup,
+ __closeutx, __copyenv, __cthread_init_routine, __deallocenvstate,
+ __endutxent, __flockfile_debug_stub, __fseeko, __ftello, __fwalk,
+ __getenvp, __getutxent, __getutxid, __getutxline, __inet_aton_check,
+ __init_clock_port, __int_to_time, __libc_fork_child, __libc_fork_parent,
+ __libc_fork_prepare, __libc_initializer, __long_to_time, __mkpath_np,
+ __mktemp, __openutx, __os_assert_log, __os_assert_log_ctx,
+ __os_assumes_log, __os_assumes_log_ctx, __os_avoid_tail_call,
+ __os_crash, __os_crash_callback, __os_crash_fmt, __os_crash_msg,
+ __os_debug_log, __os_debug_log_error_offset, __os_debug_log_error_str,
+ __putenvp, __pututxline, __rand48_add, __rand48_mult, __rand48_seed,
+ __readdir_unlocked, __reclaim_telldir, __seekdir, __setenvp,
+ __setutxent, __sigaction_nobind, __sigintr, __signal_nobind,
+ __sigvec_nobind, __sread, __sseek, __subsystem_init, __swrite,
+ __time32_to_time, __time64_to_time, __time_to_int, __time_to_long,
+ __time_to_time32, __time_to_time64, __unsetenvp, __utmpxname,
+ _a64l, _abort, _abort_report_np, _abs, _acl_add_flag_np, _acl_add_perm,
+ _acl_calc_mask, _acl_clear_flags_np, _acl_clear_perms, _acl_copy_entry,
+ _acl_copy_ext, _acl_copy_ext_native, _acl_copy_int, _acl_copy_int_native,
+ _acl_create_entry, _acl_create_entry_np, _acl_delete_def_file,
+ _acl_delete_entry, _acl_delete_fd_np, _acl_delete_file_np,
+ _acl_delete_flag_np, _acl_delete_link_np, _acl_delete_perm,
+ _acl_dup, _acl_free, _acl_from_text, _acl_get_entry, _acl_get_fd,
+ _acl_get_fd_np, _acl_get_file, _acl_get_flag_np, _acl_get_flagset_np,
+ _acl_get_link_np, _acl_get_perm_np, _acl_get_permset, _acl_get_permset_mask_np,
+ _acl_get_qualifier, _acl_get_tag_type, _acl_init, _acl_maximal_permset_mask_np,
+ _acl_set_fd, _acl_set_fd_np, _acl_set_file, _acl_set_flagset_np,
+ _acl_set_link_np, _acl_set_permset, _acl_set_permset_mask_np,
+ _acl_set_qualifier, _acl_set_tag_type, _acl_size, _acl_to_text,
+ _acl_valid, _acl_valid_fd_np, _acl_valid_file_np, _acl_valid_link,
+ _addr2ascii, _alarm, _alphasort, _arc4random, _arc4random_addrandom,
+ _arc4random_buf, _arc4random_stir, _arc4random_uniform, _ascii2addr,
+ _asctime, _asctime_r, _asprintf, _asprintf_l, _asxprintf,
+ _asxprintf_exec, _atexit, _atexit_b, _atof, _atof_l, _atoi,
+ _atoi_l, _atol, _atol_l, _atoll, _atoll_l, _backtrace, _backtrace_async,
+ _backtrace_from_fp, _backtrace_image_offsets, _backtrace_set_pcs_func,
_backtrace_symbols, _backtrace_symbols_fd, _basename, _basename_r,
_bcopy, _brk, _bsd_signal, _bsearch, _bsearch_b, _btowc, _btowc_l,
_catclose, _catgets, _catopen, _cfgetispeed, _cfgetospeed,
@@ -1587,16 +1397,17 @@ exports:
_strncat, _strndup, _strnstr, _strnunvis, _strnunvisx, _strnvis,
_strnvisx, _strpbrk, _strptime, _strptime_l, _strrchr, _strsenvisx,
_strsep, _strsignal, _strsignal_r, _strsnvis, _strsnvisx,
- _strspn, _strsvis, _strsvisx, _strtod, _strtod_l, _strtof,
- _strtof_l, _strtofflags, _strtoimax, _strtoimax_l, _strtok,
- _strtok_r, _strtol, _strtol_l, _strtold, _strtold_l, _strtoll,
- _strtoll_l, _strtonum, _strtoq, _strtoq_l, _strtoul, _strtoul_l,
- _strtoull, _strtoull_l, _strtoumax, _strtoumax_l, _strtouq,
- _strtouq_l, _strunvis, _strunvisx, _strvis, _strvisx, _strxfrm,
- _strxfrm_l, _suboptarg, _svis, _swab, _swprintf, _swprintf_l,
- _swscanf, _swscanf_l, _sxprintf, _sxprintf_exec, _sync_volume_np,
- _sys_errlist, _sys_nerr, _sys_siglist, _sys_signame, _sysconf,
- _sysctl, _sysctlbyname, _sysctlnametomib, _system, '_system$NOCANCEL',
+ _strspn, _strsvis, _strsvisx, _strtod, _strtod_l, _strtoencf16,
+ _strtoencf32, _strtoencf64, _strtoencf64x, _strtof, _strtof_l,
+ _strtofflags, _strtoimax, _strtoimax_l, _strtok, _strtok_r,
+ _strtol, _strtol_l, _strtold, _strtold_l, _strtoll, _strtoll_l,
+ _strtonum, _strtoq, _strtoq_l, _strtoul, _strtoul_l, _strtoull,
+ _strtoull_l, _strtoumax, _strtoumax_l, _strtouq, _strtouq_l,
+ _strunvis, _strunvisx, _strvis, _strvisx, _strxfrm, _strxfrm_l,
+ _suboptarg, _svis, _swab, _swprintf, _swprintf_l, _swscanf,
+ _swscanf_l, _sxprintf, _sxprintf_exec, _sync_volume_np, _sys_errlist,
+ _sys_nerr, _sys_siglist, _sys_signame, _sysconf, _sysctl,
+ _sysctlbyname, _sysctlnametomib, _system, '_system$NOCANCEL',
_tcdrain, '_tcdrain$NOCANCEL', _tcflow, _tcflush, _tcgetattr,
_tcgetpgrp, _tcgetsid, _tcsendbreak, _tcsetattr, _tcsetpgrp,
_tdelete, _telldir, _tempnam, _tfind, _thread_stack_async_pcs,
@@ -1652,21 +1463,8 @@ reexports:
tbd-version: 4
targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst,
arm64e-macos, arm64e-maccatalyst ]
-uuids:
- - target: x86_64-macos
- value: 2053883C-79F4-3AF8-A37C-DE204E208C60
- - target: x86_64-maccatalyst
- value: 2053883C-79F4-3AF8-A37C-DE204E208C60
- - target: arm64-macos
- value: 00000000-0000-0000-0000-000000000000
- - target: arm64-maccatalyst
- value: 00000000-0000-0000-0000-000000000000
- - target: arm64e-macos
- value: CB445464-28B4-353C-976E-59DA0E229FED
- - target: arm64e-maccatalyst
- value: CB445464-28B4-353C-976E-59DA0E229FED
install-name: '/usr/lib/system/libsystem_collections.dylib'
-current-version: 1534.40.2
+current-version: 1534.100.14
parent-umbrella:
- targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst,
arm64e-macos, arm64e-maccatalyst ]
@@ -1695,21 +1493,8 @@ exports:
tbd-version: 4
targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst,
arm64e-macos, arm64e-maccatalyst ]
-uuids:
- - target: x86_64-macos
- value: E7F80C5C-E18C-3201-ACB6-9A4C46B6574B
- - target: x86_64-maccatalyst
- value: E7F80C5C-E18C-3201-ACB6-9A4C46B6574B
- - target: arm64-macos
- value: 00000000-0000-0000-0000-000000000000
- - target: arm64-maccatalyst
- value: 00000000-0000-0000-0000-000000000000
- - target: arm64e-macos
- value: 113A1DDB-1B61-3C33-9FD5-B39A2A29D779
- - target: arm64e-maccatalyst
- value: 113A1DDB-1B61-3C33-9FD5-B39A2A29D779
install-name: '/usr/lib/system/libsystem_configuration.dylib'
-current-version: 1241.60.3
+current-version: 1241.100.11
parent-umbrella:
- targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst,
arm64e-macos, arm64e-maccatalyst ]
@@ -1735,19 +1520,6 @@ exports:
tbd-version: 4
targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst,
arm64e-macos, arm64e-maccatalyst ]
-uuids:
- - target: x86_64-macos
- value: D44E0845-001C-3C46-B3A7-E4926DAEF6B3
- - target: x86_64-maccatalyst
- value: D44E0845-001C-3C46-B3A7-E4926DAEF6B3
- - target: arm64-macos
- value: 00000000-0000-0000-0000-000000000000
- - target: arm64-maccatalyst
- value: 00000000-0000-0000-0000-000000000000
- - target: arm64e-macos
- value: 2694748C-A452-3438-BB47-161D7B220AE2
- - target: arm64e-maccatalyst
- value: 2694748C-A452-3438-BB47-161D7B220AE2
install-name: '/usr/lib/system/libsystem_containermanager.dylib'
parent-umbrella:
- targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst,
@@ -1792,6 +1564,7 @@ exports:
_container_create_or_lookup_app_group_paths, _container_create_or_lookup_app_group_paths_for_current_user,
_container_create_or_lookup_app_group_paths_for_platform,
_container_create_or_lookup_app_group_paths_from_entitlements,
+ _container_create_or_lookup_app_group_paths_from_entitlements_4ls,
_container_create_or_lookup_for_current_user, _container_create_or_lookup_for_platform,
_container_create_or_lookup_group_container_paths_for_current_user,
_container_create_or_lookup_path, _container_create_or_lookup_path_for_current_user,
@@ -1910,19 +1683,6 @@ exports:
tbd-version: 4
targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst,
arm64e-macos, arm64e-maccatalyst ]
-uuids:
- - target: x86_64-macos
- value: D86D13CC-2AF9-3A17-BCF3-0D16703F99A7
- - target: x86_64-maccatalyst
- value: D86D13CC-2AF9-3A17-BCF3-0D16703F99A7
- - target: arm64-macos
- value: 00000000-0000-0000-0000-000000000000
- - target: arm64-maccatalyst
- value: 00000000-0000-0000-0000-000000000000
- - target: arm64e-macos
- value: 6E9DED8E-2A44-33E3-909F-74B4786482A2
- - target: arm64e-maccatalyst
- value: 6E9DED8E-2A44-33E3-909F-74B4786482A2
install-name: '/usr/lib/system/libsystem_coreservices.dylib'
current-version: 129
parent-umbrella:
@@ -1944,19 +1704,6 @@ exports:
tbd-version: 4
targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst,
arm64e-macos, arm64e-maccatalyst ]
-uuids:
- - target: x86_64-macos
- value: E272E2C2-8511-3C94-8C39-F5319F2812BB
- - target: x86_64-maccatalyst
- value: E272E2C2-8511-3C94-8C39-F5319F2812BB
- - target: arm64-macos
- value: 00000000-0000-0000-0000-000000000000
- - target: arm64-maccatalyst
- value: 00000000-0000-0000-0000-000000000000
- - target: arm64e-macos
- value: 74F6C923-5FF6-39D0-90DE-8FB4812EA263
- - target: arm64e-maccatalyst
- value: 74F6C923-5FF6-39D0-90DE-8FB4812EA263
install-name: '/usr/lib/system/libsystem_darwin.dylib'
parent-umbrella:
- targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst,
@@ -1995,21 +1742,8 @@ exports:
tbd-version: 4
targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst,
arm64e-macos, arm64e-maccatalyst ]
-uuids:
- - target: x86_64-macos
- value: 77610ACE-81D4-33E5-A343-5FDA27F53E10
- - target: x86_64-maccatalyst
- value: 77610ACE-81D4-33E5-A343-5FDA27F53E10
- - target: arm64-macos
- value: 00000000-0000-0000-0000-000000000000
- - target: arm64-maccatalyst
- value: 00000000-0000-0000-0000-000000000000
- - target: arm64e-macos
- value: F87EFC17-B673-3488-B503-C67E2FFDE6A0
- - target: arm64e-maccatalyst
- value: F87EFC17-B673-3488-B503-C67E2FFDE6A0
install-name: '/usr/lib/system/libsystem_dnssd.dylib'
-current-version: 1790.60.25
+current-version: 1807.101.2
parent-umbrella:
- targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst,
arm64e-macos, arm64e-maccatalyst ]
@@ -2045,21 +1779,8 @@ exports:
tbd-version: 4
targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst,
arm64e-macos, arm64e-maccatalyst ]
-uuids:
- - target: x86_64-macos
- value: 223BBDCF-6D59-3770-9E6A-38B762676030
- - target: x86_64-maccatalyst
- value: 223BBDCF-6D59-3770-9E6A-38B762676030
- - target: arm64-macos
- value: 00000000-0000-0000-0000-000000000000
- - target: arm64-maccatalyst
- value: 00000000-0000-0000-0000-000000000000
- - target: arm64e-macos
- value: EE355E15-A47F-3BED-A955-1041497449AE
- - target: arm64e-maccatalyst
- value: EE355E15-A47F-3BED-A955-1041497449AE
install-name: '/usr/lib/system/libsystem_featureflags.dylib'
-current-version: 71
+current-version: 74
parent-umbrella:
- targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst,
arm64e-macos, arm64e-maccatalyst ]
@@ -2072,19 +1793,6 @@ exports:
tbd-version: 4
targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst,
arm64e-macos, arm64e-maccatalyst ]
-uuids:
- - target: x86_64-macos
- value: 7B76D94D-56F7-3B8A-B63D-ED567EFA12F6
- - target: x86_64-maccatalyst
- value: 7B76D94D-56F7-3B8A-B63D-ED567EFA12F6
- - target: arm64-macos
- value: 00000000-0000-0000-0000-000000000000
- - target: arm64-maccatalyst
- value: 00000000-0000-0000-0000-000000000000
- - target: arm64e-macos
- value: 67168754-ABAC-33C6-AFF7-FF53F1A8745C
- - target: arm64e-maccatalyst
- value: 67168754-ABAC-33C6-AFF7-FF53F1A8745C
install-name: '/usr/lib/system/libsystem_info.dylib'
parent-umbrella:
- targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst,
@@ -2209,21 +1917,8 @@ exports:
tbd-version: 4
targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst,
arm64e-macos, arm64e-maccatalyst ]
-uuids:
- - target: x86_64-macos
- value: 7C3DCC95-9F42-3C7C-8796-476FF67B9CF7
- - target: x86_64-maccatalyst
- value: 7C3DCC95-9F42-3C7C-8796-476FF67B9CF7
- - target: arm64-macos
- value: EB0327EE-CB9C-37ED-AB6A-E9AF74E814F0
- - target: arm64-maccatalyst
- value: EB0327EE-CB9C-37ED-AB6A-E9AF74E814F0
- - target: arm64e-macos
- value: AEBF397E-E2EF-3A49-BE58-23D4558511F6
- - target: arm64e-maccatalyst
- value: AEBF397E-E2EF-3A49-BE58-23D4558511F6
install-name: '/usr/lib/system/libsystem_kernel.dylib'
-current-version: 8792.61.2
+current-version: 8796.101.5
parent-umbrella:
- targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst,
arm64e-macos, arm64e-maccatalyst ]
@@ -2243,19 +1938,20 @@ exports:
___channel_get_opt, ___channel_open, ___channel_set_opt, ___channel_sync,
___chmod, ___chmod_extended, ___close_nocancel, ___coalition,
___coalition_info, ___coalition_ledger, ___commpage_gettimeofday,
- ___connect, ___connect_nocancel, ___copyfile, ___csrctl, ___darwin_check_fd_set_overflow,
- ___debug_syscall_reject, ___debug_syscall_reject_config, ___delete,
- ___disable_threadsignal, ___error, ___execve, ___exit, ___fchmod,
- ___fchmod_extended, ___fcntl, ___fcntl_nocancel, ___fork,
- ___fs_snapshot, ___fstat64_extended, ___fstat_extended, ___fsync_nocancel,
- ___get_remove_counter, ___getattrlist, ___getdirentries64,
- ___gethostuuid, ___getlogin, ___getpeername, ___getpid, ___getrlimit,
- ___getsgroups, ___getsockname, ___gettid, ___gettimeofday,
- ___getwgroups, ___guarded_open_dprotected_np, ___guarded_open_np,
- ___identitysvc, ___inc_remove_counter, ___initgroups, ___ioctl,
- ___iopolicysys, ___kdebug_trace, ___kdebug_trace64, ___kdebug_trace_string,
- ___kdebug_typefilter, ___kill, ___kqueue_workloop_ctl, ___lchown,
- ___libkernel_init, ___libkernel_init_after_boot_tasks, ___libkernel_init_late,
+ ___connect, ___connect_nocancel, ___copyfile, ___crossarch_trap,
+ ___csrctl, ___darwin_check_fd_set_overflow, ___debug_syscall_reject,
+ ___debug_syscall_reject_config, ___delete, ___disable_threadsignal,
+ ___error, ___execve, ___exit, ___fchmod, ___fchmod_extended,
+ ___fcntl, ___fcntl_nocancel, ___fork, ___fs_snapshot, ___fstat64_extended,
+ ___fstat_extended, ___fsync_nocancel, ___get_remove_counter,
+ ___getattrlist, ___getdirentries64, ___gethostuuid, ___getlogin,
+ ___getpeername, ___getpid, ___getrlimit, ___getsgroups, ___getsockname,
+ ___gettid, ___gettimeofday, ___getwgroups, ___guarded_open_dprotected_np,
+ ___guarded_open_np, ___identitysvc, ___inc_remove_counter,
+ ___initgroups, ___ioctl, ___iopolicysys, ___kdebug_trace,
+ ___kdebug_trace64, ___kdebug_trace_string, ___kdebug_typefilter,
+ ___kill, ___kqueue_workloop_ctl, ___lchown, ___libkernel_init,
+ ___libkernel_init_after_boot_tasks, ___libkernel_init_late,
___libkernel_platform_init, ___libkernel_voucher_init, ___listen,
___log_data, ___lseek, ___lstat64_extended, ___lstat_extended,
___mac_execve, ___mac_get_fd, ___mac_get_file, ___mac_get_link,
@@ -2572,32 +2268,32 @@ exports:
_posix_spawnattr_set_uid_np, _posix_spawnattr_setarchpref_np,
_posix_spawnattr_setauditsessionport_np, _posix_spawnattr_setbinpref_np,
_posix_spawnattr_setcoalition_np, _posix_spawnattr_setcpumonitor,
- _posix_spawnattr_setcpumonitor_default, _posix_spawnattr_setexceptionports_np,
- _posix_spawnattr_setflags, _posix_spawnattr_setjetsam_ext,
- _posix_spawnattr_setmacpolicyinfo_np, _posix_spawnattr_setnosmt_np,
- _posix_spawnattr_setpcontrol_np, _posix_spawnattr_setpgroup,
- _posix_spawnattr_setprocesstype_np, _posix_spawnattr_setsigdefault,
- _posix_spawnattr_setsigmask, _posix_spawnattr_setspecialport_np,
- _pread, '_pread$NOCANCEL', _preadv, '_preadv$NOCANCEL', _proc_clear_cpulimits,
- _proc_clear_delayidlesleep, _proc_clear_dirty, _proc_clear_vmpressure,
- _proc_current_thread_schedinfo, _proc_denap_assertion_begin_with_msg,
- _proc_denap_assertion_complete, _proc_disable_apptype, _proc_disable_cpumon,
- _proc_disable_wakemon, _proc_donate_importance_boost, _proc_enable_apptype,
- _proc_get_cpumon_params, _proc_get_dirty, _proc_get_wakemon_params,
- _proc_importance_assertion_begin_with_msg, _proc_importance_assertion_complete,
- _proc_kmsgbuf, _proc_libversion, _proc_list_dynkqueueids,
- _proc_list_uptrs, _proc_listallpids, _proc_listchildpids,
- _proc_listcoalitions, _proc_listpgrppids, _proc_listpids,
- _proc_listpidspath, _proc_name, _proc_pid_rusage, _proc_piddynkqueueinfo,
- _proc_pidfdinfo, _proc_pidfileportinfo, _proc_pidinfo, _proc_pidoriginatorinfo,
- _proc_pidpath, _proc_pidpath_audittoken, _proc_regionfilename,
- _proc_reset_footprint_interval, _proc_resume_cpumon, _proc_rlimit_control,
- _proc_set_cpumon_defaults, _proc_set_cpumon_params, _proc_set_cpumon_params_fatal,
- _proc_set_csm, _proc_set_delayidlesleep, _proc_set_dirty,
- _proc_set_no_smt, _proc_set_owner_vmpressure, _proc_set_wakemon_defaults,
- _proc_set_wakemon_params, _proc_setcpu_percentage, _proc_setpcontrol,
- _proc_setthread_cpupercent, _proc_setthread_csm, _proc_setthread_no_smt,
- _proc_suppress, _proc_terminate, _proc_terminate_all_rsr,
+ _posix_spawnattr_setcpumonitor_default, _posix_spawnattr_setdataless_iopolicy_np,
+ _posix_spawnattr_setexceptionports_np, _posix_spawnattr_setflags,
+ _posix_spawnattr_setjetsam_ext, _posix_spawnattr_setmacpolicyinfo_np,
+ _posix_spawnattr_setnosmt_np, _posix_spawnattr_setpcontrol_np,
+ _posix_spawnattr_setpgroup, _posix_spawnattr_setprocesstype_np,
+ _posix_spawnattr_setsigdefault, _posix_spawnattr_setsigmask,
+ _posix_spawnattr_setspecialport_np, _pread, '_pread$NOCANCEL',
+ _preadv, '_preadv$NOCANCEL', _proc_clear_cpulimits, _proc_clear_delayidlesleep,
+ _proc_clear_dirty, _proc_clear_vmpressure, _proc_current_thread_schedinfo,
+ _proc_denap_assertion_begin_with_msg, _proc_denap_assertion_complete,
+ _proc_disable_apptype, _proc_disable_cpumon, _proc_disable_wakemon,
+ _proc_donate_importance_boost, _proc_enable_apptype, _proc_get_cpumon_params,
+ _proc_get_dirty, _proc_get_wakemon_params, _proc_importance_assertion_begin_with_msg,
+ _proc_importance_assertion_complete, _proc_kmsgbuf, _proc_libversion,
+ _proc_list_dynkqueueids, _proc_list_uptrs, _proc_listallpids,
+ _proc_listchildpids, _proc_listcoalitions, _proc_listpgrppids,
+ _proc_listpids, _proc_listpidspath, _proc_name, _proc_pid_rusage,
+ _proc_piddynkqueueinfo, _proc_pidfdinfo, _proc_pidfileportinfo,
+ _proc_pidinfo, _proc_pidoriginatorinfo, _proc_pidpath, _proc_pidpath_audittoken,
+ _proc_regionfilename, _proc_reset_footprint_interval, _proc_resume_cpumon,
+ _proc_rlimit_control, _proc_set_cpumon_defaults, _proc_set_cpumon_params,
+ _proc_set_cpumon_params_fatal, _proc_set_csm, _proc_set_delayidlesleep,
+ _proc_set_dirty, _proc_set_no_smt, _proc_set_owner_vmpressure,
+ _proc_set_wakemon_defaults, _proc_set_wakemon_params, _proc_setcpu_percentage,
+ _proc_setpcontrol, _proc_setthread_cpupercent, _proc_setthread_csm,
+ _proc_setthread_no_smt, _proc_suppress, _proc_terminate, _proc_terminate_all_rsr,
_proc_trace_log, _proc_track_dirty, _proc_udata_info, _proc_uuid_policy,
_processor_assign, _processor_control, _processor_exit, _processor_get_assignment,
_processor_info, _processor_set_create, _processor_set_default,
@@ -2707,25 +2403,8 @@ exports:
tbd-version: 4
targets: [ x86_64-macos, x86_64-maccatalyst, x86_64h-macos, x86_64h-maccatalyst,
arm64-macos, arm64-maccatalyst, arm64e-macos, arm64e-maccatalyst ]
-uuids:
- - target: x86_64-macos
- value: DC460796-C8A7-3507-8539-C890D9EDDC8C
- - target: x86_64-maccatalyst
- value: DC460796-C8A7-3507-8539-C890D9EDDC8C
- - target: x86_64h-macos
- value: 73F0FC1C-FC2A-3B36-8796-7C2C2CBA7214
- - target: x86_64h-maccatalyst
- value: 73F0FC1C-FC2A-3B36-8796-7C2C2CBA7214
- - target: arm64-macos
- value: 00000000-0000-0000-0000-000000000000
- - target: arm64-maccatalyst
- value: 00000000-0000-0000-0000-000000000000
- - target: arm64e-macos
- value: 6BEE17F3-04F2-3B1F-B8EB-C94379ABA9BD
- - target: arm64e-maccatalyst
- value: 6BEE17F3-04F2-3B1F-B8EB-C94379ABA9BD
install-name: '/usr/lib/system/libsystem_m.dylib'
-current-version: 3226.0.1
+current-version: 3226.100.4
parent-umbrella:
- targets: [ x86_64-macos, x86_64-maccatalyst, x86_64h-macos, x86_64h-maccatalyst,
arm64-macos, arm64-maccatalyst, arm64e-macos, arm64e-maccatalyst ]
@@ -2938,21 +2617,8 @@ exports:
tbd-version: 4
targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst,
arm64e-macos, arm64e-maccatalyst ]
-uuids:
- - target: x86_64-macos
- value: F609F029-BCD0-3A54-B48A-99B3CE8378CE
- - target: x86_64-maccatalyst
- value: F609F029-BCD0-3A54-B48A-99B3CE8378CE
- - target: arm64-macos
- value: 00000000-0000-0000-0000-000000000000
- - target: arm64-maccatalyst
- value: 00000000-0000-0000-0000-000000000000
- - target: arm64e-macos
- value: 04185997-16D2-30DA-8691-7C82612635A3
- - target: arm64e-maccatalyst
- value: 04185997-16D2-30DA-8691-7C82612635A3
install-name: '/usr/lib/system/libsystem_malloc.dylib'
-current-version: 409.60.6
+current-version: 425.100.7
parent-umbrella:
- targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst,
arm64e-macos, arm64e-maccatalyst ]
@@ -2992,7 +2658,7 @@ exports:
_malloc_zone_print, _malloc_zone_print_ptr_info, _malloc_zone_realloc,
_malloc_zone_register, _malloc_zone_statistics, _malloc_zone_unregister,
_malloc_zone_valloc, _malloc_zones, _mstats, _pgm_diagnose_fault_from_crash_reporter,
- _pgm_disable_for_current_thread, _posix_memalign, _quarantine_diagnose_fault_from_crash_reporter,
+ _posix_memalign, _quarantine_diagnose_fault_from_crash_reporter,
_realloc, '_reallocarray$DARWIN_EXTSN', '_reallocarrayf$DARWIN_EXTSN',
_scalable_zone_info, _scalable_zone_statistics, _set_malloc_singlethreaded,
_stack_logging_enable_logging, _szone_check_counter, _szone_check_modulo,
@@ -3002,19 +2668,6 @@ exports:
tbd-version: 4
targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst,
arm64e-macos, arm64e-maccatalyst ]
-uuids:
- - target: x86_64-macos
- value: 09114B12-EC3D-3943-A1BD-9909EE2F85B6
- - target: x86_64-maccatalyst
- value: 09114B12-EC3D-3943-A1BD-9909EE2F85B6
- - target: arm64-macos
- value: 00000000-0000-0000-0000-000000000000
- - target: arm64-maccatalyst
- value: 00000000-0000-0000-0000-000000000000
- - target: arm64e-macos
- value: 8737AB7F-91FA-3C06-B797-566A62D0751C
- - target: arm64e-maccatalyst
- value: 8737AB7F-91FA-3C06-B797-566A62D0751C
install-name: '/usr/lib/system/libsystem_networkextension.dylib'
parent-umbrella:
- targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst,
@@ -3039,9 +2692,9 @@ exports:
_NEHelperSettingsSetArray, _NEHelperSettingsSetBool, _NEHelperSettingsSetNumber,
_NEHelperVPNConfigurationExists, _NEHelperVPNSetEnabled, _g_ne_read_uuid_cache,
_g_ne_uuid_cache_hit, _ne_copy_cached_bundle_identifier_for_uuid,
- _ne_copy_cached_preferred_bundle_for_bundle_identifier, _ne_copy_cached_uuids_for_bundle_identifier,
- _ne_copy_signature_info_for_pid, _ne_copy_signing_identifier_for_pid,
- _ne_copy_uuid_cache, _ne_force_reset_uuid_cache, _ne_get_configuration_generation,
+ _ne_copy_cached_uuids_for_bundle_identifier, _ne_copy_signature_info_for_pid,
+ _ne_copy_signing_identifier_for_pid, _ne_copy_uuid_cache,
+ _ne_force_reset_uuid_cache, _ne_get_configuration_generation,
_ne_is_sockaddr_valid, _ne_log_large_obj, _ne_log_obj, _ne_print_backtrace,
_ne_privacy_dns_netagent_id, _ne_privacy_proxy_netagent_id,
_ne_session_add_necp_drop_dest_from_dest_list, _ne_session_add_necp_drop_dest_from_path,
@@ -3069,20 +2722,20 @@ exports:
_ne_session_policy_match_get_service, _ne_session_policy_match_get_service_action,
_ne_session_policy_match_get_service_type, _ne_session_policy_match_is_drop,
_ne_session_policy_match_is_flow_divert, _ne_session_policy_match_service_is_registered,
- _ne_session_release, _ne_session_retain, _ne_session_send_barrier,
- _ne_session_service_get_dns_service_id, _ne_session_service_get_dns_service_id_for_interface,
- _ne_session_service_matches_address, _ne_session_service_matches_address_for_interface,
- _ne_session_set_event_handler, _ne_session_set_socket_attributes,
- _ne_session_set_socket_context_attribute, _ne_session_set_socket_tracker_attributes,
- _ne_session_should_disable_nexus, _ne_session_start, _ne_session_start_on_behalf_of,
- _ne_session_start_with_options, _ne_session_status_to_string,
- _ne_session_stop, _ne_session_stop_all_with_plugin_type, _ne_session_stop_reason_to_string,
- _ne_session_type_to_string, _ne_session_use_as_system_vpn,
- _ne_session_vod_evaluate_connection_present, _ne_session_vpn_include_all_networks_configs_present,
- _ne_socket_set_attribution, _ne_socket_set_domains, _ne_socket_set_is_app_initiated,
- _ne_socket_set_website_attribution, _ne_tracker_build_cache,
- _ne_tracker_build_trie, _ne_tracker_check_info_changed, _ne_tracker_clear_cache,
- _ne_tracker_context_get_domain, _ne_tracker_context_get_domain_owner,
+ _ne_session_random_port_fallback, _ne_session_release, _ne_session_retain,
+ _ne_session_send_barrier, _ne_session_service_get_dns_service_id,
+ _ne_session_service_get_dns_service_id_for_interface, _ne_session_service_matches_address,
+ _ne_session_service_matches_address_for_interface, _ne_session_set_event_handler,
+ _ne_session_set_socket_attributes, _ne_session_set_socket_context_attribute,
+ _ne_session_set_socket_tracker_attributes, _ne_session_should_disable_nexus,
+ _ne_session_start, _ne_session_start_on_behalf_of, _ne_session_start_with_options,
+ _ne_session_status_to_string, _ne_session_stop, _ne_session_stop_all_with_plugin_type,
+ _ne_session_stop_reason_to_string, _ne_session_type_to_string,
+ _ne_session_use_as_system_vpn, _ne_session_vod_evaluate_connection_present,
+ _ne_session_vpn_include_all_networks_configs_present, _ne_socket_set_attribution,
+ _ne_socket_set_domains, _ne_socket_set_is_app_initiated, _ne_socket_set_website_attribution,
+ _ne_tracker_build_cache, _ne_tracker_build_trie, _ne_tracker_check_info_changed,
+ _ne_tracker_clear_cache, _ne_tracker_context_get_domain, _ne_tracker_context_get_domain_owner,
_ne_tracker_context_is_from_app_list, _ne_tracker_context_is_from_web_list,
_ne_tracker_get_ddg_dictionary, _ne_tracker_lookup_app_domains,
_ne_tracker_set_test_domains, _ne_tracker_validate_domain,
@@ -3095,21 +2748,8 @@ exports:
tbd-version: 4
targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst,
arm64e-macos, arm64e-maccatalyst ]
-uuids:
- - target: x86_64-macos
- value: 0463374D-9E62-3E58-A668-C9EFF9DB217C
- - target: x86_64-maccatalyst
- value: 0463374D-9E62-3E58-A668-C9EFF9DB217C
- - target: arm64-macos
- value: 00000000-0000-0000-0000-000000000000
- - target: arm64-maccatalyst
- value: 00000000-0000-0000-0000-000000000000
- - target: arm64e-macos
- value: 62FA1CCF-D4BB-3606-BDC9-C2F247A12CE8
- - target: arm64e-maccatalyst
- value: 62FA1CCF-D4BB-3606-BDC9-C2F247A12CE8
install-name: '/usr/lib/system/libsystem_notify.dylib'
-current-version: 306
+current-version: 312
parent-umbrella:
- targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst,
arm64e-macos, arm64e-maccatalyst ]
@@ -3128,21 +2768,8 @@ exports:
tbd-version: 4
targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst,
arm64e-macos, arm64e-maccatalyst ]
-uuids:
- - target: x86_64-macos
- value: F314B62B-98F4-3A7C-8296-8739F8B6855A
- - target: x86_64-maccatalyst
- value: F314B62B-98F4-3A7C-8296-8739F8B6855A
- - target: arm64-macos
- value: ABF0BAEB-706B-3AC1-B6AD-B5CF380B8963
- - target: arm64-maccatalyst
- value: ABF0BAEB-706B-3AC1-B6AD-B5CF380B8963
- - target: arm64e-macos
- value: B215AE90-4ED2-3FCD-8CCC-6C0D93CC4F41
- - target: arm64e-maccatalyst
- value: B215AE90-4ED2-3FCD-8CCC-6C0D93CC4F41
install-name: '/usr/lib/system/libsystem_platform.dylib'
-current-version: 288
+current-version: 292.100.1
parent-umbrella:
- targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst,
arm64e-macos, arm64e-maccatalyst ]
@@ -3204,37 +2831,18 @@ exports:
_os_unfair_lock_unlock, _os_unfair_lock_unlock_no_tsd, _os_unfair_recursive_lock_lock_with_options,
_os_unfair_recursive_lock_owned, _os_unfair_recursive_lock_trylock,
_os_unfair_recursive_lock_tryunlock4objc, _os_unfair_recursive_lock_unlock,
- _os_unfair_recursive_lock_unlock_forked_child, _platform_task_attach,
- _platform_task_copy_next_thread, _platform_task_detach, _platform_task_is_64_bit,
- _platform_task_perform, _platform_task_resume_threads, _platform_task_suspend_threads,
- _platform_task_update_threads, _platform_thread_abort_safely,
- _platform_thread_get_pthread, _platform_thread_get_state,
- _platform_thread_get_unique_id, _platform_thread_info, _platform_thread_perform,
- _platform_thread_release, _platform_thread_resume, _platform_thread_set_state,
- _platform_thread_suspend, _setcontext, _setjmp, _siglongjmp,
- _sigsetjmp, _spin_lock, _spin_lock_try, _spin_unlock, _swapcontext,
- _sys_cache_control, _sys_dcache_flush, _sys_icache_invalidate ]
+ _os_unfair_recursive_lock_unlock_forked_child, _setcontext,
+ _setjmp, _siglongjmp, _sigsetjmp, _spin_lock, _spin_lock_try,
+ _spin_unlock, _swapcontext, _sys_cache_control, _sys_dcache_flush,
+ _sys_icache_invalidate ]
- targets: [ arm64-macos, arm64-maccatalyst, arm64e-macos, arm64e-maccatalyst ]
symbols: [ __ctx_done ]
--- !tapi-tbd
tbd-version: 4
targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst,
arm64e-macos, arm64e-maccatalyst ]
-uuids:
- - target: x86_64-macos
- value: 5920E36F-53EC-33F0-B675-8AE48B58418C
- - target: x86_64-maccatalyst
- value: 5920E36F-53EC-33F0-B675-8AE48B58418C
- - target: arm64-macos
- value: 51C613E3-4ABF-359C-B275-2608BB1BE0B6
- - target: arm64-maccatalyst
- value: 51C613E3-4ABF-359C-B275-2608BB1BE0B6
- - target: arm64e-macos
- value: 132084C6-C347-3489-9AC2-FCAAD21CDB73
- - target: arm64e-maccatalyst
- value: 132084C6-C347-3489-9AC2-FCAAD21CDB73
install-name: '/usr/lib/system/libsystem_pthread.dylib'
-current-version: 514
+current-version: 514.100.2
parent-umbrella:
- targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst,
arm64e-macos, arm64e-maccatalyst ]
@@ -3328,21 +2936,8 @@ exports:
tbd-version: 4
targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst,
arm64e-macos, arm64e-maccatalyst ]
-uuids:
- - target: x86_64-macos
- value: D199B283-8F09-3F2F-A17E-274BFF7733BE
- - target: x86_64-maccatalyst
- value: D199B283-8F09-3F2F-A17E-274BFF7733BE
- - target: arm64-macos
- value: 00000000-0000-0000-0000-000000000000
- - target: arm64-maccatalyst
- value: 00000000-0000-0000-0000-000000000000
- - target: arm64e-macos
- value: 3680811A-78F7-361A-ABBE-8E783165AC81
- - target: arm64e-maccatalyst
- value: 3680811A-78F7-361A-ABBE-8E783165AC81
install-name: '/usr/lib/system/libsystem_sandbox.dylib'
-current-version: 1845.60.12
+current-version: 1846.100.185
parent-umbrella:
- targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst,
arm64e-macos, arm64e-maccatalyst ]
@@ -3370,8 +2965,8 @@ exports:
_rootless_check_trusted_class, _rootless_check_trusted_fd,
_rootless_convert_to_datavault, _rootless_manifest_free, _rootless_manifest_parse,
_rootless_mkdir_datavault, _rootless_mkdir_nounlink, _rootless_mkdir_restricted,
- _rootless_preflight, _rootless_protected_volume, _rootless_register_trusted_storage_class,
- _rootless_remove_datavault_in_favor_of_static_storage_class,
+ _rootless_preflight, _rootless_protected_volume, _rootless_protected_volume_fd,
+ _rootless_register_trusted_storage_class, _rootless_remove_datavault_in_favor_of_static_storage_class,
_rootless_remove_restricted_in_favor_of_static_storage_class,
_rootless_restricted_environment, _rootless_suspend, _rootless_trusted_by_self_token,
_rootless_verify_trusted_by_self_token, _sandbox_builtin_query,
@@ -3415,21 +3010,8 @@ exports:
tbd-version: 4
targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst,
arm64e-macos, arm64e-maccatalyst ]
-uuids:
- - target: x86_64-macos
- value: F24B1FA9-5692-35BA-9A9C-E071B7BFA5D7
- - target: x86_64-maccatalyst
- value: F24B1FA9-5692-35BA-9A9C-E071B7BFA5D7
- - target: arm64-macos
- value: 00000000-0000-0000-0000-000000000000
- - target: arm64-maccatalyst
- value: 00000000-0000-0000-0000-000000000000
- - target: arm64e-macos
- value: 82513DC5-565F-3A4E-9431-4511FB0C22FA
- - target: arm64e-maccatalyst
- value: 82513DC5-565F-3A4E-9431-4511FB0C22FA
install-name: '/usr/lib/system/libsystem_secinit.dylib'
-current-version: 119.40.2
+current-version: 120.100.7
parent-umbrella:
- targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst,
arm64e-macos, arm64e-maccatalyst ]
@@ -3444,19 +3026,6 @@ exports:
tbd-version: 4
targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst,
arm64e-macos, arm64e-maccatalyst ]
-uuids:
- - target: x86_64-macos
- value: A5915FB2-F0C9-3BF0-ADC6-BEB571C73E57
- - target: x86_64-maccatalyst
- value: A5915FB2-F0C9-3BF0-ADC6-BEB571C73E57
- - target: arm64-macos
- value: 00000000-0000-0000-0000-000000000000
- - target: arm64-maccatalyst
- value: 00000000-0000-0000-0000-000000000000
- - target: arm64e-macos
- value: B31CD553-083B-39C6-BCB9-B0413ECAF562
- - target: arm64e-maccatalyst
- value: B31CD553-083B-39C6-BCB9-B0413ECAF562
install-name: '/usr/lib/system/libsystem_symptoms.dylib'
parent-umbrella:
- targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst,
@@ -3474,21 +3043,8 @@ exports:
tbd-version: 4
targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst,
arm64e-macos, arm64e-maccatalyst ]
-uuids:
- - target: x86_64-macos
- value: C5359E6E-7B63-3E51-A664-3E3581E15F52
- - target: x86_64-maccatalyst
- value: C5359E6E-7B63-3E51-A664-3E3581E15F52
- - target: arm64-macos
- value: 00000000-0000-0000-0000-000000000000
- - target: arm64-maccatalyst
- value: 00000000-0000-0000-0000-000000000000
- - target: arm64e-macos
- value: 616F473A-EB21-377D-B3B4-F1581F127F0D
- - target: arm64e-maccatalyst
- value: 616F473A-EB21-377D-B3B4-F1581F127F0D
install-name: '/usr/lib/system/libsystem_trace.dylib'
-current-version: 1406.60.2
+current-version: 1431.100.13
parent-umbrella:
- targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst,
arm64e-macos, arm64e-maccatalyst ]
@@ -3534,15 +3090,17 @@ exports:
_os_log_backtrace_create_from_return_address, _os_log_backtrace_destroy,
_os_log_backtrace_get_frames, _os_log_backtrace_get_length,
_os_log_backtrace_print_to_blob, _os_log_backtrace_serialize_to_blob,
- _os_log_create, _os_log_errors_count, _os_log_fault_default_callback,
- _os_log_faults_count, _os_log_fmt_compose, _os_log_fmt_convert_trace,
- _os_log_fmt_extract_pubdata, _os_log_fmt_get_plugin, _os_log_get_type,
- _os_log_is_debug_enabled, _os_log_is_enabled, _os_log_pack_compose,
- _os_log_pack_send, _os_log_pack_send_and_compose, _os_log_set_client_type,
- _os_log_set_enabled, _os_log_set_fault_callback, _os_log_shim_enabled,
+ _os_log_compare_enablement, _os_log_copy_decorated_message,
+ _os_log_copy_message_string, _os_log_create, _os_log_errors_count,
+ _os_log_fault_default_callback, _os_log_faults_count, _os_log_fmt_compose,
+ _os_log_fmt_convert_trace, _os_log_fmt_extract_pubdata, _os_log_fmt_get_plugin,
+ _os_log_get_type, _os_log_is_debug_enabled, _os_log_is_enabled,
+ _os_log_pack_compose, _os_log_pack_send, _os_log_pack_send_and_compose,
+ _os_log_set_client_type, _os_log_set_enabled, _os_log_set_fault_callback,
+ _os_log_set_hook, _os_log_set_test_callback, _os_log_shim_enabled,
_os_log_shim_legacy_logging_enabled, _os_log_shim_with_CFString,
- _os_log_type_enabled, _os_log_with_args, _os_signpost_enabled,
- _os_signpost_id_generate, _os_signpost_id_make_with_pointer,
+ _os_log_type_enabled, _os_log_type_get_name, _os_log_with_args,
+ _os_signpost_enabled, _os_signpost_id_generate, _os_signpost_id_make_with_pointer,
_os_signpost_set_introspection_hook_4Perf, _os_state_add_handler,
_os_state_remove_handler, _os_trace_debug_enabled, _os_trace_get_mode,
_os_trace_get_type, _os_trace_info_enabled, _os_trace_set_mode ]
@@ -3551,21 +3109,8 @@ exports:
tbd-version: 4
targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst,
arm64e-macos, arm64e-maccatalyst ]
-uuids:
- - target: x86_64-macos
- value: E45FA86E-48EB-3926-A24C-323DB84D3700
- - target: x86_64-maccatalyst
- value: E45FA86E-48EB-3926-A24C-323DB84D3700
- - target: arm64-macos
- value: 00000000-0000-0000-0000-000000000000
- - target: arm64-maccatalyst
- value: 00000000-0000-0000-0000-000000000000
- - target: arm64e-macos
- value: 1228EDDF-7C61-3674-8C42-B537FFE9EDDA
- - target: arm64e-maccatalyst
- value: 1228EDDF-7C61-3674-8C42-B537FFE9EDDA
install-name: '/usr/lib/system/libunwind.dylib'
-current-version: 202.100
+current-version: 1500.26
parent-umbrella:
- targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst,
arm64e-macos, arm64e-maccatalyst ]
@@ -3614,7 +3159,8 @@ exports:
__Unwind_GetLanguageSpecificData, __Unwind_GetRegionStart,
__Unwind_GetTextRelBase, __Unwind_RaiseException, __Unwind_Resume,
__Unwind_Resume_or_Rethrow, __Unwind_SetGR, __Unwind_SetIP,
- ___deregister_frame, ___register_frame, ___unw_add_dynamic_fde,
+ ___deregister_frame, ___register_frame, ___unw_add_dynamic_eh_frame_section,
+ ___unw_add_dynamic_fde, ___unw_remove_dynamic_eh_frame_section,
___unw_remove_dynamic_fde, _unw_get_fpreg, _unw_get_proc_info,
_unw_get_proc_name, _unw_get_reg, _unw_getcontext, _unw_init_local,
_unw_is_fpreg, _unw_is_signal_frame, _unw_iterate_dwarf_unwind_cache,
@@ -3624,21 +3170,8 @@ exports:
tbd-version: 4
targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst,
arm64e-macos, arm64e-maccatalyst ]
-uuids:
- - target: x86_64-macos
- value: 7E56F9FE-DC35-3354-BA23-4103C09E22DD
- - target: x86_64-maccatalyst
- value: 7E56F9FE-DC35-3354-BA23-4103C09E22DD
- - target: arm64-macos
- value: 00000000-0000-0000-0000-000000000000
- - target: arm64-maccatalyst
- value: 00000000-0000-0000-0000-000000000000
- - target: arm64e-macos
- value: 8EF4547D-1AF8-37CF-B15A-29405BF12642
- - target: arm64e-maccatalyst
- value: 8EF4547D-1AF8-37CF-B15A-29405BF12642
install-name: '/usr/lib/system/libxpc.dylib'
-current-version: 2462.60.15
+current-version: 2462.100.95
parent-umbrella:
- targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst,
arm64e-macos, arm64e-maccatalyst ]
@@ -3685,12 +3218,13 @@ exports:
_XPC_COALITION_INFO_KEY_RESOURCE_USAGE_BLOB, __availability_version_check,
__launch_job_routine, __launch_job_routine_async, __launch_msg2,
__launch_server_test_routine, __launch_service_stats_copy_4ppse_impl,
- __libxpc_initializer, __spawn_via_launchd, __system_ios_support_version_copy_string_sysctl,
- __system_version_copy_string_plist, __system_version_copy_string_sysctl,
- __system_version_fallback, __system_version_parse_string,
- __vproc_get_last_exit_status, __vproc_grab_subset, __vproc_kickstart_by_label,
- __vproc_log, __vproc_log_error, __vproc_logv, __vproc_pid_is_managed,
- __vproc_post_fork_ping, __vproc_send_signal_by_label, __vproc_set_global_on_demand,
+ __launch_service_stats_copy_impl, __libxpc_initializer, __spawn_via_launchd,
+ __system_ios_support_version_copy_string_sysctl, __system_version_copy_string_plist,
+ __system_version_copy_string_sysctl, __system_version_fallback,
+ __system_version_parse_string, __vproc_get_last_exit_status,
+ __vproc_grab_subset, __vproc_kickstart_by_label, __vproc_log,
+ __vproc_log_error, __vproc_logv, __vproc_pid_is_managed, __vproc_post_fork_ping,
+ __vproc_send_signal_by_label, __vproc_set_global_on_demand,
__vproc_standby_begin, __vproc_standby_count, __vproc_standby_end,
__vproc_standby_timeout, __vproc_transaction_begin, __vproc_transaction_count,
__vproc_transaction_count_for_pid, __vproc_transaction_end,
@@ -3762,16 +3296,17 @@ exports:
_launch_perfcheck_property_endpoint_name, _launch_perfcheck_property_endpoint_needs_activation,
_launch_perfcheck_property_endpoints, _launch_remove_external_service,
_launch_service_instance_copy_uuids, _launch_service_instance_create,
- _launch_service_instance_remove, _launch_service_stats_disable_4ppse,
- _launch_service_stats_enable_4ppse, _launch_service_stats_is_enabled_4ppse,
- _launch_set_service_enabled, _launch_set_system_service_enabled,
- _launch_socket_service_check_in, _launch_version_for_user_service_4coresim,
- _launch_wait, _launchd_close, _launchd_fdopen, _launchd_getfd,
- _launchd_msg_recv, _launchd_msg_send, _load_launchd_jobs_at_loginwindow_prompt,
- _mpm_uncork_fork, _mpm_wait, _os_system_version_get_current_version,
- _os_system_version_get_ios_support_version, _os_system_version_sim_get_current_host_version,
- _os_transaction_copy_description, _os_transaction_create,
- _os_transaction_get_description, _os_transaction_get_timestamp,
+ _launch_service_instance_remove, _launch_service_stats_disable,
+ _launch_service_stats_disable_4ppse, _launch_service_stats_enable,
+ _launch_service_stats_enable_4ppse, _launch_service_stats_is_enabled,
+ _launch_service_stats_is_enabled_4ppse, _launch_set_service_enabled,
+ _launch_set_system_service_enabled, _launch_socket_service_check_in,
+ _launch_version_for_user_service_4coresim, _launch_wait, _launchd_close,
+ _launchd_fdopen, _launchd_getfd, _launchd_msg_recv, _launchd_msg_send,
+ _load_launchd_jobs_at_loginwindow_prompt, _mpm_uncork_fork,
+ _mpm_wait, _os_system_version_get_current_version, _os_system_version_get_ios_support_version,
+ _os_system_version_sim_get_current_host_version, _os_transaction_copy_description,
+ _os_transaction_create, _os_transaction_get_description, _os_transaction_get_timestamp,
_os_transaction_needs_more_time, _place_hold_on_real_loginwindow,
_reboot2, _reboot3, _vproc_release, _vproc_retain, _vproc_standby_begin,
_vproc_standby_end, _vproc_swap_complex, _vproc_swap_integer,
diff --git a/src/link/tapi.zig b/src/link/tapi.zig
@@ -36,7 +36,7 @@ pub const TbdV3 = struct {
pub const TbdV4 = struct {
tbd_version: u3,
targets: []const []const u8,
- uuids: []const struct {
+ uuids: ?[]const struct {
target: []const u8,
value: []const u8,
},
diff --git a/src/link/tapi/Tokenizer.zig b/src/link/tapi/Tokenizer.zig
@@ -1,7 +1,7 @@
const Tokenizer = @This();
const std = @import("std");
-const log = std.log.scoped(.tapi);
+const log = std.log.scoped(.yaml);
const testing = std.testing;
buffer: []const u8,
@@ -13,29 +13,31 @@ pub const Token = struct {
end: usize,
pub const Id = enum {
- Eof,
-
- NewLine,
- DocStart, // ---
- DocEnd, // ...
- SeqItemInd, // -
- MapValueInd, // :
- FlowMapStart, // {
- FlowMapEnd, // }
- FlowSeqStart, // [
- FlowSeqEnd, // ]
-
- Comma,
- Space,
- Tab,
- Comment, // #
- Alias, // *
- Anchor, // &
- Tag, // !
- SingleQuote, // '
- DoubleQuote, // "
-
- Literal,
+ // zig fmt: off
+ eof,
+
+ new_line,
+ doc_start, // ---
+ doc_end, // ...
+ seq_item_ind, // -
+ map_value_ind, // :
+ flow_map_start, // {
+ flow_map_end, // }
+ flow_seq_start, // [
+ flow_seq_end, // ]
+
+ comma,
+ space,
+ tab,
+ comment, // #
+ alias, // *
+ anchor, // &
+ tag, // !
+
+ single_quoted, // '...'
+ double_quoted, // "..."
+ literal,
+ // zig fmt: on
};
};
@@ -45,8 +47,8 @@ pub const TokenIterator = struct {
buffer: []const Token,
pos: TokenIndex = 0,
- pub fn next(self: *TokenIterator) Token {
- const token = self.buffer[self.pos];
+ pub fn next(self: *TokenIterator) ?Token {
+ const token = self.peek() orelse return null;
self.pos += 1;
return token;
}
@@ -74,180 +76,212 @@ pub const TokenIterator = struct {
}
};
+fn stringMatchesPattern(comptime pattern: []const u8, slice: []const u8) bool {
+ comptime var count: usize = 0;
+ inline while (count < pattern.len) : (count += 1) {
+ if (count >= slice.len) return false;
+ const c = slice[count];
+ if (pattern[count] != c) return false;
+ }
+ return true;
+}
+
+fn matchesPattern(self: Tokenizer, comptime pattern: []const u8) bool {
+ return stringMatchesPattern(pattern, self.buffer[self.index..]);
+}
+
pub fn next(self: *Tokenizer) Token {
var result = Token{
- .id = .Eof,
+ .id = .eof,
.start = self.index,
.end = undefined,
};
- var state: union(enum) {
- Start,
- NewLine,
- Space,
- Tab,
- Hyphen: usize,
- Dot: usize,
- Literal,
- } = .Start;
+ var state: enum {
+ start,
+ new_line,
+ space,
+ tab,
+ comment,
+ single_quoted,
+ double_quoted,
+ literal,
+ } = .start;
while (self.index < self.buffer.len) : (self.index += 1) {
const c = self.buffer[self.index];
switch (state) {
- .Start => switch (c) {
+ .start => switch (c) {
' ' => {
- state = .Space;
+ state = .space;
},
'\t' => {
- state = .Tab;
+ state = .tab;
},
'\n' => {
- result.id = .NewLine;
+ result.id = .new_line;
self.index += 1;
break;
},
'\r' => {
- state = .NewLine;
+ state = .new_line;
},
- '-' => {
- state = .{ .Hyphen = 1 };
+
+ '-' => if (self.matchesPattern("---")) {
+ result.id = .doc_start;
+ self.index += "---".len;
+ break;
+ } else if (self.matchesPattern("- ")) {
+ result.id = .seq_item_ind;
+ self.index += "- ".len;
+ break;
+ } else {
+ state = .literal;
},
- '.' => {
- state = .{ .Dot = 1 };
+
+ '.' => if (self.matchesPattern("...")) {
+ result.id = .doc_end;
+ self.index += "...".len;
+ break;
+ } else {
+ state = .literal;
},
+
',' => {
- result.id = .Comma;
+ result.id = .comma;
self.index += 1;
break;
},
'#' => {
- result.id = .Comment;
- self.index += 1;
- break;
+ state = .comment;
},
'*' => {
- result.id = .Alias;
+ result.id = .alias;
self.index += 1;
break;
},
'&' => {
- result.id = .Anchor;
+ result.id = .anchor;
self.index += 1;
break;
},
'!' => {
- result.id = .Tag;
- self.index += 1;
- break;
- },
- '\'' => {
- result.id = .SingleQuote;
- self.index += 1;
- break;
- },
- '"' => {
- result.id = .DoubleQuote;
+ result.id = .tag;
self.index += 1;
break;
},
'[' => {
- result.id = .FlowSeqStart;
+ result.id = .flow_seq_start;
self.index += 1;
break;
},
']' => {
- result.id = .FlowSeqEnd;
+ result.id = .flow_seq_end;
self.index += 1;
break;
},
':' => {
- result.id = .MapValueInd;
+ result.id = .map_value_ind;
self.index += 1;
break;
},
'{' => {
- result.id = .FlowMapStart;
+ result.id = .flow_map_start;
self.index += 1;
break;
},
'}' => {
- result.id = .FlowMapEnd;
+ result.id = .flow_map_end;
self.index += 1;
break;
},
+ '\'' => {
+ state = .single_quoted;
+ },
+ '"' => {
+ state = .double_quoted;
+ },
else => {
- state = .Literal;
+ state = .literal;
+ },
+ },
+
+ .comment => switch (c) {
+ '\r', '\n' => {
+ result.id = .comment;
+ break;
},
+ else => {},
},
- .Space => switch (c) {
+
+ .space => switch (c) {
' ' => {},
else => {
- result.id = .Space;
+ result.id = .space;
break;
},
},
- .Tab => switch (c) {
+
+ .tab => switch (c) {
'\t' => {},
else => {
- result.id = .Tab;
+ result.id = .tab;
break;
},
},
- .NewLine => switch (c) {
+
+ .new_line => switch (c) {
'\n' => {
- result.id = .NewLine;
+ result.id = .new_line;
self.index += 1;
break;
},
else => {}, // TODO this should be an error condition
},
- .Hyphen => |*count| switch (c) {
- ' ' => {
- result.id = .SeqItemInd;
+
+ .single_quoted => switch (c) {
+ '\'' => if (!self.matchesPattern("''")) {
+ result.id = .single_quoted;
self.index += 1;
break;
+ } else {
+ self.index += "''".len - 1;
},
- '-' => {
- count.* += 1;
-
- if (count.* == 3) {
- result.id = .DocStart;
- self.index += 1;
- break;
- }
- },
- else => {
- state = .Literal;
- },
+ else => {},
},
- .Dot => |*count| switch (c) {
- '.' => {
- count.* += 1;
- if (count.* == 3) {
- result.id = .DocEnd;
+ .double_quoted => switch (c) {
+ '"' => {
+ if (stringMatchesPattern("\\", self.buffer[self.index - 1 ..])) {
+ self.index += 1;
+ } else {
+ result.id = .double_quoted;
self.index += 1;
break;
}
},
- else => {
- state = .Literal;
- },
+ else => {},
},
- .Literal => switch (c) {
+
+ .literal => switch (c) {
'\r', '\n', ' ', '\'', '"', ',', ':', ']', '}' => {
- result.id = .Literal;
+ result.id = .literal;
break;
},
else => {
- result.id = .Literal;
+ result.id = .literal;
},
},
}
}
- if (state == .Literal and result.id == .Eof) {
- result.id = .Literal;
+ if (self.index >= self.buffer.len) {
+ switch (state) {
+ .literal => {
+ result.id = .literal;
+ },
+ else => {},
+ }
}
result.end = self.index;
@@ -263,22 +297,24 @@ fn testExpected(source: []const u8, expected: []const Token.Id) !void {
.buffer = source,
};
- var token_len: usize = 0;
- for (expected) |exp| {
- token_len += 1;
+ var given = std.ArrayList(Token.Id).init(testing.allocator);
+ defer given.deinit();
+
+ while (true) {
const token = tokenizer.next();
- try testing.expectEqual(exp, token.id);
+ try given.append(token.id);
+ if (token.id == .eof) break;
}
- while (tokenizer.next().id != .Eof) {
- token_len += 1; // consume all tokens
- }
+ try testing.expectEqualSlices(Token.Id, expected, given.items);
+}
- try testing.expectEqual(expected.len, token_len);
+test {
+ std.testing.refAllDecls(@This());
}
test "empty doc" {
- try testExpected("", &[_]Token.Id{.Eof});
+ try testExpected("", &[_]Token.Id{.eof});
}
test "empty doc with explicit markers" {
@@ -286,7 +322,22 @@ test "empty doc with explicit markers" {
\\---
\\...
, &[_]Token.Id{
- .DocStart, .NewLine, .DocEnd, .Eof,
+ .doc_start, .new_line, .doc_end, .eof,
+ });
+}
+
+test "empty doc with explicit markers and a directive" {
+ try testExpected(
+ \\--- !tbd-v1
+ \\...
+ , &[_]Token.Id{
+ .doc_start,
+ .space,
+ .tag,
+ .literal,
+ .new_line,
+ .doc_end,
+ .eof,
});
}
@@ -296,15 +347,15 @@ test "sequence of values" {
\\- 1
\\- 2
, &[_]Token.Id{
- .SeqItemInd,
- .Literal,
- .NewLine,
- .SeqItemInd,
- .Literal,
- .NewLine,
- .SeqItemInd,
- .Literal,
- .Eof,
+ .seq_item_ind,
+ .literal,
+ .new_line,
+ .seq_item_ind,
+ .literal,
+ .new_line,
+ .seq_item_ind,
+ .literal,
+ .eof,
});
}
@@ -313,24 +364,24 @@ test "sequence of sequences" {
\\- [ val1, val2]
\\- [val3, val4 ]
, &[_]Token.Id{
- .SeqItemInd,
- .FlowSeqStart,
- .Space,
- .Literal,
- .Comma,
- .Space,
- .Literal,
- .FlowSeqEnd,
- .NewLine,
- .SeqItemInd,
- .FlowSeqStart,
- .Literal,
- .Comma,
- .Space,
- .Literal,
- .Space,
- .FlowSeqEnd,
- .Eof,
+ .seq_item_ind,
+ .flow_seq_start,
+ .space,
+ .literal,
+ .comma,
+ .space,
+ .literal,
+ .flow_seq_end,
+ .new_line,
+ .seq_item_ind,
+ .flow_seq_start,
+ .literal,
+ .comma,
+ .space,
+ .literal,
+ .space,
+ .flow_seq_end,
+ .eof,
});
}
@@ -339,16 +390,16 @@ test "mappings" {
\\key1: value1
\\key2: value2
, &[_]Token.Id{
- .Literal,
- .MapValueInd,
- .Space,
- .Literal,
- .NewLine,
- .Literal,
- .MapValueInd,
- .Space,
- .Literal,
- .Eof,
+ .literal,
+ .map_value_ind,
+ .space,
+ .literal,
+ .new_line,
+ .literal,
+ .map_value_ind,
+ .space,
+ .literal,
+ .eof,
});
}
@@ -357,21 +408,21 @@ test "inline mapped sequence of values" {
\\key : [ val1,
\\ val2 ]
, &[_]Token.Id{
- .Literal,
- .Space,
- .MapValueInd,
- .Space,
- .FlowSeqStart,
- .Space,
- .Literal,
- .Comma,
- .Space,
- .NewLine,
- .Space,
- .Literal,
- .Space,
- .FlowSeqEnd,
- .Eof,
+ .literal,
+ .space,
+ .map_value_ind,
+ .space,
+ .flow_seq_start,
+ .space,
+ .literal,
+ .comma,
+ .space,
+ .new_line,
+ .space,
+ .literal,
+ .space,
+ .flow_seq_end,
+ .eof,
});
}
@@ -388,52 +439,50 @@ test "part of tbd" {
\\install-name: '/usr/lib/libSystem.B.dylib'
\\...
, &[_]Token.Id{
- .DocStart,
- .Space,
- .Tag,
- .Literal,
- .NewLine,
- .Literal,
- .MapValueInd,
- .Space,
- .Literal,
- .NewLine,
- .Literal,
- .MapValueInd,
- .Space,
- .FlowSeqStart,
- .Space,
- .Literal,
- .Space,
- .FlowSeqEnd,
- .NewLine,
- .NewLine,
- .Literal,
- .MapValueInd,
- .NewLine,
- .Space,
- .SeqItemInd,
- .Literal,
- .MapValueInd,
- .Space,
- .Literal,
- .NewLine,
- .Space,
- .Literal,
- .MapValueInd,
- .Space,
- .Literal,
- .NewLine,
- .NewLine,
- .Literal,
- .MapValueInd,
- .Space,
- .SingleQuote,
- .Literal,
- .SingleQuote,
- .NewLine,
- .DocEnd,
- .Eof,
+ .doc_start,
+ .space,
+ .tag,
+ .literal,
+ .new_line,
+ .literal,
+ .map_value_ind,
+ .space,
+ .literal,
+ .new_line,
+ .literal,
+ .map_value_ind,
+ .space,
+ .flow_seq_start,
+ .space,
+ .literal,
+ .space,
+ .flow_seq_end,
+ .new_line,
+ .new_line,
+ .literal,
+ .map_value_ind,
+ .new_line,
+ .space,
+ .seq_item_ind,
+ .literal,
+ .map_value_ind,
+ .space,
+ .literal,
+ .new_line,
+ .space,
+ .literal,
+ .map_value_ind,
+ .space,
+ .literal,
+ .new_line,
+ .new_line,
+ .literal,
+ .map_value_ind,
+ .space,
+ .single_quoted,
+ .new_line,
+ .doc_end,
+ .eof,
});
}
@@ -443,18 +492,84 @@ test "Unindented list" {
\\- foo: 1
\\c: 1
, &[_]Token.Id{
- .Literal,
- .MapValueInd,
- .NewLine,
- .SeqItemInd,
- .Literal,
- .MapValueInd,
- .Space,
- .Literal,
- .NewLine,
- .Literal,
- .MapValueInd,
- .Space,
- .Literal,
+ .literal,
+ .map_value_ind,
+ .new_line,
+ .seq_item_ind,
+ .literal,
+ .map_value_ind,
+ .space,
+ .literal,
+ .new_line,
+ .literal,
+ .map_value_ind,
+ .space,
+ .literal,
+ .eof,
+ });
+}
+
+test "escape sequences" {
+ try testExpected(
+ \\a: 'here''s an apostrophe'
+ \\b: "a newline\nand a\ttab"
+ \\c: "\"here\" and there"
+ , &[_]Token.Id{
+ .literal,
+ .map_value_ind,
+ .space,
+ .single_quoted,
+ .new_line,
+ .literal,
+ .map_value_ind,
+ .space,
+ .double_quoted,
+ .new_line,
+ .literal,
+ .map_value_ind,
+ .space,
+ .double_quoted,
+ .eof,
+ });
+}
+
+test "comments" {
+ try testExpected(
+ \\key: # some comment about the key
+ \\# first value
+ \\- val1
+ \\# second value
+ \\- val2
+ , &[_]Token.Id{
+ .literal,
+ .map_value_ind,
+ .space,
+ .comment,
+ .new_line,
+ .comment,
+ .new_line,
+ .seq_item_ind,
+ .literal,
+ .new_line,
+ .comment,
+ .new_line,
+ .seq_item_ind,
+ .literal,
+ .eof,
+ });
+}
+
+test "quoted literals" {
+ try testExpected(
+ \\'#000000'
+ \\'[000000'
+ \\"&someString"
+ , &[_]Token.Id{
+ .single_quoted,
+ .new_line,
+ .single_quoted,
+ .new_line,
+ .double_quoted,
+ .eof,
});
}
diff --git a/src/link/tapi/parse.zig b/src/link/tapi/parse.zig
@@ -1,8 +1,7 @@
const std = @import("std");
const assert = std.debug.assert;
-const log = std.log.scoped(.tapi);
+const log = std.log.scoped(.yaml);
const mem = std.mem;
-const testing = std.testing;
const Allocator = mem.Allocator;
const Tokenizer = @import("Tokenizer.zig");
@@ -11,9 +10,9 @@ const TokenIndex = Tokenizer.TokenIndex;
const TokenIterator = Tokenizer.TokenIterator;
pub const ParseError = error{
+ InvalidEscapeSequence,
MalformedYaml,
NestedDocuments,
- UnexpectedTag,
UnexpectedEof,
UnexpectedToken,
Unhandled,
@@ -22,6 +21,8 @@ pub const ParseError = error{
pub const Node = struct {
tag: Tag,
tree: *const Tree,
+ start: TokenIndex,
+ end: TokenIndex,
pub const Tag = enum {
doc,
@@ -61,9 +62,12 @@ pub const Node = struct {
}
pub const Doc = struct {
- base: Node = Node{ .tag = Tag.doc, .tree = undefined },
- start: ?TokenIndex = null,
- end: ?TokenIndex = null,
+ base: Node = Node{
+ .tag = Tag.doc,
+ .tree = undefined,
+ .start = undefined,
+ .end = undefined,
+ },
directive: ?TokenIndex = null,
value: ?*Node = null,
@@ -86,10 +90,8 @@ pub const Node = struct {
_ = fmt;
if (self.directive) |id| {
try std.fmt.format(writer, "{{ ", .{});
- const directive = self.base.tree.tokens[id];
- try std.fmt.format(writer, ".directive = {s}, ", .{
- self.base.tree.source[directive.start..directive.end],
- });
+ const directive = self.base.tree.getRaw(id, id);
+ try std.fmt.format(writer, ".directive = {s}, ", .{directive});
}
if (self.value) |node| {
try std.fmt.format(writer, "{}", .{node});
@@ -101,22 +103,27 @@ pub const Node = struct {
};
pub const Map = struct {
- base: Node = Node{ .tag = Tag.map, .tree = undefined },
- start: ?TokenIndex = null,
- end: ?TokenIndex = null,
+ base: Node = Node{
+ .tag = Tag.map,
+ .tree = undefined,
+ .start = undefined,
+ .end = undefined,
+ },
values: std.ArrayListUnmanaged(Entry) = .{},
pub const base_tag: Node.Tag = .map;
pub const Entry = struct {
key: TokenIndex,
- value: *Node,
+ value: ?*Node,
};
pub fn deinit(self: *Map, allocator: Allocator) void {
for (self.values.items) |entry| {
- entry.value.deinit(allocator);
- allocator.destroy(entry.value);
+ if (entry.value) |value| {
+ value.deinit(allocator);
+ allocator.destroy(value);
+ }
}
self.values.deinit(allocator);
}
@@ -131,20 +138,24 @@ pub const Node = struct {
_ = fmt;
try std.fmt.format(writer, "{{ ", .{});
for (self.values.items) |entry| {
- const key = self.base.tree.tokens[entry.key];
- try std.fmt.format(writer, "{s} => {}, ", .{
- self.base.tree.source[key.start..key.end],
- entry.value,
- });
+ const key = self.base.tree.getRaw(entry.key, entry.key);
+ if (entry.value) |value| {
+ try std.fmt.format(writer, "{s} => {}, ", .{ key, value });
+ } else {
+ try std.fmt.format(writer, "{s} => null, ", .{key});
+ }
}
return std.fmt.format(writer, " }}", .{});
}
};
pub const List = struct {
- base: Node = Node{ .tag = Tag.list, .tree = undefined },
- start: ?TokenIndex = null,
- end: ?TokenIndex = null,
+ base: Node = Node{
+ .tag = Tag.list,
+ .tree = undefined,
+ .start = undefined,
+ .end = undefined,
+ },
values: std.ArrayListUnmanaged(*Node) = .{},
pub const base_tag: Node.Tag = .list;
@@ -174,15 +185,18 @@ pub const Node = struct {
};
pub const Value = struct {
- base: Node = Node{ .tag = Tag.value, .tree = undefined },
- start: ?TokenIndex = null,
- end: ?TokenIndex = null,
+ base: Node = Node{
+ .tag = Tag.value,
+ .tree = undefined,
+ .start = undefined,
+ .end = undefined,
+ },
+ string_value: std.ArrayListUnmanaged(u8) = .{},
pub const base_tag: Node.Tag = .value;
pub fn deinit(self: *Value, allocator: Allocator) void {
- _ = self;
- _ = allocator;
+ self.string_value.deinit(allocator);
}
pub fn format(
@@ -193,11 +207,8 @@ pub const Node = struct {
) !void {
_ = options;
_ = fmt;
- const start = self.base.tree.tokens[self.start.?];
- const end = self.base.tree.tokens[self.end.?];
- return std.fmt.format(writer, "{s}", .{
- self.base.tree.source[start.start..end.end],
- });
+ const raw = self.base.tree.getRaw(self.base.start, self.base.end);
+ return std.fmt.format(writer, "{s}", .{raw});
}
};
};
@@ -233,6 +244,21 @@ pub const Tree = struct {
self.docs.deinit(self.allocator);
}
+ pub fn getDirective(self: Tree, doc_index: usize) ?[]const u8 {
+ assert(doc_index < self.docs.items.len);
+ const doc = self.docs.items[doc_index].cast(Node.Doc) orelse return null;
+ const id = doc.directive orelse return null;
+ return self.getRaw(id, id);
+ }
+
+ pub fn getRaw(self: Tree, start: TokenIndex, end: TokenIndex) []const u8 {
+ assert(start <= end);
+ assert(start < self.tokens.len and end < self.tokens.len);
+ const start_token = self.tokens[start];
+ const end_token = self.tokens[end];
+ return self.source[start_token.start..end_token.end];
+ }
+
pub fn parse(self: *Tree, source: []const u8) !void {
var tokenizer = Tokenizer{ .buffer = source };
var tokens = std.ArrayList(Token).init(self.allocator);
@@ -252,8 +278,8 @@ pub const Tree = struct {
});
switch (token.id) {
- .Eof => break,
- .NewLine => {
+ .eof => break,
+ .new_line => {
line += 1;
prev_line_last_col = token.end;
},
@@ -272,20 +298,20 @@ pub const Tree = struct {
.line_cols = &self.line_cols,
};
- while (true) {
- if (parser.token_it.peek() == null) return;
+ parser.eatCommentsAndSpace(&.{});
- const pos = parser.token_it.pos;
- const token = parser.token_it.next();
+ while (true) {
+ parser.eatCommentsAndSpace(&.{});
+ const token = parser.token_it.next() orelse break;
- log.debug("Next token: {}, {}", .{ pos, token });
+ log.debug("(main) next {s}@{d}", .{ @tagName(token.id), parser.token_it.pos - 1 });
switch (token.id) {
- .Space, .Comment, .NewLine => {},
- .Eof => break,
+ .eof => break,
else => {
- const doc = try parser.doc(pos);
- try self.docs.append(self.allocator, &doc.base);
+ parser.token_it.seekBy(-1);
+ const doc = try parser.doc();
+ try self.docs.append(self.allocator, doc);
},
}
}
@@ -298,355 +324,308 @@ const Parser = struct {
token_it: *TokenIterator,
line_cols: *const std.AutoHashMap(TokenIndex, LineCol),
- fn doc(self: *Parser, start: TokenIndex) ParseError!*Node.Doc {
+ fn value(self: *Parser) ParseError!?*Node {
+ self.eatCommentsAndSpace(&.{});
+
+ const pos = self.token_it.pos;
+ const token = self.token_it.next() orelse return error.UnexpectedEof;
+
+ log.debug(" next {s}@{d}", .{ @tagName(token.id), pos });
+
+ switch (token.id) {
+ .literal => if (self.eatToken(.map_value_ind, &.{ .new_line, .comment })) |_| {
+ // map
+ self.token_it.seekTo(pos);
+ return self.map();
+ } else {
+ // leaf value
+ self.token_it.seekTo(pos);
+ return self.leaf_value();
+ },
+ .single_quoted, .double_quoted => {
+ // leaf value
+ self.token_it.seekBy(-1);
+ return self.leaf_value();
+ },
+ .seq_item_ind => {
+ // list
+ self.token_it.seekBy(-1);
+ return self.list();
+ },
+ .flow_seq_start => {
+ // list
+ self.token_it.seekBy(-1);
+ return self.list_bracketed();
+ },
+ else => return null,
+ }
+ }
+
+ fn doc(self: *Parser) ParseError!*Node {
const node = try self.allocator.create(Node.Doc);
errdefer self.allocator.destroy(node);
- node.* = .{ .start = start };
+ node.* = .{};
node.base.tree = self.tree;
+ node.base.start = self.token_it.pos;
- self.token_it.seekTo(start);
-
- log.debug("Doc start: {}, {}", .{ start, self.tree.tokens[start] });
+ log.debug("(doc) begin {s}@{d}", .{ @tagName(self.tree.tokens[node.base.start].id), node.base.start });
- const explicit_doc: bool = if (self.eatToken(.DocStart)) |_| explicit_doc: {
- if (self.eatToken(.Tag)) |_| {
- node.directive = try self.expectToken(.Literal);
+ // Parse header
+ const explicit_doc: bool = if (self.eatToken(.doc_start, &.{})) |doc_pos| explicit_doc: {
+ if (self.getCol(doc_pos) > 0) return error.MalformedYaml;
+ if (self.eatToken(.tag, &.{ .new_line, .comment })) |_| {
+ node.directive = try self.expectToken(.literal, &.{ .new_line, .comment });
}
- _ = try self.expectToken(.NewLine);
break :explicit_doc true;
} else false;
- while (true) {
- const pos = self.token_it.pos;
- const token = self.token_it.next();
-
- log.debug("Next token: {}, {}", .{ pos, token });
+ // Parse value
+ node.value = try self.value();
+ if (node.value == null) {
+ self.token_it.seekBy(-1);
+ }
+ errdefer if (node.value) |val| {
+ val.deinit(self.allocator);
+ self.allocator.destroy(val);
+ };
- switch (token.id) {
- .Tag => {
- return error.UnexpectedTag;
- },
- .Literal, .SingleQuote, .DoubleQuote => {
- _ = try self.expectToken(.MapValueInd);
- const map_node = try self.map(pos);
- node.value = &map_node.base;
- },
- .SeqItemInd => {
- const list_node = try self.list(pos);
- node.value = &list_node.base;
- },
- .FlowSeqStart => {
- const list_node = try self.list_bracketed(pos);
- node.value = &list_node.base;
- },
- .DocEnd => {
- if (explicit_doc) break;
- return error.UnexpectedToken;
- },
- .DocStart, .Eof => {
- self.token_it.seekBy(-1);
- break;
- },
- else => {
- return error.UnexpectedToken;
- },
+ // Parse footer
+ footer: {
+ if (self.eatToken(.doc_end, &.{})) |pos| {
+ if (!explicit_doc) return error.UnexpectedToken;
+ if (self.getCol(pos) > 0) return error.MalformedYaml;
+ node.base.end = pos;
+ break :footer;
+ }
+ if (self.eatToken(.doc_start, &.{})) |pos| {
+ if (!explicit_doc) return error.UnexpectedToken;
+ if (self.getCol(pos) > 0) return error.MalformedYaml;
+ self.token_it.seekBy(-1);
+ node.base.end = pos - 1;
+ break :footer;
+ }
+ if (self.eatToken(.eof, &.{})) |pos| {
+ node.base.end = pos - 1;
+ break :footer;
}
+ return error.UnexpectedToken;
}
- node.end = self.token_it.pos - 1;
+ log.debug("(doc) end {s}@{d}", .{ @tagName(self.tree.tokens[node.base.end].id), node.base.end });
- log.debug("Doc end: {}, {}", .{ node.end.?, self.tree.tokens[node.end.?] });
-
- return node;
+ return &node.base;
}
- fn map(self: *Parser, start: TokenIndex) ParseError!*Node.Map {
+ fn map(self: *Parser) ParseError!*Node {
const node = try self.allocator.create(Node.Map);
errdefer self.allocator.destroy(node);
- node.* = .{ .start = start };
+ node.* = .{};
node.base.tree = self.tree;
+ node.base.start = self.token_it.pos;
+ errdefer {
+ for (node.values.items) |entry| {
+ if (entry.value) |val| {
+ val.deinit(self.allocator);
+ self.allocator.destroy(val);
+ }
+ }
+ node.values.deinit(self.allocator);
+ }
- self.token_it.seekTo(start);
-
- log.debug("Map start: {}, {}", .{ start, self.tree.tokens[start] });
+ log.debug("(map) begin {s}@{d}", .{ @tagName(self.tree.tokens[node.base.start].id), node.base.start });
- const col = self.getCol(start);
+ const col = self.getCol(node.base.start);
while (true) {
- self.eatCommentsAndSpace();
+ self.eatCommentsAndSpace(&.{});
- // Parse key.
+ // Parse key
const key_pos = self.token_it.pos;
- if (self.getCol(key_pos) != col) {
+ if (self.getCol(key_pos) < col) {
break;
}
- const key = self.token_it.next();
+ const key = self.token_it.next() orelse return error.UnexpectedEof;
switch (key.id) {
- .Literal => {},
- else => {
+ .literal => {},
+ .doc_start, .doc_end, .eof => {
self.token_it.seekBy(-1);
break;
},
+ else => {
+ // TODO key not being a literal
+ return error.Unhandled;
+ },
}
- log.debug("Map key: {}, '{s}'", .{ key, self.tree.source[key.start..key.end] });
+ log.debug("(map) key {s}@{d}", .{ self.tree.getRaw(key_pos, key_pos), key_pos });
// Separator
- _ = try self.expectToken(.MapValueInd);
-
- // Parse value.
- const value: *Node = value: {
- if (self.eatToken(.NewLine)) |_| {
- self.eatCommentsAndSpace();
-
- // Explicit, complex value such as list or map.
- const value_pos = self.token_it.pos;
- const value = self.token_it.next();
- switch (value.id) {
- .Literal, .SingleQuote, .DoubleQuote => {
- // Assume nested map.
- const map_node = try self.map(value_pos);
- break :value &map_node.base;
- },
- .SeqItemInd => {
- // Assume list of values.
- const list_node = try self.list(value_pos);
- break :value &list_node.base;
- },
- else => {
- log.err("{}", .{key});
- return error.Unhandled;
- },
- }
- } else {
- self.eatCommentsAndSpace();
-
- const value_pos = self.token_it.pos;
- const value = self.token_it.next();
- switch (value.id) {
- .Literal, .SingleQuote, .DoubleQuote => {
- // Assume leaf value.
- const leaf_node = try self.leaf_value(value_pos);
- break :value &leaf_node.base;
- },
- .FlowSeqStart => {
- const list_node = try self.list_bracketed(value_pos);
- break :value &list_node.base;
- },
- else => {
- log.err("{}", .{key});
- return error.Unhandled;
- },
+ _ = try self.expectToken(.map_value_ind, &.{ .new_line, .comment });
+
+ // Parse value
+ const val = try self.value();
+ errdefer if (val) |v| {
+ v.deinit(self.allocator);
+ self.allocator.destroy(v);
+ };
+
+ if (val) |v| {
+ if (self.getCol(v.start) < self.getCol(key_pos)) {
+ return error.MalformedYaml;
+ }
+ if (v.cast(Node.Value)) |_| {
+ if (self.getCol(v.start) == self.getCol(key_pos)) {
+ return error.MalformedYaml;
}
}
- };
- log.debug("Map value: {}", .{value});
+ }
try node.values.append(self.allocator, .{
.key = key_pos,
- .value = value,
+ .value = val,
});
-
- _ = self.eatToken(.NewLine);
}
- node.end = self.token_it.pos - 1;
+ node.base.end = self.token_it.pos - 1;
- log.debug("Map end: {}, {}", .{ node.end.?, self.tree.tokens[node.end.?] });
+ log.debug("(map) end {s}@{d}", .{ @tagName(self.tree.tokens[node.base.end].id), node.base.end });
- return node;
+ return &node.base;
}
- fn list(self: *Parser, start: TokenIndex) ParseError!*Node.List {
+ fn list(self: *Parser) ParseError!*Node {
const node = try self.allocator.create(Node.List);
errdefer self.allocator.destroy(node);
- node.* = .{
- .start = start,
- };
+ node.* = .{};
node.base.tree = self.tree;
+ node.base.start = self.token_it.pos;
+ errdefer {
+ for (node.values.items) |val| {
+ val.deinit(self.allocator);
+ self.allocator.destroy(val);
+ }
+ node.values.deinit(self.allocator);
+ }
- self.token_it.seekTo(start);
-
- log.debug("List start: {}, {}", .{ start, self.tree.tokens[start] });
-
- const col = self.getCol(start);
+ log.debug("(list) begin {s}@{d}", .{ @tagName(self.tree.tokens[node.base.start].id), node.base.start });
while (true) {
- self.eatCommentsAndSpace();
+ self.eatCommentsAndSpace(&.{});
- if (self.getCol(self.token_it.pos) != col) {
- break;
- }
- _ = self.eatToken(.SeqItemInd) orelse {
- break;
- };
+ _ = self.eatToken(.seq_item_ind, &.{}) orelse break;
- const pos = self.token_it.pos;
- const token = self.token_it.next();
- const value: *Node = value: {
- switch (token.id) {
- .Literal, .SingleQuote, .DoubleQuote => {
- if (self.eatToken(.MapValueInd)) |_| {
- // nested map
- const map_node = try self.map(pos);
- break :value &map_node.base;
- } else {
- // standalone (leaf) value
- const leaf_node = try self.leaf_value(pos);
- break :value &leaf_node.base;
- }
- },
- .FlowSeqStart => {
- const list_node = try self.list_bracketed(pos);
- break :value &list_node.base;
- },
- else => {
- log.err("{}", .{token});
- return error.Unhandled;
- },
- }
- };
- try node.values.append(self.allocator, value);
-
- _ = self.eatToken(.NewLine);
+ const val = (try self.value()) orelse return error.MalformedYaml;
+ try node.values.append(self.allocator, val);
}
- node.end = self.token_it.pos - 1;
+ node.base.end = self.token_it.pos - 1;
- log.debug("List end: {}, {}", .{ node.end.?, self.tree.tokens[node.end.?] });
+ log.debug("(list) end {s}@{d}", .{ @tagName(self.tree.tokens[node.base.end].id), node.base.end });
- return node;
+ return &node.base;
}
- fn list_bracketed(self: *Parser, start: TokenIndex) ParseError!*Node.List {
+ fn list_bracketed(self: *Parser) ParseError!*Node {
const node = try self.allocator.create(Node.List);
errdefer self.allocator.destroy(node);
- node.* = .{ .start = start };
+ node.* = .{};
node.base.tree = self.tree;
+ node.base.start = self.token_it.pos;
+ errdefer {
+ for (node.values.items) |val| {
+ val.deinit(self.allocator);
+ self.allocator.destroy(val);
+ }
+ node.values.deinit(self.allocator);
+ }
- self.token_it.seekTo(start);
-
- log.debug("List start: {}, {}", .{ start, self.tree.tokens[start] });
+ log.debug("(list) begin {s}@{d}", .{ @tagName(self.tree.tokens[node.base.start].id), node.base.start });
- _ = try self.expectToken(.FlowSeqStart);
+ _ = try self.expectToken(.flow_seq_start, &.{});
while (true) {
- _ = self.eatToken(.NewLine);
- self.eatCommentsAndSpace();
+ self.eatCommentsAndSpace(&.{.comment});
- const pos = self.token_it.pos;
- const token = self.token_it.next();
-
- log.debug("Next token: {}, {}", .{ pos, token });
+ if (self.eatToken(.flow_seq_end, &.{.comment})) |pos| {
+ node.base.end = pos;
+ break;
+ }
+ _ = self.eatToken(.comma, &.{.comment});
- const value: *Node = value: {
- switch (token.id) {
- .FlowSeqStart => {
- const list_node = try self.list_bracketed(pos);
- break :value &list_node.base;
- },
- .FlowSeqEnd => {
- break;
- },
- .Literal, .SingleQuote, .DoubleQuote => {
- const leaf_node = try self.leaf_value(pos);
- _ = self.eatToken(.Comma);
- // TODO newline
- break :value &leaf_node.base;
- },
- else => {
- log.err("{}", .{token});
- return error.Unhandled;
- },
- }
- };
- try node.values.append(self.allocator, value);
+ const val = (try self.value()) orelse return error.MalformedYaml;
+ try node.values.append(self.allocator, val);
}
- node.end = self.token_it.pos - 1;
-
- log.debug("List end: {}, {}", .{ node.end.?, self.tree.tokens[node.end.?] });
+ log.debug("(list) end {s}@{d}", .{ @tagName(self.tree.tokens[node.base.end].id), node.base.end });
- return node;
+ return &node.base;
}
- fn leaf_value(self: *Parser, start: TokenIndex) ParseError!*Node.Value {
+ fn leaf_value(self: *Parser) ParseError!*Node {
const node = try self.allocator.create(Node.Value);
errdefer self.allocator.destroy(node);
- node.* = .{ .start = start };
+ node.* = .{ .string_value = .{} };
node.base.tree = self.tree;
-
- self.token_it.seekTo(start);
-
- log.debug("Leaf start: {}, {}", .{ node.start.?, self.tree.tokens[node.start.?] });
-
- parse: {
- if (self.eatToken(.SingleQuote)) |_| {
- node.start = node.start.? + 1;
- while (true) {
- const tok = self.token_it.next();
- switch (tok.id) {
- .SingleQuote => {
- node.end = self.token_it.pos - 2;
- break :parse;
- },
- .NewLine => return error.UnexpectedToken,
- else => {},
- }
- }
- }
-
- if (self.eatToken(.DoubleQuote)) |_| {
- node.start = node.start.? + 1;
- while (true) {
- const tok = self.token_it.next();
- switch (tok.id) {
- .DoubleQuote => {
- node.end = self.token_it.pos - 2;
- break :parse;
- },
- .NewLine => return error.UnexpectedToken,
- else => {},
- }
- }
- }
-
- // TODO handle multiline strings in new block scope
- while (true) {
- const tok = self.token_it.next();
- switch (tok.id) {
- .Literal => {},
- .Space => {
- const trailing = self.token_it.pos - 2;
- self.eatCommentsAndSpace();
- if (self.token_it.peek()) |peek| {
- if (peek.id != .Literal) {
- node.end = trailing;
- break;
- }
+ node.base.start = self.token_it.pos;
+ errdefer node.string_value.deinit(self.allocator);
+
+ // TODO handle multiline strings in new block scope
+ while (self.token_it.next()) |tok| {
+ switch (tok.id) {
+ .single_quoted => {
+ node.base.end = self.token_it.pos - 1;
+ const raw = self.tree.getRaw(node.base.start, node.base.end);
+ try self.parseSingleQuoted(node, raw);
+ break;
+ },
+ .double_quoted => {
+ node.base.end = self.token_it.pos - 1;
+ const raw = self.tree.getRaw(node.base.start, node.base.end);
+ try self.parseDoubleQuoted(node, raw);
+ break;
+ },
+ .literal => {},
+ .space => {
+ const trailing = self.token_it.pos - 2;
+ self.eatCommentsAndSpace(&.{});
+ if (self.token_it.peek()) |peek| {
+ if (peek.id != .literal) {
+ node.base.end = trailing;
+ const raw = self.tree.getRaw(node.base.start, node.base.end);
+ try node.string_value.appendSlice(self.allocator, raw);
+ break;
}
- },
- else => {
- self.token_it.seekBy(-1);
- node.end = self.token_it.pos - 1;
- break;
- },
- }
+ }
+ },
+ else => {
+ self.token_it.seekBy(-1);
+ node.base.end = self.token_it.pos - 1;
+ const raw = self.tree.getRaw(node.base.start, node.base.end);
+ try node.string_value.appendSlice(self.allocator, raw);
+ break;
+ },
}
}
- log.debug("Leaf end: {}, {}", .{ node.end.?, self.tree.tokens[node.end.?] });
+ log.debug("(leaf) {s}", .{self.tree.getRaw(node.base.start, node.base.end)});
- return node;
+ return &node.base;
}
- fn eatCommentsAndSpace(self: *Parser) void {
- while (true) {
- _ = self.token_it.peek() orelse return;
- const token = self.token_it.next();
+ fn eatCommentsAndSpace(self: *Parser, comptime exclusions: []const Token.Id) void {
+ log.debug("eatCommentsAndSpace", .{});
+ outer: while (self.token_it.next()) |token| {
+ log.debug(" (token '{s}')", .{@tagName(token.id)});
switch (token.id) {
- .Comment, .Space => {},
+ .comment, .space, .new_line => |space| {
+ inline for (exclusions) |excl| {
+ if (excl == space) {
+ self.token_it.seekBy(-1);
+ break :outer;
+ }
+ } else continue;
+ },
else => {
self.token_it.seekBy(-1);
break;
@@ -655,25 +634,24 @@ const Parser = struct {
}
}
- fn eatToken(self: *Parser, id: Token.Id) ?TokenIndex {
- while (true) {
- const pos = self.token_it.pos;
- _ = self.token_it.peek() orelse return null;
- const token = self.token_it.next();
- switch (token.id) {
- .Comment, .Space => continue,
- else => |next_id| if (next_id == id) {
- return pos;
- } else {
- self.token_it.seekTo(pos);
- return null;
- },
- }
+ fn eatToken(self: *Parser, id: Token.Id, comptime exclusions: []const Token.Id) ?TokenIndex {
+ log.debug("eatToken('{s}')", .{@tagName(id)});
+ self.eatCommentsAndSpace(exclusions);
+ const pos = self.token_it.pos;
+ const token = self.token_it.next() orelse return null;
+ if (token.id == id) {
+ log.debug(" (found at {d})", .{pos});
+ return pos;
+ } else {
+ log.debug(" (not found)", .{});
+ self.token_it.seekBy(-1);
+ return null;
}
}
- fn expectToken(self: *Parser, id: Token.Id) ParseError!TokenIndex {
- return self.eatToken(id) orelse error.UnexpectedToken;
+ fn expectToken(self: *Parser, id: Token.Id, comptime exclusions: []const Token.Id) ParseError!TokenIndex {
+ log.debug("expectToken('{s}')", .{@tagName(id)});
+ return self.eatToken(id, exclusions) orelse error.UnexpectedToken;
}
fn getLine(self: *Parser, index: TokenIndex) usize {
@@ -683,8 +661,85 @@ const Parser = struct {
fn getCol(self: *Parser, index: TokenIndex) usize {
return self.line_cols.get(index).?.col;
}
+
+ fn parseSingleQuoted(self: *Parser, node: *Node.Value, raw: []const u8) ParseError!void {
+ assert(raw[0] == '\'' and raw[raw.len - 1] == '\'');
+
+ const raw_no_quotes = raw[1 .. raw.len - 1];
+ try node.string_value.ensureTotalCapacity(self.allocator, raw_no_quotes.len);
+
+ var state: enum {
+ start,
+ escape,
+ } = .start;
+ var index: usize = 0;
+
+ while (index < raw_no_quotes.len) : (index += 1) {
+ const c = raw_no_quotes[index];
+ switch (state) {
+ .start => switch (c) {
+ '\'' => {
+ state = .escape;
+ },
+ else => {
+ node.string_value.appendAssumeCapacity(c);
+ },
+ },
+ .escape => switch (c) {
+ '\'' => {
+ state = .start;
+ node.string_value.appendAssumeCapacity(c);
+ },
+ else => return error.InvalidEscapeSequence,
+ },
+ }
+ }
+ }
+
+ fn parseDoubleQuoted(self: *Parser, node: *Node.Value, raw: []const u8) ParseError!void {
+ assert(raw[0] == '"' and raw[raw.len - 1] == '"');
+
+ const raw_no_quotes = raw[1 .. raw.len - 1];
+ try node.string_value.ensureTotalCapacity(self.allocator, raw_no_quotes.len);
+
+ var state: enum {
+ start,
+ escape,
+ } = .start;
+
+ var index: usize = 0;
+ while (index < raw_no_quotes.len) : (index += 1) {
+ const c = raw_no_quotes[index];
+ switch (state) {
+ .start => switch (c) {
+ '\\' => {
+ state = .escape;
+ },
+ else => {
+ node.string_value.appendAssumeCapacity(c);
+ },
+ },
+ .escape => switch (c) {
+ 'n' => {
+ state = .start;
+ node.string_value.appendAssumeCapacity('\n');
+ },
+ 't' => {
+ state = .start;
+ node.string_value.appendAssumeCapacity('\t');
+ },
+ '"' => {
+ state = .start;
+ node.string_value.appendAssumeCapacity('"');
+ },
+ else => return error.InvalidEscapeSequence,
+ },
+ }
+ }
+ }
};
test {
+ std.testing.refAllDecls(@This());
_ = @import("parse/test.zig");
}
diff --git a/src/link/tapi/parse/test.zig b/src/link/tapi/parse/test.zig
@@ -21,45 +21,45 @@ test "explicit doc" {
try testing.expectEqual(tree.docs.items.len, 1);
const doc = tree.docs.items[0].cast(Node.Doc).?;
- try testing.expectEqual(doc.start.?, 0);
- try testing.expectEqual(doc.end.?, tree.tokens.len - 2);
+ try testing.expectEqual(doc.base.start, 0);
+ try testing.expectEqual(doc.base.end, tree.tokens.len - 2);
const directive = tree.tokens[doc.directive.?];
- try testing.expectEqual(directive.id, .Literal);
- try testing.expect(mem.eql(u8, "tapi-tbd", tree.source[directive.start..directive.end]));
+ try testing.expectEqual(directive.id, .literal);
+ try testing.expectEqualStrings("tapi-tbd", tree.source[directive.start..directive.end]);
try testing.expect(doc.value != null);
try testing.expectEqual(doc.value.?.tag, .map);
const map = doc.value.?.cast(Node.Map).?;
- try testing.expectEqual(map.start.?, 5);
- try testing.expectEqual(map.end.?, 14);
+ try testing.expectEqual(map.base.start, 5);
+ try testing.expectEqual(map.base.end, 14);
try testing.expectEqual(map.values.items.len, 2);
{
const entry = map.values.items[0];
const key = tree.tokens[entry.key];
- try testing.expectEqual(key.id, .Literal);
- try testing.expect(mem.eql(u8, "tbd-version", tree.source[key.start..key.end]));
+ try testing.expectEqual(key.id, .literal);
+ try testing.expectEqualStrings("tbd-version", tree.source[key.start..key.end]);
- const value = entry.value.cast(Node.Value).?;
- const value_tok = tree.tokens[value.start.?];
- try testing.expectEqual(value_tok.id, .Literal);
- try testing.expect(mem.eql(u8, "4", tree.source[value_tok.start..value_tok.end]));
+ const value = entry.value.?.cast(Node.Value).?;
+ const value_tok = tree.tokens[value.base.start];
+ try testing.expectEqual(value_tok.id, .literal);
+ try testing.expectEqualStrings("4", tree.source[value_tok.start..value_tok.end]);
}
{
const entry = map.values.items[1];
const key = tree.tokens[entry.key];
- try testing.expectEqual(key.id, .Literal);
- try testing.expect(mem.eql(u8, "abc-version", tree.source[key.start..key.end]));
+ try testing.expectEqual(key.id, .literal);
+ try testing.expectEqualStrings("abc-version", tree.source[key.start..key.end]);
- const value = entry.value.cast(Node.Value).?;
- const value_tok = tree.tokens[value.start.?];
- try testing.expectEqual(value_tok.id, .Literal);
- try testing.expect(mem.eql(u8, "5", tree.source[value_tok.start..value_tok.end]));
+ const value = entry.value.?.cast(Node.Value).?;
+ const value_tok = tree.tokens[value.base.start];
+ try testing.expectEqual(value_tok.id, .literal);
+ try testing.expectEqualStrings("5", tree.source[value_tok.start..value_tok.end]);
}
}
@@ -77,39 +77,31 @@ test "leaf in quotes" {
try testing.expectEqual(tree.docs.items.len, 1);
const doc = tree.docs.items[0].cast(Node.Doc).?;
- try testing.expectEqual(doc.start.?, 0);
- try testing.expectEqual(doc.end.?, tree.tokens.len - 2);
+ try testing.expectEqual(doc.base.start, 0);
+ try testing.expectEqual(doc.base.end, tree.tokens.len - 2);
try testing.expect(doc.directive == null);
try testing.expect(doc.value != null);
try testing.expectEqual(doc.value.?.tag, .map);
const map = doc.value.?.cast(Node.Map).?;
- try testing.expectEqual(map.start.?, 0);
- try testing.expectEqual(map.end.?, tree.tokens.len - 2);
+ try testing.expectEqual(map.base.start, 0);
+ try testing.expectEqual(map.base.end, tree.tokens.len - 2);
try testing.expectEqual(map.values.items.len, 3);
{
const entry = map.values.items[0];
const key = tree.tokens[entry.key];
- try testing.expectEqual(key.id, .Literal);
- try testing.expect(mem.eql(
- u8,
- "key1",
- tree.source[key.start..key.end],
- ));
-
- const value = entry.value.cast(Node.Value).?;
- const start = tree.tokens[value.start.?];
- const end = tree.tokens[value.end.?];
- try testing.expectEqual(start.id, .Literal);
- try testing.expectEqual(end.id, .Literal);
- try testing.expect(mem.eql(
- u8,
- "no quotes",
- tree.source[start.start..end.end],
- ));
+ try testing.expectEqual(key.id, .literal);
+ try testing.expectEqualStrings("key1", tree.source[key.start..key.end]);
+
+ const value = entry.value.?.cast(Node.Value).?;
+ const start = tree.tokens[value.base.start];
+ const end = tree.tokens[value.base.end];
+ try testing.expectEqual(start.id, .literal);
+ try testing.expectEqual(end.id, .literal);
+ try testing.expectEqualStrings("no quotes", tree.source[start.start..end.end]);
}
}
@@ -128,70 +120,60 @@ test "nested maps" {
try testing.expectEqual(tree.docs.items.len, 1);
const doc = tree.docs.items[0].cast(Node.Doc).?;
- try testing.expectEqual(doc.start.?, 0);
- try testing.expectEqual(doc.end.?, tree.tokens.len - 2);
+ try testing.expectEqual(doc.base.start, 0);
+ try testing.expectEqual(doc.base.end, tree.tokens.len - 2);
try testing.expect(doc.directive == null);
try testing.expect(doc.value != null);
try testing.expectEqual(doc.value.?.tag, .map);
const map = doc.value.?.cast(Node.Map).?;
- try testing.expectEqual(map.start.?, 0);
- try testing.expectEqual(map.end.?, tree.tokens.len - 2);
+ try testing.expectEqual(map.base.start, 0);
+ try testing.expectEqual(map.base.end, tree.tokens.len - 2);
try testing.expectEqual(map.values.items.len, 2);
{
const entry = map.values.items[0];
const key = tree.tokens[entry.key];
- try testing.expectEqual(key.id, .Literal);
- try testing.expect(mem.eql(u8, "key1", tree.source[key.start..key.end]));
+ try testing.expectEqual(key.id, .literal);
+ try testing.expectEqualStrings("key1", tree.source[key.start..key.end]);
- const nested_map = entry.value.cast(Node.Map).?;
- try testing.expectEqual(nested_map.start.?, 4);
- try testing.expectEqual(nested_map.end.?, 16);
+ const nested_map = entry.value.?.cast(Node.Map).?;
+ try testing.expectEqual(nested_map.base.start, 4);
+ try testing.expectEqual(nested_map.base.end, 16);
try testing.expectEqual(nested_map.values.items.len, 2);
{
const nested_entry = nested_map.values.items[0];
const nested_key = tree.tokens[nested_entry.key];
- try testing.expectEqual(nested_key.id, .Literal);
- try testing.expect(mem.eql(
- u8,
- "key1_1",
- tree.source[nested_key.start..nested_key.end],
- ));
-
- const nested_value = nested_entry.value.cast(Node.Value).?;
- const nested_value_tok = tree.tokens[nested_value.start.?];
- try testing.expectEqual(nested_value_tok.id, .Literal);
- try testing.expect(mem.eql(
- u8,
+ try testing.expectEqual(nested_key.id, .literal);
+ try testing.expectEqualStrings("key1_1", tree.source[nested_key.start..nested_key.end]);
+
+ const nested_value = nested_entry.value.?.cast(Node.Value).?;
+ const nested_value_tok = tree.tokens[nested_value.base.start];
+ try testing.expectEqual(nested_value_tok.id, .literal);
+ try testing.expectEqualStrings(
"value1_1",
tree.source[nested_value_tok.start..nested_value_tok.end],
- ));
+ );
}
{
const nested_entry = nested_map.values.items[1];
const nested_key = tree.tokens[nested_entry.key];
- try testing.expectEqual(nested_key.id, .Literal);
- try testing.expect(mem.eql(
- u8,
- "key1_2",
- tree.source[nested_key.start..nested_key.end],
- ));
-
- const nested_value = nested_entry.value.cast(Node.Value).?;
- const nested_value_tok = tree.tokens[nested_value.start.?];
- try testing.expectEqual(nested_value_tok.id, .Literal);
- try testing.expect(mem.eql(
- u8,
+ try testing.expectEqual(nested_key.id, .literal);
+ try testing.expectEqualStrings("key1_2", tree.source[nested_key.start..nested_key.end]);
+
+ const nested_value = nested_entry.value.?.cast(Node.Value).?;
+ const nested_value_tok = tree.tokens[nested_value.base.start];
+ try testing.expectEqual(nested_value_tok.id, .literal);
+ try testing.expectEqualStrings(
"value1_2",
tree.source[nested_value_tok.start..nested_value_tok.end],
- ));
+ );
}
}
@@ -199,17 +181,13 @@ test "nested maps" {
const entry = map.values.items[1];
const key = tree.tokens[entry.key];
- try testing.expectEqual(key.id, .Literal);
- try testing.expect(mem.eql(u8, "key2", tree.source[key.start..key.end]));
-
- const value = entry.value.cast(Node.Value).?;
- const value_tok = tree.tokens[value.start.?];
- try testing.expectEqual(value_tok.id, .Literal);
- try testing.expect(mem.eql(
- u8,
- "value2",
- tree.source[value_tok.start..value_tok.end],
- ));
+ try testing.expectEqual(key.id, .literal);
+ try testing.expectEqualStrings("key2", tree.source[key.start..key.end]);
+
+ const value = entry.value.?.cast(Node.Value).?;
+ const value_tok = tree.tokens[value.base.start];
+ try testing.expectEqual(value_tok.id, .literal);
+ try testing.expectEqualStrings("value2", tree.source[value_tok.start..value_tok.end]);
}
}
@@ -227,46 +205,46 @@ test "map of list of values" {
try testing.expectEqual(tree.docs.items.len, 1);
const doc = tree.docs.items[0].cast(Node.Doc).?;
- try testing.expectEqual(doc.start.?, 0);
- try testing.expectEqual(doc.end.?, tree.tokens.len - 2);
+ try testing.expectEqual(doc.base.start, 0);
+ try testing.expectEqual(doc.base.end, tree.tokens.len - 2);
try testing.expect(doc.value != null);
try testing.expectEqual(doc.value.?.tag, .map);
const map = doc.value.?.cast(Node.Map).?;
- try testing.expectEqual(map.start.?, 0);
- try testing.expectEqual(map.end.?, tree.tokens.len - 2);
+ try testing.expectEqual(map.base.start, 0);
+ try testing.expectEqual(map.base.end, tree.tokens.len - 2);
try testing.expectEqual(map.values.items.len, 1);
const entry = map.values.items[0];
const key = tree.tokens[entry.key];
- try testing.expectEqual(key.id, .Literal);
- try testing.expect(mem.eql(u8, "ints", tree.source[key.start..key.end]));
+ try testing.expectEqual(key.id, .literal);
+ try testing.expectEqualStrings("ints", tree.source[key.start..key.end]);
- const value = entry.value.cast(Node.List).?;
- try testing.expectEqual(value.start.?, 4);
- try testing.expectEqual(value.end.?, tree.tokens.len - 2);
+ const value = entry.value.?.cast(Node.List).?;
+ try testing.expectEqual(value.base.start, 4);
+ try testing.expectEqual(value.base.end, tree.tokens.len - 2);
try testing.expectEqual(value.values.items.len, 3);
{
const elem = value.values.items[0].cast(Node.Value).?;
- const leaf = tree.tokens[elem.start.?];
- try testing.expectEqual(leaf.id, .Literal);
- try testing.expect(mem.eql(u8, "0", tree.source[leaf.start..leaf.end]));
+ const leaf = tree.tokens[elem.base.start];
+ try testing.expectEqual(leaf.id, .literal);
+ try testing.expectEqualStrings("0", tree.source[leaf.start..leaf.end]);
}
{
const elem = value.values.items[1].cast(Node.Value).?;
- const leaf = tree.tokens[elem.start.?];
- try testing.expectEqual(leaf.id, .Literal);
- try testing.expect(mem.eql(u8, "1", tree.source[leaf.start..leaf.end]));
+ const leaf = tree.tokens[elem.base.start];
+ try testing.expectEqual(leaf.id, .literal);
+ try testing.expectEqualStrings("1", tree.source[leaf.start..leaf.end]);
}
{
const elem = value.values.items[2].cast(Node.Value).?;
- const leaf = tree.tokens[elem.start.?];
- try testing.expectEqual(leaf.id, .Literal);
- try testing.expect(mem.eql(u8, "2", tree.source[leaf.start..leaf.end]));
+ const leaf = tree.tokens[elem.base.start];
+ try testing.expectEqual(leaf.id, .literal);
+ try testing.expectEqualStrings("2", tree.source[leaf.start..leaf.end]);
}
}
@@ -285,64 +263,64 @@ test "map of list of maps" {
try testing.expectEqual(tree.docs.items.len, 1);
const doc = tree.docs.items[0].cast(Node.Doc).?;
- try testing.expectEqual(doc.start.?, 0);
- try testing.expectEqual(doc.end.?, tree.tokens.len - 2);
+ try testing.expectEqual(doc.base.start, 0);
+ try testing.expectEqual(doc.base.end, tree.tokens.len - 2);
try testing.expect(doc.value != null);
try testing.expectEqual(doc.value.?.tag, .map);
const map = doc.value.?.cast(Node.Map).?;
- try testing.expectEqual(map.start.?, 0);
- try testing.expectEqual(map.end.?, tree.tokens.len - 2);
+ try testing.expectEqual(map.base.start, 0);
+ try testing.expectEqual(map.base.end, tree.tokens.len - 2);
try testing.expectEqual(map.values.items.len, 1);
const entry = map.values.items[0];
const key = tree.tokens[entry.key];
- try testing.expectEqual(key.id, .Literal);
- try testing.expect(mem.eql(u8, "key1", tree.source[key.start..key.end]));
+ try testing.expectEqual(key.id, .literal);
+ try testing.expectEqualStrings("key1", tree.source[key.start..key.end]);
- const value = entry.value.cast(Node.List).?;
- try testing.expectEqual(value.start.?, 3);
- try testing.expectEqual(value.end.?, tree.tokens.len - 2);
+ const value = entry.value.?.cast(Node.List).?;
+ try testing.expectEqual(value.base.start, 3);
+ try testing.expectEqual(value.base.end, tree.tokens.len - 2);
try testing.expectEqual(value.values.items.len, 3);
{
const elem = value.values.items[0].cast(Node.Map).?;
const nested = elem.values.items[0];
const nested_key = tree.tokens[nested.key];
- try testing.expectEqual(nested_key.id, .Literal);
- try testing.expect(mem.eql(u8, "key2", tree.source[nested_key.start..nested_key.end]));
+ try testing.expectEqual(nested_key.id, .literal);
+ try testing.expectEqualStrings("key2", tree.source[nested_key.start..nested_key.end]);
- const nested_v = nested.value.cast(Node.Value).?;
- const leaf = tree.tokens[nested_v.start.?];
- try testing.expectEqual(leaf.id, .Literal);
- try testing.expect(mem.eql(u8, "value2", tree.source[leaf.start..leaf.end]));
+ const nested_v = nested.value.?.cast(Node.Value).?;
+ const leaf = tree.tokens[nested_v.base.start];
+ try testing.expectEqual(leaf.id, .literal);
+ try testing.expectEqualStrings("value2", tree.source[leaf.start..leaf.end]);
}
{
const elem = value.values.items[1].cast(Node.Map).?;
const nested = elem.values.items[0];
const nested_key = tree.tokens[nested.key];
- try testing.expectEqual(nested_key.id, .Literal);
- try testing.expect(mem.eql(u8, "key3", tree.source[nested_key.start..nested_key.end]));
+ try testing.expectEqual(nested_key.id, .literal);
+ try testing.expectEqualStrings("key3", tree.source[nested_key.start..nested_key.end]);
- const nested_v = nested.value.cast(Node.Value).?;
- const leaf = tree.tokens[nested_v.start.?];
- try testing.expectEqual(leaf.id, .Literal);
- try testing.expect(mem.eql(u8, "value3", tree.source[leaf.start..leaf.end]));
+ const nested_v = nested.value.?.cast(Node.Value).?;
+ const leaf = tree.tokens[nested_v.base.start];
+ try testing.expectEqual(leaf.id, .literal);
+ try testing.expectEqualStrings("value3", tree.source[leaf.start..leaf.end]);
}
{
const elem = value.values.items[2].cast(Node.Map).?;
const nested = elem.values.items[0];
const nested_key = tree.tokens[nested.key];
- try testing.expectEqual(nested_key.id, .Literal);
- try testing.expect(mem.eql(u8, "key4", tree.source[nested_key.start..nested_key.end]));
+ try testing.expectEqual(nested_key.id, .literal);
+ try testing.expectEqualStrings("key4", tree.source[nested_key.start..nested_key.end]);
- const nested_v = nested.value.cast(Node.Value).?;
- const leaf = tree.tokens[nested_v.start.?];
- try testing.expectEqual(leaf.id, .Literal);
- try testing.expect(mem.eql(u8, "value4", tree.source[leaf.start..leaf.end]));
+ const nested_v = nested.value.?.cast(Node.Value).?;
+ const leaf = tree.tokens[nested_v.base.start];
+ try testing.expectEqual(leaf.id, .literal);
+ try testing.expectEqualStrings("value4", tree.source[leaf.start..leaf.end]);
}
}
@@ -360,15 +338,15 @@ test "list of lists" {
try testing.expectEqual(tree.docs.items.len, 1);
const doc = tree.docs.items[0].cast(Node.Doc).?;
- try testing.expectEqual(doc.start.?, 0);
- try testing.expectEqual(doc.end.?, tree.tokens.len - 2);
+ try testing.expectEqual(doc.base.start, 0);
+ try testing.expectEqual(doc.base.end, tree.tokens.len - 2);
try testing.expect(doc.value != null);
try testing.expectEqual(doc.value.?.tag, .list);
const list = doc.value.?.cast(Node.List).?;
- try testing.expectEqual(list.start.?, 0);
- try testing.expectEqual(list.end.?, tree.tokens.len - 2);
+ try testing.expectEqual(list.base.start, 0);
+ try testing.expectEqual(list.base.end, tree.tokens.len - 2);
try testing.expectEqual(list.values.items.len, 3);
{
@@ -379,22 +357,22 @@ test "list of lists" {
{
try testing.expectEqual(nested.values.items[0].tag, .value);
const value = nested.values.items[0].cast(Node.Value).?;
- const leaf = tree.tokens[value.start.?];
- try testing.expect(mem.eql(u8, "name", tree.source[leaf.start..leaf.end]));
+ const leaf = tree.tokens[value.base.start];
+ try testing.expectEqualStrings("name", tree.source[leaf.start..leaf.end]);
}
{
try testing.expectEqual(nested.values.items[1].tag, .value);
const value = nested.values.items[1].cast(Node.Value).?;
- const leaf = tree.tokens[value.start.?];
- try testing.expect(mem.eql(u8, "hr", tree.source[leaf.start..leaf.end]));
+ const leaf = tree.tokens[value.base.start];
+ try testing.expectEqualStrings("hr", tree.source[leaf.start..leaf.end]);
}
{
try testing.expectEqual(nested.values.items[2].tag, .value);
const value = nested.values.items[2].cast(Node.Value).?;
- const leaf = tree.tokens[value.start.?];
- try testing.expect(mem.eql(u8, "avg", tree.source[leaf.start..leaf.end]));
+ const leaf = tree.tokens[value.base.start];
+ try testing.expectEqualStrings("avg", tree.source[leaf.start..leaf.end]);
}
}
@@ -406,23 +384,23 @@ test "list of lists" {
{
try testing.expectEqual(nested.values.items[0].tag, .value);
const value = nested.values.items[0].cast(Node.Value).?;
- const start = tree.tokens[value.start.?];
- const end = tree.tokens[value.end.?];
- try testing.expect(mem.eql(u8, "Mark McGwire", tree.source[start.start..end.end]));
+ const start = tree.tokens[value.base.start];
+ const end = tree.tokens[value.base.end];
+ try testing.expectEqualStrings("Mark McGwire", tree.source[start.start..end.end]);
}
{
try testing.expectEqual(nested.values.items[1].tag, .value);
const value = nested.values.items[1].cast(Node.Value).?;
- const leaf = tree.tokens[value.start.?];
- try testing.expect(mem.eql(u8, "65", tree.source[leaf.start..leaf.end]));
+ const leaf = tree.tokens[value.base.start];
+ try testing.expectEqualStrings("65", tree.source[leaf.start..leaf.end]);
}
{
try testing.expectEqual(nested.values.items[2].tag, .value);
const value = nested.values.items[2].cast(Node.Value).?;
- const leaf = tree.tokens[value.start.?];
- try testing.expect(mem.eql(u8, "0.278", tree.source[leaf.start..leaf.end]));
+ const leaf = tree.tokens[value.base.start];
+ try testing.expectEqualStrings("0.278", tree.source[leaf.start..leaf.end]);
}
}
@@ -434,23 +412,23 @@ test "list of lists" {
{
try testing.expectEqual(nested.values.items[0].tag, .value);
const value = nested.values.items[0].cast(Node.Value).?;
- const start = tree.tokens[value.start.?];
- const end = tree.tokens[value.end.?];
- try testing.expect(mem.eql(u8, "Sammy Sosa", tree.source[start.start..end.end]));
+ const start = tree.tokens[value.base.start];
+ const end = tree.tokens[value.base.end];
+ try testing.expectEqualStrings("Sammy Sosa", tree.source[start.start..end.end]);
}
{
try testing.expectEqual(nested.values.items[1].tag, .value);
const value = nested.values.items[1].cast(Node.Value).?;
- const leaf = tree.tokens[value.start.?];
- try testing.expect(mem.eql(u8, "63", tree.source[leaf.start..leaf.end]));
+ const leaf = tree.tokens[value.base.start];
+ try testing.expectEqualStrings("63", tree.source[leaf.start..leaf.end]);
}
{
try testing.expectEqual(nested.values.items[2].tag, .value);
const value = nested.values.items[2].cast(Node.Value).?;
- const leaf = tree.tokens[value.start.?];
- try testing.expect(mem.eql(u8, "0.288", tree.source[leaf.start..leaf.end]));
+ const leaf = tree.tokens[value.base.start];
+ try testing.expectEqualStrings("0.288", tree.source[leaf.start..leaf.end]);
}
}
}
@@ -467,36 +445,36 @@ test "inline list" {
try testing.expectEqual(tree.docs.items.len, 1);
const doc = tree.docs.items[0].cast(Node.Doc).?;
- try testing.expectEqual(doc.start.?, 0);
- try testing.expectEqual(doc.end.?, tree.tokens.len - 2);
+ try testing.expectEqual(doc.base.start, 0);
+ try testing.expectEqual(doc.base.end, tree.tokens.len - 2);
try testing.expect(doc.value != null);
try testing.expectEqual(doc.value.?.tag, .list);
const list = doc.value.?.cast(Node.List).?;
- try testing.expectEqual(list.start.?, 0);
- try testing.expectEqual(list.end.?, tree.tokens.len - 2);
+ try testing.expectEqual(list.base.start, 0);
+ try testing.expectEqual(list.base.end, tree.tokens.len - 2);
try testing.expectEqual(list.values.items.len, 3);
{
try testing.expectEqual(list.values.items[0].tag, .value);
const value = list.values.items[0].cast(Node.Value).?;
- const leaf = tree.tokens[value.start.?];
- try testing.expect(mem.eql(u8, "name", tree.source[leaf.start..leaf.end]));
+ const leaf = tree.tokens[value.base.start];
+ try testing.expectEqualStrings("name", tree.source[leaf.start..leaf.end]);
}
{
try testing.expectEqual(list.values.items[1].tag, .value);
const value = list.values.items[1].cast(Node.Value).?;
- const leaf = tree.tokens[value.start.?];
- try testing.expect(mem.eql(u8, "hr", tree.source[leaf.start..leaf.end]));
+ const leaf = tree.tokens[value.base.start];
+ try testing.expectEqualStrings("hr", tree.source[leaf.start..leaf.end]);
}
{
try testing.expectEqual(list.values.items[2].tag, .value);
const value = list.values.items[2].cast(Node.Value).?;
- const leaf = tree.tokens[value.start.?];
- try testing.expect(mem.eql(u8, "avg", tree.source[leaf.start..leaf.end]));
+ const leaf = tree.tokens[value.base.start];
+ try testing.expectEqualStrings("avg", tree.source[leaf.start..leaf.end]);
}
}
@@ -514,45 +492,273 @@ test "inline list as mapping value" {
try testing.expectEqual(tree.docs.items.len, 1);
const doc = tree.docs.items[0].cast(Node.Doc).?;
- try testing.expectEqual(doc.start.?, 0);
- try testing.expectEqual(doc.end.?, tree.tokens.len - 2);
+ try testing.expectEqual(doc.base.start, 0);
+ try testing.expectEqual(doc.base.end, tree.tokens.len - 2);
try testing.expect(doc.value != null);
try testing.expectEqual(doc.value.?.tag, .map);
const map = doc.value.?.cast(Node.Map).?;
- try testing.expectEqual(map.start.?, 0);
- try testing.expectEqual(map.end.?, tree.tokens.len - 2);
+ try testing.expectEqual(map.base.start, 0);
+ try testing.expectEqual(map.base.end, tree.tokens.len - 2);
try testing.expectEqual(map.values.items.len, 1);
const entry = map.values.items[0];
const key = tree.tokens[entry.key];
- try testing.expectEqual(key.id, .Literal);
- try testing.expect(mem.eql(u8, "key", tree.source[key.start..key.end]));
+ try testing.expectEqual(key.id, .literal);
+ try testing.expectEqualStrings("key", tree.source[key.start..key.end]);
- const list = entry.value.cast(Node.List).?;
- try testing.expectEqual(list.start.?, 4);
- try testing.expectEqual(list.end.?, tree.tokens.len - 2);
+ const list = entry.value.?.cast(Node.List).?;
+ try testing.expectEqual(list.base.start, 4);
+ try testing.expectEqual(list.base.end, tree.tokens.len - 2);
try testing.expectEqual(list.values.items.len, 3);
{
try testing.expectEqual(list.values.items[0].tag, .value);
const value = list.values.items[0].cast(Node.Value).?;
- const leaf = tree.tokens[value.start.?];
- try testing.expect(mem.eql(u8, "name", tree.source[leaf.start..leaf.end]));
+ const leaf = tree.tokens[value.base.start];
+ try testing.expectEqualStrings("name", tree.source[leaf.start..leaf.end]);
}
{
try testing.expectEqual(list.values.items[1].tag, .value);
const value = list.values.items[1].cast(Node.Value).?;
- const leaf = tree.tokens[value.start.?];
- try testing.expect(mem.eql(u8, "hr", tree.source[leaf.start..leaf.end]));
+ const leaf = tree.tokens[value.base.start];
+ try testing.expectEqualStrings("hr", tree.source[leaf.start..leaf.end]);
}
{
try testing.expectEqual(list.values.items[2].tag, .value);
const value = list.values.items[2].cast(Node.Value).?;
- const leaf = tree.tokens[value.start.?];
- try testing.expect(mem.eql(u8, "avg", tree.source[leaf.start..leaf.end]));
+ const leaf = tree.tokens[value.base.start];
+ try testing.expectEqualStrings("avg", tree.source[leaf.start..leaf.end]);
}
}
+
+fn parseSuccess(comptime source: []const u8) !void {
+ var tree = Tree.init(testing.allocator);
+ defer tree.deinit();
+ try tree.parse(source);
+}
+
+fn parseError(comptime source: []const u8, err: parse.ParseError) !void {
+ var tree = Tree.init(testing.allocator);
+ defer tree.deinit();
+ try testing.expectError(err, tree.parse(source));
+}
+
+test "empty doc with spaces and comments" {
+ try parseSuccess(
+ \\
+ \\
+ \\ # this is a comment in a weird place
+ \\# and this one is too
+ );
+}
+
+test "comment between --- and ! in document start" {
+ try parseError(
+ \\--- # what is it?
+ \\!
+ , error.UnexpectedToken);
+}
+
+test "correct doc start with tag" {
+ try parseSuccess(
+ \\--- !some-tag
+ \\
+ );
+}
+
+test "doc close without explicit doc open" {
+ try parseError(
+ \\
+ \\
+ \\# something cool
+ \\...
+ , error.UnexpectedToken);
+}
+
+test "doc open and close are ok" {
+ try parseSuccess(
+ \\---
+ \\# first doc
+ \\
+ \\
+ \\---
+ \\# second doc
+ \\
+ \\
+ \\...
+ );
+}
+
+test "doc with a single string is ok" {
+ try parseSuccess(
+ \\a string of some sort
+ \\
+ );
+}
+
+test "explicit doc with a single string is ok" {
+ try parseSuccess(
+ \\--- !anchor
+ \\# nothing to see here except one string
+ \\ # not a lot to go on with
+ \\a single string
+ \\...
+ );
+}
+
+test "doc with two string is bad" {
+ try parseError(
+ \\first
+ \\second
+ \\# this should fail already
+ , error.UnexpectedToken);
+}
+
+test "single quote string can have new lines" {
+ try parseSuccess(
+ \\'what is this
+ \\ thing?'
+ );
+}
+
+test "single quote string on one line is fine" {
+ try parseSuccess(
+ \\'here''s an apostrophe'
+ );
+}
+
+test "double quote string can have new lines" {
+ try parseSuccess(
+ \\"what is this
+ \\ thing?"
+ );
+}
+
+test "double quote string on one line is fine" {
+ try parseSuccess(
+ \\"a newline\nand a\ttab"
+ );
+}
+
+test "map with key and value literals" {
+ try parseSuccess(
+ \\key1: val1
+ \\key2 : val2
+ );
+}
+
+test "map of maps" {
+ try parseSuccess(
+ \\
+ \\# the first key
+ \\key1:
+ \\ # the first subkey
+ \\ key1_1: 0
+ \\ key1_2: 1
+ \\# the second key
+ \\key2:
+ \\ key2_1: -1
+ \\ key2_2: -2
+ \\# the end of map
+ );
+}
+
+test "map value indicator needs to be on the same line" {
+ try parseError(
+ \\a
+ \\ : b
+ , error.UnexpectedToken);
+}
+
+test "value needs to be indented" {
+ try parseError(
+ \\a:
+ \\b
+ , error.MalformedYaml);
+}
+
+test "comment between a key and a value is fine" {
+ try parseSuccess(
+ \\a:
+ \\ # this is a value
+ \\ b
+ );
+}
+
+test "simple list" {
+ try parseSuccess(
+ \\# first el
+ \\- a
+ \\# second el
+ \\- b
+ \\# third el
+ \\- c
+ );
+}
+
+test "list indentation matters" {
+ try parseSuccess(
+ \\ - a
+ \\- b
+ );
+
+ try parseSuccess(
+ \\- a
+ \\ - b
+ );
+}
+
+test "unindented list is fine too" {
+ try parseSuccess(
+ \\a:
+ \\- 0
+ \\- 1
+ );
+}
+
+test "empty values in a map" {
+ try parseSuccess(
+ \\a:
+ \\b:
+ \\- 0
+ );
+}
+
+test "weirdly nested map of maps of lists" {
+ try parseSuccess(
+ \\a:
+ \\ b:
+ \\ - 0
+ \\ - 1
+ );
+}
+
+test "square brackets denote a list" {
+ try parseSuccess(
+ \\[ a,
+ \\ b, c ]
+ );
+}
+
+test "empty list" {
+ try parseSuccess(
+ \\[ ]
+ );
+}
+
+test "comment within a bracketed list is an error" {
+ try parseError(
+ \\[ # something
+ \\]
+ , error.MalformedYaml);
+}
+
+test "mixed ints with floats in a list" {
+ try parseSuccess(
+ \\[0, 1.0]
+ );
+}
diff --git a/src/link/tapi/yaml.zig b/src/link/tapi/yaml.zig
@@ -2,8 +2,7 @@ const std = @import("std");
const assert = std.debug.assert;
const math = std.math;
const mem = std.mem;
-const testing = std.testing;
-const log = std.log.scoped(.tapi);
+const log = std.log.scoped(.yaml);
const Allocator = mem.Allocator;
const ArenaAllocator = std.heap.ArenaAllocator;
@@ -17,22 +16,15 @@ const ParseError = parse.ParseError;
pub const YamlError = error{
UnexpectedNodeType,
+ DuplicateMapKey,
OutOfMemory,
+ CannotEncodeValue,
} || ParseError || std.fmt.ParseIntError;
-pub const ValueType = enum {
- empty,
- int,
- float,
- string,
- list,
- map,
-};
-
pub const List = []Value;
-pub const Map = std.StringArrayHashMap(Value);
+pub const Map = std.StringHashMap(Value);
-pub const Value = union(ValueType) {
+pub const Value = union(enum) {
empty,
int: i64,
float: f64,
@@ -70,9 +62,7 @@ pub const Value = union(ValueType) {
should_inline_first_key: bool = false,
};
- pub const StringifyError = std.os.WriteError;
-
- pub fn stringify(self: Value, writer: anytype, args: StringifyArgs) StringifyError!void {
+ pub fn stringify(self: Value, writer: anytype, args: StringifyArgs) anyerror!void {
switch (self) {
.empty => return,
.int => |int| return writer.print("{}", .{int}),
@@ -83,7 +73,7 @@ pub const Value = union(ValueType) {
if (len == 0) return;
const first = list[0];
- if (first.is_compound()) {
+ if (first.isCompound()) {
for (list, 0..) |elem, i| {
try writer.writeByteNTimes(' ', args.indentation);
try writer.writeAll("- ");
@@ -108,20 +98,23 @@ pub const Value = union(ValueType) {
try writer.writeAll(" ]");
},
.map => |map| {
- const keys = map.keys();
- const len = keys.len;
+ const len = map.count();
if (len == 0) return;
- for (keys, 0..) |key, i| {
+ var i: usize = 0;
+ var it = map.iterator();
+ while (it.next()) |entry| {
+ const key = entry.key_ptr.*;
+ const value = entry.value_ptr.*;
+
if (!args.should_inline_first_key or i != 0) {
try writer.writeByteNTimes(' ', args.indentation);
}
try writer.print("{s}: ", .{key});
- const value = map.get(key) orelse unreachable;
const should_inline = blk: {
- if (!value.is_compound()) break :blk true;
- if (value == .list and value.list.len > 0 and !value.list[0].is_compound()) break :blk true;
+ if (!value.isCompound()) break :blk true;
+ if (value == .list and value.list.len > 0 and !value.list[0].isCompound()) break :blk true;
break :blk false;
};
@@ -137,35 +130,44 @@ pub const Value = union(ValueType) {
if (i < len - 1) {
try writer.writeByte('\n');
}
+
+ i += 1;
}
},
}
}
- fn is_compound(self: Value) bool {
+ fn isCompound(self: Value) bool {
return switch (self) {
.list, .map => true,
else => false,
};
}
- fn fromNode(arena: Allocator, tree: *const Tree, node: *const Node, type_hint: ?ValueType) YamlError!Value {
+ fn fromNode(arena: Allocator, tree: *const Tree, node: *const Node) YamlError!Value {
if (node.cast(Node.Doc)) |doc| {
const inner = doc.value orelse {
// empty doc
return Value{ .empty = {} };
};
- return Value.fromNode(arena, tree, inner, null);
+ return Value.fromNode(arena, tree, inner);
} else if (node.cast(Node.Map)) |map| {
- var out_map = std.StringArrayHashMap(Value).init(arena);
- try out_map.ensureUnusedCapacity(map.values.items.len);
+ // TODO use ContextAdapted HashMap and do not duplicate keys, intern
+ // in a contiguous string buffer.
+ var out_map = std.StringHashMap(Value).init(arena);
+ try out_map.ensureUnusedCapacity(math.cast(u32, map.values.items.len) orelse return error.Overflow);
for (map.values.items) |entry| {
- const key_tok = tree.tokens[entry.key];
- const key = try arena.dupe(u8, tree.source[key_tok.start..key_tok.end]);
- const value = try Value.fromNode(arena, tree, entry.value, null);
-
- out_map.putAssumeCapacityNoClobber(key, value);
+ const key = try arena.dupe(u8, tree.getRaw(entry.key, entry.key));
+ const gop = out_map.getOrPutAssumeCapacity(key);
+ if (gop.found_existing) {
+ return error.DuplicateMapKey;
+ }
+ const value = if (entry.value) |value|
+ try Value.fromNode(arena, tree, value)
+ else
+ .empty;
+ gop.value_ptr.* = value;
}
return Value{ .map = out_map };
@@ -173,56 +175,124 @@ pub const Value = union(ValueType) {
var out_list = std.ArrayList(Value).init(arena);
try out_list.ensureUnusedCapacity(list.values.items.len);
- if (list.values.items.len > 0) {
- const hint = if (list.values.items[0].cast(Node.Value)) |value| hint: {
- const start = tree.tokens[value.start.?];
- const end = tree.tokens[value.end.?];
- const raw = tree.source[start.start..end.end];
- _ = std.fmt.parseInt(i64, raw, 10) catch {
- _ = std.fmt.parseFloat(f64, raw) catch {
- break :hint ValueType.string;
- };
- break :hint ValueType.float;
- };
- break :hint ValueType.int;
- } else null;
-
- for (list.values.items) |elem| {
- const value = try Value.fromNode(arena, tree, elem, hint);
- out_list.appendAssumeCapacity(value);
- }
+ for (list.values.items) |elem| {
+ const value = try Value.fromNode(arena, tree, elem);
+ out_list.appendAssumeCapacity(value);
}
return Value{ .list = try out_list.toOwnedSlice() };
} else if (node.cast(Node.Value)) |value| {
- const start = tree.tokens[value.start.?];
- const end = tree.tokens[value.end.?];
- const raw = tree.source[start.start..end.end];
-
- if (type_hint) |hint| {
- return switch (hint) {
- .int => Value{ .int = try std.fmt.parseInt(i64, raw, 10) },
- .float => Value{ .float = try std.fmt.parseFloat(f64, raw) },
- .string => Value{ .string = try arena.dupe(u8, raw) },
- else => unreachable,
- };
- }
+ const raw = tree.getRaw(node.start, node.end);
try_int: {
// TODO infer base for int
const int = std.fmt.parseInt(i64, raw, 10) catch break :try_int;
return Value{ .int = int };
}
+
try_float: {
const float = std.fmt.parseFloat(f64, raw) catch break :try_float;
return Value{ .float = float };
}
- return Value{ .string = try arena.dupe(u8, raw) };
+
+ return Value{ .string = try arena.dupe(u8, value.string_value.items) };
} else {
log.err("Unexpected node type: {}", .{node.tag});
return error.UnexpectedNodeType;
}
}
+
+ fn encode(arena: Allocator, input: anytype) YamlError!?Value {
+ switch (@typeInfo(@TypeOf(input))) {
+ .ComptimeInt,
+ .Int,
+ => return Value{ .int = math.cast(i64, input) orelse return error.Overflow },
+
+ .Float => return Value{ .float = math.lossyCast(f64, input) },
+
+ .Struct => |info| if (info.is_tuple) {
+ var list = std.ArrayList(Value).init(arena);
+ errdefer list.deinit();
+ try list.ensureTotalCapacityPrecise(info.fields.len);
+
+ inline for (info.fields) |field| {
+ if (try encode(arena, @field(input, field.name))) |value| {
+ list.appendAssumeCapacity(value);
+ }
+ }
+
+ return Value{ .list = try list.toOwnedSlice() };
+ } else {
+ var map = Map.init(arena);
+ errdefer map.deinit();
+ try map.ensureTotalCapacity(info.fields.len);
+
+ inline for (info.fields) |field| {
+ if (try encode(arena, @field(input, field.name))) |value| {
+ const key = try arena.dupe(u8, field.name);
+ map.putAssumeCapacityNoClobber(key, value);
+ }
+ }
+
+ return Value{ .map = map };
+ },
+
+ .Union => |info| if (info.tag_type) |tag_type| {
+ inline for (info.fields) |field| {
+ if (@field(tag_type, field.name) == input) {
+ return try encode(arena, @field(input, field.name));
+ }
+ } else unreachable;
+ } else return error.UntaggedUnion,
+
+ .Array => return encode(arena, &input),
+
+ .Pointer => |info| switch (info.size) {
+ .One => switch (@typeInfo(info.child)) {
+ .Array => |child_info| {
+ const Slice = []const child_info.child;
+ return encode(arena, @as(Slice, input));
+ },
+ else => {
+ @compileError("Unhandled type: {s}" ++ @typeName(info.child));
+ },
+ },
+ .Slice => {
+ if (info.child == u8) {
+ return Value{ .string = try arena.dupe(u8, input) };
+ }
+
+ var list = std.ArrayList(Value).init(arena);
+ errdefer list.deinit();
+ try list.ensureTotalCapacityPrecise(input.len);
+
+ for (input) |elem| {
+ if (try encode(arena, elem)) |value| {
+ list.appendAssumeCapacity(value);
+ } else {
+ log.err("Could not encode value in a list: {any}", .{elem});
+ return error.CannotEncodeValue;
+ }
+ }
+
+ return Value{ .list = try list.toOwnedSlice() };
+ },
+ else => {
+ @compileError("Unhandled type: {s}" ++ @typeName(@TypeOf(input)));
+ },
+ },
+
+ // TODO we should probably have an option to encode `null` and also
+ // allow for some default value too.
+ .Optional => return if (input) |val| encode(arena, val) else null,
+
+ .Null => return null,
+
+ else => {
+ @compileError("Unhandled type: {s}" ++ @typeName(@TypeOf(input)));
+ },
+ }
+ }
};
pub const Yaml = struct {
@@ -234,30 +304,18 @@ pub const Yaml = struct {
self.arena.deinit();
}
- pub fn stringify(self: Yaml, writer: anytype) !void {
- for (self.docs.items) |doc| {
- // if (doc.directive) |directive| {
- // try writer.print("--- !{s}\n", .{directive});
- // }
- try doc.stringify(writer, .{});
- // if (doc.directive != null) {
- // try writer.writeAll("...\n");
- // }
- }
- }
-
pub fn load(allocator: Allocator, source: []const u8) !Yaml {
var arena = ArenaAllocator.init(allocator);
- const arena_allocator = arena.allocator();
+ errdefer arena.deinit();
- var tree = Tree.init(arena_allocator);
+ var tree = Tree.init(arena.allocator());
try tree.parse(source);
- var docs = std.ArrayList(Value).init(arena_allocator);
- try docs.ensureUnusedCapacity(tree.docs.items.len);
+ var docs = std.ArrayList(Value).init(arena.allocator());
+ try docs.ensureTotalCapacityPrecise(tree.docs.items.len);
for (tree.docs.items) |node| {
- const value = try Value.fromNode(arena_allocator, &tree, node, null);
+ const value = try Value.fromNode(arena.allocator(), &tree, node);
docs.appendAssumeCapacity(value);
}
@@ -316,17 +374,19 @@ pub const Yaml = struct {
fn parseValue(self: *Yaml, comptime T: type, value: Value) Error!T {
return switch (@typeInfo(T)) {
- .Int => math.cast(T, try value.asInt()) orelse error.Overflow,
- .Float => math.lossyCast(T, try value.asFloat()),
+ .Int => math.cast(T, try value.asInt()) orelse return error.Overflow,
+ .Float => if (value.asFloat()) |float| {
+ return math.lossyCast(T, float);
+ } else |_| {
+ return math.lossyCast(T, try value.asInt());
+ },
.Struct => self.parseStruct(T, try value.asMap()),
.Union => self.parseUnion(T, value),
.Array => self.parseArray(T, try value.asList()),
- .Pointer => {
- if (value.asList()) |list| {
- return self.parsePointer(T, .{ .list = list });
- } else |_| {
- return self.parsePointer(T, .{ .string = try value.asString() });
- }
+ .Pointer => if (value.asList()) |list| {
+ return self.parsePointer(T, .{ .list = list });
+ } else |_| {
+ return self.parsePointer(T, .{ .string = try value.asString() });
},
.Void => error.TypeMismatch,
.Optional => unreachable,
@@ -372,7 +432,7 @@ pub const Yaml = struct {
}
const unwrapped = value orelse {
- log.debug("missing struct field: {s}: {s}", .{ field.name, @typeName(field.type) });
+ log.err("missing struct field: {s}: {s}", .{ field.name, @typeName(field.type) });
return error.StructFieldMissing;
};
@field(parsed, field.name) = try self.parseValue(field.type, unwrapped);
@@ -387,8 +447,7 @@ pub const Yaml = struct {
switch (ptr_info.size) {
.Slice => {
- const child_info = @typeInfo(ptr_info.child);
- if (child_info == .Int and child_info.Int.bits == 8) {
+ if (ptr_info.child == u8) {
return value.asString();
}
@@ -413,315 +472,36 @@ pub const Yaml = struct {
return parsed;
}
-};
-
-test {
- testing.refAllDecls(@This());
-}
-
-test "simple list" {
- const source =
- \\- a
- \\- b
- \\- c
- ;
-
- var yaml = try Yaml.load(testing.allocator, source);
- defer yaml.deinit();
- try testing.expectEqual(yaml.docs.items.len, 1);
-
- const list = yaml.docs.items[0].list;
- try testing.expectEqual(list.len, 3);
-
- try testing.expect(mem.eql(u8, list[0].string, "a"));
- try testing.expect(mem.eql(u8, list[1].string, "b"));
- try testing.expect(mem.eql(u8, list[2].string, "c"));
-}
-
-test "simple list typed as array of strings" {
- const source =
- \\- a
- \\- b
- \\- c
- ;
-
- var yaml = try Yaml.load(testing.allocator, source);
- defer yaml.deinit();
-
- try testing.expectEqual(yaml.docs.items.len, 1);
-
- const arr = try yaml.parse([3][]const u8);
- try testing.expectEqual(arr.len, 3);
- try testing.expect(mem.eql(u8, arr[0], "a"));
- try testing.expect(mem.eql(u8, arr[1], "b"));
- try testing.expect(mem.eql(u8, arr[2], "c"));
-}
-
-test "simple list typed as array of ints" {
- const source =
- \\- 0
- \\- 1
- \\- 2
- ;
-
- var yaml = try Yaml.load(testing.allocator, source);
- defer yaml.deinit();
-
- try testing.expectEqual(yaml.docs.items.len, 1);
-
- const arr = try yaml.parse([3]u8);
- try testing.expectEqual(arr.len, 3);
- try testing.expectEqual(arr[0], 0);
- try testing.expectEqual(arr[1], 1);
- try testing.expectEqual(arr[2], 2);
-}
-
-test "list of mixed sign integer" {
- const source =
- \\- 0
- \\- -1
- \\- 2
- ;
-
- var yaml = try Yaml.load(testing.allocator, source);
- defer yaml.deinit();
-
- try testing.expectEqual(yaml.docs.items.len, 1);
-
- const arr = try yaml.parse([3]i8);
- try testing.expectEqual(arr.len, 3);
- try testing.expectEqual(arr[0], 0);
- try testing.expectEqual(arr[1], -1);
- try testing.expectEqual(arr[2], 2);
-}
-
-test "simple map untyped" {
- const source =
- \\a: 0
- ;
-
- var yaml = try Yaml.load(testing.allocator, source);
- defer yaml.deinit();
-
- try testing.expectEqual(yaml.docs.items.len, 1);
-
- const map = yaml.docs.items[0].map;
- try testing.expect(map.contains("a"));
- try testing.expectEqual(map.get("a").?.int, 0);
-}
-
-test "simple map untyped with a list of maps" {
- const source =
- \\a: 0
- \\b:
- \\ - foo: 1
- \\ bar: 2
- \\ - foo: 3
- \\ bar: 4
- \\c: 1
- ;
-
- var yaml = try Yaml.load(testing.allocator, source);
- defer yaml.deinit();
-
- try testing.expectEqual(yaml.docs.items.len, 1);
-
- const map = yaml.docs.items[0].map;
- try testing.expect(map.contains("a"));
- try testing.expect(map.contains("b"));
- try testing.expect(map.contains("c"));
- try testing.expectEqual(map.get("a").?.int, 0);
- try testing.expectEqual(map.get("c").?.int, 1);
- try testing.expectEqual(map.get("b").?.list[0].map.get("foo").?.int, 1);
- try testing.expectEqual(map.get("b").?.list[0].map.get("bar").?.int, 2);
- try testing.expectEqual(map.get("b").?.list[1].map.get("foo").?.int, 3);
- try testing.expectEqual(map.get("b").?.list[1].map.get("bar").?.int, 4);
-}
-
-test "simple map untyped with a list of maps. no indent" {
- const source =
- \\b:
- \\- foo: 1
- \\c: 1
- ;
-
- var yaml = try Yaml.load(testing.allocator, source);
- defer yaml.deinit();
-
- try testing.expectEqual(yaml.docs.items.len, 1);
-
- const map = yaml.docs.items[0].map;
- try testing.expect(map.contains("b"));
- try testing.expect(map.contains("c"));
- try testing.expectEqual(map.get("c").?.int, 1);
- try testing.expectEqual(map.get("b").?.list[0].map.get("foo").?.int, 1);
-}
-
-test "simple map untyped with a list of maps. no indent 2" {
- const source =
- \\a: 0
- \\b:
- \\- foo: 1
- \\ bar: 2
- \\- foo: 3
- \\ bar: 4
- \\c: 1
- ;
-
- var yaml = try Yaml.load(testing.allocator, source);
- defer yaml.deinit();
-
- try testing.expectEqual(yaml.docs.items.len, 1);
-
- const map = yaml.docs.items[0].map;
- try testing.expect(map.contains("a"));
- try testing.expect(map.contains("b"));
- try testing.expect(map.contains("c"));
- try testing.expectEqual(map.get("a").?.int, 0);
- try testing.expectEqual(map.get("c").?.int, 1);
- try testing.expectEqual(map.get("b").?.list[0].map.get("foo").?.int, 1);
- try testing.expectEqual(map.get("b").?.list[0].map.get("bar").?.int, 2);
- try testing.expectEqual(map.get("b").?.list[1].map.get("foo").?.int, 3);
- try testing.expectEqual(map.get("b").?.list[1].map.get("bar").?.int, 4);
-}
-
-test "simple map typed" {
- const source =
- \\a: 0
- \\b: hello there
- \\c: 'wait, what?'
- ;
-
- var yaml = try Yaml.load(testing.allocator, source);
- defer yaml.deinit();
-
- const simple = try yaml.parse(struct { a: usize, b: []const u8, c: []const u8 });
- try testing.expectEqual(simple.a, 0);
- try testing.expect(mem.eql(u8, simple.b, "hello there"));
- try testing.expect(mem.eql(u8, simple.c, "wait, what?"));
-}
-
-test "typed nested structs" {
- const source =
- \\a:
- \\ b: hello there
- \\ c: 'wait, what?'
- ;
-
- var yaml = try Yaml.load(testing.allocator, source);
- defer yaml.deinit();
-
- const simple = try yaml.parse(struct {
- a: struct {
- b: []const u8,
- c: []const u8,
- },
- });
- try testing.expect(mem.eql(u8, simple.a.b, "hello there"));
- try testing.expect(mem.eql(u8, simple.a.c, "wait, what?"));
-}
-
-test "multidoc typed as a slice of structs" {
- const source =
- \\---
- \\a: 0
- \\---
- \\a: 1
- \\...
- ;
-
- var yaml = try Yaml.load(testing.allocator, source);
- defer yaml.deinit();
-
- {
- const result = try yaml.parse([2]struct { a: usize });
- try testing.expectEqual(result.len, 2);
- try testing.expectEqual(result[0].a, 0);
- try testing.expectEqual(result[1].a, 1);
- }
-
- {
- const result = try yaml.parse([]struct { a: usize });
- try testing.expectEqual(result.len, 2);
- try testing.expectEqual(result[0].a, 0);
- try testing.expectEqual(result[1].a, 1);
+ pub fn stringify(self: Yaml, writer: anytype) !void {
+ for (self.docs.items, 0..) |doc, i| {
+ try writer.writeAll("---");
+ if (self.tree.?.getDirective(i)) |directive| {
+ try writer.print(" !{s}", .{directive});
+ }
+ try writer.writeByte('\n');
+ try doc.stringify(writer, .{});
+ try writer.writeByte('\n');
+ }
+ try writer.writeAll("...\n");
}
-}
-
-test "multidoc typed as a struct is an error" {
- const source =
- \\---
- \\a: 0
- \\---
- \\b: 1
- \\...
- ;
-
- var yaml = try Yaml.load(testing.allocator, source);
- defer yaml.deinit();
-
- try testing.expectError(Yaml.Error.TypeMismatch, yaml.parse(struct { a: usize }));
- try testing.expectError(Yaml.Error.TypeMismatch, yaml.parse(struct { b: usize }));
- try testing.expectError(Yaml.Error.TypeMismatch, yaml.parse(struct { a: usize, b: usize }));
-}
-
-test "multidoc typed as a slice of structs with optionals" {
- const source =
- \\---
- \\a: 0
- \\c: 1.0
- \\---
- \\a: 1
- \\b: different field
- \\...
- ;
-
- var yaml = try Yaml.load(testing.allocator, source);
- defer yaml.deinit();
-
- const result = try yaml.parse([]struct { a: usize, b: ?[]const u8, c: ?f16 });
- try testing.expectEqual(result.len, 2);
-
- try testing.expectEqual(result[0].a, 0);
- try testing.expect(result[0].b == null);
- try testing.expect(result[0].c != null);
- try testing.expectEqual(result[0].c.?, 1.0);
-
- try testing.expectEqual(result[1].a, 1);
- try testing.expect(result[1].b != null);
- try testing.expect(mem.eql(u8, result[1].b.?, "different field"));
- try testing.expect(result[1].c == null);
-}
-
-test "empty yaml can be represented as void" {
- const source = "";
- var yaml = try Yaml.load(testing.allocator, source);
- defer yaml.deinit();
- const result = try yaml.parse(void);
- try testing.expect(@TypeOf(result) == void);
-}
+};
-test "nonempty yaml cannot be represented as void" {
- const source =
- \\a: b
- ;
+pub fn stringify(allocator: Allocator, input: anytype, writer: anytype) !void {
+ var arena = ArenaAllocator.init(allocator);
+ defer arena.deinit();
- var yaml = try Yaml.load(testing.allocator, source);
- defer yaml.deinit();
+ var maybe_value = try Value.encode(arena.allocator(), input);
- try testing.expectError(Yaml.Error.TypeMismatch, yaml.parse(void));
+ if (maybe_value) |value| {
+ // TODO should we output as an explicit doc?
+ // How can allow the user to specify?
+ try value.stringify(writer, .{});
+ }
}
-test "typed array size mismatch" {
- const source =
- \\- 0
- \\- 0
- ;
-
- var yaml = try Yaml.load(testing.allocator, source);
- defer yaml.deinit();
-
- try testing.expectError(Yaml.Error.ArraySizeMismatch, yaml.parse([1]usize));
- try testing.expectError(Yaml.Error.ArraySizeMismatch, yaml.parse([5]usize));
+test {
+ std.testing.refAllDecls(Tokenizer);
+ std.testing.refAllDecls(parse);
+ _ = @import("yaml/test.zig");
}
diff --git a/src/link/tapi/yaml/test.zig b/src/link/tapi/yaml/test.zig
@@ -0,0 +1,475 @@
+const std = @import("std");
+const mem = std.mem;
+const testing = std.testing;
+
+const yaml_mod = @import("../yaml.zig");
+const Yaml = yaml_mod.Yaml;
+
+test "simple list" {
+ const source =
+ \\- a
+ \\- b
+ \\- c
+ ;
+
+ var yaml = try Yaml.load(testing.allocator, source);
+ defer yaml.deinit();
+
+ try testing.expectEqual(yaml.docs.items.len, 1);
+
+ const list = yaml.docs.items[0].list;
+ try testing.expectEqual(list.len, 3);
+
+ try testing.expectEqualStrings("a", list[0].string);
+ try testing.expectEqualStrings("b", list[1].string);
+ try testing.expectEqualStrings("c", list[2].string);
+}
+
+test "simple list typed as array of strings" {
+ const source =
+ \\- a
+ \\- b
+ \\- c
+ ;
+
+ var yaml = try Yaml.load(testing.allocator, source);
+ defer yaml.deinit();
+
+ try testing.expectEqual(yaml.docs.items.len, 1);
+
+ const arr = try yaml.parse([3][]const u8);
+ try testing.expectEqual(3, arr.len);
+ try testing.expectEqualStrings("a", arr[0]);
+ try testing.expectEqualStrings("b", arr[1]);
+ try testing.expectEqualStrings("c", arr[2]);
+}
+
+test "simple list typed as array of ints" {
+ const source =
+ \\- 0
+ \\- 1
+ \\- 2
+ ;
+
+ var yaml = try Yaml.load(testing.allocator, source);
+ defer yaml.deinit();
+
+ try testing.expectEqual(yaml.docs.items.len, 1);
+
+ const arr = try yaml.parse([3]u8);
+ try testing.expectEqualSlices(u8, &[_]u8{ 0, 1, 2 }, &arr);
+}
+
+test "list of mixed sign integer" {
+ const source =
+ \\- 0
+ \\- -1
+ \\- 2
+ ;
+
+ var yaml = try Yaml.load(testing.allocator, source);
+ defer yaml.deinit();
+
+ try testing.expectEqual(yaml.docs.items.len, 1);
+
+ const arr = try yaml.parse([3]i8);
+ try testing.expectEqualSlices(i8, &[_]i8{ 0, -1, 2 }, &arr);
+}
+
+test "simple map untyped" {
+ const source =
+ \\a: 0
+ ;
+
+ var yaml = try Yaml.load(testing.allocator, source);
+ defer yaml.deinit();
+
+ try testing.expectEqual(yaml.docs.items.len, 1);
+
+ const map = yaml.docs.items[0].map;
+ try testing.expect(map.contains("a"));
+ try testing.expectEqual(@as(i64, 0), map.get("a").?.int);
+}
+
+test "simple map untyped with a list of maps" {
+ const source =
+ \\a: 0
+ \\b:
+ \\ - foo: 1
+ \\ bar: 2
+ \\ - foo: 3
+ \\ bar: 4
+ \\c: 1
+ ;
+
+ var yaml = try Yaml.load(testing.allocator, source);
+ defer yaml.deinit();
+
+ try testing.expectEqual(yaml.docs.items.len, 1);
+
+ const map = yaml.docs.items[0].map;
+ try testing.expect(map.contains("a"));
+ try testing.expect(map.contains("b"));
+ try testing.expect(map.contains("c"));
+ try testing.expectEqual(@as(i64, 0), map.get("a").?.int);
+ try testing.expectEqual(@as(i64, 1), map.get("c").?.int);
+ try testing.expectEqual(@as(i64, 1), map.get("b").?.list[0].map.get("foo").?.int);
+ try testing.expectEqual(@as(i64, 2), map.get("b").?.list[0].map.get("bar").?.int);
+ try testing.expectEqual(@as(i64, 3), map.get("b").?.list[1].map.get("foo").?.int);
+ try testing.expectEqual(@as(i64, 4), map.get("b").?.list[1].map.get("bar").?.int);
+}
+
+test "simple map untyped with a list of maps. no indent" {
+ const source =
+ \\b:
+ \\- foo: 1
+ \\c: 1
+ ;
+
+ var yaml = try Yaml.load(testing.allocator, source);
+ defer yaml.deinit();
+
+ try testing.expectEqual(yaml.docs.items.len, 1);
+
+ const map = yaml.docs.items[0].map;
+ try testing.expect(map.contains("b"));
+ try testing.expect(map.contains("c"));
+ try testing.expectEqual(@as(i64, 1), map.get("c").?.int);
+ try testing.expectEqual(@as(i64, 1), map.get("b").?.list[0].map.get("foo").?.int);
+}
+
+test "simple map untyped with a list of maps. no indent 2" {
+ const source =
+ \\a: 0
+ \\b:
+ \\- foo: 1
+ \\ bar: 2
+ \\- foo: 3
+ \\ bar: 4
+ \\c: 1
+ ;
+
+ var yaml = try Yaml.load(testing.allocator, source);
+ defer yaml.deinit();
+
+ try testing.expectEqual(yaml.docs.items.len, 1);
+
+ const map = yaml.docs.items[0].map;
+ try testing.expect(map.contains("a"));
+ try testing.expect(map.contains("b"));
+ try testing.expect(map.contains("c"));
+ try testing.expectEqual(@as(i64, 0), map.get("a").?.int);
+ try testing.expectEqual(@as(i64, 1), map.get("c").?.int);
+ try testing.expectEqual(@as(i64, 1), map.get("b").?.list[0].map.get("foo").?.int);
+ try testing.expectEqual(@as(i64, 2), map.get("b").?.list[0].map.get("bar").?.int);
+ try testing.expectEqual(@as(i64, 3), map.get("b").?.list[1].map.get("foo").?.int);
+ try testing.expectEqual(@as(i64, 4), map.get("b").?.list[1].map.get("bar").?.int);
+}
+
+test "simple map typed" {
+ const source =
+ \\a: 0
+ \\b: hello there
+ \\c: 'wait, what?'
+ ;
+
+ var yaml = try Yaml.load(testing.allocator, source);
+ defer yaml.deinit();
+
+ const simple = try yaml.parse(struct { a: usize, b: []const u8, c: []const u8 });
+ try testing.expectEqual(@as(usize, 0), simple.a);
+ try testing.expectEqualStrings("hello there", simple.b);
+ try testing.expectEqualStrings("wait, what?", simple.c);
+}
+
+test "typed nested structs" {
+ const source =
+ \\a:
+ \\ b: hello there
+ \\ c: 'wait, what?'
+ ;
+
+ var yaml = try Yaml.load(testing.allocator, source);
+ defer yaml.deinit();
+
+ const simple = try yaml.parse(struct {
+ a: struct {
+ b: []const u8,
+ c: []const u8,
+ },
+ });
+ try testing.expectEqualStrings("hello there", simple.a.b);
+ try testing.expectEqualStrings("wait, what?", simple.a.c);
+}
+
+test "single quoted string" {
+ const source =
+ \\- 'hello'
+ \\- 'here''s an escaped quote'
+ \\- 'newlines and tabs\nare not\tsupported'
+ ;
+
+ var yaml = try Yaml.load(testing.allocator, source);
+ defer yaml.deinit();
+
+ const arr = try yaml.parse([3][]const u8);
+ try testing.expectEqual(arr.len, 3);
+ try testing.expectEqualStrings("hello", arr[0]);
+ try testing.expectEqualStrings("here's an escaped quote", arr[1]);
+ try testing.expectEqualStrings("newlines and tabs\\nare not\\tsupported", arr[2]);
+}
+
+test "double quoted string" {
+ const source =
+ \\- "hello"
+ \\- "\"here\" are some escaped quotes"
+ \\- "newlines and tabs\nare\tsupported"
+ \\- "let's have
+ \\some fun!"
+ ;
+
+ var yaml = try Yaml.load(testing.allocator, source);
+ defer yaml.deinit();
+
+ const arr = try yaml.parse([4][]const u8);
+ try testing.expectEqual(arr.len, 4);
+ try testing.expectEqualStrings("hello", arr[0]);
+ try testing.expectEqualStrings(
+ \\"here" are some escaped quotes
+ , arr[1]);
+ try testing.expectEqualStrings(
+ \\newlines and tabs
+ \\are supported
+ , arr[2]);
+ try testing.expectEqualStrings(
+ \\let's have
+ \\some fun!
+ , arr[3]);
+}
+
+test "multidoc typed as a slice of structs" {
+ const source =
+ \\---
+ \\a: 0
+ \\---
+ \\a: 1
+ \\...
+ ;
+
+ var yaml = try Yaml.load(testing.allocator, source);
+ defer yaml.deinit();
+
+ {
+ const result = try yaml.parse([2]struct { a: usize });
+ try testing.expectEqual(result.len, 2);
+ try testing.expectEqual(result[0].a, 0);
+ try testing.expectEqual(result[1].a, 1);
+ }
+
+ {
+ const result = try yaml.parse([]struct { a: usize });
+ try testing.expectEqual(result.len, 2);
+ try testing.expectEqual(result[0].a, 0);
+ try testing.expectEqual(result[1].a, 1);
+ }
+}
+
+test "multidoc typed as a struct is an error" {
+ const source =
+ \\---
+ \\a: 0
+ \\---
+ \\b: 1
+ \\...
+ ;
+
+ var yaml = try Yaml.load(testing.allocator, source);
+ defer yaml.deinit();
+
+ try testing.expectError(Yaml.Error.TypeMismatch, yaml.parse(struct { a: usize }));
+ try testing.expectError(Yaml.Error.TypeMismatch, yaml.parse(struct { b: usize }));
+ try testing.expectError(Yaml.Error.TypeMismatch, yaml.parse(struct { a: usize, b: usize }));
+}
+
+test "multidoc typed as a slice of structs with optionals" {
+ const source =
+ \\---
+ \\a: 0
+ \\c: 1.0
+ \\---
+ \\a: 1
+ \\b: different field
+ \\...
+ ;
+
+ var yaml = try Yaml.load(testing.allocator, source);
+ defer yaml.deinit();
+
+ const result = try yaml.parse([]struct { a: usize, b: ?[]const u8, c: ?f16 });
+ try testing.expectEqual(result.len, 2);
+
+ try testing.expectEqual(result[0].a, 0);
+ try testing.expect(result[0].b == null);
+ try testing.expect(result[0].c != null);
+ try testing.expectEqual(result[0].c.?, 1.0);
+
+ try testing.expectEqual(result[1].a, 1);
+ try testing.expect(result[1].b != null);
+ try testing.expectEqualStrings("different field", result[1].b.?);
+ try testing.expect(result[1].c == null);
+}
+
+test "empty yaml can be represented as void" {
+ const source = "";
+ var yaml = try Yaml.load(testing.allocator, source);
+ defer yaml.deinit();
+ const result = try yaml.parse(void);
+ try testing.expect(@TypeOf(result) == void);
+}
+
+test "nonempty yaml cannot be represented as void" {
+ const source =
+ \\a: b
+ ;
+
+ var yaml = try Yaml.load(testing.allocator, source);
+ defer yaml.deinit();
+
+ try testing.expectError(Yaml.Error.TypeMismatch, yaml.parse(void));
+}
+
+test "typed array size mismatch" {
+ const source =
+ \\- 0
+ \\- 0
+ ;
+
+ var yaml = try Yaml.load(testing.allocator, source);
+ defer yaml.deinit();
+
+ try testing.expectError(Yaml.Error.ArraySizeMismatch, yaml.parse([1]usize));
+ try testing.expectError(Yaml.Error.ArraySizeMismatch, yaml.parse([5]usize));
+}
+
+test "comments" {
+ const source =
+ \\
+ \\key: # this is the key
+ \\# first value
+ \\
+ \\- val1
+ \\
+ \\# second value
+ \\- val2
+ ;
+
+ var yaml = try Yaml.load(testing.allocator, source);
+ defer yaml.deinit();
+
+ const simple = try yaml.parse(struct {
+ key: []const []const u8,
+ });
+ try testing.expect(simple.key.len == 2);
+ try testing.expectEqualStrings("val1", simple.key[0]);
+ try testing.expectEqualStrings("val2", simple.key[1]);
+}
+
+test "promote ints to floats in a list mixed numeric types" {
+ const source =
+ \\a_list: [0, 1.0]
+ ;
+
+ var yaml = try Yaml.load(testing.allocator, source);
+ defer yaml.deinit();
+
+ const simple = try yaml.parse(struct {
+ a_list: []const f64,
+ });
+ try testing.expectEqualSlices(f64, &[_]f64{ 0.0, 1.0 }, simple.a_list);
+}
+
+test "demoting floats to ints in a list is an error" {
+ const source =
+ \\a_list: [0, 1.0]
+ ;
+
+ var yaml = try Yaml.load(testing.allocator, source);
+ defer yaml.deinit();
+
+ try testing.expectError(error.TypeMismatch, yaml.parse(struct {
+ a_list: []const u64,
+ }));
+}
+
+test "duplicate map keys" {
+ const source =
+ \\a: b
+ \\a: c
+ ;
+ try testing.expectError(error.DuplicateMapKey, Yaml.load(testing.allocator, source));
+}
+
+fn testStringify(expected: []const u8, input: anytype) !void {
+ var output = std.ArrayList(u8).init(testing.allocator);
+ defer output.deinit();
+
+ try yaml_mod.stringify(testing.allocator, input, output.writer());
+ try testing.expectEqualStrings(expected, output.items);
+}
+
+test "stringify an int" {
+ try testStringify("128", @as(u32, 128));
+}
+
+test "stringify a simple struct" {
+ try testStringify(
+ \\a: 1
+ \\b: 2
+ \\c: 2.5
+ , struct { a: i64, b: f64, c: f64 }{ .a = 1, .b = 2.0, .c = 2.5 });
+}
+
+test "stringify a struct with an optional" {
+ try testStringify(
+ \\a: 1
+ \\b: 2
+ \\c: 2.5
+ , struct { a: i64, b: ?f64, c: f64 }{ .a = 1, .b = 2.0, .c = 2.5 });
+
+ try testStringify(
+ \\a: 1
+ \\c: 2.5
+ , struct { a: i64, b: ?f64, c: f64 }{ .a = 1, .b = null, .c = 2.5 });
+}
+
+test "stringify a struct with all optionals" {
+ try testStringify("", struct { a: ?i64, b: ?f64 }{ .a = null, .b = null });
+}
+
+test "stringify an optional" {
+ try testStringify("", null);
+ try testStringify("", @as(?u64, null));
+}
+
+test "stringify a union" {
+ const Dummy = union(enum) {
+ x: u64,
+ y: f64,
+ };
+ try testStringify("a: 1", struct { a: Dummy }{ .a = .{ .x = 1 } });
+ try testStringify("a: 2.1", struct { a: Dummy }{ .a = .{ .y = 2.1 } });
+}
+
+test "stringify a string" {
+ try testStringify("a: name", struct { a: []const u8 }{ .a = "name" });
+ try testStringify("name", "name");
+}
+
+test "stringify a list" {
+ try testStringify("[ 1, 2, 3 ]", @as([]const u64, &.{ 1, 2, 3 }));
+ try testStringify("[ 1, 2, 3 ]", .{ @as(i64, 1), 2, 3 });
+ try testStringify("[ 1, name, 3 ]", .{ 1, "name", 3 });
+
+ const arr: [3]i64 = .{ 1, 2, 3 };
+ try testStringify("[ 1, 2, 3 ]", arr);
+}