target-lexicon-0.10.0/.gitignore010066400017510001751000000001061327071344300147330ustar0000000000000000*.bk *.swp *.swo *.swx tags target Cargo.lock .*.rustfmt rusty-tags.* target-lexicon-0.10.0/.rustfmt.toml010066400017510001751000000000001327071322100154050ustar0000000000000000target-lexicon-0.10.0/.travis.yml010066400017510001751000000023551353420126500150610ustar0000000000000000language: rust rust: - stable - beta - nightly matrix: allow_failures: - rust: beta - rust: nightly dist: trusty sudo: false before_script: # If an old version of rustfmt from cargo is already installed, uninstall # it, since it can prevent the installation of the new version from rustup. - cargo uninstall rustfmt || true - cargo install --list # If we're testing beta or nightly, we still need to install the stable # toolchain so that we can run the stable version of rustfmt. - rustup toolchain install stable # Install the stable version of rustfmt. - rustup component add --toolchain=stable rustfmt-preview - rustup component list --toolchain=stable - rustup show - rustfmt +stable --version || echo fail # Sometimes the component isn't actually ready after being installed, and # rustup update makes it ready. - rustup update # Add targets for testing cross-compilation. - rustup target add arm-unknown-linux-gnueabi - rustup target add aarch64-unknown-linux-gnu - rustfmt +stable --version script: - cargo test - cargo build --target arm-unknown-linux-gnueabi - cargo build --target aarch64-unknown-linux-gnu cache: cargo: true target-lexicon-0.10.0/Cargo.toml.orig010066400017510001751000000011251356467442300156460ustar0000000000000000[package] name = "target-lexicon" version = "0.10.0" authors = ["Dan Gohman "] description = "Targeting utilities for compilers and related tools" documentation = "https://docs.rs/target-lexicon/" readme = "README.md" keywords = ["target", "host", "triple", "compiler", "jit"] categories = ["no-std"] license = "Apache-2.0 WITH LLVM-exception" repository = "https://github.com/CraneStation/target-lexicon" edition = "2018" [features] default = [] std = [] [badges] maintenance = { status = "passively-maintained" } travis-ci = { repository = "CraneStation/target-lexicon" } target-lexicon-0.10.0/Cargo.toml0000644000000021370000000000000120770ustar00# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO # # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies # to registry (e.g., crates.io) dependencies # # If you believe there's an error in this file please file an # issue against the rust-lang/cargo repository. If you're # editing this file be aware that the upstream Cargo.toml # will likely look very different (and much more reasonable) [package] edition = "2018" name = "target-lexicon" version = "0.10.0" authors = ["Dan Gohman "] description = "Targeting utilities for compilers and related tools" documentation = "https://docs.rs/target-lexicon/" readme = "README.md" keywords = ["target", "host", "triple", "compiler", "jit"] categories = ["no-std"] license = "Apache-2.0 WITH LLVM-exception" repository = "https://github.com/CraneStation/target-lexicon" [features] default = [] std = [] [badges.maintenance] status = "passively-maintained" [badges.travis-ci] repository = "CraneStation/target-lexicon" target-lexicon-0.10.0/LICENSE010066400017510001751000000277231336613172400137700ustar0000000000000000 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. --- 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. target-lexicon-0.10.0/README.md010066400017510001751000000016751353133461100142320ustar0000000000000000This is a library for managing targets for compilers and related tools. Currently, the main feature is support for decoding "triples", which are strings that identify a particular target configuration. They're named "triples" because historically they contained three fields, though over time they've added additional fields. This library provides a `Triple` struct containing enums for each of fields of a triple. `Triple` implements `FromStr` and `fmt::Display` so it can be converted to and from the conventional string representation of a triple. `Triple` also has functions for querying a triple's endianness, pointer bit width, and binary format. And, `Triple` and the enum types have `host()` constructors, for targeting the host. It supports all triples currently used by rustc and rustup. It does not support reading JSON target files itself. To use it with a JSON target file, construct a `Triple` using the value of the "llvm-target" field. target-lexicon-0.10.0/build.rs010066400017510001751000000127311356467442300144310ustar0000000000000000//! build.rs file to obtain the host information. // Allow dead code in triple.rs and targets.rs for our purposes here. #![allow(dead_code)] use std::env; use std::fs::File; use std::io::{self, Write}; use std::path::PathBuf; use std::str::FromStr; extern crate alloc; // Include triple.rs and targets.rs so we can parse the TARGET environment variable. mod triple { include!("src/triple.rs"); } mod targets { include!("src/targets.rs"); } // Stub out `ParseError` to minimally support triple.rs and targets.rs. mod parse_error { #[derive(Debug)] pub enum ParseError { UnrecognizedArchitecture(String), UnrecognizedVendor(String), UnrecognizedOperatingSystem(String), UnrecognizedEnvironment(String), UnrecognizedBinaryFormat(String), UnrecognizedField(String), } } use self::targets::Vendor; use self::triple::Triple; fn main() { let out_dir = PathBuf::from(env::var("OUT_DIR").expect("The OUT_DIR environment variable must be set")); let target = env::var("TARGET").expect("The TARGET environment variable must be set"); let triple = Triple::from_str(&target).expect(&format!("Invalid target name: '{}'", target)); let out = File::create(out_dir.join("host.rs")).expect("error creating host.rs"); write_host_rs(out, triple).expect("error writing host.rs"); } fn write_host_rs(mut out: File, triple: Triple) -> io::Result<()> { // The generated Debug implementation for the inner architecture variants // doesn't print the enum name qualifier, so import them here. There // shouldn't be any conflicts because these enums all share a namespace // in the triple string format. writeln!(out, "#[allow(unused_imports)]")?; writeln!(out, "use crate::Aarch64Architecture::*;")?; writeln!(out, "#[allow(unused_imports)]")?; writeln!(out, "use crate::ArmArchitecture::*;")?; writeln!(out, "#[allow(unused_imports)]")?; writeln!(out, "use crate::CustomVendor;")?; writeln!(out)?; writeln!(out, "/// The `Triple` of the current host.")?; writeln!(out, "pub const HOST: Triple = Triple {{")?; writeln!( out, " architecture: Architecture::{:?},", triple.architecture )?; writeln!(out, " vendor: {},", vendor_display(&triple.vendor))?; writeln!( out, " operating_system: OperatingSystem::{:?},", triple.operating_system )?; writeln!( out, " environment: Environment::{:?},", triple.environment )?; writeln!( out, " binary_format: BinaryFormat::{:?},", triple.binary_format )?; writeln!(out, "}};")?; writeln!(out)?; writeln!(out, "impl Architecture {{")?; writeln!(out, " /// Return the architecture for the current host.")?; writeln!(out, " pub const fn host() -> Self {{")?; writeln!(out, " Architecture::{:?}", triple.architecture)?; writeln!(out, " }}")?; writeln!(out, "}}")?; writeln!(out)?; writeln!(out, "impl Vendor {{")?; writeln!(out, " /// Return the vendor for the current host.")?; writeln!(out, " pub const fn host() -> Self {{")?; writeln!(out, " {}", vendor_display(&triple.vendor))?; writeln!(out, " }}")?; writeln!(out, "}}")?; writeln!(out)?; writeln!(out, "impl OperatingSystem {{")?; writeln!( out, " /// Return the operating system for the current host." )?; writeln!(out, " pub const fn host() -> Self {{")?; writeln!( out, " OperatingSystem::{:?}", triple.operating_system )?; writeln!(out, " }}")?; writeln!(out, "}}")?; writeln!(out)?; writeln!(out, "impl Environment {{")?; writeln!(out, " /// Return the environment for the current host.")?; writeln!(out, " pub const fn host() -> Self {{")?; writeln!(out, " Environment::{:?}", triple.environment)?; writeln!(out, " }}")?; writeln!(out, "}}")?; writeln!(out)?; writeln!(out, "impl BinaryFormat {{")?; writeln!( out, " /// Return the binary format for the current host." )?; writeln!(out, " pub const fn host() -> Self {{")?; writeln!(out, " BinaryFormat::{:?}", triple.binary_format)?; writeln!(out, " }}")?; writeln!(out, "}}")?; writeln!(out)?; writeln!(out, "impl Triple {{")?; writeln!(out, " /// Return the triple for the current host.")?; writeln!(out, " pub const fn host() -> Self {{")?; writeln!(out, " Self {{")?; writeln!( out, " architecture: Architecture::{:?},", triple.architecture )?; writeln!( out, " vendor: {},", vendor_display(&triple.vendor) )?; writeln!( out, " operating_system: OperatingSystem::{:?},", triple.operating_system )?; writeln!( out, " environment: Environment::{:?},", triple.environment )?; writeln!( out, " binary_format: BinaryFormat::{:?},", triple.binary_format )?; writeln!(out, " }}")?; writeln!(out, " }}")?; writeln!(out, "}}")?; Ok(()) } fn vendor_display(vendor: &Vendor) -> String { match vendor { Vendor::Custom(custom) => format!( "Vendor::Custom(CustomVendor::Static({:?}))", custom.as_str() ), known => format!("Vendor::{:?}", known), } } target-lexicon-0.10.0/examples/host.rs010066400017510001751000000003201354575714500161160ustar0000000000000000extern crate target_lexicon; use target_lexicon::HOST; fn main() { println!( "{}", HOST.pointer_width() .expect("architecture should be known") .bytes() ); } target-lexicon-0.10.0/examples/misc.rs010066400017510001751000000006251356033622400160700ustar0000000000000000extern crate target_lexicon; use core::str::FromStr; use target_lexicon::{Triple, HOST}; fn main() { println!("The host triple is {}.", HOST); let e = Triple::from_str("riscv32-unknown-unknown") .expect("expected to recognize the RISC-V target") .endianness() .expect("expected to know the endianness of RISC-V"); println!("The endianness of RISC-V is {:?}.", e); } target-lexicon-0.10.0/src/host.rs010066400017510001751000000025671344004263200150640ustar0000000000000000use crate::{Architecture, BinaryFormat, Environment, OperatingSystem, Triple, Vendor}; // Include the implementations of the `HOST` object containing information // about the current host. include!(concat!(env!("OUT_DIR"), "/host.rs")); #[cfg(test)] mod tests { #[cfg(target_os = "linux")] #[test] fn test_linux() { use super::*; assert_eq!(OperatingSystem::host(), OperatingSystem::Linux); } #[cfg(target_os = "macos")] #[test] fn test_macos() { use super::*; assert_eq!(OperatingSystem::host(), OperatingSystem::Darwin); } #[cfg(windows)] #[test] fn test_windows() { use super::*; assert_eq!(OperatingSystem::host(), OperatingSystem::Windows); } #[cfg(target_pointer_width = "16")] #[test] fn test_ptr16() { use super::*; assert_eq!(Architecture::host().pointer_width().unwrap().bits(), 16); } #[cfg(target_pointer_width = "32")] #[test] fn test_ptr32() { use super::*; assert_eq!(Architecture::host().pointer_width().unwrap().bits(), 32); } #[cfg(target_pointer_width = "64")] #[test] fn test_ptr64() { use super::*; assert_eq!(Architecture::host().pointer_width().unwrap().bits(), 64); } #[test] fn host_object() { use super::*; assert_eq!(HOST, Triple::host()); } } target-lexicon-0.10.0/src/lib.rs010066400017510001751000000015551356467442300146710ustar0000000000000000//! Target triple support. #![deny(missing_docs, trivial_numeric_casts, unused_extern_crates)] #![warn(unused_import_braces)] #![cfg_attr( feature = "cargo-clippy", warn( clippy::float_arithmetic, clippy::mut_mut, clippy::nonminimal_bool, clippy::option_map_unwrap_or, clippy::option_map_unwrap_or_else, clippy::print_stdout, clippy::unicode_not_nfc, clippy::use_self ) )] #![cfg_attr(not(feature = "std"), no_std)] extern crate alloc; mod host; mod parse_error; mod targets; #[macro_use] mod triple; pub use self::host::HOST; pub use self::parse_error::ParseError; pub use self::targets::{ Aarch64Architecture, Architecture, ArmArchitecture, BinaryFormat, CustomVendor, Environment, OperatingSystem, Vendor, }; pub use self::triple::{CallingConvention, Endianness, PointerWidth, Triple}; target-lexicon-0.10.0/src/parse_error.rs010066400017510001751000000022701356004126200164220ustar0000000000000000use alloc::string::String; use core::fmt; /// An error returned from parsing a triple. #[derive(Clone, Debug, PartialEq, Eq)] #[allow(missing_docs)] pub enum ParseError { UnrecognizedArchitecture(String), UnrecognizedVendor(String), UnrecognizedOperatingSystem(String), UnrecognizedEnvironment(String), UnrecognizedBinaryFormat(String), UnrecognizedField(String), } impl fmt::Display for ParseError { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { use ParseError::*; match self { UnrecognizedArchitecture(msg) => write!(fmt, "Unrecognized architecture: {}", msg), UnrecognizedVendor(msg) => write!(fmt, "Unrecognized vendor: {}", msg), UnrecognizedOperatingSystem(msg) => { write!(fmt, "Unrecognized operating system: {}", msg) } UnrecognizedEnvironment(msg) => write!(fmt, "Unrecognized environment: {}", msg), UnrecognizedBinaryFormat(msg) => write!(fmt, "Unrecognized binary format: {}", msg), UnrecognizedField(msg) => write!(fmt, "Unrecognized field: {}", msg), } } } #[cfg(feature = "std")] impl std::error::Error for ParseError {} target-lexicon-0.10.0/src/targets.rs010066400017510001751000001274471356467442300156050ustar0000000000000000// This file defines all the identifier enums and target-aware logic. use crate::triple::{Endianness, PointerWidth, Triple}; use alloc::boxed::Box; use alloc::string::String; use core::fmt; use core::hash::{Hash, Hasher}; use core::str::FromStr; /// The "architecture" field, which in some cases also specifies a specific /// subarchitecture. #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] #[allow(missing_docs)] pub enum Architecture { Unknown, Arm(ArmArchitecture), AmdGcn, Aarch64(Aarch64Architecture), Asmjs, Hexagon, I386, I586, I686, Mips, Mips64, Mips64el, Mipsel, Mipsisa32r6, Mipsisa32r6el, Mipsisa64r6, Mipsisa64r6el, Msp430, Nvptx64, Powerpc, Powerpc64, Powerpc64le, Riscv32, Riscv32i, Riscv32imac, Riscv32imc, Riscv64, Riscv64gc, Riscv64imac, S390x, Sparc, Sparc64, Sparcv9, Wasm32, X86_64, } #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] #[allow(missing_docs)] pub enum ArmArchitecture { Arm, // Generic arm Armeb, Armv4, Armv4t, Armv5t, Armv5te, Armv5tej, Armv6, Armv6j, Armv6k, Armv6z, Armv6kz, Armv6t2, Armv6m, Armv7, Armv7a, Armv7ve, Armv7m, Armv7r, Armv7s, Armv8, Armv8a, Armv8_1a, Armv8_2a, Armv8_3a, Armv8_4a, Armv8_5a, Armv8mBase, Armv8mMain, Armv8r, Armebv7r, Thumbeb, Thumbv6m, Thumbv7a, Thumbv7em, Thumbv7m, Thumbv7neon, Thumbv8mBase, Thumbv8mMain, } #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] #[allow(missing_docs)] pub enum Aarch64Architecture { Aarch64, Aarch64be, } // #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] // #[allow(missing_docs)] // pub enum ArmFpu { // Vfp, // Vfpv2, // Vfpv3, // Vfpv3Fp16, // Vfpv3Xd, // Vfpv3XdFp16, // Neon, // NeonVfpv3, // NeonVfpv4, // Vfpv4, // Vfpv4D16, // Fpv4SpD16, // Fpv5SpD16, // Fpv5D16, // FpArmv8, // NeonFpArmv8, // CryptoNeonFpArmv8, // } impl ArmArchitecture { /// Test if this architecture uses the Thumb instruction set. pub fn is_thumb(self) -> bool { match self { ArmArchitecture::Arm | ArmArchitecture::Armeb | ArmArchitecture::Armv4 | ArmArchitecture::Armv4t | ArmArchitecture::Armv5t | ArmArchitecture::Armv5te | ArmArchitecture::Armv5tej | ArmArchitecture::Armv6 | ArmArchitecture::Armv6j | ArmArchitecture::Armv6k | ArmArchitecture::Armv6z | ArmArchitecture::Armv6kz | ArmArchitecture::Armv6t2 | ArmArchitecture::Armv6m | ArmArchitecture::Armv7 | ArmArchitecture::Armv7a | ArmArchitecture::Armv7ve | ArmArchitecture::Armv7m | ArmArchitecture::Armv7r | ArmArchitecture::Armv7s | ArmArchitecture::Armv8 | ArmArchitecture::Armv8a | ArmArchitecture::Armv8_1a | ArmArchitecture::Armv8_2a | ArmArchitecture::Armv8_3a | ArmArchitecture::Armv8_4a | ArmArchitecture::Armv8_5a | ArmArchitecture::Armv8mBase | ArmArchitecture::Armv8mMain | ArmArchitecture::Armv8r | ArmArchitecture::Armebv7r => false, ArmArchitecture::Thumbeb | ArmArchitecture::Thumbv6m | ArmArchitecture::Thumbv7a | ArmArchitecture::Thumbv7em | ArmArchitecture::Thumbv7m | ArmArchitecture::Thumbv7neon | ArmArchitecture::Thumbv8mBase | ArmArchitecture::Thumbv8mMain => true, } } // pub fn has_fpu(self) -> Result<&'static [ArmFpu], ()> { // } /// Return the pointer bit width of this target's architecture. pub fn pointer_width(self) -> PointerWidth { match self { ArmArchitecture::Arm | ArmArchitecture::Armeb | ArmArchitecture::Armv4 | ArmArchitecture::Armv4t | ArmArchitecture::Armv5t | ArmArchitecture::Armv5te | ArmArchitecture::Armv5tej | ArmArchitecture::Armv6 | ArmArchitecture::Armv6j | ArmArchitecture::Armv6k | ArmArchitecture::Armv6z | ArmArchitecture::Armv6kz | ArmArchitecture::Armv6t2 | ArmArchitecture::Armv6m | ArmArchitecture::Armv7 | ArmArchitecture::Armv7a | ArmArchitecture::Armv7ve | ArmArchitecture::Armv7m | ArmArchitecture::Armv7r | ArmArchitecture::Armv7s | ArmArchitecture::Armv8 | ArmArchitecture::Armv8a | ArmArchitecture::Armv8_1a | ArmArchitecture::Armv8_2a | ArmArchitecture::Armv8_3a | ArmArchitecture::Armv8_4a | ArmArchitecture::Armv8_5a | ArmArchitecture::Armv8mBase | ArmArchitecture::Armv8mMain | ArmArchitecture::Armv8r | ArmArchitecture::Armebv7r | ArmArchitecture::Thumbeb | ArmArchitecture::Thumbv6m | ArmArchitecture::Thumbv7a | ArmArchitecture::Thumbv7em | ArmArchitecture::Thumbv7m | ArmArchitecture::Thumbv7neon | ArmArchitecture::Thumbv8mBase | ArmArchitecture::Thumbv8mMain => PointerWidth::U32, } } /// Return the endianness of this architecture. pub fn endianness(self) -> Endianness { match self { ArmArchitecture::Arm | ArmArchitecture::Armv4 | ArmArchitecture::Armv4t | ArmArchitecture::Armv5t | ArmArchitecture::Armv5te | ArmArchitecture::Armv5tej | ArmArchitecture::Armv6 | ArmArchitecture::Armv6j | ArmArchitecture::Armv6k | ArmArchitecture::Armv6z | ArmArchitecture::Armv6kz | ArmArchitecture::Armv6t2 | ArmArchitecture::Armv6m | ArmArchitecture::Armv7 | ArmArchitecture::Armv7a | ArmArchitecture::Armv7ve | ArmArchitecture::Armv7m | ArmArchitecture::Armv7r | ArmArchitecture::Armv7s | ArmArchitecture::Armv8 | ArmArchitecture::Armv8a | ArmArchitecture::Armv8_1a | ArmArchitecture::Armv8_2a | ArmArchitecture::Armv8_3a | ArmArchitecture::Armv8_4a | ArmArchitecture::Armv8_5a | ArmArchitecture::Armv8mBase | ArmArchitecture::Armv8mMain | ArmArchitecture::Armv8r | ArmArchitecture::Thumbv6m | ArmArchitecture::Thumbv7a | ArmArchitecture::Thumbv7em | ArmArchitecture::Thumbv7m | ArmArchitecture::Thumbv7neon | ArmArchitecture::Thumbv8mBase | ArmArchitecture::Thumbv8mMain => Endianness::Little, ArmArchitecture::Armeb | ArmArchitecture::Armebv7r | ArmArchitecture::Thumbeb => { Endianness::Big } } } } impl Aarch64Architecture { /// Test if this architecture uses the Thumb instruction set. pub fn is_thumb(self) -> bool { match self { Aarch64Architecture::Aarch64 | Aarch64Architecture::Aarch64be => false, } } // pub fn has_fpu(self) -> Result<&'static [ArmFpu], ()> { // } /// Return the pointer bit width of this target's architecture. pub fn pointer_width(self) -> PointerWidth { match self { Aarch64Architecture::Aarch64 | Aarch64Architecture::Aarch64be => PointerWidth::U64, } } /// Return the endianness of this architecture. pub fn endianness(self) -> Endianness { match self { Aarch64Architecture::Aarch64 => Endianness::Little, Aarch64Architecture::Aarch64be => Endianness::Big, } } } /// A string for a `Vendor::Custom` that can either be used in `const` /// contexts or hold dynamic strings. #[derive(Clone, Debug, Eq)] pub enum CustomVendor { /// An owned `String`. This supports the general case. Owned(Box), /// A static `str`, so that `CustomVendor` can be constructed in `const` /// contexts. Static(&'static str), } impl CustomVendor { /// Extracts a string slice. pub fn as_str(&self) -> &str { match self { CustomVendor::Owned(s) => s, CustomVendor::Static(s) => s, } } } impl PartialEq for CustomVendor { fn eq(&self, other: &Self) -> bool { self.as_str() == other.as_str() } } impl Hash for CustomVendor { fn hash(&self, state: &mut H) { self.as_str().hash(state) } } /// The "vendor" field, which in practice is little more than an arbitrary /// modifier. #[derive(Clone, Debug, PartialEq, Eq, Hash)] #[allow(missing_docs)] pub enum Vendor { Unknown, Amd, Apple, Experimental, Fortanix, Nvidia, Pc, Rumprun, Sun, Uwp, Wrs, /// A custom vendor. "Custom" in this context means that the vendor is /// not specifically recognized by upstream Autotools, LLVM, Rust, or other /// relevant authorities on triple naming. It's useful for people building /// and using locally patched toolchains. /// /// Outside of such patched environments, users of `target-lexicon` should /// treat `Custom` the same as `Unknown` and ignore the string. Custom(CustomVendor), } /// The "operating system" field, which sometimes implies an environment, and /// sometimes isn't an actual operating system. #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] #[allow(missing_docs)] pub enum OperatingSystem { Unknown, AmdHsa, Bitrig, Cloudabi, Cuda, Darwin, Dragonfly, Emscripten, Freebsd, Fuchsia, Haiku, Hermit, Ios, L4re, Linux, MacOSX { major: u16, minor: u16, patch: u16 }, Nebulet, Netbsd, None_, Openbsd, Redox, Solaris, Uefi, VxWorks, Wasi, Windows, } /// The "environment" field, which specifies an ABI environment on top of the /// operating system. In many configurations, this field is omitted, and the /// environment is implied by the operating system. #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] #[allow(missing_docs)] pub enum Environment { Unknown, AmdGiz, Android, Androideabi, Eabi, Eabihf, Gnu, Gnuabi64, Gnueabi, Gnueabihf, Gnuspe, Gnux32, Musl, Musleabi, Musleabihf, Muslabi64, Msvc, Kernel, Uclibc, Sgx, Softfloat, Spe, } /// The "binary format" field, which is usually omitted, and the binary format /// is implied by the other fields. #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] #[allow(missing_docs)] pub enum BinaryFormat { Unknown, Elf, Coff, Macho, Wasm, } impl Architecture { /// Return the endianness of this architecture. pub fn endianness(self) -> Result { match self { Architecture::Unknown => Err(()), Architecture::Arm(arm) => Ok(arm.endianness()), Architecture::Aarch64(aarch) => Ok(aarch.endianness()), Architecture::AmdGcn | Architecture::Asmjs | Architecture::Hexagon | Architecture::I386 | Architecture::I586 | Architecture::I686 | Architecture::Mips64el | Architecture::Mipsel | Architecture::Mipsisa32r6el | Architecture::Mipsisa64r6el | Architecture::Msp430 | Architecture::Nvptx64 | Architecture::Powerpc64le | Architecture::Riscv32 | Architecture::Riscv32i | Architecture::Riscv32imac | Architecture::Riscv32imc | Architecture::Riscv64 | Architecture::Riscv64gc | Architecture::Riscv64imac | Architecture::Wasm32 | Architecture::X86_64 => Ok(Endianness::Little), Architecture::Mips | Architecture::Mips64 | Architecture::Mipsisa32r6 | Architecture::Mipsisa64r6 | Architecture::Powerpc | Architecture::Powerpc64 | Architecture::S390x | Architecture::Sparc | Architecture::Sparc64 | Architecture::Sparcv9 => Ok(Endianness::Big), } } /// Return the pointer bit width of this target's architecture. pub fn pointer_width(self) -> Result { match self { Architecture::Unknown => Err(()), Architecture::Msp430 => Ok(PointerWidth::U16), Architecture::Arm(arm) => Ok(arm.pointer_width()), Architecture::Aarch64(aarch) => Ok(aarch.pointer_width()), Architecture::Asmjs | Architecture::Hexagon | Architecture::I386 | Architecture::I586 | Architecture::I686 | Architecture::Mipsel | Architecture::Mipsisa32r6 | Architecture::Mipsisa32r6el | Architecture::Riscv32 | Architecture::Riscv32i | Architecture::Riscv32imac | Architecture::Riscv32imc | Architecture::Sparc | Architecture::Wasm32 | Architecture::Mips | Architecture::Powerpc => Ok(PointerWidth::U32), Architecture::AmdGcn | Architecture::Mips64el | Architecture::Mipsisa64r6 | Architecture::Mipsisa64r6el | Architecture::Powerpc64le | Architecture::Riscv64 | Architecture::Riscv64gc | Architecture::Riscv64imac | Architecture::X86_64 | Architecture::Mips64 | Architecture::Nvptx64 | Architecture::Powerpc64 | Architecture::S390x | Architecture::Sparc64 | Architecture::Sparcv9 => Ok(PointerWidth::U64), } } } /// Return the binary format implied by this target triple, ignoring its /// `binary_format` field. pub(crate) fn default_binary_format(triple: &Triple) -> BinaryFormat { match triple.operating_system { OperatingSystem::None_ => match triple.environment { Environment::Eabi | Environment::Eabihf => BinaryFormat::Elf, _ => BinaryFormat::Unknown, }, OperatingSystem::Darwin | OperatingSystem::Ios | OperatingSystem::MacOSX { .. } => { BinaryFormat::Macho } OperatingSystem::Windows => BinaryFormat::Coff, OperatingSystem::Nebulet | OperatingSystem::Emscripten | OperatingSystem::VxWorks | OperatingSystem::Wasi | OperatingSystem::Unknown => match triple.architecture { Architecture::Wasm32 => BinaryFormat::Wasm, _ => BinaryFormat::Unknown, }, _ => BinaryFormat::Elf, } } impl fmt::Display for ArmArchitecture { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { let s = match *self { ArmArchitecture::Arm => "arm", ArmArchitecture::Armeb => "armeb", ArmArchitecture::Armv4 => "armv4", ArmArchitecture::Armv4t => "armv4t", ArmArchitecture::Armv5t => "armv5t", ArmArchitecture::Armv5te => "armv5te", ArmArchitecture::Armv5tej => "armv5tej", ArmArchitecture::Armv6 => "armv6", ArmArchitecture::Armv6j => "armv6j", ArmArchitecture::Armv6k => "armv6k", ArmArchitecture::Armv6z => "armv6z", ArmArchitecture::Armv6kz => "armv6kz", ArmArchitecture::Armv6t2 => "armv6t2", ArmArchitecture::Armv6m => "armv6m", ArmArchitecture::Armv7 => "armv7", ArmArchitecture::Armv7a => "armv7a", ArmArchitecture::Armv7ve => "armv7ve", ArmArchitecture::Armv7m => "armv7m", ArmArchitecture::Armv7r => "armv7r", ArmArchitecture::Armv7s => "armv7s", ArmArchitecture::Armv8 => "armv8", ArmArchitecture::Armv8a => "armv8a", ArmArchitecture::Armv8_1a => "armv8.1a", ArmArchitecture::Armv8_2a => "armv8.2a", ArmArchitecture::Armv8_3a => "armv8.3a", ArmArchitecture::Armv8_4a => "armv8.4a", ArmArchitecture::Armv8_5a => "armv8.5a", ArmArchitecture::Armv8mBase => "armv8m.base", ArmArchitecture::Armv8mMain => "armv8m.main", ArmArchitecture::Armv8r => "armv8r", ArmArchitecture::Thumbeb => "thumbeb", ArmArchitecture::Thumbv6m => "thumbv6m", ArmArchitecture::Thumbv7a => "thumbv7a", ArmArchitecture::Thumbv7em => "thumbv7em", ArmArchitecture::Thumbv7m => "thumbv7m", ArmArchitecture::Thumbv7neon => "thumbv7neon", ArmArchitecture::Thumbv8mBase => "thumbv8m.base", ArmArchitecture::Thumbv8mMain => "thumbv8m.main", ArmArchitecture::Armebv7r => "armebv7r", }; f.write_str(s) } } impl fmt::Display for Aarch64Architecture { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { let s = match *self { Aarch64Architecture::Aarch64 => "aarch64", Aarch64Architecture::Aarch64be => "aarch64be", }; f.write_str(s) } } impl fmt::Display for Architecture { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { Architecture::Arm(arm) => arm.fmt(f), Architecture::Aarch64(aarch) => aarch.fmt(f), Architecture::Unknown => f.write_str("unknown"), Architecture::AmdGcn => f.write_str("amdgcn"), Architecture::Asmjs => f.write_str("asmjs"), Architecture::Hexagon => f.write_str("hexagon"), Architecture::I386 => f.write_str("i386"), Architecture::I586 => f.write_str("i586"), Architecture::I686 => f.write_str("i686"), Architecture::Mips => f.write_str("mips"), Architecture::Mips64 => f.write_str("mips64"), Architecture::Mips64el => f.write_str("mips64el"), Architecture::Mipsel => f.write_str("mipsel"), Architecture::Mipsisa32r6 => f.write_str("mipsisa32r6"), Architecture::Mipsisa32r6el => f.write_str("mipsisa32r6el"), Architecture::Mipsisa64r6 => f.write_str("mipsisa64r6"), Architecture::Mipsisa64r6el => f.write_str("mipsisa64r6el"), Architecture::Msp430 => f.write_str("msp430"), Architecture::Nvptx64 => f.write_str("nvptx64"), Architecture::Powerpc => f.write_str("powerpc"), Architecture::Powerpc64 => f.write_str("powerpc64"), Architecture::Powerpc64le => f.write_str("powerpc64le"), Architecture::Riscv32 => f.write_str("riscv32"), Architecture::Riscv32i => f.write_str("riscv32i"), Architecture::Riscv32imac => f.write_str("riscv32imac"), Architecture::Riscv32imc => f.write_str("riscv32imc"), Architecture::Riscv64 => f.write_str("riscv64"), Architecture::Riscv64gc => f.write_str("riscv64gc"), Architecture::Riscv64imac => f.write_str("riscv64imac"), Architecture::S390x => f.write_str("s390x"), Architecture::Sparc => f.write_str("sparc"), Architecture::Sparc64 => f.write_str("sparc64"), Architecture::Sparcv9 => f.write_str("sparcv9"), Architecture::Wasm32 => f.write_str("wasm32"), Architecture::X86_64 => f.write_str("x86_64"), } } } impl FromStr for ArmArchitecture { type Err = (); fn from_str(s: &str) -> Result { Ok(match s { "arm" => ArmArchitecture::Arm, "armeb" => ArmArchitecture::Armeb, "armv4" => ArmArchitecture::Armv4, "armv4t" => ArmArchitecture::Armv4t, "armv5t" => ArmArchitecture::Armv5t, "armv5te" => ArmArchitecture::Armv5te, "armv5tej" => ArmArchitecture::Armv5tej, "armv6" => ArmArchitecture::Armv6, "armv6j" => ArmArchitecture::Armv6j, "armv6k" => ArmArchitecture::Armv6k, "armv6z" => ArmArchitecture::Armv6z, "armv6kz" => ArmArchitecture::Armv6kz, "armv6t2" => ArmArchitecture::Armv6t2, "armv6m" => ArmArchitecture::Armv6m, "armv7" => ArmArchitecture::Armv7, "armv7a" => ArmArchitecture::Armv7a, "armv7ve" => ArmArchitecture::Armv7ve, "armv7m" => ArmArchitecture::Armv7m, "armv7r" => ArmArchitecture::Armv7r, "armv7s" => ArmArchitecture::Armv7s, "armv8" => ArmArchitecture::Armv8, "armv8a" => ArmArchitecture::Armv8a, "armv8.1a" => ArmArchitecture::Armv8_1a, "armv8.2a" => ArmArchitecture::Armv8_2a, "armv8.3a" => ArmArchitecture::Armv8_3a, "armv8.4a" => ArmArchitecture::Armv8_4a, "armv8.5a" => ArmArchitecture::Armv8_5a, "armv8m.base" => ArmArchitecture::Armv8mBase, "armv8m.main" => ArmArchitecture::Armv8mMain, "armv8r" => ArmArchitecture::Armv8r, "thumbeb" => ArmArchitecture::Thumbeb, "thumbv6m" => ArmArchitecture::Thumbv6m, "thumbv7a" => ArmArchitecture::Thumbv7a, "thumbv7em" => ArmArchitecture::Thumbv7em, "thumbv7m" => ArmArchitecture::Thumbv7m, "thumbv7neon" => ArmArchitecture::Thumbv7neon, "thumbv8m.base" => ArmArchitecture::Thumbv8mBase, "thumbv8m.main" => ArmArchitecture::Thumbv8mMain, "armebv7r" => ArmArchitecture::Armebv7r, _ => return Err(()), }) } } impl FromStr for Aarch64Architecture { type Err = (); fn from_str(s: &str) -> Result { Ok(match s { "aarch64" => Aarch64Architecture::Aarch64, "arm64" => Aarch64Architecture::Aarch64, "aarch64be" => Aarch64Architecture::Aarch64be, _ => return Err(()), }) } } impl FromStr for Architecture { type Err = (); fn from_str(s: &str) -> Result { Ok(match s { "unknown" => Architecture::Unknown, "amdgcn" => Architecture::AmdGcn, "asmjs" => Architecture::Asmjs, "hexagon" => Architecture::Hexagon, "i386" => Architecture::I386, "i586" => Architecture::I586, "i686" => Architecture::I686, "mips" => Architecture::Mips, "mips64" => Architecture::Mips64, "mips64el" => Architecture::Mips64el, "mipsel" => Architecture::Mipsel, "mipsisa32r6" => Architecture::Mipsisa32r6, "mipsisa32r6el" => Architecture::Mipsisa32r6el, "mipsisa64r6" => Architecture::Mipsisa64r6, "mipsisa64r6el" => Architecture::Mipsisa64r6el, "msp430" => Architecture::Msp430, "nvptx64" => Architecture::Nvptx64, "powerpc" => Architecture::Powerpc, "powerpc64" => Architecture::Powerpc64, "powerpc64le" => Architecture::Powerpc64le, "riscv32" => Architecture::Riscv32, "riscv32i" => Architecture::Riscv32i, "riscv32imac" => Architecture::Riscv32imac, "riscv32imc" => Architecture::Riscv32imc, "riscv64" => Architecture::Riscv64, "riscv64gc" => Architecture::Riscv64gc, "riscv64imac" => Architecture::Riscv64imac, "s390x" => Architecture::S390x, "sparc" => Architecture::Sparc, "sparc64" => Architecture::Sparc64, "sparcv9" => Architecture::Sparcv9, "wasm32" => Architecture::Wasm32, "x86_64" => Architecture::X86_64, _ => { if let Ok(arm) = ArmArchitecture::from_str(s) { Architecture::Arm(arm) } else if let Ok(aarch64) = Aarch64Architecture::from_str(s) { Architecture::Aarch64(aarch64) } else { return Err(()); } } }) } } impl fmt::Display for Vendor { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { let s = match *self { Vendor::Unknown => "unknown", Vendor::Amd => "amd", Vendor::Apple => "apple", Vendor::Experimental => "experimental", Vendor::Fortanix => "fortanix", Vendor::Nvidia => "nvidia", Vendor::Pc => "pc", Vendor::Rumprun => "rumprun", Vendor::Sun => "sun", Vendor::Uwp => "uwp", Vendor::Wrs => "wrs", Vendor::Custom(ref name) => name.as_str(), }; f.write_str(s) } } impl FromStr for Vendor { type Err = (); fn from_str(s: &str) -> Result { Ok(match s { "unknown" => Vendor::Unknown, "amd" => Vendor::Amd, "apple" => Vendor::Apple, "experimental" => Vendor::Experimental, "fortanix" => Vendor::Fortanix, "nvidia" => Vendor::Nvidia, "pc" => Vendor::Pc, "rumprun" => Vendor::Rumprun, "sun" => Vendor::Sun, "uwp" => Vendor::Uwp, "wrs" => Vendor::Wrs, custom => { use alloc::borrow::ToOwned; // A custom vendor. Since triple syntax is so loosely defined, // be as conservative as we can to avoid potential ambiguities. // We err on the side of being too strict here, as we can // always relax it if needed. // Don't allow empty string names. if custom.is_empty() { return Err(()); } // Don't allow any other recognized name as a custom vendor, // since vendors can be omitted in some contexts. if Architecture::from_str(custom).is_ok() || OperatingSystem::from_str(custom).is_ok() || Environment::from_str(custom).is_ok() || BinaryFormat::from_str(custom).is_ok() { return Err(()); } // Require the first character to be an ascii lowercase. if !custom.chars().nth(0).unwrap().is_ascii_lowercase() { return Err(()); } // Restrict the set of characters permitted in a custom vendor. if custom.chars().any(|c: char| { !(c.is_ascii_lowercase() || c.is_ascii_digit() || c == '_' || c == '.') }) { return Err(()); } Vendor::Custom(CustomVendor::Owned(Box::new(custom.to_owned()))) } }) } } impl fmt::Display for OperatingSystem { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { let s = match *self { OperatingSystem::Unknown => "unknown", OperatingSystem::AmdHsa => "amdhsa", OperatingSystem::Bitrig => "bitrig", OperatingSystem::Cloudabi => "cloudabi", OperatingSystem::Cuda => "cuda", OperatingSystem::Darwin => "darwin", OperatingSystem::Dragonfly => "dragonfly", OperatingSystem::Emscripten => "emscripten", OperatingSystem::Freebsd => "freebsd", OperatingSystem::Fuchsia => "fuchsia", OperatingSystem::Haiku => "haiku", OperatingSystem::Hermit => "hermit", OperatingSystem::Ios => "ios", OperatingSystem::L4re => "l4re", OperatingSystem::Linux => "linux", OperatingSystem::MacOSX { major, minor, patch, } => { return write!(f, "macosx{}.{}.{}", major, minor, patch); } OperatingSystem::Nebulet => "nebulet", OperatingSystem::Netbsd => "netbsd", OperatingSystem::None_ => "none", OperatingSystem::Openbsd => "openbsd", OperatingSystem::Redox => "redox", OperatingSystem::Solaris => "solaris", OperatingSystem::Uefi => "uefi", OperatingSystem::VxWorks => "vxworks", OperatingSystem::Wasi => "wasi", OperatingSystem::Windows => "windows", }; f.write_str(s) } } impl FromStr for OperatingSystem { type Err = (); fn from_str(s: &str) -> Result { // TODO also parse version number for darwin and ios OSes if s.starts_with("macosx") { // Parse operating system names like `macosx10.7.0`. let s = &s["macosx".len()..]; let mut parts = s.split('.').map(|num| num.parse::()); macro_rules! get_part { () => { if let Some(Ok(part)) = parts.next() { part } else { return Err(()); } }; } let major = get_part!(); let minor = get_part!(); let patch = get_part!(); if parts.next().is_some() { return Err(()); } return Ok(OperatingSystem::MacOSX { major, minor, patch, }); } Ok(match s { "unknown" => OperatingSystem::Unknown, "amdhsa" => OperatingSystem::AmdHsa, "bitrig" => OperatingSystem::Bitrig, "cloudabi" => OperatingSystem::Cloudabi, "cuda" => OperatingSystem::Cuda, "darwin" => OperatingSystem::Darwin, "dragonfly" => OperatingSystem::Dragonfly, "emscripten" => OperatingSystem::Emscripten, "freebsd" => OperatingSystem::Freebsd, "fuchsia" => OperatingSystem::Fuchsia, "haiku" => OperatingSystem::Haiku, "hermit" => OperatingSystem::Hermit, "ios" => OperatingSystem::Ios, "l4re" => OperatingSystem::L4re, "linux" => OperatingSystem::Linux, "nebulet" => OperatingSystem::Nebulet, "netbsd" => OperatingSystem::Netbsd, "none" => OperatingSystem::None_, "openbsd" => OperatingSystem::Openbsd, "redox" => OperatingSystem::Redox, "solaris" => OperatingSystem::Solaris, "uefi" => OperatingSystem::Uefi, "vxworks" => OperatingSystem::VxWorks, "wasi" => OperatingSystem::Wasi, "windows" => OperatingSystem::Windows, _ => return Err(()), }) } } impl fmt::Display for Environment { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { let s = match *self { Environment::Unknown => "unknown", Environment::AmdGiz => "amdgiz", Environment::Android => "android", Environment::Androideabi => "androideabi", Environment::Eabi => "eabi", Environment::Eabihf => "eabihf", Environment::Gnu => "gnu", Environment::Gnuabi64 => "gnuabi64", Environment::Gnueabi => "gnueabi", Environment::Gnueabihf => "gnueabihf", Environment::Gnuspe => "gnuspe", Environment::Gnux32 => "gnux32", Environment::Musl => "musl", Environment::Musleabi => "musleabi", Environment::Musleabihf => "musleabihf", Environment::Muslabi64 => "muslabi64", Environment::Msvc => "msvc", Environment::Kernel => "kernel", Environment::Uclibc => "uclibc", Environment::Sgx => "sgx", Environment::Softfloat => "softfloat", Environment::Spe => "spe", }; f.write_str(s) } } impl FromStr for Environment { type Err = (); fn from_str(s: &str) -> Result { Ok(match s { "unknown" => Environment::Unknown, "amdgiz" => Environment::AmdGiz, "android" => Environment::Android, "androideabi" => Environment::Androideabi, "eabi" => Environment::Eabi, "eabihf" => Environment::Eabihf, "gnu" => Environment::Gnu, "gnuabi64" => Environment::Gnuabi64, "gnueabi" => Environment::Gnueabi, "gnueabihf" => Environment::Gnueabihf, "gnuspe" => Environment::Gnuspe, "gnux32" => Environment::Gnux32, "musl" => Environment::Musl, "musleabi" => Environment::Musleabi, "musleabihf" => Environment::Musleabihf, "muslabi64" => Environment::Muslabi64, "msvc" => Environment::Msvc, "kernel" => Environment::Kernel, "uclibc" => Environment::Uclibc, "sgx" => Environment::Sgx, "softfloat" => Environment::Softfloat, "spe" => Environment::Spe, _ => return Err(()), }) } } impl fmt::Display for BinaryFormat { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { let s = match *self { BinaryFormat::Unknown => "unknown", BinaryFormat::Elf => "elf", BinaryFormat::Coff => "coff", BinaryFormat::Macho => "macho", BinaryFormat::Wasm => "wasm", }; f.write_str(s) } } impl FromStr for BinaryFormat { type Err = (); fn from_str(s: &str) -> Result { Ok(match s { "unknown" => BinaryFormat::Unknown, "elf" => BinaryFormat::Elf, "coff" => BinaryFormat::Coff, "macho" => BinaryFormat::Macho, "wasm" => BinaryFormat::Wasm, _ => return Err(()), }) } } #[cfg(test)] mod tests { use super::*; use alloc::string::ToString; #[test] fn roundtrip_known_triples() { // This list is constructed from: // - targets emitted by "rustup target list" // - targets emitted by "rustc +nightly --print target-list" // - targets contributors have added let targets = [ "aarch64-apple-ios", "aarch64-fuchsia", "aarch64-linux-android", "aarch64-pc-windows-msvc", "aarch64-unknown-cloudabi", "aarch64-unknown-freebsd", "aarch64-unknown-hermit", "aarch64-unknown-linux-gnu", "aarch64-unknown-linux-musl", "aarch64-unknown-netbsd", "aarch64-unknown-none", "aarch64-unknown-none-softfloat", "aarch64-unknown-openbsd", "aarch64-unknown-redox", "aarch64-uwp-windows-msvc", "aarch64-wrs-vxworks", "amdgcn-amd-amdhsa", "amdgcn-amd-amdhsa-amdgiz", "armebv7r-none-eabi", "armebv7r-none-eabihf", "arm-linux-androideabi", "arm-unknown-linux-gnueabi", "arm-unknown-linux-gnueabihf", "arm-unknown-linux-musleabi", "arm-unknown-linux-musleabihf", "armv4t-unknown-linux-gnueabi", "armv5te-unknown-linux-gnueabi", "armv5te-unknown-linux-musleabi", "armv6-unknown-freebsd", "armv6-unknown-netbsd-eabihf", "armv7-apple-ios", "armv7-linux-androideabi", "armv7r-none-eabi", "armv7r-none-eabihf", "armv7s-apple-ios", "armv7-unknown-cloudabi-eabihf", "armv7-unknown-freebsd", "armv7-unknown-linux-gnueabi", "armv7-unknown-linux-gnueabihf", "armv7-unknown-linux-musleabi", "armv7-unknown-linux-musleabihf", "armv7-unknown-netbsd-eabihf", "armv7-wrs-vxworks-eabihf", "asmjs-unknown-emscripten", "hexagon-unknown-linux-musl", "i386-apple-ios", "i586-pc-windows-msvc", "i586-unknown-linux-gnu", "i586-unknown-linux-musl", "i686-apple-darwin", "i686-linux-android", "i686-apple-macosx10.7.0", "i686-pc-windows-gnu", "i686-pc-windows-msvc", "i686-unknown-cloudabi", "i686-unknown-dragonfly", "i686-unknown-freebsd", "i686-unknown-haiku", "i686-unknown-linux-gnu", "i686-unknown-linux-musl", "i686-unknown-netbsd", "i686-unknown-openbsd", "i686-unknown-uefi", "i686-uwp-windows-gnu", "i686-uwp-windows-msvc", "i686-wrs-vxworks", "mips64el-unknown-linux-gnuabi64", "mips64el-unknown-linux-muslabi64", "mips64-unknown-linux-gnuabi64", "mips64-unknown-linux-muslabi64", "mipsel-unknown-linux-gnu", "mipsel-unknown-linux-musl", "mipsel-unknown-linux-uclibc", "mipsisa32r6el-unknown-linux-gnu", "mipsisa32r6-unknown-linux-gnu", "mipsisa64r6el-unknown-linux-gnuabi64", "mipsisa64r6-unknown-linux-gnuabi64", "mips-unknown-linux-gnu", "mips-unknown-linux-musl", "mips-unknown-linux-uclibc", "msp430-none-elf", "nvptx64-nvidia-cuda", "powerpc64le-unknown-linux-gnu", "powerpc64le-unknown-linux-musl", "powerpc64-unknown-freebsd", "powerpc64-unknown-linux-gnu", "powerpc64-unknown-linux-musl", "powerpc64-wrs-vxworks", "powerpc-unknown-linux-gnu", "powerpc-unknown-linux-gnuspe", "powerpc-unknown-linux-musl", "powerpc-unknown-netbsd", "powerpc-wrs-vxworks", "powerpc-wrs-vxworks-spe", "riscv32imac-unknown-none-elf", "riscv32imc-unknown-none-elf", "riscv32i-unknown-none-elf", "riscv64gc-unknown-none-elf", "riscv64imac-unknown-none-elf", "s390x-unknown-linux-gnu", "sparc64-unknown-linux-gnu", "sparc64-unknown-netbsd", "sparc64-unknown-openbsd", "sparc-unknown-linux-gnu", "sparcv9-sun-solaris", "thumbv6m-none-eabi", "thumbv7a-pc-windows-msvc", "thumbv7em-none-eabi", "thumbv7em-none-eabihf", "thumbv7m-none-eabi", "thumbv7neon-linux-androideabi", "thumbv7neon-unknown-linux-gnueabihf", "thumbv8m.base-none-eabi", "thumbv8m.main-none-eabi", "thumbv8m.main-none-eabihf", "wasm32-experimental-emscripten", "wasm32-unknown-emscripten", "wasm32-unknown-unknown", "wasm32-wasi", "x86_64-apple-darwin", "x86_64-apple-ios", "x86_64-fortanix-unknown-sgx", "x86_64-fuchsia", "x86_64-linux-android", "x86_64-linux-kernel", "x86_64-apple-macosx10.7.0", "x86_64-pc-solaris", "x86_64-pc-windows-gnu", "x86_64-pc-windows-msvc", "x86_64-rumprun-netbsd", "x86_64-sun-solaris", "x86_64-unknown-bitrig", "x86_64-unknown-cloudabi", "x86_64-unknown-dragonfly", "x86_64-unknown-freebsd", "x86_64-unknown-haiku", "x86_64-unknown-hermit", "x86_64-unknown-l4re-uclibc", "x86_64-unknown-linux-gnu", "x86_64-unknown-linux-gnux32", "x86_64-unknown-linux-musl", "x86_64-unknown-netbsd", "x86_64-unknown-openbsd", "x86_64-unknown-redox", "x86_64-unknown-uefi", "x86_64-uwp-windows-gnu", "x86_64-uwp-windows-msvc", "x86_64-wrs-vxworks", ]; for target in targets.iter() { let t = Triple::from_str(target).expect("can't parse target"); assert_ne!(t.architecture, Architecture::Unknown); assert_eq!(t.to_string(), *target); } } #[test] fn thumbv7em_none_eabihf() { let t = Triple::from_str("thumbv7em-none-eabihf").expect("can't parse target"); assert_eq!( t.architecture, Architecture::Arm(ArmArchitecture::Thumbv7em) ); assert_eq!(t.vendor, Vendor::Unknown); assert_eq!(t.operating_system, OperatingSystem::None_); assert_eq!(t.environment, Environment::Eabihf); assert_eq!(t.binary_format, BinaryFormat::Elf); } #[test] fn custom_vendors() { // Test various invalid cases. assert!(Triple::from_str("x86_64--linux").is_err()); assert!(Triple::from_str("x86_64-42-linux").is_err()); assert!(Triple::from_str("x86_64-__customvendor__-linux").is_err()); assert!(Triple::from_str("x86_64-^-linux").is_err()); assert!(Triple::from_str("x86_64- -linux").is_err()); assert!(Triple::from_str("x86_64-CustomVendor-linux").is_err()); assert!(Triple::from_str("x86_64-linux-linux").is_err()); assert!(Triple::from_str("x86_64-x86_64-linux").is_err()); assert!(Triple::from_str("x86_64-elf-linux").is_err()); assert!(Triple::from_str("x86_64-gnu-linux").is_err()); assert!(Triple::from_str("x86_64-linux-customvendor").is_err()); assert!(Triple::from_str("customvendor").is_err()); assert!(Triple::from_str("customvendor-x86_64").is_err()); assert!(Triple::from_str("x86_64-").is_err()); assert!(Triple::from_str("x86_64--").is_err()); // Test various Unicode things. assert!( Triple::from_str("x86_64-𝓬𝓾𝓼𝓽𝓸𝓶𝓿𝓮𝓷𝓭𝓸𝓻-linux").is_err(), "unicode font hazard" ); assert!( Triple::from_str("x86_64-ćúśtőḿvéńdőŕ-linux").is_err(), "diacritical mark stripping hazard" ); assert!( Triple::from_str("x86_64-customvendοr-linux").is_err(), "homoglyph hazard" ); assert!(Triple::from_str("x86_64-customvendor-linux").is_ok()); assert!( Triple::from_str("x86_64-ffi-linux").is_err(), "normalization hazard" ); assert!(Triple::from_str("x86_64-ffi-linux").is_ok()); assert!( Triple::from_str("x86_64-custom‍vendor-linux").is_err(), "zero-width character hazard" ); assert!( Triple::from_str("x86_64-customvendor-linux").is_err(), "BOM hazard" ); // Test some valid cases. let t = Triple::from_str("x86_64-customvendor-linux") .expect("can't parse target with custom vendor"); assert_eq!(t.architecture, Architecture::X86_64); assert_eq!( t.vendor, Vendor::Custom(CustomVendor::Static("customvendor")) ); assert_eq!(t.operating_system, OperatingSystem::Linux); assert_eq!(t.environment, Environment::Unknown); assert_eq!(t.binary_format, BinaryFormat::Elf); assert_eq!(t.to_string(), "x86_64-customvendor-linux"); let t = Triple::from_str("x86_64-customvendor").expect("can't parse target with custom vendor"); assert_eq!(t.architecture, Architecture::X86_64); assert_eq!( t.vendor, Vendor::Custom(CustomVendor::Static("customvendor")) ); assert_eq!(t.operating_system, OperatingSystem::Unknown); assert_eq!(t.environment, Environment::Unknown); assert_eq!(t.binary_format, BinaryFormat::Unknown); assert_eq!( Triple::from_str("unknown-foo"), Ok(Triple { architecture: Architecture::Unknown, vendor: Vendor::Custom(CustomVendor::Static("foo")), operating_system: OperatingSystem::Unknown, environment: Environment::Unknown, binary_format: BinaryFormat::Unknown, }) ); } } target-lexicon-0.10.0/src/triple.rs010066400017510001751000000306621356467442300154230ustar0000000000000000// This file defines the `Triple` type and support code shared by all targets. use crate::parse_error::ParseError; use crate::targets::{ default_binary_format, Architecture, ArmArchitecture, BinaryFormat, Environment, OperatingSystem, Vendor, }; use alloc::borrow::ToOwned; use core::fmt; use core::str::FromStr; /// The target memory endianness. #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] #[allow(missing_docs)] pub enum Endianness { Little, Big, } /// The width of a pointer (in the default address space). #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] #[allow(missing_docs)] pub enum PointerWidth { U16, U32, U64, } impl PointerWidth { /// Return the number of bits in a pointer. pub fn bits(self) -> u8 { match self { PointerWidth::U16 => 16, PointerWidth::U32 => 32, PointerWidth::U64 => 64, } } /// Return the number of bytes in a pointer. /// /// For these purposes, there are 8 bits in a byte. pub fn bytes(self) -> u8 { match self { PointerWidth::U16 => 2, PointerWidth::U32 => 4, PointerWidth::U64 => 8, } } } /// The calling convention, which specifies things like which registers are /// used for passing arguments, which registers are callee-saved, and so on. #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] #[allow(missing_docs)] pub enum CallingConvention { /// "System V", which is used on most Unix-like platfoms. Note that the /// specific conventions vary between hardware architectures; for example, /// x86-32's "System V" is entirely different from x86-64's "System V". SystemV, /// The WebAssembly C ABI. /// https://github.com/WebAssembly/tool-conventions/blob/master/BasicCABI.md WasmBasicCAbi, /// "Windows Fastcall", which is used on Windows. Note that like "System V", /// this varies between hardware architectures. On x86-32 it describes what /// Windows documentation calls "fastcall", and on x86-64 it describes what /// Windows documentation often just calls the Windows x64 calling convention /// (though the compiler still recognizes "fastcall" as an alias for it). WindowsFastcall, } /// A target "triple". Historically such things had three fields, though they've /// added additional fields over time. #[derive(Clone, Debug, PartialEq, Eq, Hash)] pub struct Triple { /// The "architecture" (and sometimes the subarchitecture). pub architecture: Architecture, /// The "vendor" (whatever that means). pub vendor: Vendor, /// The "operating system" (sometimes also the environment). pub operating_system: OperatingSystem, /// The "environment" on top of the operating system (often omitted for /// operating systems with a single predominant environment). pub environment: Environment, /// The "binary format" (rarely used). pub binary_format: BinaryFormat, } impl Triple { /// Return the endianness of this target's architecture. pub fn endianness(&self) -> Result { self.architecture.endianness() } /// Return the pointer width of this target's architecture. pub fn pointer_width(&self) -> Result { self.architecture.pointer_width() } /// Return the default calling convention for the given target triple. pub fn default_calling_convention(&self) -> Result { Ok(match self.operating_system { OperatingSystem::Bitrig | OperatingSystem::Cloudabi | OperatingSystem::Darwin | OperatingSystem::Dragonfly | OperatingSystem::Freebsd | OperatingSystem::Fuchsia | OperatingSystem::Haiku | OperatingSystem::Ios | OperatingSystem::L4re | OperatingSystem::Linux | OperatingSystem::MacOSX { .. } | OperatingSystem::Netbsd | OperatingSystem::Openbsd | OperatingSystem::Redox | OperatingSystem::Solaris => CallingConvention::SystemV, OperatingSystem::Windows => CallingConvention::WindowsFastcall, OperatingSystem::Nebulet | OperatingSystem::Emscripten | OperatingSystem::Wasi | OperatingSystem::Unknown => match self.architecture { Architecture::Wasm32 => CallingConvention::WasmBasicCAbi, _ => return Err(()), }, _ => return Err(()), }) } } impl Default for Triple { fn default() -> Self { Self { architecture: Architecture::Unknown, vendor: Vendor::Unknown, operating_system: OperatingSystem::Unknown, environment: Environment::Unknown, binary_format: BinaryFormat::Unknown, } } } impl Default for Architecture { fn default() -> Self { Architecture::Unknown } } impl Default for Vendor { fn default() -> Self { Vendor::Unknown } } impl Default for OperatingSystem { fn default() -> Self { OperatingSystem::Unknown } } impl Default for Environment { fn default() -> Self { Environment::Unknown } } impl Default for BinaryFormat { fn default() -> Self { BinaryFormat::Unknown } } impl fmt::Display for Triple { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { let implied_binary_format = default_binary_format(&self); write!(f, "{}", self.architecture)?; if self.vendor == Vendor::Unknown && ((self.operating_system == OperatingSystem::Linux && (self.environment == Environment::Android || self.environment == Environment::Androideabi || self.environment == Environment::Kernel)) || self.operating_system == OperatingSystem::Fuchsia || self.operating_system == OperatingSystem::Wasi || (self.operating_system == OperatingSystem::None_ && (self.architecture == Architecture::Arm(ArmArchitecture::Armebv7r) || self.architecture == Architecture::Arm(ArmArchitecture::Armv7r) || self.architecture == Architecture::Arm(ArmArchitecture::Thumbv6m) || self.architecture == Architecture::Arm(ArmArchitecture::Thumbv7em) || self.architecture == Architecture::Arm(ArmArchitecture::Thumbv7m) || self.architecture == Architecture::Arm(ArmArchitecture::Thumbv8mBase) || self.architecture == Architecture::Arm(ArmArchitecture::Thumbv8mMain) || self.architecture == Architecture::Msp430 || self.architecture == Architecture::X86_64))) { // As a special case, omit the vendor for Android, Fuchsia, Wasi, and sometimes // None_, depending on the hardware architecture. This logic is entirely // ad-hoc, and is just sufficient to handle the current set of recognized // triples. write!(f, "-{}", self.operating_system)?; } else { write!(f, "-{}-{}", self.vendor, self.operating_system)?; } if self.environment != Environment::Unknown { write!(f, "-{}", self.environment)?; } if self.binary_format != implied_binary_format { write!(f, "-{}", self.binary_format)?; } Ok(()) } } impl FromStr for Triple { type Err = ParseError; fn from_str(s: &str) -> Result { let mut parts = s.split('-'); let mut result = Self::default(); let mut current_part; current_part = parts.next(); if let Some(s) = current_part { if let Ok(architecture) = Architecture::from_str(s) { result.architecture = architecture; current_part = parts.next(); } else { // Insist that the triple start with a valid architecture. return Err(ParseError::UnrecognizedArchitecture(s.to_owned())); } } let mut has_vendor = false; let mut has_operating_system = false; if let Some(s) = current_part { if let Ok(vendor) = Vendor::from_str(s) { has_vendor = true; result.vendor = vendor; current_part = parts.next(); } } if !has_operating_system { if let Some(s) = current_part { if let Ok(operating_system) = OperatingSystem::from_str(s) { has_operating_system = true; result.operating_system = operating_system; current_part = parts.next(); } } } let mut has_environment = false; if let Some(s) = current_part { if let Ok(environment) = Environment::from_str(s) { has_environment = true; result.environment = environment; current_part = parts.next(); } } let mut has_binary_format = false; if let Some(s) = current_part { if let Ok(binary_format) = BinaryFormat::from_str(s) { has_binary_format = true; result.binary_format = binary_format; current_part = parts.next(); } } // The binary format is frequently omitted; if that's the case here, // infer it from the other fields. if !has_binary_format { result.binary_format = default_binary_format(&result); } if let Some(s) = current_part { Err( if !has_vendor && !has_operating_system && !has_environment && !has_binary_format { ParseError::UnrecognizedVendor(s.to_owned()) } else if !has_operating_system && !has_environment && !has_binary_format { ParseError::UnrecognizedOperatingSystem(s.to_owned()) } else if !has_environment && !has_binary_format { ParseError::UnrecognizedEnvironment(s.to_owned()) } else if !has_binary_format { ParseError::UnrecognizedBinaryFormat(s.to_owned()) } else { ParseError::UnrecognizedField(s.to_owned()) }, ) } else { Ok(result) } } } /// A convenient syntax for triple literals. /// /// This currently expands to code that just calls `Triple::from_str` and does /// an `expect`, though in the future it would be cool to use procedural macros /// or so to report errors at compile time instead. #[macro_export] macro_rules! triple { ($str:tt) => { target_lexicon::Triple::from_str($str).expect("invalid triple literal") }; } #[cfg(test)] mod tests { use super::*; #[test] fn parse_errors() { assert_eq!( Triple::from_str(""), Err(ParseError::UnrecognizedArchitecture("".to_owned())) ); assert_eq!( Triple::from_str("foo"), Err(ParseError::UnrecognizedArchitecture("foo".to_owned())) ); assert_eq!( Triple::from_str("unknown-unknown-foo"), Err(ParseError::UnrecognizedOperatingSystem("foo".to_owned())) ); assert_eq!( Triple::from_str("unknown-unknown-unknown-foo"), Err(ParseError::UnrecognizedEnvironment("foo".to_owned())) ); assert_eq!( Triple::from_str("unknown-unknown-unknown-unknown-foo"), Err(ParseError::UnrecognizedBinaryFormat("foo".to_owned())) ); assert_eq!( Triple::from_str("unknown-unknown-unknown-unknown-unknown-foo"), Err(ParseError::UnrecognizedField("foo".to_owned())) ); } #[test] fn defaults() { assert_eq!( Triple::from_str("unknown-unknown-unknown"), Ok(Triple::default()) ); assert_eq!( Triple::from_str("unknown-unknown-unknown-unknown"), Ok(Triple::default()) ); assert_eq!( Triple::from_str("unknown-unknown-unknown-unknown-unknown"), Ok(Triple::default()) ); } #[test] fn unknown_properties() { assert_eq!(Triple::default().endianness(), Err(())); assert_eq!(Triple::default().pointer_width(), Err(())); assert_eq!(Triple::default().default_calling_convention(), Err(())); } } target-lexicon-0.10.0/a010066400017510001751000000035261356032260500131150ustar0000000000000000diff --git a/src/targets.rs b/src/targets.rs index 6ae570e..3aa1044 100644 --- a/src/targets.rs +++ b/src/targets.rs @@ -1,6 +1,7 @@ // This file defines all the identifier enums and target-aware logic. use crate::triple::{Endianness, PointerWidth, Triple}; +use alloc::string::String; use core::fmt; use core::str::FromStr; @@ -292,7 +293,7 @@ impl Aarch64Architecture { /// The "vendor" field, which in practice is little more than an arbitrary /// modifier. -#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] +#[derive(Clone, Debug, PartialEq, Eq, Hash)] #[allow(missing_docs)] pub enum Vendor { Unknown, @@ -306,6 +307,7 @@ pub enum Vendor { Sun, Uwp, Wrs, + Custom(String), } /// The "operating system" field, which sometimes implies an environment, and @@ -717,6 +719,7 @@ impl fmt::Display for Vendor { Vendor::Sun => "sun", Vendor::Uwp => "uwp", Vendor::Wrs => "wrs", + Vendor::Custom(ref name) => name, }; f.write_str(s) } @@ -738,7 +741,20 @@ impl FromStr for Vendor { "sun" => Vendor::Sun, "uwp" => Vendor::Uwp, "wrs" => Vendor::Wrs, - _ => return Err(()), + custom => { + use alloc::borrow::ToOwned; + if Architecture::from_str(custom).is_ok() + || OperatingSystem::from_str(custom).is_ok() + || Environment::from_str(custom).is_ok() + || BinaryFormat::from_str(custom).is_ok() + { + return Err(()); + } + if custom.find(|c: char| !c.is_ascii_alphanumeric() && c != '_' && c != '.').is_some() { + return Err(()); + } + Vendor::Custom(custom.to_owned()) + } }) } } target-lexicon-0.10.0/host.rs010066400017510001751000000027741356467467700143300ustar0000000000000000#[allow(unused_imports)] use crate::Aarch64Architecture::*; #[allow(unused_imports)] use crate::ArmArchitecture::*; #[allow(unused_imports)] use crate::CustomVendor; /// The `Triple` of the current host. pub const HOST: Triple = Triple { architecture: Architecture::Aarch64(Aarch64), vendor: Vendor::Unknown, operating_system: OperatingSystem::Linux, environment: Environment::Gnu, binary_format: BinaryFormat::Elf, }; impl Architecture { /// Return the architecture for the current host. pub const fn host() -> Self { Architecture::Aarch64(Aarch64) } } impl Vendor { /// Return the vendor for the current host. pub const fn host() -> Self { Vendor::Unknown } } impl OperatingSystem { /// Return the operating system for the current host. pub const fn host() -> Self { OperatingSystem::Linux } } impl Environment { /// Return the environment for the current host. pub const fn host() -> Self { Environment::Gnu } } impl BinaryFormat { /// Return the binary format for the current host. pub const fn host() -> Self { BinaryFormat::Elf } } impl Triple { /// Return the triple for the current host. pub const fn host() -> Self { Self { architecture: Architecture::Aarch64(Aarch64), vendor: Vendor::Unknown, operating_system: OperatingSystem::Linux, environment: Environment::Gnu, binary_format: BinaryFormat::Elf, } } } target-lexicon-0.10.0/newlist010077500017510001751000000003241350040664500143570ustar0000000000000000#!/bin/bash set -euo pipefail rustup target list | sed 's/ (.*//' > list.txt rustc +nightly --print target-list >> list.txt cat list.txt | sort | uniq |sed 's/\(.*\)/ "\1",/' > sorted.txt rm list.txt target-lexicon-0.10.0/sorted.txt010066400017510001751000000127301356467471700150320ustar0000000000000000 "aarch64-apple-ios", "aarch64-fuchsia", "aarch64-linux-android", "aarch64-pc-windows-msvc", "aarch64-unknown-cloudabi", "aarch64-unknown-freebsd", "aarch64-unknown-hermit", "aarch64-unknown-linux-gnu", "aarch64-unknown-linux-musl", "aarch64-unknown-netbsd", "aarch64-unknown-none", "aarch64-unknown-none-softfloat", "aarch64-unknown-openbsd", "aarch64-unknown-redox", "aarch64-uwp-windows-msvc", "aarch64-wrs-vxworks", "armebv7r-none-eabi", "armebv7r-none-eabihf", "arm-linux-androideabi", "arm-unknown-linux-gnueabi", "arm-unknown-linux-gnueabihf", "arm-unknown-linux-musleabi", "arm-unknown-linux-musleabihf", "armv4t-unknown-linux-gnueabi", "armv5te-unknown-linux-gnueabi", "armv5te-unknown-linux-musleabi", "armv6-unknown-freebsd", "armv6-unknown-netbsd-eabihf", "armv7-apple-ios", "armv7-linux-androideabi", "armv7r-none-eabi", "armv7r-none-eabihf", "armv7s-apple-ios", "armv7-unknown-cloudabi-eabihf", "armv7-unknown-freebsd", "armv7-unknown-linux-gnueabi", "armv7-unknown-linux-gnueabihf", "armv7-unknown-linux-musleabi", "armv7-unknown-linux-musleabihf", "armv7-unknown-netbsd-eabihf", "armv7-wrs-vxworks-eabihf", "asmjs-unknown-emscripten", "hexagon-unknown-linux-musl", "i386-apple-ios", "i586-pc-windows-msvc", "i586-unknown-linux-gnu", "i586-unknown-linux-musl", "i686-apple-darwin", "i686-linux-android", "i686-pc-windows-gnu", "i686-pc-windows-msvc", "i686-unknown-cloudabi", "i686-unknown-dragonfly", "i686-unknown-freebsd", "i686-unknown-haiku", "i686-unknown-linux-gnu", "i686-unknown-linux-musl", "i686-unknown-netbsd", "i686-unknown-openbsd", "i686-unknown-uefi", "i686-uwp-windows-gnu", "i686-uwp-windows-msvc", "i686-wrs-vxworks", "mips64el-unknown-linux-gnuabi64", "mips64el-unknown-linux-muslabi64", "mips64-unknown-linux-gnuabi64", "mips64-unknown-linux-muslabi64", "mipsel-unknown-linux-gnu", "mipsel-unknown-linux-musl", "mipsel-unknown-linux-uclibc", "mipsisa32r6el-unknown-linux-gnu", "mipsisa32r6-unknown-linux-gnu", "mipsisa64r6el-unknown-linux-gnuabi64", "mipsisa64r6-unknown-linux-gnuabi64", "mips-unknown-linux-gnu", "mips-unknown-linux-musl", "mips-unknown-linux-uclibc", "msp430-none-elf", "nvptx64-nvidia-cuda", "powerpc64le-unknown-linux-gnu", "powerpc64le-unknown-linux-musl", "powerpc64-unknown-freebsd", "powerpc64-unknown-linux-gnu", "powerpc64-unknown-linux-musl", "powerpc64-wrs-vxworks", "powerpc-unknown-linux-gnu", "powerpc-unknown-linux-gnuspe", "powerpc-unknown-linux-musl", "powerpc-unknown-netbsd", "powerpc-wrs-vxworks", "powerpc-wrs-vxworks-spe", "riscv32imac-unknown-none-elf", "riscv32imc-unknown-none-elf", "riscv32i-unknown-none-elf", "riscv64gc-unknown-none-elf", "riscv64imac-unknown-none-elf", "s390x-unknown-linux-gnu", "sparc64-unknown-linux-gnu", "sparc64-unknown-netbsd", "sparc64-unknown-openbsd", "sparc-unknown-linux-gnu", "sparcv9-sun-solaris", "thumbv6m-none-eabi", "thumbv7a-pc-windows-msvc", "thumbv7em-none-eabi", "thumbv7em-none-eabihf", "thumbv7m-none-eabi", "thumbv7neon-linux-androideabi", "thumbv7neon-unknown-linux-gnueabihf", "thumbv7neon-unknown-linux-musleabihf", "thumbv8m.base-none-eabi", "thumbv8m.main-none-eabi", "thumbv8m.main-none-eabihf", "wasm32-unknown-emscripten", "wasm32-unknown-unknown", "wasm32-wasi", "x86_64-apple-darwin", "x86_64-apple-ios", "x86_64-fortanix-unknown-sgx", "x86_64-fuchsia", "x86_64-linux-android", "x86_64-linux-kernel", "x86_64-pc-solaris", "x86_64-pc-windows-gnu", "x86_64-pc-windows-msvc", "x86_64-rumprun-netbsd", "x86_64-sun-solaris", "x86_64-unknown-cloudabi", "x86_64-unknown-dragonfly", "x86_64-unknown-freebsd", "x86_64-unknown-haiku", "x86_64-unknown-hermit", "x86_64-unknown-l4re-uclibc", "x86_64-unknown-linux-gnu", "x86_64-unknown-linux-gnux32", "x86_64-unknown-linux-musl", "x86_64-unknown-netbsd", "x86_64-unknown-openbsd", "x86_64-unknown-redox", "x86_64-unknown-uefi", "x86_64-uwp-windows-gnu", "x86_64-uwp-windows-msvc", "x86_64-wrs-vxworks", target-lexicon-0.10.0/test.sh010077500017510001751000000005571356467467300143140ustar0000000000000000#!/bin/bash set -oeu pipefail cargo clean for trip in wasm32-unknown-unknown wasm32-wasi arm-unknown-linux-gnueabi aarch64-unknown-linux-gnu; do echo TARGET $trip cargo build --target $trip --all cp target/$trip/debug/build/target-lexicon-*/out/host.rs host.rs rustfmt host.rs diff -u target/$trip/debug/build/target-lexicon-*/out/host.rs host.rs done target-lexicon-0.10.0/Cargo.lock0000644000000002230000000000000120460ustar00# This file is automatically @generated by Cargo. # It is not intended for manual editing. [[package]] name = "target-lexicon" version = "0.10.0"