diff --git a/Cargo.lock b/Cargo.lock index 9036c5d91..6b5902b3a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,9 +4,9 @@ version = 3 [[package]] name = "addr2line" -version = "0.16.0" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e61f2b7f93d2c7d2b08263acaa4a363b3e276806c68af6134c44f523bf1aacd" +checksum = "b9ecd88a8c8378ca913a680cd98f0f13ac67383d35993f86c90a70e3f137816b" dependencies = [ "gimli", ] @@ -28,24 +28,24 @@ dependencies = [ [[package]] name = "ansi_term" -version = "0.11.0" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" +checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" dependencies = [ "winapi 0.3.9", ] [[package]] name = "anyhow" -version = "1.0.44" +version = "1.0.51" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61604a8f862e1d5c3229fdd78f8b02c68dcf73a4c4b05fd636d12240aaa242c1" +checksum = "8b26702f315f53b6071259e15dd9d64528213b44d61de1ec926eca7715d62203" [[package]] name = "app_dirs2" -version = "2.3.2" +version = "2.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55db1808b75fbf537160a28c59f868018c480a9a7f05ab6d6a760cba7d4cd303" +checksum = "2dd95d9b31f552568dcad90bb809b795f63795fba32f733eb7435a4d13f5d28f" dependencies = [ "jni", "ndk-glue", @@ -72,9 +72,9 @@ checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" [[package]] name = "backtrace" -version = "0.3.61" +version = "0.3.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7a905d892734eea339e896738c14b9afce22b5318f64b951e70bf3844419b01" +checksum = "321629d8ba6513061f26707241fa9bc89524ff1cd7a915a97ef0c62c666ce1b6" dependencies = [ "addr2line", "cc", @@ -102,9 +102,9 @@ checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" [[package]] name = "bitflags" -version = "1.2.1" +version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "block-buffer" @@ -147,9 +147,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.7.1" +version = "3.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9df67f7bf9ef8498769f994239c45613ef0c5899415fb58e9add412d2c1a538" +checksum = "8f1e260c3a9040a7c19a12468758f4c16f31a81a1fe087482be9570ec864bb6c" [[package]] name = "byte-tools" @@ -159,9 +159,9 @@ checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7" [[package]] name = "byte-unit" -version = "4.0.12" +version = "4.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "063197e6eb4b775b64160dedde7a0986bb2836cce140e9492e9e96f28e18bcd8" +checksum = "956ffc5b0ec7d7a6949e3f21fd63ba5af4cffdc2ba1e0b7bf62b481458c4ae7f" dependencies = [ "utf8-width", ] @@ -191,9 +191,9 @@ checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8" [[package]] name = "cc" -version = "1.0.71" +version = "1.0.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79c2681d6594606957bbb8631c4b90a7fcaaa72cdb714743a437b156d6a7eedd" +checksum = "22a9137b95ea06864e018375b72adfb7db6e6f68cfc8df5a04d00288050485ee" [[package]] name = "cesu8" @@ -215,9 +215,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "clap" -version = "2.33.3" +version = "2.34.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002" +checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c" dependencies = [ "ansi_term", "atty", @@ -230,9 +230,9 @@ dependencies = [ [[package]] name = "clearscreen" -version = "1.0.7" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95325739f550f23c4695b87632378f3738c2e95095531f45dab316678e5a4310" +checksum = "a7ed49b0e894fe6264a58496c7ec4e9d3c46f66b59efae527cd5bee429d0a418" dependencies = [ "nix", "terminfo", @@ -252,9 +252,9 @@ dependencies = [ [[package]] name = "combine" -version = "4.6.1" +version = "4.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a909e4d93292cd8e9c42e189f61681eff9d67b6541f96b8a1a737f23737bd001" +checksum = "b2b2f5d0ee456f3928812dfc8c6d9a1d592b98678f6d56db9b0cd2b7bc6c8db5" dependencies = [ "bytes 1.1.0", "memchr", @@ -262,9 +262,9 @@ dependencies = [ [[package]] name = "command-group" -version = "1.0.6" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29033dd7a07be0c480c88ae8796b998d85fb2f8788c87687fff2d89af51f7da0" +checksum = "f7a8a86f409b4a59df3a3e4bee2de0b83f1755fdd2a25e3a9684c396fc4bed2c" dependencies = [ "nix", "winapi 0.3.9", @@ -272,9 +272,9 @@ dependencies = [ [[package]] name = "core-foundation" -version = "0.9.1" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a89e2ae426ea83155dccf10c0fa6b1463ef6d5fcb44cee0b224a408fa640a62" +checksum = "6888e10551bb93e424d8df1d07f1a8b4fceb0001a3a4b048bfc47554946f47b3" dependencies = [ "core-foundation-sys", "libc", @@ -282,9 +282,9 @@ dependencies = [ [[package]] name = "core-foundation-sys" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea221b5284a47e40033bf9b66f35f984ec0ea2931eb03505246cd27a963f981b" +checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" [[package]] name = "cpufeatures" @@ -297,9 +297,9 @@ dependencies = [ [[package]] name = "crc32fast" -version = "1.2.1" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81156fece84ab6a9f2afdb109ce3ae577e42b1228441eded99bd77f627953b1a" +checksum = "738c290dfaea84fc1ca15ad9c168d083b05a714e1efddd8edaab678dc28d2836" dependencies = [ "cfg-if 1.0.0", ] @@ -354,9 +354,9 @@ dependencies = [ [[package]] name = "curl" -version = "0.4.39" +version = "0.4.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aaa3b8db7f3341ddef15786d250106334d4a6c4b0ae4a46cd77082777d9849b9" +checksum = "1bc6d233563261f8db6ffb83bbaad5a73837a6e6b28868e926337ebbdece0be3" dependencies = [ "curl-sys", "libc", @@ -369,9 +369,9 @@ dependencies = [ [[package]] name = "curl-sys" -version = "0.4.49+curl-7.79.1" +version = "0.4.51+curl-7.80.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0f44960aea24a786a46907b8824ebc0e66ca06bf4e4978408c7499620343483" +checksum = "d130987e6a6a34fe0889e1083022fa48cd90e6709a84be3fb8dd95801de5af20" dependencies = [ "cc", "libc", @@ -522,6 +522,15 @@ dependencies = [ "dirs-sys", ] +[[package]] +name = "dirs" +version = "3.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30baa043103c9d0c2a57cf537cc2f35623889dc0d405e6c3cccfadbc81c71309" +dependencies = [ + "dirs-sys", +] + [[package]] name = "dirs-sys" version = "0.3.6" @@ -541,9 +550,9 @@ checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" [[package]] name = "encoding_rs" -version = "0.8.28" +version = "0.8.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80df024fbc5ac80f87dfef0d9f5209a252f2a497f7f42944cff24d8253cac065" +checksum = "a74ea89a0a1b98f6332de42c95baff457ada66d1cb4030f9ff151b2041a1c746" dependencies = [ "cfg-if 1.0.0", ] @@ -673,18 +682,18 @@ checksum = "3a471a38ef8ed83cd6e40aa59c1ffe17db6855c18e3604d9c4ed8c08ebc28678" [[package]] name = "futures-channel" -version = "0.3.17" +version = "0.3.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5da6ba8c3bb3c165d3c7319fc1cc8304facf1fb8db99c5de877183c08a273888" +checksum = "7fc8cd39e3dbf865f7340dce6a2d401d24fd37c6fe6c4f0ee0de8bfca2252d27" dependencies = [ "futures-core", ] [[package]] name = "futures-core" -version = "0.3.17" +version = "0.3.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88d1c26957f23603395cd326b0ffe64124b818f4449552f960d815cfba83a53d" +checksum = "629316e42fe7c2a0b9a65b47d159ceaa5453ab14e8f0a3c5eedbb8cd55b4a445" [[package]] name = "futures-cpupool" @@ -698,29 +707,28 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.17" +version = "0.3.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "522de2a0fe3e380f1bc577ba0474108faf3f6b18321dbf60b3b9c39a75073377" +checksum = "e481354db6b5c353246ccf6a728b0c5511d752c08da7260546fc0933869daa11" [[package]] name = "futures-sink" -version = "0.3.17" +version = "0.3.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36ea153c13024fe480590b3e3d4cad89a0cfacecc24577b68f86c6ced9c2bc11" +checksum = "996c6442437b62d21a32cd9906f9c41e7dc1e19a9579843fad948696769305af" [[package]] name = "futures-task" -version = "0.3.17" +version = "0.3.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d3d00f4eddb73e498a54394f228cd55853bdf059259e8e7bc6e69d408892e99" +checksum = "dabf1872aaab32c886832f2276d2f5399887e2bd613698a02359e4ea83f8de12" [[package]] name = "futures-util" -version = "0.3.17" +version = "0.3.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36568465210a3a6ee45e1f165136d68671471a501e632e9a98d96872222b5481" +checksum = "41d22213122356472061ac0f1ab2cee28d2bac8491410fd68c2af53d1cedb83e" dependencies = [ - "autocfg", "futures-core", "futures-io", "futures-task", @@ -773,9 +781,9 @@ dependencies = [ [[package]] name = "gimli" -version = "0.25.0" +version = "0.26.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0a01e0497841a3b2db4f8afa483cce65f7e96a3498bd6c541734792aeac8fe7" +checksum = "78cc372d058dcf6d5ecd98510e7fbc9e5aec4d21de70f65fea8fecebcd881bd4" [[package]] name = "glob" @@ -816,9 +824,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.3.6" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c06815895acec637cd6ed6e9662c935b866d20a106f8361892893a7d9234964" +checksum = "7fd819562fcebdac5afc5c113c3ec36f902840b70fd4fc458799c8ce4607ae55" dependencies = [ "bytes 1.1.0", "fnv", @@ -828,7 +836,7 @@ dependencies = [ "http 0.2.5", "indexmap", "slab", - "tokio 1.12.0", + "tokio 1.14.0", "tokio-util", "tracing", ] @@ -919,9 +927,9 @@ dependencies = [ [[package]] name = "http-body" -version = "0.4.3" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "399c583b2979440c60be0821a6199eca73bc3c8dcd9d070d75ac726e2c6186e5" +checksum = "1ff4f84919677303da5f147645dbea6b1881f368d03ac84e1dc09031ebd7b2c6" dependencies = [ "bytes 1.1.0", "http 0.2.5", @@ -936,9 +944,9 @@ checksum = "acd94fdbe1d4ff688b67b04eee2e17bd50995534a61539e45adfefb45e5e5503" [[package]] name = "httpdate" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6456b8a6c8f33fee7d958fcd1b60d55b11940a79e63ae87013e6d22e26034440" +checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" [[package]] name = "hyper" @@ -972,23 +980,23 @@ dependencies = [ [[package]] name = "hyper" -version = "0.14.13" +version = "0.14.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15d1cfb9e4f68655fa04c01f59edb405b6074a0f7118ea881e5026e4a1cd8593" +checksum = "436ec0091e4f20e655156a30a0df3770fe2900aa301e548e08446ec794b6953c" dependencies = [ "bytes 1.1.0", "futures-channel", "futures-core", "futures-util", - "h2 0.3.6", + "h2 0.3.7", "http 0.2.5", - "http-body 0.4.3", + "http-body 0.4.4", "httparse", "httpdate", "itoa", "pin-project-lite", "socket2", - "tokio 1.12.0", + "tokio 1.14.0", "tower-service", "tracing", "want 0.3.0", @@ -1001,9 +1009,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" dependencies = [ "bytes 1.1.0", - "hyper 0.14.13", + "hyper 0.14.15", "native-tls", - "tokio 1.12.0", + "tokio 1.14.0", "tokio-native-tls", ] @@ -1128,9 +1136,9 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "libc" -version = "0.2.103" +version = "0.2.109" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8f7255a17a627354f321ef0055d63b898c6fb27eff628af4d1b66b7331edf6" +checksum = "f98a04dce437184842841303488f70d0188c5f51437d2a834dc097eafa909a01" [[package]] name = "libz-sys" @@ -1202,9 +1210,9 @@ dependencies = [ [[package]] name = "memoffset" -version = "0.6.4" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59accc507f1338036a0477ef61afdae33cde60840f4dfe481319ce3ad116ddf9" +checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" dependencies = [ "autocfg", ] @@ -1215,6 +1223,12 @@ version = "0.3.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + [[package]] name = "miniz_oxide" version = "0.4.4" @@ -1246,9 +1260,9 @@ dependencies = [ [[package]] name = "mio" -version = "0.7.13" +version = "0.7.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c2bdb6314ec10835cd3293dd268473a835c02b7b352e788be788b3c6ca6bb16" +checksum = "8067b404fe97c70829f082dec8bcf4f71225d7eaea1d8645349cb76fa06205cc" dependencies = [ "libc", "log", @@ -1321,10 +1335,11 @@ dependencies = [ [[package]] name = "ndk" -version = "0.3.0" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8794322172319b972f528bf90c6b467be0079f1fa82780ffb431088e741a73ab" +checksum = "d64d6af06fde0e527b1ba5c7b79a6cc89cfc46325b0b2887dffe8f70197e0c3c" dependencies = [ + "bitflags", "jni-sys", "ndk-sys", "num_enum", @@ -1333,9 +1348,9 @@ dependencies = [ [[package]] name = "ndk-glue" -version = "0.3.0" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5caf0c24d51ac1c905c27d4eda4fa0635bbe0de596b8f79235e0b17a4d29385" +checksum = "d3e9e94628f24e7a3cb5b96a2dc5683acd9230bf11991c2a1677b87695138420" dependencies = [ "lazy_static", "libc", @@ -1360,9 +1375,9 @@ dependencies = [ [[package]] name = "ndk-sys" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c44922cb3dbb1c70b5e5f443d63b64363a898564d739ba5198e3a9138442868d" +checksum = "e1bcdd74c20ad5d95aacd60ef9ba40fdf77f767051040541df557b7a9b2a2121" [[package]] name = "net2" @@ -1377,15 +1392,15 @@ dependencies = [ [[package]] name = "nix" -version = "0.22.2" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3bb9a13fa32bc5aeb64150cd3f32d6cf4c748f8f8a417cce5d2eb976a8370ba" +checksum = "cf1e25ee6b412c2a1e3fcb6a4499a5c1bfe7f43e014bdce9a6b6666e5aa2d187" dependencies = [ "bitflags", "cc", "cfg-if 1.0.0", "libc", - "memoffset 0.6.4", + "memoffset 0.6.5", ] [[package]] @@ -1398,6 +1413,17 @@ dependencies = [ "version_check", ] +[[package]] +name = "nom" +version = "7.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b1d11e1ef389c76fe5b81bcaf2ea32cf88b62bc494e19f493d0b30e7a930109" +dependencies = [ + "memchr", + "minimal-lexical", + "version_check", +] + [[package]] name = "notify" version = "4.0.17" @@ -1459,9 +1485,9 @@ dependencies = [ [[package]] name = "object" -version = "0.26.2" +version = "0.27.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39f37e50073ccad23b6d09bcb5b263f4e76d3bb6038e4a3c08e52162ffa8abc2" +checksum = "67ac1d3f9a1d3616fd9a60c8d74296f22406a238b6a72f5cc1e6f314df4ffbf9" dependencies = [ "memchr", ] @@ -1496,9 +1522,9 @@ dependencies = [ [[package]] name = "openssl" -version = "0.10.36" +version = "0.10.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d9facdb76fec0b73c406f125d44d86fdad818d66fef0531eec9233ca425ff4a" +checksum = "0c7ae222234c30df141154f159066c5093ff73b63204dcda7121eb082fc56a95" dependencies = [ "bitflags", "cfg-if 1.0.0", @@ -1516,18 +1542,18 @@ checksum = "28988d872ab76095a6e6ac88d99b54fd267702734fd7ffe610ca27f533ddb95a" [[package]] name = "openssl-src" -version = "111.16.0+1.1.1l" +version = "300.0.2+3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ab2173f69416cf3ec12debb5823d244127d23a9b127d5a5189aa97c5fa2859f" +checksum = "14a760a11390b1a5daf72074d4f6ff1a6e772534ae191f999f57e9ee8146d1fb" dependencies = [ "cc", ] [[package]] name = "openssl-sys" -version = "0.9.67" +version = "0.9.71" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69df2d8dfc6ce3aaf44b40dec6f487d5a886516cf6879c49e98e0710f310a058" +checksum = "7df13d165e607909b363a4757a6f133f8a818a74e9d3a98d09c6128e15fa4c73" dependencies = [ "autocfg", "cc", @@ -1627,15 +1653,15 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "pkg-config" -version = "0.3.20" +version = "0.3.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c9b1041b4387893b91ee6746cddfc28516aff326a3519fb2adf820932c5e6cb" +checksum = "d1a3ea4f0dd7f1f3e512cf97bf100819aa547f36a6eccac8dbaae839eb92363e" [[package]] name = "ppv-lite86" -version = "0.2.10" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857" +checksum = "ed0cfbc8191465bed66e1718596ee0b0b35d5ee1f41c5df2189d0fe8bde535ba" [[package]] name = "proc-macro-crate" @@ -1682,9 +1708,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.29" +version = "1.0.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9f5105d4fdaab20335ca9565e106a5d9b82b6219b5ba735731124ac6711d23d" +checksum = "fb37d2df5df740e582f28f8560cf425f52bb267d872fe58358eadb554909f07a" dependencies = [ "unicode-xid", ] @@ -1851,9 +1877,9 @@ dependencies = [ [[package]] name = "reqwest" -version = "0.11.5" +version = "0.11.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51c732d463dd300362ffb44b7b125f299c23d2990411a4253824630ebc7467fb" +checksum = "07bea77bc708afa10e59905c3d4af7c8fd43c9214251673095ff8b14345fcbc5" dependencies = [ "base64 0.13.0", "bytes 1.1.0", @@ -1861,8 +1887,8 @@ dependencies = [ "futures-core", "futures-util", "http 0.2.5", - "http-body 0.4.3", - "hyper 0.14.13", + "http-body 0.4.4", + "hyper 0.14.15", "hyper-tls", "ipnet", "js-sys", @@ -1875,7 +1901,7 @@ dependencies = [ "serde", "serde_json", "serde_urlencoded", - "tokio 1.12.0", + "tokio 1.14.0", "tokio-native-tls", "url", "wasm-bindgen", @@ -1901,9 +1927,9 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.5" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" +checksum = "3c9613b5a66ab9ba26415184cfc41156594925a9cf3a2057e57f31ff145f6568" [[package]] name = "same-file" @@ -1932,9 +1958,9 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" [[package]] name = "security-framework" -version = "2.3.1" +version = "2.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23a2ac85147a3a11d77ecf1bc7166ec0b92febfa4461c37944e180f319ece467" +checksum = "525bc1abfda2e1998d152c45cf13e696f76d0a4972310b22fac1658b05df7c87" dependencies = [ "bitflags", "core-foundation", @@ -1990,9 +2016,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.68" +version = "1.0.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f690853975602e1bfe1ccbf50504d67174e3bcf340f23b5ea9992e0587a52d8" +checksum = "d0ffa0837f2dfa6fb90868c2b5468cad482e175f7dad97e7421951e663f2b527" dependencies = [ "itoa", "ryu", @@ -2044,9 +2070,9 @@ checksum = "533494a8f9b724d33625ab53c6c4800f7cc445895924a8ef649222dcb76e938b" [[package]] name = "slab" -version = "0.4.4" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c307a32c1c5c437f38c7fd45d753050587732ba8628319fbdf12a7e289ccc590" +checksum = "9def91fd1e018fe007022791f865d0ccc9b3a0d5001e01aabb8b40e46000afb5" [[package]] name = "smallvec" @@ -2096,9 +2122,9 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] name = "structopt" -version = "0.3.23" +version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf9d950ef167e25e0bdb073cf1d68e9ad2795ac826f2f3f59647817cf23c0bfa" +checksum = "40b9788f4202aa75c240ecc9c15c65185e6a39ccdeb0fd5d008b98825464c87c" dependencies = [ "clap", "lazy_static", @@ -2107,9 +2133,9 @@ dependencies = [ [[package]] name = "structopt-derive" -version = "0.4.16" +version = "0.4.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134d838a2c9943ac3125cf6df165eda53493451b719f3255b2a26b85f772d0ba" +checksum = "dcb5ae327f9cc13b68763b5749770cb9e048a99bd9dfdfa58d0cf05d5f64afe0" dependencies = [ "heck", "proc-macro-error", @@ -2120,9 +2146,9 @@ dependencies = [ [[package]] name = "syn" -version = "1.0.80" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d010a1623fbd906d51d650a9916aaefc05ffa0e4053ff7fe601167f3e715d194" +checksum = "8daf5dd0bb60cbd4137b1b587d2fc0ae729bc07cf01cd70b36a1ed5ade3b9d59" dependencies = [ "proc-macro2", "quote", @@ -2356,6 +2382,16 @@ dependencies = [ "clap", ] +[[package]] +name = "tectonic_xetex_format" +version = "0.0.0-dev.0" +dependencies = [ + "byteorder", + "clap", + "nom 7.1.0", + "tectonic_errors", +] + [[package]] name = "tectonic_xetex_layout" version = "0.0.0-dev.0" @@ -2399,9 +2435,9 @@ version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "76971977e6121664ec1b960d1313aacfa75642adc93b9d4d53b247bd4cb1747e" dependencies = [ - "dirs", + "dirs 2.0.2", "fnv", - "nom", + "nom 5.1.2", "phf", "phf_codegen", ] @@ -2447,9 +2483,9 @@ dependencies = [ [[package]] name = "tinyvec" -version = "1.5.0" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f83b2a3d4d9091d0abd7eba4dc2710b1718583bd4d8992e2190720ea38f391f7" +checksum = "2c1c1d5a42b6245520c249549ec267180beaffcc0615401ac8e31853d4b6d8d2" dependencies = [ "tinyvec_macros", ] @@ -2486,15 +2522,15 @@ dependencies = [ [[package]] name = "tokio" -version = "1.12.0" +version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2c2416fdedca8443ae44b4527de1ea633af61d8f7169ffa6e72c5b53d24efcc" +checksum = "70e992e41e0d2fb9f755b37446f20900f64446ef54874f40a60c78f021ac6144" dependencies = [ "autocfg", "bytes 1.1.0", "libc", "memchr", - "mio 0.7.13", + "mio 0.7.14", "num_cpus", "pin-project-lite", "winapi 0.3.9", @@ -2571,7 +2607,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f7d995660bd2b7f8c1568414c1126076c13fbb725c40112dc0120b78eb9b717b" dependencies = [ "native-tls", - "tokio 1.12.0", + "tokio 1.14.0", ] [[package]] @@ -2681,16 +2717,16 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.6.8" +version = "0.6.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08d3725d3efa29485e87311c5b699de63cde14b00ed4d256b8318aa30ca452cd" +checksum = "9e99e1983e5d376cd8eb4b66604d2e99e79f5bd988c3055891dcd8c9e2604cc0" dependencies = [ "bytes 1.1.0", "futures-core", "futures-sink", "log", "pin-project-lite", - "tokio 1.12.0", + "tokio 1.14.0", ] [[package]] @@ -3023,9 +3059,12 @@ dependencies = [ [[package]] name = "xdg" -version = "2.2.0" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d089681aa106a86fade1b0128fb5daf07d5867a509ab036d99988dec80429a57" +checksum = "3a23fe958c70412687039c86f578938b4a0bb50ec788e96bce4d6ab00ddd5803" +dependencies = [ + "dirs 3.0.2", +] [[package]] name = "zip" diff --git a/Cargo.toml b/Cargo.toml index 3606a3e87..95a9d3c1b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -45,6 +45,7 @@ members = [ "crates/pdf_io", "crates/status_base", "crates/xdv", + "crates/xetex_format", "crates/xetex_layout", ] diff --git a/crates/docmodel/src/document.rs b/crates/docmodel/src/document.rs index 0045d3e8d..d8a66de9c 100644 --- a/crates/docmodel/src/document.rs +++ b/crates/docmodel/src/document.rs @@ -117,7 +117,7 @@ impl Document { let outputs = self .outputs .values() - .map(|r| syntax::OutputProfile::from_runtime(r)) + .map(syntax::OutputProfile::from_runtime) .collect(); let doc = syntax::Document { diff --git a/crates/docmodel/src/workspace.rs b/crates/docmodel/src/workspace.rs index 40a1b8c42..38cc939fb 100644 --- a/crates/docmodel/src/workspace.rs +++ b/crates/docmodel/src/workspace.rs @@ -29,6 +29,7 @@ use crate::document::Document; #[derive(Debug)] pub struct Workspace { /// The root directory of the workspace. + #[allow(dead_code)] // We expect to use this eventually. root_dir: PathBuf, /// This workspace's document. In the future, there might be more than one. diff --git a/crates/engine_xetex/README.md b/crates/engine_xetex/README.md index 90dd69f79..3e49a4b3e 100644 --- a/crates/engine_xetex/README.md +++ b/crates/engine_xetex/README.md @@ -22,7 +22,7 @@ This crate provides the following [Cargo features][features]: the `tectonic_bridge_harfbuzz` dependency. -## Updating the generated header +## Updating the generated headers This crate exposes Rust functions to C/C++ code using a header file created by [cbindgen]. To update the header, run: @@ -32,3 +32,15 @@ This crate exposes Rust functions to C/C++ code using a header file created by ```sh cbindgen --output xetex/xetex_bindings.h ``` + +It also uses definitions generated by the `tectonic_xetex_format` introspection crate. To +update that header, run: + +```sh +cargo run -p tectonic_xetex_format --example emit >xetex/xetex_format.h +``` + +Note that this crate defines the format serial number that it implements (in +`tectonic_engine_xetex::FORMAT_SERIAL`) separately from the maximum serial +number supported by the introspection crate (in +`tectonic_xetex_format::LATEST_VERSION`). diff --git a/crates/engine_xetex/xetex/xetex-constants.h b/crates/engine_xetex/xetex/xetex-constants.h index 246ccd6df..4e7a6d3ca 100644 --- a/crates/engine_xetex/xetex/xetex-constants.h +++ b/crates/engine_xetex/xetex/xetex-constants.h @@ -27,12 +27,7 @@ #define NUMBER_USVS (BIGGEST_USV + 1) #define TOO_BIG_USV (BIGGEST_USV + 1) -/* Various buffer sizes */ - -#define HASH_SIZE 15000 /* max number of control sequences */ -#define HASH_PRIME 8501 /* "a prime number equal to about 85% of hash_size" */ - -#define MAX_FONT_MAX 9000 +/* Various buffer sizes not fixed in xetex_format.h */ #define NUMBER_MATH_FAMILIES 256 #define TEXT_SIZE 0 @@ -42,10 +37,6 @@ #define NUMBER_REGS 256 -/* the size of our main "mem" array, minus 1; classically this is - * configurable, but we hardcode it. */ -#define MEM_TOP 4999999 - /* fixed locations in the "mem" array */ #define PAGE_INS_HEAD MEM_TOP #define CONTRIB_HEAD (MEM_TOP - 1) @@ -63,13 +54,8 @@ #define BACKUP_HEAD (MEM_TOP - 13) #define PRE_ADJUST_HEAD (MEM_TOP - 14) -/* equivalents table offsets */ +/* equivalents table locations not detailed in xetex_format.h */ -#define ACTIVE_BASE 1 /* "region 1": active character equivalents */ -#define SINGLE_BASE (ACTIVE_BASE + NUMBER_USVS) -#define NULL_CS (SINGLE_BASE + NUMBER_USVS) -#define HASH_BASE (NULL_CS + 1) /* "region 2": hash table */ -#define FROZEN_CONTROL_SEQUENCE (HASH_BASE + HASH_SIZE) #define FROZEN_PROTECTION (FROZEN_CONTROL_SEQUENCE + 0) #define FROZEN_CR (FROZEN_CONTROL_SEQUENCE + 1) #define FROZEN_END_GROUP (FROZEN_CONTROL_SEQUENCE + 2) @@ -82,237 +68,32 @@ #define FROZEN_DONT_EXPAND (FROZEN_CONTROL_SEQUENCE + 9) #define FROZEN_SPECIAL (FROZEN_CONTROL_SEQUENCE + 10) #define FROZEN_PRIMITIVE (FROZEN_CONTROL_SEQUENCE + 11) -#define PRIM_SIZE 500 -#define FROZEN_NULL_FONT (FROZEN_CONTROL_SEQUENCE + 12 + PRIM_SIZE) + #define FONT_ID_BASE FROZEN_NULL_FONT /* nominally minus FONT_BASE, but that's 0 */ -#define UNDEFINED_CONTROL_SEQUENCE (FROZEN_NULL_FONT + MAX_FONT_MAX + 1) -#define PRIM_EQTB_BASE (FROZEN_PRIMITIVE + 1) - -#define GLUE_BASE (UNDEFINED_CONTROL_SEQUENCE + 1) /* "region 3": glue values */ - -#define GLUE_PAR__line_skip 0 -#define GLUE_PAR__baseline_skip 1 -#define GLUE_PAR__par_skip 2 -#define GLUE_PAR__above_display_skip 3 -#define GLUE_PAR__below_display_skip 4 -#define GLUE_PAR__above_display_short_skip 5 -#define GLUE_PAR__below_display_short_skip 6 -#define GLUE_PAR__left_skip 7 -#define GLUE_PAR__right_skip 8 -#define GLUE_PAR__top_skip 9 -#define GLUE_PAR__split_top_skip 10 -#define GLUE_PAR__tab_skip 11 -#define GLUE_PAR__space_skip 12 -#define GLUE_PAR__xspace_skip 13 -#define GLUE_PAR__par_fill_skip 14 -#define GLUE_PAR__xetex_linebreak_skip 15 -#define GLUE_PAR__thin_mu_skip 16 -#define GLUE_PAR__med_mu_skip 17 -#define GLUE_PAR__thick_mu_skip 18 -#define GLUE_PARS 19 - -#define GLUEPAR(X) (eqtb[GLUE_BASE + GLUE_PAR__##X].b32.s1) - -#define SKIP_BASE (GLUE_BASE + GLUE_PARS) -#define SKIP_REG(n) (eqtb[SKIP_BASE + (n)].b32.s1) -#define MU_SKIP_BASE (SKIP_BASE + NUMBER_REGS) +#define GLUEPAR(p) (eqtb[GLUE_BASE + GLUE_PAR__##p].b32.s1) +#define SKIP_REG(n) (eqtb[SKIP_BASE + (n)].b32.s1) #define MU_SKIP_REG(n) (eqtb[MU_SKIP_BASE + (n)].b32.s1) - -/* "region 4": local halfword values like baselineskip. Some of these are - * used as arguments to ASSIGN_TOKS, SET_SHAPE, etc. */ - -#define LOCAL_BASE (MU_SKIP_BASE + NUMBER_REGS) -#define LOCAL__par_shape 0 -#define LOCAL__output_routine 1 -#define LOCAL__every_par 2 -#define LOCAL__every_math 3 -#define LOCAL__every_display 4 -#define LOCAL__every_hbox 5 -#define LOCAL__every_vbox 6 -#define LOCAL__every_job 7 -#define LOCAL__every_cr 8 -#define LOCAL__err_help 9 -#define LOCAL__every_eof 10 -#define LOCAL__xetex_inter_char 11 -#define LOCAL__TectonicCodaTokens 12 -#define NUM_LOCALS 13 -#define LOCAL(n) (eqtb[LOCAL_BASE + LOCAL__##n].b32.s1) - -#define TOKS_BASE (LOCAL_BASE + NUM_LOCALS) +#define LOCAL(p) (eqtb[LOCAL_BASE + LOCAL__##p].b32.s1) #define TOKS_REG(n) (eqtb[TOKS_BASE + (n)].b32.s1) - -#define ETEX_PEN_BASE (TOKS_BASE + NUMBER_REGS) -#define INTER_LINE_PENALTIES_LOC (ETEX_PEN_BASE + 0) -#define CLUB_PENALTIES_LOC (ETEX_PEN_BASE + 1) -#define WIDOW_PENALTIES_LOC (ETEX_PEN_BASE + 2) -#define DISPLAY_WIDOW_PENALTIES_LOC (ETEX_PEN_BASE + 3) -#define ETEX_PENS (ETEX_PEN_BASE + 4) - -#define BOX_BASE ETEX_PENS +#define ETEX_PENALTIES_PAR(p) (eqtb[ETEX_PEN_BASE + ETEX_PENALTIES_PAR__##p].b32.s1) #define BOX_REG(n) (eqtb[BOX_BASE + (n)].b32.s1) - -#define CUR_FONT_LOC (BOX_BASE + NUMBER_REGS) -#define MATH_FONT_BASE (CUR_FONT_LOC + 1) #define MATH_FONT(n) (eqtb[MATH_FONT_BASE + (n)].b32.s1) - -#define CAT_CODE_BASE (MATH_FONT_BASE + NUMBER_MATH_FONTS) #define CAT_CODE(n) (eqtb[CAT_CODE_BASE + (n)].b32.s1) - -#define LC_CODE_BASE (CAT_CODE_BASE + NUMBER_USVS) #define LC_CODE(n) (eqtb[LC_CODE_BASE + (n)].b32.s1) - -#define UC_CODE_BASE (LC_CODE_BASE + NUMBER_USVS) #define UC_CODE(n) (eqtb[UC_CODE_BASE + (n)].b32.s1) - -#define SF_CODE_BASE (UC_CODE_BASE + NUMBER_USVS) #define SF_CODE(n) (eqtb[SF_CODE_BASE + (n)].b32.s1) - -#define MATH_CODE_BASE (SF_CODE_BASE + NUMBER_USVS) #define MATH_CODE(n) (eqtb[MATH_CODE_BASE + (n)].b32.s1) - -#define CHAR_SUB_CODE_BASE (MATH_CODE_BASE + NUMBER_USVS) #define CHAR_SUB_CODE(n) (eqtb[CHAR_SUB_CODE_BASE + (n)].b32.s1) - -/* "region 5": current fullword integers like hyphenation penalty */ - -#define INT_BASE (CHAR_SUB_CODE_BASE + NUMBER_USVS) - -#define INT_PAR__pretolerance 0 -#define INT_PAR__tolerance 1 -#define INT_PAR__line_penalty 2 -#define INT_PAR__hyphen_penalty 3 -#define INT_PAR__ex_hyphen_penalty 4 -#define INT_PAR__club_penalty 5 -#define INT_PAR__widow_penalty 6 -#define INT_PAR__display_widow_penalty 7 -#define INT_PAR__broken_penalty 8 -#define INT_PAR__bin_op_penalty 9 -#define INT_PAR__rel_penalty 10 -#define INT_PAR__pre_display_penalty 11 -#define INT_PAR__post_display_penalty 12 -#define INT_PAR__inter_line_penalty 13 -#define INT_PAR__double_hyphen_demerits 14 -#define INT_PAR__final_hyphen_demerits 15 -#define INT_PAR__adj_demerits 16 -#define INT_PAR__mag 17 -#define INT_PAR__delimiter_factor 18 -#define INT_PAR__looseness 19 -#define INT_PAR__time 20 -#define INT_PAR__day 21 -#define INT_PAR__month 22 -#define INT_PAR__year 23 -#define INT_PAR__show_box_breadth 24 -#define INT_PAR__show_box_depth 25 -#define INT_PAR__hbadness 26 -#define INT_PAR__vbadness 27 -#define INT_PAR__pausing 28 -#define INT_PAR__tracing_online 29 -#define INT_PAR__tracing_macros 30 -#define INT_PAR__tracing_stats 31 -#define INT_PAR__tracing_paragraphs 32 -#define INT_PAR__tracing_pages 33 -#define INT_PAR__tracing_output 34 -#define INT_PAR__tracing_lost_chars 35 -#define INT_PAR__tracing_commands 36 -#define INT_PAR__tracing_restores 37 -#define INT_PAR__uc_hyph 38 -#define INT_PAR__output_penalty 39 -#define INT_PAR__max_dead_cycles 40 -#define INT_PAR__hang_after 41 -#define INT_PAR__floating_penalty 42 -#define INT_PAR__global_defs 43 -#define INT_PAR__cur_fam 44 -#define INT_PAR__escape_char 45 -#define INT_PAR__default_hyphen_char 46 -#define INT_PAR__default_skew_char 47 -#define INT_PAR__end_line_char 48 -#define INT_PAR__new_line_char 49 -#define INT_PAR__language 50 -#define INT_PAR__left_hyphen_min 51 -#define INT_PAR__right_hyphen_min 52 -#define INT_PAR__holding_inserts 53 -#define INT_PAR__error_context_lines 54 -#define INT_PAR__char_sub_def_min 55 /* = TEX_INT_PARS = WEB2C_INT_BASE */ -#define INT_PAR__char_sub_def_max 56 -#define INT_PAR__tracing_char_sub_def 57 -#define INT_PAR__tracing_assigns 58 /* = WEB2C_INT_PARS = ETEX_INT_BASE */ -#define INT_PAR__tracing_groups 59 -#define INT_PAR__tracing_ifs 60 -#define INT_PAR__tracing_scan_tokens 61 -#define INT_PAR__tracing_nesting 62 -#define INT_PAR__pre_display_correction 63 -#define INT_PAR__last_line_fit 64 -#define INT_PAR__saving_vdiscards 65 -#define INT_PAR__saving_hyphs 66 -#define INT_PAR__suppress_fontnotfound_error 67 -#define INT_PAR__xetex_linebreak_locale 68 -#define INT_PAR__xetex_linebreak_penalty 69 -#define INT_PAR__xetex_protrude_chars 70 -#define INT_PAR__texxet 71 -#define INT_PAR__xetex_dash_break 72 -#define INT_PAR__xetex_upwards 73 -#define INT_PAR__xetex_use_glyph_metrics 74 -#define INT_PAR__xetex_inter_char_tokens 75 -#define INT_PAR__xetex_input_normalization 76 -#define INT_PAR__xetex_default_input_mode 77 -#define INT_PAR__xetex_default_input_encoding 78 -#define INT_PAR__xetex_tracing_fonts 79 -#define INT_PAR__xetex_interword_space_shaping 80 -#define INT_PAR__xetex_generate_actual_text 81 -#define INT_PAR__xetex_hyphenatable_length 82 -#define INT_PAR__synctex 83 -#define INT_PAR__pdfoutput 84 -#define INT_PARS 85 - -#define INTPAR(x) (eqtb[INT_BASE + INT_PAR__##x].b32.s1) - -#define COUNT_BASE (INT_BASE + INT_PARS) +#define INTPAR(n) (eqtb[INT_BASE + INT_PAR__##n].b32.s1) #define COUNT_REG(n) (eqtb[COUNT_BASE + (n)].b32.s1) - -#define DEL_CODE_BASE (COUNT_BASE + NUMBER_REGS) #define DEL_CODE(n) (eqtb[DEL_CODE_BASE + (n)].b32.s1) - -/* "region 6": current fullword dimensions like hsize */ - -#define DIMEN_BASE (DEL_CODE_BASE + NUMBER_USVS) - -#define DIMEN_PAR__par_indent 0 -#define DIMEN_PAR__math_surround 1 -#define DIMEN_PAR__line_skip_limit 2 -#define DIMEN_PAR__hsize 3 -#define DIMEN_PAR__vsize 4 -#define DIMEN_PAR__max_depth 5 -#define DIMEN_PAR__split_max_depth 6 -#define DIMEN_PAR__box_max_depth 7 -#define DIMEN_PAR__hfuzz 8 -#define DIMEN_PAR__vfuzz 9 -#define DIMEN_PAR__delimiter_shortfall 10 -#define DIMEN_PAR__null_delimiter_space 11 -#define DIMEN_PAR__script_space 12 -#define DIMEN_PAR__pre_display_size 13 -#define DIMEN_PAR__display_width 14 -#define DIMEN_PAR__display_indent 15 -#define DIMEN_PAR__overfull_rule 16 -#define DIMEN_PAR__hang_indent 17 -#define DIMEN_PAR__h_offset 18 -#define DIMEN_PAR__v_offset 19 -#define DIMEN_PAR__emergency_stretch 20 -#define DIMEN_PAR__pdf_page_width 21 -#define DIMEN_PAR__pdf_page_height 22 -#define DIMEN_PARS 23 - -#define DIMENPAR(x) (eqtb[DIMEN_BASE + DIMEN_PAR__##x].b32.s1) - -#define SCALED_BASE (DIMEN_BASE + DIMEN_PARS) +#define DIMENPAR(n) (eqtb[DIMEN_BASE + DIMEN_PAR__##n].b32.s1) #define SCALED_REG(n) (eqtb[SCALED_BASE + (n)].b32.s1) -#define EQTB_SIZE (SCALED_BASE + NUMBER_REGS - 1) - #define LEVEL_ZERO 0 /* "really" MIN_QUARTERWORD */ #define LEVEL_ONE 1 - /* SET_INTERACTION */ #define BATCH_MODE 0 #define NONSTOP_MODE 1 @@ -465,133 +246,11 @@ #define ALIGNING 4 #define ABSORBING 5 -/* commands */ +/* Special command breakpoints - these should probably get in the autogenerated header */ -#undef IGNORE /* Windows OS headers sometimes define this */ - -#define ESCAPE 0 -#define RELAX 0 /* = ESCAPE */ -#define LEFT_BRACE 1 -#define RIGHT_BRACE 2 -#define MATH_SHIFT 3 -#define TAB_MARK 4 -#define CAR_RET 5 -#define OUT_PARAM 5 /* = CAR_RET */ -#define MAC_PARAM 6 -#define SUP_MARK 7 -#define SUB_MARK 8 -#define IGNORE 9 -#define ENDV 9 /* = IGNORE */ -#define SPACER 10 -#define LETTER 11 -#define OTHER_CHAR 12 -#define ACTIVE_CHAR 13 -#define PAR_END 13 /* = ACTIVE_CHAR */ -#define MATCH 13 /* = ACTIVE_CHAR */ -#define COMMENT 14 -#define END_MATCH 14 /* = COMMENT */ -#define STOP 14 /* = COMMENT */ -#define INVALID_CHAR 15 -#define DELIM_NUM 15 /* = INVALID_CHAR */ -#define CHAR_NUM 16 -#define MATH_CHAR_NUM 17 -#define MARK 18 -#define XRAY 19 -#define MAKE_BOX 20 -#define HMOVE 21 -#define VMOVE 22 -#define UN_HBOX 23 -#define UN_VBOX 24 -#define REMOVE_ITEM 25 -#define HSKIP 26 -#define VSKIP 27 -#define MSKIP 28 -#define KERN 29 -#define MKERN 30 -#define LEADER_SHIP 31 -#define HALIGN 32 -#define VALIGN 33 -#define NO_ALIGN 34 -#define VRULE 35 -#define HRULE 36 -#define INSERT 37 -#define VADJUST 38 -#define IGNORE_SPACES 39 -#define AFTER_ASSIGNMENT 40 -#define AFTER_GROUP 41 -#define BREAK_PENALTY 42 -#define START_PAR 43 -#define ITAL_CORR 44 -#define ACCENT 45 -#define MATH_ACCENT 46 -#define DISCRETIONARY 47 -#define EQ_NO 48 -#define LEFT_RIGHT 49 -#define MATH_COMP 50 -#define LIMIT_SWITCH 51 -#define ABOVE 52 -#define MATH_STYLE 53 -#define MATH_CHOICE 54 -#define NON_SCRIPT 55 -#define VCENTER 56 -#define CASE_SHIFT 57 -#define MESSAGE 58 -#define EXTENSION 59 -#define IN_STREAM 60 -#define BEGIN_GROUP 61 -#define END_GROUP 62 -#define OMIT 63 -#define EX_SPACE 64 -#define NO_BOUNDARY 65 -#define RADICAL 66 -#define END_CS_NAME 67 -#define CHAR_GIVEN 68 -#define MIN_INTERNAL 68 -#define MATH_GIVEN 69 -#define XETEX_MATH_GIVEN 70 -#define LAST_ITEM 71 -#define MAX_NON_PREFIXED_COMMAND 71 -#define TOKS_REGISTER 72 -#define ASSIGN_TOKS 73 -#define ASSIGN_INT 74 -#define ASSIGN_DIMEN 75 -#define ASSIGN_GLUE 76 -#define ASSIGN_MU_GLUE 77 -#define ASSIGN_FONT_DIMEN 78 -#define ASSIGN_FONT_INT 79 -#define SET_AUX 80 -#define SET_PREV_GRAF 81 -#define SET_PAGE_DIMEN 82 -#define SET_PAGE_INT 83 -#define SET_BOX_DIMEN 84 -#define SET_SHAPE 85 -#define DEF_CODE 86 -#define XETEX_DEF_CODE 87 -#define DEF_FAMILY 88 -#define SET_FONT 89 -#define DEF_FONT 90 -#define MAX_INTERNAL 91 -#define REGISTER 91 -#define ADVANCE 92 -#define MULTIPLY 93 -#define DIVIDE 94 -#define PREFIX 95 -#define LET 96 -#define SHORTHAND_DEF 97 -#define READ_TO_CS 98 -#define DEF 99 -#define SET_BOX 100 -#define HYPH_DATA 101 -#define SET_INTERACTION 102 -#define EXPAND_AFTER 104 -#define NO_EXPAND 105 -#define INPUT 106 -#define IF_TEST 107 -#define FI_OR_ELSE 108 -#define CS_NAME 109 -#define CONVERT 110 -#define THE 111 -#define TOP_BOT_MARK 112 +#define MIN_INTERNAL CHAR_GIVEN /* = 68; first "internal" command that can be expanded by \the */ +#define MAX_NON_PREFIXED_COMMAND LAST_ITEM /* = 71; last command that can't be \global */ +#define MAX_INTERNAL REGISTER /* = 91; last "iternal" command that can be expanded by \the */ /* args to SET_BOX_DIMEN */ #define WIDTH_OFFSET 1 @@ -868,6 +527,9 @@ #define SET_GLYPHS 253 #define SET_TEXT_AND_GLYPHS 254 +#define VMODE 1 +#define HMODE 104 +#define MMODE 207 #define XETEX_INPUT_MODE_AUTO 0 #define XETEX_VERSION 0 @@ -891,7 +553,6 @@ #define SLANT_CODE 1 #define SPLIT_UP 1 #define STRETCHING 1 -#define VMODE 1 #define ACC_KERN 2 #define BOTTOM_ACC 2 #define CLOSED 2 @@ -911,7 +572,6 @@ #define MATH_TEXT_CHAR 4 #define RESTORE_SA 4 #define SPACE_SHRINK_CODE 4 -#define OUT_PARAM 5 #define TOK_VAL 5 #define X_HEIGHT_CODE 5 #define ACCENTBASEHEIGHT 6 @@ -922,16 +582,12 @@ #define MARK_VAL 7 #define SUP_MARK 7 #define VAR_FAM_CLASS 7 -#define IGNORE 9 #define SUBSCRIPTTOPMAX 9 #define NATIVE_GLYPH_INFO_SIZE 10 -#define ACTIVE_CHAR 13 #define CARRIAGE_RETURN 13 #define SUPERSCRIPTBOTTOMMIN 13 #define TOTAL_MATHEX_PARAMS 13 -#define COMMENT 14 #define HI_MEM_STAT_USAGE 15 -#define INVALID_CHAR 15 #define MAX_CHAR_CODE 15 #define SUBSUPERSCRIPTGAPMIN 15 #define SUPERSCRIPTBOTTOMMAXWITHSUBSCRIPT 16 @@ -950,20 +606,7 @@ #define COND_MATH_GLUE 98 #define MU_GLUE 99 #define MAX_COMMAND 102 -#define UNDEFINED_CS 103 -#define HMODE 104 -#define CALL 113 -#define LONG_CALL 114 -#define OUTER_CALL 115 -#define LONG_OUTER_CALL 116 -#define END_TEMPLATE 117 -#define DONT_EXPAND 118 -#define GLUE_REF 119 -#define SHAPE_REF 120 -#define BOX_REF 121 -#define DATA 122 #define DIMEN_VAL_LIMIT 128 -#define MMODE 207 #define BIGGEST_LANG 255 #define MU_VAL_LIMIT 256 #define TOO_BIG_LANG 256 @@ -1027,7 +670,6 @@ #define MARKS_CODE 5 - #define IGNORE_DEPTH -65536000 #define MIDDLE_NOAD 1 diff --git a/crates/engine_xetex/xetex/xetex-ini.c b/crates/engine_xetex/xetex/xetex-ini.c index bf1cd74a4..ecc950f7b 100644 --- a/crates/engine_xetex/xetex/xetex-ini.c +++ b/crates/engine_xetex/xetex/xetex-ini.c @@ -927,7 +927,7 @@ new_patterns(void) } done: /*:996*/ - if (INTPAR(saving_hyphs) > 0) { /*1643:*/ + if (INTPAR(saving_hyph_codes) > 0) { /*1643:*/ c = cur_lang; first_child = false; p = 0; @@ -1633,7 +1633,7 @@ prefixed_command(void) } else { e = true; } - } else if (cur_chr == LOCAL_BASE + LOCAL__xetex_inter_char) { + } else if (cur_chr == LOCAL_BASE + LOCAL__xetex_inter_char_toks) { scan_char_class_not_ignored(); cur_ptr = cur_val; scan_char_class_not_ignored(); @@ -1666,7 +1666,7 @@ prefixed_command(void) } else { q = mem[cur_chr + 1].b32.s1; } - } else if (cur_chr == LOCAL_BASE + LOCAL__xetex_inter_char) { + } else if (cur_chr == LOCAL_BASE + LOCAL__xetex_inter_char_toks) { scan_char_class_not_ignored(); cur_ptr = cur_val; scan_char_class_not_ignored(); @@ -3300,7 +3300,7 @@ initialize_more_initex_variables(void) eqtb[LOCAL_BASE + LOCAL__par_shape].b16.s1 = SHAPE_REF; eqtb[LOCAL_BASE + LOCAL__par_shape].b16.s0 = LEVEL_ONE; - for (k = ETEX_PEN_BASE; k <= ETEX_PENS - 1; k++) + for (k = ETEX_PEN_BASE; k <= NUM_ETEX_PENALTIES - 1; k++) eqtb[k] = eqtb[LOCAL_BASE + LOCAL__par_shape]; for (k = LOCAL_BASE + LOCAL__output_routine; k <= TOKS_BASE + NUMBER_REGS - 1; k++) @@ -3364,13 +3364,13 @@ initialize_more_initex_variables(void) INTPAR(tolerance) = 10000; INTPAR(hang_after) = 1; INTPAR(max_dead_cycles) = 25; - INTPAR(escape_char) = '\\' ; + INTPAR(escape_char) = '\\'; INTPAR(end_line_char) = CARRIAGE_RETURN; for (k = 0; k <= NUMBER_USVS - 1; k++) DEL_CODE(k) = -1; - DEL_CODE(46) = 0; + DEL_CODE(46 /* '.' */) = 0; for (k = DIMEN_BASE; k <= EQTB_SIZE; k++) eqtb[k].b32.s1 = 0; @@ -3379,12 +3379,6 @@ initialize_more_initex_variables(void) hash_used = FROZEN_CONTROL_SEQUENCE; hash_high = 0; cs_count = 0; - eqtb[FROZEN_DONT_EXPAND].b16.s1 = DONT_EXPAND; - hash[FROZEN_DONT_EXPAND].s1 = maketexstring("notexpanded:"); - eqtb[FROZEN_PRIMITIVE].b16.s1 = IGNORE_SPACES; - eqtb[FROZEN_PRIMITIVE].b32.s1 = 1; - eqtb[FROZEN_PRIMITIVE].b16.s0 = LEVEL_ONE; - hash[FROZEN_PRIMITIVE].s1 = maketexstring("primitive"); for (k = -(int32_t) TRIE_OP_SIZE; k <= TRIE_OP_SIZE; k++) TRIE_OP_HASH(k) = 0; @@ -3395,15 +3389,9 @@ initialize_more_initex_variables(void) max_op_used = MIN_TRIE_OP; trie_op_ptr = 0; trie_not_ready = true; - hash[FROZEN_PROTECTION].s1 = maketexstring("inaccessible"); format_ident = maketexstring(" (INITEX)"); - hash[END_WRITE].s1 = maketexstring("endwrite"); - eqtb[END_WRITE].b16.s0 = LEVEL_ONE; - eqtb[END_WRITE].b16.s1 = OUTER_CALL; - eqtb[END_WRITE].b32.s1 = TEX_NULL; - max_reg_num = 32767; max_reg_help_line = "A register number must be between 0 and 32767."; @@ -3418,459 +3406,64 @@ initialize_more_initex_variables(void) static void initialize_primitives(void) { + static xetex_format_primitive_def_t primitives[] = { XETEX_FORMAT_PRIMITIVE_INITIALIZERS }; + int i; no_new_control_sequence = false; first = 0; - primitive("lineskip", ASSIGN_GLUE, GLUE_BASE + GLUE_PAR__line_skip); - primitive("baselineskip", ASSIGN_GLUE, GLUE_BASE + GLUE_PAR__baseline_skip); - primitive("parskip", ASSIGN_GLUE, GLUE_BASE + GLUE_PAR__par_skip); - primitive("abovedisplayskip", ASSIGN_GLUE, GLUE_BASE + GLUE_PAR__above_display_skip); - primitive("belowdisplayskip", ASSIGN_GLUE, GLUE_BASE + GLUE_PAR__below_display_skip); - primitive("abovedisplayshortskip", ASSIGN_GLUE, GLUE_BASE + GLUE_PAR__above_display_short_skip); - primitive("belowdisplayshortskip", ASSIGN_GLUE, GLUE_BASE + GLUE_PAR__below_display_short_skip); - primitive("leftskip", ASSIGN_GLUE, GLUE_BASE + GLUE_PAR__left_skip); - primitive("rightskip", ASSIGN_GLUE, GLUE_BASE + GLUE_PAR__right_skip); - primitive("topskip", ASSIGN_GLUE, GLUE_BASE + GLUE_PAR__top_skip); - primitive("splittopskip", ASSIGN_GLUE, GLUE_BASE + GLUE_PAR__split_top_skip); - primitive("tabskip", ASSIGN_GLUE, GLUE_BASE + GLUE_PAR__tab_skip); - primitive("spaceskip", ASSIGN_GLUE, GLUE_BASE + GLUE_PAR__space_skip); - primitive("xspaceskip", ASSIGN_GLUE, GLUE_BASE + GLUE_PAR__xspace_skip); - primitive("parfillskip", ASSIGN_GLUE, GLUE_BASE + GLUE_PAR__par_fill_skip); - primitive("XeTeXlinebreakskip", ASSIGN_GLUE, GLUE_BASE + GLUE_PAR__xetex_linebreak_skip); - - primitive("thinmuskip", ASSIGN_MU_GLUE, GLUE_BASE + GLUE_PAR__thin_mu_skip); - primitive("medmuskip", ASSIGN_MU_GLUE, GLUE_BASE + GLUE_PAR__med_mu_skip); - primitive("thickmuskip", ASSIGN_MU_GLUE, GLUE_BASE + GLUE_PAR__thick_mu_skip); - - primitive("output", ASSIGN_TOKS, LOCAL_BASE + LOCAL__output_routine); - primitive("everypar", ASSIGN_TOKS, LOCAL_BASE + LOCAL__every_par); - primitive("everymath", ASSIGN_TOKS, LOCAL_BASE + LOCAL__every_math); - primitive("everydisplay", ASSIGN_TOKS, LOCAL_BASE + LOCAL__every_display); - primitive("everyhbox", ASSIGN_TOKS, LOCAL_BASE + LOCAL__every_hbox); - primitive("everyvbox", ASSIGN_TOKS, LOCAL_BASE + LOCAL__every_vbox); - primitive("everyjob", ASSIGN_TOKS, LOCAL_BASE + LOCAL__every_job); - primitive("everycr", ASSIGN_TOKS, LOCAL_BASE + LOCAL__every_cr); - primitive("errhelp", ASSIGN_TOKS, LOCAL_BASE + LOCAL__err_help); - primitive("everyeof", ASSIGN_TOKS, LOCAL_BASE + LOCAL__every_eof); - primitive("XeTeXinterchartoks", ASSIGN_TOKS, LOCAL_BASE + LOCAL__xetex_inter_char); - primitive("TectonicCodaTokens", ASSIGN_TOKS, LOCAL_BASE + LOCAL__TectonicCodaTokens); - - primitive("pretolerance", ASSIGN_INT, INT_BASE + INT_PAR__pretolerance); - primitive("tolerance", ASSIGN_INT, INT_BASE + INT_PAR__tolerance); - primitive("linepenalty", ASSIGN_INT, INT_BASE + INT_PAR__line_penalty); - primitive("hyphenpenalty", ASSIGN_INT, INT_BASE + INT_PAR__hyphen_penalty); - primitive("exhyphenpenalty", ASSIGN_INT, INT_BASE + INT_PAR__ex_hyphen_penalty); - primitive("clubpenalty", ASSIGN_INT, INT_BASE + INT_PAR__club_penalty); - primitive("widowpenalty", ASSIGN_INT, INT_BASE + INT_PAR__widow_penalty); - primitive("displaywidowpenalty", ASSIGN_INT, INT_BASE + INT_PAR__display_widow_penalty); - primitive("brokenpenalty", ASSIGN_INT, INT_BASE + INT_PAR__broken_penalty); - primitive("binoppenalty", ASSIGN_INT, INT_BASE + INT_PAR__bin_op_penalty); - primitive("relpenalty", ASSIGN_INT, INT_BASE + INT_PAR__rel_penalty); - primitive("predisplaypenalty", ASSIGN_INT, INT_BASE + INT_PAR__pre_display_penalty); - primitive("postdisplaypenalty", ASSIGN_INT, INT_BASE + INT_PAR__post_display_penalty); - primitive("interlinepenalty", ASSIGN_INT, INT_BASE + INT_PAR__inter_line_penalty); - primitive("doublehyphendemerits", ASSIGN_INT, INT_BASE + INT_PAR__double_hyphen_demerits); - primitive("finalhyphendemerits", ASSIGN_INT, INT_BASE + INT_PAR__final_hyphen_demerits); - primitive("adjdemerits", ASSIGN_INT, INT_BASE + INT_PAR__adj_demerits); - primitive("mag", ASSIGN_INT, INT_BASE + INT_PAR__mag); - primitive("delimiterfactor", ASSIGN_INT, INT_BASE + INT_PAR__delimiter_factor); - primitive("looseness", ASSIGN_INT, INT_BASE + INT_PAR__looseness); - primitive("time", ASSIGN_INT, INT_BASE + INT_PAR__time); - primitive("day", ASSIGN_INT, INT_BASE + INT_PAR__day); - primitive("month", ASSIGN_INT, INT_BASE + INT_PAR__month); - primitive("year", ASSIGN_INT, INT_BASE + INT_PAR__year); - primitive("showboxbreadth", ASSIGN_INT, INT_BASE + INT_PAR__show_box_breadth); - primitive("showboxdepth", ASSIGN_INT, INT_BASE + INT_PAR__show_box_depth); - primitive("hbadness", ASSIGN_INT, INT_BASE + INT_PAR__hbadness); - primitive("vbadness", ASSIGN_INT, INT_BASE + INT_PAR__vbadness); - primitive("pausing", ASSIGN_INT, INT_BASE + INT_PAR__pausing); - primitive("tracingonline", ASSIGN_INT, INT_BASE + INT_PAR__tracing_online); - primitive("tracingmacros", ASSIGN_INT, INT_BASE + INT_PAR__tracing_macros); - primitive("tracingstats", ASSIGN_INT, INT_BASE + INT_PAR__tracing_stats); - primitive("tracingparagraphs", ASSIGN_INT, INT_BASE + INT_PAR__tracing_paragraphs); - primitive("tracingpages", ASSIGN_INT, INT_BASE + INT_PAR__tracing_pages); - primitive("tracingoutput", ASSIGN_INT, INT_BASE + INT_PAR__tracing_output); - primitive("tracinglostchars", ASSIGN_INT, INT_BASE + INT_PAR__tracing_lost_chars); - primitive("tracingcommands", ASSIGN_INT, INT_BASE + INT_PAR__tracing_commands); - primitive("tracingrestores", ASSIGN_INT, INT_BASE + INT_PAR__tracing_restores); - primitive("uchyph", ASSIGN_INT, INT_BASE + INT_PAR__uc_hyph); - primitive("outputpenalty", ASSIGN_INT, INT_BASE + INT_PAR__output_penalty); - primitive("maxdeadcycles", ASSIGN_INT, INT_BASE + INT_PAR__max_dead_cycles); - primitive("hangafter", ASSIGN_INT, INT_BASE + INT_PAR__hang_after); - primitive("floatingpenalty", ASSIGN_INT, INT_BASE + INT_PAR__floating_penalty); - primitive("globaldefs", ASSIGN_INT, INT_BASE + INT_PAR__global_defs); - primitive("fam", ASSIGN_INT, INT_BASE + INT_PAR__cur_fam); - primitive("escapechar", ASSIGN_INT, INT_BASE + INT_PAR__escape_char); - primitive("defaulthyphenchar", ASSIGN_INT, INT_BASE + INT_PAR__default_hyphen_char); - primitive("defaultskewchar", ASSIGN_INT, INT_BASE + INT_PAR__default_skew_char); - primitive("endlinechar", ASSIGN_INT, INT_BASE + INT_PAR__end_line_char); - primitive("newlinechar", ASSIGN_INT, INT_BASE + INT_PAR__new_line_char); - primitive("language", ASSIGN_INT, INT_BASE + INT_PAR__language); - primitive("lefthyphenmin", ASSIGN_INT, INT_BASE + INT_PAR__left_hyphen_min); - primitive("righthyphenmin", ASSIGN_INT, INT_BASE + INT_PAR__right_hyphen_min); - primitive("holdinginserts", ASSIGN_INT, INT_BASE + INT_PAR__holding_inserts); - primitive("errorcontextlines", ASSIGN_INT, INT_BASE + INT_PAR__error_context_lines); - - primitive("XeTeXlinebreakpenalty", ASSIGN_INT, INT_BASE + 69); - primitive("XeTeXprotrudechars", ASSIGN_INT, INT_BASE + 70); - - primitive("parindent", ASSIGN_DIMEN, DIMEN_BASE + 0); - primitive("mathsurround", ASSIGN_DIMEN, DIMEN_BASE + 1); - primitive("lineskiplimit", ASSIGN_DIMEN, DIMEN_BASE + 2); - primitive("hsize", ASSIGN_DIMEN, DIMEN_BASE + 3); - primitive("vsize", ASSIGN_DIMEN, DIMEN_BASE + 4); - primitive("maxdepth", ASSIGN_DIMEN, DIMEN_BASE + 5); - primitive("splitmaxdepth", ASSIGN_DIMEN, DIMEN_BASE + 6); - primitive("boxmaxdepth", ASSIGN_DIMEN, DIMEN_BASE + 7); - primitive("hfuzz", ASSIGN_DIMEN, DIMEN_BASE + 8); - primitive("vfuzz", ASSIGN_DIMEN, DIMEN_BASE + 9); - primitive("delimitershortfall", ASSIGN_DIMEN, DIMEN_BASE + 10); - primitive("nulldelimiterspace", ASSIGN_DIMEN, DIMEN_BASE + 11); - primitive("scriptspace", ASSIGN_DIMEN, DIMEN_BASE + 12); - primitive("predisplaysize", ASSIGN_DIMEN, DIMEN_BASE + 13); - primitive("displaywidth", ASSIGN_DIMEN, DIMEN_BASE + 14); - primitive("displayindent", ASSIGN_DIMEN, DIMEN_BASE + 15); - primitive("overfullrule", ASSIGN_DIMEN, DIMEN_BASE + 16); - primitive("hangindent", ASSIGN_DIMEN, DIMEN_BASE + 17); - primitive("hoffset", ASSIGN_DIMEN, DIMEN_BASE + 18); - primitive("voffset", ASSIGN_DIMEN, DIMEN_BASE + 19); - primitive("emergencystretch", ASSIGN_DIMEN, DIMEN_BASE + 20); - primitive("pdfpagewidth", ASSIGN_DIMEN, DIMEN_BASE + 21); - primitive("pdfpageheight", ASSIGN_DIMEN, DIMEN_BASE + 22); - - primitive(" ", EX_SPACE, 0); - primitive("/", ITAL_CORR, 0); - primitive("accent", ACCENT, 0); - primitive("advance", ADVANCE, 0); - primitive("afterassignment", AFTER_ASSIGNMENT, 0); - primitive("aftergroup", AFTER_GROUP, 0); - primitive("begingroup", BEGIN_GROUP, 0); - primitive("char", CHAR_NUM, 0); - primitive("csname", CS_NAME, 0); - primitive("delimiter", DELIM_NUM, 0); - primitive("XeTeXdelimiter", DELIM_NUM, 1); - primitive("Udelimiter", DELIM_NUM, 1); - primitive("divide", DIVIDE, 0); - primitive("endcsname", END_CS_NAME, 0); - primitive("endgroup", END_GROUP, 0); - hash[FROZEN_END_GROUP].s1 = maketexstring("endgroup"); - eqtb[FROZEN_END_GROUP] = eqtb[cur_val]; - primitive("expandafter", EXPAND_AFTER, 0); - primitive("font", DEF_FONT, 0); - primitive("fontdimen", ASSIGN_FONT_DIMEN, 0); - primitive("halign", HALIGN, 0); - primitive("hrule", HRULE, 0); - primitive("ignorespaces", IGNORE_SPACES, 0); - primitive("insert", INSERT, 0); - primitive("mark", MARK, 0); - primitive("mathaccent", MATH_ACCENT, 0); - primitive("XeTeXmathaccent", MATH_ACCENT, 1); - primitive("Umathaccent", MATH_ACCENT, 1); - primitive("mathchar", MATH_CHAR_NUM, 0); - primitive("XeTeXmathcharnum", MATH_CHAR_NUM, 1); - primitive("Umathcharnum", MATH_CHAR_NUM, 1); - primitive("XeTeXmathchar", MATH_CHAR_NUM, 2); - primitive("Umathchar", MATH_CHAR_NUM, 2); - primitive("mathchoice", MATH_CHOICE, 0); - primitive("multiply", MULTIPLY, 0); - primitive("noalign", NO_ALIGN, 0); - primitive("noboundary", NO_BOUNDARY, 0); - primitive("noexpand", NO_EXPAND, 0); - primitive("primitive", NO_EXPAND, 1); - primitive("nonscript", NON_SCRIPT, 0); - primitive("omit", OMIT, 0); - primitive("parshape", SET_SHAPE, LOCAL_BASE + LOCAL__par_shape); - primitive("penalty", BREAK_PENALTY, 0); - primitive("prevgraf", SET_PREV_GRAF, 0); - primitive("radical", RADICAL, 0); - primitive("XeTeXradical", RADICAL, 1); - primitive("Uradical", RADICAL, 1); - primitive("read", READ_TO_CS, 0); - primitive("relax", RELAX, TOO_BIG_USV); - hash[FROZEN_RELAX].s1 = maketexstring("relax"); - eqtb[FROZEN_RELAX] = eqtb[cur_val]; - primitive("setbox", SET_BOX, 0); - primitive("the", THE, 0); - primitive("toks", TOKS_REGISTER, 0); - primitive("vadjust", VADJUST, 0); - primitive("valign", VALIGN, 0); - primitive("vcenter", VCENTER, 0); - primitive("vrule", VRULE, 0); - primitive("par", PAR_END, TOO_BIG_USV); - par_loc = cur_val; - par_token = CS_TOKEN_FLAG + par_loc; + for (i = 0; i < sizeof(primitives) / sizeof(primitives[0]); i++) { + xetex_format_primitive_def_t prim = primitives[i]; + + if (prim.name != NULL) { + primitive(prim.name, prim.cmd, prim.chr); + + switch (prim.extra_init) { + case xf_prim_init_none: + break; - primitive("input", INPUT, 0); - primitive("endinput", INPUT, 1); - - primitive("topmark", TOP_BOT_MARK, TOP_MARK_CODE); - primitive("firstmark", TOP_BOT_MARK, FIRST_MARK_CODE); - primitive("botmark", TOP_BOT_MARK, BOT_MARK_CODE); - primitive("splitfirstmark", TOP_BOT_MARK, SPLIT_FIRST_MARK_CODE); - primitive("splitbotmark", TOP_BOT_MARK, SPLIT_BOT_MARK_CODE); - - primitive("count", REGISTER, 0); - primitive("dimen", REGISTER, 1); - primitive("skip", REGISTER, 2); - primitive("muskip", REGISTER, 3); - - primitive("spacefactor", SET_AUX, HMODE); - primitive("prevdepth", SET_AUX, VMODE); - - primitive("deadcycles", SET_PAGE_INT, 0); - primitive("insertpenalties", SET_PAGE_INT, 1); - - primitive("wd", SET_BOX_DIMEN, WIDTH_OFFSET); - primitive("ht", SET_BOX_DIMEN, HEIGHT_OFFSET); - primitive("dp", SET_BOX_DIMEN, DEPTH_OFFSET); - - primitive("lastpenalty", LAST_ITEM, INT_VAL); - primitive("lastkern", LAST_ITEM, DIMEN_VAL); - primitive("lastskip", LAST_ITEM, GLUE_VAL); - primitive("inputlineno", LAST_ITEM, INPUT_LINE_NO_CODE); - primitive("badness", LAST_ITEM, BADNESS_CODE); - primitive("pdflastxpos", LAST_ITEM, PDF_LAST_X_POS_CODE); - primitive("pdflastypos", LAST_ITEM, PDF_LAST_Y_POS_CODE); - primitive("elapsedtime", LAST_ITEM, ELAPSED_TIME_CODE); - primitive("shellescape", LAST_ITEM, PDF_SHELL_ESCAPE_CODE); - primitive("randomseed", LAST_ITEM, RANDOM_SEED_CODE); - - primitive("number", CONVERT, NUMBER_CODE); - primitive("romannumeral", CONVERT, ROMAN_NUMERAL_CODE); - primitive("string", CONVERT, STRING_CODE); - primitive("meaning", CONVERT, MEANING_CODE); - primitive("fontname", CONVERT, FONT_NAME_CODE); - primitive("expanded", CONVERT, EXPANDED_CODE); - primitive("leftmarginkern", CONVERT, LEFT_MARGIN_KERN_CODE); - primitive("rightmarginkern", CONVERT, RIGHT_MARGIN_KERN_CODE); - primitive("creationdate", CONVERT, PDF_CREATION_DATE_CODE); - primitive("filemoddate", CONVERT, PDF_FILE_MOD_DATE_CODE); - primitive("filesize", CONVERT, PDF_FILE_SIZE_CODE); - primitive("mdfivesum", CONVERT, PDF_MDFIVE_SUM_CODE); - primitive("filedump", CONVERT, PDF_FILE_DUMP_CODE); - primitive("strcmp", CONVERT, PDF_STRCMP_CODE); - primitive("uniformdeviate", CONVERT, UNIFORM_DEVIATE_CODE); - primitive("normaldeviate", CONVERT, NORMAL_DEVIATE_CODE); - primitive("jobname", CONVERT, JOB_NAME_CODE); - primitive("Uchar", CONVERT, XETEX_UCHAR_CODE); - primitive("Ucharcat", CONVERT, XETEX_UCHARCAT_CODE); - - primitive("if", IF_TEST, IF_CHAR_CODE); - primitive("ifcat", IF_TEST, IF_CAT_CODE); - primitive("ifnum", IF_TEST, IF_INT_CODE); - primitive("ifdim", IF_TEST, IF_DIM_CODE); - primitive("ifodd", IF_TEST, IF_ODD_CODE); - primitive("ifvmode", IF_TEST, IF_VMODE_CODE); - primitive("ifhmode", IF_TEST, IF_HMODE_CODE); - primitive("ifmmode", IF_TEST, IF_MMODE_CODE); - primitive("ifinner", IF_TEST, IF_INNER_CODE); - primitive("ifvoid", IF_TEST, IF_VOID_CODE); - primitive("ifhbox", IF_TEST, IF_HBOX_CODE); - primitive("ifvbox", IF_TEST, IF_VBOX_CODE); - primitive("ifx", IF_TEST, IFX_CODE); - primitive("ifeof", IF_TEST, IF_EOF_CODE); - primitive("iftrue", IF_TEST, IF_TRUE_CODE); - primitive("iffalse", IF_TEST, IF_FALSE_CODE); - primitive("ifcase", IF_TEST, IF_CASE_CODE); - primitive("ifprimitive", IF_TEST, IF_PRIMITIVE_CODE); - - primitive("fi", FI_OR_ELSE, FI_CODE); - hash[FROZEN_FI].s1 = maketexstring("fi"); - eqtb[FROZEN_FI] = eqtb[cur_val]; - primitive("or", FI_OR_ELSE, OR_CODE); - primitive("else", FI_OR_ELSE, ELSE_CODE); - - primitive("nullfont", SET_FONT, FONT_BASE); - hash[FROZEN_NULL_FONT].s1 = maketexstring("nullfont"); - eqtb[FROZEN_NULL_FONT] = eqtb[cur_val]; - - primitive("span", TAB_MARK, SPAN_CODE); - primitive("cr", CAR_RET, CR_CODE); - hash[FROZEN_CR].s1 = maketexstring("cr"); - eqtb[FROZEN_CR] = eqtb[cur_val]; - primitive("crcr", CAR_RET, CR_CR_CODE); + case xf_prim_init_par: + par_loc = cur_val; + par_token = CS_TOKEN_FLAG + par_loc; + break; + + case xf_prim_init_write: + write_loc = cur_val; + break; + + default: + /* A "frozen" primitive */ + hash[prim.extra_init].s1 = maketexstring(prim.name); + eqtb[prim.extra_init] = eqtb[cur_val]; + break; + } + } + } hash[FROZEN_END_TEMPLATE].s1 = maketexstring("endtemplate"); + eqtb[FROZEN_END_TEMPLATE].b16.s1 = END_TEMPLATE; + eqtb[FROZEN_END_TEMPLATE].b32.s1 = NULL_LIST; + eqtb[FROZEN_END_TEMPLATE].b16.s0 = LEVEL_ONE; + hash[FROZEN_ENDV].s1 = maketexstring("endtemplate"); eqtb[FROZEN_ENDV].b16.s1 = ENDV; eqtb[FROZEN_ENDV].b32.s1 = NULL_LIST; eqtb[FROZEN_ENDV].b16.s0 = LEVEL_ONE; - eqtb[FROZEN_END_TEMPLATE] = eqtb[FROZEN_ENDV]; - eqtb[FROZEN_END_TEMPLATE].b16.s1 = END_TEMPLATE; - primitive("pagegoal", SET_PAGE_DIMEN, 0); - primitive("pagetotal", SET_PAGE_DIMEN, 1); - primitive("pagestretch", SET_PAGE_DIMEN, 2); - primitive("pagefilstretch", SET_PAGE_DIMEN, 3); - primitive("pagefillstretch", SET_PAGE_DIMEN, 4); - primitive("pagefilllstretch", SET_PAGE_DIMEN, 5); - primitive("pageshrink", SET_PAGE_DIMEN, 6); - primitive("pagedepth", SET_PAGE_DIMEN, 7); - - primitive("end", STOP, 0); - primitive("dump", STOP, 1); - - primitive("hskip", HSKIP, SKIP_CODE); - primitive("hfil", HSKIP, FIL_CODE); - primitive("hfill", HSKIP, FILL_CODE); - primitive("hss", HSKIP, SS_CODE); - primitive("hfilneg", HSKIP, FIL_NEG_CODE); - primitive("vskip", VSKIP, SKIP_CODE); - primitive("vfil", VSKIP, FIL_CODE); - primitive("vfill", VSKIP, FILL_CODE); - primitive("vss", VSKIP, SS_CODE); - primitive("vfilneg", VSKIP, FIL_NEG_CODE); - primitive("mskip", MSKIP, MSKIP_CODE); - - primitive("kern", KERN, EXPLICIT); - primitive("mkern", MKERN, MU_GLUE); - primitive("moveleft", HMOVE, 1); - primitive("moveright", HMOVE, 0); - primitive("raise", VMOVE, 1); - primitive("lower", VMOVE, 0); - - primitive("box", MAKE_BOX, BOX_CODE); - primitive("copy", MAKE_BOX, COPY_CODE); - primitive("lastbox", MAKE_BOX, LAST_BOX_CODE); - primitive("vsplit", MAKE_BOX, VSPLIT_CODE); - primitive("vtop", MAKE_BOX, VTOP_CODE); - primitive("vbox", MAKE_BOX, VTOP_CODE + 1); - primitive("hbox", MAKE_BOX, VTOP_CODE + 104); - - primitive("shipout", LEADER_SHIP, A_LEADERS - 1); - primitive("leaders", LEADER_SHIP, A_LEADERS); - primitive("cleaders", LEADER_SHIP, C_LEADERS); - primitive("xleaders", LEADER_SHIP, X_LEADERS); - - primitive("indent", START_PAR, 1); - primitive("noindent", START_PAR, 0); - primitive("unpenalty", REMOVE_ITEM, PENALTY_NODE); - primitive("unkern", REMOVE_ITEM, KERN_NODE); - primitive("unskip", REMOVE_ITEM, GLUE_NODE); - primitive("unhbox", UN_HBOX, BOX_CODE); - primitive("unhcopy", UN_HBOX, COPY_CODE); - primitive("unvbox", UN_VBOX, BOX_CODE); - primitive("unvcopy", UN_VBOX, COPY_CODE); - - primitive("-", DISCRETIONARY, 1); - primitive("discretionary", DISCRETIONARY, 0); - - primitive("eqno", EQ_NO, 0); - primitive("leqno", EQ_NO, 1); - - primitive("mathord", MATH_COMP, ORD_NOAD); - primitive("mathop", MATH_COMP, OP_NOAD); - primitive("mathbin", MATH_COMP, BIN_NOAD); - primitive("mathrel", MATH_COMP, REL_NOAD); - primitive("mathopen", MATH_COMP, OPEN_NOAD); - primitive("mathclose", MATH_COMP, CLOSE_NOAD); - primitive("mathpunct", MATH_COMP, PUNCT_NOAD); - primitive("mathinner", MATH_COMP, INNER_NOAD); - primitive("underline", MATH_COMP, UNDER_NOAD); - primitive("overline", MATH_COMP, OVER_NOAD); - - primitive("displaylimits", LIMIT_SWITCH, NORMAL); - primitive("limits", LIMIT_SWITCH, LIMITS); - primitive("nolimits", LIMIT_SWITCH, NO_LIMITS); - - primitive("displaystyle", MATH_STYLE, DISPLAY_STYLE); - primitive("textstyle", MATH_STYLE, TEXT_STYLE); - primitive("scriptstyle", MATH_STYLE, SCRIPT_STYLE); - primitive("scriptscriptstyle", MATH_STYLE, SCRIPT_SCRIPT_STYLE); - - primitive("above", ABOVE, ABOVE_CODE); - primitive("over", ABOVE, OVER_CODE); - primitive("atop", ABOVE, ATOP_CODE); - primitive("abovewithdelims", ABOVE, DELIMITED_CODE + 0); - primitive("overwithdelims", ABOVE, DELIMITED_CODE + 1); - primitive("atopwithdelims", ABOVE, DELIMITED_CODE + 2); - - primitive("left", LEFT_RIGHT, LEFT_NOAD); - primitive("right", LEFT_RIGHT, RIGHT_NOAD); - hash[FROZEN_RIGHT].s1 = maketexstring("right"); - eqtb[FROZEN_RIGHT] = eqtb[cur_val]; - - primitive("long", PREFIX, 1); - primitive("outer", PREFIX, 2); - primitive("global", PREFIX, 4); - primitive("def", DEF, 0); - primitive("gdef", DEF, 1); - primitive("edef", DEF, 2); - primitive("xdef", DEF, 3); - primitive("let", LET, NORMAL); - primitive("futurelet", LET, NORMAL + 1); - - primitive("chardef", SHORTHAND_DEF, CHAR_DEF_CODE); - primitive("mathchardef", SHORTHAND_DEF, MATH_CHAR_DEF_CODE); - primitive("XeTeXmathcharnumdef", SHORTHAND_DEF, XETEX_MATH_CHAR_NUM_DEF_CODE); - primitive("Umathcharnumdef", SHORTHAND_DEF, XETEX_MATH_CHAR_NUM_DEF_CODE); - primitive("XeTeXmathchardef", SHORTHAND_DEF, XETEX_MATH_CHAR_DEF_CODE); - primitive("Umathchardef", SHORTHAND_DEF, XETEX_MATH_CHAR_DEF_CODE); - primitive("countdef", SHORTHAND_DEF, COUNT_DEF_CODE); - primitive("dimendef", SHORTHAND_DEF, DIMEN_DEF_CODE); - primitive("skipdef", SHORTHAND_DEF, SKIP_DEF_CODE); - primitive("muskipdef", SHORTHAND_DEF, MU_SKIP_DEF_CODE); - primitive("toksdef", SHORTHAND_DEF, TOKS_DEF_CODE); - - primitive("catcode", DEF_CODE, CAT_CODE_BASE); - primitive("mathcode", DEF_CODE, MATH_CODE_BASE); - primitive("XeTeXmathcodenum", XETEX_DEF_CODE, MATH_CODE_BASE); - primitive("Umathcodenum", XETEX_DEF_CODE, MATH_CODE_BASE); - primitive("XeTeXmathcode", XETEX_DEF_CODE, MATH_CODE_BASE + 1); - primitive("Umathcode", XETEX_DEF_CODE, MATH_CODE_BASE + 1); - primitive("lccode", DEF_CODE, LC_CODE_BASE); - primitive("uccode", DEF_CODE, UC_CODE_BASE); - primitive("sfcode", DEF_CODE, SF_CODE_BASE); - primitive("XeTeXcharclass", XETEX_DEF_CODE, SF_CODE_BASE); - primitive("delcode", DEF_CODE, DEL_CODE_BASE); - primitive("XeTeXdelcodenum", XETEX_DEF_CODE, DEL_CODE_BASE); - primitive("Udelcodenum", XETEX_DEF_CODE, DEL_CODE_BASE); - primitive("XeTeXdelcode", XETEX_DEF_CODE, DEL_CODE_BASE + 1); - primitive("Udelcode", XETEX_DEF_CODE, DEL_CODE_BASE + 1); - - primitive("textfont", DEF_FAMILY, MATH_FONT_BASE + TEXT_SIZE); - primitive("scriptfont", DEF_FAMILY, MATH_FONT_BASE + SCRIPT_SIZE); - primitive("scriptscriptfont", DEF_FAMILY, MATH_FONT_BASE + SCRIPT_SCRIPT_SIZE); - - primitive("hyphenation", HYPH_DATA, 0); - primitive("patterns", HYPH_DATA, 1); - - primitive("hyphenchar", ASSIGN_FONT_INT, 0); - primitive("skewchar", ASSIGN_FONT_INT, 1); - primitive("lpcode", ASSIGN_FONT_INT, 2); - primitive("rpcode", ASSIGN_FONT_INT, 3); - - primitive("batchmode", SET_INTERACTION, BATCH_MODE); - primitive("nonstopmode", SET_INTERACTION, NONSTOP_MODE); - primitive("scrollmode", SET_INTERACTION, SCROLL_MODE); - primitive("errorstopmode", SET_INTERACTION, ERROR_STOP_MODE); - - primitive("openin", IN_STREAM, 1); - primitive("closein", IN_STREAM, 0); - primitive("message", MESSAGE, 0); - primitive("errmessage", MESSAGE, 1); - primitive("lowercase", CASE_SHIFT, LC_CODE_BASE); - primitive("uppercase", CASE_SHIFT, UC_CODE_BASE); - - primitive("show", XRAY, SHOW_CODE); - primitive("showbox", XRAY, SHOW_BOX_CODE); - primitive("showthe", XRAY, SHOW_THE_CODE); - primitive("showlists", XRAY, SHOW_LISTS); - - primitive("openout", EXTENSION, OPEN_NODE); - primitive("write", EXTENSION, WRITE_NODE); - write_loc = cur_val; - primitive("closeout", EXTENSION, CLOSE_NODE); - primitive("special", EXTENSION, SPECIAL_NODE); - hash[FROZEN_SPECIAL].s1 = maketexstring("special"); - eqtb[FROZEN_SPECIAL] = eqtb[cur_val]; - primitive("immediate", EXTENSION, IMMEDIATE_CODE); - primitive("setlanguage", EXTENSION, SET_LANGUAGE_CODE); - primitive("resettimer", EXTENSION, RESET_TIMER_CODE); - primitive("setrandomseed", EXTENSION, SET_RANDOM_SEED_CODE); - - primitive("synctex", ASSIGN_INT, INT_BASE + INT_PAR__synctex); + hash[FROZEN_DONT_EXPAND].s1 = maketexstring("notexpanded:"); + eqtb[FROZEN_DONT_EXPAND].b16.s1 = DONT_EXPAND; + + hash[FROZEN_PRIMITIVE].s1 = maketexstring("primitive"); + eqtb[FROZEN_PRIMITIVE].b16.s1 = IGNORE_SPACES; + eqtb[FROZEN_PRIMITIVE].b32.s1 = 1; + eqtb[FROZEN_PRIMITIVE].b16.s0 = LEVEL_ONE; + + hash[FROZEN_PROTECTION].s1 = maketexstring("inaccessible"); + + hash[END_WRITE].s1 = maketexstring("endwrite"); + eqtb[END_WRITE].b16.s0 = LEVEL_ONE; + eqtb[END_WRITE].b16.s1 = OUTER_CALL; + eqtb[END_WRITE].b32.s1 = TEX_NULL; no_new_control_sequence = true; } @@ -4166,154 +3759,6 @@ tt_run_engine(const char *dump_name, const char *input_file_name, time_t build_d if (in_initex_mode) { no_new_control_sequence = false; - - primitive("XeTeXpicfile", EXTENSION, PIC_FILE_CODE); - primitive("XeTeXpdffile", EXTENSION, PDF_FILE_CODE); - primitive("XeTeXglyph", EXTENSION, GLYPH_CODE); - primitive("XeTeXlinebreaklocale", EXTENSION, XETEX_LINEBREAK_LOCALE_EXTENSION_CODE); - primitive("pdfsavepos", EXTENSION, PDF_SAVE_POS_NODE); - - primitive("lastnodetype", LAST_ITEM, LAST_NODE_TYPE_CODE); - primitive("eTeXversion", LAST_ITEM, ETEX_VERSION_CODE); - - primitive("eTeXrevision", CONVERT, ETEX_REVISION_CODE); - - primitive("XeTeXversion", LAST_ITEM, XETEX_VERSION_CODE); - - primitive("XeTeXrevision", CONVERT, XETEX_REVISION_CODE); - - primitive("XeTeXcountglyphs", LAST_ITEM, XETEX_COUNT_GLYPHS_CODE); - primitive("XeTeXcountvariations", LAST_ITEM, XETEX_COUNT_VARIATIONS_CODE); - primitive("XeTeXvariation", LAST_ITEM, XETEX_VARIATION_CODE); - primitive("XeTeXfindvariationbyname", LAST_ITEM, XETEX_FIND_VARIATION_BY_NAME_CODE); - primitive("XeTeXvariationmin", LAST_ITEM, XETEX_VARIATION_MIN_CODE); - primitive("XeTeXvariationmax", LAST_ITEM, XETEX_VARIATION_MAX_CODE); - primitive("XeTeXvariationdefault", LAST_ITEM, XETEX_VARIATION_DEFAULT_CODE); - primitive("XeTeXcountfeatures", LAST_ITEM, XETEX_COUNT_FEATURES_CODE); - primitive("XeTeXfeaturecode", LAST_ITEM, XETEX_FEATURE_CODE_CODE); - primitive("XeTeXfindfeaturebyname", LAST_ITEM, XETEX_FIND_FEATURE_BY_NAME_CODE); - primitive("XeTeXisexclusivefeature", LAST_ITEM, XETEX_IS_EXCLUSIVE_FEATURE_CODE); - primitive("XeTeXcountselectors", LAST_ITEM, XETEX_COUNT_SELECTORS_CODE); - primitive("XeTeXselectorcode", LAST_ITEM, XETEX_SELECTOR_CODE_CODE); - primitive("XeTeXfindselectorbyname", LAST_ITEM, XETEX_FIND_SELECTOR_BY_NAME_CODE); - primitive("XeTeXisdefaultselector", LAST_ITEM, XETEX_IS_DEFAULT_SELECTOR_CODE); - - primitive("XeTeXvariationname", CONVERT, XETEX_VARIATION_NAME_CODE); - primitive("XeTeXfeaturename", CONVERT, XETEX_FEATURE_NAME_CODE); - primitive("XeTeXselectorname", CONVERT, XETEX_SELECTOR_NAME_CODE); - - primitive("XeTeXOTcountscripts", LAST_ITEM, XETEX_OT_COUNT_SCRIPTS_CODE); - primitive("XeTeXOTcountlanguages", LAST_ITEM, XETEX_OT_COUNT_LANGUAGES_CODE); - primitive("XeTeXOTcountfeatures", LAST_ITEM, XETEX_OT_COUNT_FEATURES_CODE); - primitive("XeTeXOTscripttag", LAST_ITEM, XETEX_OT_SCRIPT_CODE); - primitive("XeTeXOTlanguagetag", LAST_ITEM, XETEX_OT_LANGUAGE_CODE); - primitive("XeTeXOTfeaturetag", LAST_ITEM, XETEX_OT_FEATURE_CODE); - primitive("XeTeXcharglyph", LAST_ITEM, XETEX_MAP_CHAR_TO_GLYPH_CODE); - primitive("XeTeXglyphindex", LAST_ITEM, XETEX_GLYPH_INDEX_CODE); - primitive("XeTeXglyphbounds", LAST_ITEM, XETEX_GLYPH_BOUNDS_CODE); - - primitive("XeTeXglyphname", CONVERT, XETEX_GLYPH_NAME_CODE); - - primitive("XeTeXfonttype", LAST_ITEM, XETEX_FONT_TYPE_CODE); - primitive("XeTeXfirstfontchar", LAST_ITEM, XETEX_FIRST_CHAR_CODE); - primitive("XeTeXlastfontchar", LAST_ITEM, XETEX_LAST_CHAR_CODE); - primitive("XeTeXpdfpagecount", LAST_ITEM, XETEX_PDF_PAGE_COUNT_CODE); - /* everyeof moved to be with other assign_toks */ - - primitive("tracingassigns", ASSIGN_INT, INT_BASE + INT_PAR__tracing_assigns); - primitive("tracinggroups", ASSIGN_INT, INT_BASE + INT_PAR__tracing_groups); - primitive("tracingifs", ASSIGN_INT, INT_BASE + INT_PAR__tracing_ifs); - primitive("tracingscantokens", ASSIGN_INT, INT_BASE + INT_PAR__tracing_scan_tokens); - primitive("tracingnesting", ASSIGN_INT, INT_BASE + INT_PAR__tracing_nesting); - primitive("predisplaydirection", ASSIGN_INT, INT_BASE + INT_PAR__pre_display_correction); - primitive("lastlinefit", ASSIGN_INT, INT_BASE + INT_PAR__last_line_fit); - primitive("savingvdiscards", ASSIGN_INT, INT_BASE + INT_PAR__saving_vdiscards); - primitive("savinghyphcodes", ASSIGN_INT, INT_BASE + INT_PAR__saving_hyphs); - - primitive("currentgrouplevel", LAST_ITEM, CURRENT_GROUP_LEVEL_CODE); - primitive("currentgrouptype", LAST_ITEM, CURRENT_GROUP_TYPE_CODE); - primitive("currentiflevel", LAST_ITEM, CURRENT_IF_LEVEL_CODE); - primitive("currentiftype", LAST_ITEM, CURRENT_IF_TYPE_CODE); - primitive("currentifbranch", LAST_ITEM, CURRENT_IF_BRANCH_CODE); - primitive("fontcharwd", LAST_ITEM, FONT_CHAR_WD_CODE); - primitive("fontcharht", LAST_ITEM, FONT_CHAR_HT_CODE); - primitive("fontchardp", LAST_ITEM, FONT_CHAR_DP_CODE); - primitive("fontcharic", LAST_ITEM, FONT_CHAR_IC_CODE); - primitive("parshapelength", LAST_ITEM, PAR_SHAPE_LENGTH_CODE); - primitive("parshapeindent", LAST_ITEM, PAR_SHAPE_INDENT_CODE); - primitive("parshapedimen", LAST_ITEM, PAR_SHAPE_DIMEN_CODE); - - primitive("showgroups", XRAY, SHOW_GROUPS); - primitive("showtokens", XRAY, SHOW_TOKENS); - - primitive("unexpanded", THE, 1); - primitive("detokenize", THE, SHOW_TOKENS); - - primitive("showifs", XRAY, SHOW_IFS); - - primitive("interactionmode", SET_PAGE_INT, 2); - - primitive("middle", LEFT_RIGHT, 1); - - primitive("suppressfontnotfounderror", ASSIGN_INT, INT_BASE + INT_PAR__suppress_fontnotfound_error); - - primitive("TeXXeTstate", ASSIGN_INT, INT_BASE + INT_PAR__texxet); - primitive("XeTeXupwardsmode", ASSIGN_INT, INT_BASE + INT_PAR__xetex_upwards); - primitive("XeTeXuseglyphmetrics", ASSIGN_INT, INT_BASE + INT_PAR__xetex_use_glyph_metrics); - primitive("XeTeXinterchartokenstate", ASSIGN_INT, INT_BASE + INT_PAR__xetex_inter_char_tokens); - primitive("XeTeXdashbreakstate", ASSIGN_INT, INT_BASE + INT_PAR__xetex_dash_break); - primitive("XeTeXinputnormalization", ASSIGN_INT, INT_BASE + INT_PAR__xetex_input_normalization); - primitive("XeTeXtracingfonts", ASSIGN_INT, INT_BASE + INT_PAR__xetex_tracing_fonts); - primitive("XeTeXinterwordspaceshaping", ASSIGN_INT, INT_BASE + INT_PAR__xetex_interword_space_shaping); - primitive("XeTeXgenerateactualtext", ASSIGN_INT, INT_BASE + INT_PAR__xetex_generate_actual_text); - primitive("XeTeXhyphenatablelength", ASSIGN_INT, INT_BASE + INT_PAR__xetex_hyphenatable_length); - primitive("pdfoutput", ASSIGN_INT, INT_BASE + INT_PAR__pdfoutput); - - primitive("XeTeXinputencoding", EXTENSION, XETEX_INPUT_ENCODING_EXTENSION_CODE); - primitive("XeTeXdefaultencoding", EXTENSION, XETEX_DEFAULT_ENCODING_EXTENSION_CODE); - - primitive("beginL", VALIGN, BEGIN_L_CODE); - primitive("endL", VALIGN, END_L_CODE); - primitive("beginR", VALIGN, BEGIN_R_CODE); - primitive("endR", VALIGN, END_R_CODE); - - primitive("scantokens", INPUT, 2); - primitive("readline", READ_TO_CS, 1); - primitive("unless", EXPAND_AFTER, 1); - - primitive("ifdefined", IF_TEST, IF_DEF_CODE); - primitive("ifcsname", IF_TEST, IF_CS_CODE); - primitive("iffontchar", IF_TEST, IF_FONT_CHAR_CODE); - primitive("ifincsname", IF_TEST, IF_IN_CSNAME_CODE); - - primitive("protected", PREFIX, 8); - - primitive("numexpr", LAST_ITEM, ETEX_EXPR + 0); - primitive("dimexpr", LAST_ITEM, ETEX_EXPR + 1); - primitive("glueexpr", LAST_ITEM, ETEX_EXPR + 2); - primitive("muexpr", LAST_ITEM, ETEX_EXPR + 3); - primitive("gluestretchorder", LAST_ITEM, GLUE_STRETCH_ORDER_CODE); - primitive("glueshrinkorder", LAST_ITEM, GLUE_SHRINK_ORDER_CODE); - primitive("gluestretch", LAST_ITEM, GLUE_STRETCH_CODE); - primitive("glueshrink", LAST_ITEM, GLUE_SHRINK_CODE); - primitive("mutoglue", LAST_ITEM, MU_TO_GLUE_CODE); - primitive("gluetomu", LAST_ITEM, GLUE_TO_MU_CODE); - - primitive("marks", MARK, 5); - primitive("topmarks", TOP_BOT_MARK, TOP_MARK_CODE + 5); - primitive("firstmarks", TOP_BOT_MARK, FIRST_MARK_CODE + 5); - primitive("botmarks", TOP_BOT_MARK, BOT_MARK_CODE + 5); - primitive("splitfirstmarks", TOP_BOT_MARK, SPLIT_FIRST_MARK_CODE + 5); - primitive("splitbotmarks", TOP_BOT_MARK, SPLIT_BOT_MARK_CODE + 5); - - primitive("pagediscards", UN_VBOX, LAST_BOX_CODE); - primitive("splitdiscards", UN_VBOX, VSPLIT_CODE); - - primitive("interlinepenalties", SET_SHAPE, INTER_LINE_PENALTIES_LOC); - primitive("clubpenalties", SET_SHAPE, CLUB_PENALTIES_LOC); - primitive("widowpenalties", SET_SHAPE, WIDOW_PENALTIES_LOC); - primitive("displaywidowpenalties", SET_SHAPE, DISPLAY_WIDOW_PENALTIES_LOC); - max_reg_num = 32767; max_reg_help_line = "A register number must be between 0 and 32767."; } diff --git a/crates/engine_xetex/xetex/xetex-linebreak.c b/crates/engine_xetex/xetex/xetex-linebreak.c index d1c28af02..59e13ed28 100644 --- a/crates/engine_xetex/xetex/xetex-linebreak.c +++ b/crates/engine_xetex/xetex/xetex-linebreak.c @@ -1271,7 +1271,7 @@ post_line_break(bool d) /* 919: Set `pen` to all of the penalties relevant to this line. */ if (cur_line + 1 != best_line) { - q = eqtb[INTER_LINE_PENALTIES_LOC].b32.s1; + q = ETEX_PENALTIES_PAR(inter_line_penalties); if (q != TEX_NULL) { r = cur_line; @@ -1282,7 +1282,7 @@ post_line_break(bool d) pen = INTPAR(inter_line_penalty); } - q = eqtb[CLUB_PENALTIES_LOC].b32.s1; + q = ETEX_PENALTIES_PAR(club_penalties); if (q != TEX_NULL) { r = cur_line - cur_list.prev_graf; @@ -1294,9 +1294,9 @@ post_line_break(bool d) } if (d) - q = eqtb[DISPLAY_WIDOW_PENALTIES_LOC].b32.s1; + q = ETEX_PENALTIES_PAR(display_widow_penalties); else - q = eqtb[WIDOW_PENALTIES_LOC].b32.s1; + q = ETEX_PENALTIES_PAR(widow_penalties); if (q != TEX_NULL) { r = best_line - cur_line - 1; diff --git a/crates/engine_xetex/xetex/xetex-math.c b/crates/engine_xetex/xetex/xetex-math.c index e48bad42c..f3294a3b9 100644 --- a/crates/engine_xetex/xetex/xetex-math.c +++ b/crates/engine_xetex/xetex/xetex-math.c @@ -320,7 +320,7 @@ void init_math(void) eq_word_define(INT_BASE + INT_PAR__cur_fam, -1); eq_word_define(DIMEN_BASE + DIMEN_PAR__pre_display_size, w); cur_list.eTeX_aux = j; - eq_word_define(INT_BASE + INT_PAR__pre_display_correction, x); + eq_word_define(INT_BASE + INT_PAR__pre_display_direction, x); eq_word_define(DIMEN_BASE + DIMEN_PAR__display_width, l); eq_word_define(DIMEN_BASE + DIMEN_PAR__display_indent, s); if (LOCAL(every_display) != TEX_NULL) @@ -763,7 +763,7 @@ app_display(int32_t j, int32_t b, scaled_t d) int32_t p, q, r, t, u; s = DIMENPAR(display_indent); - x = INTPAR(pre_display_correction); + x = INTPAR(pre_display_direction); if (x == 0) mem[b + 4].b32.s1 = s + d; @@ -1069,7 +1069,7 @@ void after_math(void) w = mem[b + 1].b32.s1; z = DIMENPAR(display_width); s = DIMENPAR(display_indent); - if (INTPAR(pre_display_correction) < 0) + if (INTPAR(pre_display_direction) < 0) s = -(int32_t) s - z; if ((a == TEX_NULL) || danger) { e = 0; diff --git a/crates/engine_xetex/xetex/xetex-xetex0.c b/crates/engine_xetex/xetex/xetex-xetex0.c index a146954ab..7cdd6764f 100644 --- a/crates/engine_xetex/xetex/xetex-xetex0.c +++ b/crates/engine_xetex/xetex/xetex-xetex0.c @@ -2053,7 +2053,7 @@ void print_param(int32_t n) case INT_PAR__tracing_nesting: print_esc_cstr("tracingnesting"); break; - case INT_PAR__pre_display_correction: + case INT_PAR__pre_display_direction: print_esc_cstr("predisplaydirection"); break; case INT_PAR__last_line_fit: @@ -2062,7 +2062,7 @@ void print_param(int32_t n) case INT_PAR__saving_vdiscards: print_esc_cstr("savingvdiscards"); break; - case INT_PAR__saving_hyphs: + case INT_PAR__saving_hyph_codes: print_esc_cstr("savinghyphcodes"); break; case INT_PAR__suppress_fontnotfound_error: @@ -2336,10 +2336,10 @@ print_cmd_chr(uint16_t cmd, int32_t chr_code) case LOCAL_BASE + LOCAL__every_eof: print_esc_cstr("everyeof"); break; - case LOCAL_BASE + LOCAL__xetex_inter_char: + case LOCAL_BASE + LOCAL__xetex_inter_char_toks: print_esc_cstr("XeTeXinterchartoks"); break; - case LOCAL_BASE + LOCAL__TectonicCodaTokens: + case LOCAL_BASE + LOCAL__tectonic_coda_tokens: print_esc_cstr("TectonicCodaTokens"); break; default: @@ -2544,16 +2544,16 @@ print_cmd_chr(uint16_t cmd, int32_t chr_code) case LOCAL_BASE + LOCAL__par_shape: print_esc_cstr("parshape"); break; - case INTER_LINE_PENALTIES_LOC: + case ETEX_PEN_BASE + ETEX_PENALTIES_PAR__inter_line_penalties: print_esc_cstr("interlinepenalties"); break; - case CLUB_PENALTIES_LOC: + case ETEX_PEN_BASE + ETEX_PENALTIES_PAR__club_penalties: print_esc_cstr("clubpenalties"); break; - case WIDOW_PENALTIES_LOC: + case ETEX_PEN_BASE + ETEX_PENALTIES_PAR__widow_penalties: print_esc_cstr("widowpenalties"); break; - case DISPLAY_WIDOW_PENALTIES_LOC: + case ETEX_PEN_BASE + ETEX_PENALTIES_PAR__display_widow_penalties: print_esc_cstr("displaywidowpenalties"); break; } @@ -5571,9 +5571,9 @@ get_next(void) * \end or \dump has been seen. We just use a global state * variable to make sure it only gets inserted once. */ - if (!used_tectonic_coda_tokens && LOCAL(TectonicCodaTokens) != TEX_NULL) { + if (!used_tectonic_coda_tokens && LOCAL(tectonic_coda_tokens) != TEX_NULL) { used_tectonic_coda_tokens = true; - begin_token_list(LOCAL(TectonicCodaTokens), TECTONIC_CODA_TEXT); + begin_token_list(LOCAL(tectonic_coda_tokens), TECTONIC_CODA_TEXT); goto restart; } @@ -7198,7 +7198,7 @@ scan_something_internal(small_number level, bool negative) } else { cur_val = mem[m + 1].b32.s1; } - } else if (cur_chr == LOCAL_BASE + LOCAL__xetex_inter_char) { + } else if (cur_chr == LOCAL_BASE + LOCAL__xetex_inter_char_toks) { scan_char_class_not_ignored(); cur_ptr = cur_val; scan_char_class_not_ignored(); @@ -14303,8 +14303,8 @@ void normal_paragraph(void) eq_word_define(INT_BASE + INT_PAR__hang_after, 1); if (LOCAL(par_shape) != TEX_NULL) eq_define(LOCAL_BASE + LOCAL__par_shape, SHAPE_REF, TEX_NULL); - if (eqtb[INTER_LINE_PENALTIES_LOC].b32.s1 != TEX_NULL) - eq_define(INTER_LINE_PENALTIES_LOC, SHAPE_REF, TEX_NULL); + if (ETEX_PENALTIES_PAR(inter_line_penalties) != TEX_NULL) + eq_define(ETEX_PEN_BASE + ETEX_PENALTIES_PAR__inter_line_penalties, SHAPE_REF, TEX_NULL); } diff --git a/crates/engine_xetex/xetex/xetex-xetexd.h b/crates/engine_xetex/xetex/xetex-xetexd.h index 7fda549d5..d7383afc0 100644 --- a/crates/engine_xetex/xetex/xetex-xetexd.h +++ b/crates/engine_xetex/xetex/xetex-xetexd.h @@ -11,6 +11,11 @@ #include "teckit-Common.h" #include "xetex-ext.h" #include "tectonic_bridge_core.h" + +/* xetex_format.h needs this: */ +typedef unsigned char eight_bits; + +#include "xetex_format.h" #include "xetex-constants.h" BEGIN_EXTERN_C @@ -39,7 +44,6 @@ BEGIN_EXTERN_C typedef unsigned short UTF16_code; typedef unsigned char UTF8_code; typedef int32_t UnicodeScalar; -typedef unsigned char eight_bits; typedef int32_t pool_pointer; typedef int32_t str_number; typedef unsigned short packed_UTF16_code; diff --git a/crates/engine_xetex/xetex/xetex_format.h b/crates/engine_xetex/xetex/xetex_format.h new file mode 100644 index 000000000..a019d418a --- /dev/null +++ b/crates/engine_xetex/xetex/xetex_format.h @@ -0,0 +1,867 @@ +/* tectonic_xetex_format engine header for version 30 */ +/* This file is automatically generated by the `xetex_format` `emit` example. Do not modify. */ + +#ifndef __TECTONIC_XETEX_FORMAT_ENGINE_HEADER__ +#define __TECTONIC_XETEX_FORMAT_ENGINE_HEADER__ + +/* Memory settings */ + +#define HASH_SIZE 15000 +#define HASH_EXTRA 600000 +#define HASH_OFFSET 514 +#define HASH_PRIME 8501 +#define PRIM_SIZE 500 +#define MAX_FONT_MAX 9000 +#define MEM_TOP 4999999 + +/* Equivalents table addresses */ + +#define ACTIVE_BASE 1 +#define SINGLE_BASE 1114113 +#define NULL_CS 2228225 +#define HASH_BASE 2228226 +#define FROZEN_CONTROL_SEQUENCE 2243226 +#define PRIM_EQTB_BASE 2243238 +#define FROZEN_NULL_FONT 2243738 +#define UNDEFINED_CONTROL_SEQUENCE 2252739 +#define GLUE_BASE 2252740 +#define SKIP_BASE 2252759 +#define MU_SKIP_BASE 2253015 +#define LOCAL_BASE 2253271 +#define TOKS_BASE 2253284 +#define ETEX_PEN_BASE 2253540 +#define BOX_BASE 2253544 +#define CUR_FONT_LOC 2253800 +#define MATH_FONT_BASE 2253801 +#define CAT_CODE_BASE 2254569 +#define LC_CODE_BASE 3368681 +#define UC_CODE_BASE 4482793 +#define SF_CODE_BASE 5596905 +#define MATH_CODE_BASE 6711017 +#define CHAR_SUB_CODE_BASE 7825129 +#define INT_BASE 8939241 +#define COUNT_BASE 8939326 +#define DEL_CODE_BASE 8939582 +#define DIMEN_BASE 10053694 +#define SCALED_BASE 10053717 +#define EQTB_SIZE 10053972 +#define EQTB_TOP 10653972 + +/* Integer parameters */ + +#define INT_PAR__pretolerance 0 +#define INT_PAR__tolerance 1 +#define INT_PAR__line_penalty 2 +#define INT_PAR__hyphen_penalty 3 +#define INT_PAR__ex_hyphen_penalty 4 +#define INT_PAR__club_penalty 5 +#define INT_PAR__widow_penalty 6 +#define INT_PAR__display_widow_penalty 7 +#define INT_PAR__broken_penalty 8 +#define INT_PAR__bin_op_penalty 9 +#define INT_PAR__rel_penalty 10 +#define INT_PAR__pre_display_penalty 11 +#define INT_PAR__post_display_penalty 12 +#define INT_PAR__inter_line_penalty 13 +#define INT_PAR__double_hyphen_demerits 14 +#define INT_PAR__final_hyphen_demerits 15 +#define INT_PAR__adj_demerits 16 +#define INT_PAR__mag 17 +#define INT_PAR__delimiter_factor 18 +#define INT_PAR__looseness 19 +#define INT_PAR__time 20 +#define INT_PAR__day 21 +#define INT_PAR__month 22 +#define INT_PAR__year 23 +#define INT_PAR__show_box_breadth 24 +#define INT_PAR__show_box_depth 25 +#define INT_PAR__hbadness 26 +#define INT_PAR__vbadness 27 +#define INT_PAR__pausing 28 +#define INT_PAR__tracing_online 29 +#define INT_PAR__tracing_macros 30 +#define INT_PAR__tracing_stats 31 +#define INT_PAR__tracing_paragraphs 32 +#define INT_PAR__tracing_pages 33 +#define INT_PAR__tracing_output 34 +#define INT_PAR__tracing_lost_chars 35 +#define INT_PAR__tracing_commands 36 +#define INT_PAR__tracing_restores 37 +#define INT_PAR__uc_hyph 38 +#define INT_PAR__output_penalty 39 +#define INT_PAR__max_dead_cycles 40 +#define INT_PAR__hang_after 41 +#define INT_PAR__floating_penalty 42 +#define INT_PAR__global_defs 43 +#define INT_PAR__cur_fam 44 +#define INT_PAR__escape_char 45 +#define INT_PAR__default_hyphen_char 46 +#define INT_PAR__default_skew_char 47 +#define INT_PAR__end_line_char 48 +#define INT_PAR__new_line_char 49 +#define INT_PAR__language 50 +#define INT_PAR__left_hyphen_min 51 +#define INT_PAR__right_hyphen_min 52 +#define INT_PAR__holding_inserts 53 +#define INT_PAR__error_context_lines 54 +#define INT_PAR__char_sub_def_min 55 +#define INT_PAR__char_sub_def_max 56 +#define INT_PAR__tracing_char_sub_def 57 +#define INT_PAR__tracing_assigns 58 +#define INT_PAR__tracing_groups 59 +#define INT_PAR__tracing_ifs 60 +#define INT_PAR__tracing_scan_tokens 61 +#define INT_PAR__tracing_nesting 62 +#define INT_PAR__pre_display_direction 63 +#define INT_PAR__last_line_fit 64 +#define INT_PAR__saving_vdiscards 65 +#define INT_PAR__saving_hyph_codes 66 +#define INT_PAR__suppress_fontnotfound_error 67 +#define INT_PAR__xetex_linebreak_locale 68 +#define INT_PAR__xetex_linebreak_penalty 69 +#define INT_PAR__xetex_protrude_chars 70 +#define INT_PAR__texxet 71 +#define INT_PAR__xetex_dash_break 72 +#define INT_PAR__xetex_upwards 73 +#define INT_PAR__xetex_use_glyph_metrics 74 +#define INT_PAR__xetex_inter_char_tokens 75 +#define INT_PAR__xetex_input_normalization 76 +#define INT_PAR__xetex_default_input_mode 77 +#define INT_PAR__xetex_default_input_encoding 78 +#define INT_PAR__xetex_tracing_fonts 79 +#define INT_PAR__xetex_interword_space_shaping 80 +#define INT_PAR__xetex_generate_actual_text 81 +#define INT_PAR__xetex_hyphenatable_length 82 +#define INT_PAR__synctex 83 +#define INT_PAR__pdfoutput 84 +#define INT_PARS 85 + +/* Dimensional (length) parameters */ + +#define DIMEN_PAR__par_indent 0 +#define DIMEN_PAR__math_surround 1 +#define DIMEN_PAR__line_skip_limit 2 +#define DIMEN_PAR__hsize 3 +#define DIMEN_PAR__vsize 4 +#define DIMEN_PAR__max_depth 5 +#define DIMEN_PAR__split_max_depth 6 +#define DIMEN_PAR__box_max_depth 7 +#define DIMEN_PAR__hfuzz 8 +#define DIMEN_PAR__vfuzz 9 +#define DIMEN_PAR__delimiter_shortfall 10 +#define DIMEN_PAR__null_delimiter_space 11 +#define DIMEN_PAR__script_space 12 +#define DIMEN_PAR__pre_display_size 13 +#define DIMEN_PAR__display_width 14 +#define DIMEN_PAR__display_indent 15 +#define DIMEN_PAR__overfull_rule 16 +#define DIMEN_PAR__hang_indent 17 +#define DIMEN_PAR__h_offset 18 +#define DIMEN_PAR__v_offset 19 +#define DIMEN_PAR__emergency_stretch 20 +#define DIMEN_PAR__pdf_page_width 21 +#define DIMEN_PAR__pdf_page_height 22 +#define DIMEN_PARS 23 + +/* Glue ("skip") parameters */ + +#define GLUE_PAR__line_skip 0 +#define GLUE_PAR__baseline_skip 1 +#define GLUE_PAR__par_skip 2 +#define GLUE_PAR__above_display_skip 3 +#define GLUE_PAR__below_display_skip 4 +#define GLUE_PAR__above_display_short_skip 5 +#define GLUE_PAR__below_display_short_skip 6 +#define GLUE_PAR__left_skip 7 +#define GLUE_PAR__right_skip 8 +#define GLUE_PAR__top_skip 9 +#define GLUE_PAR__split_top_skip 10 +#define GLUE_PAR__tab_skip 11 +#define GLUE_PAR__space_skip 12 +#define GLUE_PAR__xspace_skip 13 +#define GLUE_PAR__par_fill_skip 14 +#define GLUE_PAR__xetex_linebreak_skip 15 +#define GLUE_PAR__thin_mu_skip 16 +#define GLUE_PAR__med_mu_skip 17 +#define GLUE_PAR__thick_mu_skip 18 +#define GLUE_PARS 19 + +/* "Local" parameters (mostly token lists) */ + +#define LOCAL__par_shape 0 +#define LOCAL__output_routine 1 +#define LOCAL__every_par 2 +#define LOCAL__every_math 3 +#define LOCAL__every_display 4 +#define LOCAL__every_hbox 5 +#define LOCAL__every_vbox 6 +#define LOCAL__every_job 7 +#define LOCAL__every_cr 8 +#define LOCAL__err_help 9 +#define LOCAL__every_eof 10 +#define LOCAL__xetex_inter_char_toks 11 +#define LOCAL__tectonic_coda_tokens 12 +#define NUM_LOCALS 13 + +/* e-TeX penalties parameters */ + +#define ETEX_PENALTIES_PAR__inter_line_penalties 0 +#define ETEX_PENALTIES_PAR__club_penalties 1 +#define ETEX_PENALTIES_PAR__widow_penalties 2 +#define ETEX_PENALTIES_PAR__display_widow_penalties 3 +#define NUM_ETEX_PENALTIES 4 + +/* Commands */ + +#undef IGNORE /* Windows OS headers sometimes define this */ + +#define RELAX 0 +#define ESCAPE RELAX /* Overloaded usage in parser */ +#define LEFT_BRACE 1 +#define RIGHT_BRACE 2 +#define MATH_SHIFT 3 +#define TAB_MARK 4 +#define CAR_RET 5 +#define OUT_PARAM CAR_RET /* Overloaded usage in macro evaluation */ +#define MAC_PARAM 6 +#define SUP_MARK 7 +#define SUB_MARK 8 +#define ENDV 9 +#define IGNORE ENDV /* Overloaded usage in parser */ +#define SPACER 10 +#define LETTER 11 +#define OTHER_CHAR 12 +#define PAR_END 13 +#define ACTIVE_CHAR PAR_END /* Overloaded usage in parser */ +#define MATCH PAR_END /* Overloaded usage in macro evaluation */ +#define STOP 14 +#define COMMENT STOP /* Overloaded usage in parser */ +#define END_MATCH STOP /* Overloaded usage in macro evaluation */ +#define DELIM_NUM 15 +#define INVALID_CHAR DELIM_NUM /* Overloaded usage in parser */ +#define CHAR_NUM 16 +#define MATH_CHAR_NUM 17 +#define MARK 18 +#define XRAY 19 +#define MAKE_BOX 20 +#define HMOVE 21 +#define VMOVE 22 +#define UN_HBOX 23 +#define UN_VBOX 24 +#define REMOVE_ITEM 25 +#define HSKIP 26 +#define VSKIP 27 +#define MSKIP 28 +#define KERN 29 +#define MKERN 30 +#define LEADER_SHIP 31 +#define HALIGN 32 +#define VALIGN 33 +#define NO_ALIGN 34 +#define VRULE 35 +#define HRULE 36 +#define INSERT 37 +#define VADJUST 38 +#define IGNORE_SPACES 39 +#define AFTER_ASSIGNMENT 40 +#define AFTER_GROUP 41 +#define BREAK_PENALTY 42 +#define START_PAR 43 +#define ITAL_CORR 44 +#define ACCENT 45 +#define MATH_ACCENT 46 +#define DISCRETIONARY 47 +#define EQ_NO 48 +#define LEFT_RIGHT 49 +#define MATH_COMP 50 +#define LIMIT_SWITCH 51 +#define ABOVE 52 +#define MATH_STYLE 53 +#define MATH_CHOICE 54 +#define NON_SCRIPT 55 +#define VCENTER 56 +#define CASE_SHIFT 57 +#define MESSAGE 58 +#define EXTENSION 59 +#define IN_STREAM 60 +#define BEGIN_GROUP 61 +#define END_GROUP 62 +#define OMIT 63 +#define EX_SPACE 64 +#define NO_BOUNDARY 65 +#define RADICAL 66 +#define END_CS_NAME 67 +#define CHAR_GIVEN 68 +#define MATH_GIVEN 69 +#define XETEX_MATH_GIVEN 70 +#define LAST_ITEM 71 +#define TOKS_REGISTER 72 +#define ASSIGN_TOKS 73 +#define ASSIGN_INT 74 +#define ASSIGN_DIMEN 75 +#define ASSIGN_GLUE 76 +#define ASSIGN_MU_GLUE 77 +#define ASSIGN_FONT_DIMEN 78 +#define ASSIGN_FONT_INT 79 +#define SET_AUX 80 +#define SET_PREV_GRAF 81 +#define SET_PAGE_DIMEN 82 +#define SET_PAGE_INT 83 +#define SET_BOX_DIMEN 84 +#define SET_SHAPE 85 +#define DEF_CODE 86 +#define XETEX_DEF_CODE 87 +#define DEF_FAMILY 88 +#define SET_FONT 89 +#define DEF_FONT 90 +#define REGISTER 91 +#define ADVANCE 92 +#define MULTIPLY 93 +#define DIVIDE 94 +#define PREFIX 95 +#define LET 96 +#define SHORTHAND_DEF 97 +#define READ_TO_CS 98 +#define DEF 99 +#define SET_BOX 100 +#define HYPH_DATA 101 +#define SET_INTERACTION 102 +#define UNDEFINED_CS 103 +#define EXPAND_AFTER 104 +#define NO_EXPAND 105 +#define INPUT 106 +#define IF_TEST 107 +#define FI_OR_ELSE 108 +#define CS_NAME 109 +#define CONVERT 110 +#define THE 111 +#define TOP_BOT_MARK 112 +#define CALL 113 +#define LONG_CALL 114 +#define OUTER_CALL 115 +#define LONG_OUTER_CALL 116 +#define END_TEMPLATE 117 +#define DONT_EXPAND 118 +#define GLUE_REF 119 +#define SHAPE_REF 120 +#define BOX_REF 121 +#define DATA 122 + +/* Primitives */ + +enum xetex_format_primitive_extra_init_t { + xf_prim_init_none = 0, + xf_prim_init_par = 1, + xf_prim_init_write = 2 + /* Other values should be used to set up a "frozen" primitive */ +}; + +typedef struct xetex_format_primitive_def_t { + char const *name; + eight_bits cmd; + int32_t chr; + int32_t extra_init; +} xetex_format_primitive_def_t; + +#define XETEX_FORMAT_PRIMITIVE_INITIALIZERS \ + { "relax", RELAX, TOO_BIG_USV, FROZEN_RELAX }, \ + { "span", TAB_MARK, SPAN_CODE, xf_prim_init_none }, \ + { "cr", CAR_RET, CR_CODE, FROZEN_CR }, \ + { "crcr", CAR_RET, CR_CR_CODE, xf_prim_init_none }, \ + { "par", PAR_END, TOO_BIG_USV, xf_prim_init_par }, \ + { "end", STOP, 0, xf_prim_init_none }, \ + { "dump", STOP, 1, xf_prim_init_none }, \ + { "delimiter", DELIM_NUM, 0, xf_prim_init_none }, \ + { "Udelimiter", DELIM_NUM, 1, xf_prim_init_none }, \ + { "XeTeXdelimiter", DELIM_NUM, 1, xf_prim_init_none }, \ + { "char", CHAR_NUM, 0, xf_prim_init_none }, \ + { "mathchar", MATH_CHAR_NUM, 0, xf_prim_init_none }, \ + { "Umathcharnum", MATH_CHAR_NUM, 1, xf_prim_init_none }, \ + { "XeTeXmathcharnum", MATH_CHAR_NUM, 1, xf_prim_init_none }, \ + { "Umathchar", MATH_CHAR_NUM, 2, xf_prim_init_none }, \ + { "XeTeXmathchar", MATH_CHAR_NUM, 2, xf_prim_init_none }, \ + { "mark", MARK, 0, xf_prim_init_none }, \ + { "marks", MARK, 5, xf_prim_init_none }, \ + { "show", XRAY, SHOW_CODE, xf_prim_init_none }, \ + { "showbox", XRAY, SHOW_BOX_CODE, xf_prim_init_none }, \ + { "showthe", XRAY, SHOW_THE_CODE, xf_prim_init_none }, \ + { "showlists", XRAY, SHOW_LISTS, xf_prim_init_none }, \ + { "showgroups", XRAY, SHOW_GROUPS, xf_prim_init_none }, \ + { "showtokens", XRAY, SHOW_TOKENS, xf_prim_init_none }, \ + { "showifs", XRAY, SHOW_IFS, xf_prim_init_none }, \ + { "box", MAKE_BOX, BOX_CODE, xf_prim_init_none }, \ + { "copy", MAKE_BOX, COPY_CODE, xf_prim_init_none }, \ + { "lastbox", MAKE_BOX, LAST_BOX_CODE, xf_prim_init_none }, \ + { "vsplit", MAKE_BOX, VSPLIT_CODE, xf_prim_init_none }, \ + { "vtop", MAKE_BOX, VTOP_CODE, xf_prim_init_none }, \ + { "vbox", MAKE_BOX, VTOP_CODE + VMODE, xf_prim_init_none }, \ + { "hbox", MAKE_BOX, VTOP_CODE + HMODE, xf_prim_init_none }, \ + { "moveright", HMOVE, 0, xf_prim_init_none }, \ + { "moveleft", HMOVE, 1, xf_prim_init_none }, \ + { "lower", VMOVE, 0, xf_prim_init_none }, \ + { "raise", VMOVE, 1, xf_prim_init_none }, \ + { "unhbox", UN_HBOX, BOX_CODE, xf_prim_init_none }, \ + { "unhcopy", UN_HBOX, COPY_CODE, xf_prim_init_none }, \ + { "unvbox", UN_VBOX, BOX_CODE, xf_prim_init_none }, \ + { "unvcopy", UN_VBOX, COPY_CODE, xf_prim_init_none }, \ + { "pagediscards", UN_VBOX, LAST_BOX_CODE, xf_prim_init_none }, \ + { "splitdiscards", UN_VBOX, VSPLIT_CODE, xf_prim_init_none }, \ + { "unskip", REMOVE_ITEM, GLUE_NODE, xf_prim_init_none }, \ + { "unkern", REMOVE_ITEM, KERN_NODE, xf_prim_init_none }, \ + { "unpenalty", REMOVE_ITEM, PENALTY_NODE, xf_prim_init_none }, \ + { "hfil", HSKIP, FIL_CODE, xf_prim_init_none }, \ + { "hfill", HSKIP, FILL_CODE, xf_prim_init_none }, \ + { "hss", HSKIP, SS_CODE, xf_prim_init_none }, \ + { "hfilneg", HSKIP, FIL_NEG_CODE, xf_prim_init_none }, \ + { "hskip", HSKIP, SKIP_CODE, xf_prim_init_none }, \ + { "vfil", VSKIP, FIL_CODE, xf_prim_init_none }, \ + { "vfill", VSKIP, FILL_CODE, xf_prim_init_none }, \ + { "vss", VSKIP, SS_CODE, xf_prim_init_none }, \ + { "vfilneg", VSKIP, FIL_NEG_CODE, xf_prim_init_none }, \ + { "vskip", VSKIP, SKIP_CODE, xf_prim_init_none }, \ + { "mskip", MSKIP, MSKIP_CODE, xf_prim_init_none }, \ + { "kern", KERN, EXPLICIT, xf_prim_init_none }, \ + { "mkern", MKERN, MU_GLUE, xf_prim_init_none }, \ + { "shipout", LEADER_SHIP, A_LEADERS - 1, xf_prim_init_none }, \ + { "leaders", LEADER_SHIP, A_LEADERS, xf_prim_init_none }, \ + { "cleaders", LEADER_SHIP, C_LEADERS, xf_prim_init_none }, \ + { "xleaders", LEADER_SHIP, X_LEADERS, xf_prim_init_none }, \ + { "halign", HALIGN, 0, xf_prim_init_none }, \ + { "valign", VALIGN, 0, xf_prim_init_none }, \ + { "beginL", VALIGN, BEGIN_L_CODE, xf_prim_init_none }, \ + { "endL", VALIGN, END_L_CODE, xf_prim_init_none }, \ + { "beginR", VALIGN, BEGIN_R_CODE, xf_prim_init_none }, \ + { "endR", VALIGN, END_R_CODE, xf_prim_init_none }, \ + { "noalign", NO_ALIGN, 0, xf_prim_init_none }, \ + { "vrule", VRULE, 0, xf_prim_init_none }, \ + { "hrule", HRULE, 0, xf_prim_init_none }, \ + { "insert", INSERT, 0, xf_prim_init_none }, \ + { "vadjust", VADJUST, 0, xf_prim_init_none }, \ + { "ignorespaces", IGNORE_SPACES, 0, xf_prim_init_none }, \ + { "afterassignment", AFTER_ASSIGNMENT, 0, xf_prim_init_none }, \ + { "aftergroup", AFTER_GROUP, 0, xf_prim_init_none }, \ + { "penalty", BREAK_PENALTY, 0, xf_prim_init_none }, \ + { "noindent", START_PAR, 0, xf_prim_init_none }, \ + { "indent", START_PAR, 1, xf_prim_init_none }, \ + { "/", ITAL_CORR, 0, xf_prim_init_none }, \ + { "accent", ACCENT, 0, xf_prim_init_none }, \ + { "mathaccent", MATH_ACCENT, 0, xf_prim_init_none }, \ + { "Umathaccent", MATH_ACCENT, 1, xf_prim_init_none }, \ + { "XeTeXmathaccent", MATH_ACCENT, 1, xf_prim_init_none }, \ + { "discretionary", DISCRETIONARY, 0, xf_prim_init_none }, \ + { "-", DISCRETIONARY, 1, xf_prim_init_none }, \ + { "eqno", EQ_NO, 0, xf_prim_init_none }, \ + { "leqno", EQ_NO, 1, xf_prim_init_none }, \ + { "middle", LEFT_RIGHT, 1, xf_prim_init_none }, \ + { "left", LEFT_RIGHT, LEFT_NOAD, xf_prim_init_none }, \ + { "right", LEFT_RIGHT, RIGHT_NOAD, FROZEN_RIGHT }, \ + { "mathord", MATH_COMP, ORD_NOAD, xf_prim_init_none }, \ + { "mathop", MATH_COMP, OP_NOAD, xf_prim_init_none }, \ + { "mathbin", MATH_COMP, BIN_NOAD, xf_prim_init_none }, \ + { "mathrel", MATH_COMP, REL_NOAD, xf_prim_init_none }, \ + { "mathopen", MATH_COMP, OPEN_NOAD, xf_prim_init_none }, \ + { "mathclose", MATH_COMP, CLOSE_NOAD, xf_prim_init_none }, \ + { "mathpunct", MATH_COMP, PUNCT_NOAD, xf_prim_init_none }, \ + { "mathinner", MATH_COMP, INNER_NOAD, xf_prim_init_none }, \ + { "underline", MATH_COMP, UNDER_NOAD, xf_prim_init_none }, \ + { "overline", MATH_COMP, OVER_NOAD, xf_prim_init_none }, \ + { "displaylimits", LIMIT_SWITCH, NORMAL, xf_prim_init_none }, \ + { "limits", LIMIT_SWITCH, LIMITS, xf_prim_init_none }, \ + { "nolimits", LIMIT_SWITCH, NO_LIMITS, xf_prim_init_none }, \ + { "above", ABOVE, ABOVE_CODE, xf_prim_init_none }, \ + { "over", ABOVE, OVER_CODE, xf_prim_init_none }, \ + { "atop", ABOVE, ATOP_CODE, xf_prim_init_none }, \ + { "abovewithdelims", ABOVE, DELIMITED_CODE + ABOVE_CODE, xf_prim_init_none }, \ + { "overwithdelims", ABOVE, DELIMITED_CODE + OVER_CODE, xf_prim_init_none }, \ + { "atopwithdelims", ABOVE, DELIMITED_CODE + ATOP_CODE, xf_prim_init_none }, \ + { "displaystyle", MATH_STYLE, DISPLAY_STYLE, xf_prim_init_none }, \ + { "textstyle", MATH_STYLE, TEXT_STYLE, xf_prim_init_none }, \ + { "scriptstyle", MATH_STYLE, SCRIPT_STYLE, xf_prim_init_none }, \ + { "scriptscriptstyle", MATH_STYLE, SCRIPT_SCRIPT_STYLE, xf_prim_init_none }, \ + { "mathchoice", MATH_CHOICE, 0, xf_prim_init_none }, \ + { "nonscript", NON_SCRIPT, 0, xf_prim_init_none }, \ + { "vcenter", VCENTER, 0, xf_prim_init_none }, \ + { "lowercase", CASE_SHIFT, LC_CODE_BASE, xf_prim_init_none }, \ + { "uppercase", CASE_SHIFT, UC_CODE_BASE, xf_prim_init_none }, \ + { "message", MESSAGE, 0, xf_prim_init_none }, \ + { "errmessage", MESSAGE, 1, xf_prim_init_none }, \ + { "openout", EXTENSION, OPEN_NODE, xf_prim_init_none }, \ + { "write", EXTENSION, WRITE_NODE, xf_prim_init_write }, \ + { "closeout", EXTENSION, CLOSE_NODE, xf_prim_init_none }, \ + { "special", EXTENSION, SPECIAL_NODE, FROZEN_SPECIAL }, \ + { "immediate", EXTENSION, IMMEDIATE_CODE, xf_prim_init_none }, \ + { "setlanguage", EXTENSION, SET_LANGUAGE_CODE, xf_prim_init_none }, \ + { "pdfsavepos", EXTENSION, PDF_SAVE_POS_NODE, xf_prim_init_none }, \ + { "resettimer", EXTENSION, RESET_TIMER_CODE, xf_prim_init_none }, \ + { "setrandomseed", EXTENSION, SET_RANDOM_SEED_CODE, xf_prim_init_none }, \ + { "XeTeXdefaultencoding", EXTENSION, XETEX_DEFAULT_ENCODING_EXTENSION_CODE, xf_prim_init_none }, \ + { "XeTeXglyph", EXTENSION, GLYPH_CODE, xf_prim_init_none }, \ + { "XeTeXinputencoding", EXTENSION, XETEX_INPUT_ENCODING_EXTENSION_CODE, xf_prim_init_none }, \ + { "XeTeXlinebreaklocale", EXTENSION, XETEX_LINEBREAK_LOCALE_EXTENSION_CODE, xf_prim_init_none }, \ + { "XeTeXpdffile", EXTENSION, PDF_FILE_CODE, xf_prim_init_none }, \ + { "XeTeXpicfile", EXTENSION, PIC_FILE_CODE, xf_prim_init_none }, \ + { "closein", IN_STREAM, 0, xf_prim_init_none }, \ + { "openin", IN_STREAM, 1, xf_prim_init_none }, \ + { "begingroup", BEGIN_GROUP, 0, xf_prim_init_none }, \ + { "endgroup", END_GROUP, 0, FROZEN_END_GROUP }, \ + { "omit", OMIT, 0, xf_prim_init_none }, \ + { " ", EX_SPACE, 0, xf_prim_init_none }, \ + { "noboundary", NO_BOUNDARY, 0, xf_prim_init_none }, \ + { "radical", RADICAL, 0, xf_prim_init_none }, \ + { "Uradical", RADICAL, 1, xf_prim_init_none }, \ + { "XeTeXradical", RADICAL, 1, xf_prim_init_none }, \ + { "endcsname", END_CS_NAME, 0, xf_prim_init_none }, \ + { "badness", LAST_ITEM, BADNESS_CODE, xf_prim_init_none }, \ + { "currentgrouplevel", LAST_ITEM, CURRENT_GROUP_LEVEL_CODE, xf_prim_init_none }, \ + { "currentgrouptype", LAST_ITEM, CURRENT_GROUP_TYPE_CODE, xf_prim_init_none }, \ + { "currentifbranch", LAST_ITEM, CURRENT_IF_BRANCH_CODE, xf_prim_init_none }, \ + { "currentiflevel", LAST_ITEM, CURRENT_IF_LEVEL_CODE, xf_prim_init_none }, \ + { "currentiftype", LAST_ITEM, CURRENT_IF_TYPE_CODE, xf_prim_init_none }, \ + { "dimexpr", LAST_ITEM, ETEX_EXPR + 1, xf_prim_init_none }, \ + { "elapsedtime", LAST_ITEM, ELAPSED_TIME_CODE, xf_prim_init_none }, \ + { "eTeXversion", LAST_ITEM, ETEX_VERSION_CODE, xf_prim_init_none }, \ + { "fontchardp", LAST_ITEM, FONT_CHAR_DP_CODE, xf_prim_init_none }, \ + { "fontcharht", LAST_ITEM, FONT_CHAR_HT_CODE, xf_prim_init_none }, \ + { "fontcharic", LAST_ITEM, FONT_CHAR_IC_CODE, xf_prim_init_none }, \ + { "fontcharwd", LAST_ITEM, FONT_CHAR_WD_CODE, xf_prim_init_none }, \ + { "glueexpr", LAST_ITEM, ETEX_EXPR + 2, xf_prim_init_none }, \ + { "glueshrink", LAST_ITEM, GLUE_SHRINK_CODE, xf_prim_init_none }, \ + { "glueshrinkorder", LAST_ITEM, GLUE_SHRINK_ORDER_CODE, xf_prim_init_none }, \ + { "gluestretch", LAST_ITEM, GLUE_STRETCH_CODE, xf_prim_init_none }, \ + { "gluestretchorder", LAST_ITEM, GLUE_STRETCH_ORDER_CODE, xf_prim_init_none }, \ + { "gluetomu", LAST_ITEM, GLUE_TO_MU_CODE, xf_prim_init_none }, \ + { "inputlineno", LAST_ITEM, INPUT_LINE_NO_CODE, xf_prim_init_none }, \ + { "lastkern", LAST_ITEM, DIMEN_VAL, xf_prim_init_none }, \ + { "lastnodetype", LAST_ITEM, LAST_NODE_TYPE_CODE, xf_prim_init_none }, \ + { "lastpenalty", LAST_ITEM, INT_VAL, xf_prim_init_none }, \ + { "lastskip", LAST_ITEM, GLUE_VAL, xf_prim_init_none }, \ + { "muexpr", LAST_ITEM, ETEX_EXPR + 3, xf_prim_init_none }, \ + { "mutoglue", LAST_ITEM, MU_TO_GLUE_CODE, xf_prim_init_none }, \ + { "numexpr", LAST_ITEM, ETEX_EXPR + 0, xf_prim_init_none }, \ + { "parshapedimen", LAST_ITEM, PAR_SHAPE_DIMEN_CODE, xf_prim_init_none }, \ + { "parshapeindent", LAST_ITEM, PAR_SHAPE_INDENT_CODE, xf_prim_init_none }, \ + { "parshapelength", LAST_ITEM, PAR_SHAPE_LENGTH_CODE, xf_prim_init_none }, \ + { "pdflastxpos", LAST_ITEM, PDF_LAST_X_POS_CODE, xf_prim_init_none }, \ + { "pdflastypos", LAST_ITEM, PDF_LAST_Y_POS_CODE, xf_prim_init_none }, \ + { "randomseed", LAST_ITEM, RANDOM_SEED_CODE, xf_prim_init_none }, \ + { "shellescape", LAST_ITEM, PDF_SHELL_ESCAPE_CODE, xf_prim_init_none }, \ + { "XeTeXcharglyph", LAST_ITEM, XETEX_MAP_CHAR_TO_GLYPH_CODE, xf_prim_init_none }, \ + { "XeTeXcountfeatures", LAST_ITEM, XETEX_COUNT_FEATURES_CODE, xf_prim_init_none }, \ + { "XeTeXcountglyphs", LAST_ITEM, XETEX_COUNT_GLYPHS_CODE, xf_prim_init_none }, \ + { "XeTeXcountselectors", LAST_ITEM, XETEX_COUNT_SELECTORS_CODE, xf_prim_init_none }, \ + { "XeTeXcountvariations", LAST_ITEM, XETEX_COUNT_VARIATIONS_CODE, xf_prim_init_none }, \ + { "XeTeXfeaturecode", LAST_ITEM, XETEX_FEATURE_CODE_CODE, xf_prim_init_none }, \ + { "XeTeXfindfeaturebyname", LAST_ITEM, XETEX_FIND_FEATURE_BY_NAME_CODE, xf_prim_init_none }, \ + { "XeTeXfindselectorbyname", LAST_ITEM, XETEX_FIND_SELECTOR_BY_NAME_CODE, xf_prim_init_none }, \ + { "XeTeXfindvariationbyname", LAST_ITEM, XETEX_FIND_VARIATION_BY_NAME_CODE, xf_prim_init_none }, \ + { "XeTeXfirstfontchar", LAST_ITEM, XETEX_FIRST_CHAR_CODE, xf_prim_init_none }, \ + { "XeTeXfonttype", LAST_ITEM, XETEX_FONT_TYPE_CODE, xf_prim_init_none }, \ + { "XeTeXglyphbounds", LAST_ITEM, XETEX_GLYPH_BOUNDS_CODE, xf_prim_init_none }, \ + { "XeTeXglyphindex", LAST_ITEM, XETEX_GLYPH_INDEX_CODE, xf_prim_init_none }, \ + { "XeTeXisdefaultselector", LAST_ITEM, XETEX_IS_DEFAULT_SELECTOR_CODE, xf_prim_init_none }, \ + { "XeTeXisexclusivefeature", LAST_ITEM, XETEX_IS_EXCLUSIVE_FEATURE_CODE, xf_prim_init_none }, \ + { "XeTeXlastfontchar", LAST_ITEM, XETEX_LAST_CHAR_CODE, xf_prim_init_none }, \ + { "XeTeXOTcountfeatures", LAST_ITEM, XETEX_OT_COUNT_FEATURES_CODE, xf_prim_init_none }, \ + { "XeTeXOTcountlanguages", LAST_ITEM, XETEX_OT_COUNT_LANGUAGES_CODE, xf_prim_init_none }, \ + { "XeTeXOTcountscripts", LAST_ITEM, XETEX_OT_COUNT_SCRIPTS_CODE, xf_prim_init_none }, \ + { "XeTeXOTfeaturetag", LAST_ITEM, XETEX_OT_FEATURE_CODE, xf_prim_init_none }, \ + { "XeTeXOTlanguagetag", LAST_ITEM, XETEX_OT_LANGUAGE_CODE, xf_prim_init_none }, \ + { "XeTeXOTscripttag", LAST_ITEM, XETEX_OT_SCRIPT_CODE, xf_prim_init_none }, \ + { "XeTeXpdfpagecount", LAST_ITEM, XETEX_PDF_PAGE_COUNT_CODE, xf_prim_init_none }, \ + { "XeTeXselectorcode", LAST_ITEM, XETEX_SELECTOR_CODE_CODE, xf_prim_init_none }, \ + { "XeTeXvariationdefault", LAST_ITEM, XETEX_VARIATION_DEFAULT_CODE, xf_prim_init_none }, \ + { "XeTeXvariationmax", LAST_ITEM, XETEX_VARIATION_MAX_CODE, xf_prim_init_none }, \ + { "XeTeXvariationmin", LAST_ITEM, XETEX_VARIATION_MIN_CODE, xf_prim_init_none }, \ + { "XeTeXvariation", LAST_ITEM, XETEX_VARIATION_CODE, xf_prim_init_none }, \ + { "XeTeXversion", LAST_ITEM, XETEX_VERSION_CODE, xf_prim_init_none }, \ + { "toks", TOKS_REGISTER, 0, xf_prim_init_none }, \ + { "fontdimen", ASSIGN_FONT_DIMEN, 0, xf_prim_init_none }, \ + { "hyphenchar", ASSIGN_FONT_INT, 0, xf_prim_init_none }, \ + { "skewchar", ASSIGN_FONT_INT, 1, xf_prim_init_none }, \ + { "lpcode", ASSIGN_FONT_INT, 2, xf_prim_init_none }, \ + { "rpcode", ASSIGN_FONT_INT, 3, xf_prim_init_none }, \ + { "prevdepth", SET_AUX, VMODE, xf_prim_init_none }, \ + { "spacefactor", SET_AUX, HMODE, xf_prim_init_none }, \ + { "prevgraf", SET_PREV_GRAF, 0, xf_prim_init_none }, \ + { "pagegoal", SET_PAGE_DIMEN, 0, xf_prim_init_none }, \ + { "pagetotal", SET_PAGE_DIMEN, 1, xf_prim_init_none }, \ + { "pagestretch", SET_PAGE_DIMEN, 2, xf_prim_init_none }, \ + { "pagefilstretch", SET_PAGE_DIMEN, 3, xf_prim_init_none }, \ + { "pagefillstretch", SET_PAGE_DIMEN, 4, xf_prim_init_none }, \ + { "pagefilllstretch", SET_PAGE_DIMEN, 5, xf_prim_init_none }, \ + { "pageshrink", SET_PAGE_DIMEN, 6, xf_prim_init_none }, \ + { "pagedepth", SET_PAGE_DIMEN, 7, xf_prim_init_none }, \ + { "deadcycles", SET_PAGE_INT, 0, xf_prim_init_none }, \ + { "insertpenalties", SET_PAGE_INT, 1, xf_prim_init_none }, \ + { "interactionmode", SET_PAGE_INT, 2, xf_prim_init_none }, \ + { "wd", SET_BOX_DIMEN, WIDTH_OFFSET, xf_prim_init_none }, \ + { "dp", SET_BOX_DIMEN, DEPTH_OFFSET, xf_prim_init_none }, \ + { "ht", SET_BOX_DIMEN, HEIGHT_OFFSET, xf_prim_init_none }, \ + { "catcode", DEF_CODE, CAT_CODE_BASE, xf_prim_init_none }, \ + { "lccode", DEF_CODE, LC_CODE_BASE, xf_prim_init_none }, \ + { "uccode", DEF_CODE, UC_CODE_BASE, xf_prim_init_none }, \ + { "sfcode", DEF_CODE, SF_CODE_BASE, xf_prim_init_none }, \ + { "mathcode", DEF_CODE, MATH_CODE_BASE, xf_prim_init_none }, \ + { "delcode", DEF_CODE, DEL_CODE_BASE, xf_prim_init_none }, \ + { "XeTeXcharclass", XETEX_DEF_CODE, SF_CODE_BASE, xf_prim_init_none }, \ + { "Umathcodenum", XETEX_DEF_CODE, MATH_CODE_BASE, xf_prim_init_none }, \ + { "XeTeXmathcodenum", XETEX_DEF_CODE, MATH_CODE_BASE, xf_prim_init_none }, \ + { "Umathcode", XETEX_DEF_CODE, MATH_CODE_BASE + 1, xf_prim_init_none }, \ + { "XeTeXmathcode", XETEX_DEF_CODE, MATH_CODE_BASE + 1, xf_prim_init_none }, \ + { "Udelcodenum", XETEX_DEF_CODE, DEL_CODE_BASE, xf_prim_init_none }, \ + { "XeTeXdelcodenum", XETEX_DEF_CODE, DEL_CODE_BASE, xf_prim_init_none }, \ + { "Udelcode", XETEX_DEF_CODE, DEL_CODE_BASE + 1, xf_prim_init_none }, \ + { "XeTeXdelcode", XETEX_DEF_CODE, DEL_CODE_BASE + 1, xf_prim_init_none }, \ + { "textfont", DEF_FAMILY, MATH_FONT_BASE + TEXT_SIZE, xf_prim_init_none }, \ + { "scriptfont", DEF_FAMILY, MATH_FONT_BASE + SCRIPT_SIZE, xf_prim_init_none }, \ + { "scriptscriptfont", DEF_FAMILY, MATH_FONT_BASE + SCRIPT_SCRIPT_SIZE, xf_prim_init_none }, \ + { "nullfont", SET_FONT, FONT_BASE, FROZEN_NULL_FONT }, \ + { "font", DEF_FONT, 0, xf_prim_init_none }, \ + { "count", REGISTER, 0, xf_prim_init_none }, \ + { "dimen", REGISTER, 1, xf_prim_init_none }, \ + { "skip", REGISTER, 2, xf_prim_init_none }, \ + { "muskip", REGISTER, 3, xf_prim_init_none }, \ + { "advance", ADVANCE, 0, xf_prim_init_none }, \ + { "multiply", MULTIPLY, 0, xf_prim_init_none }, \ + { "divide", DIVIDE, 0, xf_prim_init_none }, \ + { "long", PREFIX, 1, xf_prim_init_none }, \ + { "outer", PREFIX, 2, xf_prim_init_none }, \ + { "global", PREFIX, 4, xf_prim_init_none }, \ + { "protected", PREFIX, 8, xf_prim_init_none }, \ + { "let", LET, NORMAL, xf_prim_init_none }, \ + { "futurelet", LET, NORMAL + 1, xf_prim_init_none }, \ + { "chardef", SHORTHAND_DEF, CHAR_DEF_CODE, xf_prim_init_none }, \ + { "mathchardef", SHORTHAND_DEF, MATH_CHAR_DEF_CODE, xf_prim_init_none }, \ + { "countdef", SHORTHAND_DEF, COUNT_DEF_CODE, xf_prim_init_none }, \ + { "dimendef", SHORTHAND_DEF, DIMEN_DEF_CODE, xf_prim_init_none }, \ + { "skipdef", SHORTHAND_DEF, SKIP_DEF_CODE, xf_prim_init_none }, \ + { "muskipdef", SHORTHAND_DEF, MU_SKIP_DEF_CODE, xf_prim_init_none }, \ + { "toksdef", SHORTHAND_DEF, TOKS_DEF_CODE, xf_prim_init_none }, \ + { "Umathcharnumdef", SHORTHAND_DEF, XETEX_MATH_CHAR_NUM_DEF_CODE, xf_prim_init_none }, \ + { "XeTeXmathcharnumdef", SHORTHAND_DEF, XETEX_MATH_CHAR_NUM_DEF_CODE, xf_prim_init_none }, \ + { "Umathchardef", SHORTHAND_DEF, XETEX_MATH_CHAR_DEF_CODE, xf_prim_init_none }, \ + { "XeTeXmathchardef", SHORTHAND_DEF, XETEX_MATH_CHAR_DEF_CODE, xf_prim_init_none }, \ + { "read", READ_TO_CS, 0, xf_prim_init_none }, \ + { "readline", READ_TO_CS, 1, xf_prim_init_none }, \ + { "def", DEF, 0, xf_prim_init_none }, \ + { "gdef", DEF, 1, xf_prim_init_none }, \ + { "edef", DEF, 2, xf_prim_init_none }, \ + { "xdef", DEF, 3, xf_prim_init_none }, \ + { "setbox", SET_BOX, 0, xf_prim_init_none }, \ + { "hyphenation", HYPH_DATA, 0, xf_prim_init_none }, \ + { "patterns", HYPH_DATA, 1, xf_prim_init_none }, \ + { "batchmode", SET_INTERACTION, BATCH_MODE, xf_prim_init_none }, \ + { "nonstopmode", SET_INTERACTION, NONSTOP_MODE, xf_prim_init_none }, \ + { "scrollmode", SET_INTERACTION, SCROLL_MODE, xf_prim_init_none }, \ + { "errorstopmode", SET_INTERACTION, ERROR_STOP_MODE, xf_prim_init_none }, \ + { "expandafter", EXPAND_AFTER, 0, xf_prim_init_none }, \ + { "unless", EXPAND_AFTER, 1, xf_prim_init_none }, \ + { "noexpand", NO_EXPAND, 0, xf_prim_init_none }, \ + { "primitive", NO_EXPAND, 1, xf_prim_init_none }, \ + { "input", INPUT, 0, xf_prim_init_none }, \ + { "endinput", INPUT, 1, xf_prim_init_none }, \ + { "scantokens", INPUT, 2, xf_prim_init_none }, \ + { "if", IF_TEST, IF_CHAR_CODE, xf_prim_init_none }, \ + { "ifcat", IF_TEST, IF_CAT_CODE, xf_prim_init_none }, \ + { "ifnum", IF_TEST, IF_INT_CODE, xf_prim_init_none }, \ + { "ifdim", IF_TEST, IF_DIM_CODE, xf_prim_init_none }, \ + { "ifodd", IF_TEST, IF_ODD_CODE, xf_prim_init_none }, \ + { "ifvmode", IF_TEST, IF_VMODE_CODE, xf_prim_init_none }, \ + { "ifhmode", IF_TEST, IF_HMODE_CODE, xf_prim_init_none }, \ + { "ifmmode", IF_TEST, IF_MMODE_CODE, xf_prim_init_none }, \ + { "ifinner", IF_TEST, IF_INNER_CODE, xf_prim_init_none }, \ + { "ifvoid", IF_TEST, IF_VOID_CODE, xf_prim_init_none }, \ + { "ifhbox", IF_TEST, IF_HBOX_CODE, xf_prim_init_none }, \ + { "ifvbox", IF_TEST, IF_VBOX_CODE, xf_prim_init_none }, \ + { "ifx", IF_TEST, IFX_CODE, xf_prim_init_none }, \ + { "ifeof", IF_TEST, IF_EOF_CODE, xf_prim_init_none }, \ + { "iftrue", IF_TEST, IF_TRUE_CODE, xf_prim_init_none }, \ + { "iffalse", IF_TEST, IF_FALSE_CODE, xf_prim_init_none }, \ + { "ifcase", IF_TEST, IF_CASE_CODE, xf_prim_init_none }, \ + { "ifdefined", IF_TEST, IF_DEF_CODE, xf_prim_init_none }, \ + { "ifcsname", IF_TEST, IF_CS_CODE, xf_prim_init_none }, \ + { "iffontchar", IF_TEST, IF_FONT_CHAR_CODE, xf_prim_init_none }, \ + { "ifincsname", IF_TEST, IF_IN_CSNAME_CODE, xf_prim_init_none }, \ + { "ifprimitive", IF_TEST, IF_PRIMITIVE_CODE, xf_prim_init_none }, \ + { "fi", FI_OR_ELSE, FI_CODE, FROZEN_FI }, \ + { "else", FI_OR_ELSE, ELSE_CODE, xf_prim_init_none }, \ + { "or", FI_OR_ELSE, OR_CODE, xf_prim_init_none }, \ + { "csname", CS_NAME, 0, xf_prim_init_none }, \ + { "number", CONVERT, NUMBER_CODE, xf_prim_init_none }, \ + { "romannumeral", CONVERT, ROMAN_NUMERAL_CODE, xf_prim_init_none }, \ + { "string", CONVERT, STRING_CODE, xf_prim_init_none }, \ + { "meaning", CONVERT, MEANING_CODE, xf_prim_init_none }, \ + { "fontname", CONVERT, FONT_NAME_CODE, xf_prim_init_none }, \ + { "eTeXrevision", CONVERT, ETEX_REVISION_CODE, xf_prim_init_none }, \ + { "expanded", CONVERT, EXPANDED_CODE, xf_prim_init_none }, \ + { "leftmarginkern", CONVERT, LEFT_MARGIN_KERN_CODE, xf_prim_init_none }, \ + { "rightmarginkern", CONVERT, RIGHT_MARGIN_KERN_CODE, xf_prim_init_none }, \ + { "strcmp", CONVERT, PDF_STRCMP_CODE, xf_prim_init_none }, \ + { "creationdate", CONVERT, PDF_CREATION_DATE_CODE, xf_prim_init_none }, \ + { "filemoddate", CONVERT, PDF_FILE_MOD_DATE_CODE, xf_prim_init_none }, \ + { "filesize", CONVERT, PDF_FILE_SIZE_CODE, xf_prim_init_none }, \ + { "mdfivesum", CONVERT, PDF_MDFIVE_SUM_CODE, xf_prim_init_none }, \ + { "filedump", CONVERT, PDF_FILE_DUMP_CODE, xf_prim_init_none }, \ + { "uniformdeviate", CONVERT, UNIFORM_DEVIATE_CODE, xf_prim_init_none }, \ + { "normaldeviate", CONVERT, NORMAL_DEVIATE_CODE, xf_prim_init_none }, \ + { "XeTeXvariationname", CONVERT, XETEX_VARIATION_NAME_CODE, xf_prim_init_none }, \ + { "XeTeXrevision", CONVERT, XETEX_REVISION_CODE, xf_prim_init_none }, \ + { "XeTeXfeaturename", CONVERT, XETEX_FEATURE_NAME_CODE, xf_prim_init_none }, \ + { "XeTeXselectorname", CONVERT, XETEX_SELECTOR_NAME_CODE, xf_prim_init_none }, \ + { "XeTeXglyphname", CONVERT, XETEX_GLYPH_NAME_CODE, xf_prim_init_none }, \ + { "Uchar", CONVERT, XETEX_UCHAR_CODE, xf_prim_init_none }, \ + { "Ucharcat", CONVERT, XETEX_UCHARCAT_CODE, xf_prim_init_none }, \ + { "jobname", CONVERT, JOB_NAME_CODE, xf_prim_init_none }, \ + { "the", THE, 0, xf_prim_init_none }, \ + { "unexpanded", THE, 1, xf_prim_init_none }, \ + { "detokenize", THE, SHOW_TOKENS, xf_prim_init_none }, \ + { "topmark", TOP_BOT_MARK, TOP_MARK_CODE, xf_prim_init_none }, \ + { "firstmark", TOP_BOT_MARK, FIRST_MARK_CODE, xf_prim_init_none }, \ + { "botmark", TOP_BOT_MARK, BOT_MARK_CODE, xf_prim_init_none }, \ + { "splitfirstmark", TOP_BOT_MARK, SPLIT_FIRST_MARK_CODE, xf_prim_init_none }, \ + { "splitbotmark", TOP_BOT_MARK, SPLIT_BOT_MARK_CODE, xf_prim_init_none }, \ + { "topmarks", TOP_BOT_MARK, TOP_MARK_CODE + 5, xf_prim_init_none }, \ + { "firstmarks", TOP_BOT_MARK, FIRST_MARK_CODE + 5, xf_prim_init_none }, \ + { "botmarks", TOP_BOT_MARK, BOT_MARK_CODE + 5, xf_prim_init_none }, \ + { "splitfirstmarks", TOP_BOT_MARK, SPLIT_FIRST_MARK_CODE + 5, xf_prim_init_none }, \ + { "splitbotmarks", TOP_BOT_MARK, SPLIT_BOT_MARK_CODE + 5, xf_prim_init_none }, \ + { "pretolerance", ASSIGN_INT, INT_BASE + INT_PAR__pretolerance, xf_prim_init_none }, \ + { "tolerance", ASSIGN_INT, INT_BASE + INT_PAR__tolerance, xf_prim_init_none }, \ + { "linepenalty", ASSIGN_INT, INT_BASE + INT_PAR__line_penalty, xf_prim_init_none }, \ + { "hyphenpenalty", ASSIGN_INT, INT_BASE + INT_PAR__hyphen_penalty, xf_prim_init_none }, \ + { "exhyphenpenalty", ASSIGN_INT, INT_BASE + INT_PAR__ex_hyphen_penalty, xf_prim_init_none }, \ + { "clubpenalty", ASSIGN_INT, INT_BASE + INT_PAR__club_penalty, xf_prim_init_none }, \ + { "widowpenalty", ASSIGN_INT, INT_BASE + INT_PAR__widow_penalty, xf_prim_init_none }, \ + { "displaywidowpenalty", ASSIGN_INT, INT_BASE + INT_PAR__display_widow_penalty, xf_prim_init_none }, \ + { "brokenpenalty", ASSIGN_INT, INT_BASE + INT_PAR__broken_penalty, xf_prim_init_none }, \ + { "binoppenalty", ASSIGN_INT, INT_BASE + INT_PAR__bin_op_penalty, xf_prim_init_none }, \ + { "relpenalty", ASSIGN_INT, INT_BASE + INT_PAR__rel_penalty, xf_prim_init_none }, \ + { "predisplaypenalty", ASSIGN_INT, INT_BASE + INT_PAR__pre_display_penalty, xf_prim_init_none }, \ + { "postdisplaypenalty", ASSIGN_INT, INT_BASE + INT_PAR__post_display_penalty, xf_prim_init_none }, \ + { "interlinepenalty", ASSIGN_INT, INT_BASE + INT_PAR__inter_line_penalty, xf_prim_init_none }, \ + { "doublehyphendemerits", ASSIGN_INT, INT_BASE + INT_PAR__double_hyphen_demerits, xf_prim_init_none }, \ + { "finalhyphendemerits", ASSIGN_INT, INT_BASE + INT_PAR__final_hyphen_demerits, xf_prim_init_none }, \ + { "adjdemerits", ASSIGN_INT, INT_BASE + INT_PAR__adj_demerits, xf_prim_init_none }, \ + { "mag", ASSIGN_INT, INT_BASE + INT_PAR__mag, xf_prim_init_none }, \ + { "delimiterfactor", ASSIGN_INT, INT_BASE + INT_PAR__delimiter_factor, xf_prim_init_none }, \ + { "looseness", ASSIGN_INT, INT_BASE + INT_PAR__looseness, xf_prim_init_none }, \ + { "time", ASSIGN_INT, INT_BASE + INT_PAR__time, xf_prim_init_none }, \ + { "day", ASSIGN_INT, INT_BASE + INT_PAR__day, xf_prim_init_none }, \ + { "month", ASSIGN_INT, INT_BASE + INT_PAR__month, xf_prim_init_none }, \ + { "year", ASSIGN_INT, INT_BASE + INT_PAR__year, xf_prim_init_none }, \ + { "showboxbreadth", ASSIGN_INT, INT_BASE + INT_PAR__show_box_breadth, xf_prim_init_none }, \ + { "showboxdepth", ASSIGN_INT, INT_BASE + INT_PAR__show_box_depth, xf_prim_init_none }, \ + { "hbadness", ASSIGN_INT, INT_BASE + INT_PAR__hbadness, xf_prim_init_none }, \ + { "vbadness", ASSIGN_INT, INT_BASE + INT_PAR__vbadness, xf_prim_init_none }, \ + { "pausing", ASSIGN_INT, INT_BASE + INT_PAR__pausing, xf_prim_init_none }, \ + { "tracingonline", ASSIGN_INT, INT_BASE + INT_PAR__tracing_online, xf_prim_init_none }, \ + { "tracingmacros", ASSIGN_INT, INT_BASE + INT_PAR__tracing_macros, xf_prim_init_none }, \ + { "tracingstats", ASSIGN_INT, INT_BASE + INT_PAR__tracing_stats, xf_prim_init_none }, \ + { "tracingparagraphs", ASSIGN_INT, INT_BASE + INT_PAR__tracing_paragraphs, xf_prim_init_none }, \ + { "tracingpages", ASSIGN_INT, INT_BASE + INT_PAR__tracing_pages, xf_prim_init_none }, \ + { "tracingoutput", ASSIGN_INT, INT_BASE + INT_PAR__tracing_output, xf_prim_init_none }, \ + { "tracinglostchars", ASSIGN_INT, INT_BASE + INT_PAR__tracing_lost_chars, xf_prim_init_none }, \ + { "tracingcommands", ASSIGN_INT, INT_BASE + INT_PAR__tracing_commands, xf_prim_init_none }, \ + { "tracingrestores", ASSIGN_INT, INT_BASE + INT_PAR__tracing_restores, xf_prim_init_none }, \ + { "uchyph", ASSIGN_INT, INT_BASE + INT_PAR__uc_hyph, xf_prim_init_none }, \ + { "outputpenalty", ASSIGN_INT, INT_BASE + INT_PAR__output_penalty, xf_prim_init_none }, \ + { "maxdeadcycles", ASSIGN_INT, INT_BASE + INT_PAR__max_dead_cycles, xf_prim_init_none }, \ + { "hangafter", ASSIGN_INT, INT_BASE + INT_PAR__hang_after, xf_prim_init_none }, \ + { "floatingpenalty", ASSIGN_INT, INT_BASE + INT_PAR__floating_penalty, xf_prim_init_none }, \ + { "globaldefs", ASSIGN_INT, INT_BASE + INT_PAR__global_defs, xf_prim_init_none }, \ + { "fam", ASSIGN_INT, INT_BASE + INT_PAR__cur_fam, xf_prim_init_none }, \ + { "escapechar", ASSIGN_INT, INT_BASE + INT_PAR__escape_char, xf_prim_init_none }, \ + { "defaulthyphenchar", ASSIGN_INT, INT_BASE + INT_PAR__default_hyphen_char, xf_prim_init_none }, \ + { "defaultskewchar", ASSIGN_INT, INT_BASE + INT_PAR__default_skew_char, xf_prim_init_none }, \ + { "endlinechar", ASSIGN_INT, INT_BASE + INT_PAR__end_line_char, xf_prim_init_none }, \ + { "newlinechar", ASSIGN_INT, INT_BASE + INT_PAR__new_line_char, xf_prim_init_none }, \ + { "language", ASSIGN_INT, INT_BASE + INT_PAR__language, xf_prim_init_none }, \ + { "lefthyphenmin", ASSIGN_INT, INT_BASE + INT_PAR__left_hyphen_min, xf_prim_init_none }, \ + { "righthyphenmin", ASSIGN_INT, INT_BASE + INT_PAR__right_hyphen_min, xf_prim_init_none }, \ + { "holdinginserts", ASSIGN_INT, INT_BASE + INT_PAR__holding_inserts, xf_prim_init_none }, \ + { "errorcontextlines", ASSIGN_INT, INT_BASE + INT_PAR__error_context_lines, xf_prim_init_none }, \ + { "tracingassigns", ASSIGN_INT, INT_BASE + INT_PAR__tracing_assigns, xf_prim_init_none }, \ + { "tracinggroups", ASSIGN_INT, INT_BASE + INT_PAR__tracing_groups, xf_prim_init_none }, \ + { "tracingifs", ASSIGN_INT, INT_BASE + INT_PAR__tracing_ifs, xf_prim_init_none }, \ + { "tracingscantokens", ASSIGN_INT, INT_BASE + INT_PAR__tracing_scan_tokens, xf_prim_init_none }, \ + { "tracingnesting", ASSIGN_INT, INT_BASE + INT_PAR__tracing_nesting, xf_prim_init_none }, \ + { "predisplaydirection", ASSIGN_INT, INT_BASE + INT_PAR__pre_display_direction, xf_prim_init_none }, \ + { "lastlinefit", ASSIGN_INT, INT_BASE + INT_PAR__last_line_fit, xf_prim_init_none }, \ + { "savingvdiscards", ASSIGN_INT, INT_BASE + INT_PAR__saving_vdiscards, xf_prim_init_none }, \ + { "savinghyphcodes", ASSIGN_INT, INT_BASE + INT_PAR__saving_hyph_codes, xf_prim_init_none }, \ + { "suppressfontnotfounderror", ASSIGN_INT, INT_BASE + INT_PAR__suppress_fontnotfound_error, xf_prim_init_none }, \ + { "XeTeXlinebreakpenalty", ASSIGN_INT, INT_BASE + INT_PAR__xetex_linebreak_penalty, xf_prim_init_none }, \ + { "XeTeXprotrudechars", ASSIGN_INT, INT_BASE + INT_PAR__xetex_protrude_chars, xf_prim_init_none }, \ + { "TeXXeTstate", ASSIGN_INT, INT_BASE + INT_PAR__texxet, xf_prim_init_none }, \ + { "XeTeXdashbreakstate", ASSIGN_INT, INT_BASE + INT_PAR__xetex_dash_break, xf_prim_init_none }, \ + { "XeTeXupwardsmode", ASSIGN_INT, INT_BASE + INT_PAR__xetex_upwards, xf_prim_init_none }, \ + { "XeTeXuseglyphmetrics", ASSIGN_INT, INT_BASE + INT_PAR__xetex_use_glyph_metrics, xf_prim_init_none }, \ + { "XeTeXinterchartokenstate", ASSIGN_INT, INT_BASE + INT_PAR__xetex_inter_char_tokens, xf_prim_init_none }, \ + { "XeTeXinputnormalization", ASSIGN_INT, INT_BASE + INT_PAR__xetex_input_normalization, xf_prim_init_none }, \ + { "XeTeXtracingfonts", ASSIGN_INT, INT_BASE + INT_PAR__xetex_tracing_fonts, xf_prim_init_none }, \ + { "XeTeXinterwordspaceshaping", ASSIGN_INT, INT_BASE + INT_PAR__xetex_interword_space_shaping, xf_prim_init_none }, \ + { "XeTeXgenerateactualtext", ASSIGN_INT, INT_BASE + INT_PAR__xetex_generate_actual_text, xf_prim_init_none }, \ + { "XeTeXhyphenatablelength", ASSIGN_INT, INT_BASE + INT_PAR__xetex_hyphenatable_length, xf_prim_init_none }, \ + { "synctex", ASSIGN_INT, INT_BASE + INT_PAR__synctex, xf_prim_init_none }, \ + { "pdfoutput", ASSIGN_INT, INT_BASE + INT_PAR__pdfoutput, xf_prim_init_none }, \ + { "parindent", ASSIGN_DIMEN, DIMEN_BASE + DIMEN_PAR__par_indent, xf_prim_init_none }, \ + { "mathsurround", ASSIGN_DIMEN, DIMEN_BASE + DIMEN_PAR__math_surround, xf_prim_init_none }, \ + { "lineskiplimit", ASSIGN_DIMEN, DIMEN_BASE + DIMEN_PAR__line_skip_limit, xf_prim_init_none }, \ + { "hsize", ASSIGN_DIMEN, DIMEN_BASE + DIMEN_PAR__hsize, xf_prim_init_none }, \ + { "vsize", ASSIGN_DIMEN, DIMEN_BASE + DIMEN_PAR__vsize, xf_prim_init_none }, \ + { "maxdepth", ASSIGN_DIMEN, DIMEN_BASE + DIMEN_PAR__max_depth, xf_prim_init_none }, \ + { "splitmaxdepth", ASSIGN_DIMEN, DIMEN_BASE + DIMEN_PAR__split_max_depth, xf_prim_init_none }, \ + { "boxmaxdepth", ASSIGN_DIMEN, DIMEN_BASE + DIMEN_PAR__box_max_depth, xf_prim_init_none }, \ + { "hfuzz", ASSIGN_DIMEN, DIMEN_BASE + DIMEN_PAR__hfuzz, xf_prim_init_none }, \ + { "vfuzz", ASSIGN_DIMEN, DIMEN_BASE + DIMEN_PAR__vfuzz, xf_prim_init_none }, \ + { "delimitershortfall", ASSIGN_DIMEN, DIMEN_BASE + DIMEN_PAR__delimiter_shortfall, xf_prim_init_none }, \ + { "nulldelimiterspace", ASSIGN_DIMEN, DIMEN_BASE + DIMEN_PAR__null_delimiter_space, xf_prim_init_none }, \ + { "scriptspace", ASSIGN_DIMEN, DIMEN_BASE + DIMEN_PAR__script_space, xf_prim_init_none }, \ + { "predisplaysize", ASSIGN_DIMEN, DIMEN_BASE + DIMEN_PAR__pre_display_size, xf_prim_init_none }, \ + { "displaywidth", ASSIGN_DIMEN, DIMEN_BASE + DIMEN_PAR__display_width, xf_prim_init_none }, \ + { "displayindent", ASSIGN_DIMEN, DIMEN_BASE + DIMEN_PAR__display_indent, xf_prim_init_none }, \ + { "overfullrule", ASSIGN_DIMEN, DIMEN_BASE + DIMEN_PAR__overfull_rule, xf_prim_init_none }, \ + { "hangindent", ASSIGN_DIMEN, DIMEN_BASE + DIMEN_PAR__hang_indent, xf_prim_init_none }, \ + { "hoffset", ASSIGN_DIMEN, DIMEN_BASE + DIMEN_PAR__h_offset, xf_prim_init_none }, \ + { "voffset", ASSIGN_DIMEN, DIMEN_BASE + DIMEN_PAR__v_offset, xf_prim_init_none }, \ + { "emergencystretch", ASSIGN_DIMEN, DIMEN_BASE + DIMEN_PAR__emergency_stretch, xf_prim_init_none }, \ + { "pdfpagewidth", ASSIGN_DIMEN, DIMEN_BASE + DIMEN_PAR__pdf_page_width, xf_prim_init_none }, \ + { "pdfpageheight", ASSIGN_DIMEN, DIMEN_BASE + DIMEN_PAR__pdf_page_height, xf_prim_init_none }, \ + { "lineskip", ASSIGN_GLUE, GLUE_BASE + GLUE_PAR__line_skip, xf_prim_init_none }, \ + { "baselineskip", ASSIGN_GLUE, GLUE_BASE + GLUE_PAR__baseline_skip, xf_prim_init_none }, \ + { "parskip", ASSIGN_GLUE, GLUE_BASE + GLUE_PAR__par_skip, xf_prim_init_none }, \ + { "abovedisplayskip", ASSIGN_GLUE, GLUE_BASE + GLUE_PAR__above_display_skip, xf_prim_init_none }, \ + { "belowdisplayskip", ASSIGN_GLUE, GLUE_BASE + GLUE_PAR__below_display_skip, xf_prim_init_none }, \ + { "abovedisplayshortskip", ASSIGN_GLUE, GLUE_BASE + GLUE_PAR__above_display_short_skip, xf_prim_init_none }, \ + { "belowdisplayshortskip", ASSIGN_GLUE, GLUE_BASE + GLUE_PAR__below_display_short_skip, xf_prim_init_none }, \ + { "leftskip", ASSIGN_GLUE, GLUE_BASE + GLUE_PAR__left_skip, xf_prim_init_none }, \ + { "rightskip", ASSIGN_GLUE, GLUE_BASE + GLUE_PAR__right_skip, xf_prim_init_none }, \ + { "topskip", ASSIGN_GLUE, GLUE_BASE + GLUE_PAR__top_skip, xf_prim_init_none }, \ + { "splittopskip", ASSIGN_GLUE, GLUE_BASE + GLUE_PAR__split_top_skip, xf_prim_init_none }, \ + { "tabskip", ASSIGN_GLUE, GLUE_BASE + GLUE_PAR__tab_skip, xf_prim_init_none }, \ + { "spaceskip", ASSIGN_GLUE, GLUE_BASE + GLUE_PAR__space_skip, xf_prim_init_none }, \ + { "xspaceskip", ASSIGN_GLUE, GLUE_BASE + GLUE_PAR__xspace_skip, xf_prim_init_none }, \ + { "parfillskip", ASSIGN_GLUE, GLUE_BASE + GLUE_PAR__par_fill_skip, xf_prim_init_none }, \ + { "XeTeXlinebreakskip", ASSIGN_GLUE, GLUE_BASE + GLUE_PAR__xetex_linebreak_skip, xf_prim_init_none }, \ + { "thinmuskip", ASSIGN_MU_GLUE, GLUE_BASE + GLUE_PAR__thin_mu_skip, xf_prim_init_none }, \ + { "medmuskip", ASSIGN_MU_GLUE, GLUE_BASE + GLUE_PAR__med_mu_skip, xf_prim_init_none }, \ + { "thickmuskip", ASSIGN_MU_GLUE, GLUE_BASE + GLUE_PAR__thick_mu_skip, xf_prim_init_none }, \ + { "parshape", SET_SHAPE, LOCAL_BASE + LOCAL__par_shape, xf_prim_init_none }, \ + { "output", ASSIGN_TOKS, LOCAL_BASE + LOCAL__output_routine, xf_prim_init_none }, \ + { "everypar", ASSIGN_TOKS, LOCAL_BASE + LOCAL__every_par, xf_prim_init_none }, \ + { "everymath", ASSIGN_TOKS, LOCAL_BASE + LOCAL__every_math, xf_prim_init_none }, \ + { "everydisplay", ASSIGN_TOKS, LOCAL_BASE + LOCAL__every_display, xf_prim_init_none }, \ + { "everyhbox", ASSIGN_TOKS, LOCAL_BASE + LOCAL__every_hbox, xf_prim_init_none }, \ + { "everyvbox", ASSIGN_TOKS, LOCAL_BASE + LOCAL__every_vbox, xf_prim_init_none }, \ + { "everyjob", ASSIGN_TOKS, LOCAL_BASE + LOCAL__every_job, xf_prim_init_none }, \ + { "everycr", ASSIGN_TOKS, LOCAL_BASE + LOCAL__every_cr, xf_prim_init_none }, \ + { "errhelp", ASSIGN_TOKS, LOCAL_BASE + LOCAL__err_help, xf_prim_init_none }, \ + { "everyeof", ASSIGN_TOKS, LOCAL_BASE + LOCAL__every_eof, xf_prim_init_none }, \ + { "XeTeXinterchartoks", ASSIGN_TOKS, LOCAL_BASE + LOCAL__xetex_inter_char_toks, xf_prim_init_none }, \ + { "TectonicCodaTokens", ASSIGN_TOKS, LOCAL_BASE + LOCAL__tectonic_coda_tokens, xf_prim_init_none }, \ + { "interlinepenalties", SET_SHAPE, ETEX_PEN_BASE + ETEX_PENALTIES_PAR__inter_line_penalties, xf_prim_init_none }, \ + { "clubpenalties", SET_SHAPE, ETEX_PEN_BASE + ETEX_PENALTIES_PAR__club_penalties, xf_prim_init_none }, \ + { "widowpenalties", SET_SHAPE, ETEX_PEN_BASE + ETEX_PENALTIES_PAR__widow_penalties, xf_prim_init_none }, \ + { "displaywidowpenalties", SET_SHAPE, ETEX_PEN_BASE + ETEX_PENALTIES_PAR__display_widow_penalties, xf_prim_init_none }, \ + { NULL, 0, 0, 0 } +#endif diff --git a/crates/xetex_format/CHANGELOG.md b/crates/xetex_format/CHANGELOG.md new file mode 100644 index 000000000..50660d57f --- /dev/null +++ b/crates/xetex_format/CHANGELOG.md @@ -0,0 +1,8 @@ +# See elsewhere for changelog + +This project’s release notes are curated from the Git history of its main +branch. You can find them by looking at [the version of this file on the +`release` branch][branch] or the [GitHub release history][gh-releases]. + +[branch]: https://github.com/tectonic-typesetting/tectonic/blob/release/crates/xetex_format/CHANGELOG.md +[gh-releases]: https://github.com/tectonic-typesetting/tectonic/releases diff --git a/crates/xetex_format/Cargo.toml b/crates/xetex_format/Cargo.toml new file mode 100644 index 000000000..7f4dcc775 --- /dev/null +++ b/crates/xetex_format/Cargo.toml @@ -0,0 +1,29 @@ +# Copyright 2021 the Tectonic Project +# Licensed under the MIT License. + +# See README.md for discussion of features (or lack thereof) in this crate. + +[package] +name = "tectonic_xetex_format" +version = "0.0.0-dev.0" # assigned with cranko (see README) +authors = ["Peter Williams "] +description = """ +Tectonic/XeTeX engine data structures and their expression in TeX "format" files. +""" +homepage = "https://tectonic-typesetting.github.io/" +documentation = "https://docs.rs/tectonic_xetex_format" +repository = "https://github.com/tectonic-typesetting/tectonic/" +readme = "README.md" +license = "MIT" +edition = "2018" + +[dependencies] +byteorder = "^1" +nom = "^7" +tectonic_errors = { path = "../errors", version = "0.0.0-dev.0" } + +[dev-dependencies] +clap = "^2.33" + +[package.metadata.internal_dep_versions] +tectonic_errors = "e04798bcd9b1c1d68cc0a318a710bb30230a0300" diff --git a/crates/xetex_format/README.md b/crates/xetex_format/README.md new file mode 100644 index 000000000..6de22cee9 --- /dev/null +++ b/crates/xetex_format/README.md @@ -0,0 +1,26 @@ +# The `tectonic_xetex_format` crate + +[![](http://meritbadge.herokuapp.com/tectonic_xetex_format)](https://crates.io/crates/tectonic_xetex_format) + +This crate is part of [the Tectonic +project](https://tectonic-typesetting.github.io/en-US/). It provides +introspection of the internal data structures of the Tectonic/[XeTeX] engine and +their serialization into "format files". + +[XeTeX]: http://xetex.sourceforge.net/ + +- [API documentation](https://docs.rs/tectonic_xetex_format/). +- [Main Git repository](https://github.com/tectonic-typesetting/tectonic/). + +This crate has two main uses: you can use it to decode an existing format file +and introspect the detailed setup that it encodes; or you can use it to emit a C +header file defining magic constants in the engine implementation. The former +usage isn't fully developed yet, but many of the key pieces have been +implemented. + + +## Cargo features + +This crate currently provides no [Cargo features][features]. + +[features]: https://doc.rust-lang.org/cargo/reference/features.html diff --git a/crates/xetex_format/examples/decode.rs b/crates/xetex_format/examples/decode.rs new file mode 100644 index 000000000..c49779a58 --- /dev/null +++ b/crates/xetex_format/examples/decode.rs @@ -0,0 +1,38 @@ +// Copyright 2021 the Tectonic Project +// Licensed under the MIT License. + +//! Decode a format file. + +use clap::{crate_version, App, Arg, ArgMatches}; +use std::{fs::File, io::Read, process}; +use tectonic_errors::prelude::*; +use tectonic_xetex_format::format::Format; + +fn inner(matches: ArgMatches) -> Result<()> { + let path = matches.value_of_os("PATH").unwrap(); + let mut file = File::open(&path)?; + let mut data = Vec::new(); + file.read_to_end(&mut data)?; + + let _fmt = Format::parse(&data[..])?; + println!("ok!"); + Ok(()) +} + +fn main() { + let matches = App::new("decode") + .version(crate_version!()) + .about("Decode a format file") + .arg( + Arg::with_name("PATH") + .help("The path to the format file") + .required(true) + .index(1), + ) + .get_matches(); + + if let Err(e) = inner(matches) { + eprintln!("error: {}", e); + process::exit(1); + } +} diff --git a/crates/xetex_format/examples/emit.rs b/crates/xetex_format/examples/emit.rs new file mode 100644 index 000000000..1c9300bf0 --- /dev/null +++ b/crates/xetex_format/examples/emit.rs @@ -0,0 +1,23 @@ +// Copyright 2021 the Tectonic Project +// Licensed under the MIT License. + +//! Emit the C header file for the current engine version + +use std::{io, process}; +use tectonic_errors::prelude::*; +use tectonic_xetex_format::engine::Engine; + +fn inner() -> Result<()> { + let engine = Engine::default(); + let stdout = io::stdout(); + let lock = stdout.lock(); + engine.emit_c_header(lock)?; + Ok(()) +} + +fn main() { + if let Err(e) = inner() { + eprintln!("error: {}", e); + process::exit(1); + } +} diff --git a/crates/xetex_format/src/base.rs b/crates/xetex_format/src/base.rs new file mode 100644 index 000000000..37dbe773c --- /dev/null +++ b/crates/xetex_format/src/base.rs @@ -0,0 +1,120 @@ +// Copyright 2021 the Tectonic Project +// Licensed under the MIT License. + +//! Truly basic definitions relating to the XeTeX engine. +//! +//! We don't expect these types and constants to ever change. + +use byteorder::ByteOrder; + +/// The `byteorder` endianness of Tectonic format files. +pub use byteorder::BigEndian as FormatEndian; + +/// The number of Unicode Scalar Values. +pub const NUMBER_USVS: usize = 0x11_0000; + +/// The number of basic TeX register. +pub const NUMBER_REGS: usize = 256; + +/// The number of TeX math fonts. +pub const NUMBER_MATH_FONTS: usize = 3 * 256; + +/// The number of bytes in a TeX "memory word" variable. +pub const SIZEOF_MEMORY_WORD: usize = 8; + +/// The minimum allowed value of a TeX "halfword" variable +pub const MIN_HALFWORD: i32 = -0x0FFF_FFFF; // = -268,435,455 = 0xF000_0001 + +/// The maximum allowed value of a TeX "halfword" variable +pub const MAX_HALFWORD: i32 = 0x3FFF_FFFF; // = 1,073,741,823 + +/// The value of a "null" memory pointer in TeX. +pub const TEX_NULL: i32 = MIN_HALFWORD; + +/// Read the value of the `b16.s0` field of the *index*'th word in *arr*. +/// +/// This is also known as the `hh.u.B1` field in WEB2C or `hh.b1` in WEB. Note +/// that the index is counted in "memory word" units, e.g. 8 bytes, not single +/// bytes. +#[inline(always)] +pub fn memword_read_b16_s0(arr: &[u8], index: i32) -> i16 { + let i = index as usize * SIZEOF_MEMORY_WORD; + FormatEndian::read_i16(&arr[i + 6..i + 8]) +} + +/// Read the value of the `b16.s1` field of the *index*'th word in *arr*. +/// +/// This is also known as the `hh.u.B0` field in WEB2C or `hh.b0` in WEB. Note +/// that the index is counted in "memory word" units, e.g. 8 bytes, not single +/// bytes. +#[inline(always)] +pub fn memword_read_b16_s1(arr: &[u8], index: i32) -> i16 { + let i = index as usize * SIZEOF_MEMORY_WORD; + FormatEndian::read_i16(&arr[i + 4..i + 6]) +} + +/// Read the value of the `b32.s0` field of the *index*'th word in *arr*. +/// +/// This is also known as the `hh.v.LH` field in WEB2C or `hh.lh` in WEB. Note +/// that the index is counted in "memory word" units, e.g. 8 bytes, not single +/// bytes. +#[inline(always)] +pub fn memword_read_b32_s0(arr: &[u8], index: i32) -> i32 { + let i = index as usize * SIZEOF_MEMORY_WORD; + FormatEndian::read_i32(&arr[i + 4..i + 8]) +} + +/// Read the *value* of the `b32.s1` field of the *index*'th word in *arr*. +/// +/// This is also known as the `hh.v.RH` field in WEB2C or `hh.rh` in WEB. Note +/// that the index is counted in "memory word" units, e.g. 8 bytes, not single +/// bytes. +#[inline(always)] +pub fn memword_read_b32_s1(arr: &[u8], index: i32) -> i32 { + let i = index as usize * SIZEOF_MEMORY_WORD; + FormatEndian::read_i32(&arr[i..i + 4]) +} + +/// Write *value* to the `b16.s0` field of the *index*'th word in *arr*. +/// +/// This is also known as the `hh.u.B1` field in WEB2C or `hh.b1` in WEB. Note +/// that the index is counted in "memory word" units, e.g. 8 bytes, not single +/// bytes. +#[inline(always)] +pub fn memword_write_b16_s0(arr: &mut [u8], index: i32, value: i16) { + let i = index as usize * SIZEOF_MEMORY_WORD; + FormatEndian::write_i16(&mut arr[i + 6..i + 8], value); +} + +/// Write *value* to the `b16.s1` field of the *index*'th word in *arr*. +/// +/// This is also known as the `hh.u.B0` field in WEB2C or `hh.b0` in WEB. Note +/// that the index is counted in "memory word" units, e.g. 8 bytes, not single +/// bytes. +#[inline(always)] +pub fn memword_write_b16_s1(arr: &mut [u8], index: i32, value: i16) { + let i = index as usize * SIZEOF_MEMORY_WORD; + FormatEndian::write_i16(&mut arr[i + 4..i + 6], value); +} + +/// Write *value* to the `b32.s0` field of the *index*'th word in *arr*. +/// +/// This is also known as the `hh.v.LH` field in WEB2C or `hh.lh` in WEB. Note +/// that the index is counted in "memory word" units, e.g. 8 bytes, not single +/// bytes. +#[inline(always)] +pub fn memword_write_b32_s0(arr: &mut [u8], index: i32, value: i32) { + let i = index as usize * SIZEOF_MEMORY_WORD; + FormatEndian::write_i32(&mut arr[i + 4..i + 8], value); +} + +/// Write *value* to the `b32.s1` field of the *index*'th word in *arr*. +/// +/// This is also known as the `hh.v.RH` field in WEB2C or `hh.rh` in WEB. Note +/// that the index is counted in "memory word" units, e.g. 8 bytes, not single +/// bytes. +#[inline(always)] +pub fn memword_write_b32_s1(arr: &mut [u8], index: i32, value: i32) { + let i = index as usize * SIZEOF_MEMORY_WORD; + FormatEndian::write_i32(&mut arr[i..i + 4], value); +} diff --git a/crates/xetex_format/src/commands.rs b/crates/xetex_format/src/commands.rs new file mode 100644 index 000000000..f533534fc --- /dev/null +++ b/crates/xetex_format/src/commands.rs @@ -0,0 +1,2997 @@ +// Copyright 2021 the Tectonic Project +// Licensed under the MIT License. + +//#![deny(missing_docs)] + +//! The low-level primitive commands provided by the engine. + +use std::io::{Result, Write}; + +use super::FormatVersion; + +pub type CommandCode = i16; +pub type CommandArgument = i32; + +/// Information about commands. +#[derive(Clone, Copy, Debug)] +pub struct Command { + /// The symbolic name of the command in WEB2C. + pub web2cname: &'static str, + + /// An alternative name for the command used in TeX's parser. Some commands + /// can never make it out of the parser, so their associated codes are + /// re-used deeper inside the engine. + pub parser_overload_name: Option<&'static str>, + + /// An alternative name for the command used in macro token lists. + pub macro_overload_name: Option<&'static str>, + + /// The semantics of the command argument value stored in TeX's `cur_chr` + /// variable. + pub arg_type: ArgumentType, + + /// The TeX primitives associated with the command. + pub primitives: &'static [CommandPrimitive], + + /// The first format version in which the command was introduced. + pub since: FormatVersion, +} + +/// Different TeX command argument semantics. +#[derive(Clone, Copy, Debug)] +pub enum ArgumentType { + /// This command has not yet had its argument type properly annotated. + Unspecified, + + /// The argument is unused (and should probably be zero). + Unused, + + /// The argument is a character (that is, a Unicode Scalar Value). + Character, +} + +/// A TeX primitive associated with a command. +#[derive(Clone, Copy, Debug)] +pub struct CommandPrimitive { + pub name: &'static str, + + pub arg: &'static str, + + pub init: PrimitiveExtraInit, +} + +/// Special initialization to be done after a primitive is created. +/// +/// These operations usually involve initialization of the special "frozen" +/// primitives in the eqtb. +#[derive(Clone, Copy, Debug)] +pub enum PrimitiveExtraInit { + /// No extra initialization. + None, + + /// This is `\par`: initialize `par_loc` and `par_token`. + Par, + + /// This is `\write`: initialize `write_loc` + Write, + + /// This is a frozen primitive: initialize a frozen copy + Frozen(&'static str), +} + +const COMMANDS: &[Command] = &[ + Command { + web2cname: "RELAX", + parser_overload_name: Some("ESCAPE"), + macro_overload_name: None, + arg_type: ArgumentType::Unused, + primitives: &[CommandPrimitive { + name: "relax", + arg: "TOO_BIG_USV", + init: PrimitiveExtraInit::Frozen("FROZEN_RELAX"), + }], + since: 0, + }, + Command { + web2cname: "LEFT_BRACE", + parser_overload_name: None, + macro_overload_name: None, + arg_type: ArgumentType::Character, + primitives: &[], + since: 0, + }, + Command { + web2cname: "RIGHT_BRACE", + parser_overload_name: None, + macro_overload_name: None, + arg_type: ArgumentType::Character, + primitives: &[], + since: 0, + }, + Command { + web2cname: "MATH_SHIFT", + parser_overload_name: None, + macro_overload_name: None, + arg_type: ArgumentType::Character, + primitives: &[], + since: 0, + }, + Command { + web2cname: "TAB_MARK", + parser_overload_name: None, + macro_overload_name: None, + arg_type: ArgumentType::Character, + primitives: &[CommandPrimitive { + name: "span", + arg: "SPAN_CODE", + init: PrimitiveExtraInit::None, + }], + since: 0, + }, + Command { + web2cname: "CAR_RET", + parser_overload_name: None, + macro_overload_name: Some("OUT_PARAM"), + arg_type: ArgumentType::Character, + primitives: &[ + CommandPrimitive { + name: "cr", + arg: "CR_CODE", + init: PrimitiveExtraInit::Frozen("FROZEN_CR"), + }, + CommandPrimitive { + name: "crcr", + arg: "CR_CR_CODE", + init: PrimitiveExtraInit::None, + }, + ], + since: 0, + }, + Command { + web2cname: "MAC_PARAM", + parser_overload_name: None, + macro_overload_name: None, + arg_type: ArgumentType::Character, + primitives: &[], + since: 0, + }, + Command { + web2cname: "SUP_MARK", + parser_overload_name: None, + macro_overload_name: None, + arg_type: ArgumentType::Character, + primitives: &[], + since: 0, + }, + Command { + web2cname: "SUB_MARK", + parser_overload_name: None, + macro_overload_name: None, + arg_type: ArgumentType::Character, + primitives: &[], + since: 0, + }, + Command { + web2cname: "ENDV", + parser_overload_name: Some("IGNORE"), + macro_overload_name: None, + arg_type: ArgumentType::Unspecified, + primitives: &[], + since: 0, + }, + Command { + web2cname: "SPACER", + parser_overload_name: None, + macro_overload_name: None, + arg_type: ArgumentType::Character, + primitives: &[], + since: 0, + }, + Command { + web2cname: "LETTER", + parser_overload_name: None, + macro_overload_name: None, + arg_type: ArgumentType::Character, + primitives: &[], + since: 0, + }, + Command { + web2cname: "OTHER_CHAR", + parser_overload_name: None, + macro_overload_name: None, + arg_type: ArgumentType::Character, + primitives: &[], + since: 0, + }, + Command { + web2cname: "PAR_END", + parser_overload_name: Some("ACTIVE_CHAR"), + macro_overload_name: Some("MATCH"), + arg_type: ArgumentType::Character, + primitives: &[CommandPrimitive { + name: "par", + arg: "TOO_BIG_USV", + init: PrimitiveExtraInit::Par, + }], + since: 0, + }, + Command { + web2cname: "STOP", + parser_overload_name: Some("COMMENT"), + macro_overload_name: Some("END_MATCH"), + arg_type: ArgumentType::Unspecified, + primitives: &[ + CommandPrimitive { + name: "end", + arg: "0", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "dump", + arg: "1", + init: PrimitiveExtraInit::None, + }, + ], + since: 0, + }, + Command { + web2cname: "DELIM_NUM", + parser_overload_name: Some("INVALID_CHAR"), + macro_overload_name: None, + arg_type: ArgumentType::Unspecified, + primitives: &[ + CommandPrimitive { + name: "delimiter", + arg: "0", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "Udelimiter", + arg: "1", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "XeTeXdelimiter", + arg: "1", + init: PrimitiveExtraInit::None, + }, + ], + since: 0, + }, + Command { + web2cname: "CHAR_NUM", + parser_overload_name: None, + macro_overload_name: None, + arg_type: ArgumentType::Unspecified, + primitives: &[CommandPrimitive { + name: "char", + arg: "0", + init: PrimitiveExtraInit::None, + }], + since: 0, + }, + Command { + web2cname: "MATH_CHAR_NUM", + parser_overload_name: None, + macro_overload_name: None, + arg_type: ArgumentType::Unspecified, + primitives: &[ + CommandPrimitive { + name: "mathchar", + arg: "0", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "Umathcharnum", + arg: "1", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "XeTeXmathcharnum", + arg: "1", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "Umathchar", + arg: "2", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "XeTeXmathchar", + arg: "2", + init: PrimitiveExtraInit::None, + }, + ], + since: 0, + }, + Command { + web2cname: "MARK", + parser_overload_name: None, + macro_overload_name: None, + arg_type: ArgumentType::Unspecified, + primitives: &[ + CommandPrimitive { + name: "mark", + arg: "0", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "marks", + arg: "5", + init: PrimitiveExtraInit::None, + }, + ], + since: 0, + }, + Command { + web2cname: "XRAY", + parser_overload_name: None, + macro_overload_name: None, + arg_type: ArgumentType::Unspecified, + primitives: &[ + CommandPrimitive { + name: "show", + arg: "SHOW_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "showbox", + arg: "SHOW_BOX_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "showthe", + arg: "SHOW_THE_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "showlists", + arg: "SHOW_LISTS", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "showgroups", + arg: "SHOW_GROUPS", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "showtokens", + arg: "SHOW_TOKENS", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "showifs", + arg: "SHOW_IFS", + init: PrimitiveExtraInit::None, + }, + ], + since: 0, + }, + Command { + web2cname: "MAKE_BOX", + parser_overload_name: None, + macro_overload_name: None, + arg_type: ArgumentType::Unspecified, + primitives: &[ + CommandPrimitive { + name: "box", + arg: "BOX_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "copy", + arg: "COPY_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "lastbox", + arg: "LAST_BOX_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "vsplit", + arg: "VSPLIT_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "vtop", + arg: "VTOP_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "vbox", + arg: "VTOP_CODE + VMODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "hbox", + arg: "VTOP_CODE + HMODE", + init: PrimitiveExtraInit::None, + }, + ], + since: 0, + }, + Command { + web2cname: "HMOVE", + parser_overload_name: None, + macro_overload_name: None, + arg_type: ArgumentType::Unspecified, + primitives: &[ + CommandPrimitive { + name: "moveright", + arg: "0", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "moveleft", + arg: "1", + init: PrimitiveExtraInit::None, + }, + ], + since: 0, + }, + Command { + web2cname: "VMOVE", + parser_overload_name: None, + macro_overload_name: None, + arg_type: ArgumentType::Unspecified, + primitives: &[ + CommandPrimitive { + name: "lower", + arg: "0", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "raise", + arg: "1", + init: PrimitiveExtraInit::None, + }, + ], + since: 0, + }, + Command { + web2cname: "UN_HBOX", + parser_overload_name: None, + macro_overload_name: None, + arg_type: ArgumentType::Unspecified, + primitives: &[ + CommandPrimitive { + name: "unhbox", + arg: "BOX_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "unhcopy", + arg: "COPY_CODE", + init: PrimitiveExtraInit::None, + }, + ], + since: 0, + }, + Command { + web2cname: "UN_VBOX", + parser_overload_name: None, + macro_overload_name: None, + arg_type: ArgumentType::Unspecified, + primitives: &[ + CommandPrimitive { + name: "unvbox", + arg: "BOX_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "unvcopy", + arg: "COPY_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "pagediscards", + arg: "LAST_BOX_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "splitdiscards", + arg: "VSPLIT_CODE", + init: PrimitiveExtraInit::None, + }, + ], + since: 0, + }, + Command { + web2cname: "REMOVE_ITEM", + parser_overload_name: None, + macro_overload_name: None, + arg_type: ArgumentType::Unspecified, + primitives: &[ + CommandPrimitive { + name: "unskip", + arg: "GLUE_NODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "unkern", + arg: "KERN_NODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "unpenalty", + arg: "PENALTY_NODE", + init: PrimitiveExtraInit::None, + }, + ], + since: 0, + }, + Command { + web2cname: "HSKIP", + parser_overload_name: None, + macro_overload_name: None, + arg_type: ArgumentType::Unspecified, + primitives: &[ + CommandPrimitive { + name: "hfil", + arg: "FIL_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "hfill", + arg: "FILL_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "hss", + arg: "SS_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "hfilneg", + arg: "FIL_NEG_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "hskip", + arg: "SKIP_CODE", + init: PrimitiveExtraInit::None, + }, + ], + since: 0, + }, + Command { + web2cname: "VSKIP", + parser_overload_name: None, + macro_overload_name: None, + arg_type: ArgumentType::Unspecified, + primitives: &[ + CommandPrimitive { + name: "vfil", + arg: "FIL_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "vfill", + arg: "FILL_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "vss", + arg: "SS_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "vfilneg", + arg: "FIL_NEG_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "vskip", + arg: "SKIP_CODE", + init: PrimitiveExtraInit::None, + }, + ], + since: 0, + }, + Command { + web2cname: "MSKIP", + parser_overload_name: None, + macro_overload_name: None, + arg_type: ArgumentType::Unspecified, + primitives: &[CommandPrimitive { + name: "mskip", + arg: "MSKIP_CODE", + init: PrimitiveExtraInit::None, + }], + since: 0, + }, + Command { + web2cname: "KERN", + parser_overload_name: None, + macro_overload_name: None, + arg_type: ArgumentType::Unspecified, + primitives: &[CommandPrimitive { + name: "kern", + arg: "EXPLICIT", + init: PrimitiveExtraInit::None, + }], + since: 0, + }, + Command { + web2cname: "MKERN", + parser_overload_name: None, + macro_overload_name: None, + arg_type: ArgumentType::Unspecified, + primitives: &[CommandPrimitive { + name: "mkern", + arg: "MU_GLUE", + init: PrimitiveExtraInit::None, + }], + since: 0, + }, + Command { + web2cname: "LEADER_SHIP", + parser_overload_name: None, + macro_overload_name: None, + arg_type: ArgumentType::Unspecified, + primitives: &[ + CommandPrimitive { + name: "shipout", + arg: "A_LEADERS - 1", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "leaders", + arg: "A_LEADERS", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "cleaders", + arg: "C_LEADERS", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "xleaders", + arg: "X_LEADERS", + init: PrimitiveExtraInit::None, + }, + ], + since: 0, + }, + Command { + web2cname: "HALIGN", + parser_overload_name: None, + macro_overload_name: None, + arg_type: ArgumentType::Unspecified, + primitives: &[CommandPrimitive { + name: "halign", + arg: "0", + init: PrimitiveExtraInit::None, + }], + since: 0, + }, + Command { + web2cname: "VALIGN", + parser_overload_name: None, + macro_overload_name: None, + arg_type: ArgumentType::Unspecified, + primitives: &[ + CommandPrimitive { + name: "valign", + arg: "0", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "beginL", + arg: "BEGIN_L_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "endL", + arg: "END_L_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "beginR", + arg: "BEGIN_R_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "endR", + arg: "END_R_CODE", + init: PrimitiveExtraInit::None, + }, + ], + since: 0, + }, + Command { + web2cname: "NO_ALIGN", + parser_overload_name: None, + macro_overload_name: None, + arg_type: ArgumentType::Unspecified, + primitives: &[CommandPrimitive { + name: "noalign", + arg: "0", + init: PrimitiveExtraInit::None, + }], + since: 0, + }, + Command { + web2cname: "VRULE", + parser_overload_name: None, + macro_overload_name: None, + arg_type: ArgumentType::Unspecified, + primitives: &[CommandPrimitive { + name: "vrule", + arg: "0", + init: PrimitiveExtraInit::None, + }], + since: 0, + }, + Command { + web2cname: "HRULE", + parser_overload_name: None, + macro_overload_name: None, + arg_type: ArgumentType::Unspecified, + primitives: &[CommandPrimitive { + name: "hrule", + arg: "0", + init: PrimitiveExtraInit::None, + }], + since: 0, + }, + Command { + web2cname: "INSERT", + parser_overload_name: None, + macro_overload_name: None, + arg_type: ArgumentType::Unspecified, + primitives: &[CommandPrimitive { + name: "insert", + arg: "0", + init: PrimitiveExtraInit::None, + }], + since: 0, + }, + Command { + web2cname: "VADJUST", + parser_overload_name: None, + macro_overload_name: None, + arg_type: ArgumentType::Unspecified, + primitives: &[CommandPrimitive { + name: "vadjust", + arg: "0", + init: PrimitiveExtraInit::None, + }], + since: 0, + }, + Command { + web2cname: "IGNORE_SPACES", + parser_overload_name: None, + macro_overload_name: None, + arg_type: ArgumentType::Unspecified, + primitives: &[CommandPrimitive { + name: "ignorespaces", + arg: "0", + init: PrimitiveExtraInit::None, + }], + since: 0, + }, + Command { + web2cname: "AFTER_ASSIGNMENT", + parser_overload_name: None, + macro_overload_name: None, + arg_type: ArgumentType::Unspecified, + primitives: &[CommandPrimitive { + name: "afterassignment", + arg: "0", + init: PrimitiveExtraInit::None, + }], + since: 0, + }, + Command { + web2cname: "AFTER_GROUP", + parser_overload_name: None, + macro_overload_name: None, + arg_type: ArgumentType::Unspecified, + primitives: &[CommandPrimitive { + name: "aftergroup", + arg: "0", + init: PrimitiveExtraInit::None, + }], + since: 0, + }, + Command { + web2cname: "BREAK_PENALTY", + parser_overload_name: None, + macro_overload_name: None, + arg_type: ArgumentType::Unspecified, + primitives: &[CommandPrimitive { + name: "penalty", + arg: "0", + init: PrimitiveExtraInit::None, + }], + since: 0, + }, + Command { + web2cname: "START_PAR", + parser_overload_name: None, + macro_overload_name: None, + arg_type: ArgumentType::Unspecified, + primitives: &[ + CommandPrimitive { + name: "noindent", + arg: "0", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "indent", + arg: "1", + init: PrimitiveExtraInit::None, + }, + ], + since: 0, + }, + Command { + web2cname: "ITAL_CORR", + parser_overload_name: None, + macro_overload_name: None, + arg_type: ArgumentType::Unspecified, + primitives: &[CommandPrimitive { + name: "/", + arg: "0", + init: PrimitiveExtraInit::None, + }], + since: 0, + }, + Command { + web2cname: "ACCENT", + parser_overload_name: None, + macro_overload_name: None, + arg_type: ArgumentType::Unspecified, + primitives: &[CommandPrimitive { + name: "accent", + arg: "0", + init: PrimitiveExtraInit::None, + }], + since: 0, + }, + Command { + web2cname: "MATH_ACCENT", + parser_overload_name: None, + macro_overload_name: None, + arg_type: ArgumentType::Unspecified, + primitives: &[ + CommandPrimitive { + name: "mathaccent", + arg: "0", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "Umathaccent", + arg: "1", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "XeTeXmathaccent", + arg: "1", + init: PrimitiveExtraInit::None, + }, + ], + since: 0, + }, + Command { + web2cname: "DISCRETIONARY", + parser_overload_name: None, + macro_overload_name: None, + arg_type: ArgumentType::Unspecified, + primitives: &[ + CommandPrimitive { + name: "discretionary", + arg: "0", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "-", + arg: "1", + init: PrimitiveExtraInit::None, + }, + ], + since: 0, + }, + Command { + web2cname: "EQ_NO", + parser_overload_name: None, + macro_overload_name: None, + arg_type: ArgumentType::Unspecified, + primitives: &[ + CommandPrimitive { + name: "eqno", + arg: "0", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "leqno", + arg: "1", + init: PrimitiveExtraInit::None, + }, + ], + since: 0, + }, + Command { + web2cname: "LEFT_RIGHT", + parser_overload_name: None, + macro_overload_name: None, + arg_type: ArgumentType::Unspecified, + primitives: &[ + CommandPrimitive { + name: "middle", + arg: "1", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "left", + arg: "LEFT_NOAD", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "right", + arg: "RIGHT_NOAD", + init: PrimitiveExtraInit::Frozen("FROZEN_RIGHT"), + }, + ], + since: 0, + }, + Command { + web2cname: "MATH_COMP", + parser_overload_name: None, + macro_overload_name: None, + arg_type: ArgumentType::Unspecified, + primitives: &[ + CommandPrimitive { + name: "mathord", + arg: "ORD_NOAD", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "mathop", + arg: "OP_NOAD", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "mathbin", + arg: "BIN_NOAD", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "mathrel", + arg: "REL_NOAD", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "mathopen", + arg: "OPEN_NOAD", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "mathclose", + arg: "CLOSE_NOAD", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "mathpunct", + arg: "PUNCT_NOAD", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "mathinner", + arg: "INNER_NOAD", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "underline", + arg: "UNDER_NOAD", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "overline", + arg: "OVER_NOAD", + init: PrimitiveExtraInit::None, + }, + ], + since: 0, + }, + Command { + web2cname: "LIMIT_SWITCH", + parser_overload_name: None, + macro_overload_name: None, + arg_type: ArgumentType::Unspecified, + primitives: &[ + CommandPrimitive { + name: "displaylimits", + arg: "NORMAL", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "limits", + arg: "LIMITS", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "nolimits", + arg: "NO_LIMITS", + init: PrimitiveExtraInit::None, + }, + ], + since: 0, + }, + Command { + web2cname: "ABOVE", + parser_overload_name: None, + macro_overload_name: None, + arg_type: ArgumentType::Unspecified, + primitives: &[ + CommandPrimitive { + name: "above", + arg: "ABOVE_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "over", + arg: "OVER_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "atop", + arg: "ATOP_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "abovewithdelims", + arg: "DELIMITED_CODE + ABOVE_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "overwithdelims", + arg: "DELIMITED_CODE + OVER_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "atopwithdelims", + arg: "DELIMITED_CODE + ATOP_CODE", + init: PrimitiveExtraInit::None, + }, + ], + since: 0, + }, + Command { + web2cname: "MATH_STYLE", + parser_overload_name: None, + macro_overload_name: None, + arg_type: ArgumentType::Unspecified, + primitives: &[ + CommandPrimitive { + name: "displaystyle", + arg: "DISPLAY_STYLE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "textstyle", + arg: "TEXT_STYLE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "scriptstyle", + arg: "SCRIPT_STYLE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "scriptscriptstyle", + arg: "SCRIPT_SCRIPT_STYLE", + init: PrimitiveExtraInit::None, + }, + ], + since: 0, + }, + Command { + web2cname: "MATH_CHOICE", + parser_overload_name: None, + macro_overload_name: None, + arg_type: ArgumentType::Unspecified, + primitives: &[CommandPrimitive { + name: "mathchoice", + arg: "0", + init: PrimitiveExtraInit::None, + }], + since: 0, + }, + Command { + web2cname: "NON_SCRIPT", + parser_overload_name: None, + macro_overload_name: None, + arg_type: ArgumentType::Unspecified, + primitives: &[CommandPrimitive { + name: "nonscript", + arg: "0", + init: PrimitiveExtraInit::None, + }], + since: 0, + }, + Command { + web2cname: "VCENTER", + parser_overload_name: None, + macro_overload_name: None, + arg_type: ArgumentType::Unspecified, + primitives: &[CommandPrimitive { + name: "vcenter", + arg: "0", + init: PrimitiveExtraInit::None, + }], + since: 0, + }, + Command { + web2cname: "CASE_SHIFT", + parser_overload_name: None, + macro_overload_name: None, + arg_type: ArgumentType::Unspecified, + primitives: &[ + CommandPrimitive { + name: "lowercase", + arg: "LC_CODE_BASE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "uppercase", + arg: "UC_CODE_BASE", + init: PrimitiveExtraInit::None, + }, + ], + since: 0, + }, + Command { + web2cname: "MESSAGE", + parser_overload_name: None, + macro_overload_name: None, + arg_type: ArgumentType::Unspecified, + primitives: &[ + CommandPrimitive { + name: "message", + arg: "0", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "errmessage", + arg: "1", + init: PrimitiveExtraInit::None, + }, + ], + since: 0, + }, + Command { + web2cname: "EXTENSION", + parser_overload_name: None, + macro_overload_name: None, + arg_type: ArgumentType::Unspecified, + primitives: &[ + CommandPrimitive { + name: "openout", + arg: "OPEN_NODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "write", + arg: "WRITE_NODE", + init: PrimitiveExtraInit::Write, + }, + CommandPrimitive { + name: "closeout", + arg: "CLOSE_NODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "special", + arg: "SPECIAL_NODE", + init: PrimitiveExtraInit::Frozen("FROZEN_SPECIAL"), + }, + CommandPrimitive { + name: "immediate", + arg: "IMMEDIATE_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "setlanguage", + arg: "SET_LANGUAGE_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "pdfsavepos", + arg: "PDF_SAVE_POS_NODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "resettimer", + arg: "RESET_TIMER_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "setrandomseed", + arg: "SET_RANDOM_SEED_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "XeTeXdefaultencoding", + arg: "XETEX_DEFAULT_ENCODING_EXTENSION_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "XeTeXglyph", + arg: "GLYPH_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "XeTeXinputencoding", + arg: "XETEX_INPUT_ENCODING_EXTENSION_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "XeTeXlinebreaklocale", + arg: "XETEX_LINEBREAK_LOCALE_EXTENSION_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "XeTeXpdffile", + arg: "PDF_FILE_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "XeTeXpicfile", + arg: "PIC_FILE_CODE", + init: PrimitiveExtraInit::None, + }, + ], + since: 0, + }, + Command { + web2cname: "IN_STREAM", + parser_overload_name: None, + macro_overload_name: None, + arg_type: ArgumentType::Unspecified, + primitives: &[ + CommandPrimitive { + name: "closein", + arg: "0", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "openin", + arg: "1", + init: PrimitiveExtraInit::None, + }, + ], + since: 0, + }, + Command { + web2cname: "BEGIN_GROUP", + parser_overload_name: None, + macro_overload_name: None, + arg_type: ArgumentType::Unspecified, + primitives: &[CommandPrimitive { + name: "begingroup", + arg: "0", + init: PrimitiveExtraInit::None, + }], + since: 0, + }, + Command { + web2cname: "END_GROUP", + parser_overload_name: None, + macro_overload_name: None, + arg_type: ArgumentType::Unspecified, + primitives: &[CommandPrimitive { + name: "endgroup", + arg: "0", + init: PrimitiveExtraInit::Frozen("FROZEN_END_GROUP"), + }], + since: 0, + }, + Command { + web2cname: "OMIT", + parser_overload_name: None, + macro_overload_name: None, + arg_type: ArgumentType::Unspecified, + primitives: &[CommandPrimitive { + name: "omit", + arg: "0", + init: PrimitiveExtraInit::None, + }], + since: 0, + }, + Command { + web2cname: "EX_SPACE", + parser_overload_name: None, + macro_overload_name: None, + arg_type: ArgumentType::Unspecified, + primitives: &[CommandPrimitive { + name: " ", + arg: "0", + init: PrimitiveExtraInit::None, + }], + since: 0, + }, + Command { + web2cname: "NO_BOUNDARY", + parser_overload_name: None, + macro_overload_name: None, + arg_type: ArgumentType::Unspecified, + primitives: &[CommandPrimitive { + name: "noboundary", + arg: "0", + init: PrimitiveExtraInit::None, + }], + since: 0, + }, + Command { + web2cname: "RADICAL", + parser_overload_name: None, + macro_overload_name: None, + arg_type: ArgumentType::Unspecified, + primitives: &[ + CommandPrimitive { + name: "radical", + arg: "0", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "Uradical", + arg: "1", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "XeTeXradical", + arg: "1", + init: PrimitiveExtraInit::None, + }, + ], + since: 0, + }, + Command { + web2cname: "END_CS_NAME", + parser_overload_name: None, + macro_overload_name: None, + arg_type: ArgumentType::Unspecified, + primitives: &[CommandPrimitive { + name: "endcsname", + arg: "0", + init: PrimitiveExtraInit::None, + }], + since: 0, + }, + Command { + // this is MIN_INTERNAL + web2cname: "CHAR_GIVEN", + parser_overload_name: None, + macro_overload_name: None, + arg_type: ArgumentType::Unspecified, + primitives: &[], + since: 0, + }, + Command { + web2cname: "MATH_GIVEN", + parser_overload_name: None, + macro_overload_name: None, + arg_type: ArgumentType::Unspecified, + primitives: &[], + since: 0, + }, + Command { + web2cname: "XETEX_MATH_GIVEN", + parser_overload_name: None, + macro_overload_name: None, + arg_type: ArgumentType::Unspecified, + primitives: &[], + since: 0, + }, + Command { + // this is MAX_NON_PREFIXED_COMMAND + web2cname: "LAST_ITEM", + parser_overload_name: None, + macro_overload_name: None, + arg_type: ArgumentType::Unspecified, + primitives: &[ + CommandPrimitive { + name: "badness", + arg: "BADNESS_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "currentgrouplevel", + arg: "CURRENT_GROUP_LEVEL_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "currentgrouptype", + arg: "CURRENT_GROUP_TYPE_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "currentifbranch", + arg: "CURRENT_IF_BRANCH_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "currentiflevel", + arg: "CURRENT_IF_LEVEL_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "currentiftype", + arg: "CURRENT_IF_TYPE_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "dimexpr", + arg: "ETEX_EXPR + 1", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "elapsedtime", + arg: "ELAPSED_TIME_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "eTeXversion", + arg: "ETEX_VERSION_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "fontchardp", + arg: "FONT_CHAR_DP_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "fontcharht", + arg: "FONT_CHAR_HT_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "fontcharic", + arg: "FONT_CHAR_IC_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "fontcharwd", + arg: "FONT_CHAR_WD_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "glueexpr", + arg: "ETEX_EXPR + 2", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "glueshrink", + arg: "GLUE_SHRINK_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "glueshrinkorder", + arg: "GLUE_SHRINK_ORDER_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "gluestretch", + arg: "GLUE_STRETCH_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "gluestretchorder", + arg: "GLUE_STRETCH_ORDER_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "gluetomu", + arg: "GLUE_TO_MU_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "inputlineno", + arg: "INPUT_LINE_NO_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "lastkern", + arg: "DIMEN_VAL", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "lastnodetype", + arg: "LAST_NODE_TYPE_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "lastpenalty", + arg: "INT_VAL", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "lastskip", + arg: "GLUE_VAL", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "muexpr", + arg: "ETEX_EXPR + 3", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "mutoglue", + arg: "MU_TO_GLUE_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "numexpr", + arg: "ETEX_EXPR + 0", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "parshapedimen", + arg: "PAR_SHAPE_DIMEN_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "parshapeindent", + arg: "PAR_SHAPE_INDENT_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "parshapelength", + arg: "PAR_SHAPE_LENGTH_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "pdflastxpos", + arg: "PDF_LAST_X_POS_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "pdflastypos", + arg: "PDF_LAST_Y_POS_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "randomseed", + arg: "RANDOM_SEED_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "shellescape", + arg: "PDF_SHELL_ESCAPE_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "XeTeXcharglyph", + arg: "XETEX_MAP_CHAR_TO_GLYPH_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "XeTeXcountfeatures", + arg: "XETEX_COUNT_FEATURES_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "XeTeXcountglyphs", + arg: "XETEX_COUNT_GLYPHS_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "XeTeXcountselectors", + arg: "XETEX_COUNT_SELECTORS_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "XeTeXcountvariations", + arg: "XETEX_COUNT_VARIATIONS_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "XeTeXfeaturecode", + arg: "XETEX_FEATURE_CODE_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "XeTeXfindfeaturebyname", + arg: "XETEX_FIND_FEATURE_BY_NAME_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "XeTeXfindselectorbyname", + arg: "XETEX_FIND_SELECTOR_BY_NAME_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "XeTeXfindvariationbyname", + arg: "XETEX_FIND_VARIATION_BY_NAME_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "XeTeXfirstfontchar", + arg: "XETEX_FIRST_CHAR_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "XeTeXfonttype", + arg: "XETEX_FONT_TYPE_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "XeTeXglyphbounds", + arg: "XETEX_GLYPH_BOUNDS_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "XeTeXglyphindex", + arg: "XETEX_GLYPH_INDEX_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "XeTeXisdefaultselector", + arg: "XETEX_IS_DEFAULT_SELECTOR_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "XeTeXisexclusivefeature", + arg: "XETEX_IS_EXCLUSIVE_FEATURE_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "XeTeXlastfontchar", + arg: "XETEX_LAST_CHAR_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "XeTeXOTcountfeatures", + arg: "XETEX_OT_COUNT_FEATURES_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "XeTeXOTcountlanguages", + arg: "XETEX_OT_COUNT_LANGUAGES_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "XeTeXOTcountscripts", + arg: "XETEX_OT_COUNT_SCRIPTS_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "XeTeXOTfeaturetag", + arg: "XETEX_OT_FEATURE_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "XeTeXOTlanguagetag", + arg: "XETEX_OT_LANGUAGE_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "XeTeXOTscripttag", + arg: "XETEX_OT_SCRIPT_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "XeTeXpdfpagecount", + arg: "XETEX_PDF_PAGE_COUNT_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "XeTeXselectorcode", + arg: "XETEX_SELECTOR_CODE_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "XeTeXvariationdefault", + arg: "XETEX_VARIATION_DEFAULT_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "XeTeXvariationmax", + arg: "XETEX_VARIATION_MAX_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "XeTeXvariationmin", + arg: "XETEX_VARIATION_MIN_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "XeTeXvariation", + arg: "XETEX_VARIATION_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "XeTeXversion", + arg: "XETEX_VERSION_CODE", + init: PrimitiveExtraInit::None, + }, + ], + since: 0, + }, + Command { + // The following commands are assignment commands and + // can therefore be prefixed by \global + web2cname: "TOKS_REGISTER", + parser_overload_name: None, + macro_overload_name: None, + arg_type: ArgumentType::Unspecified, + primitives: &[CommandPrimitive { + name: "toks", + arg: "0", + init: PrimitiveExtraInit::None, + }], + since: 0, + }, + Command { + web2cname: "ASSIGN_TOKS", + parser_overload_name: None, + macro_overload_name: None, + arg_type: ArgumentType::Unspecified, + primitives: &[], // populated by local pars + since: 0, + }, + Command { + web2cname: "ASSIGN_INT", + parser_overload_name: None, + macro_overload_name: None, + arg_type: ArgumentType::Unspecified, + primitives: &[], // populated by intpars + since: 0, + }, + Command { + web2cname: "ASSIGN_DIMEN", + parser_overload_name: None, + macro_overload_name: None, + arg_type: ArgumentType::Unspecified, + primitives: &[], // populated by dimenpars + since: 0, + }, + Command { + web2cname: "ASSIGN_GLUE", + parser_overload_name: None, + macro_overload_name: None, + arg_type: ArgumentType::Unspecified, + primitives: &[], // populated by gluepars + since: 0, + }, + Command { + web2cname: "ASSIGN_MU_GLUE", + parser_overload_name: None, + macro_overload_name: None, + arg_type: ArgumentType::Unspecified, + primitives: &[], // populated by gluepars + since: 0, + }, + Command { + web2cname: "ASSIGN_FONT_DIMEN", + parser_overload_name: None, + macro_overload_name: None, + arg_type: ArgumentType::Unspecified, + primitives: &[CommandPrimitive { + name: "fontdimen", + arg: "0", + init: PrimitiveExtraInit::None, + }], + since: 0, + }, + Command { + web2cname: "ASSIGN_FONT_INT", + parser_overload_name: None, + macro_overload_name: None, + arg_type: ArgumentType::Unspecified, + primitives: &[ + CommandPrimitive { + name: "hyphenchar", + arg: "0", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "skewchar", + arg: "1", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "lpcode", + arg: "2", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "rpcode", + arg: "3", + init: PrimitiveExtraInit::None, + }, + ], + since: 0, + }, + Command { + web2cname: "SET_AUX", + parser_overload_name: None, + macro_overload_name: None, + arg_type: ArgumentType::Unspecified, + primitives: &[ + CommandPrimitive { + name: "prevdepth", + arg: "VMODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "spacefactor", + arg: "HMODE", + init: PrimitiveExtraInit::None, + }, + ], + since: 0, + }, + Command { + web2cname: "SET_PREV_GRAF", + parser_overload_name: None, + macro_overload_name: None, + arg_type: ArgumentType::Unspecified, + primitives: &[CommandPrimitive { + name: "prevgraf", + arg: "0", + init: PrimitiveExtraInit::None, + }], + since: 0, + }, + Command { + web2cname: "SET_PAGE_DIMEN", + parser_overload_name: None, + macro_overload_name: None, + arg_type: ArgumentType::Unspecified, + primitives: &[ + CommandPrimitive { + name: "pagegoal", + arg: "0", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "pagetotal", + arg: "1", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "pagestretch", + arg: "2", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "pagefilstretch", + arg: "3", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "pagefillstretch", + arg: "4", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "pagefilllstretch", + arg: "5", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "pageshrink", + arg: "6", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "pagedepth", + arg: "7", + init: PrimitiveExtraInit::None, + }, + ], + since: 0, + }, + Command { + web2cname: "SET_PAGE_INT", + parser_overload_name: None, + macro_overload_name: None, + arg_type: ArgumentType::Unspecified, + primitives: &[ + CommandPrimitive { + name: "deadcycles", + arg: "0", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "insertpenalties", + arg: "1", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "interactionmode", + arg: "2", + init: PrimitiveExtraInit::None, + }, + ], + since: 0, + }, + Command { + web2cname: "SET_BOX_DIMEN", + parser_overload_name: None, + macro_overload_name: None, + arg_type: ArgumentType::Unspecified, + primitives: &[ + CommandPrimitive { + name: "wd", + arg: "WIDTH_OFFSET", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "dp", + arg: "DEPTH_OFFSET", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "ht", + arg: "HEIGHT_OFFSET", + init: PrimitiveExtraInit::None, + }, + ], + since: 0, + }, + Command { + web2cname: "SET_SHAPE", + parser_overload_name: None, + macro_overload_name: None, + arg_type: ArgumentType::Unspecified, + primitives: &[], + since: 0, + }, + Command { + web2cname: "DEF_CODE", + parser_overload_name: None, + macro_overload_name: None, + arg_type: ArgumentType::Unspecified, + primitives: &[ + CommandPrimitive { + name: "catcode", + arg: "CAT_CODE_BASE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "lccode", + arg: "LC_CODE_BASE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "uccode", + arg: "UC_CODE_BASE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "sfcode", + arg: "SF_CODE_BASE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "mathcode", + arg: "MATH_CODE_BASE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "delcode", + arg: "DEL_CODE_BASE", + init: PrimitiveExtraInit::None, + }, + ], + since: 0, + }, + Command { + web2cname: "XETEX_DEF_CODE", + parser_overload_name: None, + macro_overload_name: None, + arg_type: ArgumentType::Unspecified, + primitives: &[ + CommandPrimitive { + name: "XeTeXcharclass", + arg: "SF_CODE_BASE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "Umathcodenum", + arg: "MATH_CODE_BASE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "XeTeXmathcodenum", + arg: "MATH_CODE_BASE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "Umathcode", + arg: "MATH_CODE_BASE + 1", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "XeTeXmathcode", + arg: "MATH_CODE_BASE + 1", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "Udelcodenum", + arg: "DEL_CODE_BASE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "XeTeXdelcodenum", + arg: "DEL_CODE_BASE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "Udelcode", + arg: "DEL_CODE_BASE + 1", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "XeTeXdelcode", + arg: "DEL_CODE_BASE + 1", + init: PrimitiveExtraInit::None, + }, + ], + since: 0, + }, + Command { + web2cname: "DEF_FAMILY", + parser_overload_name: None, + macro_overload_name: None, + arg_type: ArgumentType::Unspecified, + primitives: &[ + CommandPrimitive { + name: "textfont", + arg: "MATH_FONT_BASE + TEXT_SIZE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "scriptfont", + arg: "MATH_FONT_BASE + SCRIPT_SIZE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "scriptscriptfont", + arg: "MATH_FONT_BASE + SCRIPT_SCRIPT_SIZE", + init: PrimitiveExtraInit::None, + }, + ], + since: 0, + }, + Command { + web2cname: "SET_FONT", + parser_overload_name: None, + macro_overload_name: None, + arg_type: ArgumentType::Unspecified, + primitives: &[CommandPrimitive { + name: "nullfont", + arg: "FONT_BASE", + init: PrimitiveExtraInit::Frozen("FROZEN_NULL_FONT"), + }], + since: 0, + }, + Command { + web2cname: "DEF_FONT", + parser_overload_name: None, + macro_overload_name: None, + arg_type: ArgumentType::Unspecified, + primitives: &[CommandPrimitive { + name: "font", + arg: "0", + init: PrimitiveExtraInit::None, + }], + since: 0, + }, + Command { + // this is MAX_INTERNAL + web2cname: "REGISTER", + parser_overload_name: None, + macro_overload_name: None, + arg_type: ArgumentType::Unspecified, + primitives: &[ + CommandPrimitive { + name: "count", + arg: "0", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "dimen", + arg: "1", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "skip", + arg: "2", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "muskip", + arg: "3", + init: PrimitiveExtraInit::None, + }, + ], + since: 0, + }, + Command { + web2cname: "ADVANCE", + parser_overload_name: None, + macro_overload_name: None, + arg_type: ArgumentType::Unspecified, + primitives: &[CommandPrimitive { + name: "advance", + arg: "0", + init: PrimitiveExtraInit::None, + }], + since: 0, + }, + Command { + web2cname: "MULTIPLY", + parser_overload_name: None, + macro_overload_name: None, + arg_type: ArgumentType::Unspecified, + primitives: &[CommandPrimitive { + name: "multiply", + arg: "0", + init: PrimitiveExtraInit::None, + }], + since: 0, + }, + Command { + web2cname: "DIVIDE", + parser_overload_name: None, + macro_overload_name: None, + arg_type: ArgumentType::Unspecified, + primitives: &[CommandPrimitive { + name: "divide", + arg: "0", + init: PrimitiveExtraInit::None, + }], + since: 0, + }, + Command { + web2cname: "PREFIX", + parser_overload_name: None, + macro_overload_name: None, + arg_type: ArgumentType::Unspecified, + primitives: &[ + CommandPrimitive { + name: "long", + arg: "1", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "outer", + arg: "2", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "global", + arg: "4", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "protected", + arg: "8", + init: PrimitiveExtraInit::None, + }, + ], + since: 0, + }, + Command { + web2cname: "LET", + parser_overload_name: None, + macro_overload_name: None, + arg_type: ArgumentType::Unspecified, + primitives: &[ + CommandPrimitive { + name: "let", + arg: "NORMAL", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "futurelet", + arg: "NORMAL + 1", + init: PrimitiveExtraInit::None, + }, + ], + since: 0, + }, + Command { + web2cname: "SHORTHAND_DEF", + parser_overload_name: None, + macro_overload_name: None, + arg_type: ArgumentType::Unspecified, + primitives: &[ + CommandPrimitive { + name: "chardef", + arg: "CHAR_DEF_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "mathchardef", + arg: "MATH_CHAR_DEF_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "countdef", + arg: "COUNT_DEF_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "dimendef", + arg: "DIMEN_DEF_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "skipdef", + arg: "SKIP_DEF_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "muskipdef", + arg: "MU_SKIP_DEF_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "toksdef", + arg: "TOKS_DEF_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "Umathcharnumdef", + arg: "XETEX_MATH_CHAR_NUM_DEF_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "XeTeXmathcharnumdef", + arg: "XETEX_MATH_CHAR_NUM_DEF_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "Umathchardef", + arg: "XETEX_MATH_CHAR_DEF_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "XeTeXmathchardef", + arg: "XETEX_MATH_CHAR_DEF_CODE", + init: PrimitiveExtraInit::None, + }, + ], + since: 0, + }, + Command { + web2cname: "READ_TO_CS", + parser_overload_name: None, + macro_overload_name: None, + arg_type: ArgumentType::Unspecified, + primitives: &[ + CommandPrimitive { + name: "read", + arg: "0", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "readline", + arg: "1", + init: PrimitiveExtraInit::None, + }, + ], + since: 0, + }, + Command { + web2cname: "DEF", + parser_overload_name: None, + macro_overload_name: None, + arg_type: ArgumentType::Unspecified, + primitives: &[ + CommandPrimitive { + name: "def", + arg: "0", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "gdef", + arg: "1", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "edef", + arg: "2", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "xdef", + arg: "3", + init: PrimitiveExtraInit::None, + }, + ], + since: 0, + }, + Command { + web2cname: "SET_BOX", + parser_overload_name: None, + macro_overload_name: None, + arg_type: ArgumentType::Unspecified, + primitives: &[CommandPrimitive { + name: "setbox", + arg: "0", + init: PrimitiveExtraInit::None, + }], + since: 0, + }, + Command { + web2cname: "HYPH_DATA", + parser_overload_name: None, + macro_overload_name: None, + arg_type: ArgumentType::Unspecified, + primitives: &[ + CommandPrimitive { + name: "hyphenation", + arg: "0", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "patterns", + arg: "1", + init: PrimitiveExtraInit::None, + }, + ], + since: 0, + }, + Command { + // This is also MAX_COMMAND: "the largest command code seen at + // big_switch" + web2cname: "SET_INTERACTION", + parser_overload_name: None, + macro_overload_name: None, + arg_type: ArgumentType::Unspecified, + primitives: &[ + CommandPrimitive { + name: "batchmode", + arg: "BATCH_MODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "nonstopmode", + arg: "NONSTOP_MODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "scrollmode", + arg: "SCROLL_MODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "errorstopmode", + arg: "ERROR_STOP_MODE", + init: PrimitiveExtraInit::None, + }, + ], + since: 0, + }, + Command { + // This command, and the remainders, are handled by the scanner + // but can't make it through to the main control routine. + web2cname: "UNDEFINED_CS", + parser_overload_name: None, + macro_overload_name: None, + arg_type: ArgumentType::Unspecified, + primitives: &[], + since: 0, + }, + Command { + web2cname: "EXPAND_AFTER", + parser_overload_name: None, + macro_overload_name: None, + arg_type: ArgumentType::Unspecified, + primitives: &[ + CommandPrimitive { + name: "expandafter", + arg: "0", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "unless", + arg: "1", + init: PrimitiveExtraInit::None, + }, + ], + since: 0, + }, + Command { + web2cname: "NO_EXPAND", + parser_overload_name: None, + macro_overload_name: None, + arg_type: ArgumentType::Unspecified, + primitives: &[ + CommandPrimitive { + name: "noexpand", + arg: "0", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "primitive", + arg: "1", + init: PrimitiveExtraInit::None, + }, + ], + since: 0, + }, + Command { + web2cname: "INPUT", + parser_overload_name: None, + macro_overload_name: None, + arg_type: ArgumentType::Unspecified, + primitives: &[ + CommandPrimitive { + name: "input", + arg: "0", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "endinput", + arg: "1", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "scantokens", + arg: "2", + init: PrimitiveExtraInit::None, + }, + ], + since: 0, + }, + Command { + web2cname: "IF_TEST", + parser_overload_name: None, + macro_overload_name: None, + arg_type: ArgumentType::Unspecified, + primitives: &[ + CommandPrimitive { + name: "if", + arg: "IF_CHAR_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "ifcat", + arg: "IF_CAT_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "ifnum", + arg: "IF_INT_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "ifdim", + arg: "IF_DIM_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "ifodd", + arg: "IF_ODD_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "ifvmode", + arg: "IF_VMODE_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "ifhmode", + arg: "IF_HMODE_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "ifmmode", + arg: "IF_MMODE_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "ifinner", + arg: "IF_INNER_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "ifvoid", + arg: "IF_VOID_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "ifhbox", + arg: "IF_HBOX_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "ifvbox", + arg: "IF_VBOX_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "ifx", + arg: "IFX_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "ifeof", + arg: "IF_EOF_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "iftrue", + arg: "IF_TRUE_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "iffalse", + arg: "IF_FALSE_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "ifcase", + arg: "IF_CASE_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "ifdefined", + arg: "IF_DEF_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "ifcsname", + arg: "IF_CS_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "iffontchar", + arg: "IF_FONT_CHAR_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "ifincsname", + arg: "IF_IN_CSNAME_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "ifprimitive", + arg: "IF_PRIMITIVE_CODE", + init: PrimitiveExtraInit::None, + }, + ], + since: 0, + }, + Command { + web2cname: "FI_OR_ELSE", + parser_overload_name: None, + macro_overload_name: None, + arg_type: ArgumentType::Unspecified, + primitives: &[ + CommandPrimitive { + name: "fi", + arg: "FI_CODE", + init: PrimitiveExtraInit::Frozen("FROZEN_FI"), + }, + CommandPrimitive { + name: "else", + arg: "ELSE_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "or", + arg: "OR_CODE", + init: PrimitiveExtraInit::None, + }, + ], + since: 0, + }, + Command { + web2cname: "CS_NAME", + parser_overload_name: None, + macro_overload_name: None, + arg_type: ArgumentType::Unspecified, + primitives: &[CommandPrimitive { + name: "csname", + arg: "0", + init: PrimitiveExtraInit::None, + }], + since: 0, + }, + Command { + web2cname: "CONVERT", + parser_overload_name: None, + macro_overload_name: None, + arg_type: ArgumentType::Unspecified, + primitives: &[ + CommandPrimitive { + name: "number", + arg: "NUMBER_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "romannumeral", + arg: "ROMAN_NUMERAL_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "string", + arg: "STRING_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "meaning", + arg: "MEANING_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "fontname", + arg: "FONT_NAME_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "eTeXrevision", + arg: "ETEX_REVISION_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "expanded", + arg: "EXPANDED_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "leftmarginkern", + arg: "LEFT_MARGIN_KERN_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "rightmarginkern", + arg: "RIGHT_MARGIN_KERN_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "strcmp", + arg: "PDF_STRCMP_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "creationdate", + arg: "PDF_CREATION_DATE_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "filemoddate", + arg: "PDF_FILE_MOD_DATE_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "filesize", + arg: "PDF_FILE_SIZE_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "mdfivesum", + arg: "PDF_MDFIVE_SUM_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "filedump", + arg: "PDF_FILE_DUMP_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "uniformdeviate", + arg: "UNIFORM_DEVIATE_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "normaldeviate", + arg: "NORMAL_DEVIATE_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "XeTeXvariationname", + arg: "XETEX_VARIATION_NAME_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "XeTeXrevision", + arg: "XETEX_REVISION_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "XeTeXfeaturename", + arg: "XETEX_FEATURE_NAME_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "XeTeXselectorname", + arg: "XETEX_SELECTOR_NAME_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "XeTeXglyphname", + arg: "XETEX_GLYPH_NAME_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "Uchar", + arg: "XETEX_UCHAR_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "Ucharcat", + arg: "XETEX_UCHARCAT_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "jobname", + arg: "JOB_NAME_CODE", + init: PrimitiveExtraInit::None, + }, + ], + since: 0, + }, + Command { + web2cname: "THE", + parser_overload_name: None, + macro_overload_name: None, + arg_type: ArgumentType::Unspecified, + primitives: &[ + CommandPrimitive { + name: "the", + arg: "0", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "unexpanded", + arg: "1", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "detokenize", + arg: "SHOW_TOKENS", + init: PrimitiveExtraInit::None, + }, + ], + since: 0, + }, + Command { + web2cname: "TOP_BOT_MARK", + parser_overload_name: None, + macro_overload_name: None, + arg_type: ArgumentType::Unspecified, + primitives: &[ + CommandPrimitive { + name: "topmark", + arg: "TOP_MARK_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "firstmark", + arg: "FIRST_MARK_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "botmark", + arg: "BOT_MARK_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "splitfirstmark", + arg: "SPLIT_FIRST_MARK_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "splitbotmark", + arg: "SPLIT_BOT_MARK_CODE", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "topmarks", + arg: "TOP_MARK_CODE + 5", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "firstmarks", + arg: "FIRST_MARK_CODE + 5", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "botmarks", + arg: "BOT_MARK_CODE + 5", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "splitfirstmarks", + arg: "SPLIT_FIRST_MARK_CODE + 5", + init: PrimitiveExtraInit::None, + }, + CommandPrimitive { + name: "splitbotmarks", + arg: "SPLIT_BOT_MARK_CODE + 5", + init: PrimitiveExtraInit::None, + }, + ], + since: 0, + }, + Command { + web2cname: "CALL", + parser_overload_name: None, + macro_overload_name: None, + arg_type: ArgumentType::Unspecified, + primitives: &[], + since: 0, + }, + Command { + web2cname: "LONG_CALL", + parser_overload_name: None, + macro_overload_name: None, + arg_type: ArgumentType::Unspecified, + primitives: &[], + since: 0, + }, + Command { + web2cname: "OUTER_CALL", + parser_overload_name: None, + macro_overload_name: None, + arg_type: ArgumentType::Unspecified, + primitives: &[], + since: 0, + }, + Command { + web2cname: "LONG_OUTER_CALL", + parser_overload_name: None, + macro_overload_name: None, + arg_type: ArgumentType::Unspecified, + primitives: &[], + since: 0, + }, + Command { + web2cname: "END_TEMPLATE", + parser_overload_name: None, + macro_overload_name: None, + arg_type: ArgumentType::Unspecified, + primitives: &[], + since: 0, + }, + Command { + web2cname: "DONT_EXPAND", + parser_overload_name: None, + macro_overload_name: None, + arg_type: ArgumentType::Unspecified, + primitives: &[], + since: 0, + }, + Command { + web2cname: "GLUE_REF", + parser_overload_name: None, + macro_overload_name: None, + arg_type: ArgumentType::Unspecified, + primitives: &[], + since: 0, + }, + Command { + web2cname: "SHAPE_REF", + parser_overload_name: None, + macro_overload_name: None, + arg_type: ArgumentType::Unspecified, + primitives: &[], + since: 0, + }, + Command { + web2cname: "BOX_REF", + parser_overload_name: None, + macro_overload_name: None, + arg_type: ArgumentType::Unspecified, + primitives: &[], + since: 0, + }, + Command { + web2cname: "DATA", + parser_overload_name: None, + macro_overload_name: None, + arg_type: ArgumentType::Unspecified, + primitives: &[], + since: 0, + }, +]; + +/// Get information about the commands used in the latest engine format. +pub fn get_latest_commands() -> &'static [Command] { + COMMANDS +} + +/// Get information about the commands used in a specific engine format +/// version. +pub fn get_commands_for_version(version: FormatVersion) -> Vec { + let mut r = Vec::new(); + + for p in COMMANDS { + if version >= p.since { + r.push(*p) + } + } + + r +} + +/// Emit the beginning of the C header information for the commands and +/// primitives. +pub fn emit_c_header_beginning(cmds: &[Command], mut stream: W) -> Result<()> { + writeln!( + stream, + "/* Commands */ + +#undef IGNORE /* Windows OS headers sometimes define this */ +" + )?; + + for (index, cmd) in cmds.iter().enumerate() { + writeln!(stream, "#define {} {}", cmd.web2cname, index)?; + + if let Some(o) = cmd.parser_overload_name { + writeln!( + stream, + "#define {} {} /* Overloaded usage in parser */", + o, cmd.web2cname + )?; + } + + if let Some(o) = cmd.macro_overload_name { + writeln!( + stream, + "#define {} {} /* Overloaded usage in macro evaluation */", + o, cmd.web2cname + )?; + } + } + + writeln!( + stream, + "\n/* Primitives */ + +enum xetex_format_primitive_extra_init_t {{ + xf_prim_init_none = 0, + xf_prim_init_par = 1, + xf_prim_init_write = 2 + /* Other values should be used to set up a \"frozen\" primitive */ +}}; + +typedef struct xetex_format_primitive_def_t {{ + char const *name; + eight_bits cmd; + int32_t chr; + int32_t extra_init; +}} xetex_format_primitive_def_t; + +#define XETEX_FORMAT_PRIMITIVE_INITIALIZERS \\" + )?; + + for cmd in cmds { + for prim in cmd.primitives { + let extra_init = match prim.init { + PrimitiveExtraInit::None => "xf_prim_init_none", + PrimitiveExtraInit::Par => "xf_prim_init_par", + PrimitiveExtraInit::Write => "xf_prim_init_write", + PrimitiveExtraInit::Frozen(s) => s, + }; + + writeln!( + stream, + " {{ \"{}\", {}, {}, {} }}, \\", + prim.name, cmd.web2cname, prim.arg, extra_init + )?; + } + } + + Ok(()) +} + +/// Emit the ending of the C header information for the commands and +/// primitives. +pub fn emit_c_header_ending(_cmds: &[Command], mut stream: W) -> Result<()> { + // We just need to terminate the primitives macro definition + writeln!(stream, " {{ NULL, 0, 0, 0 }}")?; + Ok(()) +} diff --git a/crates/xetex_format/src/cshash.rs b/crates/xetex_format/src/cshash.rs new file mode 100644 index 000000000..478527a64 --- /dev/null +++ b/crates/xetex_format/src/cshash.rs @@ -0,0 +1,198 @@ +// Copyright 2021 the Tectonic Project +// Licensed under the MIT License. + +//! The hash table for multi-letter control sequences. + +use nom::{ + multi::count, + number::complete::{be_i32, be_u8}, + IResult, +}; + +use crate::{ + base::{self, SIZEOF_MEMORY_WORD}, + engine::Engine, + eqtb::EqtbPointer, + parseutils, + stringtable::{StrPointer, StringTable}, +}; + +#[derive(Debug)] +pub struct ControlSeqHash { + need_offset_hash: Vec, + + // To keep this type self-contained, it's easiest just to copy out the + // settings that we need to do our various computations. + hash_base: EqtbPointer, + hash_prime: u32, + hash_offset: i32, + single_base: EqtbPointer, + null_cs_loc: EqtbPointer, + undefined_cs_loc: EqtbPointer, + eqtb_size: EqtbPointer, + eqtb_top: EqtbPointer, + prim_eqtb_base: EqtbPointer, + frozen_null_font_loc: EqtbPointer, +} + +impl ControlSeqHash { + pub(crate) fn parse<'a>( + input: &'a [u8], + engine: &Engine, + hash_high: i32, + ) -> IResult<&'a [u8], Self> { + let hash_base = engine.settings.hash_base; + let hash_prime = engine.settings.hash_prime; + let hash_offset = engine.settings.hash_offset; + let single_base = engine.settings.single_base; + let null_cs_loc = engine.settings.null_cs_loc; + let undefined_cs_loc = engine.settings.undefined_control_sequence; + let eqtb_size = engine.settings.eqtb_size; + let eqtb_top = engine.settings.eqtb_top; + let prim_eqtb_base = engine.settings.prim_eqtb_base; + let frozen_null_font_loc = engine.settings.frozen_null_font_loc; + + let index = |i: i32| (i - hash_offset) as usize * SIZEOF_MEMORY_WORD; + + let high_hash_size = engine.settings.eqtb_top + 1 - hash_offset; + let mut need_offset_hash = vec![0u8; high_hash_size as usize * SIZEOF_MEMORY_WORD]; + + let (input, hash_used) = parseutils::ranged_be_i32( + hash_base, + engine.settings.frozen_control_sequence_base, + )(input)?; + + let mut p = hash_base - 1; + let mut input = input; + + loop { + let (ii, new_p) = parseutils::ranged_be_i32(p + 1, hash_used)(input)?; + p = new_p; + + // TODO: load directly into `hash`? + let (ii, block) = count(be_u8, 8)(ii)?; + let ofs = index(p); + need_offset_hash[ofs..ofs + 8].copy_from_slice(&block[..]); + + input = ii; + + if p == hash_used { + break; + } + } + + // TODO: load directly into `hash`? + let nb = ((engine.settings.undefined_control_sequence - 1) - hash_used) as usize + * SIZEOF_MEMORY_WORD; + let (input, block) = count(be_u8, nb)(input)?; + let ofs = index(hash_used + 1); + need_offset_hash[ofs..ofs + nb].copy_from_slice(&block[..]); + + let mut input = input; + + if hash_high > 0 { + let nb = hash_high as usize * SIZEOF_MEMORY_WORD; + let (new_input, block) = count(be_u8, nb)(input)?; + input = new_input; + let ofs = index(engine.settings.eqtb_size + 1); + need_offset_hash[ofs..ofs + nb].copy_from_slice(&block[..]); + } + + let (input, _cs_count) = be_i32(input)?; + + Ok(( + input, + ControlSeqHash { + need_offset_hash, + hash_base, + hash_prime, + hash_offset, + single_base, + null_cs_loc, + undefined_cs_loc, + eqtb_size, + eqtb_top, + prim_eqtb_base, + frozen_null_font_loc, + }, + )) + } + + fn decode(&self, index: i32) -> (StrPointer, i32) { + let index = index - self.hash_offset; + let text_ptr = base::memword_read_b32_s1(&self.need_offset_hash[..], index); + let next_ptr = base::memword_read_b32_s0(&self.need_offset_hash[..], index); + (text_ptr, next_ptr) + } + + pub fn lookup(&self, csname: &str, strings: &StringTable) -> Option { + let csname_len_utf16 = crate::stringtable::len_utf16(csname); + + let mut h = 0; + + for c in csname.chars() { + h = h + h + c as u32; + while h >= self.hash_prime { + h -= self.hash_prime; + } + } + + let mut p = h as i32 + self.hash_base; + + loop { + let (str_ptr, next_ptr) = self.decode(p); + + if str_ptr > 0 { + let len = strings.utf16_length(str_ptr); + + if len == csname_len_utf16 { + let s = strings.lookup(str_ptr); + + if s == csname { + return Some(p); + } + } + } + + if next_ptr == 0 { + return None; + } + + p = next_ptr; + } + } + + /// Similar to TeX's `print_cs` + pub fn stringify(&self, p: EqtbPointer, strings: &StringTable) -> Option { + if p < self.hash_base { + // Single-character control sequence, or active character, or the + // null CS. + + if p >= self.single_base { + if p == self.null_cs_loc { + return Some("".to_owned()); + } else { + let usv = (p - self.single_base) as u32; + return char::from_u32(usv).map(|c| c.to_string()); + } + } + } + if p >= self.undefined_cs_loc && p <= self.eqtb_size { + return None; + } + + if p > self.eqtb_top { + return None; + } + + if p >= self.prim_eqtb_base && p < self.frozen_null_font_loc { + //TODO: print_esc(prim[p - PRIM_EQTB_BASE].s1 - 1); + return None; + } + + // `if (text(p) >= str_ptr) => "NONEXISTENT."` + + let (text_ptr, _next_ptr) = self.decode(p); + Some(strings.lookup(text_ptr).to_owned()) + } +} diff --git a/crates/xetex_format/src/dimenpars.rs b/crates/xetex_format/src/dimenpars.rs new file mode 100644 index 000000000..dea76fbc5 --- /dev/null +++ b/crates/xetex_format/src/dimenpars.rs @@ -0,0 +1,166 @@ +// Copyright 2021 the Tectonic Project +// Licensed under the MIT License. + +#![deny(missing_docs)] + +//! Dimensional parameters defined by the engine. + +use std::io::{Result, Write}; + +use super::FormatVersion; + +/// Information about dimensional parameters. +#[derive(Clone, Copy, Debug)] +pub struct DimenPar { + /// The name of the parameter. + name: &'static str, + + /// The first format version in which the parameter was introduced. + since: FormatVersion, +} + +const DIMEN_PARS: &[DimenPar] = &[ + DimenPar { + name: "par_indent", + since: 0, + }, + DimenPar { + name: "math_surround", + since: 0, + }, + DimenPar { + name: "line_skip_limit", + since: 0, + }, + DimenPar { + name: "hsize", + since: 0, + }, + DimenPar { + name: "vsize", + since: 0, + }, + DimenPar { + name: "max_depth", + since: 0, + }, + DimenPar { + name: "split_max_depth", + since: 0, + }, + DimenPar { + name: "box_max_depth", + since: 0, + }, + DimenPar { + name: "hfuzz", + since: 0, + }, + DimenPar { + name: "vfuzz", + since: 0, + }, + DimenPar { + name: "delimiter_shortfall", + since: 0, + }, + DimenPar { + name: "null_delimiter_space", + since: 0, + }, + DimenPar { + name: "script_space", + since: 0, + }, + DimenPar { + name: "pre_display_size", + since: 0, + }, + DimenPar { + name: "display_width", + since: 0, + }, + DimenPar { + name: "display_indent", + since: 0, + }, + DimenPar { + name: "overfull_rule", + since: 0, + }, + DimenPar { + name: "hang_indent", + since: 0, + }, + DimenPar { + name: "h_offset", + since: 0, + }, + DimenPar { + name: "v_offset", + since: 0, + }, + DimenPar { + name: "emergency_stretch", + since: 0, + }, + DimenPar { + name: "pdf_page_width", + since: 0, + }, + DimenPar { + name: "pdf_page_height", + since: 0, + }, +]; + +/// Get information about the dimension parameters used in the latest engine +/// format. +pub fn get_latest_dimenpars() -> &'static [DimenPar] { + DIMEN_PARS +} + +/// Get information about the dimension parameters used in a specific engine +/// format version. +pub fn get_dimenpars_for_version(version: FormatVersion) -> Vec { + let mut r = Vec::new(); + + for p in DIMEN_PARS { + if version >= p.since { + r.push(*p) + } + } + + r +} + +/// Emit C header information for the dimensional parameters +pub fn emit_c_header_stanza(pars: &[DimenPar], mut stream: W) -> Result<()> { + writeln!(stream, "/* Dimensional (length) parameters */\n")?; + + for (index, par) in pars.iter().enumerate() { + writeln!( + stream, + "#define DIMEN_PAR__{} {}", + par.name.to_lowercase(), + index + )?; + } + + writeln!(stream, "#define DIMEN_PARS {}\n", pars.len())?; + Ok(()) +} + +/// Emit initializers for dimenpar primitives in the C header. +pub fn emit_c_header_primitives(pars: &[DimenPar], mut stream: W) -> Result<()> { + for par in pars { + writeln!( + stream, + " {{ \"{}\", ASSIGN_DIMEN, DIMEN_BASE + DIMEN_PAR__{}, xf_prim_init_none }}, \\", + par.name.replace("_", ""), + par.name.to_lowercase(), + )?; + } + + Ok(()) +} diff --git a/crates/xetex_format/src/engine.rs b/crates/xetex_format/src/engine.rs new file mode 100644 index 000000000..7f889a898 --- /dev/null +++ b/crates/xetex_format/src/engine.rs @@ -0,0 +1,433 @@ +// Copyright 2021 the Tectonic Project +// Licensed under the MIT License. + +#![deny(missing_docs)] + +//! The overall interface provided by the engine. + +use std::io::{Result, Write}; + +use crate::{ + base, + commands::{self, CommandCode}, + dimenpars, + eqtb::EqtbPointer, + etexpenalties, gluepars, intpars, locals, + mem::MemPointer, + FormatVersion, LATEST_VERSION, +}; + +/// Information about the engine implementation. +#[derive(Clone, Debug)] +pub struct Engine { + /// The interface version implemented by this engine. + pub version: FormatVersion, + + /// Various precomputed numerical settings. + pub settings: EngineSettings, + + /// The low-level commands provided by the engine. + pub commands: Vec, + + /// The integer parameters defined in this engine implementation. + pub int_pars: Vec, + + /// The dimension parameters defined in this engine implementation. + pub dimen_pars: Vec, + + /// The glue parameters defined in this engine implementation. + pub glue_pars: Vec, + + /// The "local" (token list and shape, excluding e-TeX penalties) parameters + /// defined in this engine implementation. + pub local_pars: Vec, + + /// The e-TeX penalties parameters defined in this engine implementation. + pub etex_penalties_pars: Vec, +} + +impl Engine { + /// Get an engine definition for a specific version. + pub fn new_for_version(version: FormatVersion) -> Engine { + let int_pars = intpars::get_intpars_for_version(version); + let dimen_pars = dimenpars::get_dimenpars_for_version(version); + let glue_pars = gluepars::get_gluepars_for_version(version); + let local_pars = locals::get_local_pars_for_version(version); + let etex_penalties_pars = etexpenalties::get_etex_penalties_pars_for_version(version); + let commands = commands::get_commands_for_version(version); + let settings = EngineSettings::new( + &int_pars[..], + &dimen_pars[..], + &glue_pars[..], + &local_pars[..], + &etex_penalties_pars[..], + &commands[..], + ); + + Engine { + version, + settings, + commands, + int_pars, + dimen_pars, + glue_pars, + local_pars, + etex_penalties_pars, + } + } + + /// Create a C header file defining the WEB2C constants associated with this + /// particular engine. + pub fn emit_c_header(&self, mut stream: W) -> Result<()> { + writeln!( + stream, + "/* tectonic_xetex_format engine header for version {} */ +/* This file is automatically generated by the `xetex_format` `emit` example. Do not modify. */ + +#ifndef __TECTONIC_XETEX_FORMAT_ENGINE_HEADER__ +#define __TECTONIC_XETEX_FORMAT_ENGINE_HEADER__ +", + self.version + )?; + + self.settings.emit_c_header_stanza(&mut stream)?; + intpars::emit_c_header_stanza(&self.int_pars[..], &mut stream)?; + dimenpars::emit_c_header_stanza(&self.dimen_pars[..], &mut stream)?; + gluepars::emit_c_header_stanza(&self.glue_pars[..], &mut stream)?; + locals::emit_c_header_stanza(&self.local_pars[..], &mut stream)?; + etexpenalties::emit_c_header_stanza(&self.etex_penalties_pars[..], &mut stream)?; + + commands::emit_c_header_beginning(&self.commands[..], &mut stream)?; + intpars::emit_c_header_primitives(&self.int_pars[..], &mut stream)?; + dimenpars::emit_c_header_primitives(&self.dimen_pars[..], &mut stream)?; + gluepars::emit_c_header_primitives(&self.glue_pars[..], &mut stream)?; + locals::emit_c_header_primitives(&self.local_pars[..], &mut stream)?; + etexpenalties::emit_c_header_primitives(&self.etex_penalties_pars[..], &mut stream)?; + commands::emit_c_header_ending(&self.commands[..], &mut stream)?; + + writeln!(stream, "#endif")?; + Ok(()) + } +} + +impl Default for Engine { + fn default() -> Self { + Engine::new_for_version(LATEST_VERSION) + } +} + +/// Various parameters about engine arrays. +/// +/// Most of these are compile-time constants in the engine code, but we express +/// them as variables because the flexibility is good to have and we don't care +/// about runtime performance. +#[derive(Clone, Copy, Debug)] +pub struct EngineSettings { + /// The size of the hash table for multi-letter control sequences -- + /// so, the maximum number of allowed multi-letter control sequences. + pub hash_size: i32, + + /// Extra space for the hash table. TODO: figure out the relationship + /// between this and `hash_size` better. + pub hash_extra: i32, + + /// "smallest index in hash array" + pub hash_offset: i32, + + /// The magic number for the multiletter control sequence hash table. + pub hash_prime: u32, + + /// The size of the hash table for primitives -- + /// so, the maximum number of allowed primitives. + pub prim_size: i32, + + /// The maximum number of fonts that can be loaded (`max_font_max` in TeX) + pub max_fonts: i32, + + /// The largest valid dynamic memory address + pub mem_top: MemPointer, + + /// The eqtb location where the commands associated with active characters + /// are stored. + pub active_base: EqtbPointer, + + /// The eqtb location where single-letter control sequence equivalents are + /// stored. + pub single_base: EqtbPointer, + + /// The eqtb location where the multiletter control sequence hash table + /// starts. + pub hash_base: EqtbPointer, + + /// The eqtb location where the hash table of primitives is stored. + pub prim_eqtb_base: EqtbPointer, + + /// The eqtb location where glue parameters are stored. + pub glue_base: EqtbPointer, + + /// The eqtb location where glue registeres are stored. + pub skip_base: EqtbPointer, + + /// The eqtb location where math glue registers are stored. + pub mu_skip_base: EqtbPointer, + + /// The eqtb location where the "local" parameters are stored. + pub local_base: EqtbPointer, + + /// The eqtb location where token registers are stored. + pub toks_base: EqtbPointer, + + /// The eqtb location where the e-TeX penalties parameters are stored. + pub etex_pen_base: EqtbPointer, + + /// The eqtb location where box registers are stored. + pub box_base: EqtbPointer, + + /// The eqtb location where the current font is stored. + pub cur_font_loc: EqtbPointer, + + /// The eqtb location where math fonts are stored. + pub math_font_base: EqtbPointer, + + /// The eqtb location where character category codes are stored. + pub cat_code_base: EqtbPointer, + + /// The eqtb location where character lower-case codes are stored. + pub lc_code_base: EqtbPointer, + + /// The eqtb location where character upper-case codes are stored. + pub uc_code_base: EqtbPointer, + + /// The eqtb location where character space-factor codes are stored. + pub sf_code_base: EqtbPointer, + + /// The eqtb location where character math codes are stored. + pub math_code_base: EqtbPointer, + + /// The eqtb location where MLTeX character substitution codes are stored. + pub char_sub_code_base: EqtbPointer, + + /// The eqtb location where integer parameters are stored. + pub int_base: EqtbPointer, + + /// The eqtb location where integer registers are stored. + pub count_base: EqtbPointer, + + /// The eqtb location where delimiter codes are stored. + pub del_code_base: EqtbPointer, + + /// The eqtb location where length parameters are stored. + pub dimen_base: EqtbPointer, + + /// The eqtb location where length registers are stored. + pub scaled_base: EqtbPointer, + + /// The last address in the non-hash portion of the eqtb -- or, the size of + /// this portion minus one. + pub eqtb_size: EqtbPointer, + + /// The very last legal address in the eqtb -- or, the size of the eqtb + /// minus one. + /// + /// By definition, `eqtb_top = eqtb_size + hash_extra`. + pub eqtb_top: EqtbPointer, + + /// The eqtb location where special frozen control sequences are stored. + /// + /// In TeX this is `frozen_control_sequence`. + pub frozen_control_sequence_base: EqtbPointer, + + /// The magic eqtb location that means "undefined control sequence". + /// + /// This position in the eqtb actually exists but I don't believe it's + /// ever accessed. + pub undefined_control_sequence: EqtbPointer, + + /// The eqtb location for the "null" control sequence whose name is empty + /// (`\csname\endcsname`) + pub null_cs_loc: EqtbPointer, + + /// The command code for an undefined control sequence. + pub undefined_cs_command: CommandCode, + + /// The eqtb location where an immutable reference to the null font is + /// stored. + pub frozen_null_font_loc: EqtbPointer, +} + +impl EngineSettings { + fn new( + int_pars: &[intpars::IntPar], + dimen_pars: &[dimenpars::DimenPar], + glue_pars: &[gluepars::GluePar], + local_pars: &[locals::LocalPar], + etex_penalties_pars: &[etexpenalties::EtexPenaltiesPar], + commands: &[commands::Command], + ) -> Self { + // Basic memory parameters + + let hash_size = 15_000; + let hash_extra = 600_000; + let prim_size = 500; + let max_fonts = 9000; + let hash_offset = 514; + let hash_prime = 8501; + let mem_top = 4_999_999; + + // The size of the eqtb is fixed at runtime but depends on many + // different settings. Figure it all out. + + let n_frozen_primitives = 12; + let n_glue_pars = glue_pars.len() as i32; + let n_locals = local_pars.len() as i32; + let n_etex_pens = etex_penalties_pars.len() as i32; + let n_int_pars = int_pars.len() as i32; + let n_dimen_pars = dimen_pars.len() as i32; + + let active_base = 1; + let single_base = active_base + base::NUMBER_USVS as i32; + let null_cs_loc = single_base + base::NUMBER_USVS as i32; + let hash_base = null_cs_loc + 1; + let frozen_control_sequence_base = hash_base + hash_size; + let prim_eqtb_base = frozen_control_sequence_base + n_frozen_primitives; + let frozen_null_font_loc = prim_eqtb_base + prim_size; + let undefined_control_sequence = frozen_null_font_loc + max_fonts + 1; + let glue_base = undefined_control_sequence + 1; + let skip_base = glue_base + n_glue_pars; + let mu_skip_base = skip_base + base::NUMBER_REGS as i32; + let local_base = mu_skip_base + base::NUMBER_REGS as i32; + let toks_base = local_base + n_locals; + let etex_pen_base = toks_base + base::NUMBER_REGS as i32; + let box_base = etex_pen_base + n_etex_pens; + let cur_font_loc = box_base + base::NUMBER_REGS as i32; + let math_font_base = cur_font_loc + 1; + let cat_code_base = math_font_base + base::NUMBER_MATH_FONTS as i32; + let lc_code_base = cat_code_base + base::NUMBER_USVS as i32; + let uc_code_base = lc_code_base + base::NUMBER_USVS as i32; + let sf_code_base = uc_code_base + base::NUMBER_USVS as i32; + let math_code_base = sf_code_base + base::NUMBER_USVS as i32; + let char_sub_code_base = math_code_base + base::NUMBER_USVS as i32; + let int_base = char_sub_code_base + base::NUMBER_USVS as i32; + let count_base = int_base + n_int_pars; + let del_code_base = count_base + base::NUMBER_REGS as i32; + let dimen_base = del_code_base + base::NUMBER_USVS as i32; + let scaled_base = dimen_base + n_dimen_pars; + let eqtb_size = scaled_base + base::NUMBER_REGS as i32 - 1; // XXXX note the minus-one + let eqtb_top = eqtb_size + hash_extra; + + // Command codes of interest + + let mut undefined_cs_command = -1; + + for (index, cmd) in commands.iter().enumerate() { + if cmd.web2cname == "UNDEFINED_CS" { + undefined_cs_command = index as commands::CommandCode; + } + } + + assert!(undefined_cs_command > 0); + + // Finally we have everything + + EngineSettings { + hash_size, + hash_extra, + prim_size, + max_fonts, + mem_top, + active_base, + single_base, + hash_base, + hash_offset, + hash_prime, + glue_base, + skip_base, + mu_skip_base, + local_base, + toks_base, + etex_pen_base, + box_base, + cur_font_loc, + math_font_base, + cat_code_base, + lc_code_base, + uc_code_base, + sf_code_base, + math_code_base, + char_sub_code_base, + int_base, + count_base, + del_code_base, + dimen_base, + scaled_base, + eqtb_size, + eqtb_top, + frozen_control_sequence_base, + undefined_control_sequence, + undefined_cs_command, + null_cs_loc, + prim_eqtb_base, + frozen_null_font_loc, + } + } + + fn emit_c_header_stanza(&self, mut stream: W) -> Result<()> { + writeln!(stream, "/* Memory settings */\n")?; + writeln!(stream, "#define HASH_SIZE {}", self.hash_size)?; + writeln!(stream, "#define HASH_EXTRA {}", self.hash_extra)?; + writeln!(stream, "#define HASH_OFFSET {}", self.hash_offset)?; + writeln!(stream, "#define HASH_PRIME {}", self.hash_prime)?; + writeln!(stream, "#define PRIM_SIZE {}", self.prim_size)?; + writeln!(stream, "#define MAX_FONT_MAX {}", self.max_fonts)?; + writeln!(stream, "#define MEM_TOP {}", self.mem_top)?; + + writeln!(stream, "\n/* Equivalents table addresses */\n")?; + writeln!(stream, "#define ACTIVE_BASE {}", self.active_base)?; + writeln!(stream, "#define SINGLE_BASE {}", self.single_base)?; + writeln!(stream, "#define NULL_CS {}", self.null_cs_loc)?; + writeln!(stream, "#define HASH_BASE {}", self.hash_base)?; + writeln!( + stream, + "#define FROZEN_CONTROL_SEQUENCE {}", + self.frozen_control_sequence_base + )?; + writeln!(stream, "#define PRIM_EQTB_BASE {}", self.prim_eqtb_base)?; + writeln!( + stream, + "#define FROZEN_NULL_FONT {}", + self.frozen_null_font_loc + )?; + writeln!( + stream, + "#define UNDEFINED_CONTROL_SEQUENCE {}", + self.undefined_control_sequence + )?; + writeln!(stream, "#define GLUE_BASE {}", self.glue_base)?; + writeln!(stream, "#define SKIP_BASE {}", self.skip_base)?; + writeln!(stream, "#define MU_SKIP_BASE {}", self.mu_skip_base)?; + writeln!(stream, "#define LOCAL_BASE {}", self.local_base)?; + writeln!(stream, "#define TOKS_BASE {}", self.toks_base)?; + writeln!(stream, "#define ETEX_PEN_BASE {}", self.etex_pen_base)?; + writeln!(stream, "#define BOX_BASE {}", self.box_base)?; + writeln!(stream, "#define CUR_FONT_LOC {}", self.cur_font_loc)?; + writeln!(stream, "#define MATH_FONT_BASE {}", self.math_font_base)?; + writeln!(stream, "#define CAT_CODE_BASE {}", self.cat_code_base)?; + writeln!(stream, "#define LC_CODE_BASE {}", self.lc_code_base)?; + writeln!(stream, "#define UC_CODE_BASE {}", self.uc_code_base)?; + writeln!(stream, "#define SF_CODE_BASE {}", self.sf_code_base)?; + writeln!(stream, "#define MATH_CODE_BASE {}", self.math_code_base)?; + writeln!( + stream, + "#define CHAR_SUB_CODE_BASE {}", + self.char_sub_code_base + )?; + writeln!(stream, "#define INT_BASE {}", self.int_base)?; + writeln!(stream, "#define COUNT_BASE {}", self.count_base)?; + writeln!(stream, "#define DEL_CODE_BASE {}", self.del_code_base)?; + writeln!(stream, "#define DIMEN_BASE {}", self.dimen_base)?; + writeln!(stream, "#define SCALED_BASE {}", self.scaled_base)?; + writeln!(stream, "#define EQTB_SIZE {}", self.eqtb_size)?; + writeln!(stream, "#define EQTB_TOP {}\n", self.eqtb_top)?; + Ok(()) + } +} diff --git a/crates/xetex_format/src/eqtb.rs b/crates/xetex_format/src/eqtb.rs new file mode 100644 index 000000000..9511f5d8f --- /dev/null +++ b/crates/xetex_format/src/eqtb.rs @@ -0,0 +1,203 @@ +// Copyright 2021 the Tectonic Project +// Licensed under the MIT License. + +//! The "equivalencies table". +//! +//! Its structure is: +//! +//! 1. Active characters (`active_base`, `NUMBER_USVS` entries) +//! 2. One-letter control sequences (`single_base`, `NUMBER_USVS`) +//! 3. The "null" control sequence (`null_cs`) +//! 4. The control-sequence hash table (`hash_base`, `hash_size` = 15000) +//! 5. Special frozen control sequences (`frozen_control_sequence_base`, 12 +//! entries) +//! 0. `frozen_protection` +//! 1. frozen \cr +//! 2. frozen \endgroup +//! 3. frozen \right +//! 4. frozen \fi +//! 5. frozen \endtemplate, `frozen_end_template` +//! 6. frozen \endtemplate again, `frozen_endv` +//! 7. frozen \relax +//! 8. frozen \endwrite +//! 9. frozen \notexpanded: +//! 10. frozen \special +//! 11. frozen \pdfprimitive +//! 6. Primitives (`prim_eqtb_base`, `prim_size` = 500) +//! 7. Frozen `\nullfont` (`frozen_null_font`) +//! 8. Other fonts (`font_id_base+1`, `max_fonts+1` = 9001) +//! 9. Dummy location for undefined control sequences +//! (`undefined_control_sequence`) +//! 10. Glue parameters (`glue_base`, ~19 depending on engine version) +//! 11. "Skips" -- glue registers (`skip_base`, `NUMBER_REGS`) +//! 12. "Mu Skips" -- math glue registers (`mu_skip_base`, `NUMBER_REGS`) +//! 13. Locals -- `\parshape` and token list parameters (`local_base`, ~13 depending on engine) +//! 14. Token registers (`toks_base`, `NUMBER_REGS`) +//! 15. e-TeX penalties (`etex_pen_base`, ~4) +//! 16. Box registers (`box_base`, `NUMBER_REGS`) +//! 17. The current font (`cur_font_loc`) +//! 18. Math fonts (`math_font_base`, `NUMBER_MATH_FONTS` = 3 * 256) +//! 19. Character category codes (`cat_code_base`, `NUMBER_USVS`) +//! 20. Character lower-case codes (`lc_code_base`, `NUMBER_USVS`) +//! 21. Character upper-case codes (`uc_code_base`, `NUMBER_USVS`) +//! 22. Character space-factor codes (`sf_code_base`, `NUMBER_USVS`) +//! 23. Character math codes (`math_code_base`, `NUMBER_USVS`) +//! 24. Character substitution codes (`char_sub_code_base`, `NUMBER_USVS`). +//! This is an MLTeX vestige and perhaps could be removed. +//! 25. Integer parameters (`int_base`, ~85) +//! 26. Integer registers (`count_base`, `NUMBER_REGS`) +//! 27. Delimeter codes (`del_code_base`, `NUMBER_USVS`) +//! 28. Length parameters (`dimen_base`, ~23) +//! 29. Length registers (`scaled_base`, `NUMBER_REGS`) +//! 30. Extra control-sequence hash table (`eqtb_top + 1`, `hash_extra`) +//! +//! Total `eqtb_size` is: +//! +//! - `NUMBER_USVS` * 9 +//! - `NUMBER_REGS` * 6 +//! - hash_size +//! - 16 one-offs +//! - prim_size +//! - max_fonts + 1 +//! - number of engine glue parameters +//! - number of engine token lists +//! - number of engine e-TeX penalties +//! - number of engine integer parameters +//! - number of engine dimension parameters +//! - `NUMBER_MATH_FONTS` +//! - Minus one since eqtb_size is the highest address +//! +//! `eqtb_top` is `eqtb_size + hash_extra` and the total addressed size of the +//! array is `eqtb_top + 1`. + +use nom::{multi::count, number::complete::be_u8, IResult}; + +use crate::{ + base::{self, SIZEOF_MEMORY_WORD, TEX_NULL}, + commands::CommandCode, + engine::Engine, + parseutils, +}; + +#[derive(Debug)] +pub struct EquivalenciesTable { + eqtb: Vec, +} + +pub type EqtbPointer = i32; + +#[derive(Copy, Clone, Debug, Eq, PartialEq)] +pub struct EqtbEntry { + pub level: i16, + pub ty: CommandCode, + pub value: i32, +} + +impl EquivalenciesTable { + pub(crate) fn parse<'a>( + input: &'a [u8], + engine: &Engine, + hash_high: i32, + ) -> IResult<&'a [u8], Self> { + let mut eqtb = vec![0; (engine.settings.eqtb_top as usize + 1) * SIZEOF_MEMORY_WORD]; + + write_eqtb_type( + &mut eqtb[..], + engine.settings.undefined_control_sequence, + engine.settings.undefined_cs_command, + ); + write_eqtb_value( + &mut eqtb[..], + engine.settings.undefined_control_sequence, + TEX_NULL, + ); + write_eqtb_level(&mut eqtb[..], engine.settings.undefined_control_sequence, 0); + + let ucs_ofs = + engine.settings.undefined_control_sequence as usize * base::SIZEOF_MEMORY_WORD; + + for x in (engine.settings.eqtb_size + 1)..(engine.settings.eqtb_top + 1) { + eqtb.copy_within( + ucs_ofs..ucs_ofs + SIZEOF_MEMORY_WORD, + x as usize * SIZEOF_MEMORY_WORD, + ); + } + + let mut k = 1; // really `active_base`, but that will never change + let mut input = input; + + loop { + // "The table of equivalents usually contains repeated information, so + // we dump it in compressed form: The sequence of $n + 2$ values $(n, + // x_1, \ldots, x_n, m)$ in the format file represents $n + m$ + // consecutive entries of |eqtb|, with |m| extra copies of $x_n$, namely + // $(x_1, \ldots, x_n, x_n, \ldots, x_n)$" + + let (ii, n) = parseutils::ranged_be_i32( + 1, + (engine.settings.eqtb_size as usize + 1 - k) as i32, + )(input)?; + + // TODO: read straight into eqtb? + let nb = n as usize * SIZEOF_MEMORY_WORD; + let (ii, block) = count(be_u8, nb)(ii)?; + eqtb[k * SIZEOF_MEMORY_WORD..k * SIZEOF_MEMORY_WORD + nb].copy_from_slice(&block[..]); + k += n as usize; + + let (ii, m) = parseutils::ranged_be_i32( + 0, + (engine.settings.eqtb_size as usize + 1 - k) as i32, + )(ii)?; + + for j in k..k + m as usize { + eqtb.copy_within( + (k - 1) * SIZEOF_MEMORY_WORD..k * SIZEOF_MEMORY_WORD, + j * SIZEOF_MEMORY_WORD, + ); + } + + input = ii; + k += m as usize; + + if k > engine.settings.eqtb_size as usize { + break; + } + } + + if hash_high > 0 { + // TODO: read straight into eqtb? + let nb = hash_high as usize * SIZEOF_MEMORY_WORD; + let (new_input, block) = count(be_u8, nb)(input)?; + input = new_input; + let ofs = (engine.settings.eqtb_size as usize + 1) * SIZEOF_MEMORY_WORD; + eqtb[ofs..ofs + nb].copy_from_slice(&block[..]); + } + + Ok((input, EquivalenciesTable { eqtb })) + } + + pub fn decode(&self, index: EqtbPointer) -> EqtbEntry { + let level = base::memword_read_b16_s0(&self.eqtb[..], index); + let ty = base::memword_read_b16_s1(&self.eqtb[..], index); + let value = base::memword_read_b32_s1(&self.eqtb[..], index); + EqtbEntry { level, ty, value } + } +} + +/// Equivalent of TeX `eq_level` +#[inline(always)] +fn write_eqtb_level(arr: &mut [u8], index: i32, value: i16) { + base::memword_write_b16_s0(arr, index, value); +} + +/// A command code. Equivalent of TeX `eq_type`. +#[inline(always)] +fn write_eqtb_type(arr: &mut [u8], index: i32, value: CommandCode) { + base::memword_write_b16_s1(arr, index, value); +} + +/// Equivalent of TeX `equiv`. +#[inline(always)] +fn write_eqtb_value(arr: &mut [u8], index: i32, value: i32) { + base::memword_write_b32_s1(arr, index, value); +} diff --git a/crates/xetex_format/src/etexpenalties.rs b/crates/xetex_format/src/etexpenalties.rs new file mode 100644 index 000000000..d00cf92ae --- /dev/null +++ b/crates/xetex_format/src/etexpenalties.rs @@ -0,0 +1,94 @@ +// Copyright 2021 the Tectonic Project +// Licensed under the MIT License. + +#![deny(missing_docs)] + +//! e-TeX penalties parameters defined by the engine. +//! +//! These are modified using the `SET_SHAPE` command, which in plain TeX is only +//! used to modify the `parshape` parameter, which is a "local". All of the +//! other locals are token lists. + +use std::io::{Result, Write}; + +use super::FormatVersion; + +/// Information about e-TeX penalties parameters. +#[derive(Clone, Copy, Debug)] +pub struct EtexPenaltiesPar { + /// The name of the parameter. + name: &'static str, + + /// The first format version in which the parameter was introduced. + since: FormatVersion, +} + +const ETEX_PENALTIES_PARS: &[EtexPenaltiesPar] = &[ + EtexPenaltiesPar { + name: "inter_line_penalties", + since: 0, + }, + EtexPenaltiesPar { + name: "club_penalties", + since: 0, + }, + EtexPenaltiesPar { + name: "widow_penalties", + since: 0, + }, + EtexPenaltiesPar { + name: "display_widow_penalties", + since: 0, + }, +]; + +/// Get information about the e-TeX penalties parameters used in the latest +/// engine format. +pub fn get_latest_etex_penalties_pars() -> &'static [EtexPenaltiesPar] { + ETEX_PENALTIES_PARS +} + +/// Get information about the e-TeX penalties parameters used in a specific +/// engine format version. +pub fn get_etex_penalties_pars_for_version(version: FormatVersion) -> Vec { + let mut r = Vec::new(); + + for p in ETEX_PENALTIES_PARS { + if version >= p.since { + r.push(*p) + } + } + + r +} + +/// Emit C header information for the e-TeX penalties parameters. +pub fn emit_c_header_stanza(pars: &[EtexPenaltiesPar], mut stream: W) -> Result<()> { + writeln!(stream, "/* e-TeX penalties parameters */\n")?; + + for (index, par) in pars.iter().enumerate() { + writeln!( + stream, + "#define ETEX_PENALTIES_PAR__{} {}", + par.name.to_lowercase(), + index + )?; + } + + writeln!(stream, "#define NUM_ETEX_PENALTIES {}\n", pars.len())?; + Ok(()) +} + +/// Emit initializers for gluepar primitives in the C header. +pub fn emit_c_header_primitives(pars: &[EtexPenaltiesPar], mut stream: W) -> Result<()> { + for par in pars { + writeln!( + stream, + " {{ \"{}\", SET_SHAPE, ETEX_PEN_BASE + ETEX_PENALTIES_PAR__{}, xf_prim_init_none }}, \\", + par.name.replace("_", ""), + par.name.to_lowercase(), + )?; + } + + Ok(()) +} diff --git a/crates/xetex_format/src/format.rs b/crates/xetex_format/src/format.rs new file mode 100644 index 000000000..0ba18b5f8 --- /dev/null +++ b/crates/xetex_format/src/format.rs @@ -0,0 +1,277 @@ +// Copyright 2021 the Tectonic Project +// Licensed under the MIT License. + +//! Decode a format file. + +use nom::{ + error::{Error as NomError, ErrorKind as NomErrorKind, ParseError}, + multi::count, + number::complete::{be_i16, be_i32, be_i64, be_u16}, + Err as NomErr, IResult, +}; +use tectonic_errors::prelude::*; + +use crate::{ + base::{MAX_HALFWORD, MIN_HALFWORD}, + cshash, + engine::Engine, + eqtb, mem, parseutils, stringtable, FormatVersion, +}; + +/// Saved Tectonic/XeTeX engine state, decoded into memory. +/// +/// This public API of this structure isn't yet complete. It parses format files +/// but does not yet provide proper runtime introspection of the results. +#[derive(Debug)] +#[allow(dead_code)] // TEMPORARY! +pub struct Format { + engine: Engine, + strings: stringtable::StringTable, + mem: mem::Memory, + eqtb: eqtb::EquivalenciesTable, + cshash: cshash::ControlSeqHash, +} + +// Parsing + +const HEADER_MAGIC: i32 = 0x54_54_4E_43; // ASCII "TTNC" +const FOOTER_MAGIC: i32 = 0x00_00_02_9A; +const TOO_BIG_CHAR: i32 = 0x0001_0000; + +const HYPH_SIZE: usize = 8191; + +const TRIE_OP_SIZE: i32 = 35111; + +const BIGGEST_LANG: usize = 255; + +impl Format { + pub fn parse(input: &[u8]) -> Result { + match parse_impl(input) { + Ok((_remainder, result)) => Ok(result), + Err(NomErr::Error(inner)) => bail!("parse error: {}", inner.code.description()), + Err(NomErr::Failure(inner)) => bail!("parse failure: {}", inner.code.description()), + Err(NomErr::Incomplete(_)) => bail!("incomplete input"), + } + } +} + +fn parse_impl(input: &[u8]) -> IResult<&[u8], Format> { + let (input, _) = parseutils::satisfy_be_i32(HEADER_MAGIC)(input)?; + println!("OK header magic"); + + let (input, serial) = be_i32(input)?; + println!("format serial: {}", serial); + + let engine = Engine::new_for_version(serial as FormatVersion); + + let (input, hash_high) = be_i32(input)?; + println!("hash_high: {}", hash_high); + + let (input, mem_top) = be_i32(input)?; + println!("mem_top: {}", mem_top); + + let (input, eqtb_size) = be_i32(input)?; + println!("eqtb_size: {}", eqtb_size); + + let (input, hash_prime) = be_i32(input)?; + println!("hash_prime: {}", hash_prime); + + let (input, hyph_prime) = be_i32(input)?; + println!("hyph_prime: {}", hyph_prime); + + // string table + + let (input, strings) = stringtable::StringTable::parse(input)?; + + // "mem" array + + let (input, mem) = mem::Memory::parse(input, &engine)?; + + // eqtb + + let (input, eqtb) = eqtb::EquivalenciesTable::parse(input, &engine, hash_high)?; + + if engine.settings.eqtb_size != eqtb_size { + println!("eqtb size problem!"); + return Err(NomErr::Error(NomError::from_error_kind( + input, + NomErrorKind::Satisfy, + ))); + } + + println!("eqtb OK"); + + // nominally hash_top, but hash_top = engine.settings.eqtb_top since hash_extra is nonzero + let (input, par_loc) = parseutils::ranged_be_i32( + engine.settings.hash_base as i32, + engine.settings.eqtb_top as i32, + )(input)?; + println!("par_loc: {}", par_loc); + + let (input, write_loc) = parseutils::ranged_be_i32( + engine.settings.hash_base as i32, + engine.settings.eqtb_top as i32, + )(input)?; + println!("write_loc: {}", write_loc); + + // Primitives. TODO: figure out best type for `prims`. + + let (input, _prims) = count(be_i64, engine.settings.prim_size as usize + 1)(input)?; + + // Control sequence names -- the hash table. + + let (input, cshash) = cshash::ControlSeqHash::parse(input, &engine, hash_high)?; + println!("multi-letter control-seq hash loaded OK"); + + // font info + + let (input, fmem_ptr) = parseutils::ranged_be_i32(7, 147483647)(input)?; + println!("fmem_ptr: {}", fmem_ptr); + + let (input, _font_info) = count(be_i64, fmem_ptr as usize)(input)?; + + // NB: FONT_BASE = 0 + let (input, font_ptr) = parseutils::ranged_be_i32(0, engine.settings.max_fonts as i32)(input)?; + println!("font_ptr: {}", font_ptr); + + let n_fonts = font_ptr as usize + 1; + let (input, _font_check) = count(be_i64, n_fonts)(input)?; + let (input, _font_size) = count(be_i32, n_fonts)(input)?; + let (input, _font_dsize) = count(be_i32, n_fonts)(input)?; + let (input, _font_params) = count( + parseutils::ranged_be_i32(MIN_HALFWORD, MAX_HALFWORD), + n_fonts, + )(input)?; + let (input, _hyphen_char) = count(be_i32, n_fonts)(input)?; + let (input, _skew_char) = count(be_i32, n_fonts)(input)?; + let (input, _font_name) = count(be_i32, n_fonts)(input)?; + let (input, _font_area) = count(be_i32, n_fonts)(input)?; + let (input, _font_bc) = count(be_i16, n_fonts)(input)?; + let (input, _font_ec) = count(be_i16, n_fonts)(input)?; + let (input, _char_base) = count(be_i32, n_fonts)(input)?; + let (input, _width_base) = count(be_i32, n_fonts)(input)?; + let (input, _height_base) = count(be_i32, n_fonts)(input)?; + let (input, _depth_base) = count(be_i32, n_fonts)(input)?; + let (input, _italic_base) = count(be_i32, n_fonts)(input)?; + let (input, _lig_kern_base) = count(be_i32, n_fonts)(input)?; + let (input, _kern_base) = count(be_i32, n_fonts)(input)?; + let (input, _exten_base) = count(be_i32, n_fonts)(input)?; + let (input, _param_base) = count(be_i32, n_fonts)(input)?; + let (input, _font_glue) = count( + parseutils::ranged_be_i32(MIN_HALFWORD, mem.lo_mem_max), + n_fonts, + )(input)?; + let (input, _bchar_label) = count(parseutils::ranged_be_i32(0, fmem_ptr - 1), n_fonts)(input)?; + let (input, _font_bchar) = count(parseutils::ranged_be_i32(0, TOO_BIG_CHAR), n_fonts)(input)?; + let (input, _font_false_bchar) = + count(parseutils::ranged_be_i32(0, TOO_BIG_CHAR), n_fonts)(input)?; + + // Hyphenations! + + let (input, hyph_count) = be_i32(input)?; + println!("hyph_count: {}", hyph_count); + + let (input, mut hyph_next) = be_i32(input)?; + println!("hyph_next: {}", hyph_next); + + let mut hyph_link = vec![0u16; HYPH_SIZE]; + let mut hyph_word = vec![0i32; HYPH_SIZE]; + let mut hyph_list = vec![0i32; HYPH_SIZE]; + let mut input = input; + let max_word = strings.len() as i32 + TOO_BIG_CHAR - 1; + + for _ in 0..hyph_count { + let (ii, mut j) = be_i32(input)?; + + if j > 0xFFFF { + hyph_next = j / 0x10000; + j -= hyph_next * 0x10000; + } else { + hyph_next = 0; + } + + hyph_link[j as usize] = hyph_next as u16; + + let (ii, w) = parseutils::ranged_be_i32(0, max_word)(ii)?; + hyph_word[j as usize] = w; + + let (ii, l) = parseutils::ranged_be_i32(MIN_HALFWORD, MAX_HALFWORD)(ii)?; + hyph_list[j as usize] = l; + + input = ii; + } + + // trie + + let (input, trie_max) = be_i32(input)?; + println!("trie_max: {}", trie_max); + + let (input, hyph_start) = parseutils::ranged_be_i32(0, trie_max)(input)?; + println!("hyph_start: {}", hyph_start); + + let n_trie = trie_max as usize + 1; + let (input, _trie_trl) = count(be_i32, n_trie)(input)?; + let (input, _trie_tro) = count(be_i32, n_trie)(input)?; + let (input, _trie_trc) = count(be_u16, n_trie)(input)?; + + let (input, max_hyph_char) = be_i32(input)?; + println!("max_hyph_char: {}", max_hyph_char); + + let (input, trie_op_ptr) = parseutils::ranged_be_i32(0, TRIE_OP_SIZE)(input)?; + println!("trie_op_ptr: {}", trie_op_ptr); + + // IMPORTANT!!! XeTeX loads these into 1-based indices! + let (input, _hyf_distance) = count(be_i16, trie_op_ptr as usize)(input)?; + let (input, _hyf_num) = count(be_i16, trie_op_ptr as usize)(input)?; + let (input, _hyf_next) = count(be_u16, trie_op_ptr as usize)(input)?; + + let mut trie_used = vec![0i32; BIGGEST_LANG + 1]; + let mut op_start = vec![0i32; BIGGEST_LANG + 1]; + + let mut k = BIGGEST_LANG + 1; + let mut j = trie_op_ptr; + let mut input = input; + + while j > 0 { + let (ii, new_k) = parseutils::ranged_be_i32(0, k as i32 - 1)(input)?; + k = new_k as usize; + let (ii, u) = parseutils::ranged_be_i32(1, j)(ii)?; + trie_used[k] = u; + j -= u; + op_start[k] = j; + input = ii; + } + + // All done! + + let (input, _) = parseutils::satisfy_be_i32(FOOTER_MAGIC)(input)?; + println!("OK footer magic!"); + + // test control sequence lookup + + for s in &strings.strings { + if let Some(ptr) = cshash.lookup(s, &strings) { + println!("mlcs: \\{} => {:?}", s, eqtb.decode(ptr)); + } + } + + let csname = "showhyphens"; + let p = cshash.lookup(csname, &strings); + println!("cs {}? {:?}", csname, p); + if let Some(ptr) = p { + let ee = eqtb.decode(ptr); + assert!(ee.ty == 113); + crate::tokenlist::print_toklist(ee.value, &mem, &cshash, &strings, true); + } + + // ok really all done + + let fmt = Format { + engine, + strings, + mem, + eqtb, + cshash, + }; + Ok((input, fmt)) +} diff --git a/crates/xetex_format/src/gluepars.rs b/crates/xetex_format/src/gluepars.rs new file mode 100644 index 000000000..d6eaadff3 --- /dev/null +++ b/crates/xetex_format/src/gluepars.rs @@ -0,0 +1,187 @@ +// Copyright 2021 the Tectonic Project +// Licensed under the MIT License. + +#![deny(missing_docs)] + +//! Glue parameters defined by the engine. + +use std::io::{Result, Write}; + +use super::FormatVersion; + +/// Different kinds of glue parameters. +#[derive(Clone, Copy, Debug, Eq, PartialEq)] +pub enum GlueParKind { + /// A regular glue parameter. + Regular, + + /// A math glue parameter. + Math, +} + +/// Information about glue parameters. +#[derive(Clone, Copy, Debug)] +pub struct GluePar { + /// The name of the parameter. + name: &'static str, + + /// The kind of the parameter. + kind: GlueParKind, + + /// The first format version in which the parameter was introduced. + since: FormatVersion, +} + +const GLUE_PARS: &[GluePar] = &[ + GluePar { + name: "line_skip", + kind: GlueParKind::Regular, + since: 0, + }, + GluePar { + name: "baseline_skip", + kind: GlueParKind::Regular, + since: 0, + }, + GluePar { + name: "par_skip", + kind: GlueParKind::Regular, + since: 0, + }, + GluePar { + name: "above_display_skip", + kind: GlueParKind::Regular, + since: 0, + }, + GluePar { + name: "below_display_skip", + kind: GlueParKind::Regular, + since: 0, + }, + GluePar { + name: "above_display_short_skip", + kind: GlueParKind::Regular, + since: 0, + }, + GluePar { + name: "below_display_short_skip", + kind: GlueParKind::Regular, + since: 0, + }, + GluePar { + name: "left_skip", + kind: GlueParKind::Regular, + since: 0, + }, + GluePar { + name: "right_skip", + kind: GlueParKind::Regular, + since: 0, + }, + GluePar { + name: "top_skip", + kind: GlueParKind::Regular, + since: 0, + }, + GluePar { + name: "split_top_skip", + kind: GlueParKind::Regular, + since: 0, + }, + GluePar { + name: "tab_skip", + kind: GlueParKind::Regular, + since: 0, + }, + GluePar { + name: "space_skip", + kind: GlueParKind::Regular, + since: 0, + }, + GluePar { + name: "xspace_skip", + kind: GlueParKind::Regular, + since: 0, + }, + GluePar { + name: "par_fill_skip", + kind: GlueParKind::Regular, + since: 0, + }, + GluePar { + name: "XeTeX_linebreak_skip", + kind: GlueParKind::Regular, + since: 0, + }, + GluePar { + name: "thin_mu_skip", + kind: GlueParKind::Math, + since: 0, + }, + GluePar { + name: "med_mu_skip", + kind: GlueParKind::Math, + since: 0, + }, + GluePar { + name: "thick_mu_skip", + kind: GlueParKind::Math, + since: 0, + }, +]; + +/// Get information about the glue parameters used in the latest engine format. +pub fn get_latest_gluepars() -> &'static [GluePar] { + GLUE_PARS +} + +/// Get information about the glue parameters used in a specific engine format +/// version. +pub fn get_gluepars_for_version(version: FormatVersion) -> Vec { + let mut r = Vec::new(); + + for p in GLUE_PARS { + if version >= p.since { + r.push(*p) + } + } + + r +} + +/// Emit C header information for the glue parameters. +pub fn emit_c_header_stanza(pars: &[GluePar], mut stream: W) -> Result<()> { + writeln!(stream, "/* Glue (\"skip\") parameters */\n")?; + + for (index, par) in pars.iter().enumerate() { + writeln!( + stream, + "#define GLUE_PAR__{} {}", + par.name.to_lowercase(), + index + )?; + } + + writeln!(stream, "#define GLUE_PARS {}\n", pars.len())?; + Ok(()) +} + +/// Emit initializers for gluepar primitives in the C header. +pub fn emit_c_header_primitives(pars: &[GluePar], mut stream: W) -> Result<()> { + for par in pars { + let cmd = match par.kind { + GlueParKind::Regular => "ASSIGN_GLUE", + GlueParKind::Math => "ASSIGN_MU_GLUE", + }; + + writeln!( + stream, + " {{ \"{}\", {}, GLUE_BASE + GLUE_PAR__{}, xf_prim_init_none }}, \\", + par.name.replace("_", ""), + cmd, + par.name.to_lowercase(), + )?; + } + + Ok(()) +} diff --git a/crates/xetex_format/src/intpars.rs b/crates/xetex_format/src/intpars.rs new file mode 100644 index 000000000..598325c36 --- /dev/null +++ b/crates/xetex_format/src/intpars.rs @@ -0,0 +1,523 @@ +// Copyright 2021 the Tectonic Project +// Licensed under the MIT License. + +#![deny(missing_docs)] + +//! Integer parameters defined by the engine. + +use std::io::{Result, Write}; + +use super::FormatVersion; + +/// Information about the primitive associated with an integer parameter +#[derive(Clone, Copy, Debug)] +pub enum IntParPrimitiveKind { + /// No primitive. + None, + + /// Primitive with name base on the parameter in the usual way. + Standard, + + /// Primitive with a different name. + CustomName(&'static str), +} + +/// Information about integer parameters. +#[derive(Clone, Copy, Debug)] +pub struct IntPar { + /// The name of the parameter. + name: &'static str, + + /// The kind of primitive associated with this parameter + primitive_kind: IntParPrimitiveKind, + + /// The first format version in which the parameter was introduced. + since: FormatVersion, +} + +const INT_PARS: &[IntPar] = &[ + IntPar { + name: "pretolerance", + primitive_kind: IntParPrimitiveKind::Standard, + since: 0, + }, + IntPar { + name: "tolerance", + primitive_kind: IntParPrimitiveKind::Standard, + since: 0, + }, + IntPar { + name: "line_penalty", + primitive_kind: IntParPrimitiveKind::Standard, + since: 0, + }, + IntPar { + name: "hyphen_penalty", + primitive_kind: IntParPrimitiveKind::Standard, + since: 0, + }, + IntPar { + name: "ex_hyphen_penalty", + primitive_kind: IntParPrimitiveKind::Standard, + since: 0, + }, + IntPar { + name: "club_penalty", + primitive_kind: IntParPrimitiveKind::Standard, + since: 0, + }, + IntPar { + name: "widow_penalty", + primitive_kind: IntParPrimitiveKind::Standard, + since: 0, + }, + IntPar { + name: "display_widow_penalty", + primitive_kind: IntParPrimitiveKind::Standard, + since: 0, + }, + IntPar { + name: "broken_penalty", + primitive_kind: IntParPrimitiveKind::Standard, + since: 0, + }, + IntPar { + name: "bin_op_penalty", + primitive_kind: IntParPrimitiveKind::Standard, + since: 0, + }, + IntPar { + name: "rel_penalty", + primitive_kind: IntParPrimitiveKind::Standard, + since: 0, + }, + IntPar { + name: "pre_display_penalty", + primitive_kind: IntParPrimitiveKind::Standard, + since: 0, + }, + IntPar { + name: "post_display_penalty", + primitive_kind: IntParPrimitiveKind::Standard, + since: 0, + }, + IntPar { + name: "inter_line_penalty", + primitive_kind: IntParPrimitiveKind::Standard, + since: 0, + }, + IntPar { + name: "double_hyphen_demerits", + primitive_kind: IntParPrimitiveKind::Standard, + since: 0, + }, + IntPar { + name: "final_hyphen_demerits", + primitive_kind: IntParPrimitiveKind::Standard, + since: 0, + }, + IntPar { + name: "adj_demerits", + primitive_kind: IntParPrimitiveKind::Standard, + since: 0, + }, + IntPar { + name: "mag", + primitive_kind: IntParPrimitiveKind::Standard, + since: 0, + }, + IntPar { + name: "delimiter_factor", + primitive_kind: IntParPrimitiveKind::Standard, + since: 0, + }, + IntPar { + name: "looseness", + primitive_kind: IntParPrimitiveKind::Standard, + since: 0, + }, + IntPar { + name: "time", + primitive_kind: IntParPrimitiveKind::Standard, + since: 0, + }, + IntPar { + name: "day", + primitive_kind: IntParPrimitiveKind::Standard, + since: 0, + }, + IntPar { + name: "month", + primitive_kind: IntParPrimitiveKind::Standard, + since: 0, + }, + IntPar { + name: "year", + primitive_kind: IntParPrimitiveKind::Standard, + since: 0, + }, + IntPar { + name: "show_box_breadth", + primitive_kind: IntParPrimitiveKind::Standard, + since: 0, + }, + IntPar { + name: "show_box_depth", + primitive_kind: IntParPrimitiveKind::Standard, + since: 0, + }, + IntPar { + name: "hbadness", + primitive_kind: IntParPrimitiveKind::Standard, + since: 0, + }, + IntPar { + name: "vbadness", + primitive_kind: IntParPrimitiveKind::Standard, + since: 0, + }, + IntPar { + name: "pausing", + primitive_kind: IntParPrimitiveKind::Standard, + since: 0, + }, + IntPar { + name: "tracing_online", + primitive_kind: IntParPrimitiveKind::Standard, + since: 0, + }, + IntPar { + name: "tracing_macros", + primitive_kind: IntParPrimitiveKind::Standard, + since: 0, + }, + IntPar { + name: "tracing_stats", + primitive_kind: IntParPrimitiveKind::Standard, + since: 0, + }, + IntPar { + name: "tracing_paragraphs", + primitive_kind: IntParPrimitiveKind::Standard, + since: 0, + }, + IntPar { + name: "tracing_pages", + primitive_kind: IntParPrimitiveKind::Standard, + since: 0, + }, + IntPar { + name: "tracing_output", + primitive_kind: IntParPrimitiveKind::Standard, + since: 0, + }, + IntPar { + name: "tracing_lost_chars", + primitive_kind: IntParPrimitiveKind::Standard, + since: 0, + }, + IntPar { + name: "tracing_commands", + primitive_kind: IntParPrimitiveKind::Standard, + since: 0, + }, + IntPar { + name: "tracing_restores", + primitive_kind: IntParPrimitiveKind::Standard, + since: 0, + }, + IntPar { + name: "uc_hyph", + primitive_kind: IntParPrimitiveKind::Standard, + since: 0, + }, + IntPar { + name: "output_penalty", + primitive_kind: IntParPrimitiveKind::Standard, + since: 0, + }, + IntPar { + name: "max_dead_cycles", + primitive_kind: IntParPrimitiveKind::Standard, + since: 0, + }, + IntPar { + name: "hang_after", + primitive_kind: IntParPrimitiveKind::Standard, + since: 0, + }, + IntPar { + name: "floating_penalty", + primitive_kind: IntParPrimitiveKind::Standard, + since: 0, + }, + IntPar { + name: "global_defs", + primitive_kind: IntParPrimitiveKind::Standard, + since: 0, + }, + IntPar { + name: "cur_fam", + primitive_kind: IntParPrimitiveKind::CustomName("fam"), + since: 0, + }, + IntPar { + name: "escape_char", + primitive_kind: IntParPrimitiveKind::Standard, + since: 0, + }, + IntPar { + name: "default_hyphen_char", + primitive_kind: IntParPrimitiveKind::Standard, + since: 0, + }, + IntPar { + name: "default_skew_char", + primitive_kind: IntParPrimitiveKind::Standard, + since: 0, + }, + IntPar { + name: "end_line_char", + primitive_kind: IntParPrimitiveKind::Standard, + since: 0, + }, + IntPar { + name: "new_line_char", + primitive_kind: IntParPrimitiveKind::Standard, + since: 0, + }, + IntPar { + name: "language", + primitive_kind: IntParPrimitiveKind::Standard, + since: 0, + }, + IntPar { + name: "left_hyphen_min", + primitive_kind: IntParPrimitiveKind::Standard, + since: 0, + }, + IntPar { + name: "right_hyphen_min", + primitive_kind: IntParPrimitiveKind::Standard, + since: 0, + }, + IntPar { + name: "holding_inserts", + primitive_kind: IntParPrimitiveKind::Standard, + since: 0, + }, + IntPar { + name: "error_context_lines", + primitive_kind: IntParPrimitiveKind::Standard, + since: 0, + }, + IntPar { + name: "char_sub_def_min", + primitive_kind: IntParPrimitiveKind::None, + since: 0, + }, + IntPar { + name: "char_sub_def_max", + primitive_kind: IntParPrimitiveKind::None, + since: 0, + }, + IntPar { + name: "tracing_char_sub_def", + primitive_kind: IntParPrimitiveKind::None, + since: 0, + }, + IntPar { + name: "tracing_assigns", + primitive_kind: IntParPrimitiveKind::Standard, + since: 0, + }, + IntPar { + name: "tracing_groups", + primitive_kind: IntParPrimitiveKind::Standard, + since: 0, + }, + IntPar { + name: "tracing_ifs", + primitive_kind: IntParPrimitiveKind::Standard, + since: 0, + }, + IntPar { + name: "tracing_scan_tokens", + primitive_kind: IntParPrimitiveKind::Standard, + since: 0, + }, + IntPar { + name: "tracing_nesting", + primitive_kind: IntParPrimitiveKind::Standard, + since: 0, + }, + IntPar { + name: "pre_display_direction", + primitive_kind: IntParPrimitiveKind::Standard, + since: 0, + }, + IntPar { + name: "last_line_fit", + primitive_kind: IntParPrimitiveKind::Standard, + since: 0, + }, + IntPar { + name: "saving_vdiscards", + primitive_kind: IntParPrimitiveKind::Standard, + since: 0, + }, + IntPar { + name: "saving_hyph_codes", + primitive_kind: IntParPrimitiveKind::Standard, + since: 0, + }, + IntPar { + name: "suppress_fontnotfound_error", + primitive_kind: IntParPrimitiveKind::Standard, + since: 0, + }, + IntPar { + name: "xetex_linebreak_locale", + primitive_kind: IntParPrimitiveKind::None, + since: 0, + }, + IntPar { + name: "XeTeX_linebreak_penalty", + primitive_kind: IntParPrimitiveKind::Standard, + since: 0, + }, + IntPar { + name: "XeTeX_protrude_chars", + primitive_kind: IntParPrimitiveKind::Standard, + since: 0, + }, + IntPar { + name: "texxet", + primitive_kind: IntParPrimitiveKind::CustomName("TeXXeTstate"), + since: 0, + }, + IntPar { + name: "xetex_dash_break", + primitive_kind: IntParPrimitiveKind::CustomName("XeTeXdashbreakstate"), + since: 0, + }, + IntPar { + name: "XeTeX_upwards", + primitive_kind: IntParPrimitiveKind::CustomName("XeTeXupwardsmode"), + since: 0, + }, + IntPar { + name: "XeTeX_use_glyph_metrics", + primitive_kind: IntParPrimitiveKind::Standard, + since: 0, + }, + IntPar { + name: "XeTeX_inter_char_tokens", + primitive_kind: IntParPrimitiveKind::CustomName("XeTeXinterchartokenstate"), + since: 0, + }, + IntPar { + name: "XeTeX_input_normalization", + primitive_kind: IntParPrimitiveKind::Standard, + since: 0, + }, + IntPar { + name: "XeTeX_default_input_mode", + primitive_kind: IntParPrimitiveKind::None, + since: 0, + }, + IntPar { + name: "XeTeX_default_input_encoding", + primitive_kind: IntParPrimitiveKind::None, + since: 0, + }, + IntPar { + name: "XeTeX_tracing_fonts", + primitive_kind: IntParPrimitiveKind::Standard, + since: 0, + }, + IntPar { + name: "XeTeX_interword_space_shaping", + primitive_kind: IntParPrimitiveKind::Standard, + since: 0, + }, + IntPar { + name: "XeTeX_generate_actual_text", + primitive_kind: IntParPrimitiveKind::Standard, + since: 0, + }, + IntPar { + name: "XeTeX_hyphenatable_length", + primitive_kind: IntParPrimitiveKind::Standard, + since: 0, + }, + IntPar { + name: "synctex", + primitive_kind: IntParPrimitiveKind::Standard, + since: 0, + }, + IntPar { + name: "pdfoutput", + primitive_kind: IntParPrimitiveKind::Standard, + since: 0, + }, +]; + +/// Get information about the integer parameters used in the latest engine +/// format. +pub fn get_latest_intpars() -> &'static [IntPar] { + INT_PARS +} + +/// Get information about the integer parameters used in a specific engine +/// format version. +pub fn get_intpars_for_version(version: FormatVersion) -> Vec { + let mut r = Vec::new(); + + for p in INT_PARS { + if version >= p.since { + r.push(*p) + } + } + + r +} + +/// Emit C header information for the integer parameters +pub fn emit_c_header_stanza(pars: &[IntPar], mut stream: W) -> Result<()> { + writeln!(stream, "/* Integer parameters */\n")?; + + for (index, par) in pars.iter().enumerate() { + writeln!( + stream, + "#define INT_PAR__{} {}", + par.name.to_lowercase(), + index + )?; + } + + writeln!(stream, "#define INT_PARS {}\n", pars.len())?; + Ok(()) +} + +/// Emit initializers for intpar primitives in the C header. +pub fn emit_c_header_primitives(pars: &[IntPar], mut stream: W) -> Result<()> { + for par in pars { + let (has_prim, prim_name) = match par.primitive_kind { + IntParPrimitiveKind::None => (false, ""), + IntParPrimitiveKind::Standard => (true, par.name), + IntParPrimitiveKind::CustomName(s) => (true, s), + }; + + if has_prim { + writeln!( + stream, + " {{ \"{}\", ASSIGN_INT, INT_BASE + INT_PAR__{}, xf_prim_init_none }}, \\", + prim_name.replace("_", ""), + par.name.to_lowercase(), + )?; + } + } + + Ok(()) +} diff --git a/crates/xetex_format/src/lib.rs b/crates/xetex_format/src/lib.rs new file mode 100644 index 000000000..dbab810a4 --- /dev/null +++ b/crates/xetex_format/src/lib.rs @@ -0,0 +1,64 @@ +// Copyright 2021 the Tectonic Project +// Licensed under the MIT License. + +//! Introspection into the internal data structures of the Tectonic/XeTeX TeX +//! engine, with decoding of "format" files. +//! +//! There are currently two main entrypoints to this crate. To introspect the +//! various internal structures provided by the engine, you can create an +//! [`engine::Engine`] instance. One of its main capabilities is that it can +//! emit a C header defining the various magic constants needed for the engine +//! implementation: +//! +//! ```rust +//! let engine = tectonic_xetex_format::engine::Engine::default(); +//! engine.emit_c_header(std::io::stdout()).unwrap(); +//! ``` +//! +//! You can also parse a TeX "format file" into a [`format::Format`] struct to +//! examine saved engine state. This functionality isn't yet fully implemented, +//! but many of the key pieces are present: +//! +//! ```no_run +//! use std::{io::Read, fs::File}; +//! use tectonic_errors::prelude::*; +//! use tectonic_xetex_format::format::Format; +//! +//! # fn main() -> Result<()> { +//! let mut file = File::open("path-to-format-file.fmt")?; +//! let mut data = Vec::new(); +//! file.read_to_end(&mut data)?; +//! let format = Format::parse(&data[..])?; +//! # Ok(()) +//! # } +//! ``` +//! +//! The intention is to add enough infrastructure so that all saved macros and +//! control strings can be decoded. On Linux systems, Tectonic's auto-generated +//! format files are saved in the `~/.cache/Tectonic/formats/` directory. + +/// A type for format file version numbers. +/// +/// This is `usize`. Version numbers increment monotonically as engine commands +/// and primitives evolve +pub type FormatVersion = usize; + +/// The latest format version number supported by this version of the crate. +pub const LATEST_VERSION: FormatVersion = 30; + +mod parseutils; + +pub mod base; +pub mod commands; +pub mod cshash; +pub mod dimenpars; +pub mod engine; +pub mod eqtb; +pub mod etexpenalties; +pub mod format; +pub mod gluepars; +pub mod intpars; +pub mod locals; +pub mod mem; +pub mod stringtable; +pub mod tokenlist; diff --git a/crates/xetex_format/src/locals.rs b/crates/xetex_format/src/locals.rs new file mode 100644 index 000000000..db7f58ad8 --- /dev/null +++ b/crates/xetex_format/src/locals.rs @@ -0,0 +1,184 @@ +// Copyright 2021 the Tectonic Project +// Licensed under the MIT License. + +#![deny(missing_docs)] + +//! "Local" parameters defined by the engine. +//! +//! These are mostly token lists, but there is also the `parshape` parameter +//! which is handled specially by the `SET_SHAPE` command. In non-vanilla TeX, +//! there are a few more parameters controlled by the `SET_SHAPE` command: +//! "e-TeX penalties" parameters defined in their own section of the eqtb. + +use std::io::{Result, Write}; + +use super::FormatVersion; + +/// Different kinds of "local" parameters. +#[derive(Clone, Copy, Debug, Eq, PartialEq)] +pub enum LocalParKind { + /// A token list. + TokenList, + + /// A "shape" parameter. + Shape, +} + +/// Information about "local" parameters. +#[derive(Clone, Copy, Debug)] +pub struct LocalPar { + /// The name of the parameter. + name: &'static str, + + /// The kind of the parameter. + kind: LocalParKind, + + /// A custom name for the primitive associated with this parameter. + custom_primitive_name: Option<&'static str>, + + /// The first format version in which the parameter was introduced. + since: FormatVersion, +} + +const LOCAL_PARS: &[LocalPar] = &[ + LocalPar { + name: "par_shape", + kind: LocalParKind::Shape, + custom_primitive_name: None, + since: 0, + }, + LocalPar { + name: "output_routine", + kind: LocalParKind::TokenList, + custom_primitive_name: Some("output"), + since: 0, + }, + LocalPar { + name: "every_par", + kind: LocalParKind::TokenList, + custom_primitive_name: None, + since: 0, + }, + LocalPar { + name: "every_math", + kind: LocalParKind::TokenList, + custom_primitive_name: None, + since: 0, + }, + LocalPar { + name: "every_display", + kind: LocalParKind::TokenList, + custom_primitive_name: None, + since: 0, + }, + LocalPar { + name: "every_hbox", + kind: LocalParKind::TokenList, + custom_primitive_name: None, + since: 0, + }, + LocalPar { + name: "every_vbox", + kind: LocalParKind::TokenList, + custom_primitive_name: None, + since: 0, + }, + LocalPar { + name: "every_job", + kind: LocalParKind::TokenList, + custom_primitive_name: None, + since: 0, + }, + LocalPar { + name: "every_cr", + kind: LocalParKind::TokenList, + custom_primitive_name: None, + since: 0, + }, + LocalPar { + name: "err_help", + kind: LocalParKind::TokenList, + custom_primitive_name: None, + since: 0, + }, + LocalPar { + name: "every_eof", + kind: LocalParKind::TokenList, + custom_primitive_name: None, + since: 0, + }, + LocalPar { + name: "XeTeX_inter_char_toks", + kind: LocalParKind::TokenList, + custom_primitive_name: None, + since: 0, + }, + LocalPar { + name: "Tectonic_Coda_Tokens", + kind: LocalParKind::TokenList, + custom_primitive_name: None, + since: 0, + }, +]; + +/// Get information about the local parameters used in the latest +/// engine format. +pub fn get_latest_local_pars() -> &'static [LocalPar] { + LOCAL_PARS +} + +/// Get information about the local parameters used in a specific +/// engine format version. +pub fn get_local_pars_for_version(version: FormatVersion) -> Vec { + let mut r = Vec::new(); + + for p in LOCAL_PARS { + if version >= p.since { + r.push(*p) + } + } + + r +} + +/// Emit C header information for the "locals" parameters. +pub fn emit_c_header_stanza(pars: &[LocalPar], mut stream: W) -> Result<()> { + writeln!(stream, "/* \"Local\" parameters (mostly token lists) */\n")?; + + for (index, par) in pars.iter().enumerate() { + writeln!( + stream, + "#define LOCAL__{} {}", + par.name.to_lowercase(), + index + )?; + } + + writeln!(stream, "#define NUM_LOCALS {}\n", pars.len())?; + Ok(()) +} + +/// Emit initializers for gluepar primitives in the C header. +pub fn emit_c_header_primitives(pars: &[LocalPar], mut stream: W) -> Result<()> { + for par in pars { + let cmd = match par.kind { + LocalParKind::Shape => "SET_SHAPE", + LocalParKind::TokenList => "ASSIGN_TOKS", + }; + + let prim_name = match par.custom_primitive_name { + Some(s) => s, + None => par.name, + }; + + writeln!( + stream, + " {{ \"{}\", {}, LOCAL_BASE + LOCAL__{}, xf_prim_init_none }}, \\", + prim_name.replace("_", ""), + cmd, + par.name.to_lowercase(), + )?; + } + + Ok(()) +} diff --git a/crates/xetex_format/src/mem.rs b/crates/xetex_format/src/mem.rs new file mode 100644 index 000000000..85bd83407 --- /dev/null +++ b/crates/xetex_format/src/mem.rs @@ -0,0 +1,112 @@ +// Copyright 2021 the Tectonic Project +// Licensed under the MIT License. + +//! The TeX dynamic memory array. + +use nom::{ + multi::count, + number::complete::{be_i32, be_u8}, + IResult, +}; + +use crate::{ + base::{self, MIN_HALFWORD, SIZEOF_MEMORY_WORD}, + engine::Engine, + parseutils, +}; + +pub type MemPointer = i32; + +#[derive(Debug)] +pub struct Memory { + pub mem: Vec, + + /// This is needed by the format-file parser for a bounds check. + pub lo_mem_max: MemPointer, +} + +const HI_MEM_STAT_USAGE: i32 = 15; +const N_SERIALIZED_SA_ROOTS: usize = 7; // INT_VAL => INTER_CHAR_VAL, inclusive + +impl Memory { + pub(crate) fn parse<'a>(input: &'a [u8], engine: &Engine) -> IResult<&'a [u8], Self> { + // lower limit hardcoded (?) + let (input, lo_mem_max) = + parseutils::ranged_be_i32(1019, engine.settings.mem_top - HI_MEM_STAT_USAGE)(input)?; + println!("lo_mem_max: {}", lo_mem_max); + + // lower limit hardcoded + let (input, rover) = parseutils::ranged_be_i32(20, lo_mem_max)(input)?; + println!("rover: {}", rover); + + let (input, sa_roots) = count( + parseutils::ranged_be_i32(MIN_HALFWORD, lo_mem_max), + N_SERIALIZED_SA_ROOTS, + )(input)?; + println!("sa_roots: {:?}", sa_roots); + + // Compressed memory loading; + + let mut mem = vec![0; (engine.settings.mem_top as usize + 1) * SIZEOF_MEMORY_WORD]; + let mut input = input; + let mut p = 0; + let mut q = rover; + + loop { + let nb = (q + 2 - p) as usize * SIZEOF_MEMORY_WORD; + + // TODO: read straight into mem? + let (new_input, block) = count(be_u8, nb)(input)?; + input = new_input; + let idx = p as usize * SIZEOF_MEMORY_WORD; + mem[idx..idx + nb].copy_from_slice(&block[..]); + + let ofs = base::memword_read_b32_s0(&mem[..], q); + p = q + ofs; + assert!(p <= lo_mem_max); + + q = base::memword_read_b32_s1(&mem[..], q + 1); + + if q == rover { + break; + } + } + + // Loading the rest of low memory. TODO: straight into `mem`? + let nb = (lo_mem_max + 1 - p as i32) as usize * SIZEOF_MEMORY_WORD; + let (input, block) = count(be_u8, nb)(input)?; + let idx = p as usize * SIZEOF_MEMORY_WORD; + mem[idx..idx + nb].copy_from_slice(&block[..]); + + let (input, hi_mem_min) = parseutils::ranged_be_i32( + lo_mem_max + 1, + engine.settings.mem_top - HI_MEM_STAT_USAGE, + )(input)?; + println!("hi_mem_min: {}", hi_mem_min); + + let (input, avail) = + parseutils::ranged_be_i32(MIN_HALFWORD, engine.settings.mem_top)(input)?; + println!("avail: {}", avail); + + let nb = (engine.settings.mem_top + 1 - hi_mem_min) as usize * SIZEOF_MEMORY_WORD; + let (input, block) = count(be_u8, nb)(input)?; + mem[hi_mem_min as usize * SIZEOF_MEMORY_WORD + ..hi_mem_min as usize * SIZEOF_MEMORY_WORD + nb] + .copy_from_slice(&block[..]); + println!("loaded hi mem"); + + let (input, var_used) = be_i32(input)?; + println!("var_used: {}", var_used); + + let (input, dyn_used) = be_i32(input)?; + println!("dyn_used: {}", dyn_used); + + Ok((input, Memory { mem, lo_mem_max })) + } + + pub fn decode_toklist(&self, index: MemPointer) -> (i32, MemPointer) { + let value = base::memword_read_b32_s0(&self.mem[..], index); + let next = base::memword_read_b32_s1(&self.mem[..], index); + (value, next) + } +} diff --git a/crates/xetex_format/src/parseutils.rs b/crates/xetex_format/src/parseutils.rs new file mode 100644 index 000000000..443323963 --- /dev/null +++ b/crates/xetex_format/src/parseutils.rs @@ -0,0 +1,47 @@ +// Copyright 2021 the Tectonic Project +// Licensed under the MIT License. + +//! Format-file parsing utilities. + +use nom::{ + error::ErrorKind as NomErrorKind, error::ParseError, number::complete::be_i32, Err as NomErr, + IResult, InputIter, InputLength, Slice, +}; +use std::ops::RangeFrom; + +pub fn satisfy_be_i32>( + expected: i32, +) -> impl Fn(I) -> IResult +where + I: Slice> + InputIter + InputLength, +{ + move |i: I| { + let (new_input, value) = be_i32(i)?; + if value != expected { + return Err(NomErr::Error(Error::from_error_kind( + new_input, + NomErrorKind::Satisfy, + ))); + } + Ok((new_input, value)) + } +} + +pub fn ranged_be_i32>( + min: i32, + max: i32, +) -> impl Fn(I) -> IResult +where + I: Slice> + InputIter + InputLength, +{ + move |i: I| { + let (new_input, value) = be_i32(i)?; + if value < min || value > max { + return Err(NomErr::Error(Error::from_error_kind( + new_input, + NomErrorKind::Satisfy, + ))); + } + Ok((new_input, value)) + } +} diff --git a/crates/xetex_format/src/stringtable.rs b/crates/xetex_format/src/stringtable.rs new file mode 100644 index 000000000..818025bd5 --- /dev/null +++ b/crates/xetex_format/src/stringtable.rs @@ -0,0 +1,90 @@ +// Copyright 2021 the Tectonic Project +// Licensed under the MIT License. + +//! Dealing with the TeX string table. + +use nom::{ + multi::count, + number::complete::{be_i32, be_u16}, + Err as NomErr, IResult, +}; + +use crate::parseutils; + +pub type StrPointer = i32; + +#[derive(Debug)] +pub struct StringTable { + pub strings: Vec, +} + +pub(crate) fn len_utf16(s: &str) -> usize { + let mut len = s.len(); + + for c in s.chars() { + if c as u32 > 0xFFFF { + len += 1; + } + } + + len +} + +impl StringTable { + #[allow(clippy::len_without_is_empty)] + pub fn len(&self) -> usize { + self.strings.len() + } + + pub fn lookup(&self, sp: StrPointer) -> &str { + assert!(sp > 0xFFFF); + &self.strings[sp as usize - 0x10000] + } + + pub fn utf16_length(&self, sp: StrPointer) -> usize { + if sp > 0xFFFF { + len_utf16(self.lookup(sp)) + } else if (32..127).contains(&sp) { + 1 + } else if sp <= 127 { + 3 + } else if sp < 256 { + 4 + } else { + 8 + } + } + + pub(crate) fn parse(input: &[u8]) -> IResult<&[u8], StringTable> { + const TOO_BIG_CHAR: i32 = 0x0001_0000; + + let (input, pool_ptr) = be_i32(input)?; + let (input, str_ptr) = be_i32(input)?; + let n_strings = str_ptr - TOO_BIG_CHAR + 1; + + let (input, str_starts) = + count(parseutils::ranged_be_i32(0, pool_ptr), n_strings as usize)(input)?; + + let (input, str_pool) = count(be_u16, pool_ptr as usize)(input)?; + let mut strings = Vec::new(); + + for i in 0..(n_strings as usize) { + let idx0 = str_starts[i] as usize; + let sl = if i == n_strings as usize - 1 { + &str_pool[idx0..] + } else { + &str_pool[idx0..str_starts[i + 1] as usize] + }; + let s = String::from_utf16(sl).map_err(|_| { + use nom::error::ParseError; + NomErr::Error(nom::error::Error::from_error_kind( + input, + nom::error::ErrorKind::Satisfy, + )) + })?; + strings.push(s); + } + + Ok((input, StringTable { strings })) + } +} diff --git a/crates/xetex_format/src/tokenlist.rs b/crates/xetex_format/src/tokenlist.rs new file mode 100644 index 000000000..2253a0ca4 --- /dev/null +++ b/crates/xetex_format/src/tokenlist.rs @@ -0,0 +1,103 @@ +// Copyright 2021 the Tectonic Project +// Licensed under the MIT License. + +//! Handling TeX token lists. +//! +//! Token lists are linked lists of compressed entries that can express either +//! a character or a control sequence. + +use crate::{ + base::TEX_NULL, + commands::CommandCode, + cshash::ControlSeqHash, + eqtb::EqtbPointer, + mem::{MemPointer, Memory}, + stringtable::StringTable, +}; + +#[derive(Copy, Clone, Debug, Eq, PartialEq)] +pub enum Token { + Char { cmd: CommandCode, chr: i32 }, + ControlSeq { ptr: EqtbPointer }, +} + +const CS_TOKEN_FLAG: i32 = 0x1FF_FFFF; + +impl From for Token { + fn from(code: i32) -> Token { + if code > CS_TOKEN_FLAG { + Token::ControlSeq { + ptr: code - CS_TOKEN_FLAG, + } + } else { + let cmd = ((code & 0x1E0_0000) >> 21) as CommandCode; + let chr = code & 0x1F_FFFF; + Token::Char { cmd, chr } + } + } +} + +pub fn print_toklist( + mut p: MemPointer, + mem: &Memory, + cshash: &ControlSeqHash, + strings: &StringTable, + is_macro: bool, +) { + if is_macro { + // Skip the reference count + p = mem.decode_toklist(p).1; + println!("~~ macro template: ~~"); + } + + const CCDESCS: &[&str] = &[ + "ESC", "BGR", "EGR", "MTH", "TAB", "CAR", "MAC", "SUP", "SUB", "IGN", "SPC", "LET", "OTH", + "ACT", "COM", "INV", + ]; + + while p != TEX_NULL { + let (value, next) = mem.decode_toklist(p); + let tok = Token::from(value); + + match tok { + Token::Char { cmd, chr } => match (is_macro, cmd) { + (true, 14) => { + println!("~~ macro expansion: ~~"); + } + + (true, 13) => { + println!(""); + } + + (true, 5) => { + println!("#{}", chr); + } + + _ => { + if let Some(c) = char::from_u32(chr as u32) { + println!("{} {{{}}}", c, CCDESCS[cmd as usize]); + } else { + println!( + "[illegal USV char code 0x{:08x}] {{{}}}", + chr, CCDESCS[cmd as usize] + ); + } + } + }, + + Token::ControlSeq { ptr } => { + if let Some(text) = cshash.stringify(ptr, strings) { + if text == " " { + println!("\\ (slash-space)"); + } else { + println!("\\{}", text); + } + } else { + println!("\\[undecodable token cseq pointer {}]", ptr); + } + } + } + + p = next; + } +} diff --git a/dist/azure-ci-cd.yml b/dist/azure-ci-cd.yml index 2a5e6ab14..29a596753 100644 --- a/dist/azure-ci-cd.yml +++ b/dist/azure-ci-cd.yml @@ -242,7 +242,10 @@ stages: pool: vmImage: ubuntu-20.04 steps: - - bash: rustup component add clippy + - template: azure-generic-build-setup.yml + - bash: | + rustup component add clippy + cargo clippy --version displayName: "Install clippy" # Ew, redundant with stock builds: - bash: | diff --git a/src/driver.rs b/src/driver.rs index 193bc93f4..73dd4ccd2 100644 --- a/src/driver.rs +++ b/src/driver.rs @@ -1677,6 +1677,7 @@ impl ProcessingSession { } /// Use the TeX engine to generate a format file. + #[allow(clippy::manual_split_once)] // requires Rust 1.52 (note that we don't actually define our MSRV) fn make_format_pass(&mut self, status: &mut dyn StatusBackend) -> Result { // PathBuf.file_stem() doesn't do what we want since it only strips // one extension. As of 1.17, the compiler needs a type annotation for diff --git a/src/io/format_cache.rs b/src/io/format_cache.rs index 6af28da9c..e23c231e3 100644 --- a/src/io/format_cache.rs +++ b/src/io/format_cache.rs @@ -40,6 +40,7 @@ impl FormatCache { /// Get an on-disk path name for a given format file. This function simply /// produces a path that may or may not exist. + #[allow(clippy::manual_split_once)] // requires Rust 1.52 (note that we don't actually define our MSRV) fn path_for_format(&mut self, name: &str) -> Result { // Remove all extensions from the format name. PathBuf.file_stem() doesn't // do what we want since it only strips one extension, so here we go: diff --git a/tests/formats.rs b/tests/formats.rs index f3dffa5c7..f19bc1bfc 100644 --- a/tests/formats.rs +++ b/tests/formats.rs @@ -196,6 +196,6 @@ fn plain_format() { test_format_generation( "plain.tex", "plain.fmt", - "7012eeebbbcec81f6ce2c4d232013e306898f211fa252685434a8624ac7323d4", + "28a0e45276759cbb2bbb18f9c48d279ee4cf7762a8c6a0ebf4c2888b4e1767b9", ) }