1 | // This file defines all the identifier enums and target-aware logic. |
2 | |
3 | use crate::triple::{Endianness, PointerWidth, Triple}; |
4 | use alloc::borrow::Cow; |
5 | use alloc::boxed::Box; |
6 | use alloc::format; |
7 | use alloc::string::String; |
8 | use core::fmt; |
9 | use core::hash::{Hash, Hasher}; |
10 | use core::str::FromStr; |
11 | |
12 | /// The "architecture" field, which in some cases also specifies a specific |
13 | /// subarchitecture. |
14 | #[cfg_attr (feature = "rust_1_40" , non_exhaustive)] |
15 | #[derive (Copy, Clone, Debug, PartialEq, Eq, Hash)] |
16 | #[allow (missing_docs)] |
17 | pub enum Architecture { |
18 | Unknown, |
19 | Arm(ArmArchitecture), |
20 | AmdGcn, |
21 | Aarch64(Aarch64Architecture), |
22 | Asmjs, |
23 | Avr, |
24 | Bpfeb, |
25 | Bpfel, |
26 | Hexagon, |
27 | X86_32(X86_32Architecture), |
28 | M68k, |
29 | LoongArch64, |
30 | Mips32(Mips32Architecture), |
31 | Mips64(Mips64Architecture), |
32 | Msp430, |
33 | Nvptx64, |
34 | Powerpc, |
35 | Powerpc64, |
36 | Powerpc64le, |
37 | Riscv32(Riscv32Architecture), |
38 | Riscv64(Riscv64Architecture), |
39 | S390x, |
40 | Sparc, |
41 | Sparc64, |
42 | Sparcv9, |
43 | Wasm32, |
44 | Wasm64, |
45 | X86_64, |
46 | /// x86_64 target that only supports Haswell-compatible Intel chips. |
47 | X86_64h, |
48 | XTensa, |
49 | Clever(CleverArchitecture), |
50 | /// A software machine that produces zero-knowledge proofs of the execution. |
51 | /// |
52 | /// See https://wiki.polygon.technology/docs/category/zk-assembly/ |
53 | #[cfg (feature = "arch_zkasm" )] |
54 | ZkAsm, |
55 | } |
56 | |
57 | #[cfg_attr (feature = "rust_1_40" , non_exhaustive)] |
58 | #[derive (Copy, Clone, Debug, PartialEq, Eq, Hash)] |
59 | #[allow (missing_docs)] |
60 | pub enum ArmArchitecture { |
61 | Arm, // Generic arm |
62 | Armeb, |
63 | Armv4, |
64 | Armv4t, |
65 | Armv5t, |
66 | Armv5te, |
67 | Armv5tej, |
68 | Armv6, |
69 | Armv6j, |
70 | Armv6k, |
71 | Armv6z, |
72 | Armv6kz, |
73 | Armv6t2, |
74 | Armv6m, |
75 | Armv7, |
76 | Armv7a, |
77 | Armv7k, |
78 | Armv7ve, |
79 | Armv7m, |
80 | Armv7r, |
81 | Armv7s, |
82 | Armv8, |
83 | Armv8a, |
84 | Armv8_1a, |
85 | Armv8_2a, |
86 | Armv8_3a, |
87 | Armv8_4a, |
88 | Armv8_5a, |
89 | Armv8mBase, |
90 | Armv8mMain, |
91 | Armv8r, |
92 | |
93 | Armebv7r, |
94 | |
95 | Thumbeb, |
96 | Thumbv4t, |
97 | Thumbv5te, |
98 | Thumbv6m, |
99 | Thumbv7a, |
100 | Thumbv7em, |
101 | Thumbv7m, |
102 | Thumbv7neon, |
103 | Thumbv8mBase, |
104 | Thumbv8mMain, |
105 | } |
106 | |
107 | #[cfg_attr (feature = "rust_1_40" , non_exhaustive)] |
108 | #[derive (Copy, Clone, Debug, PartialEq, Eq, Hash)] |
109 | #[allow (missing_docs)] |
110 | pub enum Aarch64Architecture { |
111 | Aarch64, |
112 | Aarch64be, |
113 | } |
114 | |
115 | // #[cfg_attr(feature = "rust_1_40", non_exhaustive)] |
116 | // #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] |
117 | // #[allow(missing_docs)] |
118 | // pub enum ArmFpu { |
119 | // Vfp, |
120 | // Vfpv2, |
121 | // Vfpv3, |
122 | // Vfpv3Fp16, |
123 | // Vfpv3Xd, |
124 | // Vfpv3XdFp16, |
125 | // Neon, |
126 | // NeonVfpv3, |
127 | // NeonVfpv4, |
128 | // Vfpv4, |
129 | // Vfpv4D16, |
130 | // Fpv4SpD16, |
131 | // Fpv5SpD16, |
132 | // Fpv5D16, |
133 | // FpArmv8, |
134 | // NeonFpArmv8, |
135 | // CryptoNeonFpArmv8, |
136 | // } |
137 | |
138 | impl ArmArchitecture { |
139 | /// Test if this architecture uses the Thumb instruction set. |
140 | #[rustfmt::skip] |
141 | pub fn is_thumb(self) -> bool { |
142 | use ArmArchitecture::*; |
143 | |
144 | match self { |
145 | Arm |
146 | | Armeb |
147 | | Armv4 |
148 | | Armv4t |
149 | | Armv5t |
150 | | Armv5te |
151 | | Armv5tej |
152 | | Armv6 |
153 | | Armv6j |
154 | | Armv6k |
155 | | Armv6z |
156 | | Armv6kz |
157 | | Armv6t2 |
158 | | Armv6m |
159 | | Armv7 |
160 | | Armv7a |
161 | | Armv7k |
162 | | Armv7ve |
163 | | Armv7m |
164 | | Armv7r |
165 | | Armv7s |
166 | | Armv8 |
167 | | Armv8a |
168 | | Armv8_1a |
169 | | Armv8_2a |
170 | | Armv8_3a |
171 | | Armv8_4a |
172 | | Armv8_5a |
173 | | Armv8mBase |
174 | | Armv8mMain |
175 | | Armv8r |
176 | | Armebv7r => false, |
177 | Thumbeb |
178 | | Thumbv4t |
179 | | Thumbv5te |
180 | | Thumbv6m |
181 | | Thumbv7a |
182 | | Thumbv7em |
183 | | Thumbv7m |
184 | | Thumbv7neon |
185 | | Thumbv8mBase |
186 | | Thumbv8mMain => true, |
187 | } |
188 | } |
189 | |
190 | // pub fn has_fpu(self) -> Result<&'static [ArmFpu], ()> { |
191 | |
192 | // } |
193 | |
194 | /// Return the pointer bit width of this target's architecture. |
195 | #[rustfmt::skip] |
196 | pub fn pointer_width(self) -> PointerWidth { |
197 | use ArmArchitecture::*; |
198 | |
199 | match self { |
200 | Arm |
201 | | Armeb |
202 | | Armv4 |
203 | | Armv4t |
204 | | Armv5t |
205 | | Armv5te |
206 | | Armv5tej |
207 | | Armv6 |
208 | | Armv6j |
209 | | Armv6k |
210 | | Armv6z |
211 | | Armv6kz |
212 | | Armv6t2 |
213 | | Armv6m |
214 | | Armv7 |
215 | | Armv7a |
216 | | Armv7k |
217 | | Armv7ve |
218 | | Armv7m |
219 | | Armv7r |
220 | | Armv7s |
221 | | Armv8 |
222 | | Armv8a |
223 | | Armv8_1a |
224 | | Armv8_2a |
225 | | Armv8_3a |
226 | | Armv8_4a |
227 | | Armv8_5a |
228 | | Armv8mBase |
229 | | Armv8mMain |
230 | | Armv8r |
231 | | Armebv7r |
232 | | Thumbeb |
233 | | Thumbv4t |
234 | | Thumbv5te |
235 | | Thumbv6m |
236 | | Thumbv7a |
237 | | Thumbv7em |
238 | | Thumbv7m |
239 | | Thumbv7neon |
240 | | Thumbv8mBase |
241 | | Thumbv8mMain => PointerWidth::U32, |
242 | } |
243 | } |
244 | |
245 | /// Return the endianness of this architecture. |
246 | #[rustfmt::skip] |
247 | pub fn endianness(self) -> Endianness { |
248 | use ArmArchitecture::*; |
249 | |
250 | match self { |
251 | Arm |
252 | | Armv4 |
253 | | Armv4t |
254 | | Armv5t |
255 | | Armv5te |
256 | | Armv5tej |
257 | | Armv6 |
258 | | Armv6j |
259 | | Armv6k |
260 | | Armv6z |
261 | | Armv6kz |
262 | | Armv6t2 |
263 | | Armv6m |
264 | | Armv7 |
265 | | Armv7a |
266 | | Armv7k |
267 | | Armv7ve |
268 | | Armv7m |
269 | | Armv7r |
270 | | Armv7s |
271 | | Armv8 |
272 | | Armv8a |
273 | | Armv8_1a |
274 | | Armv8_2a |
275 | | Armv8_3a |
276 | | Armv8_4a |
277 | | Armv8_5a |
278 | | Armv8mBase |
279 | | Armv8mMain |
280 | | Armv8r |
281 | | Thumbv4t |
282 | | Thumbv5te |
283 | | Thumbv6m |
284 | | Thumbv7a |
285 | | Thumbv7em |
286 | | Thumbv7m |
287 | | Thumbv7neon |
288 | | Thumbv8mBase |
289 | | Thumbv8mMain => Endianness::Little, |
290 | Armeb | Armebv7r | Thumbeb => Endianness::Big, |
291 | } |
292 | } |
293 | |
294 | /// Convert into a string |
295 | pub fn into_str(self) -> Cow<'static, str> { |
296 | use ArmArchitecture::*; |
297 | |
298 | match self { |
299 | Arm => Cow::Borrowed("arm" ), |
300 | Armeb => Cow::Borrowed("armeb" ), |
301 | Armv4 => Cow::Borrowed("armv4" ), |
302 | Armv4t => Cow::Borrowed("armv4t" ), |
303 | Armv5t => Cow::Borrowed("armv5t" ), |
304 | Armv5te => Cow::Borrowed("armv5te" ), |
305 | Armv5tej => Cow::Borrowed("armv5tej" ), |
306 | Armv6 => Cow::Borrowed("armv6" ), |
307 | Armv6j => Cow::Borrowed("armv6j" ), |
308 | Armv6k => Cow::Borrowed("armv6k" ), |
309 | Armv6z => Cow::Borrowed("armv6z" ), |
310 | Armv6kz => Cow::Borrowed("armv6kz" ), |
311 | Armv6t2 => Cow::Borrowed("armv6t2" ), |
312 | Armv6m => Cow::Borrowed("armv6m" ), |
313 | Armv7 => Cow::Borrowed("armv7" ), |
314 | Armv7a => Cow::Borrowed("armv7a" ), |
315 | Armv7k => Cow::Borrowed("armv7k" ), |
316 | Armv7ve => Cow::Borrowed("armv7ve" ), |
317 | Armv7m => Cow::Borrowed("armv7m" ), |
318 | Armv7r => Cow::Borrowed("armv7r" ), |
319 | Armv7s => Cow::Borrowed("armv7s" ), |
320 | Armv8 => Cow::Borrowed("armv8" ), |
321 | Armv8a => Cow::Borrowed("armv8a" ), |
322 | Armv8_1a => Cow::Borrowed("armv8.1a" ), |
323 | Armv8_2a => Cow::Borrowed("armv8.2a" ), |
324 | Armv8_3a => Cow::Borrowed("armv8.3a" ), |
325 | Armv8_4a => Cow::Borrowed("armv8.4a" ), |
326 | Armv8_5a => Cow::Borrowed("armv8.5a" ), |
327 | Armv8mBase => Cow::Borrowed("armv8m.base" ), |
328 | Armv8mMain => Cow::Borrowed("armv8m.main" ), |
329 | Armv8r => Cow::Borrowed("armv8r" ), |
330 | Thumbeb => Cow::Borrowed("thumbeb" ), |
331 | Thumbv4t => Cow::Borrowed("thumbv4t" ), |
332 | Thumbv5te => Cow::Borrowed("thumbv5te" ), |
333 | Thumbv6m => Cow::Borrowed("thumbv6m" ), |
334 | Thumbv7a => Cow::Borrowed("thumbv7a" ), |
335 | Thumbv7em => Cow::Borrowed("thumbv7em" ), |
336 | Thumbv7m => Cow::Borrowed("thumbv7m" ), |
337 | Thumbv7neon => Cow::Borrowed("thumbv7neon" ), |
338 | Thumbv8mBase => Cow::Borrowed("thumbv8m.base" ), |
339 | Thumbv8mMain => Cow::Borrowed("thumbv8m.main" ), |
340 | Armebv7r => Cow::Borrowed("armebv7r" ), |
341 | } |
342 | } |
343 | } |
344 | |
345 | impl Aarch64Architecture { |
346 | /// Test if this architecture uses the Thumb instruction set. |
347 | pub fn is_thumb(self) -> bool { |
348 | match self { |
349 | Aarch64Architecture::Aarch64 | Aarch64Architecture::Aarch64be => false, |
350 | } |
351 | } |
352 | |
353 | // pub fn has_fpu(self) -> Result<&'static [ArmFpu], ()> { |
354 | |
355 | // } |
356 | |
357 | /// Return the pointer bit width of this target's architecture. |
358 | /// |
359 | /// This function is only aware of the CPU architecture so it is not aware |
360 | /// of ilp32 ABIs. |
361 | pub fn pointer_width(self) -> PointerWidth { |
362 | match self { |
363 | Aarch64Architecture::Aarch64 | Aarch64Architecture::Aarch64be => PointerWidth::U64, |
364 | } |
365 | } |
366 | |
367 | /// Return the endianness of this architecture. |
368 | pub fn endianness(self) -> Endianness { |
369 | match self { |
370 | Aarch64Architecture::Aarch64 => Endianness::Little, |
371 | Aarch64Architecture::Aarch64be => Endianness::Big, |
372 | } |
373 | } |
374 | |
375 | /// Convert into a string |
376 | pub fn into_str(self) -> Cow<'static, str> { |
377 | use Aarch64Architecture::*; |
378 | |
379 | match self { |
380 | Aarch64 => Cow::Borrowed("aarch64" ), |
381 | Aarch64be => Cow::Borrowed("aarch64_be" ), |
382 | } |
383 | } |
384 | } |
385 | |
386 | #[cfg_attr (feature = "rust_1_40" , non_exhaustive)] |
387 | #[derive (Copy, Clone, Debug, PartialEq, Eq, Hash)] |
388 | #[allow (missing_docs)] |
389 | pub enum CleverArchitecture { |
390 | Clever, |
391 | Clever1_0, |
392 | } |
393 | |
394 | impl CleverArchitecture { |
395 | /// Convert into a string |
396 | pub fn into_str(self) -> Cow<'static, str> { |
397 | use CleverArchitecture::*; |
398 | |
399 | match self { |
400 | Clever => Cow::Borrowed("clever" ), |
401 | Clever1_0 => Cow::Borrowed("clever1.0" ), |
402 | } |
403 | } |
404 | } |
405 | |
406 | /// An enum for all 32-bit RISC-V architectures. |
407 | #[cfg_attr (feature = "rust_1_40" , non_exhaustive)] |
408 | #[derive (Copy, Clone, Debug, PartialEq, Eq, Hash)] |
409 | #[allow (missing_docs)] |
410 | pub enum Riscv32Architecture { |
411 | Riscv32, |
412 | Riscv32gc, |
413 | Riscv32i, |
414 | Riscv32im, |
415 | Riscv32imac, |
416 | Riscv32imc, |
417 | } |
418 | |
419 | impl Riscv32Architecture { |
420 | /// Convert into a string |
421 | pub fn into_str(self) -> Cow<'static, str> { |
422 | use Riscv32Architecture::*; |
423 | |
424 | match self { |
425 | Riscv32 => Cow::Borrowed("riscv32" ), |
426 | Riscv32gc => Cow::Borrowed("riscv32gc" ), |
427 | Riscv32i => Cow::Borrowed("riscv32i" ), |
428 | Riscv32im => Cow::Borrowed("riscv32im" ), |
429 | Riscv32imac => Cow::Borrowed("riscv32imac" ), |
430 | Riscv32imc => Cow::Borrowed("riscv32imc" ), |
431 | } |
432 | } |
433 | } |
434 | |
435 | /// An enum for all 64-bit RISC-V architectures. |
436 | #[cfg_attr (feature = "rust_1_40" , non_exhaustive)] |
437 | #[derive (Copy, Clone, Debug, PartialEq, Eq, Hash)] |
438 | #[allow (missing_docs)] |
439 | pub enum Riscv64Architecture { |
440 | Riscv64, |
441 | Riscv64gc, |
442 | Riscv64imac, |
443 | } |
444 | |
445 | impl Riscv64Architecture { |
446 | /// Convert into a string |
447 | pub fn into_str(self) -> Cow<'static, str> { |
448 | use Riscv64Architecture::*; |
449 | |
450 | match self { |
451 | Riscv64 => Cow::Borrowed("riscv64" ), |
452 | Riscv64gc => Cow::Borrowed("riscv64gc" ), |
453 | Riscv64imac => Cow::Borrowed("riscv64imac" ), |
454 | } |
455 | } |
456 | } |
457 | |
458 | /// An enum for all 32-bit x86 architectures. |
459 | #[cfg_attr (feature = "rust_1_40" , non_exhaustive)] |
460 | #[derive (Copy, Clone, Debug, PartialEq, Eq, Hash)] |
461 | #[allow (missing_docs)] |
462 | pub enum X86_32Architecture { |
463 | I386, |
464 | I586, |
465 | I686, |
466 | } |
467 | |
468 | impl X86_32Architecture { |
469 | /// Convert into a string |
470 | pub fn into_str(self) -> Cow<'static, str> { |
471 | use X86_32Architecture::*; |
472 | |
473 | match self { |
474 | I386 => Cow::Borrowed("i386" ), |
475 | I586 => Cow::Borrowed("i586" ), |
476 | I686 => Cow::Borrowed("i686" ), |
477 | } |
478 | } |
479 | } |
480 | |
481 | /// An enum for all 32-bit MIPS architectures (not just "MIPS32"). |
482 | #[cfg_attr (feature = "rust_1_40" , non_exhaustive)] |
483 | #[derive (Copy, Clone, Debug, PartialEq, Eq, Hash)] |
484 | #[allow (missing_docs)] |
485 | pub enum Mips32Architecture { |
486 | Mips, |
487 | Mipsel, |
488 | Mipsisa32r6, |
489 | Mipsisa32r6el, |
490 | } |
491 | |
492 | impl Mips32Architecture { |
493 | /// Convert into a string |
494 | pub fn into_str(self) -> Cow<'static, str> { |
495 | use Mips32Architecture::*; |
496 | |
497 | match self { |
498 | Mips => Cow::Borrowed("mips" ), |
499 | Mipsel => Cow::Borrowed("mipsel" ), |
500 | Mipsisa32r6 => Cow::Borrowed("mipsisa32r6" ), |
501 | Mipsisa32r6el => Cow::Borrowed("mipsisa32r6el" ), |
502 | } |
503 | } |
504 | } |
505 | |
506 | /// An enum for all 64-bit MIPS architectures (not just "MIPS64"). |
507 | #[cfg_attr (feature = "rust_1_40" , non_exhaustive)] |
508 | #[derive (Copy, Clone, Debug, PartialEq, Eq, Hash)] |
509 | #[allow (missing_docs)] |
510 | pub enum Mips64Architecture { |
511 | Mips64, |
512 | Mips64el, |
513 | Mipsisa64r6, |
514 | Mipsisa64r6el, |
515 | } |
516 | |
517 | impl Mips64Architecture { |
518 | /// Convert into a string |
519 | pub fn into_str(self) -> Cow<'static, str> { |
520 | use Mips64Architecture::*; |
521 | |
522 | match self { |
523 | Mips64 => Cow::Borrowed("mips64" ), |
524 | Mips64el => Cow::Borrowed("mips64el" ), |
525 | Mipsisa64r6 => Cow::Borrowed("mipsisa64r6" ), |
526 | Mipsisa64r6el => Cow::Borrowed("mipsisa64r6el" ), |
527 | } |
528 | } |
529 | } |
530 | |
531 | /// A string for a `Vendor::Custom` that can either be used in `const` |
532 | /// contexts or hold dynamic strings. |
533 | #[derive (Clone, Debug, Eq)] |
534 | pub enum CustomVendor { |
535 | /// An owned `String`. This supports the general case. |
536 | Owned(Box<String>), |
537 | /// A static `str`, so that `CustomVendor` can be constructed in `const` |
538 | /// contexts. |
539 | Static(&'static str), |
540 | } |
541 | |
542 | impl CustomVendor { |
543 | /// Extracts a string slice. |
544 | pub fn as_str(&self) -> &str { |
545 | match self { |
546 | CustomVendor::Owned(s: &Box) => s, |
547 | CustomVendor::Static(s: &&str) => s, |
548 | } |
549 | } |
550 | } |
551 | |
552 | impl PartialEq for CustomVendor { |
553 | fn eq(&self, other: &Self) -> bool { |
554 | self.as_str() == other.as_str() |
555 | } |
556 | } |
557 | |
558 | impl Hash for CustomVendor { |
559 | fn hash<H: Hasher>(&self, state: &mut H) { |
560 | self.as_str().hash(state) |
561 | } |
562 | } |
563 | |
564 | /// The "vendor" field, which in practice is little more than an arbitrary |
565 | /// modifier. |
566 | #[cfg_attr (feature = "rust_1_40" , non_exhaustive)] |
567 | #[derive (Clone, Debug, PartialEq, Eq, Hash)] |
568 | #[allow (missing_docs)] |
569 | pub enum Vendor { |
570 | Unknown, |
571 | Amd, |
572 | Apple, |
573 | Espressif, |
574 | Experimental, |
575 | Fortanix, |
576 | Ibm, |
577 | Kmc, |
578 | Nintendo, |
579 | Nvidia, |
580 | Pc, |
581 | Rumprun, |
582 | Sun, |
583 | Uwp, |
584 | Wrs, |
585 | |
586 | /// A custom vendor. "Custom" in this context means that the vendor is |
587 | /// not specifically recognized by upstream Autotools, LLVM, Rust, or other |
588 | /// relevant authorities on triple naming. It's useful for people building |
589 | /// and using locally patched toolchains. |
590 | /// |
591 | /// Outside of such patched environments, users of `target-lexicon` should |
592 | /// treat `Custom` the same as `Unknown` and ignore the string. |
593 | Custom(CustomVendor), |
594 | } |
595 | |
596 | impl Vendor { |
597 | /// Extracts a string slice. |
598 | pub fn as_str(&self) -> &str { |
599 | use Vendor::*; |
600 | |
601 | match self { |
602 | Unknown => "unknown" , |
603 | Amd => "amd" , |
604 | Apple => "apple" , |
605 | Espressif => "espressif" , |
606 | Experimental => "experimental" , |
607 | Fortanix => "fortanix" , |
608 | Ibm => "ibm" , |
609 | Kmc => "kmc" , |
610 | Nintendo => "nintendo" , |
611 | Nvidia => "nvidia" , |
612 | Pc => "pc" , |
613 | Rumprun => "rumprun" , |
614 | Sun => "sun" , |
615 | Uwp => "uwp" , |
616 | Wrs => "wrs" , |
617 | Custom(name) => name.as_str(), |
618 | } |
619 | } |
620 | } |
621 | |
622 | /// The "operating system" field, which sometimes implies an environment, and |
623 | /// sometimes isn't an actual operating system. |
624 | #[cfg_attr (feature = "rust_1_40" , non_exhaustive)] |
625 | #[derive (Copy, Clone, Debug, PartialEq, Eq, Hash)] |
626 | #[allow (missing_docs)] |
627 | pub enum OperatingSystem { |
628 | Unknown, |
629 | Aix, |
630 | AmdHsa, |
631 | Bitrig, |
632 | Cloudabi, |
633 | Cuda, |
634 | Darwin, |
635 | Dragonfly, |
636 | Emscripten, |
637 | Espidf, |
638 | Freebsd, |
639 | Fuchsia, |
640 | Haiku, |
641 | Hermit, |
642 | Horizon, |
643 | Illumos, |
644 | Ios, |
645 | L4re, |
646 | Linux, |
647 | MacOSX { major: u16, minor: u16, patch: u16 }, |
648 | Nebulet, |
649 | Netbsd, |
650 | None_, |
651 | Openbsd, |
652 | Psp, |
653 | Redox, |
654 | Solaris, |
655 | SolidAsp3, |
656 | Tvos, |
657 | Uefi, |
658 | VxWorks, |
659 | Wasi, |
660 | WasiP1, |
661 | WasiP2, |
662 | Watchos, |
663 | Windows, |
664 | } |
665 | |
666 | impl OperatingSystem { |
667 | /// Convert into a string |
668 | pub fn into_str(self) -> Cow<'static, str> { |
669 | use OperatingSystem::*; |
670 | |
671 | match self { |
672 | Unknown => Cow::Borrowed("unknown" ), |
673 | Aix => Cow::Borrowed("aix" ), |
674 | AmdHsa => Cow::Borrowed("amdhsa" ), |
675 | Bitrig => Cow::Borrowed("bitrig" ), |
676 | Cloudabi => Cow::Borrowed("cloudabi" ), |
677 | Cuda => Cow::Borrowed("cuda" ), |
678 | Darwin => Cow::Borrowed("darwin" ), |
679 | Dragonfly => Cow::Borrowed("dragonfly" ), |
680 | Emscripten => Cow::Borrowed("emscripten" ), |
681 | Espidf => Cow::Borrowed("espidf" ), |
682 | Freebsd => Cow::Borrowed("freebsd" ), |
683 | Fuchsia => Cow::Borrowed("fuchsia" ), |
684 | Haiku => Cow::Borrowed("haiku" ), |
685 | Hermit => Cow::Borrowed("hermit" ), |
686 | Horizon => Cow::Borrowed("horizon" ), |
687 | Illumos => Cow::Borrowed("illumos" ), |
688 | Ios => Cow::Borrowed("ios" ), |
689 | L4re => Cow::Borrowed("l4re" ), |
690 | Linux => Cow::Borrowed("linux" ), |
691 | MacOSX { |
692 | major, |
693 | minor, |
694 | patch, |
695 | } => Cow::Owned(format!("macosx {}. {}. {}" , major, minor, patch)), |
696 | Nebulet => Cow::Borrowed("nebulet" ), |
697 | Netbsd => Cow::Borrowed("netbsd" ), |
698 | None_ => Cow::Borrowed("none" ), |
699 | Openbsd => Cow::Borrowed("openbsd" ), |
700 | Psp => Cow::Borrowed("psp" ), |
701 | Redox => Cow::Borrowed("redox" ), |
702 | Solaris => Cow::Borrowed("solaris" ), |
703 | SolidAsp3 => Cow::Borrowed("solid_asp3" ), |
704 | Tvos => Cow::Borrowed("tvos" ), |
705 | Uefi => Cow::Borrowed("uefi" ), |
706 | VxWorks => Cow::Borrowed("vxworks" ), |
707 | Wasi => Cow::Borrowed("wasi" ), |
708 | WasiP1 => Cow::Borrowed("wasip1" ), |
709 | WasiP2 => Cow::Borrowed("wasip2" ), |
710 | Watchos => Cow::Borrowed("watchos" ), |
711 | Windows => Cow::Borrowed("windows" ), |
712 | } |
713 | } |
714 | } |
715 | |
716 | /// The "environment" field, which specifies an ABI environment on top of the |
717 | /// operating system. In many configurations, this field is omitted, and the |
718 | /// environment is implied by the operating system. |
719 | #[cfg_attr (feature = "rust_1_40" , non_exhaustive)] |
720 | #[derive (Copy, Clone, Debug, PartialEq, Eq, Hash)] |
721 | #[allow (missing_docs)] |
722 | pub enum Environment { |
723 | Unknown, |
724 | AmdGiz, |
725 | Android, |
726 | Androideabi, |
727 | Eabi, |
728 | Eabihf, |
729 | Gnu, |
730 | Gnuabi64, |
731 | Gnueabi, |
732 | Gnueabihf, |
733 | Gnuspe, |
734 | Gnux32, |
735 | GnuIlp32, |
736 | GnuLlvm, |
737 | HermitKernel, |
738 | LinuxKernel, |
739 | Macabi, |
740 | Musl, |
741 | Musleabi, |
742 | Musleabihf, |
743 | Muslabi64, |
744 | Msvc, |
745 | Newlib, |
746 | Kernel, |
747 | Uclibc, |
748 | Uclibceabi, |
749 | Uclibceabihf, |
750 | Sgx, |
751 | Sim, |
752 | Softfloat, |
753 | Spe, |
754 | Threads, |
755 | } |
756 | |
757 | impl Environment { |
758 | /// Convert into a string |
759 | pub fn into_str(self) -> Cow<'static, str> { |
760 | use Environment::*; |
761 | |
762 | match self { |
763 | Unknown => Cow::Borrowed("unknown" ), |
764 | AmdGiz => Cow::Borrowed("amdgiz" ), |
765 | Android => Cow::Borrowed("android" ), |
766 | Androideabi => Cow::Borrowed("androideabi" ), |
767 | Eabi => Cow::Borrowed("eabi" ), |
768 | Eabihf => Cow::Borrowed("eabihf" ), |
769 | Gnu => Cow::Borrowed("gnu" ), |
770 | Gnuabi64 => Cow::Borrowed("gnuabi64" ), |
771 | Gnueabi => Cow::Borrowed("gnueabi" ), |
772 | Gnueabihf => Cow::Borrowed("gnueabihf" ), |
773 | Gnuspe => Cow::Borrowed("gnuspe" ), |
774 | Gnux32 => Cow::Borrowed("gnux32" ), |
775 | GnuIlp32 => Cow::Borrowed("gnu_ilp32" ), |
776 | GnuLlvm => Cow::Borrowed("gnullvm" ), |
777 | HermitKernel => Cow::Borrowed("hermitkernel" ), |
778 | LinuxKernel => Cow::Borrowed("linuxkernel" ), |
779 | Macabi => Cow::Borrowed("macabi" ), |
780 | Musl => Cow::Borrowed("musl" ), |
781 | Musleabi => Cow::Borrowed("musleabi" ), |
782 | Musleabihf => Cow::Borrowed("musleabihf" ), |
783 | Muslabi64 => Cow::Borrowed("muslabi64" ), |
784 | Msvc => Cow::Borrowed("msvc" ), |
785 | Newlib => Cow::Borrowed("newlib" ), |
786 | Kernel => Cow::Borrowed("kernel" ), |
787 | Uclibc => Cow::Borrowed("uclibc" ), |
788 | Uclibceabi => Cow::Borrowed("uclibceabi" ), |
789 | Uclibceabihf => Cow::Borrowed("uclibceabihf" ), |
790 | Sgx => Cow::Borrowed("sgx" ), |
791 | Sim => Cow::Borrowed("sim" ), |
792 | Softfloat => Cow::Borrowed("softfloat" ), |
793 | Spe => Cow::Borrowed("spe" ), |
794 | Threads => Cow::Borrowed("threads" ), |
795 | } |
796 | } |
797 | } |
798 | |
799 | /// The "binary format" field, which is usually omitted, and the binary format |
800 | /// is implied by the other fields. |
801 | #[cfg_attr (feature = "rust_1_40" , non_exhaustive)] |
802 | #[derive (Copy, Clone, Debug, PartialEq, Eq, Hash)] |
803 | #[allow (missing_docs)] |
804 | pub enum BinaryFormat { |
805 | Unknown, |
806 | Elf, |
807 | Coff, |
808 | Macho, |
809 | Wasm, |
810 | Xcoff, |
811 | } |
812 | |
813 | impl BinaryFormat { |
814 | /// Convert into a string |
815 | pub fn into_str(self) -> Cow<'static, str> { |
816 | use BinaryFormat::*; |
817 | |
818 | match self { |
819 | Unknown => Cow::Borrowed("unknown" ), |
820 | Elf => Cow::Borrowed("elf" ), |
821 | Coff => Cow::Borrowed("coff" ), |
822 | Macho => Cow::Borrowed("macho" ), |
823 | Wasm => Cow::Borrowed("wasm" ), |
824 | Xcoff => Cow::Borrowed("xcoff" ), |
825 | } |
826 | } |
827 | } |
828 | |
829 | impl Architecture { |
830 | /// Return the endianness of this architecture. |
831 | #[rustfmt::skip] |
832 | pub fn endianness(self) -> Result<Endianness, ()> { |
833 | use Architecture::*; |
834 | |
835 | match self { |
836 | Unknown => Err(()), |
837 | Arm(arm) => Ok(arm.endianness()), |
838 | Aarch64(aarch) => Ok(aarch.endianness()), |
839 | AmdGcn |
840 | | Asmjs |
841 | | Avr |
842 | | Bpfel |
843 | | Hexagon |
844 | | X86_32(_) |
845 | | LoongArch64 |
846 | | Mips64(Mips64Architecture::Mips64el) |
847 | | Mips32(Mips32Architecture::Mipsel) |
848 | | Mips32(Mips32Architecture::Mipsisa32r6el) |
849 | | Mips64(Mips64Architecture::Mipsisa64r6el) |
850 | | Msp430 |
851 | | Nvptx64 |
852 | | Powerpc64le |
853 | | Riscv32(_) |
854 | | Riscv64(_) |
855 | | Wasm32 |
856 | | Wasm64 |
857 | | X86_64 |
858 | | X86_64h |
859 | | XTensa |
860 | | Clever(_) => Ok(Endianness::Little), |
861 | Bpfeb |
862 | | M68k |
863 | | Mips32(Mips32Architecture::Mips) |
864 | | Mips64(Mips64Architecture::Mips64) |
865 | | Mips32(Mips32Architecture::Mipsisa32r6) |
866 | | Mips64(Mips64Architecture::Mipsisa64r6) |
867 | | Powerpc |
868 | | Powerpc64 |
869 | | S390x |
870 | | Sparc |
871 | | Sparc64 |
872 | | Sparcv9 => Ok(Endianness::Big), |
873 | #[cfg (feature="arch_zkasm" )] |
874 | ZkAsm => Ok(Endianness::Big), |
875 | } |
876 | |
877 | } |
878 | |
879 | /// Return the pointer bit width of this target's architecture. |
880 | /// |
881 | /// This function is only aware of the CPU architecture so it is not aware |
882 | /// of ilp32 and x32 ABIs. |
883 | #[rustfmt::skip] |
884 | pub fn pointer_width(self) -> Result<PointerWidth, ()> { |
885 | use Architecture::*; |
886 | |
887 | match self { |
888 | Unknown => Err(()), |
889 | Avr | Msp430 => Ok(PointerWidth::U16), |
890 | Arm(arm) => Ok(arm.pointer_width()), |
891 | Aarch64(aarch) => Ok(aarch.pointer_width()), |
892 | Asmjs |
893 | | Hexagon |
894 | | X86_32(_) |
895 | | Riscv32(_) |
896 | | Sparc |
897 | | Wasm32 |
898 | | M68k |
899 | | Mips32(_) |
900 | | Powerpc |
901 | | XTensa => Ok(PointerWidth::U32), |
902 | AmdGcn |
903 | | Bpfeb |
904 | | Bpfel |
905 | | Powerpc64le |
906 | | Riscv64(_) |
907 | | X86_64 |
908 | | X86_64h |
909 | | Mips64(_) |
910 | | Nvptx64 |
911 | | Powerpc64 |
912 | | S390x |
913 | | Sparc64 |
914 | | Sparcv9 |
915 | | LoongArch64 |
916 | | Wasm64 |
917 | | Clever(_) => Ok(PointerWidth::U64), |
918 | #[cfg (feature="arch_zkasm" )] |
919 | ZkAsm => Ok(PointerWidth::U64), |
920 | } |
921 | } |
922 | |
923 | /// Checks if this Architecture is some variant of Clever-ISA |
924 | pub fn is_clever(&self) -> bool { |
925 | match self { |
926 | Architecture::Clever(_) => true, |
927 | _ => false, |
928 | } |
929 | } |
930 | |
931 | /// Convert into a string |
932 | pub fn into_str(self) -> Cow<'static, str> { |
933 | use Architecture::*; |
934 | |
935 | match self { |
936 | Arm(arm) => arm.into_str(), |
937 | Aarch64(aarch) => aarch.into_str(), |
938 | Unknown => Cow::Borrowed("unknown" ), |
939 | AmdGcn => Cow::Borrowed("amdgcn" ), |
940 | Asmjs => Cow::Borrowed("asmjs" ), |
941 | Avr => Cow::Borrowed("avr" ), |
942 | Bpfeb => Cow::Borrowed("bpfeb" ), |
943 | Bpfel => Cow::Borrowed("bpfel" ), |
944 | Hexagon => Cow::Borrowed("hexagon" ), |
945 | X86_32(x86_32) => x86_32.into_str(), |
946 | LoongArch64 => Cow::Borrowed("loongarch64" ), |
947 | M68k => Cow::Borrowed("m68k" ), |
948 | Mips32(mips32) => mips32.into_str(), |
949 | Mips64(mips64) => mips64.into_str(), |
950 | Msp430 => Cow::Borrowed("msp430" ), |
951 | Nvptx64 => Cow::Borrowed("nvptx64" ), |
952 | Powerpc => Cow::Borrowed("powerpc" ), |
953 | Powerpc64 => Cow::Borrowed("powerpc64" ), |
954 | Powerpc64le => Cow::Borrowed("powerpc64le" ), |
955 | Riscv32(riscv32) => riscv32.into_str(), |
956 | Riscv64(riscv64) => riscv64.into_str(), |
957 | S390x => Cow::Borrowed("s390x" ), |
958 | Sparc => Cow::Borrowed("sparc" ), |
959 | Sparc64 => Cow::Borrowed("sparc64" ), |
960 | Sparcv9 => Cow::Borrowed("sparcv9" ), |
961 | Wasm32 => Cow::Borrowed("wasm32" ), |
962 | Wasm64 => Cow::Borrowed("wasm64" ), |
963 | X86_64 => Cow::Borrowed("x86_64" ), |
964 | X86_64h => Cow::Borrowed("x86_64h" ), |
965 | XTensa => Cow::Borrowed("xtensa" ), |
966 | Clever(ver) => ver.into_str(), |
967 | #[cfg (feature = "arch_zkasm" )] |
968 | ZkAsm => Cow::Borrowed("zkasm" ), |
969 | } |
970 | } |
971 | } |
972 | |
973 | /// Return the binary format implied by this target triple, ignoring its |
974 | /// `binary_format` field. |
975 | pub(crate) fn default_binary_format(triple: &Triple) -> BinaryFormat { |
976 | match triple.operating_system { |
977 | OperatingSystem::None_ => match triple.environment { |
978 | Environment::Eabi | Environment::Eabihf => BinaryFormat::Elf, |
979 | _ => BinaryFormat::Unknown, |
980 | }, |
981 | OperatingSystem::Aix => BinaryFormat::Xcoff, |
982 | OperatingSystem::Darwin |
983 | | OperatingSystem::Ios |
984 | | OperatingSystem::MacOSX { .. } |
985 | | OperatingSystem::Watchos |
986 | | OperatingSystem::Tvos => BinaryFormat::Macho, |
987 | OperatingSystem::Windows => BinaryFormat::Coff, |
988 | OperatingSystem::Nebulet |
989 | | OperatingSystem::Emscripten |
990 | | OperatingSystem::VxWorks |
991 | | OperatingSystem::Wasi |
992 | | OperatingSystem::Unknown => match triple.architecture { |
993 | Architecture::Wasm32 | Architecture::Wasm64 => BinaryFormat::Wasm, |
994 | _ => BinaryFormat::Unknown, |
995 | }, |
996 | _ => BinaryFormat::Elf, |
997 | } |
998 | } |
999 | |
1000 | impl fmt::Display for ArmArchitecture { |
1001 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
1002 | f.write_str(&self.into_str()) |
1003 | } |
1004 | } |
1005 | |
1006 | impl fmt::Display for Aarch64Architecture { |
1007 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
1008 | f.write_str(&self.into_str()) |
1009 | } |
1010 | } |
1011 | |
1012 | impl fmt::Display for CleverArchitecture { |
1013 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
1014 | f.write_str(&self.into_str()) |
1015 | } |
1016 | } |
1017 | |
1018 | impl fmt::Display for Riscv32Architecture { |
1019 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
1020 | f.write_str(&self.into_str()) |
1021 | } |
1022 | } |
1023 | |
1024 | impl fmt::Display for Riscv64Architecture { |
1025 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
1026 | f.write_str(&self.into_str()) |
1027 | } |
1028 | } |
1029 | |
1030 | impl fmt::Display for X86_32Architecture { |
1031 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
1032 | f.write_str(&self.into_str()) |
1033 | } |
1034 | } |
1035 | |
1036 | impl fmt::Display for Mips32Architecture { |
1037 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
1038 | f.write_str(&self.into_str()) |
1039 | } |
1040 | } |
1041 | |
1042 | impl fmt::Display for Mips64Architecture { |
1043 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
1044 | f.write_str(&self.into_str()) |
1045 | } |
1046 | } |
1047 | |
1048 | impl fmt::Display for Architecture { |
1049 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
1050 | f.write_str(&self.into_str()) |
1051 | } |
1052 | } |
1053 | |
1054 | impl FromStr for ArmArchitecture { |
1055 | type Err = (); |
1056 | |
1057 | fn from_str(s: &str) -> Result<Self, ()> { |
1058 | use ArmArchitecture::*; |
1059 | |
1060 | Ok(match s { |
1061 | "arm" => Arm, |
1062 | "armeb" => Armeb, |
1063 | "armv4" => Armv4, |
1064 | "armv4t" => Armv4t, |
1065 | "armv5t" => Armv5t, |
1066 | "armv5te" => Armv5te, |
1067 | "armv5tej" => Armv5tej, |
1068 | "armv6" => Armv6, |
1069 | "armv6j" => Armv6j, |
1070 | "armv6k" => Armv6k, |
1071 | "armv6z" => Armv6z, |
1072 | "armv6kz" => Armv6kz, |
1073 | "armv6t2" => Armv6t2, |
1074 | "armv6m" => Armv6m, |
1075 | "armv7" => Armv7, |
1076 | "armv7a" => Armv7a, |
1077 | "armv7k" => Armv7k, |
1078 | "armv7ve" => Armv7ve, |
1079 | "armv7m" => Armv7m, |
1080 | "armv7r" => Armv7r, |
1081 | "armv7s" => Armv7s, |
1082 | "armv8" => Armv8, |
1083 | "armv8a" => Armv8a, |
1084 | "armv8.1a" => Armv8_1a, |
1085 | "armv8.2a" => Armv8_2a, |
1086 | "armv8.3a" => Armv8_3a, |
1087 | "armv8.4a" => Armv8_4a, |
1088 | "armv8.5a" => Armv8_5a, |
1089 | "armv8m.base" => Armv8mBase, |
1090 | "armv8m.main" => Armv8mMain, |
1091 | "armv8r" => Armv8r, |
1092 | "thumbeb" => Thumbeb, |
1093 | "thumbv4t" => Thumbv4t, |
1094 | "thumbv5te" => Thumbv5te, |
1095 | "thumbv6m" => Thumbv6m, |
1096 | "thumbv7a" => Thumbv7a, |
1097 | "thumbv7em" => Thumbv7em, |
1098 | "thumbv7m" => Thumbv7m, |
1099 | "thumbv7neon" => Thumbv7neon, |
1100 | "thumbv8m.base" => Thumbv8mBase, |
1101 | "thumbv8m.main" => Thumbv8mMain, |
1102 | "armebv7r" => Armebv7r, |
1103 | _ => return Err(()), |
1104 | }) |
1105 | } |
1106 | } |
1107 | |
1108 | impl FromStr for Aarch64Architecture { |
1109 | type Err = (); |
1110 | |
1111 | fn from_str(s: &str) -> Result<Self, ()> { |
1112 | use Aarch64Architecture::*; |
1113 | |
1114 | Ok(match s { |
1115 | "aarch64" => Aarch64, |
1116 | "arm64" => Aarch64, |
1117 | "aarch64_be" => Aarch64be, |
1118 | _ => return Err(()), |
1119 | }) |
1120 | } |
1121 | } |
1122 | |
1123 | impl FromStr for CleverArchitecture { |
1124 | type Err = (); |
1125 | fn from_str(s: &str) -> Result<Self, ()> { |
1126 | match s { |
1127 | "clever" => Ok(CleverArchitecture::Clever), |
1128 | "clever1.0" => Ok(CleverArchitecture::Clever1_0), |
1129 | _ => Err(()), |
1130 | } |
1131 | } |
1132 | } |
1133 | |
1134 | impl FromStr for Riscv32Architecture { |
1135 | type Err = (); |
1136 | |
1137 | fn from_str(s: &str) -> Result<Self, ()> { |
1138 | use Riscv32Architecture::*; |
1139 | |
1140 | Ok(match s { |
1141 | "riscv32" => Riscv32, |
1142 | "riscv32gc" => Riscv32gc, |
1143 | "riscv32i" => Riscv32i, |
1144 | "riscv32im" => Riscv32im, |
1145 | "riscv32imac" => Riscv32imac, |
1146 | "riscv32imc" => Riscv32imc, |
1147 | _ => return Err(()), |
1148 | }) |
1149 | } |
1150 | } |
1151 | |
1152 | impl FromStr for Riscv64Architecture { |
1153 | type Err = (); |
1154 | |
1155 | fn from_str(s: &str) -> Result<Self, ()> { |
1156 | use Riscv64Architecture::*; |
1157 | |
1158 | Ok(match s { |
1159 | "riscv64" => Riscv64, |
1160 | "riscv64gc" => Riscv64gc, |
1161 | "riscv64imac" => Riscv64imac, |
1162 | _ => return Err(()), |
1163 | }) |
1164 | } |
1165 | } |
1166 | |
1167 | impl FromStr for X86_32Architecture { |
1168 | type Err = (); |
1169 | |
1170 | fn from_str(s: &str) -> Result<Self, ()> { |
1171 | use X86_32Architecture::*; |
1172 | |
1173 | Ok(match s { |
1174 | "i386" => I386, |
1175 | "i586" => I586, |
1176 | "i686" => I686, |
1177 | _ => return Err(()), |
1178 | }) |
1179 | } |
1180 | } |
1181 | |
1182 | impl FromStr for Mips32Architecture { |
1183 | type Err = (); |
1184 | |
1185 | fn from_str(s: &str) -> Result<Self, ()> { |
1186 | use Mips32Architecture::*; |
1187 | |
1188 | Ok(match s { |
1189 | "mips" => Mips, |
1190 | "mipsel" => Mipsel, |
1191 | "mipsisa32r6" => Mipsisa32r6, |
1192 | "mipsisa32r6el" => Mipsisa32r6el, |
1193 | _ => return Err(()), |
1194 | }) |
1195 | } |
1196 | } |
1197 | |
1198 | impl FromStr for Mips64Architecture { |
1199 | type Err = (); |
1200 | |
1201 | fn from_str(s: &str) -> Result<Self, ()> { |
1202 | use Mips64Architecture::*; |
1203 | |
1204 | Ok(match s { |
1205 | "mips64" => Mips64, |
1206 | "mips64el" => Mips64el, |
1207 | "mipsisa64r6" => Mipsisa64r6, |
1208 | "mipsisa64r6el" => Mipsisa64r6el, |
1209 | _ => return Err(()), |
1210 | }) |
1211 | } |
1212 | } |
1213 | |
1214 | impl FromStr for Architecture { |
1215 | type Err = (); |
1216 | |
1217 | fn from_str(s: &str) -> Result<Self, ()> { |
1218 | use Architecture::*; |
1219 | |
1220 | Ok(match s { |
1221 | "unknown" => Unknown, |
1222 | "amdgcn" => AmdGcn, |
1223 | "asmjs" => Asmjs, |
1224 | "avr" => Avr, |
1225 | "bpfeb" => Bpfeb, |
1226 | "bpfel" => Bpfel, |
1227 | "hexagon" => Hexagon, |
1228 | "loongarch64" => LoongArch64, |
1229 | "m68k" => M68k, |
1230 | "msp430" => Msp430, |
1231 | "nvptx64" => Nvptx64, |
1232 | "powerpc" => Powerpc, |
1233 | "powerpc64" => Powerpc64, |
1234 | "powerpc64le" => Powerpc64le, |
1235 | "s390x" => S390x, |
1236 | "sparc" => Sparc, |
1237 | "sparc64" => Sparc64, |
1238 | "sparcv9" => Sparcv9, |
1239 | "wasm32" => Wasm32, |
1240 | "wasm64" => Wasm64, |
1241 | "x86_64" => X86_64, |
1242 | "x86_64h" => X86_64h, |
1243 | "xtensa" => XTensa, |
1244 | #[cfg (feature = "arch_zkasm" )] |
1245 | "zkasm" => ZkAsm, |
1246 | _ => { |
1247 | if let Ok(arm) = ArmArchitecture::from_str(s) { |
1248 | Arm(arm) |
1249 | } else if let Ok(aarch64) = Aarch64Architecture::from_str(s) { |
1250 | Aarch64(aarch64) |
1251 | } else if let Ok(riscv32) = Riscv32Architecture::from_str(s) { |
1252 | Riscv32(riscv32) |
1253 | } else if let Ok(riscv64) = Riscv64Architecture::from_str(s) { |
1254 | Riscv64(riscv64) |
1255 | } else if let Ok(x86_32) = X86_32Architecture::from_str(s) { |
1256 | X86_32(x86_32) |
1257 | } else if let Ok(mips32) = Mips32Architecture::from_str(s) { |
1258 | Mips32(mips32) |
1259 | } else if let Ok(mips64) = Mips64Architecture::from_str(s) { |
1260 | Mips64(mips64) |
1261 | } else if let Ok(clever) = CleverArchitecture::from_str(s) { |
1262 | Clever(clever) |
1263 | } else { |
1264 | return Err(()); |
1265 | } |
1266 | } |
1267 | }) |
1268 | } |
1269 | } |
1270 | |
1271 | impl fmt::Display for Vendor { |
1272 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
1273 | f.write_str(self.as_str()) |
1274 | } |
1275 | } |
1276 | |
1277 | impl FromStr for Vendor { |
1278 | type Err = (); |
1279 | |
1280 | fn from_str(s: &str) -> Result<Self, ()> { |
1281 | use Vendor::*; |
1282 | |
1283 | Ok(match s { |
1284 | "unknown" => Unknown, |
1285 | "amd" => Amd, |
1286 | "apple" => Apple, |
1287 | "espressif" => Espressif, |
1288 | "experimental" => Experimental, |
1289 | "fortanix" => Fortanix, |
1290 | "ibm" => Ibm, |
1291 | "kmc" => Kmc, |
1292 | "nintendo" => Nintendo, |
1293 | "nvidia" => Nvidia, |
1294 | "pc" => Pc, |
1295 | "rumprun" => Rumprun, |
1296 | "sun" => Sun, |
1297 | "uwp" => Uwp, |
1298 | "wrs" => Wrs, |
1299 | custom => { |
1300 | #[cfg (not(feature = "std" ))] |
1301 | use alloc::borrow::ToOwned; |
1302 | |
1303 | // A custom vendor. Since triple syntax is so loosely defined, |
1304 | // be as conservative as we can to avoid potential ambiguities. |
1305 | // We err on the side of being too strict here, as we can |
1306 | // always relax it if needed. |
1307 | |
1308 | // Don't allow empty string names. |
1309 | if custom.is_empty() { |
1310 | return Err(()); |
1311 | } |
1312 | |
1313 | // Don't allow any other recognized name as a custom vendor, |
1314 | // since vendors can be omitted in some contexts. |
1315 | if Architecture::from_str(custom).is_ok() |
1316 | || OperatingSystem::from_str(custom).is_ok() |
1317 | || Environment::from_str(custom).is_ok() |
1318 | || BinaryFormat::from_str(custom).is_ok() |
1319 | { |
1320 | return Err(()); |
1321 | } |
1322 | |
1323 | // Require the first character to be an ascii lowercase. |
1324 | if !custom.chars().next().unwrap().is_ascii_lowercase() { |
1325 | return Err(()); |
1326 | } |
1327 | |
1328 | // Restrict the set of characters permitted in a custom vendor. |
1329 | let has_restricted = custom.chars().any(|c: char| { |
1330 | !(c.is_ascii_lowercase() || c.is_ascii_digit() || c == '_' || c == '.' ) |
1331 | }); |
1332 | |
1333 | if has_restricted { |
1334 | return Err(()); |
1335 | } |
1336 | |
1337 | Custom(CustomVendor::Owned(Box::new(custom.to_owned()))) |
1338 | } |
1339 | }) |
1340 | } |
1341 | } |
1342 | |
1343 | impl fmt::Display for OperatingSystem { |
1344 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
1345 | use OperatingSystem::*; |
1346 | |
1347 | match *self { |
1348 | MacOSX { |
1349 | major: u16, |
1350 | minor: u16, |
1351 | patch: u16, |
1352 | } => write!(f, "macosx {}. {}. {}" , major, minor, patch), |
1353 | os: OperatingSystem => f.write_str(&os.into_str()), |
1354 | } |
1355 | } |
1356 | } |
1357 | |
1358 | impl FromStr for OperatingSystem { |
1359 | type Err = (); |
1360 | |
1361 | fn from_str(s: &str) -> Result<Self, ()> { |
1362 | use OperatingSystem::*; |
1363 | |
1364 | // TODO also parse version number for darwin and ios OSes |
1365 | if s.starts_with("macosx" ) { |
1366 | // Parse operating system names like `macosx10.7.0`. |
1367 | let s = &s["macosx" .len()..]; |
1368 | let mut parts = s.split('.' ).map(|num| num.parse::<u16>()); |
1369 | |
1370 | macro_rules! get_part { |
1371 | () => { |
1372 | if let Some(Ok(part)) = parts.next() { |
1373 | part |
1374 | } else { |
1375 | return Err(()); |
1376 | } |
1377 | }; |
1378 | } |
1379 | |
1380 | let major = get_part!(); |
1381 | let minor = get_part!(); |
1382 | let patch = get_part!(); |
1383 | |
1384 | if parts.next().is_some() { |
1385 | return Err(()); |
1386 | } |
1387 | |
1388 | return Ok(MacOSX { |
1389 | major, |
1390 | minor, |
1391 | patch, |
1392 | }); |
1393 | } |
1394 | |
1395 | Ok(match s { |
1396 | "unknown" => Unknown, |
1397 | "aix" => Aix, |
1398 | "amdhsa" => AmdHsa, |
1399 | "bitrig" => Bitrig, |
1400 | "cloudabi" => Cloudabi, |
1401 | "cuda" => Cuda, |
1402 | "darwin" => Darwin, |
1403 | "dragonfly" => Dragonfly, |
1404 | "emscripten" => Emscripten, |
1405 | "freebsd" => Freebsd, |
1406 | "fuchsia" => Fuchsia, |
1407 | "haiku" => Haiku, |
1408 | "hermit" => Hermit, |
1409 | "horizon" => Horizon, |
1410 | "illumos" => Illumos, |
1411 | "ios" => Ios, |
1412 | "l4re" => L4re, |
1413 | "linux" => Linux, |
1414 | "nebulet" => Nebulet, |
1415 | "netbsd" => Netbsd, |
1416 | "none" => None_, |
1417 | "openbsd" => Openbsd, |
1418 | "psp" => Psp, |
1419 | "redox" => Redox, |
1420 | "solaris" => Solaris, |
1421 | "solid_asp3" => SolidAsp3, |
1422 | "tvos" => Tvos, |
1423 | "uefi" => Uefi, |
1424 | "vxworks" => VxWorks, |
1425 | "wasi" => Wasi, |
1426 | "wasip1" => WasiP1, |
1427 | "wasip2" => WasiP2, |
1428 | "watchos" => Watchos, |
1429 | "windows" => Windows, |
1430 | "espidf" => Espidf, |
1431 | _ => return Err(()), |
1432 | }) |
1433 | } |
1434 | } |
1435 | |
1436 | impl fmt::Display for Environment { |
1437 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
1438 | f.write_str(&self.into_str()) |
1439 | } |
1440 | } |
1441 | |
1442 | impl FromStr for Environment { |
1443 | type Err = (); |
1444 | |
1445 | fn from_str(s: &str) -> Result<Self, ()> { |
1446 | use Environment::*; |
1447 | |
1448 | Ok(match s { |
1449 | "unknown" => Unknown, |
1450 | "amdgiz" => AmdGiz, |
1451 | "android" => Android, |
1452 | "androideabi" => Androideabi, |
1453 | "eabi" => Eabi, |
1454 | "eabihf" => Eabihf, |
1455 | "gnu" => Gnu, |
1456 | "gnuabi64" => Gnuabi64, |
1457 | "gnueabi" => Gnueabi, |
1458 | "gnueabihf" => Gnueabihf, |
1459 | "gnuspe" => Gnuspe, |
1460 | "gnux32" => Gnux32, |
1461 | "gnu_ilp32" => GnuIlp32, |
1462 | "gnullvm" => GnuLlvm, |
1463 | "hermitkernel" => HermitKernel, |
1464 | "linuxkernel" => LinuxKernel, |
1465 | "macabi" => Macabi, |
1466 | "musl" => Musl, |
1467 | "musleabi" => Musleabi, |
1468 | "musleabihf" => Musleabihf, |
1469 | "muslabi64" => Muslabi64, |
1470 | "msvc" => Msvc, |
1471 | "newlib" => Newlib, |
1472 | "kernel" => Kernel, |
1473 | "uclibc" => Uclibc, |
1474 | "uclibceabi" => Uclibceabi, |
1475 | "uclibceabihf" => Uclibceabihf, |
1476 | "sgx" => Sgx, |
1477 | "sim" => Sim, |
1478 | "softfloat" => Softfloat, |
1479 | "spe" => Spe, |
1480 | "threads" => Threads, |
1481 | _ => return Err(()), |
1482 | }) |
1483 | } |
1484 | } |
1485 | |
1486 | impl fmt::Display for BinaryFormat { |
1487 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
1488 | f.write_str(&self.into_str()) |
1489 | } |
1490 | } |
1491 | |
1492 | impl FromStr for BinaryFormat { |
1493 | type Err = (); |
1494 | |
1495 | fn from_str(s: &str) -> Result<Self, ()> { |
1496 | use BinaryFormat::*; |
1497 | |
1498 | Ok(match s { |
1499 | "unknown" => Unknown, |
1500 | "elf" => Elf, |
1501 | "coff" => Coff, |
1502 | "macho" => Macho, |
1503 | "wasm" => Wasm, |
1504 | "xcoff" => Xcoff, |
1505 | _ => return Err(()), |
1506 | }) |
1507 | } |
1508 | } |
1509 | |
1510 | #[cfg (test)] |
1511 | mod tests { |
1512 | use super::*; |
1513 | use alloc::string::ToString; |
1514 | |
1515 | #[test ] |
1516 | fn roundtrip_known_triples() { |
1517 | // This list is constructed from: |
1518 | // - targets emitted by "rustup target list" |
1519 | // - targets emitted by "rustc +nightly --print target-list" |
1520 | // - targets contributors have added |
1521 | let targets = [ |
1522 | "aarch64-apple-darwin" , |
1523 | "aarch64-apple-ios" , |
1524 | "aarch64-apple-ios-macabi" , |
1525 | "aarch64-apple-ios-sim" , |
1526 | "aarch64-apple-tvos" , |
1527 | "aarch64-apple-watchos-sim" , |
1528 | "aarch64_be-unknown-linux-gnu" , |
1529 | "aarch64_be-unknown-linux-gnu_ilp32" , |
1530 | "aarch64_be-unknown-netbsd" , |
1531 | "aarch64-fuchsia" , |
1532 | "aarch64-kmc-solid_asp3" , |
1533 | "aarch64-linux-android" , |
1534 | //"aarch64-nintendo-switch-freestanding", // TODO |
1535 | "aarch64-pc-windows-gnullvm" , |
1536 | "aarch64-pc-windows-msvc" , |
1537 | "aarch64-unknown-cloudabi" , |
1538 | "aarch64-unknown-freebsd" , |
1539 | "aarch64-unknown-hermit" , |
1540 | "aarch64-unknown-linux-gnu" , |
1541 | "aarch64-unknown-linux-gnu_ilp32" , |
1542 | "aarch64-unknown-linux-musl" , |
1543 | "aarch64-unknown-netbsd" , |
1544 | "aarch64-unknown-none" , |
1545 | "aarch64-unknown-none-softfloat" , |
1546 | "aarch64-unknown-openbsd" , |
1547 | "aarch64-unknown-redox" , |
1548 | "aarch64-unknown-uefi" , |
1549 | "aarch64-uwp-windows-msvc" , |
1550 | "aarch64-wrs-vxworks" , |
1551 | //"arm64_32-apple-watchos", // TODO |
1552 | "armeb-unknown-linux-gnueabi" , |
1553 | "amdgcn-amd-amdhsa" , |
1554 | "amdgcn-amd-amdhsa-amdgiz" , |
1555 | "armebv7r-none-eabi" , |
1556 | "armebv7r-none-eabihf" , |
1557 | "arm-linux-androideabi" , |
1558 | "arm-unknown-linux-gnueabi" , |
1559 | "arm-unknown-linux-gnueabihf" , |
1560 | "arm-unknown-linux-musleabi" , |
1561 | "arm-unknown-linux-musleabihf" , |
1562 | "armv4t-none-eabi" , |
1563 | "armv4t-unknown-linux-gnueabi" , |
1564 | "armv5te-none-eabi" , |
1565 | "armv5te-unknown-linux-gnueabi" , |
1566 | "armv5te-unknown-linux-musleabi" , |
1567 | "armv5te-unknown-linux-uclibceabi" , |
1568 | "armv6k-nintendo-3ds" , |
1569 | "armv6-unknown-freebsd" , |
1570 | "armv6-unknown-netbsd-eabihf" , |
1571 | "armv7a-kmc-solid_asp3-eabi" , |
1572 | "armv7a-kmc-solid_asp3-eabihf" , |
1573 | "armv7a-none-eabi" , |
1574 | "armv7a-none-eabihf" , |
1575 | "armv7-apple-ios" , |
1576 | "armv7k-apple-watchos" , |
1577 | "armv7-linux-androideabi" , |
1578 | "armv7r-none-eabi" , |
1579 | "armv7r-none-eabihf" , |
1580 | "armv7s-apple-ios" , |
1581 | "armv7-unknown-cloudabi-eabihf" , |
1582 | "armv7-unknown-freebsd" , |
1583 | "armv7-unknown-linux-gnueabi" , |
1584 | "armv7-unknown-linux-gnueabihf" , |
1585 | "armv7-unknown-linux-musleabi" , |
1586 | "armv7-unknown-linux-musleabihf" , |
1587 | "armv7-unknown-linux-uclibceabi" , |
1588 | "armv7-unknown-linux-uclibceabihf" , |
1589 | "armv7-unknown-netbsd-eabihf" , |
1590 | "armv7-wrs-vxworks-eabihf" , |
1591 | "asmjs-unknown-emscripten" , |
1592 | //"avr-unknown-gnu-atmega328", // TODO |
1593 | "avr-unknown-unknown" , |
1594 | "bpfeb-unknown-none" , |
1595 | "bpfel-unknown-none" , |
1596 | "hexagon-unknown-linux-musl" , |
1597 | "i386-apple-ios" , |
1598 | "i586-pc-windows-msvc" , |
1599 | "i586-unknown-linux-gnu" , |
1600 | "i586-unknown-linux-musl" , |
1601 | "i686-apple-darwin" , |
1602 | "i686-linux-android" , |
1603 | "i686-apple-macosx10.7.0" , |
1604 | "i686-pc-windows-gnu" , |
1605 | "i686-pc-windows-msvc" , |
1606 | "i686-unknown-cloudabi" , |
1607 | "i686-unknown-dragonfly" , |
1608 | "i686-unknown-freebsd" , |
1609 | "i686-unknown-haiku" , |
1610 | "i686-unknown-linux-gnu" , |
1611 | "i686-unknown-linux-musl" , |
1612 | "i686-unknown-netbsd" , |
1613 | "i686-unknown-openbsd" , |
1614 | "i686-unknown-uefi" , |
1615 | "i686-uwp-windows-gnu" , |
1616 | "i686-uwp-windows-msvc" , |
1617 | "i686-wrs-vxworks" , |
1618 | "loongarch64-unknown-linux-gnu" , |
1619 | "m68k-unknown-linux-gnu" , |
1620 | "mips64el-unknown-linux-gnuabi64" , |
1621 | "mips64el-unknown-linux-muslabi64" , |
1622 | "mips64-openwrt-linux-musl" , |
1623 | "mips64-unknown-linux-gnuabi64" , |
1624 | "mips64-unknown-linux-muslabi64" , |
1625 | "mipsel-sony-psp" , |
1626 | "mipsel-unknown-linux-gnu" , |
1627 | "mipsel-unknown-linux-musl" , |
1628 | "mipsel-unknown-linux-uclibc" , |
1629 | "mipsel-unknown-none" , |
1630 | "mipsisa32r6el-unknown-linux-gnu" , |
1631 | "mipsisa32r6-unknown-linux-gnu" , |
1632 | "mipsisa64r6el-unknown-linux-gnuabi64" , |
1633 | "mipsisa64r6-unknown-linux-gnuabi64" , |
1634 | "mips-unknown-linux-gnu" , |
1635 | "mips-unknown-linux-musl" , |
1636 | "mips-unknown-linux-uclibc" , |
1637 | "msp430-none-elf" , |
1638 | "nvptx64-nvidia-cuda" , |
1639 | "powerpc64le-unknown-freebsd" , |
1640 | "powerpc64le-unknown-linux-gnu" , |
1641 | "powerpc64le-unknown-linux-musl" , |
1642 | "powerpc64-ibm-aix" , |
1643 | "powerpc64-unknown-freebsd" , |
1644 | "powerpc64-unknown-linux-gnu" , |
1645 | "powerpc64-unknown-linux-musl" , |
1646 | "powerpc64-unknown-openbsd" , |
1647 | "powerpc64-wrs-vxworks" , |
1648 | "powerpc-ibm-aix" , |
1649 | "powerpc-unknown-freebsd" , |
1650 | "powerpc-unknown-linux-gnu" , |
1651 | "powerpc-unknown-linux-gnuspe" , |
1652 | "powerpc-unknown-linux-musl" , |
1653 | "powerpc-unknown-netbsd" , |
1654 | "powerpc-unknown-openbsd" , |
1655 | "powerpc-wrs-vxworks" , |
1656 | "powerpc-wrs-vxworks-spe" , |
1657 | "riscv32gc-unknown-linux-gnu" , |
1658 | "riscv32gc-unknown-linux-musl" , |
1659 | "riscv32imac-unknown-none-elf" , |
1660 | //"riscv32imac-unknown-xous-elf", // TODO |
1661 | "riscv32imc-esp-espidf" , |
1662 | "riscv32imc-unknown-none-elf" , |
1663 | "riscv32im-unknown-none-elf" , |
1664 | "riscv32i-unknown-none-elf" , |
1665 | "riscv64gc-unknown-freebsd" , |
1666 | "riscv64gc-unknown-linux-gnu" , |
1667 | "riscv64gc-unknown-linux-musl" , |
1668 | "riscv64gc-unknown-netbsd" , |
1669 | "riscv64gc-unknown-none-elf" , |
1670 | "riscv64gc-unknown-openbsd" , |
1671 | "riscv64imac-unknown-none-elf" , |
1672 | "s390x-unknown-linux-gnu" , |
1673 | "s390x-unknown-linux-musl" , |
1674 | "sparc64-unknown-linux-gnu" , |
1675 | "sparc64-unknown-netbsd" , |
1676 | "sparc64-unknown-openbsd" , |
1677 | "sparc-unknown-linux-gnu" , |
1678 | "sparcv9-sun-solaris" , |
1679 | "thumbv4t-none-eabi" , |
1680 | "thumbv5te-none-eabi" , |
1681 | "thumbv6m-none-eabi" , |
1682 | "thumbv7a-pc-windows-msvc" , |
1683 | "thumbv7a-uwp-windows-msvc" , |
1684 | "thumbv7em-none-eabi" , |
1685 | "thumbv7em-none-eabihf" , |
1686 | "thumbv7m-none-eabi" , |
1687 | "thumbv7neon-linux-androideabi" , |
1688 | "thumbv7neon-unknown-linux-gnueabihf" , |
1689 | "thumbv7neon-unknown-linux-musleabihf" , |
1690 | "thumbv8m.base-none-eabi" , |
1691 | "thumbv8m.main-none-eabi" , |
1692 | "thumbv8m.main-none-eabihf" , |
1693 | "wasm32-experimental-emscripten" , |
1694 | "wasm32-unknown-emscripten" , |
1695 | "wasm32-unknown-unknown" , |
1696 | "wasm32-wasi" , |
1697 | "wasm32-wasip1-threads" , |
1698 | "wasm32-wasip1" , |
1699 | "wasm32-wasip2" , |
1700 | "wasm64-unknown-unknown" , |
1701 | "wasm64-wasi" , |
1702 | "x86_64-apple-darwin" , |
1703 | "x86_64h-apple-darwin" , |
1704 | "x86_64-apple-ios" , |
1705 | "x86_64-apple-ios-macabi" , |
1706 | "x86_64-apple-tvos" , |
1707 | "x86_64-apple-watchos-sim" , |
1708 | "x86_64-fortanix-unknown-sgx" , |
1709 | "x86_64-fuchsia" , |
1710 | "x86_64-linux-android" , |
1711 | "x86_64-linux-kernel" , // Changed to x86_64-unknown-none-linuxkernel in 1.53.0 |
1712 | "x86_64-apple-macosx10.7.0" , |
1713 | "x86_64-pc-solaris" , |
1714 | "x86_64-pc-windows-gnu" , |
1715 | "x86_64-pc-windows-gnullvm" , |
1716 | "x86_64-pc-windows-msvc" , |
1717 | "x86_64-rumprun-netbsd" , // Removed in 1.53.0 |
1718 | "x86_64-sun-solaris" , |
1719 | "x86_64-unknown-bitrig" , |
1720 | "x86_64-unknown-cloudabi" , |
1721 | "x86_64-unknown-dragonfly" , |
1722 | "x86_64-unknown-freebsd" , |
1723 | "x86_64-unknown-haiku" , |
1724 | "x86_64-unknown-hermit" , |
1725 | "x86_64-unknown-hermit-kernel" , // Changed to x86_64-unknown-none-hermitkernel in 1.53.0 |
1726 | "x86_64-unknown-illumos" , |
1727 | "x86_64-unknown-l4re-uclibc" , |
1728 | "x86_64-unknown-linux-gnu" , |
1729 | "x86_64-unknown-linux-gnux32" , |
1730 | "x86_64-unknown-linux-musl" , |
1731 | "x86_64-unknown-netbsd" , |
1732 | "x86_64-unknown-none" , |
1733 | "x86_64-unknown-none-hermitkernel" , |
1734 | "x86_64-unknown-none-linuxkernel" , |
1735 | "x86_64-unknown-openbsd" , |
1736 | "x86_64-unknown-redox" , |
1737 | "x86_64-unknown-uefi" , |
1738 | "x86_64-uwp-windows-gnu" , |
1739 | "x86_64-uwp-windows-msvc" , |
1740 | "x86_64-wrs-vxworks" , |
1741 | "xtensa-esp32-espidf" , |
1742 | "clever-unknown-elf" , |
1743 | #[cfg (feature = "arch_zkasm" )] |
1744 | "zkasm-unknown-unknown" , |
1745 | ]; |
1746 | |
1747 | for target in targets.iter() { |
1748 | let t = Triple::from_str(target).expect("can't parse target" ); |
1749 | assert_ne!(t.architecture, Architecture::Unknown); |
1750 | assert_eq!(t.to_string(), *target, " {:#?}" , t); |
1751 | } |
1752 | } |
1753 | |
1754 | #[test ] |
1755 | fn thumbv7em_none_eabihf() { |
1756 | let t = Triple::from_str("thumbv7em-none-eabihf" ).expect("can't parse target" ); |
1757 | assert_eq!( |
1758 | t.architecture, |
1759 | Architecture::Arm(ArmArchitecture::Thumbv7em) |
1760 | ); |
1761 | assert_eq!(t.vendor, Vendor::Unknown); |
1762 | assert_eq!(t.operating_system, OperatingSystem::None_); |
1763 | assert_eq!(t.environment, Environment::Eabihf); |
1764 | assert_eq!(t.binary_format, BinaryFormat::Elf); |
1765 | } |
1766 | |
1767 | #[test ] |
1768 | fn custom_vendors() { |
1769 | // Test various invalid cases. |
1770 | assert!(Triple::from_str("x86_64--linux" ).is_err()); |
1771 | assert!(Triple::from_str("x86_64-42-linux" ).is_err()); |
1772 | assert!(Triple::from_str("x86_64-__customvendor__-linux" ).is_err()); |
1773 | assert!(Triple::from_str("x86_64-^-linux" ).is_err()); |
1774 | assert!(Triple::from_str("x86_64- -linux" ).is_err()); |
1775 | assert!(Triple::from_str("x86_64-CustomVendor-linux" ).is_err()); |
1776 | assert!(Triple::from_str("x86_64-linux-linux" ).is_err()); |
1777 | assert!(Triple::from_str("x86_64-x86_64-linux" ).is_err()); |
1778 | assert!(Triple::from_str("x86_64-elf-linux" ).is_err()); |
1779 | assert!(Triple::from_str("x86_64-gnu-linux" ).is_err()); |
1780 | assert!(Triple::from_str("x86_64-linux-customvendor" ).is_err()); |
1781 | assert!(Triple::from_str("customvendor" ).is_err()); |
1782 | assert!(Triple::from_str("customvendor-x86_64" ).is_err()); |
1783 | assert!(Triple::from_str("x86_64-" ).is_err()); |
1784 | assert!(Triple::from_str("x86_64--" ).is_err()); |
1785 | |
1786 | // Test various Unicode things. |
1787 | assert!( |
1788 | Triple::from_str("x86_64-𝓬𝓾𝓼𝓽𝓸𝓶𝓿𝓮𝓷𝓭𝓸𝓻-linux" ).is_err(), |
1789 | "unicode font hazard" |
1790 | ); |
1791 | assert!( |
1792 | Triple::from_str("x86_64-ćúśtőḿvéńdőŕ-linux" ).is_err(), |
1793 | "diacritical mark stripping hazard" |
1794 | ); |
1795 | assert!( |
1796 | Triple::from_str("x86_64-customvendοr-linux" ).is_err(), |
1797 | "homoglyph hazard" |
1798 | ); |
1799 | assert!(Triple::from_str("x86_64-customvendor-linux" ).is_ok()); |
1800 | assert!( |
1801 | Triple::from_str("x86_64-ffi-linux" ).is_err(), |
1802 | "normalization hazard" |
1803 | ); |
1804 | assert!(Triple::from_str("x86_64-ffi-linux" ).is_ok()); |
1805 | assert!( |
1806 | Triple::from_str("x86_64-customvendor-linux" ).is_err(), |
1807 | "zero-width character hazard" |
1808 | ); |
1809 | assert!( |
1810 | Triple::from_str("x86_64-customvendor-linux" ).is_err(), |
1811 | "BOM hazard" |
1812 | ); |
1813 | |
1814 | // Test some valid cases. |
1815 | let t = Triple::from_str("x86_64-customvendor-linux" ) |
1816 | .expect("can't parse target with custom vendor" ); |
1817 | assert_eq!(t.architecture, Architecture::X86_64); |
1818 | assert_eq!( |
1819 | t.vendor, |
1820 | Vendor::Custom(CustomVendor::Static("customvendor" )) |
1821 | ); |
1822 | assert_eq!(t.operating_system, OperatingSystem::Linux); |
1823 | assert_eq!(t.environment, Environment::Unknown); |
1824 | assert_eq!(t.binary_format, BinaryFormat::Elf); |
1825 | assert_eq!(t.to_string(), "x86_64-customvendor-linux" ); |
1826 | |
1827 | let t = |
1828 | Triple::from_str("x86_64-customvendor" ).expect("can't parse target with custom vendor" ); |
1829 | assert_eq!(t.architecture, Architecture::X86_64); |
1830 | assert_eq!( |
1831 | t.vendor, |
1832 | Vendor::Custom(CustomVendor::Static("customvendor" )) |
1833 | ); |
1834 | assert_eq!(t.operating_system, OperatingSystem::Unknown); |
1835 | assert_eq!(t.environment, Environment::Unknown); |
1836 | assert_eq!(t.binary_format, BinaryFormat::Unknown); |
1837 | |
1838 | assert_eq!( |
1839 | Triple::from_str("unknown-foo" ), |
1840 | Ok(Triple { |
1841 | architecture: Architecture::Unknown, |
1842 | vendor: Vendor::Custom(CustomVendor::Static("foo" )), |
1843 | operating_system: OperatingSystem::Unknown, |
1844 | environment: Environment::Unknown, |
1845 | binary_format: BinaryFormat::Unknown, |
1846 | }) |
1847 | ); |
1848 | } |
1849 | } |
1850 | |