Skip to content

Commit

Permalink
Merge pull request #9 from EmbarkStudios/update
Browse files Browse the repository at this point in the history
Various components of target triples such as environment, vendor, and operating system can be specified externally from rustc via custom targets. This change allows cfg-expr to still evaluate those custom targets, as before they would not be parsed due to them being closed sets of only the builtin targets of rustc.

This also adds optional support for the target-lexicon crate (behind the targets feature flag) so that more targets than the builtin ones can be more easily evaluated against an expression.
  • Loading branch information
Jake-Shadle authored Jun 4, 2020
2 parents 4977846 + ac67f1f commit fe6fd99
Show file tree
Hide file tree
Showing 16 changed files with 681 additions and 322 deletions.
48 changes: 31 additions & 17 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,12 @@ jobs:
uses: actions-rs/cargo@v1
with:
command: clippy
args: --lib --tests -- -D warnings
args: --all-targets -- -D warnings
- name: cargo clippy all-features
uses: actions-rs/cargo@v1
with:
command: clippy
args: --all-targets --all-features -- -D warnings

test:
name: Test
Expand Down Expand Up @@ -58,33 +63,42 @@ jobs:
with:
command: test
args: --release
- name: cargo test build all-features
uses: actions-rs/cargo@v1
with:
command: build
args: --tests --release --all-features
- name: cargo test all-features
uses: actions-rs/cargo@v1
with:
command: test
args: --release --all-features

deny-check:
name: cargo-deny
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- uses: EmbarkStudios/cargo-deny-action@v0
- uses: EmbarkStudios/cargo-deny-action@v1

publish-check:
name: Publish Check
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- uses: actions-rs/toolchain@v1
with:
toolchain: stable
override: true
- name: cargo fetch
uses: actions-rs/cargo@v1
with:
command: fetch
- name: cargo publish check
uses: actions-rs/cargo@v1
with:
command: publish
args: --dry-run

- uses: actions/checkout@v1
- uses: actions-rs/toolchain@v1
with:
toolchain: stable
override: true
- name: cargo fetch
uses: actions-rs/cargo@v1
with:
command: fetch
- name: cargo publish check
uses: actions-rs/cargo@v1
with:
command: publish
args: --dry-run
# Remove this job if you don't publish the crate(s) from this repo
# You must add a crates.io API token to your GH secrets called CRATES_IO_TOKEN
# publish:
Expand Down
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

