mirror of
https://github.com/WerWolv/ImHex.git
synced 2026-03-28 15:57:03 -05:00
Compare commits
661 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4d60942fea | ||
|
|
3003dea409 | ||
|
|
0b18930017 | ||
|
|
54ef5785cd | ||
|
|
d084ec78e9 | ||
|
|
a59c17aa83 | ||
|
|
6281adc7c3 | ||
|
|
5cc01ae89d | ||
|
|
303dd28c7c | ||
|
|
dd87dc7046 | ||
|
|
235a64deef | ||
|
|
89a96c6d25 | ||
|
|
4f0e5b99a8 | ||
|
|
f75f3f4661 | ||
|
|
b936a28921 | ||
|
|
d02507ae4b | ||
|
|
0b576adcf8 | ||
|
|
22ff033b5e | ||
|
|
b1edede53a | ||
|
|
3877f0853d | ||
|
|
9af8a0113a | ||
|
|
0d01f0c9d7 | ||
|
|
9911166c24 | ||
|
|
01736d6409 | ||
|
|
4ea8971adf | ||
|
|
8da072b602 | ||
|
|
f6823d5f13 | ||
|
|
941c7ee61d | ||
|
|
fd259dcde3 | ||
|
|
79ecf7fa59 | ||
|
|
4c761df181 | ||
|
|
94dc688324 | ||
|
|
357dd883db | ||
|
|
3bad5e1d9c | ||
|
|
d09982d99f | ||
|
|
fe7eb582a4 | ||
|
|
c76b4bc9e9 | ||
|
|
55d7d7c026 | ||
|
|
6b645192d4 | ||
|
|
d6bb408078 | ||
|
|
434ced44f0 | ||
|
|
c6e1f45dc3 | ||
|
|
c861bf9a5e | ||
|
|
86be1ef1ec | ||
|
|
c4d52da924 | ||
|
|
a142d4fe20 | ||
|
|
197e86f327 | ||
|
|
b1aa58d446 | ||
|
|
60a178f75e | ||
|
|
6799263317 | ||
|
|
9b80486285 | ||
|
|
3254376d28 | ||
|
|
29c1a0cb78 | ||
|
|
800ffb5e56 | ||
|
|
1cf9f7e990 | ||
|
|
d928325fdf | ||
|
|
b3556c7c91 | ||
|
|
4b112321d2 | ||
|
|
fee1b985c0 | ||
|
|
111eabb84c | ||
|
|
f9bb4d828a | ||
|
|
434b7649c3 | ||
|
|
fc44dd4592 | ||
|
|
8ea0e9ce9c | ||
|
|
94cd83e0dc | ||
|
|
27790532f8 | ||
|
|
90d9c91717 | ||
|
|
32ed2c30c0 | ||
|
|
cf9df6e36d | ||
|
|
915106f360 | ||
|
|
a51e4afb05 | ||
|
|
c30f8fa459 | ||
|
|
46221e936f | ||
|
|
c86891e0c3 | ||
|
|
acf6b839e5 | ||
|
|
1f50e834fc | ||
|
|
6322dbf46a | ||
|
|
0e1aeee3fb | ||
|
|
173f279ac8 | ||
|
|
89e0df86a2 | ||
|
|
7ba9349de2 | ||
|
|
15fb288a5b | ||
|
|
f17e04273d | ||
|
|
76d47bf856 | ||
|
|
d4967018c2 | ||
|
|
8e759d9b5f | ||
|
|
a9cebed903 | ||
|
|
58a70f6ad8 | ||
|
|
05c8158716 | ||
|
|
17b0f2ae77 | ||
|
|
b54e6ea531 | ||
|
|
b702ad4190 | ||
|
|
4fb544d59d | ||
|
|
e37a73ae58 | ||
|
|
c5d2739a39 | ||
|
|
def40c908e | ||
|
|
ef12798fe2 | ||
|
|
c747c15567 | ||
|
|
48a57cd981 | ||
|
|
3ddef07284 | ||
|
|
a65f0a5238 | ||
|
|
ca68150970 | ||
|
|
92f0aa9593 | ||
|
|
b368b9c6d1 | ||
|
|
7e17059154 | ||
|
|
e078d810de | ||
|
|
62bf877046 | ||
|
|
1b56c7ffae | ||
|
|
f7e22ce651 | ||
|
|
b9c2b1de5f | ||
|
|
0c302da0db | ||
|
|
45492365be | ||
|
|
b497e9d867 | ||
|
|
2840935f3d | ||
|
|
69c0e6ee6e | ||
|
|
78b07e0a46 | ||
|
|
5a865774d1 | ||
|
|
8d9667c2e0 | ||
|
|
1f6acc101f | ||
|
|
0d91db68db | ||
|
|
825e788646 | ||
|
|
f3815673c0 | ||
|
|
b070092a64 | ||
|
|
25ede7ad18 | ||
|
|
03d216f116 | ||
|
|
b1cab5ccd2 | ||
|
|
04d0458ae7 | ||
|
|
3b5d54dd96 | ||
|
|
87571450f4 | ||
|
|
766fd626f2 | ||
|
|
be1f711fda | ||
|
|
ef3627321c | ||
|
|
dbcb13f473 | ||
|
|
c1359a71d6 | ||
|
|
b1a26d02c1 | ||
|
|
ceae23eab1 | ||
|
|
ab29303c2e | ||
|
|
ed831c6fc9 | ||
|
|
d86be9d9b3 | ||
|
|
c26bed894b | ||
|
|
27cf5953ae | ||
|
|
d0b3a60a09 | ||
|
|
15f2376c62 | ||
|
|
efeeea37f6 | ||
|
|
5726e52df2 | ||
|
|
a1b596adc0 | ||
|
|
763196f0cc | ||
|
|
ff9048fcf0 | ||
|
|
7d9c86f584 | ||
|
|
6129360b06 | ||
|
|
3c5e91b611 | ||
|
|
e529a79ddb | ||
|
|
45bb9e6706 | ||
|
|
e6d14507e2 | ||
|
|
9a5881fc47 | ||
|
|
f7dd28002e | ||
|
|
496b0ec41d | ||
|
|
02df578939 | ||
|
|
eb4a1e2692 | ||
|
|
e6bec7d2b2 | ||
|
|
80f3bbb0af | ||
|
|
3a117b3bed | ||
|
|
ff91335011 | ||
|
|
01917439dd | ||
|
|
f21c80c48a | ||
|
|
3dc42b711c | ||
|
|
4b2863ca14 | ||
|
|
fe1b4b45b5 | ||
|
|
a20d6aa2b2 | ||
|
|
78e52a0fe3 | ||
|
|
b4b507ecc9 | ||
|
|
d7d19d7594 | ||
|
|
90df4413c3 | ||
|
|
4cd6646cca | ||
|
|
87ed0d31d4 | ||
|
|
921bdd9e3b | ||
|
|
1f51a603f0 | ||
|
|
5fbbdb8e3c | ||
|
|
745da6ba45 | ||
|
|
ad71e612a3 | ||
|
|
85823e8e5d | ||
|
|
b4fa8bebe9 | ||
|
|
7859a9bb1f | ||
|
|
696d8d1d54 | ||
|
|
6e8d3e0d7f | ||
|
|
6a0422fb27 | ||
|
|
26898feb62 | ||
|
|
0311feee9b | ||
|
|
cf601586fc | ||
|
|
f7b988906e | ||
|
|
5777a6d401 | ||
|
|
4807ca0057 | ||
|
|
f1aeec309e | ||
|
|
4b8e275254 | ||
|
|
4b6a75fb60 | ||
|
|
d463491026 | ||
|
|
df3d5e38ce | ||
|
|
4e22d636d3 | ||
|
|
e71841b871 | ||
|
|
e272c5d000 | ||
|
|
0d7740773e | ||
|
|
e4fbb1b640 | ||
|
|
986252d97f | ||
|
|
e0c1fc81e3 | ||
|
|
ee94e9d619 | ||
|
|
264da1ed78 | ||
|
|
ce37c795a7 | ||
|
|
ed2297ab7f | ||
|
|
ae5d8c9aad | ||
|
|
603ff9256c | ||
|
|
a966cab155 | ||
|
|
978dd65528 | ||
|
|
6502920047 | ||
|
|
ed97757dde | ||
|
|
da8ec1565e | ||
|
|
ad85a4a0e3 | ||
|
|
f9a7cdf4dd | ||
|
|
a5296bab95 | ||
|
|
bda7a2b351 | ||
|
|
f23351f11c | ||
|
|
e3f2541fde | ||
|
|
94723dbba3 | ||
|
|
6e0b92a4de | ||
|
|
13a61f5249 | ||
|
|
1347f81236 | ||
|
|
ab93894442 | ||
|
|
8ed6c2094b | ||
|
|
42d7f1ca67 | ||
|
|
cf51e04777 | ||
|
|
8398c12f74 | ||
|
|
2a345e770e | ||
|
|
b3fcf71982 | ||
|
|
3b94a42783 | ||
|
|
453ddaf0d6 | ||
|
|
d4ff36fde0 | ||
|
|
6239858d0a | ||
|
|
1dd873462e | ||
|
|
825c613d64 | ||
|
|
4aa314b3ab | ||
|
|
8e696e3fc4 | ||
|
|
217cf799c2 | ||
|
|
b10a59661e | ||
|
|
0f028db856 | ||
|
|
c194588118 | ||
|
|
398dc8101f | ||
|
|
13cb330711 | ||
|
|
c0740822a3 | ||
|
|
340e627af9 | ||
|
|
3089a710bd | ||
|
|
7d0474335a | ||
|
|
3d5190f51a | ||
|
|
de2de1e1d7 | ||
|
|
91a4f52f67 | ||
|
|
c8af25533d | ||
|
|
b1f76aeda6 | ||
|
|
3fccd03bbb | ||
|
|
3bcfa7e10b | ||
|
|
cbd7c10f3d | ||
|
|
0d09c24840 | ||
|
|
d54d371ab7 | ||
|
|
c90aa0a742 | ||
|
|
7f0bdea212 | ||
|
|
b29d184488 | ||
|
|
168d6b2080 | ||
|
|
b2c970c3bd | ||
|
|
a0445c4f7b | ||
|
|
9074a6fcf1 | ||
|
|
4c5d2f6ebb | ||
|
|
23ce2ec271 | ||
|
|
5bbc2fd94c | ||
|
|
901b8f0424 | ||
|
|
d2705988ac | ||
|
|
291da649c1 | ||
|
|
48e9d3b4e9 | ||
|
|
45e2578c5b | ||
|
|
a6742de405 | ||
|
|
948b5b2d9c | ||
|
|
6cb9714f06 | ||
|
|
c35eaa7a4d | ||
|
|
bececff9e5 | ||
|
|
2826e6f325 | ||
|
|
6bc1f94b60 | ||
|
|
9fd37221f6 | ||
|
|
db3072630a | ||
|
|
5cf6baca88 | ||
|
|
582858c0d4 | ||
|
|
7d56c64a9c | ||
|
|
902b35e189 | ||
|
|
5f6050aaec | ||
|
|
cb94213a04 | ||
|
|
fa6580f622 | ||
|
|
07effffa5e | ||
|
|
e15bcb51aa | ||
|
|
a04e2bc8f6 | ||
|
|
6aad609a48 | ||
|
|
24c0cc10a1 | ||
|
|
e567061e3c | ||
|
|
32ab1c1a06 | ||
|
|
e76d5854b8 | ||
|
|
d3b6c2d0e6 | ||
|
|
ef6cac6e92 | ||
|
|
0c5e72ab6a | ||
|
|
f67c9735c5 | ||
|
|
858e1aed3b | ||
|
|
3b7f2fbdaa | ||
|
|
2c167d6d27 | ||
|
|
f53d7fc9f3 | ||
|
|
04a4957ccf | ||
|
|
b5f7be2384 | ||
|
|
33a0ee37fa | ||
|
|
1eb9858f62 | ||
|
|
b829abf56c | ||
|
|
139a379a09 | ||
|
|
6a8611d98d | ||
|
|
241b93aab5 | ||
|
|
6d08a4386d | ||
|
|
37b4d5e7b5 | ||
|
|
f3b0971d00 | ||
|
|
05e8e53451 | ||
|
|
08251eeab7 | ||
|
|
8c96ba1c58 | ||
|
|
e170c45556 | ||
|
|
a537fe90a0 | ||
|
|
802ad96c49 | ||
|
|
5d979da3e2 | ||
|
|
b843d8e98a | ||
|
|
af6ad96cb6 | ||
|
|
f9e960070d | ||
|
|
1ab949b7ef | ||
|
|
8b39c8f219 | ||
|
|
14b28ba899 | ||
|
|
dd9b6643e6 | ||
|
|
e3f88395ec | ||
|
|
72ee1d186e | ||
|
|
ee53eca19f | ||
|
|
7331b8d5ae | ||
|
|
d17911d753 | ||
|
|
b41d01f126 | ||
|
|
27fc3fd659 | ||
|
|
cc9dc90655 | ||
|
|
015266181e | ||
|
|
299933c4f7 | ||
|
|
5312d6f9fa | ||
|
|
16eb7b3dbd | ||
|
|
cb9458dab4 | ||
|
|
e32a85a33f | ||
|
|
e4680fb0a2 | ||
|
|
1c52e0018a | ||
|
|
ee2838bada | ||
|
|
4d17265e90 | ||
|
|
6a6b860622 | ||
|
|
e78c452daf | ||
|
|
86e33a1ee9 | ||
|
|
37850ad85a | ||
|
|
daca49658e | ||
|
|
6975d7e2cd | ||
|
|
5b8bed6083 | ||
|
|
7474aa3e5d | ||
|
|
c6d2d51d4c | ||
|
|
9055105627 | ||
|
|
a44de63e24 | ||
|
|
8fc7931132 | ||
|
|
4070833229 | ||
|
|
3a9c3f939e | ||
|
|
aa42fb5076 | ||
|
|
50158a7977 | ||
|
|
f2ded359d8 | ||
|
|
0e358bbefe | ||
|
|
2cea561468 | ||
|
|
8024b0a186 | ||
|
|
2b135cf7e0 | ||
|
|
ce8c64a679 | ||
|
|
f0da6ec82f | ||
|
|
46e3b9b5d6 | ||
|
|
d5a08ae568 | ||
|
|
11f63f9b02 | ||
|
|
5694eaba8c | ||
|
|
484481f886 | ||
|
|
210106901e | ||
|
|
eb247b8607 | ||
|
|
fb1453d98a | ||
|
|
b734fb5511 | ||
|
|
2cd6cb8814 | ||
|
|
2a93eab14c | ||
|
|
f039ea68d0 | ||
|
|
e0c35e0002 | ||
|
|
5ace199dc4 | ||
|
|
556895744b | ||
|
|
7f2c60b0d7 | ||
|
|
7bb9e7ee82 | ||
|
|
26be4c3ac8 | ||
|
|
b80517ab15 | ||
|
|
b17cd3696c | ||
|
|
accd554600 | ||
|
|
8bf586cfa9 | ||
|
|
ebea409e6a | ||
|
|
6fdba3d555 | ||
|
|
e865883611 | ||
|
|
9c484e7b57 | ||
|
|
b365e16cc9 | ||
|
|
6a07a2f85d | ||
|
|
0fd7461266 | ||
|
|
62eb0ccd1d | ||
|
|
3367237da3 | ||
|
|
3504987ab3 | ||
|
|
554e625bda | ||
|
|
84530e0817 | ||
|
|
663fb88367 | ||
|
|
4d99c4b59d | ||
|
|
12ee235380 | ||
|
|
e30ed35d69 | ||
|
|
e2f8c7d989 | ||
|
|
ca6a8a7a46 | ||
|
|
f52dae4297 | ||
|
|
d643f8f8f7 | ||
|
|
08a12dd2b0 | ||
|
|
b33dd5d4f5 | ||
|
|
e797ac3a57 | ||
|
|
8bd31f6375 | ||
|
|
d3f83e63c9 | ||
|
|
b450f4797e | ||
|
|
0552084673 | ||
|
|
d021e2b362 | ||
|
|
c769e9cc32 | ||
|
|
639390115b | ||
|
|
ceaf80a186 | ||
|
|
86274b8b94 | ||
|
|
669427eb24 | ||
|
|
5ba22e7554 | ||
|
|
65ad88eed9 | ||
|
|
e34703ea5a | ||
|
|
55bd2c6da6 | ||
|
|
96b5221c1d | ||
|
|
3a94be9abb | ||
|
|
9656b40d53 | ||
|
|
7e61b513f3 | ||
|
|
1d4cbbe418 | ||
|
|
e0e2996e25 | ||
|
|
a102f5fcbf | ||
|
|
4e5d56e2c0 | ||
|
|
a55177edfa | ||
|
|
4c01a749de | ||
|
|
7b61268f22 | ||
|
|
b11dbe4fe1 | ||
|
|
6dbff81f95 | ||
|
|
9893e7a965 | ||
|
|
814c595c12 | ||
|
|
f8b4d04713 | ||
|
|
3cdc8c5884 | ||
|
|
5eabc05396 | ||
|
|
b2932773b9 | ||
|
|
59a04e6dbf | ||
|
|
ddf1e8a179 | ||
|
|
17cc87d633 | ||
|
|
fd7beb642f | ||
|
|
b766cf0807 | ||
|
|
6c9469961b | ||
|
|
d8844236d0 | ||
|
|
60eb59c605 | ||
|
|
6a7bbb8752 | ||
|
|
e4431749e1 | ||
|
|
c587b357eb | ||
|
|
7357c26d54 | ||
|
|
73ca45ad3d | ||
|
|
bf00503d1f | ||
|
|
44a90f5c7d | ||
|
|
5c3ee9f499 | ||
|
|
03f357efd1 | ||
|
|
5462575f5c | ||
|
|
120e2bc300 | ||
|
|
c3137df83c | ||
|
|
737155a226 | ||
|
|
66d64cf020 | ||
|
|
42f5c0f484 | ||
|
|
75047e26e2 | ||
|
|
9fa6d82775 | ||
|
|
d1468984e7 | ||
|
|
20a2331504 | ||
|
|
5b00c8ee08 | ||
|
|
bda4aadc54 | ||
|
|
9d7e2eccac | ||
|
|
8c219b981c | ||
|
|
7d87c8bb98 | ||
|
|
13afd96806 | ||
|
|
4fb74a1769 | ||
|
|
aa658b7dbc | ||
|
|
7e3601989a | ||
|
|
3a1c0f8d66 | ||
|
|
91160b4311 | ||
|
|
83f4093796 | ||
|
|
f219395b25 | ||
|
|
ae6a7ad8e5 | ||
|
|
d990ee102a | ||
|
|
cfde9939b4 | ||
|
|
a22725bb67 | ||
|
|
7a4040f6ec | ||
|
|
2fbb351314 | ||
|
|
96e85c0685 | ||
|
|
50577c9ea0 | ||
|
|
073323b517 | ||
|
|
37cc8f3aae | ||
|
|
6367152650 | ||
|
|
ffbaef3872 | ||
|
|
a0b2473bf4 | ||
|
|
95a3104a56 | ||
|
|
2d5f77730b | ||
|
|
033a0dfbb9 | ||
|
|
cb682b6e21 | ||
|
|
7312908d4d | ||
|
|
b44f6035b3 | ||
|
|
b6bc8abf83 | ||
|
|
c60c1154b9 | ||
|
|
219afb6244 | ||
|
|
22b6bdb5cf | ||
|
|
d9a47fe815 | ||
|
|
45e987b413 | ||
|
|
a920696d03 | ||
|
|
f72b153fe0 | ||
|
|
d240b4ed49 | ||
|
|
1a21627cdb | ||
|
|
0a115a3c03 | ||
|
|
7ef11f566b | ||
|
|
7f6aa9f9a6 | ||
|
|
4df1496a0f | ||
|
|
b68eb0bb5e | ||
|
|
7c0fb7c4f2 | ||
|
|
ede8048680 | ||
|
|
b10ba8fea0 | ||
|
|
3eb2cca286 | ||
|
|
721ac837e0 | ||
|
|
f6fef35d3d | ||
|
|
0569770239 | ||
|
|
6689b8ebfa | ||
|
|
3cb6c4f775 | ||
|
|
b687eb88f9 | ||
|
|
33a375910a | ||
|
|
a620400e4e | ||
|
|
cc7dc3597b | ||
|
|
60b5842e94 | ||
|
|
2b9c6ec447 | ||
|
|
742a4e53b5 | ||
|
|
0cd10b6b70 | ||
|
|
aabf718e60 | ||
|
|
03116c4ab8 | ||
|
|
38162c0129 | ||
|
|
f62edea450 | ||
|
|
940f1e30c5 | ||
|
|
af32d68c3f | ||
|
|
eb874ac810 | ||
|
|
a79bf4c3ec | ||
|
|
90adacab9f | ||
|
|
e86ca29b8c | ||
|
|
4f1f9a718c | ||
|
|
cc09014e6e | ||
|
|
de98b40c93 | ||
|
|
a6eaa34f6d | ||
|
|
dacb64ae66 | ||
|
|
c0a5e2012f | ||
|
|
389e53a8a0 | ||
|
|
928fbe235a | ||
|
|
7d85a8b6fc | ||
|
|
d004962e3a | ||
|
|
1462a4689d | ||
|
|
93be4c8ed1 | ||
|
|
536c6df438 | ||
|
|
f8a089a61f | ||
|
|
491ee6aa2f | ||
|
|
6a88c7cbaa | ||
|
|
be82ee15b7 | ||
|
|
1ddd3ea2b9 | ||
|
|
a56a8c1d6c | ||
|
|
9c4e314bb6 | ||
|
|
ea26722a18 | ||
|
|
5aee359700 | ||
|
|
5d11fc960e | ||
|
|
707fec0e2a | ||
|
|
55b877d5e0 | ||
|
|
e779285be4 | ||
|
|
cf6ae52889 | ||
|
|
caad705975 | ||
|
|
0c3fc6f858 | ||
|
|
0529155faa | ||
|
|
aa01d58b33 | ||
|
|
0c0caf6942 | ||
|
|
7e01ff451f | ||
|
|
e0e4b0a5a9 | ||
|
|
0e2c1f1355 | ||
|
|
0ed7341f71 | ||
|
|
29e970fd81 | ||
|
|
43ab72dcb8 | ||
|
|
07dc77f13d | ||
|
|
9b2ee998de | ||
|
|
e1c5cd1e86 | ||
|
|
0d0301f4f6 | ||
|
|
29adeae6a3 | ||
|
|
6b62a1963e | ||
|
|
fb2af5593f | ||
|
|
e938b75acd | ||
|
|
03daf0c95b | ||
|
|
189ea1c3c7 | ||
|
|
8448c3367b | ||
|
|
cc29707bb1 | ||
|
|
eff9ecf7cd | ||
|
|
21b22e7667 | ||
|
|
7d5b17d5c9 | ||
|
|
49d47a0eed | ||
|
|
78785ddc3c | ||
|
|
dea6caccf1 | ||
|
|
b917bfca07 | ||
|
|
85f0e04d0e | ||
|
|
440ba3823e | ||
|
|
b580691871 | ||
|
|
72c4f50871 | ||
|
|
7bc2c4a0d4 | ||
|
|
128551e193 | ||
|
|
72f7c72094 | ||
|
|
568b7f5139 | ||
|
|
164cb1285b | ||
|
|
e16be09f9a | ||
|
|
d55c59c796 | ||
|
|
5c13cf9dbf | ||
|
|
19a0dc80db | ||
|
|
683018a9d2 | ||
|
|
4c331341e5 | ||
|
|
ceb26add15 | ||
|
|
4b720ee3a2 | ||
|
|
d4af07ed51 | ||
|
|
a3132b7d13 | ||
|
|
0192c791ce | ||
|
|
f1ec2ef0c4 | ||
|
|
b1e93fda4b | ||
|
|
f349aafc37 | ||
|
|
8ebbe6fb4e | ||
|
|
e38b6ecd2c | ||
|
|
966f3b8597 | ||
|
|
f0756bceb8 | ||
|
|
423e23e3c0 | ||
|
|
2c740cab06 | ||
|
|
519a9edb60 | ||
|
|
e16216b39e | ||
|
|
f221d0f430 | ||
|
|
1aa497cb7b | ||
|
|
738a537723 | ||
|
|
d8d3a315a4 | ||
|
|
f62ca307b0 | ||
|
|
edfac4ef60 | ||
|
|
916962cf83 | ||
|
|
189766ceb4 | ||
|
|
2200e11e85 | ||
|
|
69d000488e | ||
|
|
88f8bb9848 | ||
|
|
4f37345324 | ||
|
|
31fcf86008 | ||
|
|
7d93c54444 | ||
|
|
b2b753c2b3 | ||
|
|
a97f853110 | ||
|
|
3dc5f0e2be | ||
|
|
d7accb6916 | ||
|
|
9c01f3efe3 | ||
|
|
49cc85dd3b | ||
|
|
974b9c77e0 |
178
.clang-format
178
.clang-format
@@ -1,178 +0,0 @@
|
||||
---
|
||||
Language: Cpp
|
||||
# BasedOnStyle: LLVM
|
||||
AccessModifierOffset: -4
|
||||
AlignAfterOpenBracket: false
|
||||
AlignArrayOfStructures: Left
|
||||
AlignConsecutiveMacros: Consecutive
|
||||
AlignConsecutiveAssignments: Consecutive
|
||||
AlignConsecutiveBitFields: AcrossEmptyLinesAndComments
|
||||
AlignConsecutiveDeclarations: None
|
||||
AlignEscapedNewlines: Left
|
||||
AlignOperands: Align
|
||||
AlignTrailingComments: true
|
||||
AllowAllArgumentsOnNextLine: true
|
||||
AllowAllConstructorInitializersOnNextLine: true
|
||||
AllowAllParametersOfDeclarationOnNextLine: false
|
||||
AllowShortEnumsOnASingleLine: false
|
||||
AllowShortBlocksOnASingleLine: Always
|
||||
AllowShortCaseLabelsOnASingleLine: false
|
||||
AllowShortFunctionsOnASingleLine: All
|
||||
AllowShortLambdasOnASingleLine: All
|
||||
AllowShortIfStatementsOnASingleLine: AllIfsAndElse
|
||||
AllowShortLoopsOnASingleLine: true
|
||||
AlwaysBreakAfterDefinitionReturnType: None
|
||||
AlwaysBreakAfterReturnType: None
|
||||
AlwaysBreakBeforeMultilineStrings: false
|
||||
AlwaysBreakTemplateDeclarations: Yes
|
||||
AttributeMacros:
|
||||
- __capability
|
||||
BinPackArguments: false
|
||||
BinPackParameters: false
|
||||
BraceWrapping:
|
||||
AfterCaseLabel: false
|
||||
AfterClass: false
|
||||
AfterControlStatement: Never
|
||||
AfterEnum: false
|
||||
AfterFunction: false
|
||||
AfterNamespace: false
|
||||
AfterObjCDeclaration: false
|
||||
AfterStruct: false
|
||||
AfterUnion: false
|
||||
AfterExternBlock: false
|
||||
BeforeCatch: false
|
||||
BeforeElse: false
|
||||
BeforeLambdaBody: false
|
||||
BeforeWhile: false
|
||||
IndentBraces: false
|
||||
SplitEmptyFunction: false
|
||||
SplitEmptyRecord: false
|
||||
SplitEmptyNamespace: false
|
||||
BreakBeforeBinaryOperators: None
|
||||
BreakBeforeConceptDeclarations: false
|
||||
BreakBeforeBraces: Attach
|
||||
BreakBeforeInheritanceComma: false
|
||||
BreakInheritanceList: AfterComma
|
||||
BreakBeforeTernaryOperators: true
|
||||
BreakConstructorInitializersBeforeComma: false
|
||||
BreakConstructorInitializers: BeforeColon
|
||||
BreakAfterJavaFieldAnnotations: false
|
||||
BreakStringLiterals: false
|
||||
ColumnLimit: 0
|
||||
CommentPragmas: '^ IWYU pragma:'
|
||||
CompactNamespaces: false
|
||||
ConstructorInitializerAllOnOneLineOrOnePerLine: false
|
||||
ConstructorInitializerIndentWidth: 4
|
||||
ContinuationIndentWidth: 4
|
||||
Cpp11BracedListStyle: false
|
||||
DeriveLineEnding: true
|
||||
DerivePointerAlignment: false
|
||||
DisableFormat: false
|
||||
EmptyLineAfterAccessModifier: Never
|
||||
EmptyLineBeforeAccessModifier: LogicalBlock
|
||||
ExperimentalAutoDetectBinPacking: true
|
||||
FixNamespaceComments: false
|
||||
ForEachMacros:
|
||||
- foreach
|
||||
- Q_FOREACH
|
||||
- BOOST_FOREACH
|
||||
IfMacros:
|
||||
- KJ_IF_MAYBE
|
||||
IncludeBlocks: Regroup
|
||||
IncludeCategories:
|
||||
- Regex: '^"(llvm|llvm-c|clang|clang-c)/'
|
||||
Priority: 2
|
||||
SortPriority: 0
|
||||
CaseSensitive: false
|
||||
- Regex: '^(<|"(gtest|gmock|isl|json)/)'
|
||||
Priority: 3
|
||||
SortPriority: 0
|
||||
CaseSensitive: false
|
||||
- Regex: '.*'
|
||||
Priority: 1
|
||||
SortPriority: 0
|
||||
CaseSensitive: false
|
||||
IncludeIsMainRegex: '(Test)?$'
|
||||
IncludeIsMainSourceRegex: ''
|
||||
IndentAccessModifiers: false
|
||||
IndentCaseLabels: true
|
||||
IndentCaseBlocks: true
|
||||
IndentGotoLabels: true
|
||||
IndentPPDirectives: BeforeHash
|
||||
IndentExternBlock: Indent
|
||||
IndentRequires: false
|
||||
IndentWidth: 4
|
||||
IndentWrappedFunctionNames: false
|
||||
InsertTrailingCommas: None
|
||||
JavaScriptQuotes: Leave
|
||||
JavaScriptWrapImports: true
|
||||
KeepEmptyLinesAtTheStartOfBlocks: true
|
||||
LambdaBodyIndentation: Signature
|
||||
MacroBlockBegin: ''
|
||||
MacroBlockEnd: ''
|
||||
MaxEmptyLinesToKeep: 2
|
||||
NamespaceIndentation: All
|
||||
ObjCBinPackProtocolList: Auto
|
||||
ObjCBlockIndentWidth: 4
|
||||
ObjCBreakBeforeNestedBlockParam: true
|
||||
ObjCSpaceAfterProperty: false
|
||||
ObjCSpaceBeforeProtocolList: true
|
||||
PenaltyBreakAssignment: 2
|
||||
PenaltyBreakBeforeFirstCallParameter: 19
|
||||
PenaltyBreakComment: 300
|
||||
PenaltyBreakFirstLessLess: 120
|
||||
PenaltyBreakString: 1000
|
||||
PenaltyBreakTemplateDeclaration: 10
|
||||
PenaltyExcessCharacter: 1000000
|
||||
PenaltyReturnTypeOnItsOwnLine: 60
|
||||
PenaltyIndentedWhitespace: 0
|
||||
PointerAlignment: Right
|
||||
PPIndentWidth: 4
|
||||
ReferenceAlignment: Pointer
|
||||
ReflowComments: true
|
||||
ShortNamespaceLines: 5
|
||||
SortIncludes: Never
|
||||
SortJavaStaticImport: Before
|
||||
SortUsingDeclarations: true
|
||||
SpaceAfterCStyleCast: false
|
||||
SpaceAfterLogicalNot: false
|
||||
SpaceAfterTemplateKeyword: false
|
||||
SpaceBeforeAssignmentOperators: true
|
||||
SpaceBeforeCaseColon: false
|
||||
SpaceBeforeCpp11BracedList: true
|
||||
SpaceBeforeCtorInitializerColon: true
|
||||
SpaceBeforeInheritanceColon: true
|
||||
SpaceBeforeParens: ControlStatements
|
||||
SpaceAroundPointerQualifiers: Default
|
||||
SpaceBeforeRangeBasedForLoopColon: true
|
||||
SpaceInEmptyBlock: true
|
||||
SpaceInEmptyParentheses: false
|
||||
SpacesBeforeTrailingComments: 4
|
||||
SpacesInAngles: Never
|
||||
SpacesInConditionalStatement: false
|
||||
SpacesInContainerLiterals: true
|
||||
SpacesInCStyleCastParentheses: false
|
||||
SpacesInLineCommentPrefix:
|
||||
Minimum: 1
|
||||
Maximum: -1
|
||||
SpacesInParentheses: false
|
||||
SpacesInSquareBrackets: false
|
||||
SpaceBeforeSquareBrackets: false
|
||||
BitFieldColonSpacing: Both
|
||||
Standard: Latest
|
||||
StatementAttributeLikeMacros:
|
||||
- Q_EMIT
|
||||
StatementMacros:
|
||||
- Q_UNUSED
|
||||
- QT_REQUIRE_VERSION
|
||||
TabWidth: 4
|
||||
UseCRLF: false
|
||||
UseTab: Never
|
||||
WhitespaceSensitiveMacros:
|
||||
- STRINGIZE
|
||||
- PP_STRINGIZE
|
||||
- BOOST_PP_STRINGIZE
|
||||
- NS_SWIFT_NAME
|
||||
- CF_SWIFT_NAME
|
||||
...
|
||||
|
||||
4
.gitattributes
vendored
4
.gitattributes
vendored
@@ -1,3 +1 @@
|
||||
lib/external/** linguist-vendored
|
||||
lib/libimhex-rs/imgui-rs/** linguist-vendored
|
||||
lib/libimhex-rs/imgui-sys/** linguist-vendored
|
||||
lib/external/** linguist-vendored
|
||||
10
.github/ISSUE_TEMPLATE/bug_report.yaml
vendored
10
.github/ISSUE_TEMPLATE/bug_report.yaml
vendored
@@ -1,6 +1,7 @@
|
||||
name: Bug Report
|
||||
description: Something doesn't work correctly in ImHex.
|
||||
title: "[Bug] "
|
||||
labels: bug
|
||||
body:
|
||||
- type: dropdown
|
||||
id: os
|
||||
@@ -39,10 +40,17 @@ body:
|
||||
label: ImHex Build Type
|
||||
options:
|
||||
- label: Nightly or built from sources
|
||||
- type: input
|
||||
attributes:
|
||||
label: Installation type
|
||||
description: |
|
||||
How did you install ImHex ? MSI/Portable/DMG/AppImage/Fedora package/etc..
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Additional context?
|
||||
value: |
|
||||
placeholder: |
|
||||
- Additional information about your environment.
|
||||
- If possible and useful, please upload the binary you've been editing when the bug occurred.
|
||||
validations:
|
||||
|
||||
4
.github/ISSUE_TEMPLATE/feature_request.yaml
vendored
4
.github/ISSUE_TEMPLATE/feature_request.yaml
vendored
@@ -1,6 +1,7 @@
|
||||
name: Feature Request
|
||||
description: Something you'd like to see added to ImHex in the future
|
||||
title: "[Feature] "
|
||||
labels: feature request
|
||||
body:
|
||||
- type: textarea
|
||||
attributes:
|
||||
@@ -20,3 +21,6 @@ body:
|
||||
label: Request Type
|
||||
options:
|
||||
- label: I can provide a PoC for this feature or am willing to work on it myself and submit a PR
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Additional context?
|
||||
|
||||
17
.github/workflows/analysis.yml
vendored
17
.github/workflows/analysis.yml
vendored
@@ -25,21 +25,20 @@ jobs:
|
||||
with:
|
||||
languages: 'cpp'
|
||||
|
||||
- name: 📜 Restore ccache
|
||||
uses: actions/cache@v3
|
||||
- name: 📜 Setup ccache
|
||||
uses: hendrikmuhs/ccache-action@v1.2
|
||||
with:
|
||||
path: |
|
||||
~/.cache/ccache
|
||||
key: ${{ runner.os }}-${{ secrets.CACHE_VERSION }}-build-${{ github.run_id }}
|
||||
restore-keys: ${{ runner.os }}-${{ secrets.CACHE_VERSION }}-build
|
||||
|
||||
key: ${{ runner.os }}-analysis-${{ secrets.CACHE_VERSION }}-build-${{ github.run_id }}
|
||||
restore-keys: ${{ runner.os }}-analysis-${{ secrets.CACHE_VERSION }}-build
|
||||
max-size: 50M
|
||||
|
||||
- name: 📜 Restore CMakeCache
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: |
|
||||
build/CMakeCache.txt
|
||||
key: ${{ runner.os }}-${{ secrets.CACHE_VERSION }}-build-${{ hashFiles('**/CMakeLists.txt') }}
|
||||
|
||||
key: ${{ runner.os }}-analysis-${{ secrets.CACHE_VERSION }}-build-${{ hashFiles('**/CMakeLists.txt') }}
|
||||
|
||||
- name: ⬇️ Install dependencies
|
||||
run: |
|
||||
sudo apt update
|
||||
|
||||
474
.github/workflows/build.yml
vendored
474
.github/workflows/build.yml
vendored
@@ -28,21 +28,13 @@ jobs:
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: 📜 Prepare Cache
|
||||
id: prep-ccache
|
||||
shell: bash
|
||||
run: |
|
||||
mkdir -p "${CCACHE_DIR}"
|
||||
echo "::set-output name=dir::$CCACHE_DIR"
|
||||
|
||||
- name: 📜 Restore ccache
|
||||
uses: actions/cache@v3
|
||||
- name: 📜 Setup ccache
|
||||
uses: hendrikmuhs/ccache-action@v1.2
|
||||
id: cache-ccache
|
||||
with:
|
||||
path: |
|
||||
${{ steps.prep-ccache.outputs.dir }}
|
||||
key: ${{ runner.os }}-${{ secrets.CACHE_VERSION }}-build-${{ github.run_id }}
|
||||
restore-keys: ${{ runner.os }}-${{ secrets.CACHE_VERSION }}-build
|
||||
max-size: 50M
|
||||
|
||||
- name: 📜 Restore CMakeCache
|
||||
uses: actions/cache@v3
|
||||
@@ -64,87 +56,137 @@ jobs:
|
||||
glfw:p
|
||||
file:p
|
||||
mbedtls:p
|
||||
python:p
|
||||
freetype:p
|
||||
dlfcn:p
|
||||
libbacktrace:p
|
||||
|
||||
- name: ⬇️ Install dependencies
|
||||
- name: 📜 Set version variable
|
||||
run: |
|
||||
curl --proto '=https' --tlsv1.2 -sSf https://win.rustup.rs > rustup-init.exe
|
||||
./rustup-init.exe -y --default-host=x86_64-pc-windows-gnu --default-toolchain=none
|
||||
rm rustup-init.exe
|
||||
$USERPROFILE/.cargo/bin/rustup.exe target add x86_64-pc-windows-gnu
|
||||
$USERPROFILE/.cargo/bin/rustup.exe default nightly
|
||||
echo "IMHEX_VERSION=`cat VERSION`" >> $GITHUB_ENV
|
||||
|
||||
# Windows cmake build
|
||||
- name: 🛠️ Build
|
||||
run: |
|
||||
mkdir -p build
|
||||
cd build
|
||||
# Get path to mingw python library
|
||||
PYTHON_LIB_NAME=$(pkg-config --libs-only-l python3 | sed 's/^-l//' | sed 's/ //')
|
||||
PYTHON_LIB_PATH=$(cygpath -m $(which lib${PYTHON_LIB_NAME}.dll))
|
||||
|
||||
cmake -G "MinGW Makefiles" \
|
||||
-DCMAKE_BUILD_TYPE=$BUILD_TYPE \
|
||||
-DCMAKE_INSTALL_PREFIX="$PWD/install" \
|
||||
-DCREATE_PACKAGE=ON \
|
||||
-DPython_LIBRARY="$PYTHON_LIB_PATH" \
|
||||
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
|
||||
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
|
||||
-DCMAKE_C_FLAGS="-fuse-ld=lld" \
|
||||
-DCMAKE_CXX_FLAGS="-fuse-ld=lld" \
|
||||
-DRUST_PATH="$USERPROFILE/.cargo/bin/" \
|
||||
-DIMHEX_PATTERNS_PULL_MASTER=ON \
|
||||
..
|
||||
mingw32-make -j4 install
|
||||
cpack
|
||||
touch $PWD/install/PORTABLE
|
||||
mv imhex-*.msi ../imhex-${{env.IMHEX_VERSION}}-Windows-x86_64.msi
|
||||
|
||||
- name: ⬆️ Upload Portable ZIP
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: Windows Portable
|
||||
path: |
|
||||
build/install/*
|
||||
echo "ImHex checks for the existence of this file to determine if it is running in portable mode. You should not delete this file" > $PWD/install/PORTABLE
|
||||
|
||||
- name: ⬆️ Upload Windows Installer
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: Windows Installer
|
||||
name: Windows Installer x86_64
|
||||
path: |
|
||||
build/*.msi
|
||||
imhex-*.msi
|
||||
|
||||
- name: ⬆️ Upload Portable ZIP
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: Windows Portable x86_64
|
||||
path: |
|
||||
build/install/*
|
||||
|
||||
- name: ⬇️ Download Mesa3D for NoGPU version
|
||||
shell: bash
|
||||
run: |
|
||||
echo "NoGPU version Powered by Mesa 3D : https://fdossena.com/?p=mesa%2Findex.frag" > build/install/MESA.md
|
||||
curl https://werwolv.net/downloads/mesa/MesaForWindows-x64-latest.7z -L -o mesa.7z
|
||||
7z e mesa.7z
|
||||
mv opengl32.dll build/install
|
||||
|
||||
- name: ⬆️ Upload NoGPU Portable ZIP
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: Windows Portable NoGPU x86_64
|
||||
path: |
|
||||
build/install/*
|
||||
|
||||
# MacOS build
|
||||
macos:
|
||||
runs-on: macos-11
|
||||
name: 🍎 macOS 11.0
|
||||
steps:
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
- suffix: "-NoGPU"
|
||||
custom_glfw: true
|
||||
- suffix: ""
|
||||
custom_glfw: false
|
||||
|
||||
name: 🍎 macOS 11.0${{matrix.suffix}}
|
||||
|
||||
steps:
|
||||
- name: 🧰 Checkout
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: 📜 Restore ccache
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: |
|
||||
~/Library/Caches/ccache
|
||||
key: ${{ runner.os }}-${{ secrets.CACHE_VERSION }}-build-${{ github.run_id }}
|
||||
restore-keys: ${{ runner.os }}-${{ secrets.CACHE_VERSION }}-build
|
||||
|
||||
|
||||
- name: 📜 Set version variable
|
||||
run: |
|
||||
echo "IMHEX_VERSION=`cat VERSION`" >> $GITHUB_ENV
|
||||
|
||||
- name: 📜 Setup ccache
|
||||
uses: hendrikmuhs/ccache-action@v1.2
|
||||
with:
|
||||
key: ${{ runner.os }}-${{ matrix.suffix }}-${{ secrets.CACHE_VERSION }}-build-${{ github.run_id }}
|
||||
restore-keys: ${{ runner.os }}-${{ matrix.suffix }}-${{ secrets.CACHE_VERSION }}-build
|
||||
max-size: 50M
|
||||
|
||||
- name: 📜 Restore CMakeCache
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: |
|
||||
build/CMakeCache.txt
|
||||
key: ${{ runner.os }}-${{ secrets.CACHE_VERSION }}-build-${{ hashFiles('**/CMakeLists.txt') }}
|
||||
key: ${{ runner.os }}-${{ matrix.suffix }}-${{ secrets.CACHE_VERSION }}-build-${{ hashFiles('**/CMakeLists.txt') }}
|
||||
|
||||
- name: ⬇️ Install dependencies
|
||||
run: |
|
||||
brew bundle --no-lock --file dist/Brewfile
|
||||
rm -rf /usr/local/Cellar/capstone
|
||||
|
||||
- name: ⬇️ Install classic glfw
|
||||
if: ${{! matrix.custom_glfw}}
|
||||
run: |
|
||||
brew install glfw
|
||||
|
||||
- name: 🧰 Checkout glfw
|
||||
if: ${{matrix.custom_glfw}}
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
repository: glfw/glfw
|
||||
path: glfw
|
||||
|
||||
- name: ⬇️ Patch and install custom glfw
|
||||
if: ${{matrix.custom_glfw}}
|
||||
run: |
|
||||
cd glfw
|
||||
git apply ../dist/macOS/0001-glfw-SW.patch
|
||||
|
||||
mkdir build
|
||||
cd build
|
||||
|
||||
cmake \
|
||||
-DBUILD_SHARED_LIBS=ON \
|
||||
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
|
||||
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
|
||||
-DCMAKE_OBJC_COMPILER_LAUNCHER=ccache \
|
||||
-DCMAKE_OBJCXX_COMPILER_LAUNCHER=ccache \
|
||||
..
|
||||
make -j 4 install
|
||||
|
||||
# MacOS cmake build
|
||||
- name: 🛠️ Build
|
||||
@@ -167,13 +209,14 @@ jobs:
|
||||
-DCMAKE_OBJCXX_COMPILER_LAUNCHER=ccache \
|
||||
-DIMHEX_PATTERNS_PULL_MASTER=ON \
|
||||
-DCMAKE_OSX_DEPLOYMENT_TARGET="10.10" \
|
||||
-DCPACK_PACKAGE_FILE_NAME="imhex-${{env.IMHEX_VERSION}}-macOS${{matrix.suffix}}-x86_64" \
|
||||
..
|
||||
make -j4 package
|
||||
|
||||
- name: ⬆️ Upload DMG
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: macOS DMG
|
||||
name: macOS DMG${{matrix.suffix}} x86_64
|
||||
path: build/*.dmg
|
||||
|
||||
# Ubuntu build
|
||||
@@ -187,124 +230,135 @@ jobs:
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: 📜 Restore cache
|
||||
uses: actions/cache@v3
|
||||
- name: 📜 Setup ccache
|
||||
uses: hendrikmuhs/ccache-action@v1.2
|
||||
with:
|
||||
path: |
|
||||
~/.cache/ccache
|
||||
key: ${{ runner.os }}-${{ secrets.CACHE_VERSION }}-build-${{ github.run_id }}
|
||||
restore-keys: ${{ runner.os }}-${{ secrets.CACHE_VERSION }}-build
|
||||
|
||||
- name: 📜 Restore other caches
|
||||
max-size: 50M
|
||||
|
||||
- name: 📜 Restore CMakeCache
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: |
|
||||
build/CMakeCache.txt
|
||||
.flatpak-builder
|
||||
key: ${{ runner.os }}-${{ secrets.CACHE_VERSION }}-build-${{ hashFiles('**/CMakeLists.txt') }}
|
||||
|
||||
|
||||
- name: ⬇️ Install dependencies
|
||||
run: |
|
||||
sudo rm -rf /usr/share/dotnet
|
||||
sudo rm -rf /opt/ghc
|
||||
sudo rm -rf "/usr/local/share/boost"
|
||||
sudo rm -rf "$AGENT_TOOLSDIRECTORY"
|
||||
|
||||
sudo apt update
|
||||
sudo bash dist/get_deps_debian.sh
|
||||
|
||||
sudo apt install -y python3-pip python3-setuptools desktop-file-utils libgdk-pixbuf2.0-dev fuse
|
||||
sudo wget https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-x86_64.AppImage -O /usr/local/bin/appimagetool
|
||||
sudo chmod +x /usr/local/bin/appimagetool
|
||||
sudo pip3 install appimage-builder==1.0.0
|
||||
|
||||
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs > rustup-init.sh
|
||||
sh rustup-init.sh -y --default-toolchain none
|
||||
rm rustup-init.sh
|
||||
$HOME/.cargo/bin/rustup install nightly
|
||||
$HOME/.cargo/bin/rustup target add x86_64-unknown-linux-gnu
|
||||
$HOME/.cargo/bin/rustup default nightly
|
||||
|
||||
# Ubuntu cmake build
|
||||
- name: 🛠️ Build
|
||||
run: |
|
||||
mkdir -p build
|
||||
cd build
|
||||
CC=gcc-12 CXX=g++-12 cmake \
|
||||
-DCMAKE_BUILD_TYPE=$BUILD_TYPE \
|
||||
-DCMAKE_INSTALL_PREFIX="/usr" \
|
||||
-DCMAKE_INSTALL_PREFIX="/usr" \
|
||||
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
|
||||
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
|
||||
-DCMAKE_C_FLAGS="-fuse-ld=lld" \
|
||||
-DCMAKE_CXX_FLAGS="-fuse-ld=lld" \
|
||||
-DRUST_PATH="$HOME/.cargo/bin/" \
|
||||
-DIMHEX_PATTERNS_PULL_MASTER=ON \
|
||||
-DCMAKE_INTERPROCEDURAL_OPTIMIZATION=ON \
|
||||
..
|
||||
make -j 4 install DESTDIR=AppDir
|
||||
make -j 4 install DESTDIR=DebDir
|
||||
|
||||
- name: 📜 Set version variable
|
||||
run: |
|
||||
echo "IMHEX_VERSION=`cat VERSION`" >> $GITHUB_ENV
|
||||
|
||||
#- name: 📦 Bundle Flatpak
|
||||
# run: |
|
||||
# sudo apt install flatpak flatpak-builder
|
||||
# flatpak --user remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo
|
||||
# flatpak --user install -y flathub org.freedesktop.Platform//20.08
|
||||
# flatpak --user install -y flathub org.freedesktop.Sdk//20.08
|
||||
# flatpak-builder --jobs=4 --repo=imhex _flatpak dist/net.werwolv.ImHex.yaml --ccache --keep-build-dirs
|
||||
# flatpak build-bundle imhex imhex.flatpak net.werwolv.ImHex stable
|
||||
|
||||
- name: 📦 Bundle DEB
|
||||
run: |
|
||||
cp -r build/DEBIAN build/AppDir
|
||||
dpkg-deb --build build/AppDir
|
||||
mv build/AppDir.deb imhex-${{env.IMHEX_VERSION}}.deb
|
||||
rm -rf build/AppDir/DEBIAN
|
||||
|
||||
- name: 🛠️ Reconfigure build for AppImage
|
||||
run: |
|
||||
# Reconfigure CMake to include a flag needed for AppImage
|
||||
# Other flags are kept from old configuration
|
||||
|
||||
cd build
|
||||
cmake \
|
||||
-DIMHEX_PLUGINS_IN_SHARE=ON \
|
||||
..
|
||||
|
||||
rm -rf AppDir
|
||||
make -j 4 install DESTDIR=AppDir
|
||||
|
||||
- name: 📦 Bundle AppImage
|
||||
run: |
|
||||
cd build
|
||||
appimage-builder --recipe ../dist/AppImageBuilder.yml
|
||||
mv ImHex-AppImage-x86_64.AppImage ../imhex-${{env.IMHEX_VERSION}}.AppImage
|
||||
cd ..
|
||||
|
||||
#- name: ⬆️ Upload Flatpak
|
||||
# uses: actions/upload-artifact@v3
|
||||
# with:
|
||||
# name: Linux Flatpak
|
||||
# path: |
|
||||
# imhex.flatpak
|
||||
cp -r build/DEBIAN build/DebDir
|
||||
dpkg-deb -Zgzip --build build/DebDir
|
||||
mv build/DebDir.deb imhex-${{env.IMHEX_VERSION}}-Ubuntu-22.04-x86_64.deb
|
||||
|
||||
- name: ⬆️ Upload DEB
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: Linux DEB (Ubuntu 22.04)
|
||||
name: Ubuntu 22.04 DEB x86_64
|
||||
path: '*.deb'
|
||||
|
||||
# AppImage build
|
||||
appimage:
|
||||
runs-on: ubuntu-22.04
|
||||
name: ⬇️ AppImage
|
||||
steps:
|
||||
|
||||
- name: 🧰 Checkout
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: 📜 Setup ccache
|
||||
uses: hendrikmuhs/ccache-action@v1.2
|
||||
with:
|
||||
key: ${{ runner.os }}-appimage-${{ secrets.CACHE_VERSION }}-build-${{ github.run_id }}
|
||||
restore-keys: ${{ runner.os }}-appimage-${{ secrets.CACHE_VERSION }}-build
|
||||
max-size: 50M
|
||||
|
||||
- name: 📜 Restore CMakeCache
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: |
|
||||
build-appimage/CMakeCache.txt
|
||||
key: ${{ runner.os }}-appimage-${{ secrets.CACHE_VERSION }}-build-${{ hashFiles('**/CMakeLists.txt') }}
|
||||
|
||||
- name: ⬇️ Install dependencies
|
||||
run: |
|
||||
sudo apt update
|
||||
sudo bash dist/get_deps_debian.sh
|
||||
|
||||
sudo apt install -y python3-pip python3-setuptools desktop-file-utils libgdk-pixbuf2.0-dev fuse
|
||||
sudo wget https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-x86_64.AppImage -O /usr/local/bin/appimagetool
|
||||
sudo chmod +x /usr/local/bin/appimagetool
|
||||
sudo pip3 install git+https://github.com/iTrooz/appimage-builder@dpkg-package-versions
|
||||
|
||||
- name: 📜 Set version variable
|
||||
run: |
|
||||
echo "IMHEX_VERSION=`cat VERSION`" >> $GITHUB_ENV
|
||||
|
||||
# AppImage cmake build
|
||||
- name: 🛠️ Build
|
||||
run: |
|
||||
mkdir -p build-appimage
|
||||
cd build-appimage
|
||||
CC=gcc-12 CXX=g++-12 cmake \
|
||||
-DCMAKE_BUILD_TYPE=$BUILD_TYPE \
|
||||
-DCMAKE_INSTALL_PREFIX="/usr" \
|
||||
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
|
||||
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
|
||||
-DIMHEX_PATTERNS_PULL_MASTER=ON \
|
||||
-DCMAKE_INTERPROCEDURAL_OPTIMIZATION=ON \
|
||||
-DIMHEX_PLUGINS_IN_SHARE=ON \
|
||||
-DIMHEX_USE_BUNDLED_CA=ON \
|
||||
..
|
||||
make -j 4 install DESTDIR=AppDir
|
||||
|
||||
- name: 📦 Bundle AppImage
|
||||
run: |
|
||||
cd build-appimage
|
||||
export VERSION=${{env.IMHEX_VERSION}}
|
||||
appimage-builder --recipe ../dist/AppImageBuilder.yml
|
||||
|
||||
- name: ⬆️ Upload AppImage
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: Linux AppImage
|
||||
path: '*.AppImage'
|
||||
name: Linux AppImage x86_64
|
||||
path: 'build-appimage/*.AppImage'
|
||||
|
||||
- name: ⬆️ Upload AppImage zsync
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: Linux AppImage zsync x86_64
|
||||
path: 'build-appimage/*.AppImage.zsync'
|
||||
|
||||
# ArchLinux build
|
||||
archlinux-build:
|
||||
name: 🐧 ArchLinux
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
|
||||
container:
|
||||
image: archlinux:base-devel
|
||||
|
||||
@@ -316,7 +370,7 @@ jobs:
|
||||
- name: ⬇️ Install setup dependencies
|
||||
run: |
|
||||
pacman -Syu git ccache --noconfirm
|
||||
|
||||
|
||||
- name: 🧰 Checkout
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
@@ -326,21 +380,20 @@ jobs:
|
||||
run: |
|
||||
dist/get_deps_archlinux.sh --noconfirm
|
||||
|
||||
- name: 📜 Restore ccache
|
||||
uses: actions/cache@v3
|
||||
- name: 📜 Setup ccache
|
||||
uses: hendrikmuhs/ccache-action@v1.2
|
||||
with:
|
||||
path: |
|
||||
~/.cache/ccache
|
||||
key: archlinux-${{ secrets.CACHE_VERSION }}-build-${{ github.run_id }}
|
||||
restore-keys: archlinux-${{ secrets.CACHE_VERSION }}-build
|
||||
|
||||
max-size: 50M
|
||||
|
||||
- name: 📜 Restore CMakeCache
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: |
|
||||
build/CMakeCache.txt
|
||||
key: archlinux-${{ secrets.CACHE_VERSION }}-build-${{ hashFiles('**/CMakeLists.txt') }}
|
||||
|
||||
|
||||
# ArchLinux cmake build
|
||||
- name: 🛠️ Build
|
||||
run: |
|
||||
@@ -351,21 +404,20 @@ jobs:
|
||||
-DCMAKE_INSTALL_PREFIX="/usr" \
|
||||
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
|
||||
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
|
||||
-DCMAKE_C_FLAGS="-fuse-ld=lld" \
|
||||
-DCMAKE_CXX_FLAGS="-fuse-ld=lld" \
|
||||
-DUSE_SYSTEM_CURL=ON \
|
||||
-DUSE_SYSTEM_FMT=ON \
|
||||
-DUSE_SYSTEM_YARA=ON \
|
||||
-DUSE_SYSTEM_NLOHMANN_JSON=ON \
|
||||
-DUSE_SYSTEM_CAPSTONE=OFF \
|
||||
-DIMHEX_PATTERNS_PULL_MASTER=ON \
|
||||
-DCMAKE_INTERPROCEDURAL_OPTIMIZATION=ON \
|
||||
..
|
||||
make -j 4 install DESTDIR=installDir
|
||||
|
||||
- name: 📜 Set version variable
|
||||
run: |
|
||||
echo "IMHEX_VERSION=`cat VERSION`" >> $GITHUB_ENV
|
||||
|
||||
|
||||
- name: ✒️ Prepare PKGBUILD
|
||||
run: |
|
||||
cp dist/Arch/PKGBUILD build
|
||||
@@ -375,100 +427,142 @@ jobs:
|
||||
- name: 📦 Package ArchLinux .pkg.tar.zst
|
||||
run: |
|
||||
cd build
|
||||
|
||||
|
||||
# the name is a small trick to make makepkg recognize it as the source
|
||||
# else, it would try to download the file from the release
|
||||
tar -cvf imhex-${{env.IMHEX_VERSION}}-ArchLinux.pkg.tar.zst -C installDir .
|
||||
|
||||
tar -cvf imhex-${{env.IMHEX_VERSION}}-ArchLinux-x86_64.pkg.tar.zst -C installDir .
|
||||
|
||||
chmod -R 777 .
|
||||
|
||||
|
||||
sudo -u nobody makepkg
|
||||
|
||||
# Replace the old file
|
||||
rm imhex-${{env.IMHEX_VERSION}}-ArchLinux.pkg.tar.zst
|
||||
mv *.pkg.tar.zst imhex-${{env.IMHEX_VERSION}}-ArchLinux.pkg.tar.zst
|
||||
|
||||
rm imhex-${{env.IMHEX_VERSION}}-ArchLinux-x86_64.pkg.tar.zst
|
||||
mv *.pkg.tar.zst imhex-${{env.IMHEX_VERSION}}-ArchLinux-x86_64.pkg.tar.zst
|
||||
|
||||
- name: ⬆️ Upload imhex-archlinux.pkg.tar.zst
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: ArchLinux .pkg.tar.zst
|
||||
name: ArchLinux .pkg.tar.zst x86_64
|
||||
path: |
|
||||
build/imhex-${{env.IMHEX_VERSION}}-ArchLinux.pkg.tar.zst
|
||||
build/imhex-${{env.IMHEX_VERSION}}-ArchLinux-x86_64.pkg.tar.zst
|
||||
|
||||
# Fedora build
|
||||
fedora-build:
|
||||
# RPM distro builds
|
||||
rpm-build:
|
||||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
- docker_image: fedora:latest
|
||||
release: Latest
|
||||
- docker_image: fedora:rawhide
|
||||
release: Rawhide
|
||||
- name: Fedora
|
||||
mock_release: rawhide
|
||||
release_num: rawhide
|
||||
mock_config: fedora-rawhide
|
||||
- name: Fedora
|
||||
mock_release: f37
|
||||
release_num: 37
|
||||
mock_config: fedora-37
|
||||
- name: Fedora
|
||||
mock_release: f36
|
||||
release_num: 36
|
||||
mock_config: fedora-36
|
||||
- name: RHEL-AlmaLinux
|
||||
mock_release: epel9
|
||||
release_num: 9
|
||||
mock_config: "alma+epel-9"
|
||||
|
||||
|
||||
name: 🐧 Fedora ${{ matrix.release }}
|
||||
name: 🐧 ${{ matrix.name }} ${{ matrix.release_num }}
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
|
||||
container:
|
||||
image: "${{ matrix.docker_image }}"
|
||||
image: "fedora:latest"
|
||||
options: --privileged
|
||||
|
||||
steps:
|
||||
- name: ⬇️ Update all packages
|
||||
run: |
|
||||
dnf upgrade -y
|
||||
- name: ⬇️ Install git-core
|
||||
run: dnf install --disablerepo="*" --enablerepo="fedora" git-core -y
|
||||
|
||||
- name: ⬇️ Install setup dependencies
|
||||
run: |
|
||||
dnf install -y \
|
||||
ccache \
|
||||
desktop-file-utils \
|
||||
fmt-devel \
|
||||
git \
|
||||
json-devel \
|
||||
libcurl-devel \
|
||||
llvm-devel \
|
||||
mbedtls-devel \
|
||||
python3-devel \
|
||||
rpm-build \
|
||||
yara-devel
|
||||
|
||||
- name: 🧰 Checkout
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
path: ImHex
|
||||
submodules: recursive
|
||||
|
||||
- name: ⬇️ Install ImHex dependencies
|
||||
run: |
|
||||
dist/get_deps_fedora.sh
|
||||
- name: 📜 Setup DNF Cache
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: /var/cache/dnf
|
||||
key: ${{ matrix.mock_release }}-${{secrets.CACHE_VERSION }}-dnf-${{ github.run_id }}
|
||||
restore-keys: |
|
||||
${{ matrix.mock_release }}-${{secrets.CACHE_VERSION }}-dnf-
|
||||
|
||||
- name: 📜 Restore ccache
|
||||
uses: actions/cache@v3
|
||||
- name: ⬇️ Update all packages and install dependencies
|
||||
run: |
|
||||
dnf upgrade --disablerepo="*" --enablerepo="fedora,updates" -y
|
||||
dnf install --disablerepo="*" --enablerepo="fedora,updates" -y \
|
||||
fedpkg \
|
||||
ccache
|
||||
|
||||
- name: 📜 Setup ccache
|
||||
uses: hendrikmuhs/ccache-action@v1.2.5
|
||||
with:
|
||||
path: |
|
||||
~/.cache/ccache
|
||||
key: fedora-${{ matrix.release }}-${{ secrets.CACHE_VERSION }}-build-${{ github.run_id }}
|
||||
restore-keys: fedora-${{ matrix.release }}-${{ secrets.CACHE_VERSION }}-build
|
||||
|
||||
- name: 📜 Restore CMakeCache
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: |
|
||||
~/rpmbuild/BUILDROOT/CMakeCache.txt
|
||||
key: fedora-${{ matrix.release }}-${{ secrets.CACHE_VERSION }}-build-${{ hashFiles('**/CMakeLists.txt') }}
|
||||
|
||||
key: rpm-${{ matrix.mock_release }}-${{ secrets.CACHE_VERSION }}-build-${{ github.run_id }}
|
||||
restore-keys: rpm-${{ matrix.mock_release }}-${{ secrets.CACHE_VERSION }}-build
|
||||
max-size: 1G
|
||||
|
||||
- name: 📜 Set version variable
|
||||
run: |
|
||||
echo "IMHEX_VERSION=`cat VERSION`" >> $GITHUB_ENV
|
||||
|
||||
echo "IMHEX_VERSION=`cat ImHex/VERSION`" >> $GITHUB_ENV
|
||||
|
||||
- name: 🗜️ Create tarball from sources with dependencies
|
||||
run: tar --exclude-vcs -czf $GITHUB_WORKSPACE/imhex-$IMHEX_VERSION.tar.gz ImHex
|
||||
|
||||
- name: "✒️ Modify spec file: set version, use latest pattern language, enable online build"
|
||||
run: |
|
||||
sed -i \
|
||||
-e 's/Version: [0-9]*\.[0-9]*\.[0-9]*$/Version: ${{env.IMHEX_VERSION}}/g' \
|
||||
-e 's/IMHEX_OFFLINE_BUILD=ON/IMHEX_OFFLINE_BUILD=OFF/g' \
|
||||
-e '/IMHEX_OFFLINE_BUILD=OFF/a -D IMHEX_PATTERNS_PULL_MASTER=ON \\' \
|
||||
-e '/BuildRequires: cmake/a BuildRequires: git-core' \
|
||||
-e '/%files/a %{_datadir}/%{name}/' \
|
||||
$GITHUB_WORKSPACE/ImHex/dist/rpm/imhex.spec
|
||||
|
||||
- name: 📜 Fix ccache on EL9
|
||||
if: matrix.mock_release == 'epel9'
|
||||
run: sed -i '/\. \/opt\/rh\/gcc-toolset-12\/enable/a PATH=/usr/lib64/ccache:$PATH' $GITHUB_WORKSPACE/ImHex/dist/rpm/imhex.spec
|
||||
|
||||
- name: 🟩 Copy spec file to build root
|
||||
run: mv $GITHUB_WORKSPACE/ImHex/dist/rpm/imhex.spec $GITHUB_WORKSPACE/imhex.spec
|
||||
|
||||
- name: 📜 Enable ccache for mock
|
||||
run: |
|
||||
cat <<EOT > $GITHUB_WORKSPACE/mock.cfg
|
||||
include('${{ matrix.mock_config }}-x86_64.cfg')
|
||||
config_opts['plugin_conf']['ccache_enable'] = True
|
||||
config_opts['plugin_conf']['ccache_opts']['max_cache_size'] = '1G'
|
||||
config_opts['plugin_conf']['ccache_opts']['compress'] = True
|
||||
config_opts['plugin_conf']['ccache_opts']['dir'] = "$GITHUB_WORKSPACE/.ccache"
|
||||
EOT
|
||||
|
||||
- name: 📜 Setup Mock Cache
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: /var/cache/mock
|
||||
key: ${{ matrix.mock_release }}-${{secrets.CACHE_VERSION }}-mock-${{ github.run_id }}
|
||||
restore-keys: |
|
||||
${{ matrix.mock_release }}-${{secrets.CACHE_VERSION }}-mock-
|
||||
|
||||
# Fedora cmake build (in imhex.spec)
|
||||
- name: 📦 Build RPM
|
||||
run: |
|
||||
rpmbuild -ba --define "_version ${{env.IMHEX_VERSION}}" --define "_src_path $GITHUB_WORKSPACE" --define "_build_type $BUILD_TYPE" $GITHUB_WORKSPACE/dist/rpm/imhex.spec
|
||||
mv ~/rpmbuild/RPMS/x86_64/*.rpm imhex-${{env.IMHEX_VERSION}}-Fedora-${{matrix.release}}.rpm
|
||||
|
||||
fedpkg --path $GITHUB_WORKSPACE --release ${{ matrix.mock_release }} mockbuild --enable-network -N --root $GITHUB_WORKSPACE/mock.cfg extra_args -- -v
|
||||
|
||||
- name: 🟩 Move and rename finished RPM
|
||||
run: |
|
||||
mv $GITHUB_WORKSPACE/results_imhex/${{env.IMHEX_VERSION}}/*/imhex-${{env.IMHEX_VERSION}}-0.*.x86_64.rpm \
|
||||
$GITHUB_WORKSPACE/imhex-${{env.IMHEX_VERSION}}-${{matrix.name}}-${{matrix.release_num}}-x86_64.rpm
|
||||
|
||||
- name: ⬆️ Upload RPM
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: Fedora ${{ matrix.release }} RPM
|
||||
name: ${{ matrix.name }} ${{ matrix.release_num }} RPM x86_64
|
||||
path: |
|
||||
imhex-${{env.IMHEX_VERSION}}-Fedora-${{matrix.release}}.rpm
|
||||
imhex-${{env.IMHEX_VERSION}}-${{matrix.name}}-${{matrix.release_num}}-x86_64.rpm
|
||||
|
||||
64
.github/workflows/release.yml
vendored
64
.github/workflows/release.yml
vendored
@@ -6,11 +6,12 @@ name: Release
|
||||
on:
|
||||
release:
|
||||
types: [published]
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
release:
|
||||
release-common:
|
||||
runs-on: ubuntu-latest
|
||||
name: Release
|
||||
name: Release Common
|
||||
|
||||
steps:
|
||||
- name: 🧰 Checkout
|
||||
@@ -33,7 +34,7 @@ jobs:
|
||||
|
||||
- name: 🗜️ Create tarball from sources with dependencies
|
||||
run: tar --exclude-vcs -czvf Full.Sources.tar.gz ImHex
|
||||
|
||||
|
||||
- name: ⬇️ Download artifacts from latest workflow
|
||||
uses: dawidd6/action-download-artifact@v2
|
||||
with:
|
||||
@@ -42,7 +43,7 @@ jobs:
|
||||
branch: ${{ github.event.release.target_commitish }}
|
||||
workflow_conclusion: success
|
||||
skip_unpack: true
|
||||
|
||||
|
||||
- name: 🗜️ Unzip files when needed
|
||||
run: |
|
||||
for zipfile in ./*.zip
|
||||
@@ -57,8 +58,10 @@ jobs:
|
||||
fi
|
||||
done
|
||||
|
||||
- name: 🟩 Rename Windows Portable Zip
|
||||
run: mv "Windows Portable.zip" imhex-${{env.IMHEX_VERSION}}-Windows-Portable.zip
|
||||
- name: 🟩 Rename artifacts when needed
|
||||
run: |
|
||||
mv "Windows Portable x86_64.zip" imhex-${{env.IMHEX_VERSION}}-Windows-Portable-x86_64.zip
|
||||
mv "Windows Portable NoGPU x86_64.zip" imhex-${{env.IMHEX_VERSION}}-Windows-Portable-NoGPU-x86_64.zip
|
||||
|
||||
- name: ⬆️ Upload everything to release
|
||||
uses: softprops/action-gh-release@v1
|
||||
@@ -68,14 +71,14 @@ jobs:
|
||||
- name: ✒️ Prepare PKGBUILD
|
||||
run: |
|
||||
cp ImHex/dist/Arch/PKGBUILD .
|
||||
|
||||
hash=`md5sum imhex-${{env.IMHEX_VERSION}}-ArchLinux.pkg.tar.zst | cut -d ' ' -f 1`
|
||||
|
||||
hash=`md5sum imhex-${{env.IMHEX_VERSION}}-ArchLinux.pkg.tar.zst-x86_64 | cut -d ' ' -f 1`
|
||||
|
||||
sed -i 's/%version%/${{env.IMHEX_VERSION}}/g' PKGBUILD
|
||||
sed -i "s/(SKIP)/($hash)/g" PKGBUILD
|
||||
|
||||
- name: ⬆️ Publish AUR package
|
||||
|
||||
|
||||
# I couldn't make the condition in the env directly for some reason
|
||||
env:
|
||||
AUR_SSH_PRIVATE_KEY: ${{ secrets.AUR_SSH_PRIVATE_KEY }}
|
||||
@@ -110,3 +113,46 @@ jobs:
|
||||
tag: ImHex-v${{env.IMHEX_VERSION}}
|
||||
repo: ImHex-Patterns
|
||||
token: ${{ secrets.RELEASE_TOKEN }}
|
||||
|
||||
- name: ✉️ Update C++ Plugin Template
|
||||
uses: peter-evans/repository-dispatch@v2
|
||||
env:
|
||||
RELEASE_TOKEN: ${{ secrets.RELEASE_TOKEN }}
|
||||
if: "${{ env.RELEASE_TOKEN != '' }}"
|
||||
with:
|
||||
token: ${{ secrets.RELEASE_TOKEN }}
|
||||
repository: WerWolv/ImHex-Cpp-Plugin-Template
|
||||
event_type: update_submodule
|
||||
|
||||
- name: ✉️ Update Rust Plugin Template
|
||||
uses: peter-evans/repository-dispatch@v2
|
||||
env:
|
||||
RELEASE_TOKEN: ${{ secrets.RELEASE_TOKEN }}
|
||||
if: "${{ env.RELEASE_TOKEN != '' }}"
|
||||
with:
|
||||
token: ${{ secrets.RELEASE_TOKEN }}
|
||||
repository: WerWolv/ImHex-Rust-Plugin-Template
|
||||
event_type: update_submodule
|
||||
|
||||
release-windows:
|
||||
name: Release Windows
|
||||
needs: release-common
|
||||
runs-on: windows-2022
|
||||
steps:
|
||||
- name: ⬇️ Download dependencies
|
||||
shell: pwsh
|
||||
run: |
|
||||
iwr https://github.com/microsoft/winget-create/releases/download/v1.1.2.0/wingetcreate.exe -OutFile wingetcreate.exe
|
||||
- name: ⬆️ Update winget manifest
|
||||
shell: pwsh
|
||||
env:
|
||||
WINGET_GITHUB_TOKEN: ${{ secrets.RELEASE_TOKEN }}
|
||||
if: "${{ env.WINGET_GITHUB_TOKEN != '' }}"
|
||||
run: |
|
||||
$tagname = $env:GITHUB_REF.Replace("refs/tags/", "")
|
||||
$version = $tagname.Replace("v", "")
|
||||
$url = "https://github.com/WerWolv/ImHex/releases/download/${tagname}/imhex-${version}-Windows-x86_64.msi"
|
||||
.\wingetcreate.exe update WerWolv.ImHex -u $url --version $version
|
||||
if ($version -notmatch "-") {
|
||||
.\wingetcreate.exe submit .\manifests\w\WerWolv\ImHex\${version}\ --token $env:WINGET_GITHUB_TOKEN
|
||||
}
|
||||
|
||||
36
.github/workflows/tests.yml
vendored
36
.github/workflows/tests.yml
vendored
@@ -22,22 +22,21 @@ jobs:
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: 📜 Restore ccache
|
||||
uses: actions/cache@v3
|
||||
- name: 📜 Setup ccache
|
||||
uses: hendrikmuhs/ccache-action@v1.2
|
||||
with:
|
||||
path: |
|
||||
~/.cache/ccache
|
||||
key: ${{ runner.os }}-${{ secrets.CACHE_VERSION }}-build-${{ github.run_id }}
|
||||
restore-keys: ${{ runner.os }}-${{ secrets.CACHE_VERSION }}-build
|
||||
|
||||
key: ${{ runner.os }}-tests-${{ secrets.CACHE_VERSION }}-build-${{ github.run_id }}
|
||||
restore-keys: ${{ runner.os }}-tests-${{ secrets.CACHE_VERSION }}-build
|
||||
max-size: 50M
|
||||
|
||||
|
||||
- name: 📜 Restore CMakeCache
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: |
|
||||
build/CMakeCache.txt
|
||||
key: ${{ runner.os }}-${{ secrets.CACHE_VERSION }}-build-${{ hashFiles('**/CMakeLists.txt') }}
|
||||
|
||||
key: ${{ runner.os }}-tests-${{ secrets.CACHE_VERSION }}-build-${{ hashFiles('**/CMakeLists.txt') }}
|
||||
|
||||
- name: ⬇️ Install dependencies
|
||||
run: |
|
||||
sudo apt update
|
||||
@@ -47,18 +46,17 @@ jobs:
|
||||
run: |
|
||||
mkdir -p build
|
||||
cd build
|
||||
CC=gcc-12 CXX=g++-12 cmake \
|
||||
-DCMAKE_BUILD_TYPE=$BUILD_TYPE \
|
||||
-DCMAKE_INSTALL_PREFIX="$PWD/install" \
|
||||
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
|
||||
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
|
||||
-DCMAKE_C_FLAGS="-fuse-ld=lld" \
|
||||
-DCMAKE_CXX_FLAGS="-fuse-ld=lld" \
|
||||
-DIMHEX_PATTERNS_PULL_MASTER=ON \
|
||||
CC=gcc-12 CXX=g++-12 cmake \
|
||||
-DCMAKE_BUILD_TYPE=Debug \
|
||||
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
|
||||
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
|
||||
-DCMAKE_C_FLAGS="-fuse-ld=lld -fsanitize=address,leak,undefined -fno-sanitize-recover=all" \
|
||||
-DCMAKE_CXX_FLAGS="-fuse-ld=lld -fsanitize=address,leak,undefined -fno-sanitize-recover=all" \
|
||||
-DIMHEX_OFFLINE_BUILD=ON \
|
||||
..
|
||||
make -j4 unit_tests install
|
||||
make -j4 unit_tests
|
||||
|
||||
- name: 🧪 Perform Unit Tests
|
||||
run: |
|
||||
cd build
|
||||
ctest
|
||||
ctest --output-on-failure
|
||||
|
||||
8
.gitignore
vendored
8
.gitignore
vendored
@@ -2,15 +2,9 @@
|
||||
.idea/
|
||||
|
||||
cmake-build-*/
|
||||
|
||||
build-linux/
|
||||
build*/
|
||||
venv/
|
||||
|
||||
*.mgc
|
||||
imgui.ini
|
||||
.DS_Store
|
||||
plugins/.rustc_info.json
|
||||
|
||||
**/target
|
||||
|
||||
plugins/example_rust/Cargo.lock
|
||||
|
||||
8
.idea/.gitignore
generated
vendored
8
.idea/.gitignore
generated
vendored
@@ -1,8 +0,0 @@
|
||||
# Default ignored files
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
# Datasource local storage ignored files
|
||||
/../../../../../:\_Dev\Cpp\HexEditor\.idea/dataSources/
|
||||
/dataSources.local.xml
|
||||
# Editor-based HTTP Client requests
|
||||
/httpRequests/
|
||||
1
.idea/.name
generated
1
.idea/.name
generated
@@ -1 +0,0 @@
|
||||
imhex
|
||||
14
.idea/deployment.xml
generated
14
.idea/deployment.xml
generated
@@ -1,14 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="PublishConfigData" remoteFilesAllowedToDisappearOnAutoupload="false">
|
||||
<serverData>
|
||||
<paths name="WSL (e494f5fa-cb38-49f1-b2cb-b9524b92ed51)">
|
||||
<serverdata>
|
||||
<mappings>
|
||||
<mapping local="$PROJECT_DIR$" web="/" />
|
||||
</mappings>
|
||||
</serverdata>
|
||||
</paths>
|
||||
</serverData>
|
||||
</component>
|
||||
</project>
|
||||
2
.idea/imhex.iml
generated
2
.idea/imhex.iml
generated
@@ -1,2 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module classpath="CMake" type="CPP_MODULE" version="4" />
|
||||
4
.idea/misc.xml
generated
4
.idea/misc.xml
generated
@@ -1,4 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="CMakeWorkspace" PROJECT_DIR="$PROJECT_DIR$" />
|
||||
</project>
|
||||
8
.idea/modules.xml
generated
8
.idea/modules.xml
generated
@@ -1,8 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/imhex.iml" filepath="$PROJECT_DIR$/.idea/imhex.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
||||
15
.idea/vcs.xml
generated
15
.idea/vcs.xml
generated
@@ -1,15 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||
<mapping directory="$PROJECT_DIR$/lib/external/capstone" vcs="Git" />
|
||||
<mapping directory="$PROJECT_DIR$/lib/external/curl" vcs="Git" />
|
||||
<mapping directory="$PROJECT_DIR$/lib/external/fmt" vcs="Git" />
|
||||
<mapping directory="$PROJECT_DIR$/lib/external/libromfs" vcs="Git" />
|
||||
<mapping directory="$PROJECT_DIR$/lib/external/nativefiledialog" vcs="Git" />
|
||||
<mapping directory="$PROJECT_DIR$/lib/external/pattern_language" vcs="Git" />
|
||||
<mapping directory="$PROJECT_DIR$/lib/external/pattern_language/external/fmt" vcs="Git" />
|
||||
<mapping directory="$PROJECT_DIR$/lib/external/xdgpp" vcs="Git" />
|
||||
<mapping directory="$PROJECT_DIR$/lib/external/yara/yara" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
||||
@@ -1,15 +1,18 @@
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
cmake_minimum_required(VERSION 3.20)
|
||||
|
||||
# Options
|
||||
option(IMHEX_USE_BUNDLED_CA "Use the CA bundle in romfs instead of the system one" OFF)
|
||||
option(IMHEX_PLUGINS_IN_SHARE "Put the plugins in share/imhex/plugins instead of lib[..]/imhex/plugins" OFF)
|
||||
option(IMHEX_STRIP_RELEASE "Strip the release builds" ON)
|
||||
option(IMHEX_OFFLINE_BUILD "Enable offline build" OFF)
|
||||
option(IMHEX_IGNORE_BAD_CLONE "Disabled the bad clone prevention checks" OFF)
|
||||
option(IMHEX_IGNORE_BAD_CLONE "Disable the bad clone prevention checks" OFF)
|
||||
option(IMHEX_PATTERNS_PULL_MASTER "Download latest files from master branch of the ImHex-Patterns repo" OFF)
|
||||
option(IMHEX_IGNORE_BAD_COMPILER "Allow compiling with an unsupported compiler" OFF)
|
||||
option(IMHEX_USE_GTK_FILE_PICKER "Use GTK file picker instead of xdg-desktop-portals" OFF)
|
||||
|
||||
# Basic compiler and cmake configurations
|
||||
set(CMAKE_CXX_STANDARD 23)
|
||||
set(CMAKE_INCLUDE_DIRECTORIES_BEFORE ON)
|
||||
set(IMHEX_BASE_FOLDER ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
set(CMAKE_MODULE_PATH "${IMHEX_BASE_FOLDER}/cmake/modules")
|
||||
include("${IMHEX_BASE_FOLDER}/cmake/build_helpers.cmake")
|
||||
@@ -17,7 +20,11 @@ include("${IMHEX_BASE_FOLDER}/cmake/build_helpers.cmake")
|
||||
# Setup project
|
||||
loadVersion(IMHEX_VERSION)
|
||||
setVariableInParent(IMHEX_VERSION ${IMHEX_VERSION})
|
||||
project(imhex VERSION ${IMHEX_VERSION})
|
||||
project(imhex
|
||||
LANGUAGES C CXX VERSION ${IMHEX_VERSION}
|
||||
DESCRIPTION "The ImHex Hex Editor"
|
||||
HOMEPAGE_URL "https://imhex.werwolv.net"
|
||||
)
|
||||
|
||||
# Make sure project is configured correctly
|
||||
setDefaultBuiltTypeIfUnset()
|
||||
@@ -35,11 +42,13 @@ detectOS()
|
||||
detectArch()
|
||||
addVersionDefines()
|
||||
configurePackingResources()
|
||||
setUninstallTarget()
|
||||
addBundledLibraries()
|
||||
|
||||
# Add ImHex sources
|
||||
add_subdirectory(lib/libimhex)
|
||||
add_subdirectory(main)
|
||||
add_custom_target(imhex_all ALL DEPENDS main)
|
||||
add_custom_target(imhex ALL DEPENDS main libimhex)
|
||||
|
||||
# Add unit tests
|
||||
enable_testing()
|
||||
|
||||
67
HACKING.md
Normal file
67
HACKING.md
Normal file
@@ -0,0 +1,67 @@
|
||||
# Hacking guide
|
||||
|
||||
## Introduction
|
||||
|
||||
This document is a guide for developers who want to contribute to ImHex in any way. It contains information about the codebase, the build process and the general workflow.
|
||||
|
||||
## Codebase
|
||||
|
||||
ImHex is written in C++ and usually uses the latest compiler and standard library features available in gcc on all supported OSes. At the time of writing this is C++23.
|
||||
|
||||
### Structure
|
||||
|
||||
- `main`: Contains the main application code
|
||||
- Important to understand here is that the main ImHex application is basically just an empty shell.
|
||||
- All it does is create a Window and a OpenGL context using GLFW, load all available plugins, properly configure ImGui and render it to the screen.
|
||||
- Everything else is done inside of plugins. ImHex comes with a few plugins by default, most notably the `builtin` plugin which contains the majority of the application code.
|
||||
- In most cases, this code doesn't need to be modified. Most features should be self-contained inside a plugin.
|
||||
- `lib`
|
||||
- `libimhex`: Contains all helper utilities as well as various APIs for plugins to interact with ImHex.
|
||||
- The library's main purpose is for Dependency Inversion. The ImHex main application as well as libimhex do not know about the existence of plugins at build time. Plugins and the main application instead link against libimhex and use it as a common API to interact with each other.
|
||||
- Since libimhex is a doesn't know about the existence of plugins, it cannot depend on any of them. This includes localizations and things that get registered by plugins after launch.
|
||||
- Even if the builtin plugin is technically always available, it is still a plugin and should be treated that way.
|
||||
- All important APIs can be found in the `hex/api` include directory and are documented in the respective header file.
|
||||
- `external`: All libraries that need custom patches or aren't typically available in package managers go into here.
|
||||
- If you'd like to add new features to the Pattern language, please make a PR to https://github.com/WerWolv/PatternLanguage instead. ImHex usually depends on the latest commit of the master branch of this repo.
|
||||
- `plugins`
|
||||
- `builtin`: The builtin plugin. Contains the majority of the application code.
|
||||
- It's the heart of ImHex's functionality. It contains most of the default views, providers, etc. so if you want to add new functionality to ImHex, this is the place to start.
|
||||
- `tests`: Contains all unit tests for ImHex. These are run automatically by the CI and should be kept up to date, especially when adding new helper functions to libimhex.
|
||||
|
||||
### RomFS
|
||||
|
||||
ImHex uses a custom library called [libromfs](https://github.com/WerWolv/libromfs). It's a simple static library which uses CMake's code generation feature to embed files into the binary at compile time so they can be accessed at runtime.
|
||||
All plugins have a `romfs` folder which contains all files that should be embedded into the binary. Resources that need to be embedded into the main application (this is usually not necessary), go into the `resources/romfs` folder.
|
||||
When adding, changing files or removing files, make sure to re-run CMake to update the generated code. Otherwise, the changes might not be reflected in the binary.
|
||||
|
||||
## Development Environment
|
||||
|
||||
I personally use CLion for development since it makes configuring and building the project very easy on all platforms.
|
||||
|
||||
### Windows
|
||||
- Install MSYS2 from https://www.msys2.org/ and use the `dist/get_deps_msys2.sh` script to install all dependencies.
|
||||
### Linux
|
||||
- Install all dependencies using one of the `dist/get_deps_*.sh` scripts depending on your distribution or install them manually with your package manager.
|
||||
### macOS
|
||||
- Install all dependencies using brew and the `dist/Brewfile` script.
|
||||
|
||||
## Making Changes
|
||||
|
||||
### Adding new features to ImHex
|
||||
|
||||
If you'd like to add new features, the best way to start is by joining our Discord and telling us about your idea. We can then discuss the best way to implement it and how it should be integrated into ImHex or if it should be done in a separate plugin.
|
||||
|
||||
There are standalone plugin templates that use ImHex as a submodule. You can find them here:
|
||||
- https://github.com/WerWolv/ImHex-Cpp-Plugin-Template
|
||||
- https://github.com/WerWolv/ImHex-Rust-Plugin-Template
|
||||
|
||||
### Adding a new language
|
||||
|
||||
If you'd like to support a new language in ImHex, the best way is by using the `dist/langtool.py` tool. It will create the necessary file for you and help you fill them out.
|
||||
First, run the tool with `python3 dist/langtool.py create plugins/builtin/romfs/lang <iso_code>` where `<iso_code>` is the ISO 639-1 code of your language. This will create a new file in the language directory.
|
||||
Afterwards follow the prompts of the program to populate the entire file. Once you're done, rerun cmake and rebuild ImHex. Your language should now be available in the settings.
|
||||
|
||||
### Updating an existing language
|
||||
|
||||
If you'd like to add missing keys to an existing language, you can also use the `dist/langtool.py` tool. Run it with `python3 dist/langtool.py translate plugins/builtin/romfs/lang <iso_code>` where `<iso_code>` is the ISO 639-1 code of the language.
|
||||
This will one by one list all the missing translation keys that are present in the default translation file, and you can fill them in with the correct translation for your language.
|
||||
101
INSTALL.md
Normal file
101
INSTALL.md
Normal file
@@ -0,0 +1,101 @@
|
||||
# Installing ImHex
|
||||
|
||||
## Official Releases
|
||||
|
||||
The easiest way to install ImHex is to download the latest release from the [GitHub Releases page](https://github.com/WerWolv/ImHex/releases/latest).
|
||||
|
||||
There's also a NoGPU version available for users who don't have a GPU or want to run ImHex in a VM without GPU passthrough.
|
||||
|
||||
### Windows
|
||||
|
||||
#### Installer
|
||||
Simply run the installer to install ImHex on your system
|
||||
|
||||
#### Portable
|
||||
Extract the zip file to any location on your system.
|
||||
|
||||
### macOS
|
||||
Simply use the drag-n-drop dmg package to install ImHex on your system. It's possible that you need to allow the app to run in the security settings.
|
||||
|
||||
### Linux
|
||||
|
||||
#### AppImage
|
||||
To run the AppImage, make sure it's executable. Then simply run it.
|
||||
|
||||
```bash
|
||||
chmod +x imhex-*.AppImage
|
||||
./imhex-*.AppImage
|
||||
```
|
||||
|
||||
#### Flatpak
|
||||
To install the Flatpak, make sure you have the Flathub repository added to your system. Then simply run the following command:
|
||||
|
||||
```bash
|
||||
flatpak install flathub net.werwolv.ImHex
|
||||
```
|
||||
|
||||
#### Ubuntu DEB Package
|
||||
To install the DEB package, simply run the following command:
|
||||
|
||||
```bash
|
||||
sudo apt install ./imhex-*.deb
|
||||
```
|
||||
|
||||
#### Arch Linux
|
||||
To install the Arch Linux package, simply run the following command:
|
||||
|
||||
```bash
|
||||
sudo pacman -U imhex-*.pkg.tar.zst
|
||||
```
|
||||
|
||||
#### Fedora / RHEL / AlmaLinux RPM Package
|
||||
To install the RPM package, simply run the following command:
|
||||
|
||||
```bash
|
||||
sudo dnf install ./imhex-*.rpm
|
||||
```
|
||||
|
||||
## Nightly Builds
|
||||
|
||||
The GitHub Actions CI builds a new release package on every commit made to repository. These builds are available on the [GitHub Actions page](https://github.com/WerWolv/ImHex/actions?query=workflow%3A%22Build%22).
|
||||
These builds are not guaranteed to be stable and may contain bugs, however they also contain new features that are not yet available in the official releases.
|
||||
|
||||
## Building from source
|
||||
|
||||
Build instructions for Windows, Linux and macOS can be found under `/dist/compiling`:
|
||||
- Windows: [Link](dist/compiling/windows.md)
|
||||
- macOS: [Link](dist/compiling/macos.md)
|
||||
- Linux: [Link](dist/compiling/linux.md)
|
||||
|
||||
## Package managers
|
||||
|
||||
ImHex is also available on various package managers. The officially supported ones are listed here:
|
||||
|
||||
### Windows
|
||||
|
||||
- **Chocolatey**
|
||||
- [imhex](https://community.chocolatey.org/packages/imhex) (Thanks to @Jarcho)
|
||||
- `choco install imhex`
|
||||
- **Winget**
|
||||
- [WerWolv.ImHex](https://github.com/microsoft/winget-pkgs/tree/master/manifests/w/WerWolv/ImHex)
|
||||
- `winget install WerWolv.ImHex`
|
||||
|
||||
### Linux
|
||||
- **Arch Linux AUR**
|
||||
- [imhex-bin](https://aur.archlinux.org/packages/imhex-bin/) (Thanks to @iTrooz)
|
||||
- `yay -S imhex-bin`
|
||||
- [imhex](https://aur.archlinux.org/packages/imhex/) (Thanks to @KokaKiwi)
|
||||
- `yay -S imhex`
|
||||
- **Fedora**
|
||||
- [imhex](https://src.fedoraproject.org/rpms/imhex/) (Thanks to @jonathanspw)
|
||||
- `dnf install imhex`
|
||||
- **Flatpak**
|
||||
- [net.werwolv.Imhex](https://flathub.org/apps/details/net.werwolv.ImHex) (Thanks to @Mailaender)
|
||||
- `flatpak install flathub net.werwolv.ImHex`
|
||||
|
||||
### Available on other package managers
|
||||
|
||||
Packages that aren't explicitly mentioned above are not officially supported but they will most likely still work.
|
||||
Contact the maintainer of the package if you have any issues.
|
||||
|
||||
[](https://repology.org/project/imhex/versions)
|
||||
86
README.md
86
README.md
@@ -1,11 +1,30 @@
|
||||
<a href="https://imhex.werwolv.net"><h1 align="center" >:mag: ImHex</h1></a>
|
||||
<a href="https://imhex.werwolv.net">
|
||||
<h1 align="center">
|
||||
<picture>
|
||||
<source media="(prefers-color-scheme: dark)" srcset="./resources/projects/logo_text_light.svg">
|
||||
<img height="100px" src="./resources/projects/logo_text_dark.svg">
|
||||
</picture>
|
||||
</h1>
|
||||
</a>
|
||||
|
||||
<p align="center">A Hex Editor for Reverse Engineers, Programmers and people who value their retinas when working at 3 AM.</p>
|
||||
|
||||
<p align="center">
|
||||
<a title="'Build' workflow Status" href="https://github.com/WerWolv/ImHex/actions?query=workflow%3ABuild"><img alt="'Build' workflow Status" src="https://img.shields.io/github/workflow/status/WerWolv/ImHex/Build?longCache=true&style=for-the-badge&label=Build&logoColor=fff&logo=GitHub%20Actions"></a>
|
||||
<a title="Discord Server" href="https://discord.gg/X63jZ36xBY"><img alt="Discord Server" src="https://img.shields.io/discord/789833418631675954?label=Discord&logo=Discord&style=for-the-badge"></a>
|
||||
<a title="Total Downloads" href="https://github.com/WerWolv/ImHex/releases/latest"><img alt="Total Downloads" src="https://img.shields.io/github/downloads/WerWolv/ImHex/total?longCache=true&style=for-the-badge&label=Downloads&logoColor=fff&logo=GitHub"></a>
|
||||
<a title="'Build' workflow Status" href="https://github.com/WerWolv/ImHex/actions?query=workflow%3ABuild">
|
||||
<img alt="'Build' workflow Status" src="https://img.shields.io/github/actions/workflow/status/WerWolv/ImHex/build.yml?longCache=true&style=for-the-badge&label=Build&logoColor=fff&logo=GitHub%20Actions&branch=master">
|
||||
</a>
|
||||
<a title="Discord Server" href="https://discord.gg/X63jZ36xBY">
|
||||
<img alt="Discord Server" src="https://img.shields.io/discord/789833418631675954?label=Discord&logo=Discord&logoColor=fff&style=for-the-badge">
|
||||
</a>
|
||||
<a title="Total Downloads" href="https://github.com/WerWolv/ImHex/releases/latest">
|
||||
<img alt="Total Downloads" src="https://img.shields.io/github/downloads/WerWolv/ImHex/total?longCache=true&style=for-the-badge&label=Downloads&logoColor=fff&logo=GitHub">
|
||||
</a>
|
||||
<a title="Code Quality" href="https://www.codefactor.io/repository/github/werwolv/imhex">
|
||||
<img alt="Code Quality" src="https://img.shields.io/codefactor/grade/github/WerWolv/ImHex?longCache=true&style=for-the-badge&label=Code%20Quality&logoColor=fff&logo=CodeFactor&branch=master">
|
||||
</a>
|
||||
<a title="Translation" href="https://weblate.werwolv.net/projects/imhex/">
|
||||
<img alt="Translation" src="https://img.shields.io/weblate/progress/imhex?logo=weblate&logoColor=%23FFFFFF&server=https%3A%2F%2Fweblate.werwolv.net&style=for-the-badge">
|
||||
</a>
|
||||
</p>
|
||||
|
||||
## Supporting
|
||||
@@ -104,7 +123,11 @@ If you like my work, please consider supporting me on GitHub Sponsors, Patreon o
|
||||
|
||||
## Pattern Language
|
||||
|
||||
The custom C-like Pattern Language developed and used by ImHex is easy to read, understand and learn. A guide with all features of the language can be found [on the docs page](http://imhex.werwolv.net/docs).
|
||||
The Pattern Language is the completely custom programming language developed for ImHex.
|
||||
It allows you to define structures and data types in a C-like syntax and then use them to parse and highlight a file's content.
|
||||
|
||||
- Source Code: [Link](https://github.com/WerWolv/PatternLanguage/)
|
||||
- Documentation: [Link](https://imhex.werwolv.net/docs/)
|
||||
|
||||
## Database
|
||||
|
||||
@@ -116,12 +139,29 @@ For format patterns, libraries, magic and constant files, check out the [ImHex-P
|
||||
|
||||
To use ImHex, the following minimal system requirements need to be met:
|
||||
|
||||
- **OS**: Windows 10 or higher, macOS 11 (Big Sur) or higher, "Modern" Linux (Ubuntu 22.04+, Fedora and Arch Linux are officially supported)
|
||||
- **OS**: Windows 7 or higher, macOS 10.15 (Catalina) or higher, "Modern" Linux (Ubuntu 22.04, Fedora 36/37, RHEL/AlmaLinux 9, and Arch Linux have official packages, other and older distributions can use the AppImage)
|
||||
- **CPU**: x86_64 (64 Bit)
|
||||
- **GPU**: OpenGL 3.0 or higher (preferable a dedicated GPU and not Intel HD Graphics)
|
||||
- **RAM**: 512MB, more may be required for more complicated analysis
|
||||
- **GPU**: OpenGL 3.0 or higher
|
||||
- Intel HD drivers are really buggy and often cause graphic artifacts
|
||||
- In case you don't have a GPU available, there are software rendered releases available for Windows and macOS
|
||||
- **RAM**: 256MB, more may be required for more complicated analysis
|
||||
- **Storage**: 100MB
|
||||
|
||||
## Installing
|
||||
|
||||
Information on how to install ImHex can be found in the [Install](/INSTALL.md) guide
|
||||
|
||||
## Compiling
|
||||
|
||||
To compile ImHex on any platform, GCC (or Clang) is required with a version that supports C++23 or higher.
|
||||
On macOS, Clang is also required to compile some ObjC code.
|
||||
All releases are being built using latest available GCC.
|
||||
|
||||
Many dependencies are bundled into the repository using submodules so make sure to clone it using the `--recurse-submodules` option.
|
||||
All dependencies that aren't bundled, can be installed using the dependency installer scripts found in the `/dist` folder.
|
||||
|
||||
For more information, check out the [Compiling](/dist/compiling) guide.
|
||||
|
||||
## Plugin development
|
||||
|
||||
To develop plugins for ImHex, use one of the following two templates projects to get started. You then have access to the entirety of libimhex as well as the ImHex API and the Content Registry to interact with ImHex or to add new content.
|
||||
@@ -129,36 +169,6 @@ To develop plugins for ImHex, use one of the following two templates projects to
|
||||
- [Rust Plugin Template](https://github.com/WerWolv/ImHex-Rust-Plugin-Template)
|
||||
|
||||
|
||||
## Nightly builds
|
||||
|
||||
Nightlies are available via GitHub Actions [here](https://github.com/WerWolv/ImHex/actions?query=workflow%3ABuild).
|
||||
|
||||
- Windows • __x86_64__
|
||||
- [Installer](https://nightly.link/WerWolv/ImHex/workflows/build/master/Windows%20Installer.zip)
|
||||
- [Portable](https://nightly.link/WerWolv/ImHex/workflows/build/master/Windows%20Portable.zip)
|
||||
- MacOS • __x86_64__
|
||||
- [DMG](https://nightly.link/WerWolv/ImHex/workflows/build/master/macOS%20DMG.zip)
|
||||
- Linux • __x86_64__
|
||||
- [Ubuntu DEB](https://nightly.link/WerWolv/ImHex/workflows/build/master/Linux%20DEB%20%28Ubuntu%2022.04%29.zip)
|
||||
- [AppImage](https://nightly.link/WerWolv/ImHex/workflows/build/master/Linux%20AppImage.zip)
|
||||
- [Arch Package](https://nightly.link/WerWolv/ImHex/workflows/build/master/ArchLinux%20.pkg.tar.zst.zip)
|
||||
- [Fedora Rawhide RPM](https://nightly.link/WerWolv/ImHex/workflows/build/master/Fedora%20Rawhide%20RPM.zip)
|
||||
- [Fedora Stable RPM](https://nightly.link/WerWolv/ImHex/workflows/build/master/Fedora%20Latest%20RPM.zip)
|
||||
|
||||
## Third party repositories
|
||||
|
||||
ImHex is available in various third party repositories.
|
||||
|
||||
[](https://repology.org/project/imhex/versions)
|
||||
|
||||
## Compiling
|
||||
|
||||
To compile ImHex on any platform, GCC is required with a version that supports C++23 or higher.
|
||||
On macOS, Clang is also required to compile some ObjC code.
|
||||
|
||||
Many dependencies are bundled into the repository using submodules so make sure to clone it using the `--recurse-submodules` option.
|
||||
All dependencies that aren't bundled, can be installed using the dependency installer scripts found in the `/dist` folder.
|
||||
|
||||
## Credits
|
||||
|
||||
### Contributors
|
||||
|
||||
@@ -36,46 +36,22 @@ macro(addVersionDefines)
|
||||
|
||||
set(CMAKE_RC_FLAGS "${CMAKE_RC_FLAGS} -DPROJECT_VERSION_MAJOR=${PROJECT_VERSION_MAJOR} -DPROJECT_VERSION_MINOR=${PROJECT_VERSION_MINOR} -DPROJECT_VERSION_PATCH=${PROJECT_VERSION_PATCH} ")
|
||||
|
||||
set(IMHEX_VERSION_STRING ${IMHEX_VERSION})
|
||||
if (CMAKE_BUILD_TYPE STREQUAL "Release")
|
||||
set(IMHEX_VERSION_STRING ${IMHEX_VERSION})
|
||||
set(IMHEX_VERSION_STRING ${IMHEX_VERSION_STRING})
|
||||
elseif (CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
set(IMHEX_VERSION_STRING ${IMHEX_VERSION}-Debug)
|
||||
add_compile_definitions(DEBUG)
|
||||
set(IMHEX_VERSION_STRING ${IMHEX_VERSION_STRING}-Debug)
|
||||
add_compile_definitions(DEBUG _GLIBCXX_DEBUG _GLIBCXX_VERBOSE)
|
||||
elseif (CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo")
|
||||
set(IMHEX_VERSION_STRING ${IMHEX_VERSION}-RelWithDebInfo)
|
||||
set(IMHEX_VERSION_STRING ${IMHEX_VERSION_STRING}-RelWithDebInfo)
|
||||
elseif (CMAKE_BUILD_TYPE STREQUAL "MinSizeRel")
|
||||
set(IMHEX_VERSION_STRING ${IMHEX_VERSION}-MinSizeRel)
|
||||
set(IMHEX_VERSION_STRING ${IMHEX_VERSION_STRING}-MinSizeRel)
|
||||
endif ()
|
||||
|
||||
add_compile_definitions(IMHEX_VERSION="${IMHEX_VERSION_STRING}")
|
||||
|
||||
endmacro()
|
||||
|
||||
macro(configurePython)
|
||||
set(CMAKE_FIND_PACKAGE_SORT_ORDER NATURAL)
|
||||
set(CMAKE_FIND_PACKAGE_SORT_DIRECTION DEC)
|
||||
|
||||
# Enforce that we use non system Python 3 on macOS.
|
||||
set(Python_FIND_FRAMEWORK NEVER)
|
||||
|
||||
find_package(Python COMPONENTS Development REQUIRED)
|
||||
if(Python_VERSION LESS 3)
|
||||
message(STATUS ${PYTHON_VERSION_MAJOR_MINOR})
|
||||
message(FATAL_ERROR "No valid version of Python 3 was found.")
|
||||
endif()
|
||||
|
||||
string(REPLACE "." ";" PYTHON_VERSION_MAJOR_MINOR ${Python_VERSION})
|
||||
|
||||
list(LENGTH PYTHON_VERSION_MAJOR_MINOR PYTHON_VERSION_COMPONENT_COUNT)
|
||||
|
||||
if (PYTHON_VERSION_COMPONENT_COUNT EQUAL 3)
|
||||
list(REMOVE_AT PYTHON_VERSION_MAJOR_MINOR 2)
|
||||
endif ()
|
||||
list(JOIN PYTHON_VERSION_MAJOR_MINOR "." PYTHON_VERSION_MAJOR_MINOR)
|
||||
|
||||
add_compile_definitions(PYTHON_VERSION_MAJOR_MINOR="${PYTHON_VERSION_MAJOR_MINOR}")
|
||||
endmacro()
|
||||
|
||||
# Detect current OS / System
|
||||
macro(detectOS)
|
||||
if (WIN32)
|
||||
@@ -83,6 +59,8 @@ macro(detectOS)
|
||||
set(CMAKE_INSTALL_BINDIR ".")
|
||||
set(CMAKE_INSTALL_LIBDIR ".")
|
||||
set(PLUGINS_INSTALL_LOCATION "plugins")
|
||||
|
||||
SET(IMHEX_USE_BUNDLED_CA ON)
|
||||
elseif (APPLE)
|
||||
add_compile_definitions(OS_MACOS)
|
||||
set(CMAKE_INSTALL_BINDIR ".")
|
||||
@@ -101,10 +79,15 @@ macro(detectOS)
|
||||
# Warning : Do not work with portable versions such as appimage (because the path is hardcoded)
|
||||
add_compile_definitions(SYSTEM_PLUGINS_LOCATION="${CMAKE_INSTALL_FULL_LIBDIR}/imhex") # "plugins" will be appended from the app
|
||||
endif()
|
||||
|
||||
|
||||
else ()
|
||||
message(FATAL_ERROR "Unknown / unsupported system!")
|
||||
endif()
|
||||
|
||||
if(IMHEX_USE_BUNDLED_CA)
|
||||
add_compile_definitions(IMHEX_USE_BUNDLED_CA)
|
||||
endif()
|
||||
|
||||
endmacro()
|
||||
|
||||
# Detect 32 vs. 64 bit system
|
||||
@@ -127,23 +110,25 @@ macro(configurePackingResources)
|
||||
if (WIN32)
|
||||
set(APPLICATION_TYPE)
|
||||
set(IMHEX_ICON "${IMHEX_BASE_FOLDER}/resources/resource.rc")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wl,--allow-multiple-definition")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wl,-subsystem,windows")
|
||||
|
||||
if (CREATE_PACKAGE)
|
||||
set(CPACK_GENERATOR "WIX")
|
||||
set(CPACK_PACKAGE_NAME "ImHex")
|
||||
set(CPACK_PACKAGE_NAME "imhex")
|
||||
set(CPACK_PACKAGE_VENDOR "WerWolv")
|
||||
set(CPACK_WIX_UPGRADE_GUID "05000E99-9659-42FD-A1CF-05C554B39285")
|
||||
set(CPACK_WIX_PRODUCT_ICON "${PROJECT_SOURCE_DIR}/resources/icon.ico")
|
||||
set(CPACK_WIX_PRODUCT_ICON "${PROJECT_SOURCE_DIR}/resources/dist/windows/icon.ico")
|
||||
set(CPACK_WIX_UI_BANNER "${PROJECT_SOURCE_DIR}/resources/dist/windows/wix_banner.png")
|
||||
set(CPACK_WIX_UI_DIALOG "${PROJECT_SOURCE_DIR}/resources/dist/windows/wix_dialog.png")
|
||||
set(CPACK_WIX_CULTURES "en-US;de-DE;ja-JP;it-IT;pt-BR;zh-CN;zh-TW")
|
||||
set(CPACK_PACKAGE_INSTALL_DIRECTORY "ImHex")
|
||||
set_property(INSTALL "$<TARGET_FILE_NAME:main>"
|
||||
PROPERTY CPACK_START_MENU_SHORTCUTS "ImHex"
|
||||
)
|
||||
set(CPACK_RESOURCE_FILE_LICENSE "${PROJECT_SOURCE_DIR}/resources/LICENSE.rtf")
|
||||
set(CPACK_RESOURCE_FILE_LICENSE "${PROJECT_SOURCE_DIR}/resources/dist/windows/LICENSE.rtf")
|
||||
endif()
|
||||
elseif (APPLE)
|
||||
set (IMHEX_ICON "${IMHEX_BASE_FOLDER}/resources/AppIcon.icns")
|
||||
set (IMHEX_ICON "${IMHEX_BASE_FOLDER}/resources/dist/macos/AppIcon.icns")
|
||||
|
||||
if (CREATE_BUNDLE)
|
||||
set(APPLICATION_TYPE MACOSX_BUNDLE)
|
||||
@@ -151,21 +136,26 @@ macro(configurePackingResources)
|
||||
set(MACOSX_BUNDLE_ICON_FILE "AppIcon.icns")
|
||||
set(MACOSX_BUNDLE_INFO_STRING "WerWolv")
|
||||
set(MACOSX_BUNDLE_BUNDLE_NAME "ImHex")
|
||||
set(MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/resources/dist/macos/Info.plist.in")
|
||||
set(MACOSX_BUNDLE_BUNDLE_VERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}")
|
||||
set(MACOSX_BUNDLE_GUI_IDENTIFIER "net.WerWolv.ImHex")
|
||||
set(MACOSX_BUNDLE_LONG_VERSION_STRING "${PROJECT_VERSION}-${GIT_COMMIT_HASH}")
|
||||
set(MACOSX_BUNDLE_SHORT_VERSION_STRING "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}")
|
||||
set(MACOSX_BUNDLE_COPYRIGHT "Copyright © 2020 WerWolv and Thog. All rights reserved." )
|
||||
|
||||
string(TIMESTAMP CURR_YEAR "%Y")
|
||||
set(MACOSX_BUNDLE_COPYRIGHT "Copyright © 2020 - ${CURR_YEAR} WerWolv. All rights reserved." )
|
||||
if ("${CMAKE_GENERATOR}" STREQUAL "Xcode")
|
||||
set ( bundle_path "${CMAKE_BINARY_DIR}/${CMAKE_BUILD_TYPE}/ImHex.app" )
|
||||
set (IMHEX_BUNDLE_PATH "${CMAKE_BINARY_DIR}/${CMAKE_BUILD_TYPE}/ImHex.app")
|
||||
else ()
|
||||
set ( bundle_path "${CMAKE_BINARY_DIR}/ImHex.app" )
|
||||
set (IMHEX_BUNDLE_PATH "${CMAKE_BINARY_DIR}/ImHex.app")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
macro(createPackage)
|
||||
set(LIBRARY_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
|
||||
|
||||
file(MAKE_DIRECTORY "plugins")
|
||||
foreach (plugin IN LISTS PLUGINS)
|
||||
add_subdirectory("plugins/${plugin}")
|
||||
@@ -180,7 +170,7 @@ macro(createPackage)
|
||||
|
||||
get_target_property(PLUGIN_LOCATION ${plugin} LOCATION)
|
||||
|
||||
install(FILES "${PLUGIN_LOCATION}/../${plugin}.hexplug" DESTINATION "${PLUGINS_INSTALL_LOCATION}")
|
||||
install(FILES "${PLUGIN_LOCATION}/../${plugin}.hexplug" DESTINATION "${PLUGINS_INSTALL_LOCATION}" PERMISSIONS ${LIBRARY_PERMISSIONS})
|
||||
else ()
|
||||
if (WIN32)
|
||||
install(TARGETS ${plugin} RUNTIME DESTINATION ${PLUGINS_INSTALL_LOCATION})
|
||||
@@ -195,7 +185,7 @@ macro(createPackage)
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
add_dependencies(imhex_all ${plugin})
|
||||
add_dependencies(imhex ${plugin})
|
||||
endif ()
|
||||
endforeach()
|
||||
|
||||
@@ -207,7 +197,6 @@ macro(createPackage)
|
||||
|
||||
# Grab all dynamically linked dependencies.
|
||||
INSTALL(CODE "set(CMAKE_INSTALL_BINDIR \"${CMAKE_INSTALL_BINDIR}\")")
|
||||
INSTALL(CODE "get_filename_component(PY_PARENT \"${Python_LIBRARIES}\" DIRECTORY)")
|
||||
INSTALL(CODE "LIST(APPEND DEP_FOLDERS \${PY_PARENT})")
|
||||
install(CODE [[
|
||||
file(GET_RUNTIME_DEPENDENCIES
|
||||
@@ -236,42 +225,51 @@ macro(createPackage)
|
||||
endforeach()
|
||||
]])
|
||||
|
||||
install(FILES "$<TARGET_FILE:libimhex>" DESTINATION "${CMAKE_INSTALL_LIBDIR}")
|
||||
install(FILES "$<TARGET_FILE:libimhex>" DESTINATION "${CMAKE_INSTALL_LIBDIR}" PERMISSIONS ${LIBRARY_PERMISSIONS})
|
||||
downloadImHexPatternsFiles("./")
|
||||
elseif(UNIX AND NOT APPLE)
|
||||
|
||||
set_target_properties(libimhex PROPERTIES SOVERSION ${IMHEX_VERSION})
|
||||
|
||||
configure_file(${CMAKE_SOURCE_DIR}/dist/DEBIAN/control.in ${CMAKE_BINARY_DIR}/DEBIAN/control)
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/dist/DEBIAN/control.in ${CMAKE_BINARY_DIR}/DEBIAN/control)
|
||||
|
||||
install(FILES ${CMAKE_SOURCE_DIR}/LICENSE DESTINATION ${CMAKE_INSTALL_PREFIX}/share/licenses/imhex)
|
||||
install(FILES ${CMAKE_SOURCE_DIR}/dist/imhex.desktop DESTINATION ${CMAKE_INSTALL_PREFIX}/share/applications)
|
||||
install(FILES ${CMAKE_SOURCE_DIR}/resources/icon.png DESTINATION ${CMAKE_INSTALL_PREFIX}/share/pixmaps RENAME imhex.png)
|
||||
install(FILES "$<TARGET_FILE:libimhex>" DESTINATION "${CMAKE_INSTALL_LIBDIR}")
|
||||
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/LICENSE DESTINATION ${CMAKE_INSTALL_PREFIX}/share/licenses/imhex)
|
||||
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/dist/imhex.desktop DESTINATION ${CMAKE_INSTALL_PREFIX}/share/applications)
|
||||
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/resources/icon.png DESTINATION ${CMAKE_INSTALL_PREFIX}/share/pixmaps RENAME imhex.png)
|
||||
install(FILES "$<TARGET_FILE:libimhex>" DESTINATION "${CMAKE_INSTALL_LIBDIR}" PERMISSIONS ${LIBRARY_PERMISSIONS})
|
||||
downloadImHexPatternsFiles("./share/imhex")
|
||||
|
||||
# install AppStream file
|
||||
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/dist/net.werwolv.imhex.metainfo.xml DESTINATION ${CMAKE_INSTALL_PREFIX}/share/metainfo)
|
||||
|
||||
# install symlink for the old standard name
|
||||
file(CREATE_LINK net.werwolv.imhex.metainfo.xml ${CMAKE_CURRENT_BINARY_DIR}/net.werwolv.imhex.appdata.xml SYMBOLIC)
|
||||
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/net.werwolv.imhex.appdata.xml DESTINATION ${CMAKE_INSTALL_PREFIX}/share/metainfo)
|
||||
|
||||
endif()
|
||||
|
||||
if (CREATE_BUNDLE)
|
||||
include(PostprocessBundle)
|
||||
|
||||
set_target_properties(libimhex PROPERTIES SOVERSION ${IMHEX_VERSION})
|
||||
|
||||
|
||||
set_property(TARGET main PROPERTY MACOSX_BUNDLE_INFO_PLIST ${MACOSX_BUNDLE_INFO_PLIST})
|
||||
|
||||
# Fix rpath
|
||||
add_custom_command(TARGET imhex_all POST_BUILD COMMAND ${CMAKE_INSTALL_NAME_TOOL} -add_rpath "@executable_path/../Frameworks/" $<TARGET_FILE:main>)
|
||||
add_custom_command(TARGET imhex POST_BUILD COMMAND ${CMAKE_INSTALL_NAME_TOOL} -add_rpath "@executable_path/../Frameworks/" $<TARGET_FILE:main>)
|
||||
|
||||
# FIXME: Remove this once we move/integrate the plugins directory.
|
||||
add_custom_target(build-time-make-plugins-directory ALL COMMAND ${CMAKE_COMMAND} -E make_directory "${bundle_path}/Contents/MacOS/plugins")
|
||||
add_custom_target(build-time-make-resources-directory ALL COMMAND ${CMAKE_COMMAND} -E make_directory "${bundle_path}/Contents/Resources")
|
||||
add_custom_target(build-time-make-plugins-directory ALL COMMAND ${CMAKE_COMMAND} -E make_directory "${IMHEX_BUNDLE_PATH}/Contents/MacOS/plugins")
|
||||
add_custom_target(build-time-make-resources-directory ALL COMMAND ${CMAKE_COMMAND} -E make_directory "${IMHEX_BUNDLE_PATH}/Contents/Resources")
|
||||
|
||||
downloadImHexPatternsFiles("${bundle_path}/Contents/MacOS")
|
||||
downloadImHexPatternsFiles("${IMHEX_BUNDLE_PATH}/Contents/MacOS")
|
||||
|
||||
install(FILES ${IMHEX_ICON} DESTINATION "${bundle_path}/Contents/Resources")
|
||||
install(FILES ${IMHEX_ICON} DESTINATION "${IMHEX_BUNDLE_PATH}/Contents/Resources")
|
||||
install(TARGETS main BUNDLE DESTINATION ".")
|
||||
install(FILES $<TARGET_FILE:main> DESTINATION "${bundle_path}")
|
||||
install(FILES $<TARGET_FILE:main> DESTINATION "${IMHEX_BUNDLE_PATH}")
|
||||
|
||||
# Update library references to make the bundle portable
|
||||
postprocess_bundle(imhex_all main)
|
||||
postprocess_bundle(imhex main)
|
||||
|
||||
# Enforce DragNDrop packaging.
|
||||
set(CPACK_GENERATOR "DragNDrop")
|
||||
@@ -280,7 +278,10 @@ macro(createPackage)
|
||||
endif()
|
||||
|
||||
if (CREATE_PACKAGE)
|
||||
include(apple)
|
||||
set (CPACK_BUNDLE_NAME "ImHex")
|
||||
set (CPACK_BUNDLE_ICON "${CMAKE_SOURCE_DIR}/resources/dist/macos/AppIcon.icns" )
|
||||
set (CPACK_BUNDLE_PLIST "${CMAKE_BINARY_DIR}/ImHex.app/Contents/Info.plist")
|
||||
|
||||
include(CPack)
|
||||
endif()
|
||||
endmacro()
|
||||
@@ -303,7 +304,10 @@ macro(setDefaultBuiltTypeIfUnset)
|
||||
endmacro()
|
||||
|
||||
function(loadVersion version)
|
||||
file(READ "${CMAKE_CURRENT_SOURCE_DIR}/VERSION" read_version)
|
||||
set(VERSION_FILE "${CMAKE_CURRENT_SOURCE_DIR}/VERSION")
|
||||
set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${VERSION_FILE})
|
||||
file(READ "${VERSION_FILE}" read_version)
|
||||
string(STRIP ${read_version} read_version)
|
||||
set(${version} ${read_version} PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
@@ -322,15 +326,17 @@ function(detectBadClone)
|
||||
endforeach ()
|
||||
endfunction()
|
||||
|
||||
set(IMHEX_REQUIRED_COMPILER "GNU")
|
||||
set(IMHEX_MIN_COMPILER_VERSION "12.0.0")
|
||||
function(verifyCompiler)
|
||||
if (IMHEX_IGNORE_BAD_COMPILER)
|
||||
return()
|
||||
endif()
|
||||
|
||||
if (NOT CMAKE_CXX_COMPILER_ID STREQUAL ${IMHEX_REQUIRED_COMPILER} OR CMAKE_CXX_COMPILER_VERSION VERSION_LESS ${IMHEX_MIN_COMPILER_VERSION})
|
||||
message(FATAL_ERROR "ImHex requires GCC ${IMHEX_MIN_COMPILER_VERSION} or newer. Please use the latest GCC version.")
|
||||
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS "12.0.0")
|
||||
message(FATAL_ERROR "ImHex requires GCC 12.0.0 or newer. Please use the latest GCC version.")
|
||||
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS "14.0.0")
|
||||
message(FATAL_ERROR "ImHex requires Clang 14.0.0 or newer. Please use the latest Clang version.")
|
||||
elseif (NOT (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang"))
|
||||
message(FATAL_ERROR "ImHex can only be compiled with GCC or Clang. ${CMAKE_CXX_COMPILER_ID} is not supported.")
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
@@ -358,8 +364,16 @@ function(downloadImHexPatternsFiles dest)
|
||||
GIT_TAG master
|
||||
)
|
||||
|
||||
FetchContent_Populate(imhex_patterns)
|
||||
message(STATUS "Downloading ImHex-Patterns repo branch ${PATTERNS_BRANCH}...")
|
||||
FetchContent_MakeAvailable(imhex_patterns)
|
||||
message(STATUS "Finished downloading ImHex-Patterns")
|
||||
|
||||
else ()
|
||||
# Maybe patterns are cloned to a subdirectory
|
||||
set(imhex_patterns_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ImHex-Patterns")
|
||||
endif ()
|
||||
|
||||
if (EXISTS ${imhex_patterns_SOURCE_DIR})
|
||||
set(PATTERNS_FOLDERS_TO_INSTALL constants encodings includes patterns magic)
|
||||
foreach (FOLDER ${PATTERNS_FOLDERS_TO_INSTALL})
|
||||
install(DIRECTORY "${imhex_patterns_SOURCE_DIR}/${FOLDER}" DESTINATION ${dest})
|
||||
@@ -369,10 +383,157 @@ function(downloadImHexPatternsFiles dest)
|
||||
endfunction()
|
||||
|
||||
macro(setupCompilerWarnings target)
|
||||
set(IMHEX_COMMON_FLAGS "-Wall -Wextra -Werror")
|
||||
set(IMHEX_C_FLAGS "${IMHEX_COMMON_FLAGS} -Wno-restrict -Wno-stringop-overread")
|
||||
set(IMHEX_COMMON_FLAGS "-Wall -Wextra -Wpedantic -Werror")
|
||||
set(IMHEX_C_FLAGS "${IMHEX_COMMON_FLAGS} -Wno-restrict -Wno-stringop-overread -Wno-stringop-overflow")
|
||||
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${IMHEX_C_FLAGS}")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${IMHEX_C_FLAGS}")
|
||||
set(CMAKE_OBJC_FLAGS "${CMAKE_OBJC_FLAGS} ${IMHEX_COMMON_FLAGS}")
|
||||
endmacro()
|
||||
endmacro()
|
||||
|
||||
# uninstall target
|
||||
macro(setUninstallTarget)
|
||||
if(NOT TARGET uninstall)
|
||||
configure_file(
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/cmake_uninstall.cmake.in"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake"
|
||||
IMMEDIATE @ONLY)
|
||||
|
||||
add_custom_target(uninstall
|
||||
COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake)
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
macro(addBundledLibraries)
|
||||
find_package(PkgConfig REQUIRED)
|
||||
|
||||
set(EXTERN_LIBS_FOLDER "${CMAKE_CURRENT_SOURCE_DIR}/lib/external")
|
||||
|
||||
set(BUILD_SHARED_LIBS OFF)
|
||||
add_subdirectory(${EXTERN_LIBS_FOLDER}/imgui)
|
||||
set_target_properties(imgui PROPERTIES POSITION_INDEPENDENT_CODE ON)
|
||||
|
||||
add_subdirectory(${EXTERN_LIBS_FOLDER}/microtar EXCLUDE_FROM_ALL)
|
||||
set_target_properties(microtar PROPERTIES POSITION_INDEPENDENT_CODE ON)
|
||||
|
||||
add_subdirectory(${EXTERN_LIBS_FOLDER}/intervaltree EXCLUDE_FROM_ALL)
|
||||
set_target_properties(intervaltree PROPERTIES POSITION_INDEPENDENT_CODE ON)
|
||||
|
||||
set(XDGPP_INCLUDE_DIRS "${EXTERN_LIBS_FOLDER}/xdgpp")
|
||||
set(CURL_USE_MBEDTLS ON)
|
||||
set(BUILD_CURL_EXE OFF)
|
||||
set(FPHSA_NAME_MISMATCHED ON CACHE BOOL "")
|
||||
|
||||
if(NOT USE_SYSTEM_FMT)
|
||||
add_subdirectory(${EXTERN_LIBS_FOLDER}/fmt EXCLUDE_FROM_ALL)
|
||||
set_target_properties(fmt PROPERTIES POSITION_INDEPENDENT_CODE ON)
|
||||
set(FMT_LIBRARIES fmt::fmt-header-only)
|
||||
else()
|
||||
find_package(fmt 8.0.0 REQUIRED)
|
||||
set(FMT_LIBRARIES fmt::fmt)
|
||||
endif()
|
||||
|
||||
if (IMHEX_USE_GTK_FILE_PICKER)
|
||||
set(NFD_PORTAL OFF CACHE BOOL "Use Portals for Linux file dialogs" FORCE)
|
||||
else ()
|
||||
set(NFD_PORTAL ON CACHE BOOL "Use GTK for Linux file dialogs" FORCE)
|
||||
endif ()
|
||||
|
||||
if (NOT USE_SYSTEM_NFD)
|
||||
add_subdirectory(${EXTERN_LIBS_FOLDER}/nativefiledialog EXCLUDE_FROM_ALL)
|
||||
set_target_properties(nfd PROPERTIES POSITION_INDEPENDENT_CODE ON)
|
||||
set(NFD_LIBRARIES nfd)
|
||||
else()
|
||||
find_package(nfd)
|
||||
set(NFD_LIBRARIES nfd)
|
||||
endif()
|
||||
|
||||
if(NOT USE_SYSTEM_NLOHMANN_JSON)
|
||||
add_subdirectory(${EXTERN_LIBS_FOLDER}/nlohmann_json EXCLUDE_FROM_ALL)
|
||||
set(NLOHMANN_JSON_LIBRARIES nlohmann_json)
|
||||
else()
|
||||
find_package(nlohmann_json 3.10.2 REQUIRED)
|
||||
set(NLOHMANN_JSON_LIBRARIES nlohmann_json::nlohmann_json)
|
||||
endif()
|
||||
|
||||
if(NOT USE_SYSTEM_CURL)
|
||||
add_subdirectory(${EXTERN_LIBS_FOLDER}/curl EXCLUDE_FROM_ALL)
|
||||
set_target_properties(libcurl PROPERTIES POSITION_INDEPENDENT_CODE ON)
|
||||
set(LIBCURL_LIBRARIES libcurl)
|
||||
else()
|
||||
find_package(PkgConfig REQUIRED)
|
||||
pkg_check_modules(LIBCURL REQUIRED IMPORTED_TARGET libcurl>=7.76.1)
|
||||
endif()
|
||||
|
||||
if (NOT USE_SYSTEM_LLVM)
|
||||
add_subdirectory(${EXTERN_LIBS_FOLDER}/llvm-demangle EXCLUDE_FROM_ALL)
|
||||
set_target_properties(LLVMDemangle PROPERTIES POSITION_INDEPENDENT_CODE ON)
|
||||
else()
|
||||
find_package(LLVM REQUIRED Demangle)
|
||||
endif()
|
||||
|
||||
if (NOT USE_SYSTEM_YARA)
|
||||
add_subdirectory(${EXTERN_LIBS_FOLDER}/yara EXCLUDE_FROM_ALL)
|
||||
set_target_properties(libyara PROPERTIES POSITION_INDEPENDENT_CODE ON)
|
||||
set(YARA_LIBRARIES libyara)
|
||||
else()
|
||||
find_package(PkgConfig REQUIRED)
|
||||
pkg_check_modules(YARA REQUIRED IMPORTED_TARGET yara)
|
||||
endif()
|
||||
|
||||
if (NOT USE_SYSTEM_MINIAUDIO)
|
||||
add_subdirectory(${EXTERN_LIBS_FOLDER}/miniaudio EXCLUDE_FROM_ALL)
|
||||
set_target_properties(miniaudio PROPERTIES POSITION_INDEPENDENT_CODE ON)
|
||||
set(MINIAUDIO_LIBRARIES miniaudio)
|
||||
else()
|
||||
find_package(PkgConfig REQUIRED)
|
||||
pkg_check_modules(miniaudio REQUIRED IMPORTED_TARGET miniaudio)
|
||||
endif()
|
||||
|
||||
if (NOT USE_SYSTEM_CAPSTONE)
|
||||
set(CAPSTONE_BUILD_STATIC_RUNTIME OFF CACHE BOOL "Disable shared library building")
|
||||
set(CAPSTONE_BUILD_SHARED OFF CACHE BOOL "Disable shared library building")
|
||||
set(CAPSTONE_BUILD_TESTS OFF CACHE BOOL "Disable tests")
|
||||
add_subdirectory(${EXTERN_LIBS_FOLDER}/capstone EXCLUDE_FROM_ALL)
|
||||
set_target_properties(capstone PROPERTIES POSITION_INDEPENDENT_CODE ON)
|
||||
set(CAPSTONE_LIBRARIES "capstone")
|
||||
set(CAPSTONE_INCLUDE_DIRS ${EXTERN_LIBS_FOLDER}/capstone/include)
|
||||
else()
|
||||
find_package(PkgConfig REQUIRED)
|
||||
pkg_search_module(CAPSTONE 4.0.2 REQUIRED capstone)
|
||||
endif()
|
||||
|
||||
add_subdirectory(${EXTERN_LIBS_FOLDER}/pattern_language EXCLUDE_FROM_ALL)
|
||||
set_target_properties(libpl PROPERTIES POSITION_INDEPENDENT_CODE ON)
|
||||
|
||||
find_package(mbedTLS 2.26.0 REQUIRED)
|
||||
|
||||
pkg_search_module(MAGIC libmagic>=5.39)
|
||||
if(NOT MAGIC_FOUND)
|
||||
find_library(MAGIC 5.39 magic REQUIRED)
|
||||
else()
|
||||
set(MAGIC_INCLUDE_DIRS ${MAGIC_INCLUDEDIR})
|
||||
endif()
|
||||
|
||||
if (WIN32)
|
||||
message(STATUS "StackWalk enabled!")
|
||||
set(LIBBACKTRACE_LIBRARIES DbgHelp.lib)
|
||||
else ()
|
||||
find_package(Backtrace)
|
||||
if (${Backtrace_FOUND})
|
||||
message(STATUS "Backtrace enabled! Header: ${Backtrace_HEADER}")
|
||||
|
||||
if (Backtrace_HEADER STREQUAL "execinfo.h")
|
||||
set(LIBBACKTRACE_LIBRARIES)
|
||||
set(LIBBACKTRACE_INCLUDE_DIRS ${Backtrace_INCLUDE_DIR})
|
||||
add_compile_definitions(BACKTRACE_HEADER=\"${Backtrace_HEADER}\")
|
||||
add_compile_definitions(HEX_HAS_EXECINFO)
|
||||
elseif (Backtrace_HEADER STREQUAL "backtrace.h")
|
||||
set(LIBBACKTRACE_LIBRARIES backtrace)
|
||||
set(LIBBACKTRACE_INCLUDE_DIRS ${Backtrace_INCLUDE_DIR})
|
||||
add_compile_definitions(BACKTRACE_HEADER=\"${Backtrace_HEADER}\")
|
||||
add_compile_definitions(HEX_HAS_BACKTRACE)
|
||||
endif ()
|
||||
endif()
|
||||
endif ()
|
||||
endmacro()
|
||||
|
||||
21
cmake/cmake_uninstall.cmake.in
Normal file
21
cmake/cmake_uninstall.cmake.in
Normal file
@@ -0,0 +1,21 @@
|
||||
if(NOT EXISTS "@CMAKE_BINARY_DIR@/install_manifest.txt")
|
||||
message(FATAL_ERROR "Cannot find install manifest: @CMAKE_BINARY_DIR@/install_manifest.txt")
|
||||
endif()
|
||||
|
||||
file(READ "@CMAKE_BINARY_DIR@/install_manifest.txt" files)
|
||||
string(REGEX REPLACE "\n" ";" files "${files}")
|
||||
foreach(file ${files})
|
||||
message(STATUS "Uninstalling $ENV{DESTDIR}${file}")
|
||||
if(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}")
|
||||
exec_program(
|
||||
"@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\""
|
||||
OUTPUT_VARIABLE rm_out
|
||||
RETURN_VALUE rm_retval
|
||||
)
|
||||
if(NOT "${rm_retval}" STREQUAL 0)
|
||||
message(FATAL_ERROR "Problem when removing $ENV{DESTDIR}${file}")
|
||||
endif()
|
||||
else(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}")
|
||||
message(STATUS "File $ENV{DESTDIR}${file} does not exist.")
|
||||
endif()
|
||||
endforeach()
|
||||
91
cmake/modules/FindBacktrace.cmake
Normal file
91
cmake/modules/FindBacktrace.cmake
Normal file
@@ -0,0 +1,91 @@
|
||||
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
# file Copyright.txt or https://cmake.org/licensing for details.
|
||||
|
||||
#[=======================================================================[.rst:
|
||||
FindBacktrace
|
||||
-------------
|
||||
|
||||
Find provider for `backtrace(3) <https://man7.org/linux/man-pages/man3/backtrace.3.html>`__.
|
||||
|
||||
Checks if OS supports ``backtrace(3)`` via either ``libc`` or custom library.
|
||||
This module defines the following variables:
|
||||
|
||||
``Backtrace_HEADER``
|
||||
The header file needed for ``backtrace(3)``. Cached.
|
||||
Could be forcibly set by user.
|
||||
``Backtrace_INCLUDE_DIRS``
|
||||
The include directories needed to use ``backtrace(3)`` header.
|
||||
``Backtrace_LIBRARIES``
|
||||
The libraries (linker flags) needed to use ``backtrace(3)``, if any.
|
||||
``Backtrace_FOUND``
|
||||
Is set if and only if ``backtrace(3)`` support detected.
|
||||
|
||||
The following cache variables are also available to set or use:
|
||||
|
||||
``Backtrace_LIBRARY``
|
||||
The external library providing backtrace, if any.
|
||||
``Backtrace_INCLUDE_DIR``
|
||||
The directory holding the ``backtrace(3)`` header.
|
||||
|
||||
Typical usage is to generate of header file using :command:`configure_file`
|
||||
with the contents like the following::
|
||||
|
||||
#cmakedefine01 Backtrace_FOUND
|
||||
#if Backtrace_FOUND
|
||||
# include <${Backtrace_HEADER}>
|
||||
#endif
|
||||
|
||||
And then reference that generated header file in actual source.
|
||||
#]=======================================================================]
|
||||
|
||||
include(CMakePushCheckState)
|
||||
include(CheckSymbolExists)
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
|
||||
|
||||
# List of variables to be provided to find_package_handle_standard_args()
|
||||
set(_Backtrace_STD_ARGS Backtrace_INCLUDE_DIR)
|
||||
|
||||
if(Backtrace_HEADER)
|
||||
set(_Backtrace_HEADER_TRY "${Backtrace_HEADER}")
|
||||
else(Backtrace_HEADER)
|
||||
set(_Backtrace_HEADER_TRY "execinfo.h")
|
||||
endif(Backtrace_HEADER)
|
||||
|
||||
find_path(Backtrace_INCLUDE_DIR "${_Backtrace_HEADER_TRY}")
|
||||
set(Backtrace_INCLUDE_DIRS ${Backtrace_INCLUDE_DIR})
|
||||
|
||||
if (NOT DEFINED Backtrace_LIBRARY)
|
||||
# First, check if we already have backtrace(), e.g., in libc
|
||||
cmake_push_check_state(RESET)
|
||||
set(CMAKE_REQUIRED_INCLUDES ${Backtrace_INCLUDE_DIRS})
|
||||
set(CMAKE_REQUIRED_QUIET ${Backtrace_FIND_QUIETLY})
|
||||
check_symbol_exists("backtrace" "${_Backtrace_HEADER_TRY}" _Backtrace_SYM_FOUND)
|
||||
cmake_pop_check_state()
|
||||
endif()
|
||||
|
||||
if(_Backtrace_SYM_FOUND)
|
||||
# Avoid repeating the message() call below each time CMake is run.
|
||||
if(NOT Backtrace_FIND_QUIETLY AND NOT DEFINED Backtrace_LIBRARY)
|
||||
message(STATUS "backtrace facility detected in default set of libraries")
|
||||
endif()
|
||||
set(Backtrace_LIBRARY "" CACHE FILEPATH "Library providing backtrace(3), empty for default set of libraries")
|
||||
else()
|
||||
# Check for external library, for non-glibc systems
|
||||
if(Backtrace_INCLUDE_DIR)
|
||||
# OpenBSD has libbacktrace renamed to libexecinfo
|
||||
find_library(Backtrace_LIBRARY "execinfo")
|
||||
else() # respect user wishes
|
||||
set(_Backtrace_HEADER_TRY "backtrace.h")
|
||||
find_path(Backtrace_INCLUDE_DIR ${_Backtrace_HEADER_TRY})
|
||||
find_library(Backtrace_LIBRARY "backtrace")
|
||||
endif()
|
||||
|
||||
# Prepend list with library path as it's more common practice
|
||||
set(_Backtrace_STD_ARGS Backtrace_LIBRARY ${_Backtrace_STD_ARGS})
|
||||
endif()
|
||||
|
||||
set(Backtrace_LIBRARIES ${Backtrace_LIBRARY})
|
||||
set(Backtrace_HEADER "${_Backtrace_HEADER_TRY}" CACHE STRING "Header providing backtrace(3) facility")
|
||||
|
||||
find_package_handle_standard_args(Backtrace FOUND_VAR Backtrace_FOUND REQUIRED_VARS ${_Backtrace_STD_ARGS})
|
||||
mark_as_advanced(Backtrace_HEADER Backtrace_INCLUDE_DIR Backtrace_LIBRARY)
|
||||
611
cmake/modules/FindPackageHandleStandardArgs.cmake
Normal file
611
cmake/modules/FindPackageHandleStandardArgs.cmake
Normal file
@@ -0,0 +1,611 @@
|
||||
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
# file Copyright.txt or https://cmake.org/licensing for details.
|
||||
|
||||
#[=======================================================================[.rst:
|
||||
FindPackageHandleStandardArgs
|
||||
-----------------------------
|
||||
|
||||
This module provides functions intended to be used in :ref:`Find Modules`
|
||||
implementing :command:`find_package(<PackageName>)` calls.
|
||||
|
||||
.. command:: find_package_handle_standard_args
|
||||
|
||||
This command handles the ``REQUIRED``, ``QUIET`` and version-related
|
||||
arguments of :command:`find_package`. It also sets the
|
||||
``<PackageName>_FOUND`` variable. The package is considered found if all
|
||||
variables listed contain valid results, e.g. valid filepaths.
|
||||
|
||||
There are two signatures:
|
||||
|
||||
.. code-block:: cmake
|
||||
|
||||
find_package_handle_standard_args(<PackageName>
|
||||
(DEFAULT_MSG|<custom-failure-message>)
|
||||
<required-var>...
|
||||
)
|
||||
|
||||
find_package_handle_standard_args(<PackageName>
|
||||
[FOUND_VAR <result-var>]
|
||||
[REQUIRED_VARS <required-var>...]
|
||||
[VERSION_VAR <version-var>]
|
||||
[HANDLE_VERSION_RANGE]
|
||||
[HANDLE_COMPONENTS]
|
||||
[CONFIG_MODE]
|
||||
[NAME_MISMATCHED]
|
||||
[REASON_FAILURE_MESSAGE <reason-failure-message>]
|
||||
[FAIL_MESSAGE <custom-failure-message>]
|
||||
)
|
||||
|
||||
The ``<PackageName>_FOUND`` variable will be set to ``TRUE`` if all
|
||||
the variables ``<required-var>...`` are valid and any optional
|
||||
constraints are satisfied, and ``FALSE`` otherwise. A success or
|
||||
failure message may be displayed based on the results and on
|
||||
whether the ``REQUIRED`` and/or ``QUIET`` option was given to
|
||||
the :command:`find_package` call.
|
||||
|
||||
The options are:
|
||||
|
||||
``(DEFAULT_MSG|<custom-failure-message>)``
|
||||
In the simple signature this specifies the failure message.
|
||||
Use ``DEFAULT_MSG`` to ask for a default message to be computed
|
||||
(recommended). Not valid in the full signature.
|
||||
|
||||
``FOUND_VAR <result-var>``
|
||||
.. deprecated:: 3.3
|
||||
|
||||
Specifies either ``<PackageName>_FOUND`` or
|
||||
``<PACKAGENAME>_FOUND`` as the result variable. This exists only
|
||||
for compatibility with older versions of CMake and is now ignored.
|
||||
Result variables of both names are always set for compatibility.
|
||||
|
||||
``REQUIRED_VARS <required-var>...``
|
||||
Specify the variables which are required for this package.
|
||||
These may be named in the generated failure message asking the
|
||||
user to set the missing variable values. Therefore these should
|
||||
typically be cache entries such as ``FOO_LIBRARY`` and not output
|
||||
variables like ``FOO_LIBRARIES``.
|
||||
|
||||
.. versionchanged:: 3.18
|
||||
If ``HANDLE_COMPONENTS`` is specified, this option can be omitted.
|
||||
|
||||
``VERSION_VAR <version-var>``
|
||||
Specify the name of a variable that holds the version of the package
|
||||
that has been found. This version will be checked against the
|
||||
(potentially) specified required version given to the
|
||||
:command:`find_package` call, including its ``EXACT`` option.
|
||||
The default messages include information about the required
|
||||
version and the version which has been actually found, both
|
||||
if the version is ok or not.
|
||||
|
||||
``HANDLE_VERSION_RANGE``
|
||||
.. versionadded:: 3.19
|
||||
|
||||
Enable handling of a version range, if one is specified. Without this
|
||||
option, a developer warning will be displayed if a version range is
|
||||
specified.
|
||||
|
||||
``HANDLE_COMPONENTS``
|
||||
Enable handling of package components. In this case, the command
|
||||
will report which components have been found and which are missing,
|
||||
and the ``<PackageName>_FOUND`` variable will be set to ``FALSE``
|
||||
if any of the required components (i.e. not the ones listed after
|
||||
the ``OPTIONAL_COMPONENTS`` option of :command:`find_package`) are
|
||||
missing.
|
||||
|
||||
``CONFIG_MODE``
|
||||
Specify that the calling find module is a wrapper around a
|
||||
call to ``find_package(<PackageName> NO_MODULE)``. This implies
|
||||
a ``VERSION_VAR`` value of ``<PackageName>_VERSION``. The command
|
||||
will automatically check whether the package configuration file
|
||||
was found.
|
||||
|
||||
``REASON_FAILURE_MESSAGE <reason-failure-message>``
|
||||
.. versionadded:: 3.16
|
||||
|
||||
Specify a custom message of the reason for the failure which will be
|
||||
appended to the default generated message.
|
||||
|
||||
``FAIL_MESSAGE <custom-failure-message>``
|
||||
Specify a custom failure message instead of using the default
|
||||
generated message. Not recommended.
|
||||
|
||||
``NAME_MISMATCHED``
|
||||
.. versionadded:: 3.17
|
||||
|
||||
Indicate that the ``<PackageName>`` does not match
|
||||
``${CMAKE_FIND_PACKAGE_NAME}``. This is usually a mistake and raises a
|
||||
warning, but it may be intentional for usage of the command for components
|
||||
of a larger package.
|
||||
|
||||
Example for the simple signature:
|
||||
|
||||
.. code-block:: cmake
|
||||
|
||||
find_package_handle_standard_args(LibXml2 DEFAULT_MSG
|
||||
LIBXML2_LIBRARY LIBXML2_INCLUDE_DIR)
|
||||
|
||||
The ``LibXml2`` package is considered to be found if both
|
||||
``LIBXML2_LIBRARY`` and ``LIBXML2_INCLUDE_DIR`` are valid.
|
||||
Then also ``LibXml2_FOUND`` is set to ``TRUE``. If it is not found
|
||||
and ``REQUIRED`` was used, it fails with a
|
||||
:command:`message(FATAL_ERROR)`, independent whether ``QUIET`` was
|
||||
used or not. If it is found, success will be reported, including
|
||||
the content of the first ``<required-var>``. On repeated CMake runs,
|
||||
the same message will not be printed again.
|
||||
|
||||
.. note::
|
||||
|
||||
If ``<PackageName>`` does not match ``CMAKE_FIND_PACKAGE_NAME`` for the
|
||||
calling module, a warning that there is a mismatch is given. The
|
||||
``FPHSA_NAME_MISMATCHED`` variable may be set to bypass the warning if using
|
||||
the old signature and the ``NAME_MISMATCHED`` argument using the new
|
||||
signature. To avoid forcing the caller to require newer versions of CMake for
|
||||
usage, the variable's value will be used if defined when the
|
||||
``NAME_MISMATCHED`` argument is not passed for the new signature (but using
|
||||
both is an error)..
|
||||
|
||||
Example for the full signature:
|
||||
|
||||
.. code-block:: cmake
|
||||
|
||||
find_package_handle_standard_args(LibArchive
|
||||
REQUIRED_VARS LibArchive_LIBRARY LibArchive_INCLUDE_DIR
|
||||
VERSION_VAR LibArchive_VERSION)
|
||||
|
||||
In this case, the ``LibArchive`` package is considered to be found if
|
||||
both ``LibArchive_LIBRARY`` and ``LibArchive_INCLUDE_DIR`` are valid.
|
||||
Also the version of ``LibArchive`` will be checked by using the version
|
||||
contained in ``LibArchive_VERSION``. Since no ``FAIL_MESSAGE`` is given,
|
||||
the default messages will be printed.
|
||||
|
||||
Another example for the full signature:
|
||||
|
||||
.. code-block:: cmake
|
||||
|
||||
find_package(Automoc4 QUIET NO_MODULE HINTS /opt/automoc4)
|
||||
find_package_handle_standard_args(Automoc4 CONFIG_MODE)
|
||||
|
||||
In this case, a ``FindAutmoc4.cmake`` module wraps a call to
|
||||
``find_package(Automoc4 NO_MODULE)`` and adds an additional search
|
||||
directory for ``automoc4``. Then the call to
|
||||
``find_package_handle_standard_args`` produces a proper success/failure
|
||||
message.
|
||||
|
||||
.. command:: find_package_check_version
|
||||
|
||||
.. versionadded:: 3.19
|
||||
|
||||
Helper function which can be used to check if a ``<version>`` is valid
|
||||
against version-related arguments of :command:`find_package`.
|
||||
|
||||
.. code-block:: cmake
|
||||
|
||||
find_package_check_version(<version> <result-var>
|
||||
[HANDLE_VERSION_RANGE]
|
||||
[RESULT_MESSAGE_VARIABLE <message-var>]
|
||||
)
|
||||
|
||||
The ``<result-var>`` will hold a boolean value giving the result of the check.
|
||||
|
||||
The options are:
|
||||
|
||||
``HANDLE_VERSION_RANGE``
|
||||
Enable handling of a version range, if one is specified. Without this
|
||||
option, a developer warning will be displayed if a version range is
|
||||
specified.
|
||||
|
||||
``RESULT_MESSAGE_VARIABLE <message-var>``
|
||||
Specify a variable to get back a message describing the result of the check.
|
||||
|
||||
Example for the usage:
|
||||
|
||||
.. code-block:: cmake
|
||||
|
||||
find_package_check_version(1.2.3 result HANDLE_VERSION_RANGE
|
||||
RESULT_MESSAGE_VARIABLE reason)
|
||||
if (result)
|
||||
message (STATUS "${reason}")
|
||||
else()
|
||||
message (FATAL_ERROR "${reason}")
|
||||
endif()
|
||||
#]=======================================================================]
|
||||
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/FindPackageMessage.cmake)
|
||||
|
||||
|
||||
cmake_policy(PUSH)
|
||||
# numbers and boolean constants
|
||||
cmake_policy (SET CMP0012 NEW)
|
||||
# IN_LIST operator
|
||||
cmake_policy (SET CMP0057 NEW)
|
||||
|
||||
|
||||
# internal helper macro
|
||||
macro(_FPHSA_FAILURE_MESSAGE _msg)
|
||||
set (__msg "${_msg}")
|
||||
if (FPHSA_REASON_FAILURE_MESSAGE)
|
||||
string(APPEND __msg "\n Reason given by package: ${FPHSA_REASON_FAILURE_MESSAGE}\n")
|
||||
endif()
|
||||
if (${_NAME}_FIND_REQUIRED)
|
||||
message(FATAL_ERROR "${__msg}")
|
||||
else ()
|
||||
if (NOT ${_NAME}_FIND_QUIETLY)
|
||||
message(STATUS "${__msg}")
|
||||
endif ()
|
||||
endif ()
|
||||
endmacro()
|
||||
|
||||
|
||||
# internal helper macro to generate the failure message when used in CONFIG_MODE:
|
||||
macro(_FPHSA_HANDLE_FAILURE_CONFIG_MODE)
|
||||
# <PackageName>_CONFIG is set, but FOUND is false, this means that some other of the REQUIRED_VARS was not found:
|
||||
if(${_NAME}_CONFIG)
|
||||
_FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE}: missing:${MISSING_VARS} (found ${${_NAME}_CONFIG} ${VERSION_MSG})")
|
||||
else()
|
||||
# If _CONSIDERED_CONFIGS is set, the config-file has been found, but no suitable version.
|
||||
# List them all in the error message:
|
||||
if(${_NAME}_CONSIDERED_CONFIGS)
|
||||
set(configsText "")
|
||||
list(LENGTH ${_NAME}_CONSIDERED_CONFIGS configsCount)
|
||||
math(EXPR configsCount "${configsCount} - 1")
|
||||
foreach(currentConfigIndex RANGE ${configsCount})
|
||||
list(GET ${_NAME}_CONSIDERED_CONFIGS ${currentConfigIndex} filename)
|
||||
list(GET ${_NAME}_CONSIDERED_VERSIONS ${currentConfigIndex} version)
|
||||
string(APPEND configsText "\n ${filename} (version ${version})")
|
||||
endforeach()
|
||||
if (${_NAME}_NOT_FOUND_MESSAGE)
|
||||
if (FPHSA_REASON_FAILURE_MESSAGE)
|
||||
string(PREPEND FPHSA_REASON_FAILURE_MESSAGE "${${_NAME}_NOT_FOUND_MESSAGE}\n ")
|
||||
else()
|
||||
set(FPHSA_REASON_FAILURE_MESSAGE "${${_NAME}_NOT_FOUND_MESSAGE}")
|
||||
endif()
|
||||
else()
|
||||
string(APPEND configsText "\n")
|
||||
endif()
|
||||
_FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE} ${VERSION_MSG}, checked the following files:${configsText}")
|
||||
|
||||
else()
|
||||
# Simple case: No Config-file was found at all:
|
||||
_FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE}: found neither ${_NAME}Config.cmake nor ${_NAME_LOWER}-config.cmake ${VERSION_MSG}")
|
||||
endif()
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
|
||||
function(FIND_PACKAGE_CHECK_VERSION version result)
|
||||
cmake_parse_arguments (PARSE_ARGV 2 FPCV "HANDLE_VERSION_RANGE;NO_AUTHOR_WARNING_VERSION_RANGE" "RESULT_MESSAGE_VARIABLE" "")
|
||||
|
||||
if (FPCV_UNPARSED_ARGUMENTS)
|
||||
message (FATAL_ERROR "find_package_check_version(): ${FPCV_UNPARSED_ARGUMENTS}: unexpected arguments")
|
||||
endif()
|
||||
if ("RESULT_MESSAGE_VARIABLE" IN_LIST FPCV_KEYWORDS_MISSING_VALUES)
|
||||
message (FATAL_ERROR "find_package_check_version(): RESULT_MESSAGE_VARIABLE expects an argument")
|
||||
endif()
|
||||
|
||||
set (${result} FALSE PARENT_SCOPE)
|
||||
if (FPCV_RESULT_MESSAGE_VARIABLE)
|
||||
unset (${FPCV_RESULT_MESSAGE_VARIABLE} PARENT_SCOPE)
|
||||
endif()
|
||||
|
||||
if (_CMAKE_FPHSA_PACKAGE_NAME)
|
||||
set (package "${_CMAKE_FPHSA_PACKAGE_NAME}")
|
||||
elseif (CMAKE_FIND_PACKAGE_NAME)
|
||||
set (package "${CMAKE_FIND_PACKAGE_NAME}")
|
||||
else()
|
||||
message (FATAL_ERROR "find_package_check_version(): Cannot be used outside a 'Find Module'")
|
||||
endif()
|
||||
|
||||
if (NOT FPCV_NO_AUTHOR_WARNING_VERSION_RANGE
|
||||
AND ${package}_FIND_VERSION_RANGE AND NOT FPCV_HANDLE_VERSION_RANGE)
|
||||
message(AUTHOR_WARNING
|
||||
"`find_package()` specify a version range but the option "
|
||||
"HANDLE_VERSION_RANGE` is not passed to `find_package_check_version()`. "
|
||||
"Only the lower endpoint of the range will be used.")
|
||||
endif()
|
||||
|
||||
|
||||
set (version_ok FALSE)
|
||||
unset (version_msg)
|
||||
|
||||
if (FPCV_HANDLE_VERSION_RANGE AND ${package}_FIND_VERSION_RANGE)
|
||||
if ((${package}_FIND_VERSION_RANGE_MIN STREQUAL "INCLUDE"
|
||||
AND version VERSION_GREATER_EQUAL ${package}_FIND_VERSION_MIN)
|
||||
AND ((${package}_FIND_VERSION_RANGE_MAX STREQUAL "INCLUDE"
|
||||
AND version VERSION_LESS_EQUAL ${package}_FIND_VERSION_MAX)
|
||||
OR (${package}_FIND_VERSION_RANGE_MAX STREQUAL "EXCLUDE"
|
||||
AND version VERSION_LESS ${package}_FIND_VERSION_MAX)))
|
||||
set (version_ok TRUE)
|
||||
set(version_msg "(found suitable version \"${version}\", required range is \"${${package}_FIND_VERSION_RANGE}\")")
|
||||
else()
|
||||
set(version_msg "Found unsuitable version \"${version}\", required range is \"${${package}_FIND_VERSION_RANGE}\"")
|
||||
endif()
|
||||
elseif (DEFINED ${package}_FIND_VERSION)
|
||||
if(${package}_FIND_VERSION_EXACT) # exact version required
|
||||
# count the dots in the version string
|
||||
string(REGEX REPLACE "[^.]" "" version_dots "${version}")
|
||||
# add one dot because there is one dot more than there are components
|
||||
string(LENGTH "${version_dots}." version_dots)
|
||||
if (version_dots GREATER ${package}_FIND_VERSION_COUNT)
|
||||
# Because of the C++ implementation of find_package() ${package}_FIND_VERSION_COUNT
|
||||
# is at most 4 here. Therefore a simple lookup table is used.
|
||||
if (${package}_FIND_VERSION_COUNT EQUAL 1)
|
||||
set(version_regex "[^.]*")
|
||||
elseif (${package}_FIND_VERSION_COUNT EQUAL 2)
|
||||
set(version_regex "[^.]*\\.[^.]*")
|
||||
elseif (${package}_FIND_VERSION_COUNT EQUAL 3)
|
||||
set(version_regex "[^.]*\\.[^.]*\\.[^.]*")
|
||||
else()
|
||||
set(version_regex "[^.]*\\.[^.]*\\.[^.]*\\.[^.]*")
|
||||
endif()
|
||||
string(REGEX REPLACE "^(${version_regex})\\..*" "\\1" version_head "${version}")
|
||||
if (NOT ${package}_FIND_VERSION VERSION_EQUAL version_head)
|
||||
set(version_msg "Found unsuitable version \"${version}\", but required is exact version \"${${package}_FIND_VERSION}\"")
|
||||
else ()
|
||||
set(version_ok TRUE)
|
||||
set(version_msg "(found suitable exact version \"${_FOUND_VERSION}\")")
|
||||
endif ()
|
||||
else ()
|
||||
if (NOT ${package}_FIND_VERSION VERSION_EQUAL version)
|
||||
set(version_msg "Found unsuitable version \"${version}\", but required is exact version \"${${package}_FIND_VERSION}\"")
|
||||
else ()
|
||||
set(version_ok TRUE)
|
||||
set(version_msg "(found suitable exact version \"${version}\")")
|
||||
endif ()
|
||||
endif ()
|
||||
else() # minimum version
|
||||
if (${package}_FIND_VERSION VERSION_GREATER version)
|
||||
set(version_msg "Found unsuitable version \"${version}\", but required is at least \"${${package}_FIND_VERSION}\"")
|
||||
else()
|
||||
set(version_ok TRUE)
|
||||
set(version_msg "(found suitable version \"${version}\", minimum required is \"${${package}_FIND_VERSION}\")")
|
||||
endif()
|
||||
endif()
|
||||
else ()
|
||||
set(version_ok TRUE)
|
||||
set(version_msg "(found version \"${version}\")")
|
||||
endif()
|
||||
|
||||
set (${result} ${version_ok} PARENT_SCOPE)
|
||||
if (FPCV_RESULT_MESSAGE_VARIABLE)
|
||||
set (${FPCV_RESULT_MESSAGE_VARIABLE} "${version_msg}" PARENT_SCOPE)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
|
||||
function(FIND_PACKAGE_HANDLE_STANDARD_ARGS _NAME _FIRST_ARG)
|
||||
|
||||
# Set up the arguments for `cmake_parse_arguments`.
|
||||
set(options CONFIG_MODE HANDLE_COMPONENTS NAME_MISMATCHED HANDLE_VERSION_RANGE)
|
||||
set(oneValueArgs FAIL_MESSAGE REASON_FAILURE_MESSAGE VERSION_VAR FOUND_VAR)
|
||||
set(multiValueArgs REQUIRED_VARS)
|
||||
|
||||
# Check whether we are in 'simple' or 'extended' mode:
|
||||
set(_KEYWORDS_FOR_EXTENDED_MODE ${options} ${oneValueArgs} ${multiValueArgs} )
|
||||
list(FIND _KEYWORDS_FOR_EXTENDED_MODE "${_FIRST_ARG}" INDEX)
|
||||
|
||||
unset(FPHSA_NAME_MISMATCHED_override)
|
||||
if (DEFINED FPHSA_NAME_MISMATCHED)
|
||||
# If the variable NAME_MISMATCHED variable is set, error if it is passed as
|
||||
# an argument. The former is for old signatures, the latter is for new
|
||||
# signatures.
|
||||
list(FIND ARGN "NAME_MISMATCHED" name_mismatched_idx)
|
||||
if (NOT name_mismatched_idx EQUAL "-1")
|
||||
message(FATAL_ERROR
|
||||
"The `NAME_MISMATCHED` argument may only be specified by the argument or "
|
||||
"the variable, not both.")
|
||||
endif ()
|
||||
|
||||
# But use the variable if it is not an argument to avoid forcing minimum
|
||||
# CMake version bumps for calling modules.
|
||||
set(FPHSA_NAME_MISMATCHED_override "${FPHSA_NAME_MISMATCHED}")
|
||||
endif ()
|
||||
|
||||
if(${INDEX} EQUAL -1)
|
||||
set(FPHSA_FAIL_MESSAGE ${_FIRST_ARG})
|
||||
set(FPHSA_REQUIRED_VARS ${ARGN})
|
||||
set(FPHSA_VERSION_VAR)
|
||||
else()
|
||||
cmake_parse_arguments(FPHSA "${options}" "${oneValueArgs}" "${multiValueArgs}" ${_FIRST_ARG} ${ARGN})
|
||||
|
||||
if(FPHSA_UNPARSED_ARGUMENTS)
|
||||
message(FATAL_ERROR "Unknown keywords given to FIND_PACKAGE_HANDLE_STANDARD_ARGS(): \"${FPHSA_UNPARSED_ARGUMENTS}\"")
|
||||
endif()
|
||||
|
||||
if(NOT FPHSA_FAIL_MESSAGE)
|
||||
set(FPHSA_FAIL_MESSAGE "DEFAULT_MSG")
|
||||
endif()
|
||||
|
||||
# In config-mode, we rely on the variable <PackageName>_CONFIG, which is set by find_package()
|
||||
# when it successfully found the config-file, including version checking:
|
||||
if(FPHSA_CONFIG_MODE)
|
||||
list(INSERT FPHSA_REQUIRED_VARS 0 ${_NAME}_CONFIG)
|
||||
list(REMOVE_DUPLICATES FPHSA_REQUIRED_VARS)
|
||||
set(FPHSA_VERSION_VAR ${_NAME}_VERSION)
|
||||
endif()
|
||||
|
||||
if(NOT FPHSA_REQUIRED_VARS AND NOT FPHSA_HANDLE_COMPONENTS)
|
||||
message(FATAL_ERROR "No REQUIRED_VARS specified for FIND_PACKAGE_HANDLE_STANDARD_ARGS()")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if (DEFINED FPHSA_NAME_MISMATCHED_override)
|
||||
set(FPHSA_NAME_MISMATCHED "${FPHSA_NAME_MISMATCHED_override}")
|
||||
endif ()
|
||||
|
||||
if (DEFINED CMAKE_FIND_PACKAGE_NAME
|
||||
AND NOT FPHSA_NAME_MISMATCHED
|
||||
AND NOT _NAME STREQUAL CMAKE_FIND_PACKAGE_NAME)
|
||||
message(AUTHOR_WARNING
|
||||
"The package name passed to `find_package_handle_standard_args` "
|
||||
"(${_NAME}) does not match the name of the calling package "
|
||||
"(${CMAKE_FIND_PACKAGE_NAME}). This can lead to problems in calling "
|
||||
"code that expects `find_package` result variables (e.g., `_FOUND`) "
|
||||
"to follow a certain pattern.")
|
||||
endif ()
|
||||
|
||||
if (${_NAME}_FIND_VERSION_RANGE AND NOT FPHSA_HANDLE_VERSION_RANGE)
|
||||
message(AUTHOR_WARNING
|
||||
"`find_package()` specify a version range but the module ${_NAME} does "
|
||||
"not support this capability. Only the lower endpoint of the range "
|
||||
"will be used.")
|
||||
endif()
|
||||
|
||||
# to propagate package name to FIND_PACKAGE_CHECK_VERSION
|
||||
set(_CMAKE_FPHSA_PACKAGE_NAME "${_NAME}")
|
||||
|
||||
# now that we collected all arguments, process them
|
||||
|
||||
if("x${FPHSA_FAIL_MESSAGE}" STREQUAL "xDEFAULT_MSG")
|
||||
set(FPHSA_FAIL_MESSAGE "Could NOT find ${_NAME}")
|
||||
endif()
|
||||
|
||||
if (FPHSA_REQUIRED_VARS)
|
||||
list(GET FPHSA_REQUIRED_VARS 0 _FIRST_REQUIRED_VAR)
|
||||
endif()
|
||||
|
||||
string(TOUPPER ${_NAME} _NAME_UPPER)
|
||||
string(TOLOWER ${_NAME} _NAME_LOWER)
|
||||
|
||||
if(FPHSA_FOUND_VAR)
|
||||
set(_FOUND_VAR_UPPER ${_NAME_UPPER}_FOUND)
|
||||
set(_FOUND_VAR_MIXED ${_NAME}_FOUND)
|
||||
if(FPHSA_FOUND_VAR STREQUAL _FOUND_VAR_MIXED OR FPHSA_FOUND_VAR STREQUAL _FOUND_VAR_UPPER)
|
||||
set(_FOUND_VAR ${FPHSA_FOUND_VAR})
|
||||
else()
|
||||
message(FATAL_ERROR "The argument for FOUND_VAR is \"${FPHSA_FOUND_VAR}\", but only \"${_FOUND_VAR_MIXED}\" and \"${_FOUND_VAR_UPPER}\" are valid names.")
|
||||
endif()
|
||||
else()
|
||||
set(_FOUND_VAR ${_NAME_UPPER}_FOUND)
|
||||
endif()
|
||||
|
||||
# collect all variables which were not found, so they can be printed, so the
|
||||
# user knows better what went wrong (#6375)
|
||||
set(MISSING_VARS "")
|
||||
set(DETAILS "")
|
||||
# check if all passed variables are valid
|
||||
set(FPHSA_FOUND_${_NAME} TRUE)
|
||||
foreach(_CURRENT_VAR ${FPHSA_REQUIRED_VARS})
|
||||
if(NOT ${_CURRENT_VAR})
|
||||
set(FPHSA_FOUND_${_NAME} FALSE)
|
||||
string(APPEND MISSING_VARS " ${_CURRENT_VAR}")
|
||||
else()
|
||||
string(APPEND DETAILS "[${${_CURRENT_VAR}}]")
|
||||
endif()
|
||||
endforeach()
|
||||
if(FPHSA_FOUND_${_NAME})
|
||||
set(${_NAME}_FOUND TRUE)
|
||||
set(${_NAME_UPPER}_FOUND TRUE)
|
||||
else()
|
||||
set(${_NAME}_FOUND FALSE)
|
||||
set(${_NAME_UPPER}_FOUND FALSE)
|
||||
endif()
|
||||
|
||||
# component handling
|
||||
unset(FOUND_COMPONENTS_MSG)
|
||||
unset(MISSING_COMPONENTS_MSG)
|
||||
|
||||
if(FPHSA_HANDLE_COMPONENTS)
|
||||
foreach(comp ${${_NAME}_FIND_COMPONENTS})
|
||||
if(${_NAME}_${comp}_FOUND)
|
||||
|
||||
if(NOT DEFINED FOUND_COMPONENTS_MSG)
|
||||
set(FOUND_COMPONENTS_MSG "found components:")
|
||||
endif()
|
||||
string(APPEND FOUND_COMPONENTS_MSG " ${comp}")
|
||||
|
||||
else()
|
||||
|
||||
if(NOT DEFINED MISSING_COMPONENTS_MSG)
|
||||
set(MISSING_COMPONENTS_MSG "missing components:")
|
||||
endif()
|
||||
string(APPEND MISSING_COMPONENTS_MSG " ${comp}")
|
||||
|
||||
if(${_NAME}_FIND_REQUIRED_${comp})
|
||||
set(${_NAME}_FOUND FALSE)
|
||||
string(APPEND MISSING_VARS " ${comp}")
|
||||
endif()
|
||||
|
||||
endif()
|
||||
endforeach()
|
||||
set(COMPONENT_MSG "${FOUND_COMPONENTS_MSG} ${MISSING_COMPONENTS_MSG}")
|
||||
string(APPEND DETAILS "[c${COMPONENT_MSG}]")
|
||||
endif()
|
||||
|
||||
# version handling:
|
||||
set(VERSION_MSG "")
|
||||
set(VERSION_OK TRUE)
|
||||
|
||||
# check that the version variable is not empty to avoid emitting a misleading
|
||||
# message (i.e. `Found unsuitable version ""`)
|
||||
if (DEFINED ${_NAME}_FIND_VERSION)
|
||||
if(DEFINED ${FPHSA_VERSION_VAR})
|
||||
if(NOT "${${FPHSA_VERSION_VAR}}" STREQUAL "")
|
||||
set(_FOUND_VERSION ${${FPHSA_VERSION_VAR}})
|
||||
if (FPHSA_HANDLE_VERSION_RANGE)
|
||||
set (FPCV_HANDLE_VERSION_RANGE HANDLE_VERSION_RANGE)
|
||||
else()
|
||||
set(FPCV_HANDLE_VERSION_RANGE NO_AUTHOR_WARNING_VERSION_RANGE)
|
||||
endif()
|
||||
find_package_check_version ("${_FOUND_VERSION}" VERSION_OK RESULT_MESSAGE_VARIABLE VERSION_MSG
|
||||
${FPCV_HANDLE_VERSION_RANGE})
|
||||
else()
|
||||
set(VERSION_OK FALSE)
|
||||
endif()
|
||||
endif()
|
||||
if("${${FPHSA_VERSION_VAR}}" STREQUAL "")
|
||||
# if the package was not found, but a version was given, add that to the output:
|
||||
if(${_NAME}_FIND_VERSION_EXACT)
|
||||
set(VERSION_MSG "(Required is exact version \"${${_NAME}_FIND_VERSION}\")")
|
||||
elseif (FPHSA_HANDLE_VERSION_RANGE AND ${_NAME}_FIND_VERSION_RANGE)
|
||||
set(VERSION_MSG "(Required is version range \"${${_NAME}_FIND_VERSION_RANGE}\")")
|
||||
else()
|
||||
set(VERSION_MSG "(Required is at least version \"${${_NAME}_FIND_VERSION}\")")
|
||||
endif()
|
||||
endif()
|
||||
else ()
|
||||
# Check with DEFINED as the found version may be 0.
|
||||
if(DEFINED ${FPHSA_VERSION_VAR})
|
||||
set(VERSION_MSG "(found version \"${${FPHSA_VERSION_VAR}}\")")
|
||||
endif()
|
||||
endif ()
|
||||
|
||||
if(VERSION_OK)
|
||||
string(APPEND DETAILS "[v${${FPHSA_VERSION_VAR}}(${${_NAME}_FIND_VERSION})]")
|
||||
else()
|
||||
set(${_NAME}_FOUND FALSE)
|
||||
endif()
|
||||
|
||||
|
||||
# print the result:
|
||||
if (${_NAME}_FOUND)
|
||||
FIND_PACKAGE_MESSAGE(${_NAME} "Found ${_NAME}: ${${_FIRST_REQUIRED_VAR}} ${VERSION_MSG} ${COMPONENT_MSG}" "${DETAILS}")
|
||||
else ()
|
||||
|
||||
if(FPHSA_CONFIG_MODE)
|
||||
_FPHSA_HANDLE_FAILURE_CONFIG_MODE()
|
||||
else()
|
||||
if(NOT VERSION_OK)
|
||||
set(RESULT_MSG)
|
||||
if (_FIRST_REQUIRED_VAR)
|
||||
string (APPEND RESULT_MSG "found ${${_FIRST_REQUIRED_VAR}}")
|
||||
endif()
|
||||
if (COMPONENT_MSG)
|
||||
if (RESULT_MSG)
|
||||
string (APPEND RESULT_MSG ", ")
|
||||
endif()
|
||||
string (APPEND RESULT_MSG "${FOUND_COMPONENTS_MSG}")
|
||||
endif()
|
||||
_FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE}: ${VERSION_MSG} (${RESULT_MSG})")
|
||||
else()
|
||||
_FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE} (missing:${MISSING_VARS}) ${VERSION_MSG}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
endif ()
|
||||
|
||||
set(${_NAME}_FOUND ${${_NAME}_FOUND} PARENT_SCOPE)
|
||||
set(${_NAME_UPPER}_FOUND ${${_NAME}_FOUND} PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
|
||||
cmake_policy(POP)
|
||||
48
cmake/modules/FindPackageMessage.cmake
Normal file
48
cmake/modules/FindPackageMessage.cmake
Normal file
@@ -0,0 +1,48 @@
|
||||
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
# file Copyright.txt or https://cmake.org/licensing for details.
|
||||
|
||||
#[=======================================================================[.rst:
|
||||
FindPackageMessage
|
||||
------------------
|
||||
|
||||
.. code-block:: cmake
|
||||
|
||||
find_package_message(<name> "message for user" "find result details")
|
||||
|
||||
This function is intended to be used in FindXXX.cmake modules files.
|
||||
It will print a message once for each unique find result. This is
|
||||
useful for telling the user where a package was found. The first
|
||||
argument specifies the name (XXX) of the package. The second argument
|
||||
specifies the message to display. The third argument lists details
|
||||
about the find result so that if they change the message will be
|
||||
displayed again. The macro also obeys the QUIET argument to the
|
||||
find_package command.
|
||||
|
||||
Example:
|
||||
|
||||
.. code-block:: cmake
|
||||
|
||||
if(X11_FOUND)
|
||||
find_package_message(X11 "Found X11: ${X11_X11_LIB}"
|
||||
"[${X11_X11_LIB}][${X11_INCLUDE_DIR}]")
|
||||
else()
|
||||
...
|
||||
endif()
|
||||
#]=======================================================================]
|
||||
|
||||
function(find_package_message pkg msg details)
|
||||
# Avoid printing a message repeatedly for the same find result.
|
||||
if(NOT ${pkg}_FIND_QUIETLY)
|
||||
string(REPLACE "\n" "" details "${details}")
|
||||
set(DETAILS_VAR FIND_PACKAGE_MESSAGE_DETAILS_${pkg})
|
||||
if(NOT "${details}" STREQUAL "${${DETAILS_VAR}}")
|
||||
# The message has not yet been printed.
|
||||
message(STATUS "${msg}")
|
||||
|
||||
# Save the find details in the cache to avoid printing the same
|
||||
# message again.
|
||||
set("${DETAILS_VAR}" "${details}"
|
||||
CACHE INTERNAL "Details about finding ${pkg}")
|
||||
endif()
|
||||
endif()
|
||||
endfunction()
|
||||
@@ -46,7 +46,7 @@ endfunction()
|
||||
|
||||
include(BundleUtilities)
|
||||
set(BU_CHMOD_BUNDLE_ITEMS ON)
|
||||
fixup_bundle("${BUNDLE_PATH}" "${extra_libs}" "${extra_dirs}" IGNORE_ITEM "Python")
|
||||
fixup_bundle("${BUNDLE_PATH}" "${extra_libs}" "${extra_dirs}")
|
||||
|
||||
if (CODE_SIGN_CERTIFICATE_ID)
|
||||
# Hack around Apple Silicon signing bugs by copying the real app, signing it and moving it back.
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
set (CPACK_BUNDLE_NAME "ImHex")
|
||||
set (CPACK_BUNDLE_ICON "${CMAKE_SOURCE_DIR}/resources/AppIcon.icns" )
|
||||
set (CPACK_BUNDLE_PLIST "${CMAKE_BINARY_DIR}/ImHex.app/Contents/Info.plist")
|
||||
6
dist/AppImageBuilder.yml
vendored
6
dist/AppImageBuilder.yml
vendored
@@ -6,7 +6,7 @@ AppDir:
|
||||
id: imhex
|
||||
name: ImHex
|
||||
icon: imhex
|
||||
version: AppImage
|
||||
version: "{{VERSION}}"
|
||||
exec: usr/bin/imhex
|
||||
exec_args: $@
|
||||
apt:
|
||||
@@ -107,7 +107,6 @@ AppDir:
|
||||
- /lib/x86_64-linux-gnu/libpcre2-8.so.0
|
||||
- /lib/x86_64-linux-gnu/libpixman-1.so.0
|
||||
- /lib/x86_64-linux-gnu/libpng16.so.16
|
||||
- /lib/x86_64-linux-gnu/libpython3.10.so.1.0
|
||||
- /lib/x86_64-linux-gnu/libsasl2.so.2
|
||||
- /lib/x86_64-linux-gnu/libsensors.so.5
|
||||
- /lib/x86_64-linux-gnu/libstdc++.so.6
|
||||
@@ -136,4 +135,5 @@ AppDir:
|
||||
- usr/share/doc/*/TODO.*
|
||||
AppImage:
|
||||
arch: x86_64
|
||||
update-information: guess
|
||||
update-information: gh-releases-zsync|WerWolv|ImHex|latest|imhex-*-x86_64.AppImage.zsync
|
||||
file_name: imhex-{{VERSION}}-x86_64.AppImage
|
||||
|
||||
35
dist/Arch/PKGBUILD
vendored
35
dist/Arch/PKGBUILD
vendored
@@ -1,40 +1,29 @@
|
||||
# Maintainer: iTrooz_ <itrooz at protonmail dot com>
|
||||
# Contributor: Morten Linderud <foxboron@archlinux.org>
|
||||
|
||||
pkgname=imhex-bin
|
||||
pkgver=%version%
|
||||
pkgrel=1
|
||||
pkgdesc="A Hex Editor for Reverse Engineers, Programmers and people who value their retinas when working at 3 AM. "
|
||||
arch=("x86_64")
|
||||
url="https://github.com/WerWolv/ImHex"
|
||||
repo=$url
|
||||
license=('GPL 2.0')
|
||||
groups=()
|
||||
depends=(glfw mbedtls python freetype2 libglvnd dbus xdg-desktop-portal curl fmt yara nlohmann-json)
|
||||
license=('GPL2')
|
||||
depends=(glfw mbedtls freetype2 libglvnd dbus xdg-desktop-portal curl fmt yara nlohmann-json)
|
||||
makedepends=(git)
|
||||
checkdepends=()
|
||||
optdepends=()
|
||||
provides=(imhex)
|
||||
conflicts=(imhex)
|
||||
replaces=()
|
||||
backup=()
|
||||
options=()
|
||||
source=($repo"/releases/download/v$pkgver/imhex-$pkgver-ArchLinux.pkg.tar.zst")
|
||||
noextract=()
|
||||
source=("$url/releases/download/v$pkgver/imhex-$pkgver-ArchLinux-x86_64.pkg.tar.zst")
|
||||
md5sums=(SKIP)
|
||||
validpgpkeys=()
|
||||
|
||||
package() {
|
||||
tar -xf imhex-$pkgver-ArchLinux.pkg.tar.zst
|
||||
install -Dm755 "$srcdir/usr/bin/imhex" "$pkgdir/usr/bin/imhex"
|
||||
install -Dm644 "$srcdir/usr/lib/libimhex.so.$pkgver" "$pkgdir/usr/lib/libimhex.so.$pkgver"
|
||||
|
||||
install -DT $srcdir/usr/bin/imhex $pkgdir/usr/bin/imhex
|
||||
install -DT $srcdir/usr/lib/libimhex.so.$pkgver $pkgdir/usr/lib/libimhex.so.$pkgver
|
||||
|
||||
for plugin in $srcdir/usr/lib/imhex/plugins/*.hexplug;
|
||||
do
|
||||
install -DT $plugin $pkgdir/usr/lib/imhex/plugins/`basename $plugin`
|
||||
for plugin in "$srcdir/usr/lib/imhex/plugins/"*.hexplug; do
|
||||
install -Dm644 "$plugin" "$pkgdir/usr/lib/imhex/plugins/${plugin##*/}"
|
||||
done
|
||||
|
||||
mkdir -p $pkgdir/usr/share/imhex
|
||||
cp -r $srcdir/usr/share/imhex/{constants,encodings,includes,magic,patterns} $pkgdir/usr/share/imhex
|
||||
cp -r $srcdir/usr/share/{applications,licenses} $pkgdir/usr/share
|
||||
install -d $pkgdir/usr/share
|
||||
install -d "$pkgdir/usr/share/imhex"
|
||||
cp -r "$srcdir/usr/share/imhex/"{constants,encodings,includes,magic,patterns} "$pkgdir/usr/share/imhex"
|
||||
cp -r "$srcdir/usr/share/"{applications,licenses} "$pkgdir/usr/share"
|
||||
}
|
||||
|
||||
4
dist/Brewfile
vendored
4
dist/Brewfile
vendored
@@ -1,10 +1,10 @@
|
||||
brew "glfw"
|
||||
brew "mbedtls"
|
||||
brew "nlohmann-json"
|
||||
brew "cmake"
|
||||
brew "ccache"
|
||||
brew "python3"
|
||||
brew "freetype2"
|
||||
brew "libmagic"
|
||||
brew "pkg-config"
|
||||
brew "gcc@12"
|
||||
brew "llvm"
|
||||
brew "glfw"
|
||||
|
||||
2
dist/DEBIAN/control.in
vendored
2
dist/DEBIAN/control.in
vendored
@@ -4,7 +4,7 @@ Section: editors
|
||||
Priority: optional
|
||||
Architecture: amd64
|
||||
License: GNU GPL-2
|
||||
Depends: libglfw3, libmagic1, libmbedtls14, libpython3.10, libfreetype6, libopengl0, libdbus-1-3, xdg-desktop-portal
|
||||
Depends: libglfw3, libmagic1, libmbedtls14, libfreetype6, libopengl0, libdbus-1-3, xdg-desktop-portal
|
||||
Maintainer: WerWolv <hey@werwolv.net>
|
||||
Description: ImHex Hex Editor
|
||||
A Hex Editor for Reverse Engineers, Programmers and
|
||||
|
||||
5
dist/Dockerfile
vendored
5
dist/Dockerfile
vendored
@@ -1,6 +1,6 @@
|
||||
FROM archlinux:latest
|
||||
|
||||
MAINTAINER WerWolv "hey@werwolv.net"
|
||||
LABEL maintainer="hey@werwolv.net" = WerWolv
|
||||
|
||||
# Install dependencies
|
||||
RUN pacman -Syy --needed --noconfirm
|
||||
@@ -13,7 +13,6 @@ RUN pacman -S --needed --noconfirm \
|
||||
glfw-x11 \
|
||||
file \
|
||||
mbedtls \
|
||||
python3 \
|
||||
freetype2 \
|
||||
dbus \
|
||||
xdg-desktop-portal
|
||||
@@ -25,4 +24,4 @@ RUN git clone https://github.com/WerWolv/ImHex --recurse-submodules /root/ImHex
|
||||
RUN mkdir /root/ImHex/build
|
||||
WORKDIR /root/ImHex/build
|
||||
RUN cmake .. && make -j
|
||||
WORKDIR /root/ImHex
|
||||
WORKDIR /root/ImHex
|
||||
|
||||
7
dist/ImHex-9999.ebuild
vendored
7
dist/ImHex-9999.ebuild
vendored
@@ -9,20 +9,15 @@ HOMEPAGE="https://github.com/WerWolv/ImHex"
|
||||
SRC_URI=""
|
||||
EGIT_REPO_URI="https://github.com/WerWolv/ImHex.git"
|
||||
|
||||
PYTHON_COMPAT=( python3_{6,7,8,9} )
|
||||
|
||||
inherit git-r3 python-single-r1 cmake
|
||||
inherit git-r3 cmake
|
||||
|
||||
LICENSE="GPL-2"
|
||||
SLOT="0"
|
||||
KEYWORDS="~amd64"
|
||||
IUSE=""
|
||||
|
||||
REQUIRED_USE="${PYTHON_REQUIRED_USE}"
|
||||
|
||||
DEPEND=""
|
||||
RDEPEND="${DEPEND}
|
||||
${PYTHON_DEPS}
|
||||
media-libs/glfw
|
||||
sys-apps/file
|
||||
dev-libs/mbedtls
|
||||
|
||||
24
dist/compiling/linux.md
vendored
24
dist/compiling/linux.md
vendored
@@ -1,9 +1,12 @@
|
||||
### Compiling ImHex on Linux
|
||||
|
||||
Dependency installation scripts are available for many common Linux distributions in the [/dist](dist) folder.
|
||||
After all the dependencies are installed, run the following commands to build ImHex:
|
||||
On Linux, ImHex is built through regular GCC (or optionally Clang).
|
||||
|
||||
1. Clone the repo using `git clone https://github.com/WerWolv/ImHex --recurse-submodules`
|
||||
2. Install the dependencies using one of the `dist/get_deps_*.sh` scripts. Choose the one that matches your distro.
|
||||
3. Build ImHex itself using the following commands:
|
||||
```sh
|
||||
cd ImHex
|
||||
mkdir -p build
|
||||
cd build
|
||||
CC=gcc-12 CXX=g++-12 cmake \
|
||||
@@ -15,27 +18,10 @@ CC=gcc-12 CXX=g++-12 cmake \
|
||||
-DCMAKE_CXX_FLAGS="-fuse-ld=lld" \
|
||||
-DCMAKE_OBJC_COMPILER_LAUNCHER=ccache \
|
||||
-DCMAKE_OBJCXX_COMPILER_LAUNCHER=ccache \
|
||||
-DRUST_PATH="$HOME/.cargo/bin/" \
|
||||
..
|
||||
make -j 4 install
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
Put the ImHex executable into the `/usr/bin` folder.
|
||||
Put libimhex.so into the `/usr/lib` folder.
|
||||
Configuration files go to `/usr/etc/imhex` or `~/.config/imhex`.
|
||||
All other files belong in `/usr/share/imhex` or `~/.local/share/imhex`:
|
||||
|
||||
```
|
||||
Patterns: /usr/share/imhex/patterns
|
||||
Pattern Includes: /usr/share/imhex/includes
|
||||
Magic files: /usr/share/imhex/magic
|
||||
Python: /usr/share/imhex/lib/pythonX.X
|
||||
Plugins: /usr/share/imhex/plugins
|
||||
Configuration: /etc/xdg/imhex/config
|
||||
```
|
||||
|
||||
All paths follow the XDG Base Directories standard, and can thus be modified
|
||||
with the environment variables `XDG_CONFIG_HOME`, `XDG_CONFIG_DIRS`,
|
||||
`XDG_DATA_HOME` and `XDG_DATA_DIRS`.
|
||||
@@ -1,9 +1,12 @@
|
||||
### Compiling ImHex on macOS
|
||||
|
||||
To build ImHex on macOS, run the following commands:
|
||||
On macOS, ImHex is built through regular GCC and AppleClang.
|
||||
|
||||
1. Clone the repo using `git clone https://github.com/WerWolv/ImHex --recurse-submodules`
|
||||
2. Install all the dependencies using `brew bundle --no-lock --file dist/Brewfile`
|
||||
3. Build ImHex itself using the following commands:
|
||||
```sh
|
||||
brew bundle --no-lock --file dist/Brewfile
|
||||
cd ImHex
|
||||
mkdir -p build
|
||||
cd build
|
||||
CC=$(brew --prefix gcc@12)/bin/gcc-12 \
|
||||
@@ -13,7 +16,7 @@ OBJCXX=$(brew --prefix llvm)/bin/clang++ \
|
||||
PKG_CONFIG_PATH="$(brew --prefix openssl)/lib/pkgconfig":"$(brew --prefix)/lib/pkgconfig" \
|
||||
MACOSX_DEPLOYMENT_TARGET="10.15" \
|
||||
cmake \
|
||||
-DCMAKE_BUILD_TYPE=$BUILD_TYPE \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DCREATE_BUNDLE=ON \
|
||||
-DCREATE_PACKAGE=ON \
|
||||
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
|
||||
@@ -24,18 +27,6 @@ cmake \
|
||||
make -j4 package
|
||||
```
|
||||
|
||||
Open the generated .dmg file and drag-n-drop the ImHex executable to the Applications folder
|
||||
|
||||
All other files belong in `~/Library/Application Support/imhex`:
|
||||
```
|
||||
Patterns: ~/Library/Application Support/imhex/patterns
|
||||
Pattern Includes: ~/Library/Application Support/imhex/includes
|
||||
Magic files: ~/Library/Application Support/imhex/magic
|
||||
Python: ~/Library/Application Support/imhex/lib/pythonX.X
|
||||
Plugins: ~/Library/Application Support/imhex/plugins
|
||||
Configuration: ~/Library/Application Support/imhex/config
|
||||
```
|
||||
|
||||
If the build fails while trying to find the macOS libraries, make sure you have
|
||||
XCode installed with `xcode-select --install`. Homebrew will also help get the
|
||||
most recent SDK installed and configured with `brew doctor`.
|
||||
Xcode installed with `xcode-select --install`. Homebrew will also help get the
|
||||
most recent SDK installed and configured with `brew doctor`.
|
||||
9
dist/compiling/windows.md
vendored
9
dist/compiling/windows.md
vendored
@@ -1,9 +1,14 @@
|
||||
### Compiling ImHex on Windows
|
||||
|
||||
On Windows, ImHex is built through msys2 / mingw. To install all dependencies, open a msys2 window and run the PKGCONFIG script in the [dist/msys2](dist/msys2) folder.
|
||||
After all the dependencies are installed, run the following commands to build ImHex:
|
||||
On Windows, ImHex is built through [msys2 / mingw](https://www.msys2.org/)'s gcc.
|
||||
|
||||
1. Download and install msys2 from their [website](https://www.msys2.org/).
|
||||
2. Open the `MSYS2 MinGW x64` shell
|
||||
3. Clone the repo using `git clone https://github.com/WerWolv/ImHex --recurse-submodules`
|
||||
4. Install all the dependencies using `./ImHex/dist/get_deps_msys2.sh`
|
||||
5. Build ImHex itself using the following commands:
|
||||
```sh
|
||||
cd ImHex
|
||||
mkdir build
|
||||
cd build
|
||||
cmake -G "MinGW Makefiles" \
|
||||
|
||||
1
dist/get_deps_archlinux.sh
vendored
1
dist/get_deps_archlinux.sh
vendored
@@ -7,7 +7,6 @@ pacman -S $@ --needed \
|
||||
glfw \
|
||||
file \
|
||||
mbedtls \
|
||||
python3 \
|
||||
freetype2 \
|
||||
dbus \
|
||||
xdg-desktop-portal \
|
||||
|
||||
1
dist/get_deps_debian.sh
vendored
1
dist/get_deps_debian.sh
vendored
@@ -19,7 +19,6 @@ apt install -y \
|
||||
libglm-dev \
|
||||
libmagic-dev \
|
||||
libmbedtls-dev \
|
||||
python3-dev \
|
||||
libfreetype-dev \
|
||||
libdbus-1-dev \
|
||||
xdg-desktop-portal
|
||||
|
||||
3
dist/get_deps_fedora.sh
vendored
3
dist/get_deps_fedora.sh
vendored
@@ -10,5 +10,4 @@ dnf install -y \
|
||||
mesa-libGL-devel \
|
||||
glfw-devel \
|
||||
lld \
|
||||
mbedtls-devel \
|
||||
python3-devel
|
||||
mbedtls-devel
|
||||
1
dist/get_deps_msys2.sh
vendored
1
dist/get_deps_msys2.sh
vendored
@@ -9,6 +9,5 @@ pacman -S --needed --noconfirm \
|
||||
mingw-w64-x86_64-glfw \
|
||||
mingw-w64-x86_64-file \
|
||||
mingw-w64-x86_64-mbedtls \
|
||||
mingw-w64-x86_64-python \
|
||||
mingw-w64-x86_64-freetype \
|
||||
mingw-w64-x86_64-dlfcn
|
||||
|
||||
104
dist/langtool.py
vendored
Normal file
104
dist/langtool.py
vendored
Normal file
@@ -0,0 +1,104 @@
|
||||
from pathlib import Path
|
||||
import sys
|
||||
import json
|
||||
|
||||
DEFAULT_LANG = "en_US"
|
||||
INVALID_TRANSLATION = ""
|
||||
|
||||
|
||||
def handle_missing_key(command, lang_data, key, value):
|
||||
if command == "check":
|
||||
print(f"Error: Translation {lang_data['code']} is missing translation for key '{key}'")
|
||||
exit(2)
|
||||
elif command == "translate" or command == "create":
|
||||
print(f"Key \033[1m'{key}': '{value}'\033[0m is missing in translation '{lang_data['code']}'")
|
||||
new_value = input("Enter translation: ")
|
||||
lang_data["translations"][key] = new_value
|
||||
elif command == "update":
|
||||
lang_data["translations"][key] = INVALID_TRANSLATION
|
||||
|
||||
|
||||
def main():
|
||||
if len(sys.argv) < 3:
|
||||
print(f"Usage: {Path(sys.argv[0]).name} <check|translate|update|create> <lang folder path> <language>")
|
||||
return 1
|
||||
|
||||
command = sys.argv[1]
|
||||
if command not in ["check", "translate", "update", "create"]:
|
||||
print(f"Unknown command: {command}")
|
||||
return 1
|
||||
|
||||
print(f"Using langtool in {command} mode")
|
||||
|
||||
lang_folder_path = Path(sys.argv[2])
|
||||
if not lang_folder_path.exists():
|
||||
print(f"Error: {lang_folder_path} does not exist")
|
||||
return 1
|
||||
|
||||
if not lang_folder_path.is_dir():
|
||||
print(f"Error: {lang_folder_path} is not a folder")
|
||||
return 1
|
||||
|
||||
lang = sys.argv[3] if len(sys.argv) > 3 else ""
|
||||
|
||||
print(f"Processing language files in {lang_folder_path}...")
|
||||
|
||||
default_lang_file_path = lang_folder_path / Path(DEFAULT_LANG + ".json")
|
||||
if not default_lang_file_path.exists():
|
||||
print(f"Error: Default language file {default_lang_file_path} does not exist")
|
||||
return 1
|
||||
|
||||
print(f"Using file '{default_lang_file_path.name}' as template language file")
|
||||
|
||||
with default_lang_file_path.open("r", encoding="utf-8") as default_lang_file:
|
||||
default_lang_data = json.load(default_lang_file)
|
||||
|
||||
if command == "create" and lang != "":
|
||||
lang_file_path = lang_folder_path / Path(lang + ".json")
|
||||
if lang_file_path.exists():
|
||||
print(f"Error: Language file {lang_file_path} already exists")
|
||||
return 1
|
||||
|
||||
print(f"Creating new language file '{lang_file_path.name}'")
|
||||
|
||||
with lang_file_path.open("w", encoding="utf-8") as new_lang_file:
|
||||
new_lang_data = {
|
||||
"code": lang,
|
||||
"language": input("Enter language: "),
|
||||
"country": input("Enter country: "),
|
||||
"translations": {}
|
||||
}
|
||||
json.dump(new_lang_data, new_lang_file, indent=4, ensure_ascii=False)
|
||||
|
||||
for additional_lang_file_path in lang_folder_path.glob("*.json"):
|
||||
if not lang == "" and not additional_lang_file_path.stem == lang:
|
||||
continue
|
||||
|
||||
if additional_lang_file_path.name.startswith(DEFAULT_LANG):
|
||||
continue
|
||||
|
||||
print(f"\nProcessing file '{additional_lang_file_path.name}'\n----------------------------\n")
|
||||
|
||||
with additional_lang_file_path.open("r+", encoding="utf-8") as additional_lang_file:
|
||||
additional_lang_data = json.load(additional_lang_file)
|
||||
|
||||
for key, value in default_lang_data["translations"].items():
|
||||
if key not in additional_lang_data["translations"] or additional_lang_data["translations"][key] == INVALID_TRANSLATION:
|
||||
handle_missing_key(command, additional_lang_data, key, value)
|
||||
|
||||
keys_to_remove = []
|
||||
for key, value in additional_lang_data["translations"].items():
|
||||
if key not in default_lang_data["translations"]:
|
||||
keys_to_remove.append(key)
|
||||
|
||||
for key in keys_to_remove:
|
||||
additional_lang_data["translations"].pop(key)
|
||||
print(f"Removed unused key '{key}' from translation '{additional_lang_data['code']}'")
|
||||
|
||||
additional_lang_file.seek(0)
|
||||
additional_lang_file.truncate()
|
||||
json.dump(additional_lang_data, additional_lang_file, indent=4, sort_keys=True, ensure_ascii=False)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
exit(main())
|
||||
25
dist/macOS/0001-glfw-SW.patch
vendored
Normal file
25
dist/macOS/0001-glfw-SW.patch
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
From 9c8665af4c2e2ce66555c15c05c72027bfdf0cb6 Mon Sep 17 00:00:00 2001
|
||||
From: iTrooz <itrooz@protonmail.com>
|
||||
Date: Mon, 29 Aug 2022 17:29:38 +0200
|
||||
Subject: [PATCH] Use software rendering on MacOS
|
||||
|
||||
---
|
||||
src/nsgl_context.m | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/nsgl_context.m b/src/nsgl_context.m
|
||||
index fc1f7521..e5906575 100644
|
||||
--- a/src/nsgl_context.m
|
||||
+++ b/src/nsgl_context.m
|
||||
@@ -198,7 +198,7 @@ GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window,
|
||||
NSOpenGLPixelFormatAttribute attribs[40];
|
||||
int index = 0;
|
||||
|
||||
- ADD_ATTRIB(NSOpenGLPFAAccelerated);
|
||||
+ ADD_ATTRIB(NSOpenGLPFARendererID);ADD_ATTRIB(kCGLRendererGenericFloatID);
|
||||
ADD_ATTRIB(NSOpenGLPFAClosestPolicy);
|
||||
|
||||
if (ctxconfig->nsgl.offline)
|
||||
--
|
||||
2.37.2
|
||||
|
||||
2
dist/msys2/PKGBUILD
vendored
2
dist/msys2/PKGBUILD
vendored
@@ -7,7 +7,6 @@ pkgdesc="${_realname}: a Hex Editor for Reverse Engineers, Programmers and peopl
|
||||
arch=('any')
|
||||
url="https://github.com/WerWolv/ImHex"
|
||||
license=('GPLv2')
|
||||
depends=("${MINGW_PACKAGE_PREFIX}-python")
|
||||
makedepends=("${MINGW_PACKAGE_PREFIX}-gcc"
|
||||
"${MINGW_PACKAGE_PREFIX}-lld"
|
||||
"${MINGW_PACKAGE_PREFIX}-cmake"
|
||||
@@ -17,7 +16,6 @@ makedepends=("${MINGW_PACKAGE_PREFIX}-gcc"
|
||||
"${MINGW_PACKAGE_PREFIX}-file"
|
||||
"${MINGW_PACKAGE_PREFIX}-mbedtls"
|
||||
"${MINGW_PACKAGE_PREFIX}-polly"
|
||||
"${MINGW_PACKAGE_PREFIX}-python"
|
||||
"${MINGW_PACKAGE_PREFIX}-freetype")
|
||||
|
||||
source=()
|
||||
|
||||
34
dist/net.werwolv.imhex.metainfo.xml
vendored
Normal file
34
dist/net.werwolv.imhex.metainfo.xml
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<component type="desktop-application">
|
||||
<id>imhex</id>
|
||||
<metadata_license>CC0-1.0</metadata_license>
|
||||
<project_license>GPL-2.0</project_license>
|
||||
<name>ImHex</name>
|
||||
<developer_name>WerWolv</developer_name>
|
||||
<update_contact>hey@werwolv.net</update_contact>
|
||||
<summary>A Hex Editor for Reverse Engineers, Programmers and people who value their retinas when working at 3 AM</summary>
|
||||
<description>
|
||||
<p>ImHex is a feature-rich Hex Editor aimed towards Reverse Engineers working with foreign data formats, malware, executables and raw memory.
|
||||
Besides all the features a common Hex Editor has, ImHex also features a custom scripting language used to declare and dissect data structures, support for running YARA rules, a node-based graphical data pre-processor and support for various data sources such as files, raw disks or GDB Servers.</p>
|
||||
</description>
|
||||
<launchable type="desktop-id">imhex.desktop</launchable>
|
||||
<url type="homepage">https://imhex.werwolv.net</url>
|
||||
<screenshots>
|
||||
<screenshot type="default">
|
||||
<image>https://user-images.githubusercontent.com/10835354/139717326-8044769d-527b-4d88-8adf-2d4ecafdca1f.png</image>
|
||||
</screenshot>
|
||||
<screenshot>
|
||||
<image>https://user-images.githubusercontent.com/10835354/139717323-1f8c9d52-f7eb-4f43-9f11-097ac728ed6c.png</image>
|
||||
</screenshot>
|
||||
</screenshots>
|
||||
|
||||
<provides>
|
||||
<id>imhex.desktop</id>
|
||||
</provides>
|
||||
|
||||
<categories>
|
||||
<category>Development</category>
|
||||
</categories>
|
||||
|
||||
|
||||
</component>
|
||||
117
dist/rpm/imhex.spec
vendored
117
dist/rpm/imhex.spec
vendored
@@ -1,13 +1,14 @@
|
||||
# ftbfs without this
|
||||
%global _lto_cflags %{nil}
|
||||
|
||||
Name: ImHex
|
||||
Version: %{_version}
|
||||
Name: imhex
|
||||
Version: 1.26.2
|
||||
Release: 0%{?dist}
|
||||
Summary: A hex editor for reverse engineers and programmers
|
||||
|
||||
License: GPL-2.0-only
|
||||
License: GPL-2.0-only AND Zlib AND MIT AND Apache-2.0
|
||||
# imhex is gplv2. capstone is custom. nativefiledialog is Zlib. intervaltree is MIT
|
||||
# see license dir for full breakdown
|
||||
URL: https://imhex.werwolv.net/
|
||||
# We need the archive with deps bundled
|
||||
Source0: https://github.com/WerWolv/%{name}/releases/download/v%{version}/Full.Sources.tar.gz#/%{name}-%{version}.tar.gz
|
||||
|
||||
BuildRequires: cmake
|
||||
BuildRequires: desktop-file-utils
|
||||
@@ -16,17 +17,36 @@ BuildRequires: file-devel
|
||||
BuildRequires: freetype-devel
|
||||
BuildRequires: fmt-devel
|
||||
BuildRequires: gcc-c++
|
||||
BuildRequires: mesa-libGL-devel
|
||||
BuildRequires: libappstream-glib
|
||||
BuildRequires: libglvnd-devel
|
||||
BuildRequires: glfw-devel
|
||||
BuildRequires: json-devel
|
||||
BuildRequires: libcurl-devel
|
||||
BuildRequires: llvm-devel
|
||||
BuildRequires: mbedtls-devel
|
||||
BuildRequires: python3-devel
|
||||
%if 0%{?fedora} >= 37
|
||||
BuildRequires: yara-devel
|
||||
BuildRequires: nativefiledialog-extended-devel
|
||||
%if 0%{?rhel}
|
||||
BuildRequires: gcc-toolset-12
|
||||
%endif
|
||||
|
||||
Provides: bundled(gnulib)
|
||||
Provides: bundled(capstone) = 5.0-rc2
|
||||
Provides: bundled(imgui)
|
||||
Provides: bundled(libromfs)
|
||||
Provides: bundled(microtar)
|
||||
Provides: bundled(libpl)
|
||||
# ImHex modified upstream intervaltree so we have to package it
|
||||
# https://github.com/ekg/intervaltree
|
||||
Provides: bundled(intervaltree) = 0.1
|
||||
Provides: bundled(xdgpp)
|
||||
|
||||
# ftbfs on these arches. armv7hl might compile when capstone 5.x
|
||||
# is released upstream and we can build against it
|
||||
# [7:02 PM] WerWolv: We're not supporting 32 bit anyways soooo
|
||||
# [11:38 AM] WerWolv: Officially supported are x86_64 and aarch64
|
||||
ExclusiveArch: x86_64 %{arm64} ppc64le
|
||||
|
||||
|
||||
%description
|
||||
ImHex is a Hex Editor, a tool to display, decode and analyze binary data to
|
||||
@@ -41,26 +61,26 @@ same time ImHex is completely free and open source under the GPLv2 language.
|
||||
|
||||
|
||||
%prep
|
||||
# don't use the setup macro since we're pulling from git
|
||||
cp -r %{_src_path}/* %{_builddir}/
|
||||
|
||||
%autosetup -n ImHex
|
||||
# remove bundled libs we aren't using
|
||||
rm -rf lib/external/{curl,fmt,llvm,nlohmann_json,yara}
|
||||
|
||||
%build
|
||||
%cmake \
|
||||
-DCMAKE_BUILD_TYPE=%{_build_type} \
|
||||
-D USE_SYSTEM_NLOHMANN_JSON=ON \
|
||||
-D USE_SYSTEM_FMT=ON \
|
||||
-D USE_SYSTEM_CURL=ON \
|
||||
-D USE_SYSTEM_LLVM=ON \
|
||||
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
|
||||
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
|
||||
-D IMHEX_PATTERNS_PULL_MASTER=ON \
|
||||
%if 0%{?fedora} >= 37
|
||||
-D USE_SYSTEM_YARA=ON \
|
||||
# if fedora <= 36 get updated to yara 4.2.x then they should \
|
||||
# be able to build against system libs \
|
||||
# https://bugzilla.redhat.com/show_bug.cgi?id=2112508 \
|
||||
%if 0%{?rhel}
|
||||
. /opt/rh/gcc-toolset-12/enable
|
||||
%set_build_flags
|
||||
CXXFLAGS+=" -std=gnu++2b"
|
||||
%endif
|
||||
%cmake \
|
||||
-D CMAKE_BUILD_TYPE=Release \
|
||||
-D IMHEX_STRIP_RELEASE=OFF \
|
||||
-D IMHEX_OFFLINE_BUILD=ON \
|
||||
-D USE_SYSTEM_NLOHMANN_JSON=ON \
|
||||
-D USE_SYSTEM_FMT=ON \
|
||||
-D USE_SYSTEM_CURL=ON \
|
||||
-D USE_SYSTEM_LLVM=ON \
|
||||
-D USE_SYSTEM_YARA=ON \
|
||||
-D USE_SYSTEM_NFD=ON \
|
||||
# when capstone >= 5.x is released we should be able to build against \
|
||||
# system libs of it \
|
||||
# -D USE_SYSTEM_CAPSTONE=ON
|
||||
@@ -68,21 +88,48 @@ cp -r %{_src_path}/* %{_builddir}/
|
||||
%cmake_build
|
||||
|
||||
|
||||
%check
|
||||
%if 0%{?rhel}
|
||||
. /opt/rh/gcc-toolset-12/enable
|
||||
%set_build_flags
|
||||
CXXFLAGS+=" -std=gnu++2b"
|
||||
%endif
|
||||
# build binaries required for tests
|
||||
%cmake_build --target unit_tests
|
||||
%ctest --exclude-regex '(Helpers/StoreAPI|Helpers/TipsAPI|Helpers/ContentAPI)'
|
||||
# Helpers/*API exclude tests that require network access
|
||||
|
||||
|
||||
%install
|
||||
%cmake_install
|
||||
desktop-file-validate %{buildroot}%{_datadir}/applications/imhex.desktop
|
||||
desktop-file-validate %{buildroot}%{_datadir}/applications/%{name}.desktop
|
||||
|
||||
# this is a symlink for the old appdata name that we don't need
|
||||
rm -f %{buildroot}%{_metainfodir}/net.werwolv.%{name}.appdata.xml
|
||||
|
||||
# AppData
|
||||
appstream-util validate-relax --nonet %{buildroot}%{_metainfodir}/net.werwolv.%{name}.metainfo.xml
|
||||
|
||||
# install licenses
|
||||
cp -a lib/external/nativefiledialog/LICENSE %{buildroot}%{_datadir}/licenses/%{name}/nativefiledialog-LICENSE
|
||||
cp -a lib/external/capstone/LICENSE.TXT %{buildroot}%{_datadir}/licenses/%{name}/capstone-LICENSE
|
||||
cp -a lib/external/capstone/suite/regress/LICENSE %{buildroot}%{_datadir}/licenses/%{name}/capstone-regress-LICENSE
|
||||
cp -a lib/external/microtar/LICENSE %{buildroot}%{_datadir}/licenses/%{name}/microtar-LICENSE
|
||||
cp -a lib/external/pattern_language/external/intervaltree/LICENSE %{buildroot}%{_datadir}/licenses/%{name}/pattern-language-intervaltree-LICENSE
|
||||
cp -a lib/external/xdgpp/LICENSE %{buildroot}%{_datadir}/licenses/%{name}/xdgpp-LICENSE
|
||||
|
||||
|
||||
%files
|
||||
%dir %{_datadir}/licenses/imhex
|
||||
%license %{_datadir}/licenses/imhex/LICENSE
|
||||
%license %{_datadir}/licenses/%{name}/
|
||||
%doc README.md
|
||||
%{_bindir}/imhex
|
||||
%dir %{_datadir}/imhex
|
||||
%{_datadir}/imhex/*
|
||||
%{_datadir}/pixmaps/imhex.png
|
||||
%{_datadir}/applications/imhex.desktop
|
||||
%{_prefix}/lib64/libimhex.so.%{_version}
|
||||
%{_prefix}/lib64/imhex/plugins/*
|
||||
%{_datadir}/pixmaps/%{name}.png
|
||||
%{_datadir}/applications/%{name}.desktop
|
||||
%{_libdir}/libimhex.so*
|
||||
%{_libdir}/%{name}/
|
||||
%{_metainfodir}/net.werwolv.%{name}.metainfo.xml
|
||||
|
||||
|
||||
%changelog
|
||||
* Thu Jan 01 1970 ImHex GitHub CI - 0.0.0-0
|
||||
- Build Package
|
||||
|
||||
2
lib/external/curl
vendored
2
lib/external/curl
vendored
Submodule lib/external/curl updated: 45ac4d0194...c12fb3ddaf
2
lib/external/fmt
vendored
2
lib/external/fmt
vendored
Submodule lib/external/fmt updated: c4ee726532...a33701196a
14
lib/external/imgui/CMakeLists.txt
vendored
14
lib/external/imgui/CMakeLists.txt
vendored
@@ -8,10 +8,6 @@ find_package(Freetype REQUIRED)
|
||||
find_package(OpenGL REQUIRED)
|
||||
pkg_search_module(GLFW REQUIRED glfw3)
|
||||
|
||||
if (UNIX)
|
||||
find_package(OpenGL REQUIRED)
|
||||
endif ()
|
||||
|
||||
add_library(imgui OBJECT
|
||||
source/imgui.cpp
|
||||
source/imgui_demo.cpp
|
||||
@@ -39,12 +35,8 @@ add_library(imgui OBJECT
|
||||
|
||||
add_compile_definitions(IMGUI_IMPL_OPENGL_LOADER_GLAD)
|
||||
|
||||
target_include_directories(imgui PUBLIC include ${FREETYPE_INCLUDE_DIRS} ${GLFW_INCLUDE_DIRS})
|
||||
target_include_directories(imgui PUBLIC include ${FREETYPE_INCLUDE_DIRS} ${GLFW_INCLUDE_DIRS} ${OpenGL_INCLUDE_DIRS})
|
||||
|
||||
target_link_directories(imgui PUBLIC ${GLFW_LIBRARY_DIRS})
|
||||
target_link_directories(imgui PUBLIC ${GLFW_LIBRARY_DIRS} ${OpenGL_LIBRARY_DIRS})
|
||||
|
||||
if (WIN32)
|
||||
target_link_libraries(imgui PUBLIC Freetype::Freetype glfw3 opengl32.lib)
|
||||
elseif (UNIX)
|
||||
target_link_libraries(imgui PUBLIC Freetype::Freetype glfw OpenGL::GL)
|
||||
endif()
|
||||
target_link_libraries(imgui PUBLIC Freetype::Freetype ${GLFW_LIBRARIES} ${OPENGL_LIBRARIES})
|
||||
|
||||
6
lib/external/imgui/include/TextEditor.h
vendored
6
lib/external/imgui/include/TextEditor.h
vendored
@@ -188,8 +188,8 @@ public:
|
||||
void SetLanguageDefinition(const LanguageDefinition& aLanguageDef);
|
||||
const LanguageDefinition& GetLanguageDefinition() const { return mLanguageDefinition; }
|
||||
|
||||
const Palette& GetPalette() const { return mPaletteBase; }
|
||||
void SetPalette(const Palette& aValue);
|
||||
static const Palette& GetPalette() { return sPaletteBase; }
|
||||
static void SetPalette(const Palette& aValue);
|
||||
|
||||
void SetErrorMarkers(const ErrorMarkers& aMarkers) { mErrorMarkers = aMarkers; }
|
||||
void SetBreakpoints(const Breakpoints& aMarkers) { mBreakpoints = aMarkers; }
|
||||
@@ -372,7 +372,7 @@ private:
|
||||
bool mIgnoreImGuiChild;
|
||||
bool mShowWhitespaces;
|
||||
|
||||
Palette mPaletteBase;
|
||||
static Palette sPaletteBase;
|
||||
Palette mPalette;
|
||||
LanguageDefinition mLanguageDefinition;
|
||||
RegexList mRegexList;
|
||||
|
||||
2
lib/external/imgui/include/imconfig.h
vendored
2
lib/external/imgui/include/imconfig.h
vendored
@@ -99,7 +99,7 @@
|
||||
// Your renderer backend will need to support it (most example renderer backends support both 16/32-bit indices).
|
||||
// Another way to allow large meshes while keeping 16-bit indices is to handle ImDrawCmd::VtxOffset in your renderer.
|
||||
// Read about ImGuiBackendFlags_RendererHasVtxOffset for details.
|
||||
//#define ImDrawIdx unsigned int
|
||||
#define ImDrawIdx unsigned int
|
||||
|
||||
//---- Override ImDrawCallback signature (will need to modify renderer backends accordingly)
|
||||
//struct ImDrawList;
|
||||
|
||||
6767
lib/external/imgui/include/imgui_impl_opengl3_loader.h
vendored
6767
lib/external/imgui/include/imgui_impl_opengl3_loader.h
vendored
File diff suppressed because it is too large
Load Diff
23
lib/external/imgui/source/TextEditor.cpp
vendored
23
lib/external/imgui/source/TextEditor.cpp
vendored
@@ -21,9 +21,10 @@ bool equals(InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2, Bi
|
||||
return first1 == last1 && first2 == last2;
|
||||
}
|
||||
|
||||
TextEditor::Palette TextEditor::sPaletteBase = TextEditor::GetDarkPalette();
|
||||
|
||||
TextEditor::TextEditor()
|
||||
: mLineSpacing(1.0f), mUndoIndex(0), mTabSize(4), mOverwrite(false), mReadOnly(false), mWithinRender(false), mScrollToCursor(false), mScrollToTop(false), mTextChanged(false), mColorizerEnabled(true), mTextStart(20.0f), mLeftMargin(10), mCursorPositionChanged(false), mColorRangeMin(0), mColorRangeMax(0), mSelectionMode(SelectionMode::Normal), mCheckComments(true), mLastClick(-1.0f), mHandleKeyboardInputs(true), mHandleMouseInputs(true), mIgnoreImGuiChild(false), mShowWhitespaces(true), mStartTime(std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count()) {
|
||||
SetPalette(GetDarkPalette());
|
||||
SetLanguageDefinition(LanguageDefinition::HLSL());
|
||||
mLines.push_back(Line());
|
||||
}
|
||||
@@ -42,7 +43,7 @@ void TextEditor::SetLanguageDefinition(const LanguageDefinition &aLanguageDef) {
|
||||
}
|
||||
|
||||
void TextEditor::SetPalette(const Palette &aValue) {
|
||||
mPaletteBase = aValue;
|
||||
sPaletteBase = aValue;
|
||||
}
|
||||
|
||||
std::string TextEditor::GetText(const Coordinates &aStart, const Coordinates &aEnd) const {
|
||||
@@ -740,7 +741,7 @@ void TextEditor::Render() {
|
||||
|
||||
/* Update palette with the current alpha from style */
|
||||
for (int i = 0; i < (int)PaletteIndex::Max; ++i) {
|
||||
auto color = ImGui::ColorConvertU32ToFloat4(mPaletteBase[i]);
|
||||
auto color = ImGui::ColorConvertU32ToFloat4(sPaletteBase[i]);
|
||||
color.w *= ImGui::GetStyle().Alpha;
|
||||
mPalette[i] = ImGui::ColorConvertFloat4ToU32(color);
|
||||
}
|
||||
@@ -1095,7 +1096,8 @@ void TextEditor::EnterCharacter(ImWchar aChar, bool aShift) {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
line.insert(line.begin(), Glyph('\t', TextEditor::PaletteIndex::Background));
|
||||
for (int j = start.mColumn % mTabSize; j < mTabSize; j++)
|
||||
line.insert(line.begin(), Glyph(' ', PaletteIndex::Background));
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
@@ -1156,6 +1158,13 @@ void TextEditor::EnterCharacter(ImWchar aChar, bool aShift) {
|
||||
line.erase(line.begin() + cindex, line.begin() + line.size());
|
||||
SetCursorPosition(Coordinates(coord.mLine + 1, GetCharacterColumn(coord.mLine + 1, (int)whitespaceSize)));
|
||||
u.mAdded = (char)aChar;
|
||||
} else if (aChar == '\t') {
|
||||
auto &line = mLines[coord.mLine];
|
||||
auto cindex = GetCharacterIndex(coord);
|
||||
auto spacesToInsert = mTabSize - (cindex % mTabSize);
|
||||
for (int j = 0; j < spacesToInsert; j++)
|
||||
line.insert(line.begin() + cindex, Glyph(' ', PaletteIndex::Background));
|
||||
SetCursorPosition(Coordinates(coord.mLine, GetCharacterColumn(coord.mLine, cindex + spacesToInsert)));
|
||||
} else {
|
||||
char buf[7];
|
||||
int e = ImTextCharToUtf8(buf, 7, aChar);
|
||||
@@ -2032,7 +2041,9 @@ void TextEditor::ColorizeInternal() {
|
||||
}
|
||||
}
|
||||
}
|
||||
line[currentIndex].mPreprocessor = withinPreproc;
|
||||
if (currentIndex < line.size())
|
||||
line[currentIndex].mPreprocessor = withinPreproc;
|
||||
|
||||
currentIndex += UTF8CharLength(c);
|
||||
if (currentIndex >= (int)line.size()) {
|
||||
currentIndex = 0;
|
||||
@@ -2112,7 +2123,7 @@ void TextEditor::EnsureCursorVisible() {
|
||||
if (len + mTextStart < left + 4)
|
||||
ImGui::SetScrollX(std::max(0.0f, len + mTextStart - 4));
|
||||
if (len + mTextStart > right - 4)
|
||||
ImGui::SetScrollX(std::max(0.0f, len + mTextStart + 4 - width));
|
||||
ImGui::SetScrollX(std::max(0.0f, len + mTextStart + 4 - width + mCharAdvance.x * 2));
|
||||
}
|
||||
|
||||
int TextEditor::GetPageSize() const {
|
||||
|
||||
11
lib/external/imgui/source/imgui_impl_glfw.cpp
vendored
11
lib/external/imgui/source/imgui_impl_glfw.cpp
vendored
@@ -164,7 +164,10 @@ static void ImGui_ImplGlfw_ShutdownPlatformInterface();
|
||||
// Functions
|
||||
static const char* ImGui_ImplGlfw_GetClipboardText(void* user_data)
|
||||
{
|
||||
return glfwGetClipboardString((GLFWwindow*)user_data);
|
||||
// IMHEX PATCH BEGIN
|
||||
const char *data = glfwGetClipboardString((GLFWwindow*)user_data);
|
||||
return data == nullptr ? "" : data;
|
||||
// IMHEX PATCH END
|
||||
}
|
||||
|
||||
static void ImGui_ImplGlfw_SetClipboardText(void* user_data, const char* text)
|
||||
@@ -179,12 +182,12 @@ static void ImGui_ImplGlfw_SetClipboardText(void* user_data, const char* text)
|
||||
ImGuiContext& g = *GImGui;
|
||||
g.ClipboardHandlerData.clear();
|
||||
if (!::OpenClipboard(NULL))
|
||||
return NULL;
|
||||
return "";
|
||||
HANDLE wbuf_handle = ::GetClipboardData(CF_UNICODETEXT);
|
||||
if (wbuf_handle == NULL)
|
||||
{
|
||||
::CloseClipboard();
|
||||
return NULL;
|
||||
return "";
|
||||
}
|
||||
if (const WCHAR* wbuf_global = (const WCHAR*)::GlobalLock(wbuf_handle))
|
||||
{
|
||||
@@ -194,7 +197,7 @@ static void ImGui_ImplGlfw_SetClipboardText(void* user_data, const char* text)
|
||||
}
|
||||
::GlobalUnlock(wbuf_handle);
|
||||
::CloseClipboard();
|
||||
return g.ClipboardHandlerData.Data;
|
||||
return g.ClipboardHandlerData.Data == nullptr ? "" : g.ClipboardHandlerData.Data;
|
||||
}
|
||||
|
||||
static void ImGui_ImplWin_SetClipboardText(void*, const char* text)
|
||||
|
||||
9
lib/external/intervaltree/CMakeLists.txt
vendored
Normal file
9
lib/external/intervaltree/CMakeLists.txt
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
project(intervaltree)
|
||||
|
||||
set(CMAKE_CXX_STANDARD20)
|
||||
|
||||
add_library(intervaltree INTERFACE)
|
||||
|
||||
target_include_directories(intervaltree INTERFACE include)
|
||||
target_compile_options(intervaltree INTERFACE "-DUSE_INTERVAL_TREE_NAMESPACE")
|
||||
@@ -1,11 +1,11 @@
|
||||
Copyright (c) 2015-2020 The imgui-rs Developers
|
||||
Copyright (c) 2011 Erik Garrison
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
37
lib/external/intervaltree/README.md
vendored
Normal file
37
lib/external/intervaltree/README.md
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
# intervaltree
|
||||
|
||||
## Overview
|
||||
|
||||
An interval tree can be used to efficiently find a set of numeric intervals overlapping or containing another interval.
|
||||
|
||||
This library provides a basic implementation of an interval tree using C++ templates, allowing the insertion of arbitrary types into the tree.
|
||||
|
||||
## Usage
|
||||
|
||||
Add `#include "IntervalTree.h"` to the source files in which you will use the interval tree.
|
||||
|
||||
To make an IntervalTree to contain objects of class T, use:
|
||||
|
||||
```c++
|
||||
vector<Interval<T> > intervals;
|
||||
T a, b, c;
|
||||
intervals.push_back(Interval<T>(2, 10, a));
|
||||
intervals.push_back(Interval<T>(3, 4, b));
|
||||
intervals.push_back(Interval<T>(20, 100, c));
|
||||
IntervalTree<T> tree;
|
||||
tree = IntervalTree<T>(intervals);
|
||||
```
|
||||
|
||||
Now, it's possible to query the tree and obtain a set of intervals which are contained within the start and stop coordinates.
|
||||
|
||||
```c++
|
||||
vector<Interval<T> > results;
|
||||
tree.findContained(start, stop, results);
|
||||
cout << "found " << results.size() << " overlapping intervals" << endl;
|
||||
```
|
||||
|
||||
The function IntervalTree::findOverlapping provides a method to find all those intervals which are contained or partially overlap the interval (start, stop).
|
||||
|
||||
### Author: Erik Garrison <erik.garrison@gmail.com>
|
||||
|
||||
### License: MIT
|
||||
325
lib/external/intervaltree/include/IntervalTree.h
vendored
Normal file
325
lib/external/intervaltree/include/IntervalTree.h
vendored
Normal file
@@ -0,0 +1,325 @@
|
||||
#ifndef __INTERVAL_TREE_H
|
||||
#define __INTERVAL_TREE_H
|
||||
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <cassert>
|
||||
#include <limits>
|
||||
|
||||
#ifdef USE_INTERVAL_TREE_NAMESPACE
|
||||
namespace interval_tree {
|
||||
#endif
|
||||
template <class Scalar, typename Value>
|
||||
class Interval {
|
||||
public:
|
||||
Scalar start;
|
||||
Scalar stop;
|
||||
Value value;
|
||||
Interval(const Scalar& s, const Scalar& e, const Value& v)
|
||||
: start(std::min(s, e))
|
||||
, stop(std::max(s, e))
|
||||
, value(v)
|
||||
{}
|
||||
};
|
||||
|
||||
template <class Scalar, typename Value>
|
||||
Value intervalStart(const Interval<Scalar,Value>& i) {
|
||||
return i.start;
|
||||
}
|
||||
|
||||
template <class Scalar, typename Value>
|
||||
Value intervalStop(const Interval<Scalar, Value>& i) {
|
||||
return i.stop;
|
||||
}
|
||||
|
||||
template <class Scalar, typename Value>
|
||||
std::ostream& operator<<(std::ostream& out, const Interval<Scalar, Value>& i) {
|
||||
out << "Interval(" << i.start << ", " << i.stop << "): " << i.value;
|
||||
return out;
|
||||
}
|
||||
|
||||
template <class Scalar, class Value>
|
||||
class IntervalTree {
|
||||
public:
|
||||
typedef Interval<Scalar, Value> interval;
|
||||
typedef std::vector<interval> interval_vector;
|
||||
|
||||
|
||||
struct IntervalStartCmp {
|
||||
bool operator()(const interval& a, const interval& b) {
|
||||
return a.start < b.start;
|
||||
}
|
||||
};
|
||||
|
||||
struct IntervalStopCmp {
|
||||
bool operator()(const interval& a, const interval& b) {
|
||||
return a.stop < b.stop;
|
||||
}
|
||||
};
|
||||
|
||||
IntervalTree()
|
||||
: left(nullptr)
|
||||
, right(nullptr)
|
||||
, center(0)
|
||||
{}
|
||||
|
||||
~IntervalTree() = default;
|
||||
|
||||
std::unique_ptr<IntervalTree> clone() const {
|
||||
return std::unique_ptr<IntervalTree>(new IntervalTree(*this));
|
||||
}
|
||||
|
||||
IntervalTree(const IntervalTree& other)
|
||||
: intervals(other.intervals),
|
||||
left(other.left ? other.left->clone() : nullptr),
|
||||
right(other.right ? other.right->clone() : nullptr),
|
||||
center(other.center)
|
||||
{}
|
||||
|
||||
IntervalTree& operator=(IntervalTree&&) = default;
|
||||
IntervalTree(IntervalTree&&) = default;
|
||||
|
||||
IntervalTree& operator=(const IntervalTree& other) {
|
||||
center = other.center;
|
||||
intervals = other.intervals;
|
||||
left = other.left ? other.left->clone() : nullptr;
|
||||
right = other.right ? other.right->clone() : nullptr;
|
||||
return *this;
|
||||
}
|
||||
|
||||
IntervalTree(
|
||||
interval_vector&& ivals,
|
||||
std::size_t depth = 16,
|
||||
std::size_t minbucket = 64,
|
||||
std::size_t maxbucket = 512,
|
||||
Scalar leftextent = 0,
|
||||
Scalar rightextent = 0)
|
||||
: left(nullptr)
|
||||
, right(nullptr)
|
||||
{
|
||||
--depth;
|
||||
const auto minmaxStop = std::minmax_element(ivals.begin(), ivals.end(),
|
||||
IntervalStopCmp());
|
||||
const auto minmaxStart = std::minmax_element(ivals.begin(), ivals.end(),
|
||||
IntervalStartCmp());
|
||||
if (!ivals.empty()) {
|
||||
center = (minmaxStart.first->start + minmaxStop.second->stop) / 2;
|
||||
}
|
||||
if (leftextent == 0 && rightextent == 0) {
|
||||
// sort intervals by start
|
||||
std::sort(ivals.begin(), ivals.end(), IntervalStartCmp());
|
||||
} else {
|
||||
assert(std::is_sorted(ivals.begin(), ivals.end(), IntervalStartCmp()));
|
||||
}
|
||||
if (depth == 0 || (ivals.size() < minbucket && ivals.size() < maxbucket)) {
|
||||
std::sort(ivals.begin(), ivals.end(), IntervalStartCmp());
|
||||
intervals = std::move(ivals);
|
||||
assert(is_valid().first);
|
||||
return;
|
||||
} else {
|
||||
Scalar leftp = 0;
|
||||
Scalar rightp = 0;
|
||||
|
||||
if (leftextent || rightextent) {
|
||||
leftp = leftextent;
|
||||
rightp = rightextent;
|
||||
} else {
|
||||
leftp = ivals.front().start;
|
||||
rightp = std::max_element(ivals.begin(), ivals.end(),
|
||||
IntervalStopCmp())->stop;
|
||||
}
|
||||
|
||||
interval_vector lefts;
|
||||
interval_vector rights;
|
||||
|
||||
for (typename interval_vector::const_iterator i = ivals.begin();
|
||||
i != ivals.end(); ++i) {
|
||||
const interval& interval = *i;
|
||||
if (interval.stop < center) {
|
||||
lefts.push_back(interval);
|
||||
} else if (interval.start > center) {
|
||||
rights.push_back(interval);
|
||||
} else {
|
||||
assert(interval.start <= center);
|
||||
assert(center <= interval.stop);
|
||||
intervals.push_back(interval);
|
||||
}
|
||||
}
|
||||
|
||||
if (!lefts.empty()) {
|
||||
left.reset(new IntervalTree(std::move(lefts),
|
||||
depth, minbucket, maxbucket,
|
||||
leftp, center));
|
||||
}
|
||||
if (!rights.empty()) {
|
||||
right.reset(new IntervalTree(std::move(rights),
|
||||
depth, minbucket, maxbucket,
|
||||
center, rightp));
|
||||
}
|
||||
}
|
||||
assert(is_valid().first);
|
||||
}
|
||||
|
||||
// Call f on all intervals near the range [start, stop]:
|
||||
template <class UnaryFunction>
|
||||
void visit_near(const Scalar& start, const Scalar& stop, UnaryFunction f) const {
|
||||
if (!intervals.empty() && ! (stop < intervals.front().start)) {
|
||||
for (auto & i : intervals) {
|
||||
f(i);
|
||||
}
|
||||
}
|
||||
if (left && start <= center) {
|
||||
left->visit_near(start, stop, f);
|
||||
}
|
||||
if (right && stop >= center) {
|
||||
right->visit_near(start, stop, f);
|
||||
}
|
||||
}
|
||||
|
||||
// Call f on all intervals crossing pos
|
||||
template <class UnaryFunction>
|
||||
void visit_overlapping(const Scalar& pos, UnaryFunction f) const {
|
||||
visit_overlapping(pos, pos, f);
|
||||
}
|
||||
|
||||
// Call f on all intervals overlapping [start, stop]
|
||||
template <class UnaryFunction>
|
||||
void visit_overlapping(const Scalar& start, const Scalar& stop, UnaryFunction f) const {
|
||||
auto filterF = [&](const interval& interval) {
|
||||
if (interval.stop >= start && interval.start <= stop) {
|
||||
// Only apply f if overlapping
|
||||
f(interval);
|
||||
}
|
||||
};
|
||||
visit_near(start, stop, filterF);
|
||||
}
|
||||
|
||||
// Call f on all intervals contained within [start, stop]
|
||||
template <class UnaryFunction>
|
||||
void visit_contained(const Scalar& start, const Scalar& stop, UnaryFunction f) const {
|
||||
auto filterF = [&](const interval& interval) {
|
||||
if (start <= interval.start && interval.stop <= stop) {
|
||||
f(interval);
|
||||
}
|
||||
};
|
||||
visit_near(start, stop, filterF);
|
||||
}
|
||||
|
||||
interval_vector findOverlapping(const Scalar& start, const Scalar& stop) const {
|
||||
interval_vector result;
|
||||
visit_overlapping(start, stop,
|
||||
[&](const interval& interval) {
|
||||
result.emplace_back(interval);
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
interval_vector findContained(const Scalar& start, const Scalar& stop) const {
|
||||
interval_vector result;
|
||||
visit_contained(start, stop,
|
||||
[&](const interval& interval) {
|
||||
result.push_back(interval);
|
||||
});
|
||||
return result;
|
||||
}
|
||||
bool empty() const {
|
||||
if (left && !left->empty()) {
|
||||
return false;
|
||||
}
|
||||
if (!intervals.empty()) {
|
||||
return false;
|
||||
}
|
||||
if (right && !right->empty()) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class UnaryFunction>
|
||||
void visit_all(UnaryFunction f) const {
|
||||
if (left) {
|
||||
left->visit_all(f);
|
||||
}
|
||||
std::for_each(intervals.begin(), intervals.end(), f);
|
||||
if (right) {
|
||||
right->visit_all(f);
|
||||
}
|
||||
}
|
||||
|
||||
std::pair<Scalar, Scalar> extentBruitForce() const {
|
||||
struct Extent {
|
||||
std::pair<Scalar, Scalar> x = {std::numeric_limits<Scalar>::max(),
|
||||
std::numeric_limits<Scalar>::min() };
|
||||
void operator()(const interval & interval) {
|
||||
x.first = std::min(x.first, interval.start);
|
||||
x.second = std::max(x.second, interval.stop);
|
||||
}
|
||||
};
|
||||
Extent extent;
|
||||
|
||||
visit_all([&](const interval & interval) { extent(interval); });
|
||||
return extent.x;
|
||||
}
|
||||
|
||||
// Check all constraints.
|
||||
// If first is false, second is invalid.
|
||||
std::pair<bool, std::pair<Scalar, Scalar>> is_valid() const {
|
||||
const auto minmaxStop = std::minmax_element(intervals.begin(), intervals.end(),
|
||||
IntervalStopCmp());
|
||||
const auto minmaxStart = std::minmax_element(intervals.begin(), intervals.end(),
|
||||
IntervalStartCmp());
|
||||
|
||||
std::pair<bool, std::pair<Scalar, Scalar>> result = {true, { std::numeric_limits<Scalar>::max(),
|
||||
std::numeric_limits<Scalar>::min() }};
|
||||
if (!intervals.empty()) {
|
||||
result.second.first = std::min(result.second.first, minmaxStart.first->start);
|
||||
result.second.second = std::min(result.second.second, minmaxStop.second->stop);
|
||||
}
|
||||
if (left) {
|
||||
auto valid = left->is_valid();
|
||||
result.first &= valid.first;
|
||||
result.second.first = std::min(result.second.first, valid.second.first);
|
||||
result.second.second = std::min(result.second.second, valid.second.second);
|
||||
if (!result.first) { return result; }
|
||||
if (valid.second.second >= center) {
|
||||
result.first = false;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
if (right) {
|
||||
auto valid = right->is_valid();
|
||||
result.first &= valid.first;
|
||||
result.second.first = std::min(result.second.first, valid.second.first);
|
||||
result.second.second = std::min(result.second.second, valid.second.second);
|
||||
if (!result.first) { return result; }
|
||||
if (valid.second.first <= center) {
|
||||
result.first = false;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
if (!std::is_sorted(intervals.begin(), intervals.end(), IntervalStartCmp())) {
|
||||
result.first = false;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void clear() {
|
||||
left.reset();
|
||||
right.reset();
|
||||
intervals.clear();
|
||||
center = 0;
|
||||
}
|
||||
|
||||
private:
|
||||
interval_vector intervals;
|
||||
std::unique_ptr<IntervalTree> left;
|
||||
std::unique_ptr<IntervalTree> right;
|
||||
Scalar center;
|
||||
};
|
||||
#ifdef USE_INTERVAL_TREE_NAMESPACE
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
2
lib/external/libromfs
vendored
2
lib/external/libromfs
vendored
Submodule lib/external/libromfs updated: 58757f6cad...40cd303e92
15
lib/external/llvm-demangle/CMakeLists.txt
vendored
Normal file
15
lib/external/llvm-demangle/CMakeLists.txt
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
project(LLVMDemangle)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
|
||||
add_library(LLVMDemangle STATIC
|
||||
source/Demangle.cpp
|
||||
source/DLangDemangle.cpp
|
||||
source/ItaniumDemangle.cpp
|
||||
source/MicrosoftDemangle.cpp
|
||||
source/MicrosoftDemangleNodes.cpp
|
||||
source/RustDemangle.cpp
|
||||
)
|
||||
|
||||
target_include_directories(LLVMDemangle PUBLIC include)
|
||||
@@ -1,10 +1,14 @@
|
||||
==============================================================================
|
||||
The LLVM Project is under the Apache License v2.0 with LLVM Exceptions:
|
||||
==============================================================================
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
@@ -63,14 +67,14 @@
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
@@ -86,7 +90,7 @@
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
@@ -127,7 +131,7 @@
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
@@ -135,12 +139,12 @@
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
@@ -150,7 +154,7 @@
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
@@ -162,7 +166,7 @@
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
@@ -173,12 +177,12 @@
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "{}"
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
@@ -186,17 +190,90 @@
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright {yyyy} {name of copyright owner}
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
|
||||
---- LLVM Exceptions to the Apache 2.0 License ----
|
||||
|
||||
As an exception, if, as a result of your compiling your source code, portions
|
||||
of this Software are embedded into an Object form of such source code, you
|
||||
may redistribute such embedded portions in such Object form without complying
|
||||
with the conditions of Sections 4(a), 4(b) and 4(d) of the License.
|
||||
|
||||
In addition, if you combine or link compiled forms of this Software with
|
||||
software that is licensed under the GPLv2 ("Combined Software") and if a
|
||||
court of competent jurisdiction determines that the patent provision (Section
|
||||
3), the indemnity provision (Section 9) or other Section of the License
|
||||
conflicts with the conditions of the GPLv2, you may retroactively and
|
||||
prospectively choose to deem waived or otherwise exclude such Section(s) of
|
||||
the License, but only in their entirety and only with respect to the Combined
|
||||
Software.
|
||||
|
||||
==============================================================================
|
||||
Software from third parties included in the LLVM Project:
|
||||
==============================================================================
|
||||
The LLVM Project contains third party software which is under different license
|
||||
terms. All such code will be identified clearly using at least one of two
|
||||
mechanisms:
|
||||
1) It will be in a separate directory tree with its own `LICENSE.txt` or
|
||||
`LICENSE` file at the top containing the specific license and restrictions
|
||||
which apply to that software, or
|
||||
2) It will contain specific license and restriction terms at the top of every
|
||||
file.
|
||||
|
||||
==============================================================================
|
||||
Legacy LLVM License (https://llvm.org/docs/DeveloperPolicy.html#legacy):
|
||||
==============================================================================
|
||||
University of Illinois/NCSA
|
||||
Open Source License
|
||||
|
||||
Copyright (c) 2003-2019 University of Illinois at Urbana-Champaign.
|
||||
All rights reserved.
|
||||
|
||||
Developed by:
|
||||
|
||||
LLVM Team
|
||||
|
||||
University of Illinois at Urbana-Champaign
|
||||
|
||||
http://llvm.org
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal with
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimers.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimers in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
* Neither the names of the LLVM Team, University of Illinois at
|
||||
Urbana-Champaign, nor the names of its contributors may be used to
|
||||
endorse or promote products derived from this Software without specific
|
||||
prior written permission.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE
|
||||
SOFTWARE.
|
||||
|
||||
@@ -31,7 +31,6 @@ enum : int {
|
||||
char *itaniumDemangle(const char *mangled_name, char *buf, size_t *n,
|
||||
int *status);
|
||||
|
||||
|
||||
enum MSDemangleFlags {
|
||||
MSDF_None = 0,
|
||||
MSDF_DumpBackrefs = 1 << 0,
|
||||
@@ -39,6 +38,7 @@ enum MSDemangleFlags {
|
||||
MSDF_NoCallingConvention = 1 << 2,
|
||||
MSDF_NoReturnType = 1 << 3,
|
||||
MSDF_NoMemberType = 1 << 4,
|
||||
MSDF_NoVariableType = 1 << 5,
|
||||
};
|
||||
|
||||
/// Demangles the Microsoft symbol pointed at by mangled_name and returns it.
|
||||
@@ -53,9 +53,15 @@ enum MSDemangleFlags {
|
||||
/// receives the size of the demangled string on output if n_buf is not nullptr.
|
||||
/// status receives one of the demangle_ enum entries above if it's not nullptr.
|
||||
/// Flags controls various details of the demangled representation.
|
||||
char *microsoftDemangle(const char *mangled_name, size_t *n_read,
|
||||
char *buf, size_t *n_buf,
|
||||
int *status, MSDemangleFlags Flags = MSDF_None);
|
||||
char *microsoftDemangle(const char *mangled_name, size_t *n_read, char *buf,
|
||||
size_t *n_buf, int *status,
|
||||
MSDemangleFlags Flags = MSDF_None);
|
||||
|
||||
// Demangles a Rust v0 mangled symbol.
|
||||
char *rustDemangle(const char *MangledName);
|
||||
|
||||
// Demangles a D mangled symbol.
|
||||
char *dlangDemangle(const char *MangledName);
|
||||
|
||||
/// Attempt to demangle a string using different demangling schemes.
|
||||
/// The function uses heuristics to determine which demangling scheme to use.
|
||||
@@ -64,6 +70,8 @@ char *microsoftDemangle(const char *mangled_name, size_t *n_read,
|
||||
/// demangling occurred.
|
||||
std::string demangle(const std::string &MangledName);
|
||||
|
||||
bool nonMicrosoftDemangle(const char *MangledName, std::string &Result);
|
||||
|
||||
/// "Partial" demangler. This supports demangling a string into an AST
|
||||
/// (typically an intermediate stage in itaniumDemangle) and querying certain
|
||||
/// properties or partially printing the demangled name.
|
||||
@@ -115,6 +123,7 @@ struct ItaniumPartialDemangler {
|
||||
bool isSpecialName() const;
|
||||
|
||||
~ItaniumPartialDemangler();
|
||||
|
||||
private:
|
||||
void *RootNode;
|
||||
void *Context;
|
||||
@@ -12,8 +12,8 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_DEMANGLE_COMPILER_H
|
||||
#define LLVM_DEMANGLE_COMPILER_H
|
||||
#ifndef LLVM_DEMANGLE_DEMANGLECONFIG_H
|
||||
#define LLVM_DEMANGLE_DEMANGLECONFIG_H
|
||||
|
||||
#ifndef __has_feature
|
||||
#define __has_feature(x) 0
|
||||
File diff suppressed because it is too large
Load Diff
95
lib/external/llvm-demangle/include/llvm/Demangle/ItaniumNodes.def
vendored
Normal file
95
lib/external/llvm-demangle/include/llvm/Demangle/ItaniumNodes.def
vendored
Normal file
@@ -0,0 +1,95 @@
|
||||
//===--- ItaniumNodes.def ------------*- mode:c++;eval:(read-only-mode) -*-===//
|
||||
// Do not edit! See README.txt.
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Define the demangler's node names
|
||||
|
||||
#ifndef NODE
|
||||
#error Define NODE to handle nodes
|
||||
#endif
|
||||
|
||||
NODE(NodeArrayNode)
|
||||
NODE(DotSuffix)
|
||||
NODE(VendorExtQualType)
|
||||
NODE(QualType)
|
||||
NODE(ConversionOperatorType)
|
||||
NODE(PostfixQualifiedType)
|
||||
NODE(ElaboratedTypeSpefType)
|
||||
NODE(NameType)
|
||||
NODE(AbiTagAttr)
|
||||
NODE(EnableIfAttr)
|
||||
NODE(ObjCProtoName)
|
||||
NODE(PointerType)
|
||||
NODE(ReferenceType)
|
||||
NODE(PointerToMemberType)
|
||||
NODE(ArrayType)
|
||||
NODE(FunctionType)
|
||||
NODE(NoexceptSpec)
|
||||
NODE(DynamicExceptionSpec)
|
||||
NODE(FunctionEncoding)
|
||||
NODE(LiteralOperator)
|
||||
NODE(SpecialName)
|
||||
NODE(CtorVtableSpecialName)
|
||||
NODE(QualifiedName)
|
||||
NODE(NestedName)
|
||||
NODE(LocalName)
|
||||
NODE(ModuleName)
|
||||
NODE(ModuleEntity)
|
||||
NODE(VectorType)
|
||||
NODE(PixelVectorType)
|
||||
NODE(BinaryFPType)
|
||||
NODE(BitIntType)
|
||||
NODE(SyntheticTemplateParamName)
|
||||
NODE(TypeTemplateParamDecl)
|
||||
NODE(NonTypeTemplateParamDecl)
|
||||
NODE(TemplateTemplateParamDecl)
|
||||
NODE(TemplateParamPackDecl)
|
||||
NODE(ParameterPack)
|
||||
NODE(TemplateArgumentPack)
|
||||
NODE(ParameterPackExpansion)
|
||||
NODE(TemplateArgs)
|
||||
NODE(ForwardTemplateReference)
|
||||
NODE(NameWithTemplateArgs)
|
||||
NODE(GlobalQualifiedName)
|
||||
NODE(ExpandedSpecialSubstitution)
|
||||
NODE(SpecialSubstitution)
|
||||
NODE(CtorDtorName)
|
||||
NODE(DtorName)
|
||||
NODE(UnnamedTypeName)
|
||||
NODE(ClosureTypeName)
|
||||
NODE(StructuredBindingName)
|
||||
NODE(BinaryExpr)
|
||||
NODE(ArraySubscriptExpr)
|
||||
NODE(PostfixExpr)
|
||||
NODE(ConditionalExpr)
|
||||
NODE(MemberExpr)
|
||||
NODE(SubobjectExpr)
|
||||
NODE(EnclosingExpr)
|
||||
NODE(CastExpr)
|
||||
NODE(SizeofParamPackExpr)
|
||||
NODE(CallExpr)
|
||||
NODE(NewExpr)
|
||||
NODE(DeleteExpr)
|
||||
NODE(PrefixExpr)
|
||||
NODE(FunctionParam)
|
||||
NODE(ConversionExpr)
|
||||
NODE(PointerToMemberConversionExpr)
|
||||
NODE(InitListExpr)
|
||||
NODE(FoldExpr)
|
||||
NODE(ThrowExpr)
|
||||
NODE(BoolExpr)
|
||||
NODE(StringLiteral)
|
||||
NODE(LambdaExpr)
|
||||
NODE(EnumLiteral)
|
||||
NODE(IntegerLiteral)
|
||||
NODE(FloatLiteral)
|
||||
NODE(DoubleLiteral)
|
||||
NODE(LongDoubleLiteral)
|
||||
NODE(BracedExpr)
|
||||
NODE(BracedRangeExpr)
|
||||
|
||||
#undef NODE
|
||||
@@ -6,13 +6,11 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_DEMANGLE_MICROSOFT_DEMANGLE_H
|
||||
#define LLVM_DEMANGLE_MICROSOFT_DEMANGLE_H
|
||||
#ifndef LLVM_DEMANGLE_MICROSOFTDEMANGLE_H
|
||||
#define LLVM_DEMANGLE_MICROSOFTDEMANGLE_H
|
||||
|
||||
#include "llvm/Demangle/DemangleConfig.h"
|
||||
#include "llvm/Demangle/MicrosoftDemangleNodes.h"
|
||||
#include "llvm/Demangle/StringView.h"
|
||||
#include "llvm/Demangle/Utility.h"
|
||||
|
||||
#include <utility>
|
||||
|
||||
@@ -275,4 +273,4 @@ private:
|
||||
} // namespace ms_demangle
|
||||
} // namespace llvm
|
||||
|
||||
#endif // LLVM_DEMANGLE_MICROSOFT_DEMANGLE_H
|
||||
#endif // LLVM_DEMANGLE_MICROSOFTDEMANGLE_H
|
||||
@@ -10,10 +10,9 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_SUPPORT_MICROSOFTDEMANGLENODES_H
|
||||
#define LLVM_SUPPORT_MICROSOFTDEMANGLENODES_H
|
||||
#ifndef LLVM_DEMANGLE_MICROSOFTDEMANGLENODES_H
|
||||
#define LLVM_DEMANGLE_MICROSOFTDEMANGLENODES_H
|
||||
|
||||
#include "llvm/Demangle/DemangleConfig.h"
|
||||
#include "llvm/Demangle/StringView.h"
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
@@ -21,11 +20,11 @@
|
||||
|
||||
namespace llvm {
|
||||
namespace itanium_demangle {
|
||||
class OutputStream;
|
||||
class OutputBuffer;
|
||||
}
|
||||
}
|
||||
|
||||
using llvm::itanium_demangle::OutputStream;
|
||||
using llvm::itanium_demangle::OutputBuffer;
|
||||
using llvm::itanium_demangle::StringView;
|
||||
|
||||
namespace llvm {
|
||||
@@ -67,6 +66,8 @@ enum class CallingConv : uint8_t {
|
||||
Eabi,
|
||||
Vectorcall,
|
||||
Regcall,
|
||||
Swift, // Clang-only
|
||||
SwiftAsync, // Clang-only
|
||||
};
|
||||
|
||||
enum class ReferenceKind : uint8_t { None, LValueRef, RValueRef };
|
||||
@@ -78,6 +79,7 @@ enum OutputFlags {
|
||||
OF_NoAccessSpecifier = 4,
|
||||
OF_NoMemberType = 8,
|
||||
OF_NoReturnType = 16,
|
||||
OF_NoVariableType = 32,
|
||||
};
|
||||
|
||||
// Types
|
||||
@@ -259,7 +261,7 @@ struct Node {
|
||||
|
||||
NodeKind kind() const { return Kind; }
|
||||
|
||||
virtual void output(OutputStream &OS, OutputFlags Flags) const = 0;
|
||||
virtual void output(OutputBuffer &OB, OutputFlags Flags) const = 0;
|
||||
|
||||
std::string toString(OutputFlags Flags = OF_Default) const;
|
||||
|
||||
@@ -280,9 +282,7 @@ struct StructorIdentifierNode;
|
||||
struct ThunkSignatureNode;
|
||||
struct PointerTypeNode;
|
||||
struct ArrayTypeNode;
|
||||
struct CustomNode;
|
||||
struct TagTypeNode;
|
||||
struct IntrinsicTypeNode;
|
||||
struct NodeArrayNode;
|
||||
struct QualifiedNameNode;
|
||||
struct TemplateParameterReferenceNode;
|
||||
@@ -298,12 +298,12 @@ struct SpecialTableSymbolNode;
|
||||
struct TypeNode : public Node {
|
||||
explicit TypeNode(NodeKind K) : Node(K) {}
|
||||
|
||||
virtual void outputPre(OutputStream &OS, OutputFlags Flags) const = 0;
|
||||
virtual void outputPost(OutputStream &OS, OutputFlags Flags) const = 0;
|
||||
virtual void outputPre(OutputBuffer &OB, OutputFlags Flags) const = 0;
|
||||
virtual void outputPost(OutputBuffer &OB, OutputFlags Flags) const = 0;
|
||||
|
||||
void output(OutputStream &OS, OutputFlags Flags) const override {
|
||||
outputPre(OS, Flags);
|
||||
outputPost(OS, Flags);
|
||||
void output(OutputBuffer &OB, OutputFlags Flags) const override {
|
||||
outputPre(OB, Flags);
|
||||
outputPost(OB, Flags);
|
||||
}
|
||||
|
||||
Qualifiers Quals = Q_None;
|
||||
@@ -313,8 +313,8 @@ struct PrimitiveTypeNode : public TypeNode {
|
||||
explicit PrimitiveTypeNode(PrimitiveKind K)
|
||||
: TypeNode(NodeKind::PrimitiveType), PrimKind(K) {}
|
||||
|
||||
void outputPre(OutputStream &OS, OutputFlags Flags) const override;
|
||||
void outputPost(OutputStream &OS, OutputFlags Flags) const override {}
|
||||
void outputPre(OutputBuffer &OB, OutputFlags Flags) const override;
|
||||
void outputPost(OutputBuffer &OB, OutputFlags Flags) const override {}
|
||||
|
||||
PrimitiveKind PrimKind;
|
||||
};
|
||||
@@ -323,8 +323,8 @@ struct FunctionSignatureNode : public TypeNode {
|
||||
explicit FunctionSignatureNode(NodeKind K) : TypeNode(K) {}
|
||||
FunctionSignatureNode() : TypeNode(NodeKind::FunctionSignature) {}
|
||||
|
||||
void outputPre(OutputStream &OS, OutputFlags Flags) const override;
|
||||
void outputPost(OutputStream &OS, OutputFlags Flags) const override;
|
||||
void outputPre(OutputBuffer &OB, OutputFlags Flags) const override;
|
||||
void outputPost(OutputBuffer &OB, OutputFlags Flags) const override;
|
||||
|
||||
// Valid if this FunctionTypeNode is the Pointee of a PointerType or
|
||||
// MemberPointerType.
|
||||
@@ -357,13 +357,13 @@ struct IdentifierNode : public Node {
|
||||
NodeArrayNode *TemplateParams = nullptr;
|
||||
|
||||
protected:
|
||||
void outputTemplateParameters(OutputStream &OS, OutputFlags Flags) const;
|
||||
void outputTemplateParameters(OutputBuffer &OB, OutputFlags Flags) const;
|
||||
};
|
||||
|
||||
struct VcallThunkIdentifierNode : public IdentifierNode {
|
||||
VcallThunkIdentifierNode() : IdentifierNode(NodeKind::VcallThunkIdentifier) {}
|
||||
|
||||
void output(OutputStream &OS, OutputFlags Flags) const override;
|
||||
void output(OutputBuffer &OB, OutputFlags Flags) const override;
|
||||
|
||||
uint64_t OffsetInVTable = 0;
|
||||
};
|
||||
@@ -372,7 +372,7 @@ struct DynamicStructorIdentifierNode : public IdentifierNode {
|
||||
DynamicStructorIdentifierNode()
|
||||
: IdentifierNode(NodeKind::DynamicStructorIdentifier) {}
|
||||
|
||||
void output(OutputStream &OS, OutputFlags Flags) const override;
|
||||
void output(OutputBuffer &OB, OutputFlags Flags) const override;
|
||||
|
||||
VariableSymbolNode *Variable = nullptr;
|
||||
QualifiedNameNode *Name = nullptr;
|
||||
@@ -382,7 +382,7 @@ struct DynamicStructorIdentifierNode : public IdentifierNode {
|
||||
struct NamedIdentifierNode : public IdentifierNode {
|
||||
NamedIdentifierNode() : IdentifierNode(NodeKind::NamedIdentifier) {}
|
||||
|
||||
void output(OutputStream &OS, OutputFlags Flags) const override;
|
||||
void output(OutputBuffer &OB, OutputFlags Flags) const override;
|
||||
|
||||
StringView Name;
|
||||
};
|
||||
@@ -392,7 +392,7 @@ struct IntrinsicFunctionIdentifierNode : public IdentifierNode {
|
||||
: IdentifierNode(NodeKind::IntrinsicFunctionIdentifier),
|
||||
Operator(Operator) {}
|
||||
|
||||
void output(OutputStream &OS, OutputFlags Flags) const override;
|
||||
void output(OutputBuffer &OB, OutputFlags Flags) const override;
|
||||
|
||||
IntrinsicFunctionKind Operator;
|
||||
};
|
||||
@@ -401,7 +401,7 @@ struct LiteralOperatorIdentifierNode : public IdentifierNode {
|
||||
LiteralOperatorIdentifierNode()
|
||||
: IdentifierNode(NodeKind::LiteralOperatorIdentifier) {}
|
||||
|
||||
void output(OutputStream &OS, OutputFlags Flags) const override;
|
||||
void output(OutputBuffer &OB, OutputFlags Flags) const override;
|
||||
|
||||
StringView Name;
|
||||
};
|
||||
@@ -410,7 +410,7 @@ struct LocalStaticGuardIdentifierNode : public IdentifierNode {
|
||||
LocalStaticGuardIdentifierNode()
|
||||
: IdentifierNode(NodeKind::LocalStaticGuardIdentifier) {}
|
||||
|
||||
void output(OutputStream &OS, OutputFlags Flags) const override;
|
||||
void output(OutputBuffer &OB, OutputFlags Flags) const override;
|
||||
|
||||
bool IsThread = false;
|
||||
uint32_t ScopeIndex = 0;
|
||||
@@ -420,7 +420,7 @@ struct ConversionOperatorIdentifierNode : public IdentifierNode {
|
||||
ConversionOperatorIdentifierNode()
|
||||
: IdentifierNode(NodeKind::ConversionOperatorIdentifier) {}
|
||||
|
||||
void output(OutputStream &OS, OutputFlags Flags) const override;
|
||||
void output(OutputBuffer &OB, OutputFlags Flags) const override;
|
||||
|
||||
// The type that this operator converts too.
|
||||
TypeNode *TargetType = nullptr;
|
||||
@@ -432,7 +432,7 @@ struct StructorIdentifierNode : public IdentifierNode {
|
||||
: IdentifierNode(NodeKind::StructorIdentifier),
|
||||
IsDestructor(IsDestructor) {}
|
||||
|
||||
void output(OutputStream &OS, OutputFlags Flags) const override;
|
||||
void output(OutputBuffer &OB, OutputFlags Flags) const override;
|
||||
|
||||
// The name of the class that this is a structor of.
|
||||
IdentifierNode *Class = nullptr;
|
||||
@@ -442,8 +442,8 @@ struct StructorIdentifierNode : public IdentifierNode {
|
||||
struct ThunkSignatureNode : public FunctionSignatureNode {
|
||||
ThunkSignatureNode() : FunctionSignatureNode(NodeKind::ThunkSignature) {}
|
||||
|
||||
void outputPre(OutputStream &OS, OutputFlags Flags) const override;
|
||||
void outputPost(OutputStream &OS, OutputFlags Flags) const override;
|
||||
void outputPre(OutputBuffer &OB, OutputFlags Flags) const override;
|
||||
void outputPost(OutputBuffer &OB, OutputFlags Flags) const override;
|
||||
|
||||
struct ThisAdjustor {
|
||||
uint32_t StaticOffset = 0;
|
||||
@@ -457,8 +457,8 @@ struct ThunkSignatureNode : public FunctionSignatureNode {
|
||||
|
||||
struct PointerTypeNode : public TypeNode {
|
||||
PointerTypeNode() : TypeNode(NodeKind::PointerType) {}
|
||||
void outputPre(OutputStream &OS, OutputFlags Flags) const override;
|
||||
void outputPost(OutputStream &OS, OutputFlags Flags) const override;
|
||||
void outputPre(OutputBuffer &OB, OutputFlags Flags) const override;
|
||||
void outputPost(OutputBuffer &OB, OutputFlags Flags) const override;
|
||||
|
||||
// Is this a pointer, reference, or rvalue-reference?
|
||||
PointerAffinity Affinity = PointerAffinity::None;
|
||||
@@ -474,8 +474,8 @@ struct PointerTypeNode : public TypeNode {
|
||||
struct TagTypeNode : public TypeNode {
|
||||
explicit TagTypeNode(TagKind Tag) : TypeNode(NodeKind::TagType), Tag(Tag) {}
|
||||
|
||||
void outputPre(OutputStream &OS, OutputFlags Flags) const override;
|
||||
void outputPost(OutputStream &OS, OutputFlags Flags) const override;
|
||||
void outputPre(OutputBuffer &OB, OutputFlags Flags) const override;
|
||||
void outputPost(OutputBuffer &OB, OutputFlags Flags) const override;
|
||||
|
||||
QualifiedNameNode *QualifiedName = nullptr;
|
||||
TagKind Tag;
|
||||
@@ -484,11 +484,11 @@ struct TagTypeNode : public TypeNode {
|
||||
struct ArrayTypeNode : public TypeNode {
|
||||
ArrayTypeNode() : TypeNode(NodeKind::ArrayType) {}
|
||||
|
||||
void outputPre(OutputStream &OS, OutputFlags Flags) const override;
|
||||
void outputPost(OutputStream &OS, OutputFlags Flags) const override;
|
||||
void outputPre(OutputBuffer &OB, OutputFlags Flags) const override;
|
||||
void outputPost(OutputBuffer &OB, OutputFlags Flags) const override;
|
||||
|
||||
void outputDimensionsImpl(OutputStream &OS, OutputFlags Flags) const;
|
||||
void outputOneDimension(OutputStream &OS, OutputFlags Flags, Node *N) const;
|
||||
void outputDimensionsImpl(OutputBuffer &OB, OutputFlags Flags) const;
|
||||
void outputOneDimension(OutputBuffer &OB, OutputFlags Flags, Node *N) const;
|
||||
|
||||
// A list of array dimensions. e.g. [3,4,5] in `int Foo[3][4][5]`
|
||||
NodeArrayNode *Dimensions = nullptr;
|
||||
@@ -499,14 +499,14 @@ struct ArrayTypeNode : public TypeNode {
|
||||
|
||||
struct IntrinsicNode : public TypeNode {
|
||||
IntrinsicNode() : TypeNode(NodeKind::IntrinsicType) {}
|
||||
void output(OutputStream &OS, OutputFlags Flags) const override {}
|
||||
void output(OutputBuffer &OB, OutputFlags Flags) const override {}
|
||||
};
|
||||
|
||||
struct CustomTypeNode : public TypeNode {
|
||||
CustomTypeNode() : TypeNode(NodeKind::Custom) {}
|
||||
|
||||
void outputPre(OutputStream &OS, OutputFlags Flags) const override;
|
||||
void outputPost(OutputStream &OS, OutputFlags Flags) const override;
|
||||
void outputPre(OutputBuffer &OB, OutputFlags Flags) const override;
|
||||
void outputPost(OutputBuffer &OB, OutputFlags Flags) const override;
|
||||
|
||||
IdentifierNode *Identifier = nullptr;
|
||||
};
|
||||
@@ -514,9 +514,9 @@ struct CustomTypeNode : public TypeNode {
|
||||
struct NodeArrayNode : public Node {
|
||||
NodeArrayNode() : Node(NodeKind::NodeArray) {}
|
||||
|
||||
void output(OutputStream &OS, OutputFlags Flags) const override;
|
||||
void output(OutputBuffer &OB, OutputFlags Flags) const override;
|
||||
|
||||
void output(OutputStream &OS, OutputFlags Flags, StringView Separator) const;
|
||||
void output(OutputBuffer &OB, OutputFlags Flags, StringView Separator) const;
|
||||
|
||||
Node **Nodes = nullptr;
|
||||
size_t Count = 0;
|
||||
@@ -525,7 +525,7 @@ struct NodeArrayNode : public Node {
|
||||
struct QualifiedNameNode : public Node {
|
||||
QualifiedNameNode() : Node(NodeKind::QualifiedName) {}
|
||||
|
||||
void output(OutputStream &OS, OutputFlags Flags) const override;
|
||||
void output(OutputBuffer &OB, OutputFlags Flags) const override;
|
||||
|
||||
NodeArrayNode *Components = nullptr;
|
||||
|
||||
@@ -539,7 +539,7 @@ struct TemplateParameterReferenceNode : public Node {
|
||||
TemplateParameterReferenceNode()
|
||||
: Node(NodeKind::TemplateParameterReference) {}
|
||||
|
||||
void output(OutputStream &OS, OutputFlags Flags) const override;
|
||||
void output(OutputBuffer &OB, OutputFlags Flags) const override;
|
||||
|
||||
SymbolNode *Symbol = nullptr;
|
||||
|
||||
@@ -554,7 +554,7 @@ struct IntegerLiteralNode : public Node {
|
||||
IntegerLiteralNode(uint64_t Value, bool IsNegative)
|
||||
: Node(NodeKind::IntegerLiteral), Value(Value), IsNegative(IsNegative) {}
|
||||
|
||||
void output(OutputStream &OS, OutputFlags Flags) const override;
|
||||
void output(OutputBuffer &OB, OutputFlags Flags) const override;
|
||||
|
||||
uint64_t Value = 0;
|
||||
bool IsNegative = false;
|
||||
@@ -564,7 +564,7 @@ struct RttiBaseClassDescriptorNode : public IdentifierNode {
|
||||
RttiBaseClassDescriptorNode()
|
||||
: IdentifierNode(NodeKind::RttiBaseClassDescriptor) {}
|
||||
|
||||
void output(OutputStream &OS, OutputFlags Flags) const override;
|
||||
void output(OutputBuffer &OB, OutputFlags Flags) const override;
|
||||
|
||||
uint32_t NVOffset = 0;
|
||||
int32_t VBPtrOffset = 0;
|
||||
@@ -574,7 +574,7 @@ struct RttiBaseClassDescriptorNode : public IdentifierNode {
|
||||
|
||||
struct SymbolNode : public Node {
|
||||
explicit SymbolNode(NodeKind K) : Node(K) {}
|
||||
void output(OutputStream &OS, OutputFlags Flags) const override;
|
||||
void output(OutputBuffer &OB, OutputFlags Flags) const override;
|
||||
QualifiedNameNode *Name = nullptr;
|
||||
};
|
||||
|
||||
@@ -582,7 +582,7 @@ struct SpecialTableSymbolNode : public SymbolNode {
|
||||
explicit SpecialTableSymbolNode()
|
||||
: SymbolNode(NodeKind::SpecialTableSymbol) {}
|
||||
|
||||
void output(OutputStream &OS, OutputFlags Flags) const override;
|
||||
void output(OutputBuffer &OB, OutputFlags Flags) const override;
|
||||
QualifiedNameNode *TargetName = nullptr;
|
||||
Qualifiers Quals = Qualifiers::Q_None;
|
||||
};
|
||||
@@ -591,7 +591,7 @@ struct LocalStaticGuardVariableNode : public SymbolNode {
|
||||
LocalStaticGuardVariableNode()
|
||||
: SymbolNode(NodeKind::LocalStaticGuardVariable) {}
|
||||
|
||||
void output(OutputStream &OS, OutputFlags Flags) const override;
|
||||
void output(OutputBuffer &OB, OutputFlags Flags) const override;
|
||||
|
||||
bool IsVisible = false;
|
||||
};
|
||||
@@ -599,7 +599,7 @@ struct LocalStaticGuardVariableNode : public SymbolNode {
|
||||
struct EncodedStringLiteralNode : public SymbolNode {
|
||||
EncodedStringLiteralNode() : SymbolNode(NodeKind::EncodedStringLiteral) {}
|
||||
|
||||
void output(OutputStream &OS, OutputFlags Flags) const override;
|
||||
void output(OutputBuffer &OB, OutputFlags Flags) const override;
|
||||
|
||||
StringView DecodedString;
|
||||
bool IsTruncated = false;
|
||||
@@ -609,7 +609,7 @@ struct EncodedStringLiteralNode : public SymbolNode {
|
||||
struct VariableSymbolNode : public SymbolNode {
|
||||
VariableSymbolNode() : SymbolNode(NodeKind::VariableSymbol) {}
|
||||
|
||||
void output(OutputStream &OS, OutputFlags Flags) const override;
|
||||
void output(OutputBuffer &OB, OutputFlags Flags) const override;
|
||||
|
||||
StorageClass SC = StorageClass::None;
|
||||
TypeNode *Type = nullptr;
|
||||
@@ -618,7 +618,7 @@ struct VariableSymbolNode : public SymbolNode {
|
||||
struct FunctionSymbolNode : public SymbolNode {
|
||||
FunctionSymbolNode() : SymbolNode(NodeKind::FunctionSymbol) {}
|
||||
|
||||
void output(OutputStream &OS, OutputFlags Flags) const override;
|
||||
void output(OutputBuffer &OB, OutputFlags Flags) const override;
|
||||
|
||||
FunctionSignatureNode *Signature = nullptr;
|
||||
};
|
||||
61
lib/external/llvm-demangle/include/llvm/Demangle/README.txt
vendored
Normal file
61
lib/external/llvm-demangle/include/llvm/Demangle/README.txt
vendored
Normal file
@@ -0,0 +1,61 @@
|
||||
Itanium Name Demangler Library
|
||||
==============================
|
||||
|
||||
Introduction
|
||||
------------
|
||||
|
||||
This directory contains the generic itanium name demangler
|
||||
library. The main purpose of the library is to demangle C++ symbols,
|
||||
i.e. convert the string "_Z1fv" into "f()". You can also use the CRTP
|
||||
base ManglingParser to perform some simple analysis on the mangled
|
||||
name, or (in LLVM) use the opaque ItaniumPartialDemangler to query the
|
||||
demangled AST.
|
||||
|
||||
Why are there multiple copies of the this library in the source tree?
|
||||
---------------------------------------------------------------------
|
||||
|
||||
The canonical sources are in libcxxabi/src/demangle and some of the
|
||||
files are copied to llvm/include/llvm/Demangle. The simple reason for
|
||||
this comes from before the monorepo, and both [sub]projects need to
|
||||
demangle symbols, but neither can depend on each other.
|
||||
|
||||
* libcxxabi needs the demangler to implement __cxa_demangle, which is
|
||||
part of the itanium ABI spec.
|
||||
|
||||
* LLVM needs a copy for a bunch of places, and cannot rely on the
|
||||
system's __cxa_demangle because it a) might not be available (i.e.,
|
||||
on Windows), and b) may not be up-to-date on the latest language
|
||||
features.
|
||||
|
||||
The copy of the demangler in LLVM has some extra stuff that aren't
|
||||
needed in libcxxabi (ie, the MSVC demangler, ItaniumPartialDemangler),
|
||||
which depend on the shared generic components. Despite these
|
||||
differences, we want to keep the "core" generic demangling library
|
||||
identical between both copies to simplify development and testing.
|
||||
|
||||
If you're working on the generic library, then do the work first in
|
||||
libcxxabi, then run the cp-to-llvm.sh script in src/demangle. This
|
||||
script takes as an optional argument the path to llvm, and copies the
|
||||
changes you made to libcxxabi over. Note that this script just
|
||||
blindly overwrites all changes to the generic library in llvm, so be
|
||||
careful.
|
||||
|
||||
Because the core demangler needs to work in libcxxabi, everything
|
||||
needs to be declared in an anonymous namespace (see
|
||||
DEMANGLE_NAMESPACE_BEGIN), and you can't introduce any code that
|
||||
depends on the libcxx dylib.
|
||||
|
||||
FIXME: Now that LLVM is a monorepo, it should be possible to
|
||||
de-duplicate this code, and have both LLVM and libcxxabi depend on a
|
||||
shared demangler library.
|
||||
|
||||
Testing
|
||||
-------
|
||||
|
||||
The tests are split up between libcxxabi/test/{unit,}test_demangle.cpp, and
|
||||
llvm/unittest/Demangle. The llvm directory should only get tests for stuff not
|
||||
included in the core library. In the future though, we should probably move all
|
||||
the tests to LLVM.
|
||||
|
||||
It is also a really good idea to run libFuzzer after non-trivial changes, see
|
||||
libcxxabi/fuzz/cxa_demangle_fuzzer.cpp and https://llvm.org/docs/LibFuzzer.html.
|
||||
@@ -1,5 +1,5 @@
|
||||
//===--- StringView.h -------------------------------------------*- C++ -*-===//
|
||||
//
|
||||
//===--- StringView.h ----------------*- mode:c++;eval:(read-only-mode) -*-===//
|
||||
// Do not edit! See README.txt.
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
@@ -7,14 +7,16 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// FIXME: Use std::string_view instead when we support C++17.
|
||||
// There are two copies of this file in the source tree. The one under
|
||||
// libcxxabi is the original and the one under llvm is the copy. Use
|
||||
// cp-to-llvm.sh to update the copy. See README.txt for more details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef DEMANGLE_STRINGVIEW_H
|
||||
#define DEMANGLE_STRINGVIEW_H
|
||||
#ifndef LLVM_DEMANGLE_STRINGVIEW_H
|
||||
#define LLVM_DEMANGLE_STRINGVIEW_H
|
||||
|
||||
#include "DemangleConfig.h"
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
|
||||
@@ -36,29 +38,23 @@ public:
|
||||
StringView(const char *Str) : First(Str), Last(Str + std::strlen(Str)) {}
|
||||
StringView() : First(nullptr), Last(nullptr) {}
|
||||
|
||||
StringView substr(size_t From) const {
|
||||
return StringView(begin() + From, size() - From);
|
||||
StringView substr(size_t Pos, size_t Len = npos) const {
|
||||
assert(Pos <= size());
|
||||
if (Len > size() - Pos)
|
||||
Len = size() - Pos;
|
||||
return StringView(begin() + Pos, Len);
|
||||
}
|
||||
|
||||
size_t find(char C, size_t From = 0) const {
|
||||
size_t FindBegin = std::min(From, size());
|
||||
// Avoid calling memchr with nullptr.
|
||||
if (FindBegin < size()) {
|
||||
if (From < size()) {
|
||||
// Just forward to memchr, which is faster than a hand-rolled loop.
|
||||
if (const void *P = ::memchr(First + FindBegin, C, size() - FindBegin))
|
||||
if (const void *P = ::memchr(First + From, C, size() - From))
|
||||
return size_t(static_cast<const char *>(P) - First);
|
||||
}
|
||||
return npos;
|
||||
}
|
||||
|
||||
StringView substr(size_t From, size_t To) const {
|
||||
if (To >= size())
|
||||
To = size() - 1;
|
||||
if (From >= size())
|
||||
From = size() - 1;
|
||||
return StringView(First + From, First + To);
|
||||
}
|
||||
|
||||
StringView dropFront(size_t N = 1) const {
|
||||
if (N >= size())
|
||||
N = size();
|
||||
@@ -105,7 +101,7 @@ public:
|
||||
bool startsWith(StringView Str) const {
|
||||
if (Str.size() > size())
|
||||
return false;
|
||||
return std::equal(Str.begin(), Str.end(), begin());
|
||||
return std::strncmp(Str.begin(), begin(), Str.size()) == 0;
|
||||
}
|
||||
|
||||
const char &operator[](size_t Idx) const { return *(begin() + Idx); }
|
||||
@@ -118,7 +114,7 @@ public:
|
||||
|
||||
inline bool operator==(const StringView &LHS, const StringView &RHS) {
|
||||
return LHS.size() == RHS.size() &&
|
||||
std::equal(LHS.begin(), LHS.end(), RHS.begin());
|
||||
std::strncmp(LHS.begin(), RHS.begin(), LHS.size()) == 0;
|
||||
}
|
||||
|
||||
DEMANGLE_NAMESPACE_END
|
||||
218
lib/external/llvm-demangle/include/llvm/Demangle/Utility.h
vendored
Normal file
218
lib/external/llvm-demangle/include/llvm/Demangle/Utility.h
vendored
Normal file
@@ -0,0 +1,218 @@
|
||||
//===--- Utility.h -------------------*- mode:c++;eval:(read-only-mode) -*-===//
|
||||
// Do not edit! See README.txt.
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Provide some utility classes for use in the demangler.
|
||||
// There are two copies of this file in the source tree. The one in libcxxabi
|
||||
// is the original and the one in llvm is the copy. Use cp-to-llvm.sh to update
|
||||
// the copy. See README.txt for more details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_DEMANGLE_UTILITY_H
|
||||
#define LLVM_DEMANGLE_UTILITY_H
|
||||
|
||||
#include "StringView.h"
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <exception>
|
||||
#include <limits>
|
||||
|
||||
DEMANGLE_NAMESPACE_BEGIN
|
||||
|
||||
// Stream that AST nodes write their string representation into after the AST
|
||||
// has been parsed.
|
||||
class OutputBuffer {
|
||||
char *Buffer = nullptr;
|
||||
size_t CurrentPosition = 0;
|
||||
size_t BufferCapacity = 0;
|
||||
|
||||
// Ensure there are at least N more positions in the buffer.
|
||||
void grow(size_t N) {
|
||||
size_t Need = N + CurrentPosition;
|
||||
if (Need > BufferCapacity) {
|
||||
// Reduce the number of reallocations, with a bit of hysteresis. The
|
||||
// number here is chosen so the first allocation will more-than-likely not
|
||||
// allocate more than 1K.
|
||||
Need += 1024 - 32;
|
||||
BufferCapacity *= 2;
|
||||
if (BufferCapacity < Need)
|
||||
BufferCapacity = Need;
|
||||
Buffer = static_cast<char *>(std::realloc(Buffer, BufferCapacity));
|
||||
if (Buffer == nullptr)
|
||||
std::terminate();
|
||||
}
|
||||
}
|
||||
|
||||
OutputBuffer &writeUnsigned(uint64_t N, bool isNeg = false) {
|
||||
std::array<char, 21> Temp;
|
||||
char *TempPtr = Temp.data() + Temp.size();
|
||||
|
||||
// Output at least one character.
|
||||
do {
|
||||
*--TempPtr = char('0' + N % 10);
|
||||
N /= 10;
|
||||
} while (N);
|
||||
|
||||
// Add negative sign.
|
||||
if (isNeg)
|
||||
*--TempPtr = '-';
|
||||
|
||||
return operator+=(StringView(TempPtr, Temp.data() + Temp.size()));
|
||||
}
|
||||
|
||||
public:
|
||||
OutputBuffer(char *StartBuf, size_t Size)
|
||||
: Buffer(StartBuf), CurrentPosition(0), BufferCapacity(Size) {}
|
||||
OutputBuffer() = default;
|
||||
// Non-copyable
|
||||
OutputBuffer(const OutputBuffer &) = delete;
|
||||
OutputBuffer &operator=(const OutputBuffer &) = delete;
|
||||
|
||||
operator StringView() const { return StringView(Buffer, CurrentPosition); }
|
||||
|
||||
void reset(char *Buffer_, size_t BufferCapacity_) {
|
||||
CurrentPosition = 0;
|
||||
Buffer = Buffer_;
|
||||
BufferCapacity = BufferCapacity_;
|
||||
}
|
||||
|
||||
/// If a ParameterPackExpansion (or similar type) is encountered, the offset
|
||||
/// into the pack that we're currently printing.
|
||||
unsigned CurrentPackIndex = std::numeric_limits<unsigned>::max();
|
||||
unsigned CurrentPackMax = std::numeric_limits<unsigned>::max();
|
||||
|
||||
/// When zero, we're printing template args and '>' needs to be parenthesized.
|
||||
/// Use a counter so we can simply increment inside parentheses.
|
||||
unsigned GtIsGt = 1;
|
||||
|
||||
bool isGtInsideTemplateArgs() const { return GtIsGt == 0; }
|
||||
|
||||
void printOpen(char Open = '(') {
|
||||
GtIsGt++;
|
||||
*this += Open;
|
||||
}
|
||||
void printClose(char Close = ')') {
|
||||
GtIsGt--;
|
||||
*this += Close;
|
||||
}
|
||||
|
||||
OutputBuffer &operator+=(StringView R) {
|
||||
if (size_t Size = R.size()) {
|
||||
grow(Size);
|
||||
std::memcpy(Buffer + CurrentPosition, R.begin(), Size);
|
||||
CurrentPosition += Size;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
OutputBuffer &operator+=(char C) {
|
||||
grow(1);
|
||||
Buffer[CurrentPosition++] = C;
|
||||
return *this;
|
||||
}
|
||||
|
||||
OutputBuffer &prepend(StringView R) {
|
||||
size_t Size = R.size();
|
||||
|
||||
grow(Size);
|
||||
std::memmove(Buffer + Size, Buffer, CurrentPosition);
|
||||
std::memcpy(Buffer, R.begin(), Size);
|
||||
CurrentPosition += Size;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
OutputBuffer &operator<<(StringView R) { return (*this += R); }
|
||||
|
||||
OutputBuffer &operator<<(char C) { return (*this += C); }
|
||||
|
||||
OutputBuffer &operator<<(long long N) {
|
||||
return writeUnsigned(static_cast<unsigned long long>(std::abs(N)), N < 0);
|
||||
}
|
||||
|
||||
OutputBuffer &operator<<(unsigned long long N) {
|
||||
return writeUnsigned(N, false);
|
||||
}
|
||||
|
||||
OutputBuffer &operator<<(long N) {
|
||||
return this->operator<<(static_cast<long long>(N));
|
||||
}
|
||||
|
||||
OutputBuffer &operator<<(unsigned long N) {
|
||||
return this->operator<<(static_cast<unsigned long long>(N));
|
||||
}
|
||||
|
||||
OutputBuffer &operator<<(int N) {
|
||||
return this->operator<<(static_cast<long long>(N));
|
||||
}
|
||||
|
||||
OutputBuffer &operator<<(unsigned int N) {
|
||||
return this->operator<<(static_cast<unsigned long long>(N));
|
||||
}
|
||||
|
||||
void insert(size_t Pos, const char *S, size_t N) {
|
||||
assert(Pos <= CurrentPosition);
|
||||
if (N == 0)
|
||||
return;
|
||||
grow(N);
|
||||
std::memmove(Buffer + Pos + N, Buffer + Pos, CurrentPosition - Pos);
|
||||
std::memcpy(Buffer + Pos, S, N);
|
||||
CurrentPosition += N;
|
||||
}
|
||||
|
||||
size_t getCurrentPosition() const { return CurrentPosition; }
|
||||
void setCurrentPosition(size_t NewPos) { CurrentPosition = NewPos; }
|
||||
|
||||
char back() const {
|
||||
assert(CurrentPosition);
|
||||
return Buffer[CurrentPosition - 1];
|
||||
}
|
||||
|
||||
bool empty() const { return CurrentPosition == 0; }
|
||||
|
||||
char *getBuffer() { return Buffer; }
|
||||
char *getBufferEnd() { return Buffer + CurrentPosition - 1; }
|
||||
size_t getBufferCapacity() const { return BufferCapacity; }
|
||||
};
|
||||
|
||||
template <class T> class ScopedOverride {
|
||||
T &Loc;
|
||||
T Original;
|
||||
|
||||
public:
|
||||
ScopedOverride(T &Loc_) : ScopedOverride(Loc_, Loc_) {}
|
||||
|
||||
ScopedOverride(T &Loc_, T NewVal) : Loc(Loc_), Original(Loc_) {
|
||||
Loc_ = std::move(NewVal);
|
||||
}
|
||||
~ScopedOverride() { Loc = std::move(Original); }
|
||||
|
||||
ScopedOverride(const ScopedOverride &) = delete;
|
||||
ScopedOverride &operator=(const ScopedOverride &) = delete;
|
||||
};
|
||||
|
||||
inline bool initializeOutputBuffer(char *Buf, size_t *N, OutputBuffer &OB,
|
||||
size_t InitSize) {
|
||||
size_t BufferSize;
|
||||
if (Buf == nullptr) {
|
||||
Buf = static_cast<char *>(std::malloc(InitSize));
|
||||
if (Buf == nullptr)
|
||||
return false;
|
||||
BufferSize = InitSize;
|
||||
} else
|
||||
BufferSize = *N;
|
||||
|
||||
OB.reset(Buf, BufferSize);
|
||||
return true;
|
||||
}
|
||||
|
||||
DEMANGLE_NAMESPACE_END
|
||||
|
||||
#endif
|
||||
578
lib/external/llvm-demangle/source/DLangDemangle.cpp
vendored
Normal file
578
lib/external/llvm-demangle/source/DLangDemangle.cpp
vendored
Normal file
@@ -0,0 +1,578 @@
|
||||
//===--- DLangDemangle.cpp ------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
///
|
||||
/// \file
|
||||
/// This file defines a demangler for the D programming language as specified
|
||||
/// in the ABI specification, available at:
|
||||
/// https://dlang.org/spec/abi.html#name_mangling
|
||||
///
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/Demangle/Demangle.h"
|
||||
#include "llvm/Demangle/StringView.h"
|
||||
#include "llvm/Demangle/Utility.h"
|
||||
|
||||
#include <cctype>
|
||||
#include <cstring>
|
||||
#include <limits>
|
||||
|
||||
using namespace llvm;
|
||||
using llvm::itanium_demangle::OutputBuffer;
|
||||
using llvm::itanium_demangle::StringView;
|
||||
|
||||
namespace {
|
||||
|
||||
/// Demangle information structure.
|
||||
struct Demangler {
|
||||
/// Initialize the information structure we use to pass around information.
|
||||
///
|
||||
/// \param Mangled String to demangle.
|
||||
Demangler(const char *Mangled);
|
||||
|
||||
/// Extract and demangle the mangled symbol and append it to the output
|
||||
/// string.
|
||||
///
|
||||
/// \param Demangled Output buffer to write the demangled name.
|
||||
///
|
||||
/// \return The remaining string on success or nullptr on failure.
|
||||
///
|
||||
/// \see https://dlang.org/spec/abi.html#name_mangling .
|
||||
/// \see https://dlang.org/spec/abi.html#MangledName .
|
||||
const char *parseMangle(OutputBuffer *Demangled);
|
||||
|
||||
private:
|
||||
/// Extract and demangle a given mangled symbol and append it to the output
|
||||
/// string.
|
||||
///
|
||||
/// \param Demangled output buffer to write the demangled name.
|
||||
/// \param Mangled mangled symbol to be demangled.
|
||||
///
|
||||
/// \return The remaining string on success or nullptr on failure.
|
||||
///
|
||||
/// \see https://dlang.org/spec/abi.html#name_mangling .
|
||||
/// \see https://dlang.org/spec/abi.html#MangledName .
|
||||
const char *parseMangle(OutputBuffer *Demangled, const char *Mangled);
|
||||
|
||||
/// Extract the number from a given string.
|
||||
///
|
||||
/// \param Mangled string to extract the number.
|
||||
/// \param Ret assigned result value.
|
||||
///
|
||||
/// \return The remaining string on success or nullptr on failure.
|
||||
///
|
||||
/// \note A result larger than UINT_MAX is considered a failure.
|
||||
///
|
||||
/// \see https://dlang.org/spec/abi.html#Number .
|
||||
const char *decodeNumber(const char *Mangled, unsigned long &Ret);
|
||||
|
||||
/// Extract the back reference position from a given string.
|
||||
///
|
||||
/// \param Mangled string to extract the back reference position.
|
||||
/// \param Ret assigned result value.
|
||||
///
|
||||
/// \return the remaining string on success or nullptr on failure.
|
||||
///
|
||||
/// \note Ret is always >= 0 on success, and unspecified on failure
|
||||
///
|
||||
/// \see https://dlang.org/spec/abi.html#back_ref .
|
||||
/// \see https://dlang.org/spec/abi.html#NumberBackRef .
|
||||
const char *decodeBackrefPos(const char *Mangled, long &Ret);
|
||||
|
||||
/// Extract the symbol pointed by the back reference form a given string.
|
||||
///
|
||||
/// \param Mangled string to extract the back reference position.
|
||||
/// \param Ret assigned result value.
|
||||
///
|
||||
/// \return the remaining string on success or nullptr on failure.
|
||||
///
|
||||
/// \see https://dlang.org/spec/abi.html#back_ref .
|
||||
const char *decodeBackref(const char *Mangled, const char *&Ret);
|
||||
|
||||
/// Extract and demangle backreferenced symbol from a given mangled symbol
|
||||
/// and append it to the output string.
|
||||
///
|
||||
/// \param Demangled output buffer to write the demangled name.
|
||||
/// \param Mangled mangled symbol to be demangled.
|
||||
///
|
||||
/// \return the remaining string on success or nullptr on failure.
|
||||
///
|
||||
/// \see https://dlang.org/spec/abi.html#back_ref .
|
||||
/// \see https://dlang.org/spec/abi.html#IdentifierBackRef .
|
||||
const char *parseSymbolBackref(OutputBuffer *Demangled, const char *Mangled);
|
||||
|
||||
/// Extract and demangle backreferenced type from a given mangled symbol
|
||||
/// and append it to the output string.
|
||||
///
|
||||
/// \param Mangled mangled symbol to be demangled.
|
||||
///
|
||||
/// \return the remaining string on success or nullptr on failure.
|
||||
///
|
||||
/// \see https://dlang.org/spec/abi.html#back_ref .
|
||||
/// \see https://dlang.org/spec/abi.html#TypeBackRef .
|
||||
const char *parseTypeBackref(const char *Mangled);
|
||||
|
||||
/// Check whether it is the beginning of a symbol name.
|
||||
///
|
||||
/// \param Mangled string to extract the symbol name.
|
||||
///
|
||||
/// \return true on success, false otherwise.
|
||||
///
|
||||
/// \see https://dlang.org/spec/abi.html#SymbolName .
|
||||
bool isSymbolName(const char *Mangled);
|
||||
|
||||
/// Extract and demangle an identifier from a given mangled symbol append it
|
||||
/// to the output string.
|
||||
///
|
||||
/// \param Demangled Output buffer to write the demangled name.
|
||||
/// \param Mangled Mangled symbol to be demangled.
|
||||
///
|
||||
/// \return The remaining string on success or nullptr on failure.
|
||||
///
|
||||
/// \see https://dlang.org/spec/abi.html#SymbolName .
|
||||
const char *parseIdentifier(OutputBuffer *Demangled, const char *Mangled);
|
||||
|
||||
/// Extract and demangle the plain identifier from a given mangled symbol and
|
||||
/// prepend/append it to the output string, with a special treatment for some
|
||||
/// magic compiler generated symbols.
|
||||
///
|
||||
/// \param Demangled Output buffer to write the demangled name.
|
||||
/// \param Mangled Mangled symbol to be demangled.
|
||||
/// \param Len Length of the mangled symbol name.
|
||||
///
|
||||
/// \return The remaining string on success or nullptr on failure.
|
||||
///
|
||||
/// \see https://dlang.org/spec/abi.html#LName .
|
||||
const char *parseLName(OutputBuffer *Demangled, const char *Mangled,
|
||||
unsigned long Len);
|
||||
|
||||
/// Extract and demangle the qualified symbol from a given mangled symbol
|
||||
/// append it to the output string.
|
||||
///
|
||||
/// \param Demangled Output buffer to write the demangled name.
|
||||
/// \param Mangled Mangled symbol to be demangled.
|
||||
///
|
||||
/// \return The remaining string on success or nullptr on failure.
|
||||
///
|
||||
/// \see https://dlang.org/spec/abi.html#QualifiedName .
|
||||
const char *parseQualified(OutputBuffer *Demangled, const char *Mangled);
|
||||
|
||||
/// Extract and demangle a type from a given mangled symbol append it to
|
||||
/// the output string.
|
||||
///
|
||||
/// \param Mangled mangled symbol to be demangled.
|
||||
///
|
||||
/// \return the remaining string on success or nullptr on failure.
|
||||
///
|
||||
/// \see https://dlang.org/spec/abi.html#Type .
|
||||
const char *parseType(const char *Mangled);
|
||||
|
||||
/// The string we are demangling.
|
||||
const char *Str;
|
||||
/// The index of the last back reference.
|
||||
int LastBackref;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
const char *Demangler::decodeNumber(const char *Mangled, unsigned long &Ret) {
|
||||
// Return nullptr if trying to extract something that isn't a digit.
|
||||
if (Mangled == nullptr || !std::isdigit(*Mangled))
|
||||
return nullptr;
|
||||
|
||||
unsigned long Val = 0;
|
||||
|
||||
do {
|
||||
unsigned long Digit = Mangled[0] - '0';
|
||||
|
||||
// Check for overflow.
|
||||
if (Val > (std::numeric_limits<unsigned int>::max() - Digit) / 10)
|
||||
return nullptr;
|
||||
|
||||
Val = Val * 10 + Digit;
|
||||
++Mangled;
|
||||
} while (std::isdigit(*Mangled));
|
||||
|
||||
if (*Mangled == '\0')
|
||||
return nullptr;
|
||||
|
||||
Ret = Val;
|
||||
return Mangled;
|
||||
}
|
||||
|
||||
const char *Demangler::decodeBackrefPos(const char *Mangled, long &Ret) {
|
||||
// Return nullptr if trying to extract something that isn't a digit
|
||||
if (Mangled == nullptr || !std::isalpha(*Mangled))
|
||||
return nullptr;
|
||||
|
||||
// Any identifier or non-basic type that has been emitted to the mangled
|
||||
// symbol before will not be emitted again, but is referenced by a special
|
||||
// sequence encoding the relative position of the original occurrence in the
|
||||
// mangled symbol name.
|
||||
// Numbers in back references are encoded with base 26 by upper case letters
|
||||
// A-Z for higher digits but lower case letters a-z for the last digit.
|
||||
// NumberBackRef:
|
||||
// [a-z]
|
||||
// [A-Z] NumberBackRef
|
||||
// ^
|
||||
unsigned long Val = 0;
|
||||
|
||||
while (std::isalpha(*Mangled)) {
|
||||
// Check for overflow
|
||||
if (Val > (std::numeric_limits<unsigned long>::max() - 25) / 26)
|
||||
break;
|
||||
|
||||
Val *= 26;
|
||||
|
||||
if (Mangled[0] >= 'a' && Mangled[0] <= 'z') {
|
||||
Val += Mangled[0] - 'a';
|
||||
if ((long)Val <= 0)
|
||||
break;
|
||||
Ret = Val;
|
||||
return Mangled + 1;
|
||||
}
|
||||
|
||||
Val += Mangled[0] - 'A';
|
||||
++Mangled;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const char *Demangler::decodeBackref(const char *Mangled, const char *&Ret) {
|
||||
assert(Mangled != nullptr && *Mangled == 'Q' && "Invalid back reference!");
|
||||
Ret = nullptr;
|
||||
|
||||
// Position of 'Q'
|
||||
const char *Qpos = Mangled;
|
||||
long RefPos;
|
||||
++Mangled;
|
||||
|
||||
Mangled = decodeBackrefPos(Mangled, RefPos);
|
||||
if (Mangled == nullptr)
|
||||
return nullptr;
|
||||
|
||||
if (RefPos > Qpos - Str)
|
||||
return nullptr;
|
||||
|
||||
// Set the position of the back reference.
|
||||
Ret = Qpos - RefPos;
|
||||
|
||||
return Mangled;
|
||||
}
|
||||
|
||||
const char *Demangler::parseSymbolBackref(OutputBuffer *Demangled,
|
||||
const char *Mangled) {
|
||||
// An identifier back reference always points to a digit 0 to 9.
|
||||
// IdentifierBackRef:
|
||||
// Q NumberBackRef
|
||||
// ^
|
||||
const char *Backref;
|
||||
unsigned long Len;
|
||||
|
||||
// Get position of the back reference
|
||||
Mangled = decodeBackref(Mangled, Backref);
|
||||
|
||||
// Must point to a simple identifier
|
||||
Backref = decodeNumber(Backref, Len);
|
||||
if (Backref == nullptr || strlen(Backref) < Len)
|
||||
return nullptr;
|
||||
|
||||
Backref = parseLName(Demangled, Backref, Len);
|
||||
if (Backref == nullptr)
|
||||
return nullptr;
|
||||
|
||||
return Mangled;
|
||||
}
|
||||
|
||||
const char *Demangler::parseTypeBackref(const char *Mangled) {
|
||||
// A type back reference always points to a letter.
|
||||
// TypeBackRef:
|
||||
// Q NumberBackRef
|
||||
// ^
|
||||
const char *Backref;
|
||||
|
||||
// If we appear to be moving backwards through the mangle string, then
|
||||
// bail as this may be a recursive back reference.
|
||||
if (Mangled - Str >= LastBackref)
|
||||
return nullptr;
|
||||
|
||||
int SaveRefPos = LastBackref;
|
||||
LastBackref = Mangled - Str;
|
||||
|
||||
// Get position of the back reference.
|
||||
Mangled = decodeBackref(Mangled, Backref);
|
||||
|
||||
// Can't decode back reference.
|
||||
if (Backref == nullptr)
|
||||
return nullptr;
|
||||
|
||||
// TODO: Add support for function type back references.
|
||||
Backref = parseType(Backref);
|
||||
|
||||
LastBackref = SaveRefPos;
|
||||
|
||||
if (Backref == nullptr)
|
||||
return nullptr;
|
||||
|
||||
return Mangled;
|
||||
}
|
||||
|
||||
bool Demangler::isSymbolName(const char *Mangled) {
|
||||
long Ret;
|
||||
const char *Qref = Mangled;
|
||||
|
||||
if (std::isdigit(*Mangled))
|
||||
return true;
|
||||
|
||||
// TODO: Handle template instances.
|
||||
|
||||
if (*Mangled != 'Q')
|
||||
return false;
|
||||
|
||||
Mangled = decodeBackrefPos(Mangled + 1, Ret);
|
||||
if (Mangled == nullptr || Ret > Qref - Str)
|
||||
return false;
|
||||
|
||||
return std::isdigit(Qref[-Ret]);
|
||||
}
|
||||
|
||||
const char *Demangler::parseMangle(OutputBuffer *Demangled,
|
||||
const char *Mangled) {
|
||||
// A D mangled symbol is comprised of both scope and type information.
|
||||
// MangleName:
|
||||
// _D QualifiedName Type
|
||||
// _D QualifiedName Z
|
||||
// ^
|
||||
// The caller should have guaranteed that the start pointer is at the
|
||||
// above location.
|
||||
// Note that type is never a function type, but only the return type of
|
||||
// a function or the type of a variable.
|
||||
Mangled += 2;
|
||||
|
||||
Mangled = parseQualified(Demangled, Mangled);
|
||||
|
||||
if (Mangled != nullptr) {
|
||||
// Artificial symbols end with 'Z' and have no type.
|
||||
if (*Mangled == 'Z')
|
||||
++Mangled;
|
||||
else {
|
||||
Mangled = parseType(Mangled);
|
||||
}
|
||||
}
|
||||
|
||||
return Mangled;
|
||||
}
|
||||
|
||||
const char *Demangler::parseQualified(OutputBuffer *Demangled,
|
||||
const char *Mangled) {
|
||||
// Qualified names are identifiers separated by their encoded length.
|
||||
// Nested functions also encode their argument types without specifying
|
||||
// what they return.
|
||||
// QualifiedName:
|
||||
// SymbolFunctionName
|
||||
// SymbolFunctionName QualifiedName
|
||||
// ^
|
||||
// SymbolFunctionName:
|
||||
// SymbolName
|
||||
// SymbolName TypeFunctionNoReturn
|
||||
// SymbolName M TypeFunctionNoReturn
|
||||
// SymbolName M TypeModifiers TypeFunctionNoReturn
|
||||
// The start pointer should be at the above location.
|
||||
|
||||
// Whether it has more than one symbol
|
||||
size_t NotFirst = false;
|
||||
do {
|
||||
// Skip over anonymous symbols.
|
||||
if (*Mangled == '0') {
|
||||
do
|
||||
++Mangled;
|
||||
while (*Mangled == '0');
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (NotFirst)
|
||||
*Demangled << '.';
|
||||
NotFirst = true;
|
||||
|
||||
Mangled = parseIdentifier(Demangled, Mangled);
|
||||
|
||||
} while (Mangled && isSymbolName(Mangled));
|
||||
|
||||
return Mangled;
|
||||
}
|
||||
|
||||
const char *Demangler::parseIdentifier(OutputBuffer *Demangled,
|
||||
const char *Mangled) {
|
||||
unsigned long Len;
|
||||
|
||||
if (Mangled == nullptr || *Mangled == '\0')
|
||||
return nullptr;
|
||||
|
||||
if (*Mangled == 'Q')
|
||||
return parseSymbolBackref(Demangled, Mangled);
|
||||
|
||||
// TODO: Parse lengthless template instances.
|
||||
|
||||
const char *Endptr = decodeNumber(Mangled, Len);
|
||||
|
||||
if (Endptr == nullptr || Len == 0)
|
||||
return nullptr;
|
||||
|
||||
if (strlen(Endptr) < Len)
|
||||
return nullptr;
|
||||
|
||||
Mangled = Endptr;
|
||||
|
||||
// TODO: Parse template instances with a length prefix.
|
||||
|
||||
// There can be multiple different declarations in the same function that
|
||||
// have the same mangled name. To make the mangled names unique, a fake
|
||||
// parent in the form `__Sddd' is added to the symbol.
|
||||
if (Len >= 4 && Mangled[0] == '_' && Mangled[1] == '_' && Mangled[2] == 'S') {
|
||||
const char *NumPtr = Mangled + 3;
|
||||
while (NumPtr < (Mangled + Len) && std::isdigit(*NumPtr))
|
||||
++NumPtr;
|
||||
|
||||
if (Mangled + Len == NumPtr) {
|
||||
// Skip over the fake parent.
|
||||
Mangled += Len;
|
||||
return parseIdentifier(Demangled, Mangled);
|
||||
}
|
||||
|
||||
// Else demangle it as a plain identifier.
|
||||
}
|
||||
|
||||
return parseLName(Demangled, Mangled, Len);
|
||||
}
|
||||
|
||||
const char *Demangler::parseType(const char *Mangled) {
|
||||
if (*Mangled == '\0')
|
||||
return nullptr;
|
||||
|
||||
switch (*Mangled) {
|
||||
// TODO: Parse type qualifiers.
|
||||
// TODO: Parse function types.
|
||||
// TODO: Parse compound types.
|
||||
// TODO: Parse delegate types.
|
||||
// TODO: Parse tuple types.
|
||||
|
||||
// Basic types.
|
||||
case 'i':
|
||||
++Mangled;
|
||||
// TODO: Add type name dumping
|
||||
return Mangled;
|
||||
|
||||
// TODO: Add support for the rest of the basic types.
|
||||
|
||||
// Back referenced type.
|
||||
case 'Q':
|
||||
return parseTypeBackref(Mangled);
|
||||
|
||||
default: // unhandled.
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
const char *Demangler::parseLName(OutputBuffer *Demangled, const char *Mangled,
|
||||
unsigned long Len) {
|
||||
switch (Len) {
|
||||
case 6:
|
||||
if (strncmp(Mangled, "__initZ", Len + 1) == 0) {
|
||||
// The static initializer for a given symbol.
|
||||
Demangled->prepend("initializer for ");
|
||||
Demangled->setCurrentPosition(Demangled->getCurrentPosition() - 1);
|
||||
Mangled += Len;
|
||||
return Mangled;
|
||||
}
|
||||
if (strncmp(Mangled, "__vtblZ", Len + 1) == 0) {
|
||||
// The vtable symbol for a given class.
|
||||
Demangled->prepend("vtable for ");
|
||||
Demangled->setCurrentPosition(Demangled->getCurrentPosition() - 1);
|
||||
Mangled += Len;
|
||||
return Mangled;
|
||||
}
|
||||
break;
|
||||
|
||||
case 7:
|
||||
if (strncmp(Mangled, "__ClassZ", Len + 1) == 0) {
|
||||
// The classinfo symbol for a given class.
|
||||
Demangled->prepend("ClassInfo for ");
|
||||
Demangled->setCurrentPosition(Demangled->getCurrentPosition() - 1);
|
||||
Mangled += Len;
|
||||
return Mangled;
|
||||
}
|
||||
break;
|
||||
|
||||
case 11:
|
||||
if (strncmp(Mangled, "__InterfaceZ", Len + 1) == 0) {
|
||||
// The interface symbol for a given class.
|
||||
Demangled->prepend("Interface for ");
|
||||
Demangled->setCurrentPosition(Demangled->getCurrentPosition() - 1);
|
||||
Mangled += Len;
|
||||
return Mangled;
|
||||
}
|
||||
break;
|
||||
|
||||
case 12:
|
||||
if (strncmp(Mangled, "__ModuleInfoZ", Len + 1) == 0) {
|
||||
// The ModuleInfo symbol for a given module.
|
||||
Demangled->prepend("ModuleInfo for ");
|
||||
Demangled->setCurrentPosition(Demangled->getCurrentPosition() - 1);
|
||||
Mangled += Len;
|
||||
return Mangled;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
*Demangled << StringView(Mangled, Len);
|
||||
Mangled += Len;
|
||||
|
||||
return Mangled;
|
||||
}
|
||||
|
||||
Demangler::Demangler(const char *Mangled)
|
||||
: Str(Mangled), LastBackref(strlen(Mangled)) {}
|
||||
|
||||
const char *Demangler::parseMangle(OutputBuffer *Demangled) {
|
||||
return parseMangle(Demangled, this->Str);
|
||||
}
|
||||
|
||||
char *llvm::dlangDemangle(const char *MangledName) {
|
||||
if (MangledName == nullptr || strncmp(MangledName, "_D", 2) != 0)
|
||||
return nullptr;
|
||||
|
||||
OutputBuffer Demangled;
|
||||
if (!initializeOutputBuffer(nullptr, nullptr, Demangled, 1024))
|
||||
return nullptr;
|
||||
|
||||
if (strcmp(MangledName, "_Dmain") == 0) {
|
||||
Demangled << "D main";
|
||||
} else {
|
||||
|
||||
Demangler D = Demangler(MangledName);
|
||||
MangledName = D.parseMangle(&Demangled);
|
||||
|
||||
// Check that the entire symbol was successfully demangled.
|
||||
if (MangledName == nullptr || *MangledName != '\0') {
|
||||
std::free(Demangled.getBuffer());
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
// OutputBuffer's internal buffer is not null terminated and therefore we need
|
||||
// to add it to comply with C null terminated strings.
|
||||
if (Demangled.getCurrentPosition() > 0) {
|
||||
Demangled << '\0';
|
||||
Demangled.setCurrentPosition(Demangled.getCurrentPosition() - 1);
|
||||
return Demangled.getBuffer();
|
||||
}
|
||||
|
||||
std::free(Demangled.getBuffer());
|
||||
return nullptr;
|
||||
}
|
||||
64
lib/external/llvm-demangle/source/Demangle.cpp
vendored
Normal file
64
lib/external/llvm-demangle/source/Demangle.cpp
vendored
Normal file
@@ -0,0 +1,64 @@
|
||||
//===-- Demangle.cpp - Common demangling functions ------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
///
|
||||
/// \file This file contains definitions of common demangling functions.
|
||||
///
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/Demangle/Demangle.h"
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
|
||||
static bool isItaniumEncoding(const char *S) {
|
||||
// Itanium encoding requires 1 or 3 leading underscores, followed by 'Z'.
|
||||
return std::strncmp(S, "_Z", 2) == 0 || std::strncmp(S, "___Z", 4) == 0;
|
||||
}
|
||||
|
||||
static bool isRustEncoding(const char *S) { return S[0] == '_' && S[1] == 'R'; }
|
||||
|
||||
static bool isDLangEncoding(const std::string &MangledName) {
|
||||
return MangledName.size() >= 2 && MangledName[0] == '_' &&
|
||||
MangledName[1] == 'D';
|
||||
}
|
||||
|
||||
std::string llvm::demangle(const std::string &MangledName) {
|
||||
std::string Result;
|
||||
const char *S = MangledName.c_str();
|
||||
|
||||
if (nonMicrosoftDemangle(S, Result))
|
||||
return Result;
|
||||
|
||||
if (S[0] == '_' && nonMicrosoftDemangle(S + 1, Result))
|
||||
return Result;
|
||||
|
||||
if (char *Demangled =
|
||||
microsoftDemangle(S, nullptr, nullptr, nullptr, nullptr)) {
|
||||
Result = Demangled;
|
||||
std::free(Demangled);
|
||||
return Result;
|
||||
}
|
||||
|
||||
return MangledName;
|
||||
}
|
||||
|
||||
bool llvm::nonMicrosoftDemangle(const char *MangledName, std::string &Result) {
|
||||
char *Demangled = nullptr;
|
||||
if (isItaniumEncoding(MangledName))
|
||||
Demangled = itaniumDemangle(MangledName, nullptr, nullptr, nullptr);
|
||||
else if (isRustEncoding(MangledName))
|
||||
Demangled = rustDemangle(MangledName);
|
||||
else if (isDLangEncoding(MangledName))
|
||||
Demangled = dlangDemangle(MangledName);
|
||||
|
||||
if (!Demangled)
|
||||
return false;
|
||||
|
||||
Result = Demangled;
|
||||
std::free(Demangled);
|
||||
return true;
|
||||
}
|
||||
@@ -19,9 +19,7 @@
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <functional>
|
||||
#include <numeric>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
using namespace llvm;
|
||||
using namespace llvm::itanium_demangle;
|
||||
@@ -174,6 +172,50 @@ struct DumpVisitor {
|
||||
return printStr("TemplateParamKind::Template");
|
||||
}
|
||||
}
|
||||
void print(Node::Prec P) {
|
||||
switch (P) {
|
||||
case Node::Prec::Primary:
|
||||
return printStr("Node::Prec::Primary");
|
||||
case Node::Prec::Postfix:
|
||||
return printStr("Node::Prec::Postfix");
|
||||
case Node::Prec::Unary:
|
||||
return printStr("Node::Prec::Unary");
|
||||
case Node::Prec::Cast:
|
||||
return printStr("Node::Prec::Cast");
|
||||
case Node::Prec::PtrMem:
|
||||
return printStr("Node::Prec::PtrMem");
|
||||
case Node::Prec::Multiplicative:
|
||||
return printStr("Node::Prec::Multiplicative");
|
||||
case Node::Prec::Additive:
|
||||
return printStr("Node::Prec::Additive");
|
||||
case Node::Prec::Shift:
|
||||
return printStr("Node::Prec::Shift");
|
||||
case Node::Prec::Spaceship:
|
||||
return printStr("Node::Prec::Spaceship");
|
||||
case Node::Prec::Relational:
|
||||
return printStr("Node::Prec::Relational");
|
||||
case Node::Prec::Equality:
|
||||
return printStr("Node::Prec::Equality");
|
||||
case Node::Prec::And:
|
||||
return printStr("Node::Prec::And");
|
||||
case Node::Prec::Xor:
|
||||
return printStr("Node::Prec::Xor");
|
||||
case Node::Prec::Ior:
|
||||
return printStr("Node::Prec::Ior");
|
||||
case Node::Prec::AndIf:
|
||||
return printStr("Node::Prec::AndIf");
|
||||
case Node::Prec::OrIf:
|
||||
return printStr("Node::Prec::OrIf");
|
||||
case Node::Prec::Conditional:
|
||||
return printStr("Node::Prec::Conditional");
|
||||
case Node::Prec::Assign:
|
||||
return printStr("Node::Prec::Assign");
|
||||
case Node::Prec::Comma:
|
||||
return printStr("Node::Prec::Comma");
|
||||
case Node::Prec::Default:
|
||||
return printStr("Node::Prec::Default");
|
||||
}
|
||||
}
|
||||
|
||||
void newLine() {
|
||||
printStr("\n");
|
||||
@@ -333,21 +375,21 @@ char *llvm::itaniumDemangle(const char *MangledName, char *Buf,
|
||||
|
||||
int InternalStatus = demangle_success;
|
||||
Demangler Parser(MangledName, MangledName + std::strlen(MangledName));
|
||||
OutputStream S;
|
||||
OutputBuffer OB;
|
||||
|
||||
Node *AST = Parser.parse();
|
||||
|
||||
if (AST == nullptr)
|
||||
InternalStatus = demangle_invalid_mangled_name;
|
||||
else if (!initializeOutputStream(Buf, N, S, 1024))
|
||||
else if (!initializeOutputBuffer(Buf, N, OB, 1024))
|
||||
InternalStatus = demangle_memory_alloc_failure;
|
||||
else {
|
||||
assert(Parser.ForwardTemplateRefs.empty());
|
||||
AST->print(S);
|
||||
S += '\0';
|
||||
AST->print(OB);
|
||||
OB += '\0';
|
||||
if (N != nullptr)
|
||||
*N = S.getCurrentPosition();
|
||||
Buf = S.getBuffer();
|
||||
*N = OB.getCurrentPosition();
|
||||
Buf = OB.getBuffer();
|
||||
}
|
||||
|
||||
if (Status)
|
||||
@@ -385,14 +427,14 @@ bool ItaniumPartialDemangler::partialDemangle(const char *MangledName) {
|
||||
}
|
||||
|
||||
static char *printNode(const Node *RootNode, char *Buf, size_t *N) {
|
||||
OutputStream S;
|
||||
if (!initializeOutputStream(Buf, N, S, 128))
|
||||
OutputBuffer OB;
|
||||
if (!initializeOutputBuffer(Buf, N, OB, 128))
|
||||
return nullptr;
|
||||
RootNode->print(S);
|
||||
S += '\0';
|
||||
RootNode->print(OB);
|
||||
OB += '\0';
|
||||
if (N != nullptr)
|
||||
*N = S.getCurrentPosition();
|
||||
return S.getBuffer();
|
||||
*N = OB.getCurrentPosition();
|
||||
return OB.getBuffer();
|
||||
}
|
||||
|
||||
char *ItaniumPartialDemangler::getFunctionBaseName(char *Buf, size_t *N) const {
|
||||
@@ -406,8 +448,8 @@ char *ItaniumPartialDemangler::getFunctionBaseName(char *Buf, size_t *N) const {
|
||||
case Node::KAbiTagAttr:
|
||||
Name = static_cast<const AbiTagAttr *>(Name)->Base;
|
||||
continue;
|
||||
case Node::KStdQualifiedName:
|
||||
Name = static_cast<const StdQualifiedName *>(Name)->Child;
|
||||
case Node::KModuleEntity:
|
||||
Name = static_cast<const ModuleEntity *>(Name)->Name;
|
||||
continue;
|
||||
case Node::KNestedName:
|
||||
Name = static_cast<const NestedName *>(Name)->Name;
|
||||
@@ -430,8 +472,8 @@ char *ItaniumPartialDemangler::getFunctionDeclContextName(char *Buf,
|
||||
return nullptr;
|
||||
const Node *Name = static_cast<const FunctionEncoding *>(RootNode)->getName();
|
||||
|
||||
OutputStream S;
|
||||
if (!initializeOutputStream(Buf, N, S, 128))
|
||||
OutputBuffer OB;
|
||||
if (!initializeOutputBuffer(Buf, N, OB, 128))
|
||||
return nullptr;
|
||||
|
||||
KeepGoingLocalFunction:
|
||||
@@ -447,27 +489,27 @@ char *ItaniumPartialDemangler::getFunctionDeclContextName(char *Buf,
|
||||
break;
|
||||
}
|
||||
|
||||
if (Name->getKind() == Node::KModuleEntity)
|
||||
Name = static_cast<const ModuleEntity *>(Name)->Name;
|
||||
|
||||
switch (Name->getKind()) {
|
||||
case Node::KStdQualifiedName:
|
||||
S += "std";
|
||||
break;
|
||||
case Node::KNestedName:
|
||||
static_cast<const NestedName *>(Name)->Qual->print(S);
|
||||
static_cast<const NestedName *>(Name)->Qual->print(OB);
|
||||
break;
|
||||
case Node::KLocalName: {
|
||||
auto *LN = static_cast<const LocalName *>(Name);
|
||||
LN->Encoding->print(S);
|
||||
S += "::";
|
||||
LN->Encoding->print(OB);
|
||||
OB += "::";
|
||||
Name = LN->Entity;
|
||||
goto KeepGoingLocalFunction;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
S += '\0';
|
||||
OB += '\0';
|
||||
if (N != nullptr)
|
||||
*N = S.getCurrentPosition();
|
||||
return S.getBuffer();
|
||||
*N = OB.getCurrentPosition();
|
||||
return OB.getBuffer();
|
||||
}
|
||||
|
||||
char *ItaniumPartialDemangler::getFunctionName(char *Buf, size_t *N) const {
|
||||
@@ -483,17 +525,17 @@ char *ItaniumPartialDemangler::getFunctionParameters(char *Buf,
|
||||
return nullptr;
|
||||
NodeArray Params = static_cast<FunctionEncoding *>(RootNode)->getParams();
|
||||
|
||||
OutputStream S;
|
||||
if (!initializeOutputStream(Buf, N, S, 128))
|
||||
OutputBuffer OB;
|
||||
if (!initializeOutputBuffer(Buf, N, OB, 128))
|
||||
return nullptr;
|
||||
|
||||
S += '(';
|
||||
Params.printWithComma(S);
|
||||
S += ')';
|
||||
S += '\0';
|
||||
OB += '(';
|
||||
Params.printWithComma(OB);
|
||||
OB += ')';
|
||||
OB += '\0';
|
||||
if (N != nullptr)
|
||||
*N = S.getCurrentPosition();
|
||||
return S.getBuffer();
|
||||
*N = OB.getCurrentPosition();
|
||||
return OB.getBuffer();
|
||||
}
|
||||
|
||||
char *ItaniumPartialDemangler::getFunctionReturnType(
|
||||
@@ -501,18 +543,18 @@ char *ItaniumPartialDemangler::getFunctionReturnType(
|
||||
if (!isFunction())
|
||||
return nullptr;
|
||||
|
||||
OutputStream S;
|
||||
if (!initializeOutputStream(Buf, N, S, 128))
|
||||
OutputBuffer OB;
|
||||
if (!initializeOutputBuffer(Buf, N, OB, 128))
|
||||
return nullptr;
|
||||
|
||||
if (const Node *Ret =
|
||||
static_cast<const FunctionEncoding *>(RootNode)->getReturnType())
|
||||
Ret->print(S);
|
||||
Ret->print(OB);
|
||||
|
||||
S += '\0';
|
||||
OB += '\0';
|
||||
if (N != nullptr)
|
||||
*N = S.getCurrentPosition();
|
||||
return S.getBuffer();
|
||||
*N = OB.getCurrentPosition();
|
||||
return OB.getBuffer();
|
||||
}
|
||||
|
||||
char *ItaniumPartialDemangler::finishDemangle(char *Buf, size_t *N) const {
|
||||
@@ -552,8 +594,8 @@ bool ItaniumPartialDemangler::isCtorOrDtor() const {
|
||||
case Node::KNestedName:
|
||||
N = static_cast<const NestedName *>(N)->Name;
|
||||
break;
|
||||
case Node::KStdQualifiedName:
|
||||
N = static_cast<const StdQualifiedName *>(N)->Child;
|
||||
case Node::KModuleEntity:
|
||||
N = static_cast<const ModuleEntity *>(N)->Name;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -245,8 +245,8 @@ demanglePointerCVQualifiers(StringView &MangledName) {
|
||||
}
|
||||
|
||||
StringView Demangler::copyString(StringView Borrowed) {
|
||||
char *Stable = Arena.allocUnalignedBuffer(Borrowed.size() + 1);
|
||||
std::strcpy(Stable, Borrowed.begin());
|
||||
char *Stable = Arena.allocUnalignedBuffer(Borrowed.size());
|
||||
std::memcpy(Stable, Borrowed.begin(), Borrowed.size());
|
||||
|
||||
return {Stable, Borrowed.size()};
|
||||
}
|
||||
@@ -823,11 +823,15 @@ SymbolNode *Demangler::parse(StringView &MangledName) {
|
||||
}
|
||||
|
||||
TagTypeNode *Demangler::parseTagUniqueName(StringView &MangledName) {
|
||||
if (!MangledName.consumeFront(".?A"))
|
||||
if (!MangledName.consumeFront(".?A")) {
|
||||
Error = true;
|
||||
return nullptr;
|
||||
}
|
||||
MangledName.consumeFront(".?A");
|
||||
if (MangledName.empty())
|
||||
if (MangledName.empty()) {
|
||||
Error = true;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return demangleClassType(MangledName);
|
||||
}
|
||||
@@ -965,17 +969,14 @@ NamedIdentifierNode *Demangler::demangleBackRefName(StringView &MangledName) {
|
||||
void Demangler::memorizeIdentifier(IdentifierNode *Identifier) {
|
||||
// Render this class template name into a string buffer so that we can
|
||||
// memorize it for the purpose of back-referencing.
|
||||
OutputStream OS;
|
||||
if (!initializeOutputStream(nullptr, nullptr, OS, 1024))
|
||||
OutputBuffer OB;
|
||||
if (!initializeOutputBuffer(nullptr, nullptr, OB, 1024))
|
||||
// FIXME: Propagate out-of-memory as an error?
|
||||
std::terminate();
|
||||
Identifier->output(OS, OF_Default);
|
||||
OS << '\0';
|
||||
char *Name = OS.getBuffer();
|
||||
|
||||
StringView Owned = copyString(Name);
|
||||
Identifier->output(OB, OF_Default);
|
||||
StringView Owned = copyString(OB);
|
||||
memorizeString(Owned);
|
||||
std::free(Name);
|
||||
std::free(OB.getBuffer());
|
||||
}
|
||||
|
||||
IdentifierNode *
|
||||
@@ -1107,7 +1108,7 @@ static void writeHexDigit(char *Buffer, uint8_t Digit) {
|
||||
*Buffer = (Digit < 10) ? ('0' + Digit) : ('A' + Digit - 10);
|
||||
}
|
||||
|
||||
static void outputHex(OutputStream &OS, unsigned C) {
|
||||
static void outputHex(OutputBuffer &OB, unsigned C) {
|
||||
assert (C != 0);
|
||||
|
||||
// It's easier to do the math if we can work from right to left, but we need
|
||||
@@ -1130,43 +1131,43 @@ static void outputHex(OutputStream &OS, unsigned C) {
|
||||
TempBuffer[Pos--] = 'x';
|
||||
assert(Pos >= 0);
|
||||
TempBuffer[Pos--] = '\\';
|
||||
OS << StringView(&TempBuffer[Pos + 1]);
|
||||
OB << StringView(&TempBuffer[Pos + 1]);
|
||||
}
|
||||
|
||||
static void outputEscapedChar(OutputStream &OS, unsigned C) {
|
||||
static void outputEscapedChar(OutputBuffer &OB, unsigned C) {
|
||||
switch (C) {
|
||||
case '\0': // nul
|
||||
OS << "\\0";
|
||||
OB << "\\0";
|
||||
return;
|
||||
case '\'': // single quote
|
||||
OS << "\\\'";
|
||||
OB << "\\\'";
|
||||
return;
|
||||
case '\"': // double quote
|
||||
OS << "\\\"";
|
||||
OB << "\\\"";
|
||||
return;
|
||||
case '\\': // backslash
|
||||
OS << "\\\\";
|
||||
OB << "\\\\";
|
||||
return;
|
||||
case '\a': // bell
|
||||
OS << "\\a";
|
||||
OB << "\\a";
|
||||
return;
|
||||
case '\b': // backspace
|
||||
OS << "\\b";
|
||||
OB << "\\b";
|
||||
return;
|
||||
case '\f': // form feed
|
||||
OS << "\\f";
|
||||
OB << "\\f";
|
||||
return;
|
||||
case '\n': // new line
|
||||
OS << "\\n";
|
||||
OB << "\\n";
|
||||
return;
|
||||
case '\r': // carriage return
|
||||
OS << "\\r";
|
||||
OB << "\\r";
|
||||
return;
|
||||
case '\t': // tab
|
||||
OS << "\\t";
|
||||
OB << "\\t";
|
||||
return;
|
||||
case '\v': // vertical tab
|
||||
OS << "\\v";
|
||||
OB << "\\v";
|
||||
return;
|
||||
default:
|
||||
break;
|
||||
@@ -1174,11 +1175,11 @@ static void outputEscapedChar(OutputStream &OS, unsigned C) {
|
||||
|
||||
if (C > 0x1F && C < 0x7F) {
|
||||
// Standard ascii char.
|
||||
OS << (char)C;
|
||||
OB << (char)C;
|
||||
return;
|
||||
}
|
||||
|
||||
outputHex(OS, C);
|
||||
outputHex(OB, C);
|
||||
}
|
||||
|
||||
static unsigned countTrailingNullBytes(const uint8_t *StringBytes, int Length) {
|
||||
@@ -1273,18 +1274,17 @@ FunctionSymbolNode *Demangler::demangleVcallThunkNode(StringView &MangledName) {
|
||||
EncodedStringLiteralNode *
|
||||
Demangler::demangleStringLiteral(StringView &MangledName) {
|
||||
// This function uses goto, so declare all variables up front.
|
||||
OutputStream OS;
|
||||
OutputBuffer OB;
|
||||
StringView CRC;
|
||||
uint64_t StringByteSize;
|
||||
bool IsWcharT = false;
|
||||
bool IsNegative = false;
|
||||
size_t CrcEndPos = 0;
|
||||
char *ResultBuffer = nullptr;
|
||||
|
||||
EncodedStringLiteralNode *Result = Arena.alloc<EncodedStringLiteralNode>();
|
||||
|
||||
// Must happen before the first `goto StringLiteralError`.
|
||||
if (!initializeOutputStream(nullptr, nullptr, OS, 1024))
|
||||
if (!initializeOutputBuffer(nullptr, nullptr, OB, 1024))
|
||||
// FIXME: Propagate out-of-memory as an error?
|
||||
std::terminate();
|
||||
|
||||
@@ -1329,7 +1329,7 @@ Demangler::demangleStringLiteral(StringView &MangledName) {
|
||||
goto StringLiteralError;
|
||||
wchar_t W = demangleWcharLiteral(MangledName);
|
||||
if (StringByteSize != 2 || Result->IsTruncated)
|
||||
outputEscapedChar(OS, W);
|
||||
outputEscapedChar(OB, W);
|
||||
StringByteSize -= 2;
|
||||
if (Error)
|
||||
goto StringLiteralError;
|
||||
@@ -1371,19 +1371,17 @@ Demangler::demangleStringLiteral(StringView &MangledName) {
|
||||
unsigned NextChar =
|
||||
decodeMultiByteChar(StringBytes, CharIndex, CharBytes);
|
||||
if (CharIndex + 1 < NumChars || Result->IsTruncated)
|
||||
outputEscapedChar(OS, NextChar);
|
||||
outputEscapedChar(OB, NextChar);
|
||||
}
|
||||
}
|
||||
|
||||
OS << '\0';
|
||||
ResultBuffer = OS.getBuffer();
|
||||
Result->DecodedString = copyString(ResultBuffer);
|
||||
std::free(ResultBuffer);
|
||||
Result->DecodedString = copyString(OB);
|
||||
std::free(OB.getBuffer());
|
||||
return Result;
|
||||
|
||||
StringLiteralError:
|
||||
Error = true;
|
||||
std::free(OS.getBuffer());
|
||||
std::free(OB.getBuffer());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -1447,18 +1445,17 @@ Demangler::demangleLocallyScopedNamePiece(StringView &MangledName) {
|
||||
return nullptr;
|
||||
|
||||
// Render the parent symbol's name into a buffer.
|
||||
OutputStream OS;
|
||||
if (!initializeOutputStream(nullptr, nullptr, OS, 1024))
|
||||
OutputBuffer OB;
|
||||
if (!initializeOutputBuffer(nullptr, nullptr, OB, 1024))
|
||||
// FIXME: Propagate out-of-memory as an error?
|
||||
std::terminate();
|
||||
OS << '`';
|
||||
Scope->output(OS, OF_Default);
|
||||
OS << '\'';
|
||||
OS << "::`" << Number << "'";
|
||||
OS << '\0';
|
||||
char *Result = OS.getBuffer();
|
||||
Identifier->Name = copyString(Result);
|
||||
std::free(Result);
|
||||
OB << '`';
|
||||
Scope->output(OB, OF_Default);
|
||||
OB << '\'';
|
||||
OB << "::`" << Number << "'";
|
||||
|
||||
Identifier->Name = copyString(OB);
|
||||
std::free(OB.getBuffer());
|
||||
return Identifier;
|
||||
}
|
||||
|
||||
@@ -1711,6 +1708,10 @@ CallingConv Demangler::demangleCallingConvention(StringView &MangledName) {
|
||||
return CallingConv::Eabi;
|
||||
case 'Q':
|
||||
return CallingConv::Vectorcall;
|
||||
case 'S':
|
||||
return CallingConv::Swift;
|
||||
case 'W':
|
||||
return CallingConv::SwiftAsync;
|
||||
}
|
||||
|
||||
return CallingConv::None;
|
||||
@@ -2309,19 +2310,19 @@ void Demangler::dumpBackReferences() {
|
||||
(int)Backrefs.FunctionParamCount);
|
||||
|
||||
// Create an output stream so we can render each type.
|
||||
OutputStream OS;
|
||||
if (!initializeOutputStream(nullptr, nullptr, OS, 1024))
|
||||
OutputBuffer OB;
|
||||
if (!initializeOutputBuffer(nullptr, nullptr, OB, 1024))
|
||||
std::terminate();
|
||||
for (size_t I = 0; I < Backrefs.FunctionParamCount; ++I) {
|
||||
OS.setCurrentPosition(0);
|
||||
OB.setCurrentPosition(0);
|
||||
|
||||
TypeNode *T = Backrefs.FunctionParams[I];
|
||||
T->output(OS, OF_Default);
|
||||
T->output(OB, OF_Default);
|
||||
|
||||
std::printf(" [%d] - %.*s\n", (int)I, (int)OS.getCurrentPosition(),
|
||||
OS.getBuffer());
|
||||
StringView B = OB;
|
||||
std::printf(" [%d] - %.*s\n", (int)I, (int)B.size(), B.begin());
|
||||
}
|
||||
std::free(OS.getBuffer());
|
||||
std::free(OB.getBuffer());
|
||||
|
||||
if (Backrefs.FunctionParamCount > 0)
|
||||
std::printf("\n");
|
||||
@@ -2338,7 +2339,7 @@ char *llvm::microsoftDemangle(const char *MangledName, size_t *NMangled,
|
||||
char *Buf, size_t *N,
|
||||
int *Status, MSDemangleFlags Flags) {
|
||||
Demangler D;
|
||||
OutputStream S;
|
||||
OutputBuffer OB;
|
||||
|
||||
StringView Name{MangledName};
|
||||
SymbolNode *AST = D.parse(Name);
|
||||
@@ -2357,18 +2358,20 @@ char *llvm::microsoftDemangle(const char *MangledName, size_t *NMangled,
|
||||
OF = OutputFlags(OF | OF_NoReturnType);
|
||||
if (Flags & MSDF_NoMemberType)
|
||||
OF = OutputFlags(OF | OF_NoMemberType);
|
||||
if (Flags & MSDF_NoVariableType)
|
||||
OF = OutputFlags(OF | OF_NoVariableType);
|
||||
|
||||
int InternalStatus = demangle_success;
|
||||
if (D.Error)
|
||||
InternalStatus = demangle_invalid_mangled_name;
|
||||
else if (!initializeOutputStream(Buf, N, S, 1024))
|
||||
else if (!initializeOutputBuffer(Buf, N, OB, 1024))
|
||||
InternalStatus = demangle_memory_alloc_failure;
|
||||
else {
|
||||
AST->output(S, OF);
|
||||
S += '\0';
|
||||
AST->output(OB, OF);
|
||||
OB += '\0';
|
||||
if (N != nullptr)
|
||||
*N = S.getCurrentPosition();
|
||||
Buf = S.getBuffer();
|
||||
*N = OB.getCurrentPosition();
|
||||
Buf = OB.getBuffer();
|
||||
}
|
||||
|
||||
if (Status)
|
||||
@@ -11,7 +11,6 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/Demangle/MicrosoftDemangleNodes.h"
|
||||
#include "llvm/Demangle/DemangleConfig.h"
|
||||
#include "llvm/Demangle/Utility.h"
|
||||
#include <cctype>
|
||||
#include <string>
|
||||
@@ -21,91 +20,97 @@ using namespace ms_demangle;
|
||||
|
||||
#define OUTPUT_ENUM_CLASS_VALUE(Enum, Value, Desc) \
|
||||
case Enum::Value: \
|
||||
OS << Desc; \
|
||||
OB << Desc; \
|
||||
break;
|
||||
|
||||
// Writes a space if the last token does not end with a punctuation.
|
||||
static void outputSpaceIfNecessary(OutputStream &OS) {
|
||||
if (OS.empty())
|
||||
static void outputSpaceIfNecessary(OutputBuffer &OB) {
|
||||
if (OB.empty())
|
||||
return;
|
||||
|
||||
char C = OS.back();
|
||||
char C = OB.back();
|
||||
if (std::isalnum(C) || C == '>')
|
||||
OS << " ";
|
||||
OB << " ";
|
||||
}
|
||||
|
||||
static void outputSingleQualifier(OutputStream &OS, Qualifiers Q) {
|
||||
static void outputSingleQualifier(OutputBuffer &OB, Qualifiers Q) {
|
||||
switch (Q) {
|
||||
case Q_Const:
|
||||
OS << "const";
|
||||
OB << "const";
|
||||
break;
|
||||
case Q_Volatile:
|
||||
OS << "volatile";
|
||||
OB << "volatile";
|
||||
break;
|
||||
case Q_Restrict:
|
||||
OS << "__restrict";
|
||||
OB << "__restrict";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static bool outputQualifierIfPresent(OutputStream &OS, Qualifiers Q,
|
||||
static bool outputQualifierIfPresent(OutputBuffer &OB, Qualifiers Q,
|
||||
Qualifiers Mask, bool NeedSpace) {
|
||||
if (!(Q & Mask))
|
||||
return NeedSpace;
|
||||
|
||||
if (NeedSpace)
|
||||
OS << " ";
|
||||
OB << " ";
|
||||
|
||||
outputSingleQualifier(OS, Mask);
|
||||
outputSingleQualifier(OB, Mask);
|
||||
return true;
|
||||
}
|
||||
|
||||
static void outputQualifiers(OutputStream &OS, Qualifiers Q, bool SpaceBefore,
|
||||
static void outputQualifiers(OutputBuffer &OB, Qualifiers Q, bool SpaceBefore,
|
||||
bool SpaceAfter) {
|
||||
if (Q == Q_None)
|
||||
return;
|
||||
|
||||
size_t Pos1 = OS.getCurrentPosition();
|
||||
SpaceBefore = outputQualifierIfPresent(OS, Q, Q_Const, SpaceBefore);
|
||||
SpaceBefore = outputQualifierIfPresent(OS, Q, Q_Volatile, SpaceBefore);
|
||||
SpaceBefore = outputQualifierIfPresent(OS, Q, Q_Restrict, SpaceBefore);
|
||||
size_t Pos2 = OS.getCurrentPosition();
|
||||
size_t Pos1 = OB.getCurrentPosition();
|
||||
SpaceBefore = outputQualifierIfPresent(OB, Q, Q_Const, SpaceBefore);
|
||||
SpaceBefore = outputQualifierIfPresent(OB, Q, Q_Volatile, SpaceBefore);
|
||||
SpaceBefore = outputQualifierIfPresent(OB, Q, Q_Restrict, SpaceBefore);
|
||||
size_t Pos2 = OB.getCurrentPosition();
|
||||
if (SpaceAfter && Pos2 > Pos1)
|
||||
OS << " ";
|
||||
OB << " ";
|
||||
}
|
||||
|
||||
static void outputCallingConvention(OutputStream &OS, CallingConv CC) {
|
||||
outputSpaceIfNecessary(OS);
|
||||
static void outputCallingConvention(OutputBuffer &OB, CallingConv CC) {
|
||||
outputSpaceIfNecessary(OB);
|
||||
|
||||
switch (CC) {
|
||||
case CallingConv::Cdecl:
|
||||
OS << "__cdecl";
|
||||
OB << "__cdecl";
|
||||
break;
|
||||
case CallingConv::Fastcall:
|
||||
OS << "__fastcall";
|
||||
OB << "__fastcall";
|
||||
break;
|
||||
case CallingConv::Pascal:
|
||||
OS << "__pascal";
|
||||
OB << "__pascal";
|
||||
break;
|
||||
case CallingConv::Regcall:
|
||||
OS << "__regcall";
|
||||
OB << "__regcall";
|
||||
break;
|
||||
case CallingConv::Stdcall:
|
||||
OS << "__stdcall";
|
||||
OB << "__stdcall";
|
||||
break;
|
||||
case CallingConv::Thiscall:
|
||||
OS << "__thiscall";
|
||||
OB << "__thiscall";
|
||||
break;
|
||||
case CallingConv::Eabi:
|
||||
OS << "__eabi";
|
||||
OB << "__eabi";
|
||||
break;
|
||||
case CallingConv::Vectorcall:
|
||||
OS << "__vectorcall";
|
||||
OB << "__vectorcall";
|
||||
break;
|
||||
case CallingConv::Clrcall:
|
||||
OS << "__clrcall";
|
||||
OB << "__clrcall";
|
||||
break;
|
||||
case CallingConv::Swift:
|
||||
OB << "__attribute__((__swiftcall__)) ";
|
||||
break;
|
||||
case CallingConv::SwiftAsync:
|
||||
OB << "__attribute__((__swiftasynccall__)) ";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -113,14 +118,16 @@ static void outputCallingConvention(OutputStream &OS, CallingConv CC) {
|
||||
}
|
||||
|
||||
std::string Node::toString(OutputFlags Flags) const {
|
||||
OutputStream OS;
|
||||
initializeOutputStream(nullptr, nullptr, OS, 1024);
|
||||
this->output(OS, Flags);
|
||||
OS << '\0';
|
||||
return {OS.getBuffer()};
|
||||
OutputBuffer OB;
|
||||
initializeOutputBuffer(nullptr, nullptr, OB, 1024);
|
||||
this->output(OB, Flags);
|
||||
StringView SV = OB;
|
||||
std::string Owned(SV.begin(), SV.end());
|
||||
std::free(OB.getBuffer());
|
||||
return Owned;
|
||||
}
|
||||
|
||||
void PrimitiveTypeNode::outputPre(OutputStream &OS, OutputFlags Flags) const {
|
||||
void PrimitiveTypeNode::outputPre(OutputBuffer &OB, OutputFlags Flags) const {
|
||||
switch (PrimKind) {
|
||||
OUTPUT_ENUM_CLASS_VALUE(PrimitiveKind, Void, "void");
|
||||
OUTPUT_ENUM_CLASS_VALUE(PrimitiveKind, Bool, "bool");
|
||||
@@ -144,107 +151,107 @@ void PrimitiveTypeNode::outputPre(OutputStream &OS, OutputFlags Flags) const {
|
||||
OUTPUT_ENUM_CLASS_VALUE(PrimitiveKind, Ldouble, "long double");
|
||||
OUTPUT_ENUM_CLASS_VALUE(PrimitiveKind, Nullptr, "std::nullptr_t");
|
||||
}
|
||||
outputQualifiers(OS, Quals, true, false);
|
||||
outputQualifiers(OB, Quals, true, false);
|
||||
}
|
||||
|
||||
void NodeArrayNode::output(OutputStream &OS, OutputFlags Flags) const {
|
||||
output(OS, Flags, ", ");
|
||||
void NodeArrayNode::output(OutputBuffer &OB, OutputFlags Flags) const {
|
||||
output(OB, Flags, ", ");
|
||||
}
|
||||
|
||||
void NodeArrayNode::output(OutputStream &OS, OutputFlags Flags,
|
||||
void NodeArrayNode::output(OutputBuffer &OB, OutputFlags Flags,
|
||||
StringView Separator) const {
|
||||
if (Count == 0)
|
||||
return;
|
||||
if (Nodes[0])
|
||||
Nodes[0]->output(OS, Flags);
|
||||
Nodes[0]->output(OB, Flags);
|
||||
for (size_t I = 1; I < Count; ++I) {
|
||||
OS << Separator;
|
||||
Nodes[I]->output(OS, Flags);
|
||||
OB << Separator;
|
||||
Nodes[I]->output(OB, Flags);
|
||||
}
|
||||
}
|
||||
|
||||
void EncodedStringLiteralNode::output(OutputStream &OS,
|
||||
void EncodedStringLiteralNode::output(OutputBuffer &OB,
|
||||
OutputFlags Flags) const {
|
||||
switch (Char) {
|
||||
case CharKind::Wchar:
|
||||
OS << "L\"";
|
||||
OB << "L\"";
|
||||
break;
|
||||
case CharKind::Char:
|
||||
OS << "\"";
|
||||
OB << "\"";
|
||||
break;
|
||||
case CharKind::Char16:
|
||||
OS << "u\"";
|
||||
OB << "u\"";
|
||||
break;
|
||||
case CharKind::Char32:
|
||||
OS << "U\"";
|
||||
OB << "U\"";
|
||||
break;
|
||||
}
|
||||
OS << DecodedString << "\"";
|
||||
OB << DecodedString << "\"";
|
||||
if (IsTruncated)
|
||||
OS << "...";
|
||||
OB << "...";
|
||||
}
|
||||
|
||||
void IntegerLiteralNode::output(OutputStream &OS, OutputFlags Flags) const {
|
||||
void IntegerLiteralNode::output(OutputBuffer &OB, OutputFlags Flags) const {
|
||||
if (IsNegative)
|
||||
OS << '-';
|
||||
OS << Value;
|
||||
OB << '-';
|
||||
OB << Value;
|
||||
}
|
||||
|
||||
void TemplateParameterReferenceNode::output(OutputStream &OS,
|
||||
void TemplateParameterReferenceNode::output(OutputBuffer &OB,
|
||||
OutputFlags Flags) const {
|
||||
if (ThunkOffsetCount > 0)
|
||||
OS << "{";
|
||||
OB << "{";
|
||||
else if (Affinity == PointerAffinity::Pointer)
|
||||
OS << "&";
|
||||
OB << "&";
|
||||
|
||||
if (Symbol) {
|
||||
Symbol->output(OS, Flags);
|
||||
Symbol->output(OB, Flags);
|
||||
if (ThunkOffsetCount > 0)
|
||||
OS << ", ";
|
||||
OB << ", ";
|
||||
}
|
||||
|
||||
if (ThunkOffsetCount > 0)
|
||||
OS << ThunkOffsets[0];
|
||||
OB << ThunkOffsets[0];
|
||||
for (int I = 1; I < ThunkOffsetCount; ++I) {
|
||||
OS << ", " << ThunkOffsets[I];
|
||||
OB << ", " << ThunkOffsets[I];
|
||||
}
|
||||
if (ThunkOffsetCount > 0)
|
||||
OS << "}";
|
||||
OB << "}";
|
||||
}
|
||||
|
||||
void IdentifierNode::outputTemplateParameters(OutputStream &OS,
|
||||
void IdentifierNode::outputTemplateParameters(OutputBuffer &OB,
|
||||
OutputFlags Flags) const {
|
||||
if (!TemplateParams)
|
||||
return;
|
||||
OS << "<";
|
||||
TemplateParams->output(OS, Flags);
|
||||
OS << ">";
|
||||
OB << "<";
|
||||
TemplateParams->output(OB, Flags);
|
||||
OB << ">";
|
||||
}
|
||||
|
||||
void DynamicStructorIdentifierNode::output(OutputStream &OS,
|
||||
void DynamicStructorIdentifierNode::output(OutputBuffer &OB,
|
||||
OutputFlags Flags) const {
|
||||
if (IsDestructor)
|
||||
OS << "`dynamic atexit destructor for ";
|
||||
OB << "`dynamic atexit destructor for ";
|
||||
else
|
||||
OS << "`dynamic initializer for ";
|
||||
OB << "`dynamic initializer for ";
|
||||
|
||||
if (Variable) {
|
||||
OS << "`";
|
||||
Variable->output(OS, Flags);
|
||||
OS << "''";
|
||||
OB << "`";
|
||||
Variable->output(OB, Flags);
|
||||
OB << "''";
|
||||
} else {
|
||||
OS << "'";
|
||||
Name->output(OS, Flags);
|
||||
OS << "''";
|
||||
OB << "'";
|
||||
Name->output(OB, Flags);
|
||||
OB << "''";
|
||||
}
|
||||
}
|
||||
|
||||
void NamedIdentifierNode::output(OutputStream &OS, OutputFlags Flags) const {
|
||||
OS << Name;
|
||||
outputTemplateParameters(OS, Flags);
|
||||
void NamedIdentifierNode::output(OutputBuffer &OB, OutputFlags Flags) const {
|
||||
OB << Name;
|
||||
outputTemplateParameters(OB, Flags);
|
||||
}
|
||||
|
||||
void IntrinsicFunctionIdentifierNode::output(OutputStream &OS,
|
||||
void IntrinsicFunctionIdentifierNode::output(OutputBuffer &OB,
|
||||
OutputFlags Flags) const {
|
||||
switch (Operator) {
|
||||
OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, New, "operator new");
|
||||
@@ -342,188 +349,188 @@ void IntrinsicFunctionIdentifierNode::output(OutputStream &OS,
|
||||
case IntrinsicFunctionKind::None:
|
||||
break;
|
||||
}
|
||||
outputTemplateParameters(OS, Flags);
|
||||
outputTemplateParameters(OB, Flags);
|
||||
}
|
||||
|
||||
void LocalStaticGuardIdentifierNode::output(OutputStream &OS,
|
||||
void LocalStaticGuardIdentifierNode::output(OutputBuffer &OB,
|
||||
OutputFlags Flags) const {
|
||||
if (IsThread)
|
||||
OS << "`local static thread guard'";
|
||||
OB << "`local static thread guard'";
|
||||
else
|
||||
OS << "`local static guard'";
|
||||
OB << "`local static guard'";
|
||||
if (ScopeIndex > 0)
|
||||
OS << "{" << ScopeIndex << "}";
|
||||
OB << "{" << ScopeIndex << "}";
|
||||
}
|
||||
|
||||
void ConversionOperatorIdentifierNode::output(OutputStream &OS,
|
||||
void ConversionOperatorIdentifierNode::output(OutputBuffer &OB,
|
||||
OutputFlags Flags) const {
|
||||
OS << "operator";
|
||||
outputTemplateParameters(OS, Flags);
|
||||
OS << " ";
|
||||
TargetType->output(OS, Flags);
|
||||
OB << "operator";
|
||||
outputTemplateParameters(OB, Flags);
|
||||
OB << " ";
|
||||
TargetType->output(OB, Flags);
|
||||
}
|
||||
|
||||
void StructorIdentifierNode::output(OutputStream &OS, OutputFlags Flags) const {
|
||||
void StructorIdentifierNode::output(OutputBuffer &OB, OutputFlags Flags) const {
|
||||
if (IsDestructor)
|
||||
OS << "~";
|
||||
Class->output(OS, Flags);
|
||||
outputTemplateParameters(OS, Flags);
|
||||
OB << "~";
|
||||
Class->output(OB, Flags);
|
||||
outputTemplateParameters(OB, Flags);
|
||||
}
|
||||
|
||||
void LiteralOperatorIdentifierNode::output(OutputStream &OS,
|
||||
void LiteralOperatorIdentifierNode::output(OutputBuffer &OB,
|
||||
OutputFlags Flags) const {
|
||||
OS << "operator \"\"" << Name;
|
||||
outputTemplateParameters(OS, Flags);
|
||||
OB << "operator \"\"" << Name;
|
||||
outputTemplateParameters(OB, Flags);
|
||||
}
|
||||
|
||||
void FunctionSignatureNode::outputPre(OutputStream &OS,
|
||||
void FunctionSignatureNode::outputPre(OutputBuffer &OB,
|
||||
OutputFlags Flags) const {
|
||||
if (!(Flags & OF_NoAccessSpecifier)) {
|
||||
if (FunctionClass & FC_Public)
|
||||
OS << "public: ";
|
||||
OB << "public: ";
|
||||
if (FunctionClass & FC_Protected)
|
||||
OS << "protected: ";
|
||||
OB << "protected: ";
|
||||
if (FunctionClass & FC_Private)
|
||||
OS << "private: ";
|
||||
OB << "private: ";
|
||||
}
|
||||
|
||||
if (!(Flags & OF_NoMemberType)) {
|
||||
if (!(FunctionClass & FC_Global)) {
|
||||
if (FunctionClass & FC_Static)
|
||||
OS << "static ";
|
||||
OB << "static ";
|
||||
}
|
||||
if (FunctionClass & FC_Virtual)
|
||||
OS << "virtual ";
|
||||
OB << "virtual ";
|
||||
|
||||
if (FunctionClass & FC_ExternC)
|
||||
OS << "extern \"C\" ";
|
||||
OB << "extern \"C\" ";
|
||||
}
|
||||
|
||||
if (!(Flags & OF_NoReturnType) && ReturnType) {
|
||||
ReturnType->outputPre(OS, Flags);
|
||||
OS << " ";
|
||||
ReturnType->outputPre(OB, Flags);
|
||||
OB << " ";
|
||||
}
|
||||
|
||||
if (!(Flags & OF_NoCallingConvention))
|
||||
outputCallingConvention(OS, CallConvention);
|
||||
outputCallingConvention(OB, CallConvention);
|
||||
}
|
||||
|
||||
void FunctionSignatureNode::outputPost(OutputStream &OS,
|
||||
void FunctionSignatureNode::outputPost(OutputBuffer &OB,
|
||||
OutputFlags Flags) const {
|
||||
if (!(FunctionClass & FC_NoParameterList)) {
|
||||
OS << "(";
|
||||
OB << "(";
|
||||
if (Params)
|
||||
Params->output(OS, Flags);
|
||||
Params->output(OB, Flags);
|
||||
else
|
||||
OS << "void";
|
||||
OB << "void";
|
||||
|
||||
if (IsVariadic) {
|
||||
if (OS.back() != '(')
|
||||
OS << ", ";
|
||||
OS << "...";
|
||||
if (OB.back() != '(')
|
||||
OB << ", ";
|
||||
OB << "...";
|
||||
}
|
||||
OS << ")";
|
||||
OB << ")";
|
||||
}
|
||||
|
||||
if (Quals & Q_Const)
|
||||
OS << " const";
|
||||
OB << " const";
|
||||
if (Quals & Q_Volatile)
|
||||
OS << " volatile";
|
||||
OB << " volatile";
|
||||
if (Quals & Q_Restrict)
|
||||
OS << " __restrict";
|
||||
OB << " __restrict";
|
||||
if (Quals & Q_Unaligned)
|
||||
OS << " __unaligned";
|
||||
OB << " __unaligned";
|
||||
|
||||
if (IsNoexcept)
|
||||
OS << " noexcept";
|
||||
OB << " noexcept";
|
||||
|
||||
if (RefQualifier == FunctionRefQualifier::Reference)
|
||||
OS << " &";
|
||||
OB << " &";
|
||||
else if (RefQualifier == FunctionRefQualifier::RValueReference)
|
||||
OS << " &&";
|
||||
OB << " &&";
|
||||
|
||||
if (!(Flags & OF_NoReturnType) && ReturnType)
|
||||
ReturnType->outputPost(OS, Flags);
|
||||
ReturnType->outputPost(OB, Flags);
|
||||
}
|
||||
|
||||
void ThunkSignatureNode::outputPre(OutputStream &OS, OutputFlags Flags) const {
|
||||
OS << "[thunk]: ";
|
||||
void ThunkSignatureNode::outputPre(OutputBuffer &OB, OutputFlags Flags) const {
|
||||
OB << "[thunk]: ";
|
||||
|
||||
FunctionSignatureNode::outputPre(OS, Flags);
|
||||
FunctionSignatureNode::outputPre(OB, Flags);
|
||||
}
|
||||
|
||||
void ThunkSignatureNode::outputPost(OutputStream &OS, OutputFlags Flags) const {
|
||||
void ThunkSignatureNode::outputPost(OutputBuffer &OB, OutputFlags Flags) const {
|
||||
if (FunctionClass & FC_StaticThisAdjust) {
|
||||
OS << "`adjustor{" << ThisAdjust.StaticOffset << "}'";
|
||||
OB << "`adjustor{" << ThisAdjust.StaticOffset << "}'";
|
||||
} else if (FunctionClass & FC_VirtualThisAdjust) {
|
||||
if (FunctionClass & FC_VirtualThisAdjustEx) {
|
||||
OS << "`vtordispex{" << ThisAdjust.VBPtrOffset << ", "
|
||||
OB << "`vtordispex{" << ThisAdjust.VBPtrOffset << ", "
|
||||
<< ThisAdjust.VBOffsetOffset << ", " << ThisAdjust.VtordispOffset
|
||||
<< ", " << ThisAdjust.StaticOffset << "}'";
|
||||
} else {
|
||||
OS << "`vtordisp{" << ThisAdjust.VtordispOffset << ", "
|
||||
OB << "`vtordisp{" << ThisAdjust.VtordispOffset << ", "
|
||||
<< ThisAdjust.StaticOffset << "}'";
|
||||
}
|
||||
}
|
||||
|
||||
FunctionSignatureNode::outputPost(OS, Flags);
|
||||
FunctionSignatureNode::outputPost(OB, Flags);
|
||||
}
|
||||
|
||||
void PointerTypeNode::outputPre(OutputStream &OS, OutputFlags Flags) const {
|
||||
void PointerTypeNode::outputPre(OutputBuffer &OB, OutputFlags Flags) const {
|
||||
if (Pointee->kind() == NodeKind::FunctionSignature) {
|
||||
// If this is a pointer to a function, don't output the calling convention.
|
||||
// It needs to go inside the parentheses.
|
||||
const FunctionSignatureNode *Sig =
|
||||
static_cast<const FunctionSignatureNode *>(Pointee);
|
||||
Sig->outputPre(OS, OF_NoCallingConvention);
|
||||
Sig->outputPre(OB, OF_NoCallingConvention);
|
||||
} else
|
||||
Pointee->outputPre(OS, Flags);
|
||||
Pointee->outputPre(OB, Flags);
|
||||
|
||||
outputSpaceIfNecessary(OS);
|
||||
outputSpaceIfNecessary(OB);
|
||||
|
||||
if (Quals & Q_Unaligned)
|
||||
OS << "__unaligned ";
|
||||
OB << "__unaligned ";
|
||||
|
||||
if (Pointee->kind() == NodeKind::ArrayType) {
|
||||
OS << "(";
|
||||
OB << "(";
|
||||
} else if (Pointee->kind() == NodeKind::FunctionSignature) {
|
||||
OS << "(";
|
||||
OB << "(";
|
||||
const FunctionSignatureNode *Sig =
|
||||
static_cast<const FunctionSignatureNode *>(Pointee);
|
||||
outputCallingConvention(OS, Sig->CallConvention);
|
||||
OS << " ";
|
||||
outputCallingConvention(OB, Sig->CallConvention);
|
||||
OB << " ";
|
||||
}
|
||||
|
||||
if (ClassParent) {
|
||||
ClassParent->output(OS, Flags);
|
||||
OS << "::";
|
||||
ClassParent->output(OB, Flags);
|
||||
OB << "::";
|
||||
}
|
||||
|
||||
switch (Affinity) {
|
||||
case PointerAffinity::Pointer:
|
||||
OS << "*";
|
||||
OB << "*";
|
||||
break;
|
||||
case PointerAffinity::Reference:
|
||||
OS << "&";
|
||||
OB << "&";
|
||||
break;
|
||||
case PointerAffinity::RValueReference:
|
||||
OS << "&&";
|
||||
OB << "&&";
|
||||
break;
|
||||
default:
|
||||
assert(false);
|
||||
}
|
||||
outputQualifiers(OS, Quals, false, false);
|
||||
outputQualifiers(OB, Quals, false, false);
|
||||
}
|
||||
|
||||
void PointerTypeNode::outputPost(OutputStream &OS, OutputFlags Flags) const {
|
||||
void PointerTypeNode::outputPost(OutputBuffer &OB, OutputFlags Flags) const {
|
||||
if (Pointee->kind() == NodeKind::ArrayType ||
|
||||
Pointee->kind() == NodeKind::FunctionSignature)
|
||||
OS << ")";
|
||||
OB << ")";
|
||||
|
||||
Pointee->outputPost(OS, Flags);
|
||||
Pointee->outputPost(OB, Flags);
|
||||
}
|
||||
|
||||
void TagTypeNode::outputPre(OutputStream &OS, OutputFlags Flags) const {
|
||||
void TagTypeNode::outputPre(OutputBuffer &OB, OutputFlags Flags) const {
|
||||
if (!(Flags & OF_NoTagSpecifier)) {
|
||||
switch (Tag) {
|
||||
OUTPUT_ENUM_CLASS_VALUE(TagKind, Class, "class");
|
||||
@@ -531,59 +538,59 @@ void TagTypeNode::outputPre(OutputStream &OS, OutputFlags Flags) const {
|
||||
OUTPUT_ENUM_CLASS_VALUE(TagKind, Union, "union");
|
||||
OUTPUT_ENUM_CLASS_VALUE(TagKind, Enum, "enum");
|
||||
}
|
||||
OS << " ";
|
||||
OB << " ";
|
||||
}
|
||||
QualifiedName->output(OS, Flags);
|
||||
outputQualifiers(OS, Quals, true, false);
|
||||
QualifiedName->output(OB, Flags);
|
||||
outputQualifiers(OB, Quals, true, false);
|
||||
}
|
||||
|
||||
void TagTypeNode::outputPost(OutputStream &OS, OutputFlags Flags) const {}
|
||||
void TagTypeNode::outputPost(OutputBuffer &OB, OutputFlags Flags) const {}
|
||||
|
||||
void ArrayTypeNode::outputPre(OutputStream &OS, OutputFlags Flags) const {
|
||||
ElementType->outputPre(OS, Flags);
|
||||
outputQualifiers(OS, Quals, true, false);
|
||||
void ArrayTypeNode::outputPre(OutputBuffer &OB, OutputFlags Flags) const {
|
||||
ElementType->outputPre(OB, Flags);
|
||||
outputQualifiers(OB, Quals, true, false);
|
||||
}
|
||||
|
||||
void ArrayTypeNode::outputOneDimension(OutputStream &OS, OutputFlags Flags,
|
||||
void ArrayTypeNode::outputOneDimension(OutputBuffer &OB, OutputFlags Flags,
|
||||
Node *N) const {
|
||||
assert(N->kind() == NodeKind::IntegerLiteral);
|
||||
IntegerLiteralNode *ILN = static_cast<IntegerLiteralNode *>(N);
|
||||
if (ILN->Value != 0)
|
||||
ILN->output(OS, Flags);
|
||||
ILN->output(OB, Flags);
|
||||
}
|
||||
|
||||
void ArrayTypeNode::outputDimensionsImpl(OutputStream &OS,
|
||||
void ArrayTypeNode::outputDimensionsImpl(OutputBuffer &OB,
|
||||
OutputFlags Flags) const {
|
||||
if (Dimensions->Count == 0)
|
||||
return;
|
||||
|
||||
outputOneDimension(OS, Flags, Dimensions->Nodes[0]);
|
||||
outputOneDimension(OB, Flags, Dimensions->Nodes[0]);
|
||||
for (size_t I = 1; I < Dimensions->Count; ++I) {
|
||||
OS << "][";
|
||||
outputOneDimension(OS, Flags, Dimensions->Nodes[I]);
|
||||
OB << "][";
|
||||
outputOneDimension(OB, Flags, Dimensions->Nodes[I]);
|
||||
}
|
||||
}
|
||||
|
||||
void ArrayTypeNode::outputPost(OutputStream &OS, OutputFlags Flags) const {
|
||||
OS << "[";
|
||||
outputDimensionsImpl(OS, Flags);
|
||||
OS << "]";
|
||||
void ArrayTypeNode::outputPost(OutputBuffer &OB, OutputFlags Flags) const {
|
||||
OB << "[";
|
||||
outputDimensionsImpl(OB, Flags);
|
||||
OB << "]";
|
||||
|
||||
ElementType->outputPost(OS, Flags);
|
||||
ElementType->outputPost(OB, Flags);
|
||||
}
|
||||
|
||||
void SymbolNode::output(OutputStream &OS, OutputFlags Flags) const {
|
||||
Name->output(OS, Flags);
|
||||
void SymbolNode::output(OutputBuffer &OB, OutputFlags Flags) const {
|
||||
Name->output(OB, Flags);
|
||||
}
|
||||
|
||||
void FunctionSymbolNode::output(OutputStream &OS, OutputFlags Flags) const {
|
||||
Signature->outputPre(OS, Flags);
|
||||
outputSpaceIfNecessary(OS);
|
||||
Name->output(OS, Flags);
|
||||
Signature->outputPost(OS, Flags);
|
||||
void FunctionSymbolNode::output(OutputBuffer &OB, OutputFlags Flags) const {
|
||||
Signature->outputPre(OB, Flags);
|
||||
outputSpaceIfNecessary(OB);
|
||||
Name->output(OB, Flags);
|
||||
Signature->outputPost(OB, Flags);
|
||||
}
|
||||
|
||||
void VariableSymbolNode::output(OutputStream &OS, OutputFlags Flags) const {
|
||||
void VariableSymbolNode::output(OutputBuffer &OB, OutputFlags Flags) const {
|
||||
const char *AccessSpec = nullptr;
|
||||
bool IsStatic = true;
|
||||
switch (SC) {
|
||||
@@ -601,53 +608,52 @@ void VariableSymbolNode::output(OutputStream &OS, OutputFlags Flags) const {
|
||||
break;
|
||||
}
|
||||
if (!(Flags & OF_NoAccessSpecifier) && AccessSpec)
|
||||
OS << AccessSpec << ": ";
|
||||
OB << AccessSpec << ": ";
|
||||
if (!(Flags & OF_NoMemberType) && IsStatic)
|
||||
OS << "static ";
|
||||
OB << "static ";
|
||||
|
||||
if (Type) {
|
||||
Type->outputPre(OS, Flags);
|
||||
outputSpaceIfNecessary(OS);
|
||||
if (!(Flags & OF_NoVariableType) && Type) {
|
||||
Type->outputPre(OB, Flags);
|
||||
outputSpaceIfNecessary(OB);
|
||||
}
|
||||
Name->output(OS, Flags);
|
||||
if (Type)
|
||||
Type->outputPost(OS, Flags);
|
||||
Name->output(OB, Flags);
|
||||
if (!(Flags & OF_NoVariableType) && Type)
|
||||
Type->outputPost(OB, Flags);
|
||||
}
|
||||
|
||||
void CustomTypeNode::outputPre(OutputStream &OS, OutputFlags Flags) const {
|
||||
Identifier->output(OS, Flags);
|
||||
void CustomTypeNode::outputPre(OutputBuffer &OB, OutputFlags Flags) const {
|
||||
Identifier->output(OB, Flags);
|
||||
}
|
||||
void CustomTypeNode::outputPost(OutputStream &OS, OutputFlags Flags) const {}
|
||||
void CustomTypeNode::outputPost(OutputBuffer &OB, OutputFlags Flags) const {}
|
||||
|
||||
void QualifiedNameNode::output(OutputStream &OS, OutputFlags Flags) const {
|
||||
Components->output(OS, Flags, "::");
|
||||
void QualifiedNameNode::output(OutputBuffer &OB, OutputFlags Flags) const {
|
||||
Components->output(OB, Flags, "::");
|
||||
}
|
||||
|
||||
void RttiBaseClassDescriptorNode::output(OutputStream &OS,
|
||||
void RttiBaseClassDescriptorNode::output(OutputBuffer &OB,
|
||||
OutputFlags Flags) const {
|
||||
OS << "`RTTI Base Class Descriptor at (";
|
||||
OS << NVOffset << ", " << VBPtrOffset << ", " << VBTableOffset << ", "
|
||||
OB << "`RTTI Base Class Descriptor at (";
|
||||
OB << NVOffset << ", " << VBPtrOffset << ", " << VBTableOffset << ", "
|
||||
<< this->Flags;
|
||||
OS << ")'";
|
||||
OB << ")'";
|
||||
}
|
||||
|
||||
void LocalStaticGuardVariableNode::output(OutputStream &OS,
|
||||
void LocalStaticGuardVariableNode::output(OutputBuffer &OB,
|
||||
OutputFlags Flags) const {
|
||||
Name->output(OS, Flags);
|
||||
Name->output(OB, Flags);
|
||||
}
|
||||
|
||||
void VcallThunkIdentifierNode::output(OutputStream &OS,
|
||||
void VcallThunkIdentifierNode::output(OutputBuffer &OB,
|
||||
OutputFlags Flags) const {
|
||||
OS << "`vcall'{" << OffsetInVTable << ", {flat}}";
|
||||
OB << "`vcall'{" << OffsetInVTable << ", {flat}}";
|
||||
}
|
||||
|
||||
void SpecialTableSymbolNode::output(OutputStream &OS, OutputFlags Flags) const {
|
||||
outputQualifiers(OS, Quals, false, true);
|
||||
Name->output(OS, Flags);
|
||||
void SpecialTableSymbolNode::output(OutputBuffer &OB, OutputFlags Flags) const {
|
||||
outputQualifiers(OB, Quals, false, true);
|
||||
Name->output(OB, Flags);
|
||||
if (TargetName) {
|
||||
OS << "{for `";
|
||||
TargetName->output(OS, Flags);
|
||||
OS << "'}";
|
||||
OB << "{for `";
|
||||
TargetName->output(OB, Flags);
|
||||
OB << "'}";
|
||||
}
|
||||
return;
|
||||
}
|
||||
1265
lib/external/llvm-demangle/source/RustDemangle.cpp
vendored
Normal file
1265
lib/external/llvm-demangle/source/RustDemangle.cpp
vendored
Normal file
File diff suppressed because it is too large
Load Diff
13
lib/external/llvm/CMakeLists.txt
vendored
13
lib/external/llvm/CMakeLists.txt
vendored
@@ -1,13 +0,0 @@
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
project(LLVMDemangle)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
|
||||
add_library(LLVMDemangle STATIC
|
||||
Demangle/Demangle.cpp
|
||||
Demangle/ItaniumDemangle.cpp
|
||||
Demangle/MicrosoftDemangle.cpp
|
||||
Demangle/MicrosoftDemangleNodes.cpp
|
||||
)
|
||||
|
||||
target_include_directories(LLVMDemangle PUBLIC include)
|
||||
36
lib/external/llvm/Demangle/Demangle.cpp
vendored
36
lib/external/llvm/Demangle/Demangle.cpp
vendored
@@ -1,36 +0,0 @@
|
||||
//===-- Demangle.cpp - Common demangling functions ------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
///
|
||||
/// \file This file contains definitions of common demangling functions.
|
||||
///
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/Demangle/Demangle.h"
|
||||
#include <cstdlib>
|
||||
|
||||
static bool isItaniumEncoding(const std::string &MangledName) {
|
||||
size_t Pos = MangledName.find_first_not_of('_');
|
||||
// A valid Itanium encoding requires 1-4 leading underscores, followed by 'Z'.
|
||||
return Pos > 0 && Pos <= 4 && MangledName[Pos] == 'Z';
|
||||
}
|
||||
|
||||
std::string llvm::demangle(const std::string &MangledName) {
|
||||
char *Demangled;
|
||||
if (isItaniumEncoding(MangledName))
|
||||
Demangled = itaniumDemangle(MangledName.c_str(), nullptr, nullptr, nullptr);
|
||||
else
|
||||
Demangled = microsoftDemangle(MangledName.c_str(), nullptr, nullptr,
|
||||
nullptr, nullptr);
|
||||
|
||||
if (!Demangled)
|
||||
return MangledName;
|
||||
|
||||
std::string Ret = Demangled;
|
||||
free(Demangled);
|
||||
return Ret;
|
||||
}
|
||||
191
lib/external/llvm/include/llvm/Demangle/Utility.h
vendored
191
lib/external/llvm/include/llvm/Demangle/Utility.h
vendored
@@ -1,191 +0,0 @@
|
||||
//===--- Utility.h ----------------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Provide some utility classes for use in the demangler(s).
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef DEMANGLE_UTILITY_H
|
||||
#define DEMANGLE_UTILITY_H
|
||||
|
||||
#include "StringView.h"
|
||||
#include <cstdint>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <iterator>
|
||||
#include <limits>
|
||||
|
||||
DEMANGLE_NAMESPACE_BEGIN
|
||||
|
||||
// Stream that AST nodes write their string representation into after the AST
|
||||
// has been parsed.
|
||||
class OutputStream {
|
||||
char *Buffer = nullptr;
|
||||
size_t CurrentPosition = 0;
|
||||
size_t BufferCapacity = 0;
|
||||
|
||||
// Ensure there is at least n more positions in buffer.
|
||||
void grow(size_t N) {
|
||||
if (N + CurrentPosition >= BufferCapacity) {
|
||||
BufferCapacity *= 2;
|
||||
if (BufferCapacity < N + CurrentPosition)
|
||||
BufferCapacity = N + CurrentPosition;
|
||||
Buffer = static_cast<char *>(std::realloc(Buffer, BufferCapacity));
|
||||
if (Buffer == nullptr)
|
||||
std::terminate();
|
||||
}
|
||||
}
|
||||
|
||||
void writeUnsigned(uint64_t N, bool isNeg = false) {
|
||||
// Handle special case...
|
||||
if (N == 0) {
|
||||
*this << '0';
|
||||
return;
|
||||
}
|
||||
|
||||
char Temp[21];
|
||||
char *TempPtr = std::end(Temp);
|
||||
|
||||
while (N) {
|
||||
*--TempPtr = '0' + char(N % 10);
|
||||
N /= 10;
|
||||
}
|
||||
|
||||
// Add negative sign...
|
||||
if (isNeg)
|
||||
*--TempPtr = '-';
|
||||
this->operator<<(StringView(TempPtr, std::end(Temp)));
|
||||
}
|
||||
|
||||
public:
|
||||
OutputStream(char *StartBuf, size_t Size)
|
||||
: Buffer(StartBuf), CurrentPosition(0), BufferCapacity(Size) {}
|
||||
OutputStream() = default;
|
||||
void reset(char *Buffer_, size_t BufferCapacity_) {
|
||||
CurrentPosition = 0;
|
||||
Buffer = Buffer_;
|
||||
BufferCapacity = BufferCapacity_;
|
||||
}
|
||||
|
||||
/// If a ParameterPackExpansion (or similar type) is encountered, the offset
|
||||
/// into the pack that we're currently printing.
|
||||
unsigned CurrentPackIndex = std::numeric_limits<unsigned>::max();
|
||||
unsigned CurrentPackMax = std::numeric_limits<unsigned>::max();
|
||||
|
||||
OutputStream &operator+=(StringView R) {
|
||||
size_t Size = R.size();
|
||||
if (Size == 0)
|
||||
return *this;
|
||||
grow(Size);
|
||||
std::memmove(Buffer + CurrentPosition, R.begin(), Size);
|
||||
CurrentPosition += Size;
|
||||
return *this;
|
||||
}
|
||||
|
||||
OutputStream &operator+=(char C) {
|
||||
grow(1);
|
||||
Buffer[CurrentPosition++] = C;
|
||||
return *this;
|
||||
}
|
||||
|
||||
OutputStream &operator<<(StringView R) { return (*this += R); }
|
||||
|
||||
OutputStream &operator<<(char C) { return (*this += C); }
|
||||
|
||||
OutputStream &operator<<(long long N) {
|
||||
if (N < 0)
|
||||
writeUnsigned(static_cast<unsigned long long>(-N), true);
|
||||
else
|
||||
writeUnsigned(static_cast<unsigned long long>(N));
|
||||
return *this;
|
||||
}
|
||||
|
||||
OutputStream &operator<<(unsigned long long N) {
|
||||
writeUnsigned(N, false);
|
||||
return *this;
|
||||
}
|
||||
|
||||
OutputStream &operator<<(long N) {
|
||||
return this->operator<<(static_cast<long long>(N));
|
||||
}
|
||||
|
||||
OutputStream &operator<<(unsigned long N) {
|
||||
return this->operator<<(static_cast<unsigned long long>(N));
|
||||
}
|
||||
|
||||
OutputStream &operator<<(int N) {
|
||||
return this->operator<<(static_cast<long long>(N));
|
||||
}
|
||||
|
||||
OutputStream &operator<<(unsigned int N) {
|
||||
return this->operator<<(static_cast<unsigned long long>(N));
|
||||
}
|
||||
|
||||
size_t getCurrentPosition() const { return CurrentPosition; }
|
||||
void setCurrentPosition(size_t NewPos) { CurrentPosition = NewPos; }
|
||||
|
||||
char back() const {
|
||||
return CurrentPosition ? Buffer[CurrentPosition - 1] : '\0';
|
||||
}
|
||||
|
||||
bool empty() const { return CurrentPosition == 0; }
|
||||
|
||||
char *getBuffer() { return Buffer; }
|
||||
char *getBufferEnd() { return Buffer + CurrentPosition - 1; }
|
||||
size_t getBufferCapacity() const { return BufferCapacity; }
|
||||
};
|
||||
|
||||
template <class T> class SwapAndRestore {
|
||||
T &Restore;
|
||||
T OriginalValue;
|
||||
bool ShouldRestore = true;
|
||||
|
||||
public:
|
||||
SwapAndRestore(T &Restore_) : SwapAndRestore(Restore_, Restore_) {}
|
||||
|
||||
SwapAndRestore(T &Restore_, T NewVal)
|
||||
: Restore(Restore_), OriginalValue(Restore) {
|
||||
Restore = std::move(NewVal);
|
||||
}
|
||||
~SwapAndRestore() {
|
||||
if (ShouldRestore)
|
||||
Restore = std::move(OriginalValue);
|
||||
}
|
||||
|
||||
void shouldRestore(bool ShouldRestore_) { ShouldRestore = ShouldRestore_; }
|
||||
|
||||
void restoreNow(bool Force) {
|
||||
if (!Force && !ShouldRestore)
|
||||
return;
|
||||
|
||||
Restore = std::move(OriginalValue);
|
||||
ShouldRestore = false;
|
||||
}
|
||||
|
||||
SwapAndRestore(const SwapAndRestore &) = delete;
|
||||
SwapAndRestore &operator=(const SwapAndRestore &) = delete;
|
||||
};
|
||||
|
||||
inline bool initializeOutputStream(char *Buf, size_t *N, OutputStream &S,
|
||||
size_t InitSize) {
|
||||
size_t BufferSize;
|
||||
if (Buf == nullptr) {
|
||||
Buf = static_cast<char *>(std::malloc(InitSize));
|
||||
if (Buf == nullptr)
|
||||
return false;
|
||||
BufferSize = InitSize;
|
||||
} else
|
||||
BufferSize = *N;
|
||||
|
||||
S.reset(Buf, BufferSize);
|
||||
return true;
|
||||
}
|
||||
|
||||
DEMANGLE_NAMESPACE_END
|
||||
|
||||
#endif
|
||||
12
lib/external/miniaudio/CMakeLists.txt
vendored
Normal file
12
lib/external/miniaudio/CMakeLists.txt
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
project(miniaudio)
|
||||
|
||||
add_library(miniaudio STATIC
|
||||
source/miniaudio.c
|
||||
)
|
||||
|
||||
target_include_directories(miniaudio PUBLIC include)
|
||||
|
||||
if (APPLE)
|
||||
set_source_files_properties(source/miniaudio.c PROPERTIES LANGUAGE OBJC)
|
||||
endif ()
|
||||
47
lib/external/miniaudio/LICENSE
vendored
Normal file
47
lib/external/miniaudio/LICENSE
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
This software is available as a choice of the following licenses. Choose
|
||||
whichever you prefer.
|
||||
|
||||
===============================================================================
|
||||
ALTERNATIVE 1 - Public Domain (www.unlicense.org)
|
||||
===============================================================================
|
||||
This is free and unencumbered software released into the public domain.
|
||||
|
||||
Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
|
||||
software, either in source code form or as a compiled binary, for any purpose,
|
||||
commercial or non-commercial, and by any means.
|
||||
|
||||
In jurisdictions that recognize copyright laws, the author or authors of this
|
||||
software dedicate any and all copyright interest in the software to the public
|
||||
domain. We make this dedication for the benefit of the public at large and to
|
||||
the detriment of our heirs and successors. We intend this dedication to be an
|
||||
overt act of relinquishment in perpetuity of all present and future rights to
|
||||
this software under copyright law.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
For more information, please refer to <http://unlicense.org/>
|
||||
|
||||
===============================================================================
|
||||
ALTERNATIVE 2 - MIT No Attribution
|
||||
===============================================================================
|
||||
Copyright 2020 David Reid
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
7509
lib/external/miniaudio/include/miniaudio.h
vendored
Normal file
7509
lib/external/miniaudio/include/miniaudio.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
80169
lib/external/miniaudio/source/miniaudio.c
vendored
Normal file
80169
lib/external/miniaudio/source/miniaudio.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
2
lib/external/nativefiledialog
vendored
2
lib/external/nativefiledialog
vendored
Submodule lib/external/nativefiledialog updated: 3311592818...6efc824070
2
lib/external/pattern_language
vendored
2
lib/external/pattern_language
vendored
Submodule lib/external/pattern_language updated: a8c44795db...565df62329
25
lib/external/yara/CMakeLists.txt
vendored
25
lib/external/yara/CMakeLists.txt
vendored
@@ -95,23 +95,24 @@ set(LIBYARA_MODULES
|
||||
${LIBYARA_SOURCE_PATH}/modules/time/time.c
|
||||
)
|
||||
|
||||
# Add mbedtls crypto wrappers
|
||||
add_compile_definitions("HAVE_MBEDTLS")
|
||||
|
||||
add_compile_definitions("USE_NO_PROC")
|
||||
|
||||
add_compile_definitions("HASH_MODULE")
|
||||
add_compile_definitions("DOTNET_MODULE")
|
||||
add_compile_definitions("MAGIC_MODULE")
|
||||
add_compile_definitions("MACHO_MODULE")
|
||||
add_compile_definitions("DEX_MODULE")
|
||||
|
||||
find_package(mbedTLS 2.26.0 REQUIRED)
|
||||
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-shift-count-overflow")
|
||||
add_library(libyara STATIC ${LIBYARA_SOURCE} ${LIBYARA_INCLUDES} ${LIBYARA_MODULES})
|
||||
set_property(TARGET libyara PROPERTY POSITION_INDEPENDENT_CODE ON)
|
||||
|
||||
# Add mbedtls crypto wrappers
|
||||
target_compile_definitions(libyara PRIVATE HAVE_MBEDTLS)
|
||||
|
||||
target_compile_definitions(libyara PRIVATE USE_NO_PROC)
|
||||
|
||||
target_compile_definitions(libyara PRIVATE HASH_MODULE)
|
||||
target_compile_definitions(libyara PRIVATE DOTNET_MODULE)
|
||||
target_compile_definitions(libyara PRIVATE MAGIC_MODULE)
|
||||
target_compile_definitions(libyara PRIVATE MACHO_MODULE)
|
||||
target_compile_definitions(libyara PRIVATE DEX_MODULE)
|
||||
|
||||
target_compile_options(libyara PRIVATE "-Wno-shift-count-overflow")
|
||||
|
||||
target_include_directories(
|
||||
libyara
|
||||
PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/yara> $<BUILD_INTERFACE:${LIBYARA_SOURCE_PATH}/include> $<INSTALL_INTERFACE:include>
|
||||
|
||||
2
lib/external/yara/yara
vendored
2
lib/external/yara/yara
vendored
Submodule lib/external/yara/yara updated: d5a7565a8b...ba94b4f8eb
808
lib/libimhex-rs/Cargo.lock
generated
808
lib/libimhex-rs/Cargo.lock
generated
@@ -1,808 +0,0 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "0.7.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ansi_term"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2"
|
||||
dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "aquamarine"
|
||||
version = "0.1.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "96e14cb2a51c8b45d26a4219981985c7350fc05eacb7b5b2939bceb2ffefdf3e"
|
||||
dependencies = [
|
||||
"itertools 0.9.0",
|
||||
"proc-macro-error",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "atty"
|
||||
version = "0.2.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
|
||||
dependencies = [
|
||||
"hermit-abi",
|
||||
"libc",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "autocxx"
|
||||
version = "0.16.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "13e6384cb95b48be8c5b83764ef800858322436f57aa17974915d23dadb6a7d5"
|
||||
dependencies = [
|
||||
"aquamarine",
|
||||
"autocxx-engine",
|
||||
"autocxx-macro",
|
||||
"cxx",
|
||||
"moveit",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "autocxx-bindgen"
|
||||
version = "0.59.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6e603c1eb79e21068072ef990e5463f613e0cedddd6712ff11afeae2a90b2510"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"cexpr",
|
||||
"clang-sys",
|
||||
"clap",
|
||||
"env_logger",
|
||||
"itertools 0.10.3",
|
||||
"lazy_static",
|
||||
"lazycell",
|
||||
"log",
|
||||
"peeking_take_while",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"regex",
|
||||
"rustc-hash",
|
||||
"shlex",
|
||||
"which",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "autocxx-build"
|
||||
version = "0.16.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4a5f5b45a4fe71d3ac68d8b4fd11abe54c791046ec4def7effe27961269b6ab3"
|
||||
dependencies = [
|
||||
"autocxx-engine",
|
||||
"env_logger",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "autocxx-engine"
|
||||
version = "0.16.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "02323905bec49fde96ff028fcff1c478d0eba14fa34ea5eb5e4d17439748e42a"
|
||||
dependencies = [
|
||||
"aquamarine",
|
||||
"autocxx-bindgen",
|
||||
"autocxx-parser",
|
||||
"cc",
|
||||
"cxx",
|
||||
"cxx-gen",
|
||||
"indoc",
|
||||
"itertools 0.10.3",
|
||||
"log",
|
||||
"once_cell",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"serde_json",
|
||||
"strum_macros",
|
||||
"syn",
|
||||
"tempfile",
|
||||
"unzip-n",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "autocxx-macro"
|
||||
version = "0.16.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8106ca477cbe6edf188311f2e05606b81bf463c41748ce7120c31d1b11875515"
|
||||
dependencies = [
|
||||
"autocxx-parser",
|
||||
"proc-macro-error",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "autocxx-parser"
|
||||
version = "0.16.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ad0ad08260adcecc119b08f460b0633b6e306ea2f6fda4f27e4dd28e20b9a2f4"
|
||||
dependencies = [
|
||||
"log",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.70"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d26a6ce4b6a484fa3edb70f7efa6fc430fd2b87285fe8b84304fd0936faa0dc0"
|
||||
|
||||
[[package]]
|
||||
name = "cexpr"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766"
|
||||
dependencies = [
|
||||
"nom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "chlorine"
|
||||
version = "1.0.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bd650552110e39b7c5058986cf177decd3365841836578ac50a286094eac0be6"
|
||||
|
||||
[[package]]
|
||||
name = "clang-sys"
|
||||
version = "1.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4cc00842eed744b858222c4c9faf7243aafc6d33f92f96935263ef4d8a41ce21"
|
||||
dependencies = [
|
||||
"glob",
|
||||
"libc",
|
||||
"libloading",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "2.34.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c"
|
||||
dependencies = [
|
||||
"ansi_term",
|
||||
"atty",
|
||||
"bitflags",
|
||||
"strsim",
|
||||
"textwrap",
|
||||
"unicode-width",
|
||||
"vec_map",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "codespan-reporting"
|
||||
version = "0.11.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e"
|
||||
dependencies = [
|
||||
"termcolor",
|
||||
"unicode-width",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cxx"
|
||||
version = "1.0.55"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "638fb099591b763a988ca69e5f0ee4b82bedb8bc762b3c6cfbfdd3a6dc6b54b4"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"cxxbridge-flags",
|
||||
"cxxbridge-macro",
|
||||
"link-cplusplus",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cxx-gen"
|
||||
version = "0.7.65"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "836e95ae34fc21fb39c206444879afda2c6e704424c9c621662764f1b459e83a"
|
||||
dependencies = [
|
||||
"codespan-reporting",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cxxbridge-flags"
|
||||
version = "1.0.55"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "44d4bde25840be4cf0eb1d7e3a74634105189d5609b855bcc8d601ffb037f5f4"
|
||||
|
||||
[[package]]
|
||||
name = "cxxbridge-macro"
|
||||
version = "1.0.55"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3869bf8972075de8f0446b433d40026f2dfdbd8a9edbc24e9d645ca2ebf2f93a"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "either"
|
||||
version = "1.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"
|
||||
|
||||
[[package]]
|
||||
name = "env_logger"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0b2cf0344971ee6c64c31be0d530793fba457d322dfec2810c453d0ef228f9c3"
|
||||
dependencies = [
|
||||
"atty",
|
||||
"humantime",
|
||||
"log",
|
||||
"regex",
|
||||
"termcolor",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fastrand"
|
||||
version = "1.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c3fcf0cee53519c866c09b5de1f6c56ff9d647101f81c1964fa632e148896cdf"
|
||||
dependencies = [
|
||||
"instant",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "glob"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574"
|
||||
|
||||
[[package]]
|
||||
name = "heck"
|
||||
version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c"
|
||||
dependencies = [
|
||||
"unicode-segmentation",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.1.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "humantime"
|
||||
version = "2.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
|
||||
|
||||
[[package]]
|
||||
name = "imgui"
|
||||
version = "0.8.0"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"imgui-sys",
|
||||
"parking_lot",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "imgui-sys"
|
||||
version = "0.8.0"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"chlorine",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "imhex-macros"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "indoc"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e7906a9fababaeacb774f72410e497a1d18de916322e33797bb2cd29baa23c9e"
|
||||
dependencies = [
|
||||
"unindent",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "instant"
|
||||
version = "0.1.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "716d3d89f35ac6a34fd0eed635395f4c3b76fa889338a4632e5231a8684216bd"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itertools"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "284f18f85651fe11e8a991b2adb42cb078325c996ed026d994719efcfca1d54b"
|
||||
dependencies = [
|
||||
"either",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itertools"
|
||||
version = "0.10.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a9a9d19fa1e79b6215ff29b9d6880b706147f16e9b1dbb1e4e5947b5b02bc5e3"
|
||||
dependencies = [
|
||||
"either",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35"
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||
|
||||
[[package]]
|
||||
name = "lazycell"
|
||||
version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.103"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dd8f7255a17a627354f321ef0055d63b898c6fb27eff628af4d1b66b7331edf6"
|
||||
|
||||
[[package]]
|
||||
name = "libimhex-rs"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"autocxx",
|
||||
"autocxx-build",
|
||||
"cxx",
|
||||
"imgui",
|
||||
"imhex-macros",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libloading"
|
||||
version = "0.7.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "efbc0f03f9a775e9f6aed295c6a1ba2253c5757a9e03d55c6caa46a681abcddd"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "link-cplusplus"
|
||||
version = "1.0.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f1becd27d473556dc610b8afa1636ef90747b574a84553bc11e82371d5ef2d1"
|
||||
dependencies = [
|
||||
"cc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lock_api"
|
||||
version = "0.4.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "712a4d093c9976e24e7dbca41db895dabcbac38eb5f4045393d17a95bdfb1109"
|
||||
dependencies = [
|
||||
"scopeguard",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a"
|
||||
|
||||
[[package]]
|
||||
name = "minimal-lexical"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
|
||||
|
||||
[[package]]
|
||||
name = "moveit"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bd833d6adefa6bcfc56948d061c1d697dfa3ab63711963c7ef4aa23eda945676"
|
||||
dependencies = [
|
||||
"cxx",
|
||||
]
|
||||
|
||||
[[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 = "once_cell"
|
||||
version = "1.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "da32515d9f6e6e489d7bc9d84c71b060db7247dc035bbe44eac88cf87486d8d5"
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot"
|
||||
version = "0.11.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99"
|
||||
dependencies = [
|
||||
"instant",
|
||||
"lock_api",
|
||||
"parking_lot_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot_core"
|
||||
version = "0.8.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d76e8e1493bcac0d2766c42737f34458f1c8c50c0d23bcb24ea953affb273216"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"instant",
|
||||
"libc",
|
||||
"redox_syscall",
|
||||
"smallvec",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "peeking_take_while"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-error"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
|
||||
dependencies = [
|
||||
"proc-macro-error-attr",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-error-attr"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.29"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b9f5105d4fdaab20335ca9565e106a5d9b82b6219b5ba735731124ac6711d23d"
|
||||
dependencies = [
|
||||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.2.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8383f39639269cde97d255a32bdb68c047337295414940c68bdd30c2e13203ff"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.5.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d83f127d94bdbcda4c8cc2e50f6f84f4b611f69c902699ca385a39c3a75f9ff1"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
"regex-syntax",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.6.26"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "49b3de9ec5dc0a3417da371aab17d729997c15010e7fd24ff707773a33bddb64"
|
||||
|
||||
[[package]]
|
||||
name = "remove_dir_all"
|
||||
version = "0.5.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7"
|
||||
dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc-hash"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
|
||||
|
||||
[[package]]
|
||||
name = "rustversion"
|
||||
version = "1.0.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f2cc38e8fa666e2de3c4aba7edeb5ffc5246c1c2ed0e3d17e560aeeba736b23f"
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f"
|
||||
|
||||
[[package]]
|
||||
name = "scopeguard"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.136"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ce31e24b01e1e524df96f1c2fdd054405f8d7376249a5110886fb4b658484789"
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.136"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "08597e7152fcd306f41838ed3e37be9eaeed2b61c42e2117266a554fab4662f9"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.79"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8e8d9fa5c3b304765ce1fd9c4c8a3de2c8db365a5b91be52f186efc675681d95"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"ryu",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "shlex"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "43b2853a4d09f215c24cc5489c992ce46052d359b5109343cbafbf26bc62f8a3"
|
||||
|
||||
[[package]]
|
||||
name = "smallvec"
|
||||
version = "1.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1ecab6c735a6bb4139c0caafd0cc3635748bbb3acf4550e8138122099251f309"
|
||||
|
||||
[[package]]
|
||||
name = "strsim"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
|
||||
|
||||
[[package]]
|
||||
name = "strum_macros"
|
||||
version = "0.23.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5bb0dc7ee9c15cea6199cde9a127fa16a4c5819af85395457ad72d68edc85a38"
|
||||
dependencies = [
|
||||
"heck",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"rustversion",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.77"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5239bc68e0fef57495900cfea4e8dc75596d9a319d7e16b1e0a440d24e6fe0a0"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tempfile"
|
||||
version = "3.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"fastrand",
|
||||
"libc",
|
||||
"redox_syscall",
|
||||
"remove_dir_all",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "termcolor"
|
||||
version = "1.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2dfed899f0eb03f32ee8c6a0aabdb8a7949659e3466561fc0adf54e26d88c5f4"
|
||||
dependencies = [
|
||||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "textwrap"
|
||||
version = "0.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
|
||||
dependencies = [
|
||||
"unicode-width",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-segmentation"
|
||||
version = "1.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7e8820f5d777f6224dc4be3632222971ac30164d4a258d595640799554ebfd99"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-width"
|
||||
version = "0.1.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-xid"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
|
||||
|
||||
[[package]]
|
||||
name = "unindent"
|
||||
version = "0.1.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "514672a55d7380da379785a4d70ca8386c8883ff7eaae877be4d2081cebe73d8"
|
||||
|
||||
[[package]]
|
||||
name = "unzip-n"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c2e7e85a0596447f0f2ac090e16bc4c516c6fe91771fb0c0ccf7fa3dae896b9c"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "vec_map"
|
||||
version = "0.8.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191"
|
||||
|
||||
[[package]]
|
||||
name = "version_check"
|
||||
version = "0.9.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
|
||||
|
||||
[[package]]
|
||||
name = "which"
|
||||
version = "4.2.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2a5a7e487e921cf220206864a94a89b6c6905bfc19f1057fa26a4cb360e5c1d2"
|
||||
dependencies = [
|
||||
"either",
|
||||
"lazy_static",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
|
||||
dependencies = [
|
||||
"winapi-i686-pc-windows-gnu",
|
||||
"winapi-x86_64-pc-windows-gnu",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-i686-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-util"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
|
||||
dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-x86_64-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
@@ -1,18 +0,0 @@
|
||||
[package]
|
||||
name = "libimhex-rs"
|
||||
version = "0.1.0"
|
||||
edition = "2018"
|
||||
build = "build.rs"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
imhex-macros = { path = "proc_macros" }
|
||||
imgui = { path = "imgui-rs" }
|
||||
|
||||
cxx = "1.0.55"
|
||||
autocxx = "0.16"
|
||||
|
||||
[build-dependencies]
|
||||
autocxx-build = "0.16"
|
||||
#cxx-build = "1.0.55"
|
||||
@@ -1,26 +0,0 @@
|
||||
fn main() {
|
||||
println!("cargo:rustc-link-lib=dylib=imhex");
|
||||
println!(
|
||||
"cargo:rustc-link-search=all={}",
|
||||
env!("LIBIMHEX_OUTPUT_DIRECTORY")
|
||||
);
|
||||
|
||||
println!("cargo:rerun-if-changed=src/lib.rs");
|
||||
println!("cargo:rerun-if-changed=src/imhex_api.rs");
|
||||
|
||||
let include = format!("-I{}/include", env!("LIBIMHEX_SOURCE_DIRECTORY"));
|
||||
|
||||
let path = std::path::PathBuf::from("src");
|
||||
let mut build = autocxx_build::Builder::new("src/lib.rs", &[&path])
|
||||
.extra_clang_args(&[&include, "-x", "c++", "-std=gnu++20"])
|
||||
.auto_allowlist(true)
|
||||
.expect_build();
|
||||
|
||||
build
|
||||
.include(format!("{}/include", env!("LIBIMHEX_SOURCE_DIRECTORY")))
|
||||
.flag_if_supported("-std=gnu++20")
|
||||
.flag_if_supported("-std=gnu++2a")
|
||||
.flag_if_supported("-fconcepts")
|
||||
.compiler(env!("CXX_COMPILER"))
|
||||
.compile("libimhex-bridge");
|
||||
}
|
||||
159
lib/libimhex-rs/imgui-rs/Cargo.lock
generated
159
lib/libimhex-rs/imgui-rs/Cargo.lock
generated
@@ -1,159 +0,0 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.71"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "79c2681d6594606957bbb8631c4b90a7fcaaa72cdb714743a437b156d6a7eedd"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "chlorine"
|
||||
version = "1.0.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bd650552110e39b7c5058986cf177decd3365841836578ac50a286094eac0be6"
|
||||
|
||||
[[package]]
|
||||
name = "imgui"
|
||||
version = "0.8.0"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"imgui-sys",
|
||||
"memoffset",
|
||||
"parking_lot",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "imgui-sys"
|
||||
version = "0.8.0"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"chlorine",
|
||||
"pkg-config",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "instant"
|
||||
version = "0.1.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "716d3d89f35ac6a34fd0eed635395f4c3b76fa889338a4632e5231a8684216bd"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.103"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dd8f7255a17a627354f321ef0055d63b898c6fb27eff628af4d1b66b7331edf6"
|
||||
|
||||
[[package]]
|
||||
name = "lock_api"
|
||||
version = "0.4.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "712a4d093c9976e24e7dbca41db895dabcbac38eb5f4045393d17a95bdfb1109"
|
||||
dependencies = [
|
||||
"scopeguard",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memoffset"
|
||||
version = "0.6.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "59accc507f1338036a0477ef61afdae33cde60840f4dfe481319ce3ad116ddf9"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot"
|
||||
version = "0.11.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99"
|
||||
dependencies = [
|
||||
"instant",
|
||||
"lock_api",
|
||||
"parking_lot_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot_core"
|
||||
version = "0.8.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d76e8e1493bcac0d2766c42737f34458f1c8c50c0d23bcb24ea953affb273216"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"instant",
|
||||
"libc",
|
||||
"redox_syscall",
|
||||
"smallvec",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pkg-config"
|
||||
version = "0.3.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7c9b1041b4387893b91ee6746cddfc28516aff326a3519fb2adf820932c5e6cb"
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.2.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8383f39639269cde97d255a32bdb68c047337295414940c68bdd30c2e13203ff"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "scopeguard"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
|
||||
|
||||
[[package]]
|
||||
name = "smallvec"
|
||||
version = "1.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1ecab6c735a6bb4139c0caafd0cc3635748bbb3acf4550e8138122099251f309"
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
|
||||
dependencies = [
|
||||
"winapi-i686-pc-windows-gnu",
|
||||
"winapi-x86_64-pc-windows-gnu",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-i686-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-x86_64-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
@@ -1,31 +0,0 @@
|
||||
[package]
|
||||
name = "imgui"
|
||||
version = "0.8.0"
|
||||
edition = "2018"
|
||||
authors = ["The imgui-rs Developers"]
|
||||
description = "High-level Rust bindings to dear imgui"
|
||||
homepage = "https://github.com/imgui-rs/imgui-rs"
|
||||
repository = "https://github.com/imgui-rs/imgui-rs"
|
||||
license = "MIT/Apache-2.0"
|
||||
categories = ["gui", "api-bindings"]
|
||||
readme = "../README.markdown"
|
||||
|
||||
exclude = ["/resources"]
|
||||
|
||||
[dependencies]
|
||||
bitflags = "1"
|
||||
imgui-sys = { path = "../imgui-sys" }
|
||||
parking_lot = "0.11"
|
||||
|
||||
[features]
|
||||
default = ["min-const-generics"]
|
||||
|
||||
wasm = ["imgui-sys/wasm"]
|
||||
freetype = ["imgui-sys/freetype"]
|
||||
min-const-generics = []
|
||||
# this api is in beta in the upstream imgui crate. See issue #524 for more info.
|
||||
# it should be stable and fine to use though.
|
||||
tables-api = []
|
||||
|
||||
[dev-dependencies]
|
||||
memoffset = "0.6"
|
||||
@@ -1,202 +0,0 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "{}"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright {yyyy} {name of copyright owner}
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
../README.markdown
|
||||
@@ -1,142 +0,0 @@
|
||||
use std::ffi::{CStr, CString};
|
||||
use std::fmt;
|
||||
use std::os::raw::{c_char, c_void};
|
||||
use std::panic::catch_unwind;
|
||||
use std::process;
|
||||
use std::ptr;
|
||||
|
||||
// use crate::string::{ImStr, ImString};
|
||||
use crate::Ui;
|
||||
|
||||
/// Trait for clipboard backends
|
||||
pub trait ClipboardBackend: 'static {
|
||||
/// Returns the current clipboard contents as an owned imgui-rs string, or None if the
|
||||
/// clipboard is empty or inaccessible
|
||||
fn get(&mut self) -> Option<String>;
|
||||
/// Sets the clipboard contents to the given imgui-rs string slice.
|
||||
fn set(&mut self, value: &str);
|
||||
}
|
||||
|
||||
pub(crate) struct ClipboardContext {
|
||||
backend: Box<dyn ClipboardBackend>,
|
||||
// this is needed to keep ownership of the value when the raw C callback is called
|
||||
last_value: CString,
|
||||
}
|
||||
|
||||
impl ClipboardContext {
|
||||
/// Creates a new [ClipboardContext]. This function previously took a `Box`, but now
|
||||
/// is generic over the T it takes and boxes itself (which should be less strange).
|
||||
pub fn new<T: ClipboardBackend>(backend: T) -> ClipboardContext {
|
||||
ClipboardContext {
|
||||
backend: Box::new(backend) as Box<dyn ClipboardBackend>,
|
||||
last_value: CString::default(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn dummy() -> ClipboardContext {
|
||||
Self {
|
||||
backend: Box::new(DummyClipboardContext),
|
||||
last_value: CString::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct DummyClipboardContext;
|
||||
impl ClipboardBackend for DummyClipboardContext {
|
||||
fn get(&mut self) -> Option<String> {
|
||||
None
|
||||
}
|
||||
|
||||
fn set(&mut self, _: &str) {
|
||||
// empty
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for ClipboardContext {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.debug_struct("ClipboardContext")
|
||||
// beautiful code, no?
|
||||
.field("backend", &(&(*self.backend) as *const _))
|
||||
.field("last_value", &self.last_value)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) unsafe extern "C" fn get_clipboard_text(user_data: *mut c_void) -> *const c_char {
|
||||
let result = catch_unwind(|| {
|
||||
let ctx = &mut *(user_data as *mut ClipboardContext);
|
||||
match ctx.backend.get() {
|
||||
Some(text) => {
|
||||
ctx.last_value = CString::new(text).unwrap();
|
||||
ctx.last_value.as_ptr()
|
||||
}
|
||||
None => ptr::null(),
|
||||
}
|
||||
});
|
||||
result.unwrap_or_else(|_| {
|
||||
eprintln!("Clipboard getter panicked");
|
||||
process::abort();
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) unsafe extern "C" fn set_clipboard_text(user_data: *mut c_void, text: *const c_char) {
|
||||
let result = catch_unwind(|| {
|
||||
let ctx = &mut *(user_data as *mut ClipboardContext);
|
||||
let text = CStr::from_ptr(text).to_owned();
|
||||
ctx.backend.set(text.to_str().unwrap());
|
||||
});
|
||||
result.unwrap_or_else(|_| {
|
||||
eprintln!("Clipboard setter panicked");
|
||||
process::abort();
|
||||
});
|
||||
}
|
||||
|
||||
/// # Clipboard
|
||||
#[allow(clippy::fn_address_comparisons)] // This is allowed because although function addresses wont be unique, we just care if its OURS
|
||||
impl<'ui> Ui<'ui> {
|
||||
/// Returns the current clipboard contents as text, or None if the clipboard is empty or cannot
|
||||
/// be accessed
|
||||
pub fn clipboard_text(&self) -> Option<String> {
|
||||
let io = self.io();
|
||||
io.get_clipboard_text_fn.and_then(|get_clipboard_text_fn| {
|
||||
// Bypass FFI if we end up calling our own function anyway
|
||||
if get_clipboard_text_fn == get_clipboard_text {
|
||||
let ctx = unsafe { &mut *(io.clipboard_user_data as *mut ClipboardContext) };
|
||||
ctx.backend.get()
|
||||
} else {
|
||||
unsafe {
|
||||
let text_ptr = get_clipboard_text_fn(io.clipboard_user_data);
|
||||
if text_ptr.is_null() || *text_ptr == b'\0' as c_char {
|
||||
None
|
||||
} else {
|
||||
Some(
|
||||
CStr::from_ptr(text_ptr)
|
||||
.to_owned()
|
||||
.to_str()
|
||||
.ok()?
|
||||
.to_owned(),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/// Sets the clipboard contents.
|
||||
///
|
||||
/// Does nothing if the clipboard cannot be accessed.
|
||||
pub fn set_clipboard_text(&self, text: impl AsRef<str>) {
|
||||
let io = self.io();
|
||||
if let Some(set_clipboard_text_fn) = io.set_clipboard_text_fn {
|
||||
// Bypass FFI if we end up calling our own function anyway
|
||||
if set_clipboard_text_fn == set_clipboard_text {
|
||||
let ctx = unsafe { &mut *(io.clipboard_user_data as *mut ClipboardContext) };
|
||||
ctx.backend.set(text.as_ref());
|
||||
} else {
|
||||
unsafe {
|
||||
set_clipboard_text_fn(io.clipboard_user_data, self.scratch_txt(text));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,370 +0,0 @@
|
||||
/// Wraps u32 that represents a packed RGBA color. Mostly used by types in the
|
||||
/// low level custom drawing API, such as [`DrawListMut`](crate::DrawListMut).
|
||||
///
|
||||
/// The bits of a color are in "`0xAABBGGRR`" format (e.g. RGBA as little endian
|
||||
/// bytes). For clarity: we don't support an equivalent to the
|
||||
/// `IMGUI_USE_BGRA_PACKED_COLOR` define.
|
||||
///
|
||||
/// This used to be named `ImColor32`, but was renamed to avoid confusion with
|
||||
/// the type with that name in the C++ API (which uses 32 bits per channel).
|
||||
///
|
||||
/// While it doesn't provide methods to access the fields, they can be accessed
|
||||
/// via the `Deref`/`DerefMut` impls it provides targeting
|
||||
/// [`imgui::color::ImColor32Fields`](crate::color::ImColor32Fields), which has
|
||||
/// no other meaningful uses.
|
||||
///
|
||||
/// # Example
|
||||
/// ```
|
||||
/// let mut c = imgui::ImColor32::from_rgba(0x80, 0xc0, 0x40, 0xff);
|
||||
/// assert_eq!(c.to_bits(), 0xff_40_c0_80); // Note: 0xAA_BB_GG_RR
|
||||
/// // Field access
|
||||
/// assert_eq!(c.r, 0x80);
|
||||
/// assert_eq!(c.g, 0xc0);
|
||||
/// assert_eq!(c.b, 0x40);
|
||||
/// assert_eq!(c.a, 0xff);
|
||||
/// c.b = 0xbb;
|
||||
/// assert_eq!(c.to_bits(), 0xff_bb_c0_80);
|
||||
/// ```
|
||||
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
|
||||
#[repr(transparent)]
|
||||
pub struct ImColor32(u32); // TBH maybe the wrapped field should be `pub`.
|
||||
|
||||
impl ImColor32 {
|
||||
/// Convenience constant for solid black.
|
||||
pub const BLACK: Self = Self(0xff_00_00_00);
|
||||
|
||||
/// Convenience constant for solid white.
|
||||
pub const WHITE: Self = Self(0xff_ff_ff_ff);
|
||||
|
||||
/// Convenience constant for full transparency.
|
||||
pub const TRANSPARENT: Self = Self(0);
|
||||
|
||||
/// Construct a color from 4 single-byte `u8` channel values, which should
|
||||
/// be between 0 and 255.
|
||||
#[inline]
|
||||
pub const fn from_rgba(r: u8, g: u8, b: u8, a: u8) -> Self {
|
||||
Self(
|
||||
((a as u32) << Self::A_SHIFT)
|
||||
| ((r as u32) << Self::R_SHIFT)
|
||||
| ((g as u32) << Self::G_SHIFT)
|
||||
| ((b as u32) << Self::B_SHIFT),
|
||||
)
|
||||
}
|
||||
|
||||
/// Construct a fully opaque color from 3 single-byte `u8` channel values.
|
||||
/// Same as [`Self::from_rgba`] with a == 255
|
||||
#[inline]
|
||||
pub const fn from_rgb(r: u8, g: u8, b: u8) -> Self {
|
||||
Self::from_rgba(r, g, b, 0xff)
|
||||
}
|
||||
|
||||
/// Construct a fully opaque color from 4 `f32` channel values in the range
|
||||
/// `0.0 ..= 1.0` (values outside this range are clamped to it, with NaN
|
||||
/// mapped to 0.0).
|
||||
///
|
||||
/// Note: No alpha premultiplication is done, so your input should be have
|
||||
/// premultiplied alpha if needed.
|
||||
#[inline]
|
||||
// not const fn because no float math in const eval yet 😩
|
||||
pub fn from_rgba_f32s(r: f32, g: f32, b: f32, a: f32) -> Self {
|
||||
Self::from_rgba(
|
||||
f32_to_u8_sat(r),
|
||||
f32_to_u8_sat(g),
|
||||
f32_to_u8_sat(b),
|
||||
f32_to_u8_sat(a),
|
||||
)
|
||||
}
|
||||
|
||||
/// Return the channels as an array of f32 in `[r, g, b, a]` order.
|
||||
#[inline]
|
||||
pub fn to_rgba_f32s(self) -> [f32; 4] {
|
||||
let &ImColor32Fields { r, g, b, a } = &*self;
|
||||
[
|
||||
u8_to_f32_sat(r),
|
||||
u8_to_f32_sat(g),
|
||||
u8_to_f32_sat(b),
|
||||
u8_to_f32_sat(a),
|
||||
]
|
||||
}
|
||||
|
||||
/// Return the channels as an array of u8 in `[r, g, b, a]` order.
|
||||
#[inline]
|
||||
pub fn to_rgba(self) -> [u8; 4] {
|
||||
let &ImColor32Fields { r, g, b, a } = &*self;
|
||||
[r, g, b, a]
|
||||
}
|
||||
|
||||
/// Equivalent to [`Self::from_rgba_f32s`], but with an alpha of 1.0 (e.g.
|
||||
/// opaque).
|
||||
#[inline]
|
||||
pub fn from_rgb_f32s(r: f32, g: f32, b: f32) -> Self {
|
||||
Self::from_rgba(f32_to_u8_sat(r), f32_to_u8_sat(g), f32_to_u8_sat(b), 0xff)
|
||||
}
|
||||
|
||||
/// Construct a color from the `u32` that makes up the bits in `0xAABBGGRR`
|
||||
/// format.
|
||||
///
|
||||
/// Specifically, this takes the RGBA values as a little-endian u32 with 8
|
||||
/// bits per channel.
|
||||
///
|
||||
/// Note that [`ImColor32::from_rgba`] may be a bit easier to use.
|
||||
#[inline]
|
||||
pub const fn from_bits(u: u32) -> Self {
|
||||
Self(u)
|
||||
}
|
||||
|
||||
/// Return the bits of the color as a u32. These are in "`0xAABBGGRR`" format, that
|
||||
/// is, little-endian RGBA with 8 bits per channel.
|
||||
#[inline]
|
||||
pub const fn to_bits(self) -> u32 {
|
||||
self.0
|
||||
}
|
||||
|
||||
// These are public in C++ ImGui, should they be public here?
|
||||
/// The number of bits to shift the byte of the red channel. Always 0.
|
||||
const R_SHIFT: u32 = 0;
|
||||
/// The number of bits to shift the byte of the green channel. Always 8.
|
||||
const G_SHIFT: u32 = 8;
|
||||
/// The number of bits to shift the byte of the blue channel. Always 16.
|
||||
const B_SHIFT: u32 = 16;
|
||||
/// The number of bits to shift the byte of the alpha channel. Always 24.
|
||||
const A_SHIFT: u32 = 24;
|
||||
}
|
||||
|
||||
impl Default for ImColor32 {
|
||||
#[inline]
|
||||
fn default() -> Self {
|
||||
Self::TRANSPARENT
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Debug for ImColor32 {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
f.debug_struct("ImColor32")
|
||||
.field("r", &self.r)
|
||||
.field("g", &self.g)
|
||||
.field("b", &self.b)
|
||||
.field("a", &self.a)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
/// A struct that exists to allow field access to [`ImColor32`]. It essentially
|
||||
/// exists to be a `Deref`/`DerefMut` target and provide field access.
|
||||
///
|
||||
/// Note that while this is repr(C), be aware that on big-endian machines
|
||||
/// (`cfg(target_endian = "big")`) the order of the fields is reversed, as this
|
||||
/// is a view into a packed u32.
|
||||
///
|
||||
/// Generally should not be used, except as the target of the `Deref` impl of
|
||||
/// [`ImColor32`].
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
#[repr(C, align(4))]
|
||||
// Should this be #[non_exhaustive] to discourage direct use?
|
||||
#[rustfmt::skip]
|
||||
pub struct ImColor32Fields {
|
||||
#[cfg(target_endian = "little")] pub r: u8,
|
||||
#[cfg(target_endian = "little")] pub g: u8,
|
||||
#[cfg(target_endian = "little")] pub b: u8,
|
||||
#[cfg(target_endian = "little")] pub a: u8,
|
||||
// TODO(someday): i guess we should have BE tests, but for now I verified
|
||||
// this locally.
|
||||
#[cfg(target_endian = "big")] pub a: u8,
|
||||
#[cfg(target_endian = "big")] pub b: u8,
|
||||
#[cfg(target_endian = "big")] pub g: u8,
|
||||
#[cfg(target_endian = "big")] pub r: u8,
|
||||
}
|
||||
|
||||
// We assume that big and little are the only endiannesses, and that exactly one
|
||||
// is set. That is, PDP endian is not in use, and the we aren't using a
|
||||
// completely broken custom target json or something.
|
||||
#[cfg(any(
|
||||
all(target_endian = "little", target_endian = "big"),
|
||||
all(not(target_endian = "little"), not(target_endian = "big")),
|
||||
))]
|
||||
compile_error!("`cfg(target_endian = \"little\")` must be `cfg(not(target_endian = \"big\")`");
|
||||
|
||||
// static assert sizes match
|
||||
const _: [(); core::mem::size_of::<ImColor32>()] = [(); core::mem::size_of::<ImColor32Fields>()];
|
||||
const _: [(); core::mem::align_of::<ImColor32>()] = [(); core::mem::align_of::<ImColor32Fields>()];
|
||||
|
||||
impl core::ops::Deref for ImColor32 {
|
||||
type Target = ImColor32Fields;
|
||||
#[inline]
|
||||
fn deref(&self) -> &ImColor32Fields {
|
||||
// Safety: we statically assert the size and align match, and neither
|
||||
// type has any special invariants.
|
||||
unsafe { &*(self as *const Self as *const ImColor32Fields) }
|
||||
}
|
||||
}
|
||||
impl core::ops::DerefMut for ImColor32 {
|
||||
#[inline]
|
||||
fn deref_mut(&mut self) -> &mut ImColor32Fields {
|
||||
// Safety: we statically assert the size and align match, and neither
|
||||
// type has any special invariants.
|
||||
unsafe { &mut *(self as *mut Self as *mut ImColor32Fields) }
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ImColor32> for u32 {
|
||||
#[inline]
|
||||
fn from(color: ImColor32) -> Self {
|
||||
color.0
|
||||
}
|
||||
}
|
||||
|
||||
impl From<u32> for ImColor32 {
|
||||
#[inline]
|
||||
fn from(color: u32) -> Self {
|
||||
ImColor32(color)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<[f32; 4]> for ImColor32 {
|
||||
#[inline]
|
||||
fn from(v: [f32; 4]) -> Self {
|
||||
Self::from_rgba_f32s(v[0], v[1], v[2], v[3])
|
||||
}
|
||||
}
|
||||
|
||||
impl From<(f32, f32, f32, f32)> for ImColor32 {
|
||||
#[inline]
|
||||
fn from(v: (f32, f32, f32, f32)) -> Self {
|
||||
Self::from_rgba_f32s(v.0, v.1, v.2, v.3)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<[f32; 3]> for ImColor32 {
|
||||
#[inline]
|
||||
fn from(v: [f32; 3]) -> Self {
|
||||
Self::from_rgb_f32s(v[0], v[1], v[2])
|
||||
}
|
||||
}
|
||||
|
||||
impl From<(f32, f32, f32)> for ImColor32 {
|
||||
fn from(v: (f32, f32, f32)) -> Self {
|
||||
Self::from_rgb_f32s(v.0, v.1, v.2)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ImColor32> for [f32; 4] {
|
||||
#[inline]
|
||||
fn from(v: ImColor32) -> Self {
|
||||
v.to_rgba_f32s()
|
||||
}
|
||||
}
|
||||
impl From<ImColor32> for (f32, f32, f32, f32) {
|
||||
#[inline]
|
||||
fn from(color: ImColor32) -> Self {
|
||||
let [r, g, b, a]: [f32; 4] = color.into();
|
||||
(r, g, b, a)
|
||||
}
|
||||
}
|
||||
|
||||
// These utilities might be worth making `pub` as free functions in
|
||||
// `crate::color` so user code can ensure their numeric handling is
|
||||
// consistent...
|
||||
|
||||
/// Clamp `v` to between 0.0 and 1.0, always returning a value between those.
|
||||
///
|
||||
/// Never returns NaN, or -0.0 — instead returns +0.0 for these (We differ from
|
||||
/// C++ Dear ImGUI here which probably is just ignoring values like these).
|
||||
#[inline]
|
||||
pub(crate) fn saturate(v: f32) -> f32 {
|
||||
// Note: written strangely so that special values (NaN/-0.0) are handled
|
||||
// automatically with no extra checks.
|
||||
if v > 0.0 {
|
||||
if v <= 1.0 {
|
||||
v
|
||||
} else {
|
||||
1.0
|
||||
}
|
||||
} else {
|
||||
0.0
|
||||
}
|
||||
}
|
||||
|
||||
/// Quantize a value in `0.0..=1.0` to `0..=u8::MAX`. Input outside 0.0..=1.0 is
|
||||
/// clamped. Uses a bias of 0.5, because we assume centered quantization is used
|
||||
/// (and because C++ imgui does it too). See:
|
||||
/// - https://github.com/ocornut/imgui/blob/e28b51786eae60f32c18214658c15952639085a2/imgui_internal.h#L218
|
||||
/// - https://cbloomrants.blogspot.com/2020/09/topics-in-quantization-for-games.html
|
||||
/// (see `quantize_centered`)
|
||||
#[inline]
|
||||
pub(crate) fn f32_to_u8_sat(f: f32) -> u8 {
|
||||
let f = saturate(f) * 255.0 + 0.5;
|
||||
// Safety: `saturate`'s result is between 0.0 and 1.0 (never NaN even for
|
||||
// NaN input), and so for all inputs, `saturate(f) * 255.0 + 0.5` is inside
|
||||
// `0.5 ..= 255.5`.
|
||||
//
|
||||
// This is verified for all f32 in `test_f32_to_u8_sat_exhaustive`.
|
||||
//
|
||||
// Also note that LLVM doesn't bother trying to figure this out so the
|
||||
// unchecked does actually help. (That said, this likely doesn't matter
|
||||
// for imgui-rs, but I had this code in another project and it felt
|
||||
// silly to needlessly pessimize it).
|
||||
unsafe { f.to_int_unchecked() }
|
||||
}
|
||||
|
||||
/// Opposite of `f32_to_u8_sat`. Since we assume centered quantization, this is
|
||||
/// equivalent to dividing by 255 (or, multiplying by 1.0/255.0)
|
||||
#[inline]
|
||||
pub(crate) fn u8_to_f32_sat(u: u8) -> f32 {
|
||||
(u as f32) * (1.0 / 255.0)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn check_sat() {
|
||||
assert_eq!(saturate(1.0), 1.0);
|
||||
assert_eq!(saturate(0.5), 0.5);
|
||||
assert_eq!(saturate(0.0), 0.0);
|
||||
assert_eq!(saturate(-1.0), 0.0);
|
||||
// next float from 1.0
|
||||
assert_eq!(saturate(1.0 + f32::EPSILON), 1.0);
|
||||
// prev float from 0.0 (Well, from -0.0)
|
||||
assert_eq!(saturate(-f32::MIN_POSITIVE), 0.0);
|
||||
// some NaNs.
|
||||
assert_eq!(saturate(f32::NAN), 0.0);
|
||||
assert_eq!(saturate(-f32::NAN), 0.0);
|
||||
// neg zero comes through as +0
|
||||
assert_eq!(saturate(-0.0).to_bits(), 0.0f32.to_bits());
|
||||
}
|
||||
|
||||
// Check that the unsafe in `f32_to_u8_sat` is fine for all f32 (and that the
|
||||
// comments I wrote about `saturate` are actually true). This is way too slow in
|
||||
// debug mode, but finishes in ~15s on my machine for release (just this test).
|
||||
// This is tested in CI, but will only run if invoked manually with something
|
||||
// like: `cargo test -p imgui --release -- --ignored`.
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn test_f32_to_u8_sat_exhaustive() {
|
||||
for f in (0..=u32::MAX).map(f32::from_bits) {
|
||||
let v = saturate(f);
|
||||
assert!(
|
||||
(0.0..=1.0).contains(&v) && (v.to_bits() != (-0.0f32).to_bits()),
|
||||
"sat({} [e.g. {:#x}]) => {} [e.g {:#x}]",
|
||||
f,
|
||||
f.to_bits(),
|
||||
v,
|
||||
v.to_bits(),
|
||||
);
|
||||
let sat = v * 255.0 + 0.5;
|
||||
// Note: This checks what's required by is the safety predicate for
|
||||
// `f32::to_int_unchecked`:
|
||||
// https://doc.rust-lang.org/std/primitive.f32.html#method.to_int_unchecked
|
||||
assert!(
|
||||
sat.trunc() >= 0.0 && sat.trunc() <= (u8::MAX as f32) && sat.is_finite(),
|
||||
"f32_to_u8_sat({} [e.g. {:#x}]) would be UB!",
|
||||
f,
|
||||
f.to_bits(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_saturate_all_u8s() {
|
||||
for u in 0..=u8::MAX {
|
||||
let v = f32_to_u8_sat(u8_to_f32_sat(u));
|
||||
assert_eq!(u, v);
|
||||
}
|
||||
}
|
||||
@@ -1,68 +0,0 @@
|
||||
use crate::sys;
|
||||
use crate::Ui;
|
||||
|
||||
/// # Columns
|
||||
impl<'ui> Ui<'ui> {
|
||||
#[doc(alias = "Columns")]
|
||||
pub fn columns(&self, count: i32, id: impl AsRef<str>, border: bool) {
|
||||
unsafe { sys::igColumns(count, self.scratch_txt(id), border) }
|
||||
}
|
||||
/// Switches to the next column.
|
||||
///
|
||||
/// If the current row is finished, switches to first column of the next row
|
||||
#[doc(alias = "NextColumn")]
|
||||
pub fn next_column(&self) {
|
||||
unsafe { sys::igNextColumn() }
|
||||
}
|
||||
/// Returns the index of the current column
|
||||
#[doc(alias = "GetColumnIndex")]
|
||||
pub fn current_column_index(&self) -> i32 {
|
||||
unsafe { sys::igGetColumnIndex() }
|
||||
}
|
||||
/// Returns the width of the current column (in pixels)
|
||||
#[doc(alias = "GetColumnWidth")]
|
||||
pub fn current_column_width(&self) -> f32 {
|
||||
unsafe { sys::igGetColumnWidth(-1) }
|
||||
}
|
||||
#[doc(alias = "GetColumnWidth")]
|
||||
/// Returns the width of the given column (in pixels)
|
||||
pub fn column_width(&self, column_index: i32) -> f32 {
|
||||
unsafe { sys::igGetColumnWidth(column_index) }
|
||||
}
|
||||
#[doc(alias = "SetColumnWidth")]
|
||||
/// Sets the width of the current column (in pixels)
|
||||
pub fn set_current_column_width(&self, width: f32) {
|
||||
unsafe { sys::igSetColumnWidth(-1, width) };
|
||||
}
|
||||
#[doc(alias = "SetColumnWidth")]
|
||||
/// Sets the width of the given column (in pixels)
|
||||
pub fn set_column_width(&self, column_index: i32, width: f32) {
|
||||
unsafe { sys::igSetColumnWidth(column_index, width) };
|
||||
}
|
||||
/// Returns the offset of the current column (in pixels from the left side of the content
|
||||
/// region)
|
||||
#[doc(alias = "GetColumnOffset")]
|
||||
pub fn current_column_offset(&self) -> f32 {
|
||||
unsafe { sys::igGetColumnOffset(-1) }
|
||||
}
|
||||
/// Returns the offset of the given column (in pixels from the left side of the content region)
|
||||
#[doc(alias = "GetColumnOffset")]
|
||||
pub fn column_offset(&self, column_index: i32) -> f32 {
|
||||
unsafe { sys::igGetColumnOffset(column_index) }
|
||||
}
|
||||
/// Sets the offset of the current column (in pixels from the left side of the content region)
|
||||
#[doc(alias = "SetColumnOffset")]
|
||||
pub fn set_current_column_offset(&self, offset_x: f32) {
|
||||
unsafe { sys::igSetColumnOffset(-1, offset_x) };
|
||||
}
|
||||
/// Sets the offset of the given column (in pixels from the left side of the content region)
|
||||
#[doc(alias = "SetColumnOffset")]
|
||||
pub fn set_column_offset(&self, column_index: i32, offset_x: f32) {
|
||||
unsafe { sys::igSetColumnOffset(column_index, offset_x) };
|
||||
}
|
||||
/// Returns the current amount of columns
|
||||
#[doc(alias = "GetColumnCount")]
|
||||
pub fn column_count(&self) -> i32 {
|
||||
unsafe { sys::igGetColumnsCount() }
|
||||
}
|
||||
}
|
||||
@@ -1,582 +0,0 @@
|
||||
use parking_lot::ReentrantMutex;
|
||||
use std::cell::{RefCell, UnsafeCell};
|
||||
use std::ffi::{CStr, CString};
|
||||
use std::mem::ManuallyDrop;
|
||||
use std::ops::Drop;
|
||||
use std::path::PathBuf;
|
||||
use std::ptr;
|
||||
use std::rc::Rc;
|
||||
|
||||
use crate::clipboard::{ClipboardBackend, ClipboardContext};
|
||||
use crate::fonts::atlas::{FontAtlas, FontAtlasRefMut, FontId, SharedFontAtlas};
|
||||
use crate::io::Io;
|
||||
use crate::style::Style;
|
||||
use crate::sys;
|
||||
use crate::Ui;
|
||||
|
||||
/// An imgui-rs context.
|
||||
///
|
||||
/// A context needs to be created to access most library functions. Due to current Dear ImGui
|
||||
/// design choices, at most one active Context can exist at any time. This limitation will likely
|
||||
/// be removed in a future Dear ImGui version.
|
||||
///
|
||||
/// If you need more than one context, you can use suspended contexts. As long as only one context
|
||||
/// is active at a time, it's possible to have multiple independent contexts.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Creating a new active context:
|
||||
/// ```
|
||||
/// let ctx = imgui::Context::create();
|
||||
/// // ctx is dropped naturally when it goes out of scope, which deactivates and destroys the
|
||||
/// // context
|
||||
/// ```
|
||||
///
|
||||
/// Never try to create an active context when another one is active:
|
||||
///
|
||||
/// ```should_panic
|
||||
/// let ctx1 = imgui::Context::create();
|
||||
///
|
||||
/// let ctx2 = imgui::Context::create(); // PANIC
|
||||
/// ```
|
||||
///
|
||||
/// Suspending an active context allows you to create another active context:
|
||||
///
|
||||
/// ```
|
||||
/// let ctx1 = imgui::Context::create();
|
||||
/// let suspended1 = ctx1.suspend();
|
||||
/// let ctx2 = imgui::Context::create(); // this is now OK
|
||||
/// ```
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Context {
|
||||
raw: *mut sys::ImGuiContext,
|
||||
shared_font_atlas: Option<Rc<RefCell<SharedFontAtlas>>>,
|
||||
ini_filename: Option<CString>,
|
||||
log_filename: Option<CString>,
|
||||
platform_name: Option<CString>,
|
||||
renderer_name: Option<CString>,
|
||||
// we need to box this because we hand imgui a pointer to it,
|
||||
// and we don't want to deal with finding `clipboard_ctx`.
|
||||
// we also put it in an unsafecell since we're going to give
|
||||
// imgui a mutable pointer to it.
|
||||
clipboard_ctx: Box<UnsafeCell<ClipboardContext>>,
|
||||
}
|
||||
|
||||
// This mutex needs to be used to guard all public functions that can affect the underlying
|
||||
// Dear ImGui active context
|
||||
static CTX_MUTEX: ReentrantMutex<()> = parking_lot::const_reentrant_mutex(());
|
||||
|
||||
fn clear_current_context() {
|
||||
unsafe {
|
||||
sys::igSetCurrentContext(ptr::null_mut());
|
||||
}
|
||||
}
|
||||
fn no_current_context() -> bool {
|
||||
let ctx = unsafe { sys::igGetCurrentContext() };
|
||||
ctx.is_null()
|
||||
}
|
||||
|
||||
impl Context {
|
||||
/// Creates a new active imgui-rs context.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if an active context already exists
|
||||
#[doc(alias = "CreateContext")]
|
||||
pub fn create() -> Self {
|
||||
Self::create_internal(None)
|
||||
}
|
||||
/// Creates a new active imgui-rs context with a shared font atlas.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if an active context already exists
|
||||
#[doc(alias = "CreateContext")]
|
||||
pub fn create_with_shared_font_atlas(shared_font_atlas: Rc<RefCell<SharedFontAtlas>>) -> Self {
|
||||
Self::create_internal(Some(shared_font_atlas))
|
||||
}
|
||||
/// Suspends this context so another context can be the active context.
|
||||
#[doc(alias = "CreateContext")]
|
||||
pub fn suspend(self) -> SuspendedContext {
|
||||
let _guard = CTX_MUTEX.lock();
|
||||
assert!(
|
||||
self.is_current_context(),
|
||||
"context to be suspended is not the active context"
|
||||
);
|
||||
clear_current_context();
|
||||
SuspendedContext(self)
|
||||
}
|
||||
/// Returns the path to the ini file, or None if not set
|
||||
pub fn ini_filename(&self) -> Option<PathBuf> {
|
||||
let io = self.io();
|
||||
if io.ini_filename.is_null() {
|
||||
None
|
||||
} else {
|
||||
let s = unsafe { CStr::from_ptr(io.ini_filename) };
|
||||
Some(PathBuf::from(s.to_str().ok()?))
|
||||
}
|
||||
}
|
||||
/// Sets the path to the ini file (default is "imgui.ini")
|
||||
///
|
||||
/// Pass None to disable automatic .Ini saving.
|
||||
pub fn set_ini_filename<T: Into<Option<PathBuf>>>(&mut self, ini_filename: T) {
|
||||
let ini_filename: Option<PathBuf> = ini_filename.into();
|
||||
let ini_filename = ini_filename.and_then(|v| CString::new(v.to_str()?).ok());
|
||||
|
||||
self.io_mut().ini_filename = ini_filename
|
||||
.as_ref()
|
||||
.map(|x| x.as_ptr())
|
||||
.unwrap_or(ptr::null());
|
||||
self.ini_filename = ini_filename;
|
||||
}
|
||||
/// Returns the path to the log file, or None if not set
|
||||
// TODO: why do we return an `Option<PathBuf>` instead of an `Option<&Path>`?
|
||||
pub fn log_filename(&self) -> Option<PathBuf> {
|
||||
let io = self.io();
|
||||
if io.log_filename.is_null() {
|
||||
None
|
||||
} else {
|
||||
let cstr = unsafe { CStr::from_ptr(io.log_filename) };
|
||||
Some(PathBuf::from(cstr.to_str().ok()?))
|
||||
}
|
||||
}
|
||||
/// Sets the log filename (default is "imgui_log.txt").
|
||||
pub fn set_log_filename<T: Into<Option<PathBuf>>>(&mut self, log_filename: T) {
|
||||
let log_filename = log_filename
|
||||
.into()
|
||||
.and_then(|v| CString::new(v.to_str()?).ok());
|
||||
|
||||
self.io_mut().log_filename = log_filename
|
||||
.as_ref()
|
||||
.map(|x| x.as_ptr())
|
||||
.unwrap_or(ptr::null());
|
||||
self.log_filename = log_filename;
|
||||
}
|
||||
/// Returns the backend platform name, or None if not set
|
||||
pub fn platform_name(&self) -> Option<&str> {
|
||||
let io = self.io();
|
||||
if io.backend_platform_name.is_null() {
|
||||
None
|
||||
} else {
|
||||
let cstr = unsafe { CStr::from_ptr(io.backend_platform_name) };
|
||||
cstr.to_str().ok()
|
||||
}
|
||||
}
|
||||
/// Sets the backend platform name
|
||||
pub fn set_platform_name<T: Into<Option<String>>>(&mut self, platform_name: T) {
|
||||
let platform_name: Option<CString> =
|
||||
platform_name.into().and_then(|v| CString::new(v).ok());
|
||||
self.io_mut().backend_platform_name = platform_name
|
||||
.as_ref()
|
||||
.map(|x| x.as_ptr())
|
||||
.unwrap_or(ptr::null());
|
||||
self.platform_name = platform_name;
|
||||
}
|
||||
/// Returns the backend renderer name, or None if not set
|
||||
pub fn renderer_name(&self) -> Option<&str> {
|
||||
let io = self.io();
|
||||
if io.backend_renderer_name.is_null() {
|
||||
None
|
||||
} else {
|
||||
let cstr = unsafe { CStr::from_ptr(io.backend_renderer_name) };
|
||||
cstr.to_str().ok()
|
||||
}
|
||||
}
|
||||
/// Sets the backend renderer name
|
||||
pub fn set_renderer_name<T: Into<Option<String>>>(&mut self, renderer_name: T) {
|
||||
let renderer_name: Option<CString> =
|
||||
renderer_name.into().and_then(|v| CString::new(v).ok());
|
||||
|
||||
self.io_mut().backend_renderer_name = renderer_name
|
||||
.as_ref()
|
||||
.map(|x| x.as_ptr())
|
||||
.unwrap_or(ptr::null());
|
||||
|
||||
self.renderer_name = renderer_name;
|
||||
}
|
||||
/// Loads settings from a string slice containing settings in .Ini file format
|
||||
#[doc(alias = "LoadIniSettingsFromMemory")]
|
||||
pub fn load_ini_settings(&mut self, data: &str) {
|
||||
unsafe { sys::igLoadIniSettingsFromMemory(data.as_ptr() as *const _, data.len()) }
|
||||
}
|
||||
/// Saves settings to a mutable string buffer in .Ini file format
|
||||
#[doc(alias = "SaveInitSettingsToMemory")]
|
||||
pub fn save_ini_settings(&mut self, buf: &mut String) {
|
||||
let data = unsafe { CStr::from_ptr(sys::igSaveIniSettingsToMemory(ptr::null_mut())) };
|
||||
buf.push_str(&data.to_string_lossy());
|
||||
}
|
||||
/// Sets the clipboard backend used for clipboard operations
|
||||
pub fn set_clipboard_backend<T: ClipboardBackend>(&mut self, backend: T) {
|
||||
let clipboard_ctx: Box<UnsafeCell<_>> = Box::new(ClipboardContext::new(backend).into());
|
||||
let io = self.io_mut();
|
||||
io.set_clipboard_text_fn = Some(crate::clipboard::set_clipboard_text);
|
||||
io.get_clipboard_text_fn = Some(crate::clipboard::get_clipboard_text);
|
||||
|
||||
io.clipboard_user_data = clipboard_ctx.get() as *mut _;
|
||||
self.clipboard_ctx = clipboard_ctx;
|
||||
}
|
||||
fn create_internal(shared_font_atlas: Option<Rc<RefCell<SharedFontAtlas>>>) -> Self {
|
||||
let _guard = CTX_MUTEX.lock();
|
||||
assert!(
|
||||
no_current_context(),
|
||||
"A new active context cannot be created, because another one already exists"
|
||||
);
|
||||
|
||||
let shared_font_atlas_ptr = match &shared_font_atlas {
|
||||
Some(shared_font_atlas) => {
|
||||
let borrowed_font_atlas = shared_font_atlas.borrow();
|
||||
borrowed_font_atlas.0
|
||||
}
|
||||
None => ptr::null_mut(),
|
||||
};
|
||||
// Dear ImGui implicitly sets the current context during igCreateContext if the current
|
||||
// context doesn't exist
|
||||
let raw = unsafe { sys::igCreateContext(shared_font_atlas_ptr) };
|
||||
|
||||
Context {
|
||||
raw,
|
||||
shared_font_atlas,
|
||||
ini_filename: None,
|
||||
log_filename: None,
|
||||
platform_name: None,
|
||||
renderer_name: None,
|
||||
clipboard_ctx: Box::new(ClipboardContext::dummy().into()),
|
||||
}
|
||||
}
|
||||
fn is_current_context(&self) -> bool {
|
||||
let ctx = unsafe { sys::igGetCurrentContext() };
|
||||
self.raw == ctx
|
||||
}
|
||||
|
||||
/// Get a reference to the current context
|
||||
pub fn current() -> Option<ContextRef> {
|
||||
let _guard = CTX_MUTEX.lock();
|
||||
|
||||
let raw = unsafe { sys::igGetCurrentContext() };
|
||||
|
||||
if raw.is_null() {
|
||||
None
|
||||
} else {
|
||||
Some(ContextRef(ManuallyDrop::new(Context {
|
||||
raw,
|
||||
shared_font_atlas: None, // XXX: this might be needed tbh
|
||||
ini_filename: None,
|
||||
log_filename: None,
|
||||
platform_name: None,
|
||||
renderer_name: None,
|
||||
clipboard_ctx: Box::new(ClipboardContext::dummy().into()),
|
||||
})))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A reference to a [`Context`] object
|
||||
#[derive(Debug)]
|
||||
pub struct ContextRef(ManuallyDrop<Context>);
|
||||
|
||||
impl core::ops::Deref for ContextRef {
|
||||
type Target = Context;
|
||||
|
||||
fn deref(&self) -> &Context {
|
||||
&*self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl core::ops::DerefMut for ContextRef {
|
||||
fn deref_mut(&mut self) -> &mut Context {
|
||||
&mut *self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for Context {
|
||||
#[doc(alias = "DestroyContext")]
|
||||
fn drop(&mut self) {
|
||||
let _guard = CTX_MUTEX.lock();
|
||||
// If this context is the active context, Dear ImGui automatically deactivates it during
|
||||
// destruction
|
||||
unsafe {
|
||||
sys::igDestroyContext(self.raw);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A suspended imgui-rs context.
|
||||
///
|
||||
/// A suspended context retains its state, but is not usable without activating it first.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Suspended contexts are not directly very useful, but you can activate them:
|
||||
///
|
||||
/// ```
|
||||
/// let suspended = imgui::SuspendedContext::create();
|
||||
/// match suspended.activate() {
|
||||
/// Ok(ctx) => {
|
||||
/// // ctx is now the active context
|
||||
/// },
|
||||
/// Err(suspended) => {
|
||||
/// // activation failed, so you get the suspended context back
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
#[derive(Debug)]
|
||||
pub struct SuspendedContext(Context);
|
||||
|
||||
impl SuspendedContext {
|
||||
/// Creates a new suspended imgui-rs context.
|
||||
#[doc(alias = "CreateContext")]
|
||||
pub fn create() -> Self {
|
||||
Self::create_internal(None)
|
||||
}
|
||||
/// Creates a new suspended imgui-rs context with a shared font atlas.
|
||||
pub fn create_with_shared_font_atlas(shared_font_atlas: Rc<RefCell<SharedFontAtlas>>) -> Self {
|
||||
Self::create_internal(Some(shared_font_atlas))
|
||||
}
|
||||
/// Attempts to activate this suspended context.
|
||||
///
|
||||
/// If there is no active context, this suspended context is activated and `Ok` is returned,
|
||||
/// containing the activated context.
|
||||
/// If there is already an active context, nothing happens and `Err` is returned, containing
|
||||
/// the original suspended context.
|
||||
#[doc(alias = "SetCurrentContext")]
|
||||
pub fn activate(self) -> Result<Context, SuspendedContext> {
|
||||
let _guard = CTX_MUTEX.lock();
|
||||
if no_current_context() {
|
||||
unsafe {
|
||||
sys::igSetCurrentContext(self.0.raw);
|
||||
}
|
||||
Ok(self.0)
|
||||
} else {
|
||||
Err(self)
|
||||
}
|
||||
}
|
||||
fn create_internal(shared_font_atlas: Option<Rc<RefCell<SharedFontAtlas>>>) -> Self {
|
||||
let _guard = CTX_MUTEX.lock();
|
||||
let raw = unsafe { sys::igCreateContext(ptr::null_mut()) };
|
||||
let ctx = Context {
|
||||
raw,
|
||||
shared_font_atlas,
|
||||
ini_filename: None,
|
||||
log_filename: None,
|
||||
platform_name: None,
|
||||
renderer_name: None,
|
||||
clipboard_ctx: Box::new(ClipboardContext::dummy().into()),
|
||||
};
|
||||
if ctx.is_current_context() {
|
||||
// Oops, the context was activated -> deactivate
|
||||
clear_current_context();
|
||||
}
|
||||
SuspendedContext(ctx)
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_one_context() {
|
||||
let _guard = crate::test::TEST_MUTEX.lock();
|
||||
let _ctx = Context::create();
|
||||
assert!(!no_current_context());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_drop_clears_current_context() {
|
||||
let _guard = crate::test::TEST_MUTEX.lock();
|
||||
{
|
||||
let _ctx1 = Context::create();
|
||||
assert!(!no_current_context());
|
||||
}
|
||||
assert!(no_current_context());
|
||||
{
|
||||
let _ctx2 = Context::create();
|
||||
assert!(!no_current_context());
|
||||
}
|
||||
assert!(no_current_context());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_new_suspended() {
|
||||
let _guard = crate::test::TEST_MUTEX.lock();
|
||||
let ctx = Context::create();
|
||||
let _suspended = SuspendedContext::create();
|
||||
assert!(ctx.is_current_context());
|
||||
::std::mem::drop(_suspended);
|
||||
assert!(ctx.is_current_context());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_suspend() {
|
||||
let _guard = crate::test::TEST_MUTEX.lock();
|
||||
let ctx = Context::create();
|
||||
assert!(!no_current_context());
|
||||
let _suspended = ctx.suspend();
|
||||
assert!(no_current_context());
|
||||
let _ctx2 = Context::create();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_drop_suspended() {
|
||||
let _guard = crate::test::TEST_MUTEX.lock();
|
||||
let suspended = Context::create().suspend();
|
||||
assert!(no_current_context());
|
||||
let ctx2 = Context::create();
|
||||
::std::mem::drop(suspended);
|
||||
assert!(ctx2.is_current_context());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_suspend_activate() {
|
||||
let _guard = crate::test::TEST_MUTEX.lock();
|
||||
let suspended = Context::create().suspend();
|
||||
assert!(no_current_context());
|
||||
let ctx = suspended.activate().unwrap();
|
||||
assert!(ctx.is_current_context());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_suspend_failure() {
|
||||
let _guard = crate::test::TEST_MUTEX.lock();
|
||||
let suspended = Context::create().suspend();
|
||||
let _ctx = Context::create();
|
||||
assert!(suspended.activate().is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_shared_font_atlas() {
|
||||
let _guard = crate::test::TEST_MUTEX.lock();
|
||||
let atlas = Rc::new(RefCell::new(SharedFontAtlas::create()));
|
||||
let suspended1 = SuspendedContext::create_with_shared_font_atlas(atlas.clone());
|
||||
let mut ctx2 = Context::create_with_shared_font_atlas(atlas);
|
||||
{
|
||||
let _borrow = ctx2.fonts();
|
||||
}
|
||||
let _suspended2 = ctx2.suspend();
|
||||
let mut ctx = suspended1.activate().unwrap();
|
||||
let _borrow = ctx.fonts();
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn test_shared_font_atlas_borrow_panic() {
|
||||
let _guard = crate::test::TEST_MUTEX.lock();
|
||||
let atlas = Rc::new(RefCell::new(SharedFontAtlas::create()));
|
||||
let _suspended = SuspendedContext::create_with_shared_font_atlas(atlas.clone());
|
||||
let mut ctx = Context::create_with_shared_font_atlas(atlas.clone());
|
||||
let _borrow1 = atlas.borrow();
|
||||
let _borrow2 = ctx.fonts();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ini_load_save() {
|
||||
let (_guard, mut ctx) = crate::test::test_ctx();
|
||||
let data = "[Window][Debug##Default]
|
||||
Pos=60,60
|
||||
Size=400,400
|
||||
Collapsed=0";
|
||||
ctx.load_ini_settings(data);
|
||||
let mut buf = String::new();
|
||||
ctx.save_ini_settings(&mut buf);
|
||||
assert_eq!(data.trim(), buf.trim());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_default_ini_filename() {
|
||||
let _guard = crate::test::TEST_MUTEX.lock();
|
||||
let ctx = Context::create();
|
||||
assert_eq!(ctx.ini_filename(), Some(PathBuf::from("imgui.ini")));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_set_ini_filename() {
|
||||
let (_guard, mut ctx) = crate::test::test_ctx();
|
||||
ctx.set_ini_filename(Some(PathBuf::from("test.ini")));
|
||||
assert_eq!(ctx.ini_filename(), Some(PathBuf::from("test.ini")));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_default_log_filename() {
|
||||
let _guard = crate::test::TEST_MUTEX.lock();
|
||||
let ctx = Context::create();
|
||||
assert_eq!(ctx.log_filename(), Some(PathBuf::from("imgui_log.txt")));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_set_log_filename() {
|
||||
let (_guard, mut ctx) = crate::test::test_ctx();
|
||||
ctx.set_log_filename(Some(PathBuf::from("test.log")));
|
||||
assert_eq!(ctx.log_filename(), Some(PathBuf::from("test.log")));
|
||||
}
|
||||
|
||||
impl Context {
|
||||
/// Returns an immutable reference to the inputs/outputs object
|
||||
pub fn io(&self) -> &Io {
|
||||
unsafe {
|
||||
// safe because Io is a transparent wrapper around sys::ImGuiIO
|
||||
&*(sys::igGetIO() as *const Io)
|
||||
}
|
||||
}
|
||||
/// Returns a mutable reference to the inputs/outputs object
|
||||
pub fn io_mut(&mut self) -> &mut Io {
|
||||
unsafe {
|
||||
// safe because Io is a transparent wrapper around sys::ImGuiIO
|
||||
&mut *(sys::igGetIO() as *mut Io)
|
||||
}
|
||||
}
|
||||
/// Returns an immutable reference to the user interface style
|
||||
#[doc(alias = "GetStyle")]
|
||||
pub fn style(&self) -> &Style {
|
||||
unsafe {
|
||||
// safe because Style is a transparent wrapper around sys::ImGuiStyle
|
||||
&*(sys::igGetStyle() as *const Style)
|
||||
}
|
||||
}
|
||||
/// Returns a mutable reference to the user interface style
|
||||
#[doc(alias = "GetStyle")]
|
||||
pub fn style_mut(&mut self) -> &mut Style {
|
||||
unsafe {
|
||||
// safe because Style is a transparent wrapper around sys::ImGuiStyle
|
||||
&mut *(sys::igGetStyle() as *mut Style)
|
||||
}
|
||||
}
|
||||
/// Returns a mutable reference to the font atlas.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if the context uses a shared font atlas that is already borrowed
|
||||
pub fn fonts(&mut self) -> FontAtlasRefMut<'_> {
|
||||
match self.shared_font_atlas {
|
||||
Some(ref font_atlas) => FontAtlasRefMut::Shared(font_atlas.borrow_mut()),
|
||||
None => unsafe {
|
||||
// safe because FontAtlas is a transparent wrapper around sys::ImFontAtlas
|
||||
let fonts = &mut *(self.io_mut().fonts as *mut FontAtlas);
|
||||
FontAtlasRefMut::Owned(fonts)
|
||||
},
|
||||
}
|
||||
}
|
||||
/// Starts a new frame and returns an `Ui` instance for constructing a user interface.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if the context uses a shared font atlas that is already borrowed
|
||||
#[doc(alias = "NewFame")]
|
||||
pub fn frame(&mut self) -> Ui<'_> {
|
||||
// Clear default font if it no longer exists. This could be an error in the future
|
||||
let default_font = self.io().font_default;
|
||||
if !default_font.is_null() && self.fonts().get_font(FontId(default_font)).is_none() {
|
||||
self.io_mut().font_default = ptr::null_mut();
|
||||
}
|
||||
// NewFrame/Render/EndFrame mutate the font atlas so we need exclusive access to it
|
||||
let font_atlas = self
|
||||
.shared_font_atlas
|
||||
.as_ref()
|
||||
.map(|font_atlas| font_atlas.borrow_mut());
|
||||
// TODO: precondition checks
|
||||
unsafe {
|
||||
sys::igNewFrame();
|
||||
}
|
||||
Ui {
|
||||
ctx: self,
|
||||
font_atlas,
|
||||
buffer: crate::UiBuffer::new(1024).into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,594 +0,0 @@
|
||||
//! Structs to create a Drag and Drop sequence. Almost all structs are re-exported
|
||||
//! and can be accessed from the crate root; some additional utilities can be found in here.
|
||||
//!
|
||||
//! A DragDrop is a UI mechanism where users can appear to "drag"
|
||||
//! some data from one [source](DragDropSource) to one [target](DragDropTarget).
|
||||
//! A source and a target must both have some `name` identifier, which is declared when they
|
||||
//! are created. If these names are equal, then a `payload` of some kind
|
||||
//! will be given to the target caller when the user releases their mouse button over
|
||||
//! the target (additionally, the UI will reflect that the payload *can* be deposited
|
||||
//! in the target).
|
||||
//!
|
||||
//! The complexity of this implementation is primarily in managing this payload. Users
|
||||
//! can provide three different kinds of payloads:
|
||||
//!
|
||||
//! 1. Users can give an [empty payload](DragDropPayloadEmpty) with [begin](DragDropSource::begin).
|
||||
//! This payload type is essentially just a notification system, but using some shared state,
|
||||
//! this can be reasonably powerful, and is the safest way to transfer non-Copy data offered
|
||||
//! right now.
|
||||
//! 2. Users can give a [simple Copy payload](DragDropPayloadPod) with [begin](DragDropSource::begin_payload).
|
||||
//! This allows users to copy data to Dear ImGui, which will take ownership over it, and then be given
|
||||
//! it back to the Target. Please note: users are of course free to not drop any drag (cancel a drag),
|
||||
//! so this data could easily be lost forever. Our `'static + Copy` bound is intended to keep users
|
||||
//! to simplistic types.
|
||||
//! 3. An unsafe implementation is provided which allows for any data to be unsafely copied. Note that once
|
||||
//! you use this method, the safe implementations in #1 and #2 can create memory unsafety problems; notably,
|
||||
//! they both assume that a payload has certain header information within it.
|
||||
//!
|
||||
//! For examples of each payload type, see [DragDropSource].
|
||||
use std::{any, ffi, marker::PhantomData};
|
||||
|
||||
use crate::{sys, Condition, Ui};
|
||||
use bitflags::bitflags;
|
||||
|
||||
bitflags!(
|
||||
/// Flags for igBeginDragDropSource(), igAcceptDragDropPayload()
|
||||
#[repr(transparent)]
|
||||
pub struct DragDropFlags: u32 {
|
||||
/// By default, a successful call to igBeginDragDropSource opens a tooltip so you can
|
||||
/// display a preview or description of the source contents. This flag disable this
|
||||
/// behavior.
|
||||
const SOURCE_NO_PREVIEW_TOOLTIP = sys::ImGuiDragDropFlags_SourceNoPreviewTooltip;
|
||||
/// By default, when dragging we clear data so that igIsItemHovered() will return false, to
|
||||
/// avoid subsequent user code submitting tooltips. This flag disable this behavior so you
|
||||
/// can still call igIsItemHovered() on the source item.
|
||||
const SOURCE_NO_DISABLE_HOVER = sys::ImGuiDragDropFlags_SourceNoDisableHover;
|
||||
/// Disable the behavior that allows to open tree nodes and collapsing header by holding
|
||||
/// over them while dragging a source item.
|
||||
const SOURCE_NO_HOLD_TO_OPEN_OTHERS = sys::ImGuiDragDropFlags_SourceNoHoldToOpenOthers;
|
||||
/// Allow items such as igText(), igImage() that have no unique identifier to be used as
|
||||
/// drag source, by manufacturing a temporary identifier based on their window-relative
|
||||
/// position. This is extremely unusual within the dear imgui ecosystem and so we made it
|
||||
/// explicit.
|
||||
const SOURCE_ALLOW_NULL_ID = sys::ImGuiDragDropFlags_SourceAllowNullID;
|
||||
/// External source (from outside of imgui), won't attempt to read current item/window
|
||||
/// info. Will always return true. Only one Extern source can be active simultaneously.
|
||||
const SOURCE_EXTERN = sys::ImGuiDragDropFlags_SourceExtern;
|
||||
/// Automatically expire the payload if the source ceases to be submitted (otherwise
|
||||
/// payloads are persisting while being dragged)
|
||||
const SOURCE_AUTO_EXPIRE_PAYLOAD = sys::ImGuiDragDropFlags_SourceAutoExpirePayload;
|
||||
/// igAcceptDragDropPayload() will returns true even before the mouse button is released.
|
||||
/// You can then call igIsDelivery() to test if the payload needs to be delivered.
|
||||
const ACCEPT_BEFORE_DELIVERY = sys::ImGuiDragDropFlags_AcceptBeforeDelivery;
|
||||
/// Do not draw the default highlight rectangle when hovering over target.
|
||||
const ACCEPT_NO_DRAW_DEFAULT_RECT = sys::ImGuiDragDropFlags_AcceptNoDrawDefaultRect;
|
||||
/// Request hiding the igBeginDragDropSource tooltip from the igBeginDragDropTarget site.
|
||||
const ACCEPT_NO_PREVIEW_TOOLTIP = sys::ImGuiDragDropFlags_AcceptNoPreviewTooltip;
|
||||
/// For peeking ahead and inspecting the payload before delivery. This is just a convenience
|
||||
/// flag for the intersection of `ACCEPT_BEFORE_DELIVERY` and `ACCEPT_NO_DRAW_DEFAULT_RECT`
|
||||
const ACCEPT_PEEK_ONLY = sys::ImGuiDragDropFlags_AcceptPeekOnly;
|
||||
}
|
||||
);
|
||||
|
||||
/// Creates a source for drag drop data out of the last ID created.
|
||||
///
|
||||
/// ```no_run
|
||||
/// # use imgui::*;
|
||||
/// fn show_ui(ui: &Ui<'_>) {
|
||||
/// ui.button("Hello, I am a drag source!");
|
||||
///
|
||||
/// // Creates an empty DragSource with no tooltip
|
||||
/// DragDropSource::new("BUTTON_DRAG").begin(ui);
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// Notice especially the `"BUTTON_DRAG"` name -- this is the identifier of this
|
||||
/// DragDropSource; [DragDropTarget]'s will specify an identifier to *receive*, and these
|
||||
/// names must match up. A single item should only have one [DragDropSource], though
|
||||
/// a target may have multiple different targets.
|
||||
///
|
||||
/// DropDropSources don't do anything until you use one of the three `begin_` methods
|
||||
/// on this struct. Each of these methods describes how you handle the Payload which ImGui
|
||||
/// will manage, and then give to a [DragDropTarget], which will received the payload. The
|
||||
/// simplest and safest Payload is the empty payload, created with [begin](Self::begin).
|
||||
#[derive(Debug)]
|
||||
pub struct DragDropSource<T> {
|
||||
name: T,
|
||||
flags: DragDropFlags,
|
||||
cond: Condition,
|
||||
}
|
||||
|
||||
impl<T: AsRef<str>> DragDropSource<T> {
|
||||
/// Creates a new [DragDropSource] with no flags and the `Condition::Always` with the given name.
|
||||
/// ImGui refers to this `name` field as a `type`, but really it's just an identifier to match up
|
||||
/// Source/Target for DragDrop.
|
||||
pub fn new(name: T) -> Self {
|
||||
Self {
|
||||
name,
|
||||
flags: DragDropFlags::empty(),
|
||||
cond: Condition::Always,
|
||||
}
|
||||
}
|
||||
|
||||
/// Sets the flags on the [DragDropSource]. Only the flags `SOURCE_NO_PREVIEW_TOOLTIP`,
|
||||
/// `SOURCE_NO_DISABLE_HOVER`, `SOURCE_NO_HOLD_TO_OPEN_OTHERS`, `SOURCE_ALLOW_NULL_ID`,
|
||||
/// `SOURCE_EXTERN`, `SOURCE_AUTO_EXPIRE_PAYLOAD` make semantic sense, but any other flags will
|
||||
/// be accepted without panic.
|
||||
#[inline]
|
||||
pub fn flags(mut self, flags: DragDropFlags) -> Self {
|
||||
self.flags = flags;
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the condition on the [DragDropSource]. Defaults to [Always](Condition::Always).
|
||||
#[inline]
|
||||
pub fn condition(mut self, cond: Condition) -> Self {
|
||||
self.cond = cond;
|
||||
self
|
||||
}
|
||||
|
||||
/// Creates the source of a drag and returns a handle on the tooltip.
|
||||
/// This handle can be immediately dropped without binding it, in which case a default empty
|
||||
/// circle will be used for the "blank" tooltip as this item is being dragged around.
|
||||
///
|
||||
/// Otherwise, use this tooltip to add data which will display as this item is dragged.
|
||||
/// If `SOURCE_NO_PREVIEW_TOOLTIP` is enabled, however, no preview will be displayed
|
||||
/// and this returned token does nothing. Additionally, a given target may use the flag
|
||||
/// `ACCEPT_NO_PREVIEW_TOOLTIP`, which will also prevent this tooltip from being shown.
|
||||
///
|
||||
/// This drag has no payload, but is still probably the most useful way in imgui-rs to handle payloads.
|
||||
/// Using `once_cell` or some shared data, this pattern can be very powerful:
|
||||
///
|
||||
/// ```no_run
|
||||
/// # use imgui::*;
|
||||
/// fn show_ui(ui: &Ui<'_>, drop_message: &mut Option<String>) {
|
||||
/// ui.button("Drag me!");
|
||||
///
|
||||
/// let drag_drop_name = "Test Drag";
|
||||
///
|
||||
/// // drag drop SOURCE
|
||||
/// if DragDropSource::new(drag_drop_name).begin(ui).is_some() {
|
||||
/// // warning -- this would allocate every frame if `DragDropSource` has
|
||||
/// // condition `Always`, which it does by default. We're okay with that for
|
||||
/// // this example, but real code probably wouldn't want to allocate so much.
|
||||
/// *drop_message = Some("Test Payload".to_string());
|
||||
/// }
|
||||
///
|
||||
/// ui.button("Target me!");
|
||||
///
|
||||
/// // drag drop TARGET
|
||||
/// if let Some(target) = imgui::DragDropTarget::new(ui) {
|
||||
/// if target
|
||||
/// .accept_payload_empty(drag_drop_name, DragDropFlags::empty())
|
||||
/// .is_some()
|
||||
/// {
|
||||
/// let msg = drop_message.take().unwrap();
|
||||
/// assert_eq!(msg, "Test Payload");
|
||||
/// }
|
||||
///
|
||||
/// target.pop();
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// In the above, you'll see how the payload is really just a message passing service.
|
||||
/// If you want to pass a simple integer or other "plain old data", take a look at
|
||||
/// [begin_payload](Self::begin_payload).
|
||||
#[inline]
|
||||
pub fn begin<'ui>(self, ui: &Ui<'ui>) -> Option<DragDropSourceToolTip<'ui>> {
|
||||
self.begin_payload(ui, ())
|
||||
}
|
||||
|
||||
/// Creates the source of a drag and returns a handle on the tooltip.
|
||||
/// This handle can be immediately dropped without binding it, in which case a default empty
|
||||
/// circle will be used for the "blank" tooltip as this item is being dragged around.
|
||||
///
|
||||
/// Otherwise, use this tooltip to add data which will display as this item is dragged.
|
||||
/// If `SOURCE_NO_PREVIEW_TOOLTIP` is enabled, however, no preview will be displayed
|
||||
/// and this returned token does nothing. Additionally, a given target may use the flag
|
||||
/// `ACCEPT_NO_PREVIEW_TOOLTIP`, which will also prevent this tooltip from being shown.
|
||||
///
|
||||
/// This function also takes a payload in the form of `T: Copy + 'static`. ImGui will
|
||||
/// memcpy this data immediately to an internally held buffer, and will return the data
|
||||
/// to [DragDropTarget].
|
||||
///
|
||||
/// ```no_run
|
||||
/// # use imgui::*;
|
||||
/// fn show_ui(ui: &Ui<'_>) {
|
||||
/// ui.button("Drag me!");
|
||||
///
|
||||
/// let drag_drop_name = "Test Drag";
|
||||
/// let msg_to_send = "hello there sailor";
|
||||
///
|
||||
/// // drag drop SOURCE
|
||||
/// if let Some(tooltip) = DragDropSource::new(drag_drop_name).begin_payload(ui, msg_to_send) {
|
||||
/// ui.text("Sending message!");
|
||||
/// tooltip.end();
|
||||
/// }
|
||||
///
|
||||
/// ui.button("Target me!");
|
||||
///
|
||||
/// // drag drop TARGET
|
||||
/// if let Some(target) = imgui::DragDropTarget::new(ui) {
|
||||
/// if let Some(Ok(payload_data)) = target
|
||||
/// .accept_payload::<&'static str, _>(drag_drop_name, DragDropFlags::empty())
|
||||
/// {
|
||||
/// let msg = payload_data.data;
|
||||
/// assert_eq!(msg, msg_to_send);
|
||||
/// }
|
||||
///
|
||||
/// target.pop();
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
#[inline]
|
||||
pub fn begin_payload<'ui, P: Copy + 'static>(
|
||||
self,
|
||||
ui: &Ui<'ui>,
|
||||
payload: P,
|
||||
) -> Option<DragDropSourceToolTip<'ui>> {
|
||||
unsafe {
|
||||
let payload = TypedPayload::new(payload);
|
||||
self.begin_payload_unchecked(
|
||||
ui,
|
||||
&payload as *const _ as *const ffi::c_void,
|
||||
std::mem::size_of::<TypedPayload<P>>(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates the source of a drag and returns a handle on the tooltip.
|
||||
/// This handle can be immediately dropped without binding it, in which case a default empty
|
||||
/// circle will be used for the "blank" tooltip as this item is being dragged around.
|
||||
///
|
||||
/// Otherwise, use this tooltip to add data which will display as this item is dragged.
|
||||
/// If `SOURCE_NO_PREVIEW_TOOLTIP` is enabled, however, no preview will be displayed
|
||||
/// and this returned token does nothing. Additionally, a given target may use the flag
|
||||
/// `ACCEPT_NO_PREVIEW_TOOLTIP`, which will also prevent this tooltip from being shown.
|
||||
///
|
||||
/// This function also takes a payload of any `*const T`. ImGui will
|
||||
/// memcpy this data immediately to an internally held buffer, and will return the data
|
||||
/// to [DragDropTarget].
|
||||
///
|
||||
/// ## Safety
|
||||
/// This function itself will not cause a panic, but using it directly opts you into
|
||||
/// managing the lifetime of the pointer provided yourself. Dear ImGui will execute a memcpy on
|
||||
/// the data passed in with the size (in bytes) given, but this is, of course, just a copy,
|
||||
/// so if you pass in an `&String`, for example, the underlying String data will not be cloned,
|
||||
/// and could easily dangle if the `String` is dropped.
|
||||
///
|
||||
/// Moreover, if `Condition::Always` is set (as it is by default), you will be copying in your data
|
||||
/// every time this function is ran in your update loop, which if it involves an allocating and then
|
||||
/// handing the allocation to ImGui, would result in a significant amount of data created.
|
||||
///
|
||||
/// Overall, users should be very sure that this function is needed before they reach for it, and instead
|
||||
/// should consider either [begin](Self::begin) or [begin_payload](Self::begin_payload).
|
||||
#[inline]
|
||||
pub unsafe fn begin_payload_unchecked<'ui>(
|
||||
&self,
|
||||
ui: &Ui<'ui>,
|
||||
ptr: *const ffi::c_void,
|
||||
size: usize,
|
||||
) -> Option<DragDropSourceToolTip<'ui>> {
|
||||
let should_begin = sys::igBeginDragDropSource(self.flags.bits() as i32);
|
||||
|
||||
if should_begin {
|
||||
sys::igSetDragDropPayload(ui.scratch_txt(&self.name), ptr, size, self.cond as i32);
|
||||
|
||||
Some(DragDropSourceToolTip::push())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A helper struct for RAII drag-drop support.
|
||||
pub struct DragDropSourceToolTip<'ui>(PhantomData<Ui<'ui>>);
|
||||
|
||||
impl DragDropSourceToolTip<'_> {
|
||||
/// Creates a new tooltip internally.
|
||||
#[inline]
|
||||
fn push() -> Self {
|
||||
Self(PhantomData)
|
||||
}
|
||||
|
||||
/// Ends the tooltip directly. You could choose to simply allow this to drop
|
||||
/// by not calling this, which will also be fine.
|
||||
#[inline]
|
||||
pub fn end(self) {
|
||||
// left empty to invoke drop...
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for DragDropSourceToolTip<'_> {
|
||||
fn drop(&mut self) {
|
||||
unsafe { sys::igEndDragDropSource() }
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates a target for drag drop data out of the last ID created.
|
||||
///
|
||||
/// ```no_run
|
||||
/// # use imgui::*;
|
||||
/// fn show_ui(ui: &Ui<'_>) {
|
||||
/// // Drop something on this button please!
|
||||
/// ui.button("Hello, I am a drag Target!");
|
||||
///
|
||||
/// if let Some(target) = DragDropTarget::new(ui) {
|
||||
/// // accepting an empty payload (which is really just raising an event)
|
||||
/// if let Some(_payload_data) = target.accept_payload_empty("BUTTON_DRAG", DragDropFlags::empty()) {
|
||||
/// println!("Nice job getting on the payload!");
|
||||
/// }
|
||||
///
|
||||
/// // and we can accept multiple, different types of payloads with one drop target.
|
||||
/// // this is a good pattern for handling different kinds of drag/drop situations with
|
||||
/// // different kinds of data in them.
|
||||
/// if let Some(Ok(payload_data)) = target.accept_payload::<usize, _>("BUTTON_ID", DragDropFlags::empty()) {
|
||||
/// println!("Our payload's data was {}", payload_data.data);
|
||||
/// }
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// Notice especially the `"BUTTON_DRAG"` and `"BUTTON_ID"` name -- this is the identifier of this
|
||||
/// DragDropTarget; [DragDropSource]s will specify an identifier when they send a payload, and these
|
||||
/// names must match up. Notice how a target can have multiple acceptances on them -- this is a good
|
||||
/// pattern to handle multiple kinds of data which could be passed around.
|
||||
///
|
||||
/// DropDropTargets don't do anything until you use one of the three `accept_` methods
|
||||
/// on this struct. Each of these methods will spit out a _Payload struct with an increasing
|
||||
/// amount of information on the Payload. The absolute safest solution is [accept_payload_empty](Self::accept_payload_empty).
|
||||
#[derive(Debug)]
|
||||
pub struct DragDropTarget<'ui>(&'ui Ui<'ui>);
|
||||
|
||||
impl<'ui> DragDropTarget<'ui> {
|
||||
/// Creates a new DragDropTarget, holding the [Ui]'s lifetime for the duration
|
||||
/// of its existence. This is required since this struct runs some code on its Drop
|
||||
/// to end the DragDropTarget code.
|
||||
#[doc(alias = "BeginDragDropTarget")]
|
||||
pub fn new(ui: &'ui Ui<'ui>) -> Option<Self> {
|
||||
let should_begin = unsafe { sys::igBeginDragDropTarget() };
|
||||
if should_begin {
|
||||
Some(Self(ui))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
/// Accepts an empty payload. This is the safest option for raising named events
|
||||
/// in the DragDrop API. See [DragDropSource::begin] for more information on how you
|
||||
/// might use this pattern.
|
||||
///
|
||||
/// Note: If you began this operation with `begin_payload_unchecked` it always incorrect
|
||||
/// to use this function. Use `accept_payload_unchecked` instead
|
||||
pub fn accept_payload_empty(
|
||||
&self,
|
||||
name: impl AsRef<str>,
|
||||
flags: DragDropFlags,
|
||||
) -> Option<DragDropPayloadEmpty> {
|
||||
self.accept_payload(name, flags)?
|
||||
.ok()
|
||||
.map(|payload_pod: DragDropPayloadPod<()>| DragDropPayloadEmpty {
|
||||
preview: payload_pod.preview,
|
||||
delivery: payload_pod.delivery,
|
||||
})
|
||||
}
|
||||
|
||||
/// Accepts a payload with plain old data in it. This returns a Result, since you can specify any
|
||||
/// type. The sent type must match the return type (via TypeId) to receive an `Ok`.
|
||||
///
|
||||
/// Note: If you began this operation with `begin_payload_unchecked` it always incorrect
|
||||
/// to use this function. Use `accept_payload_unchecked` instead
|
||||
pub fn accept_payload<T: 'static + Copy, Name: AsRef<str>>(
|
||||
&self,
|
||||
name: Name,
|
||||
flags: DragDropFlags,
|
||||
) -> Option<Result<DragDropPayloadPod<T>, PayloadIsWrongType>> {
|
||||
let output = unsafe { self.accept_payload_unchecked(name, flags) };
|
||||
|
||||
// convert the unsafe payload to our Result
|
||||
output.map(|unsafe_payload| {
|
||||
// sheering off the typeid...
|
||||
let received =
|
||||
unsafe { (unsafe_payload.data as *const TypedPayloadHeader).read_unaligned() };
|
||||
let expected = any::TypeId::of::<T>();
|
||||
|
||||
if received.type_id == expected {
|
||||
let data =
|
||||
unsafe { (unsafe_payload.data as *const TypedPayload<T>).read_unaligned() }
|
||||
.data;
|
||||
Ok(DragDropPayloadPod {
|
||||
data,
|
||||
preview: unsafe_payload.preview,
|
||||
delivery: unsafe_payload.delivery,
|
||||
})
|
||||
} else {
|
||||
Err(PayloadIsWrongType {
|
||||
received,
|
||||
expected: TypedPayloadHeader::new::<T>(),
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/// Accepts a drag and drop payload which contains a raw pointer to [c_void](std::ffi::c_void)
|
||||
/// and a size in bytes. Users should generally avoid using this function
|
||||
/// if one of the safer variants is acceptable.
|
||||
///
|
||||
/// ## Safety
|
||||
///
|
||||
/// Because this pointer comes from ImGui, absolutely no promises can be made on its
|
||||
/// contents, alignment, or lifetime. Interacting with it is therefore extremely unsafe.
|
||||
/// **Important:** a special note needs to be made to the [ACCEPT_BEFORE_DELIVERY](DragDropFlags::ACCEPT_BEFORE_DELIVERY) flag --
|
||||
/// passing this flag will make this function return `Some(DragDropPayload)` **even before
|
||||
/// the user has actually "dropped" the payload by release their mouse button.**
|
||||
///
|
||||
/// In safe functions, this works just fine, since the data can be freely copied
|
||||
/// (or doesn't exist at all!). However, if you are working with your own data, you must
|
||||
/// be extremely careful with this data, as you may, effectively, only have immutable access to it.
|
||||
///
|
||||
/// Moreover, if the `DragDropSource` has also used `Condition::Once` or similar when they sent the data,
|
||||
/// ImGui will assume its data is still valid even after your preview, so corrupting that data could
|
||||
/// lead to all sorts of unsafe behavior on ImGui's side. In summary, using this function for any data
|
||||
/// which isn't truly `Copy` or "plain old data" is difficult, and requires substantial knowledge
|
||||
/// of the various edge cases.
|
||||
pub unsafe fn accept_payload_unchecked(
|
||||
&self,
|
||||
name: impl AsRef<str>,
|
||||
flags: DragDropFlags,
|
||||
) -> Option<DragDropPayload> {
|
||||
let inner = sys::igAcceptDragDropPayload(self.0.scratch_txt(name), flags.bits() as i32);
|
||||
if inner.is_null() {
|
||||
None
|
||||
} else {
|
||||
let inner = *inner;
|
||||
|
||||
// @fixme: there are actually other fields on `inner` which I have shorn -- they're
|
||||
// considered internal to imgui (such as id of who sent this), so i've left it for
|
||||
// now this way.
|
||||
Some(DragDropPayload {
|
||||
data: inner.Data,
|
||||
size: inner.DataSize as usize,
|
||||
preview: inner.Preview,
|
||||
delivery: inner.Delivery,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// Ends the current target. Ironically, this doesn't really do anything in ImGui
|
||||
/// or in imgui-rs, but it might in the future.
|
||||
pub fn pop(self) {
|
||||
// omitted...exists just to run Drop.
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for DragDropTarget<'_> {
|
||||
fn drop(&mut self) {
|
||||
unsafe { sys::igEndDragDropTarget() }
|
||||
}
|
||||
}
|
||||
|
||||
/// An empty DragDropPayload. It has no data in it, and just includes
|
||||
/// two bools with status information.
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
#[non_exhaustive]
|
||||
pub struct DragDropPayloadEmpty {
|
||||
/// Set when [`accept_payload_empty`](DragDropTarget::accept_payload_empty) was called
|
||||
/// and mouse has been hovering the target item.
|
||||
pub preview: bool,
|
||||
|
||||
/// Set when [`accept_payload_empty`](DragDropTarget::accept_payload_empty) was
|
||||
/// called and mouse button is released over the target item.
|
||||
pub delivery: bool,
|
||||
}
|
||||
|
||||
/// A DragDropPayload with status information and some POD, or plain old data,
|
||||
/// in it.
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
#[non_exhaustive]
|
||||
pub struct DragDropPayloadPod<T: 'static + Copy> {
|
||||
/// The kind data which was requested.
|
||||
pub data: T,
|
||||
|
||||
/// Set when [`accept_payload`](DragDropTarget::accept_payload) was called
|
||||
/// and mouse has been hovering the target item.
|
||||
pub preview: bool,
|
||||
|
||||
/// Set when [`accept_payload`](DragDropTarget::accept_payload) was
|
||||
/// called and mouse button is released over the target item.
|
||||
pub delivery: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[non_exhaustive]
|
||||
pub struct DragDropPayload {
|
||||
/// Data which is copied and owned by ImGui. If you have accepted the payload, you can
|
||||
/// take ownership of the data; otherwise, view it immutably. Interacting with `data` is
|
||||
/// very unsafe.
|
||||
pub data: *const ffi::c_void,
|
||||
|
||||
/// The size of the data in bytes.
|
||||
pub size: usize,
|
||||
|
||||
/// Set when [`accept_payload_unchecked`](DragDropTarget::accept_payload_unchecked) was called
|
||||
/// and mouse has been hovering the target item.
|
||||
pub preview: bool,
|
||||
|
||||
/// Set when [`accept_payload_unchecked`](DragDropTarget::accept_payload_unchecked) was
|
||||
/// called and mouse button is released over the target item. If this is set to false, then you
|
||||
/// set DragDropFlags::ACCEPT_BEFORE_DELIVERY and shouldn't mutate `data`.
|
||||
pub delivery: bool,
|
||||
}
|
||||
|
||||
/// A typed payload.
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
#[repr(C)]
|
||||
struct TypedPayload<T> {
|
||||
header: TypedPayloadHeader,
|
||||
data: T,
|
||||
}
|
||||
|
||||
impl<T: Copy + 'static> TypedPayload<T> {
|
||||
/// Creates a new typed payload which contains this data.
|
||||
fn new(data: T) -> Self {
|
||||
Self {
|
||||
header: TypedPayloadHeader::new::<T>(),
|
||||
data,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A header for a typed payload.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Ord, PartialOrd)]
|
||||
#[repr(C)]
|
||||
struct TypedPayloadHeader {
|
||||
type_id: any::TypeId,
|
||||
#[cfg(debug_assertions)]
|
||||
type_name: &'static str,
|
||||
}
|
||||
|
||||
impl TypedPayloadHeader {
|
||||
#[cfg(debug_assertions)]
|
||||
fn new<T: 'static>() -> Self {
|
||||
Self {
|
||||
type_id: any::TypeId::of::<T>(),
|
||||
type_name: any::type_name::<T>(),
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(debug_assertions))]
|
||||
fn new<T: 'static>() -> Self {
|
||||
Self {
|
||||
type_id: any::TypeId::of::<T>(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Indicates that an incorrect payload type was received. It is opaque,
|
||||
/// but you can view useful information with Debug formatting when
|
||||
/// `debug_assertions` are enabled.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Ord, PartialOrd)]
|
||||
pub struct PayloadIsWrongType {
|
||||
expected: TypedPayloadHeader,
|
||||
received: TypedPayloadHeader,
|
||||
}
|
||||
|
||||
#[cfg(debug_assertions)]
|
||||
impl std::fmt::Display for PayloadIsWrongType {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
"Payload is {} -- expected {}",
|
||||
self.received.type_name, self.expected.type_name
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(debug_assertions))]
|
||||
impl std::fmt::Display for PayloadIsWrongType {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
f.pad("Payload is wrong type")
|
||||
}
|
||||
}
|
||||
|
||||
impl std::error::Error for PayloadIsWrongType {}
|
||||
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user