diff --git a/lib/libc/darwin/libSystem.13.tbd b/lib/libc/darwin/libSystem.13.tbd index 76e25874ae..d29feaa1e4 100644 --- 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 index c97332984f..98ee2ed5dd 100644 --- 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 index d28700a02c..df46bb7d83 100644 --- 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, + // zig fmt: off + eof, - NewLine, - DocStart, // --- - DocEnd, // ... - SeqItemInd, // - - MapValueInd, // : - FlowMapStart, // { - FlowMapEnd, // } - FlowSeqStart, // [ - FlowSeqEnd, // ] + 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, // ! - SingleQuote, // ' - DoubleQuote, // " + comma, + space, + tab, + comment, // # + alias, // * + anchor, // & + tag, // ! - Literal, + 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; }, }, - .Space => switch (c) { + + .comment => switch (c) { + '\r', '\n' => { + result.id = .comment; + break; + }, + else => {}, + }, + + .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; + else => {}, + }, - if (count.* == 3) { - result.id = .DocStart; + .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 => {}, }, - .Dot => |*count| switch (c) { - '.' => { - count.* += 1; - if (count.* == 3) { - result.id = .DocEnd; - self.index += 1; - break; - } - }, - else => { - state = .Literal; - }, - }, - .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 index eb7bb2a0cf..09774cf00a 100644 --- 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, }; + parser.eatCommentsAndSpace(&.{}); + while (true) { - if (parser.token_it.peek() == null) return; + parser.eatCommentsAndSpace(&.{}); + const token = parser.token_it.next() orelse break; - const pos = parser.token_it.pos; - const token = parser.token_it.next(); - - 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) begin {s}@{d}", .{ @tagName(self.tree.tokens[node.base.start].id), node.base.start }); - log.debug("Doc start: {}, {}", .{ start, self.tree.tokens[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(); + // 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); + }; - log.debug("Next token: {}, {}", .{ pos, token }); - - 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) begin {s}@{d}", .{ @tagName(self.tree.tokens[node.base.start].id), node.base.start }); - log.debug("Map start: {}, {}", .{ start, self.tree.tokens[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); + _ = try self.expectToken(.map_value_ind, &.{ .new_line, .comment }); - // Parse value. - const value: *Node = value: { - if (self.eatToken(.NewLine)) |_| { - self.eatCommentsAndSpace(); + // Parse value + const val = try self.value(); + errdefer if (val) |v| { + v.deinit(self.allocator); + self.allocator.destroy(v); + }; - // 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; - }, + 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) { + _ = self.eatToken(.seq_item_ind, &.{}) orelse break; + + const val = (try self.value()) orelse return error.MalformedYaml; + try node.values.append(self.allocator, val); + } + + node.base.end = self.token_it.pos - 1; + + log.debug("(list) end {s}@{d}", .{ @tagName(self.tree.tokens[node.base.end].id), node.base.end }); + + return &node.base; + } + + fn list_bracketed(self: *Parser) ParseError!*Node { + const node = try self.allocator.create(Node.List); + errdefer self.allocator.destroy(node); + 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); + } + + log.debug("(list) begin {s}@{d}", .{ @tagName(self.tree.tokens[node.base.start].id), node.base.start }); + + _ = try self.expectToken(.flow_seq_start, &.{}); + + while (true) { + self.eatCommentsAndSpace(&.{.comment}); + + if (self.eatToken(.flow_seq_end, &.{.comment})) |pos| { + node.base.end = pos; break; } - _ = self.eatToken(.SeqItemInd) orelse { - break; - }; + _ = self.eatToken(.comma, &.{.comment}); - 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; + log.debug("(list) end {s}@{d}", .{ @tagName(self.tree.tokens[node.base.end].id), node.base.end }); - log.debug("List end: {}, {}", .{ node.end.?, self.tree.tokens[node.end.?] }); - - return node; + return &node.base; } - fn list_bracketed(self: *Parser, start: TokenIndex) ParseError!*Node.List { - const node = try self.allocator.create(Node.List); - errdefer self.allocator.destroy(node); - node.* = .{ .start = start }; - node.base.tree = self.tree; - - self.token_it.seekTo(start); - - log.debug("List start: {}, {}", .{ start, self.tree.tokens[start] }); - - _ = try self.expectToken(.FlowSeqStart); - - while (true) { - _ = self.eatToken(.NewLine); - self.eatCommentsAndSpace(); - - const pos = self.token_it.pos; - const token = self.token_it.next(); - - log.debug("Next token: {}, {}", .{ pos, token }); - - 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); - } - - node.end = self.token_it.pos - 1; - - log.debug("List end: {}, {}", .{ node.end.?, self.tree.tokens[node.end.?] }); - - return node; - } - - 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; + node.base.start = self.token_it.pos; + errdefer node.string_value.deinit(self.allocator); - 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; - } + // 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 index b310a5c0bd..2906801f23 100644 --- 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], - )); + 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.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], - )); + 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], - )); + 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.start.?]; - try testing.expectEqual(nested_value_tok.id, .Literal); - try testing.expect(mem.eql( - u8, + 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], - )); + 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.start.?]; - try testing.expectEqual(nested_value_tok.id, .Literal); - try testing.expect(mem.eql( - u8, + 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])); + 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.start.?]; - try testing.expectEqual(value_tok.id, .Literal); - try testing.expect(mem.eql( - u8, - "value2", - 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("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 index d4136b35d3..0fc165003a 100644 --- 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; } + + 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"); + } }; +pub fn stringify(allocator: Allocator, input: anytype, writer: anytype) !void { + var arena = ArenaAllocator.init(allocator); + defer arena.deinit(); + + var maybe_value = try Value.encode(arena.allocator(), input); + + if (maybe_value) |value| { + // TODO should we output as an explicit doc? + // How can allow the user to specify? + try value.stringify(writer, .{}); + } +} + 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); - } -} - -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 - ; - - 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)); + 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 new file mode 100644 index 0000000000..8db9435885 --- /dev/null +++ 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); +}