<!-- next-header -->
## [Unreleased] - ReleaseDate
### Added
- [PR#9](https://github.com/EmbarkStudios/cfg-expr/pull/9) added the optional `targets` feature, which allows matching the various `target_` predicates against a [`target_lexicon::Triple`](https://docs.rs/target-lexicon/0.11.0/target_lexicon/struct.Triple.html).

### Changed
- [PR#9](https://github.com/EmbarkStudios/cfg-expr/pull/9) changed the `Arch`, `Vendor`, `Os`, and `Env` types to no be longer enums, and are instead thin wrappers around strings. This allows for custom targets where one or more components of the target triple are not built-in to rustc. Resolved [#8](https://github.com/EmbarkStudios/cfg-expr/issues/8).
- Changed `ParseError` to remove the lifetime and just keep an owned string of the expression that failed to parse.
- Updated the list of built-in rustc targets to 1.43.1.

## [0.3.0] - 2020-04-05
### Changed
- [PR#7](https://github.com/EmbarkStudios/cfg-expr/pull/7) changed `Expression::eval` to take a `Logic` trait, to enable evaluation of 'unknown' predicates. Thanks [@sunshowers](https://github.com/sunshowers)!
Expand Down
9 changes: 7 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,12 @@ homepage = "https://github.com/EmbarkStudios/cfg-expr"
keywords = ["cargo", "rustc", "cfg"]

[dependencies]
smallvec = "1.1.0"
smallvec = "1.4"
target-lexicon = { version = "0.11", optional = true }

[dev-dependencies]
difference = "2.0.0"
difference = "2.0"

[features]
default = []
targets = ["target-lexicon"]
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
[![Contributor Covenant](https://img.shields.io/badge/contributor%20covenant-v1.4%20adopted-ff69b4.svg)](CODE_OF_CONDUCT.md)
[![Embark](https://img.shields.io/badge/embark-open%20source-blueviolet.svg)](https://embark.dev)

A parser and evaluator for Rust `cfg()` expressions. Targets as of [Rust 1.41.0](https://forge.rust-lang.org/release/platform-support.html) are supported.
A parser and evaluator for Rust `cfg()` expressions. Targets as of [Rust 1.43.1](https://forge.rust-lang.org/release/platform-support.html) are supported.

## Alternatives

Expand All @@ -17,7 +17,7 @@ A parser and evaluator for Rust `cfg()` expressions. Targets as of [Rust 1.41.0]
## Usage

```rust
use cfg_expr::{targets::get_target_by_triple, Expression, Predicate};
use cfg_expr::{targets::get_builtin_target_by_triple, Expression, Predicate};

fn main() {
let specific = Expression::parse(
Expand All @@ -38,10 +38,10 @@ fn main() {
.unwrap();

// cfg_expr includes a list of every builtin target in rustc (as of 1.41)
let x86_win = get_target_by_triple("i686-pc-windows-msvc").unwrap();
let x86_pentium_win = get_target_by_triple("i586-pc-windows-msvc").unwrap();
let uwp_win = get_target_by_triple("i686-uwp-windows-msvc").unwrap();
let mac = get_target_by_triple("x86_64-apple-darwin").unwrap();
let x86_win = get_builtin_target_by_triple("i686-pc-windows-msvc").unwrap();
let x86_pentium_win = get_builtin_target_by_triple("i586-pc-windows-msvc").unwrap();
let uwp_win = get_builtin_target_by_triple("i686-uwp-windows-msvc").unwrap();
let mac = get_builtin_target_by_triple("x86_64-apple-darwin").unwrap();

let avail_targ_feats = ["fxsr", "sse", "sse2"];

Expand Down
1 change: 1 addition & 0 deletions deny.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,6 @@ copyleft = "deny"
confidence-threshold = 0.93
allow = [
"Apache-2.0",
"Apache-2.0 WITH LLVM-exception",
"MIT",
]
10 changes: 5 additions & 5 deletions examples/eval.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use cfg_expr::{targets::get_target_by_triple, Expression, Predicate};
use cfg_expr::{targets::get_builtin_target_by_triple, Expression, Predicate};

fn main() {
let specific = Expression::parse(
Expand All @@ -19,10 +19,10 @@ fn main() {
.unwrap();

// cfg_expr includes a list of every builtin target in rustc (as of 1.41)
let x86_win = get_target_by_triple("i686-pc-windows-msvc").unwrap();
let x86_pentium_win = get_target_by_triple("i586-pc-windows-msvc").unwrap();
let uwp_win = get_target_by_triple("i686-uwp-windows-msvc").unwrap();
let mac = get_target_by_triple("x86_64-apple-darwin").unwrap();
let x86_win = get_builtin_target_by_triple("i686-pc-windows-msvc").unwrap();
let x86_pentium_win = get_builtin_target_by_triple("i586-pc-windows-msvc").unwrap();
let uwp_win = get_builtin_target_by_triple("i686-uwp-windows-msvc").unwrap();
let mac = get_builtin_target_by_triple("x86_64-apple-darwin").unwrap();

let avail_targ_feats = ["fxsr", "sse", "sse2"];

Expand Down
20 changes: 12 additions & 8 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ use std::{error::Error, fmt};

/// An error related to parsing of a cfg expression
#[derive(Debug, PartialEq)]
pub struct ParseError<'a> {
pub struct ParseError {
/// The string that was parsed
pub original: &'a str,
pub original: String,
/// The range of characters in the original string that result
/// in this error
pub span: std::ops::Range<usize>,
Expand All @@ -17,7 +17,7 @@ pub struct ParseError<'a> {
pub enum Reason {
/// not() takes exactly 1 predicate, unlike all() and any()
InvalidNot(usize),
/// The characters are not valid in an SDPX license expression
/// The characters are not valid in an cfg expression
InvalidCharacters,
/// An opening parens was unmatched with a closing parens
UnclosedParens,
Expand All @@ -29,18 +29,20 @@ pub enum Reason {
UnopenedQuotes,
/// The expression does not contain any valid terms
Empty,
/// Found an unexpected term, which wasn't one of the
/// expected terms that is listed
/// Found an unexpected term, which wasn't one of the expected terms that
/// is listed
Unexpected(&'static [&'static str]),
/// Failed to parse an integer value
InvalidInteger,
/// The root cfg() may only contain a single predicate
MultipleRootPredicates,
/// An element was not part of the builtin information in rustc
UnknownBuiltin,
}

impl<'a> fmt::Display for ParseError<'a> {
impl fmt::Display for ParseError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(self.original)?;
f.write_str(&self.original)?;
f.write_str("\n")?;

for _ in 0..self.span.start {
Expand Down Expand Up @@ -95,11 +97,12 @@ impl fmt::Display for Reason {
InvalidNot(np) => f.write_fmt(format_args!("not() takes 1 predicate, found {}", np)),
InvalidInteger => f.write_str("invalid integer"),
MultipleRootPredicates => f.write_str("multiple root predicates"),
UnknownBuiltin => f.write_str("unknown built-in"),
}
}
}

impl<'a> Error for ParseError<'a> {
impl Error for ParseError {
fn description(&self) -> &str {
use Reason::*;

Expand All @@ -114,6 +117,7 @@ impl<'a> Error for ParseError<'a> {
InvalidNot(_) => "not() takes 1 predicate",
InvalidInteger => "invalid integer",
MultipleRootPredicates => "multiple root predicates",
UnknownBuiltin => "unknown built-in",
}
}
}
6 changes: 3 additions & 3 deletions src/expr/lexer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ pub struct LexerToken<'a> {
}

impl<'a> Iterator for Lexer<'a> {
type Item = Result<LexerToken<'a>, ParseError<'a>>;
type Item = Result<LexerToken<'a>, ParseError>;

fn next(&mut self) -> Option<Self::Item> {
// Jump over any whitespace, updating `self.inner` and `self.offset` appropriately
Expand Down Expand Up @@ -114,7 +114,7 @@ impl<'a> Iterator for Lexer<'a> {
match self.inner[1..].find('"') {
Some(ind) => Some(Ok(Token::Value(&self.inner[1..=ind]))),
None => Some(Err(ParseError {
original: self.original,
original: self.original.to_owned(),
span: self.offset..self.original.len(),
reason: Reason::UnclosedQuotes,
})),
Expand All @@ -136,7 +136,7 @@ impl<'a> Iterator for Lexer<'a> {
// a Range here, not a RangeInclusive<>
#[allow(clippy::range_plus_one)]
Some(Err(ParseError {
original: self.original,
original: self.original.to_owned(),
span: self.offset..self.offset + 1,
reason: Reason::Unexpected(&["<key>", "all", "any", "not"]),
}))
Expand Down
Loading

0 comments on commit fe6fd99

Please sign in to comment.