aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMelody Horn <melody@boringcactus.com>2021-04-01 23:10:10 -0600
committerMelody Horn <melody@boringcactus.com>2021-04-01 23:10:10 -0600
commitd12f9f563968ea8471b4929936ac4f8553810428 (patch)
tree39f8f42eb840c32acb542bfc6314e2950e1e17e0
parent543124c62c8123bd67e90bbc710aa064c6c5e271 (diff)
downloadmakers-d12f9f563968ea8471b4929936ac4f8553810428.tar.gz
makers-d12f9f563968ea8471b4929936ac4f8553810428.zip
put extensions behind a feature
-rw-r--r--Cargo.toml8
-rw-r--r--README.md1
-rw-r--r--src/makefile/macro.rs4
-rw-r--r--src/makefile/mod.rs19
-rw-r--r--src/makefile/token.rs37
5 files changed, 51 insertions, 18 deletions
diff --git a/Cargo.toml b/Cargo.toml
index 41f2334..c76af6b 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -10,10 +10,14 @@ license-file = "LICENSE.md"
keywords = ["build", "make"]
categories = ["development-tools"]
+[features]
+default = ['full']
+full = ['dirs', 'glob']
+
[dependencies]
-dirs = "3.0.1"
+dirs = { version = "3.0.1", optional = true }
eyre = "0.6.5"
-glob = "0.3.0"
+glob = { version = "0.3.0", optional = true }
jane-eyre = "0.3.0"
lazy_static = "1.4.0"
nom = "6.1.2"
diff --git a/README.md b/README.md
index cce00fb..141021d 100644
--- a/README.md
+++ b/README.md
@@ -11,6 +11,7 @@ Not explicitly aiming for full support for [every GNU make feature](https://www.
- library handling not implemented
- some POSIX-specified features are pending (search `TODO` for a list)
- builtin macro `MAKE` is defined as `makers`
+- specifying the `.POSIX` special target doesn't opt out of extensions (but you can install with `--no-default-features` to get only POSIX behavior)
## status
diff --git a/src/makefile/macro.rs b/src/makefile/macro.rs
index e760282..bb4a72d 100644
--- a/src/makefile/macro.rs
+++ b/src/makefile/macro.rs
@@ -5,6 +5,7 @@ use std::fmt;
use eyre::{bail, Result, WrapErr};
use regex::Regex;
+#[cfg(feature = "full")]
use super::functions;
use super::token::{Token, TokenString};
@@ -71,6 +72,7 @@ impl<'parent, 'lookup> Set<'parent, 'lookup> {
self.data.insert(name, (source, text));
}
+ #[cfg(feature = "full")]
pub fn is_defined(&self, name: &str) -> bool {
self.data.contains_key(name)
}
@@ -113,6 +115,7 @@ impl<'parent, 'lookup> Set<'parent, 'lookup> {
};
result.push_str(&macro_value);
}
+ #[cfg(feature = "full")]
Token::FunctionCall { name, args } => {
result.push_str(&functions::expand_call(name, args, self)?);
}
@@ -129,6 +132,7 @@ impl<'parent, 'lookup> Set<'parent, 'lookup> {
}
}
+ #[cfg(feature = "full")]
pub fn with_overlay<'s>(&'s self) -> Set<'s, 'lookup> {
Set {
parent: Some(self),
diff --git a/src/makefile/mod.rs b/src/makefile/mod.rs
index 5be18e0..9038150 100644
--- a/src/makefile/mod.rs
+++ b/src/makefile/mod.rs
@@ -15,15 +15,19 @@ use regex::Regex;
use crate::args::Args;
mod command_line;
+#[cfg(feature = "full")]
mod conditional;
+#[cfg(feature = "full")]
mod functions;
mod inference_rules;
mod r#macro;
+#[cfg(feature = "full")]
mod pattern;
mod target;
mod token;
use command_line::CommandLine;
+#[cfg(feature = "full")]
use conditional::{Line as ConditionalLine, State as ConditionalState};
use inference_rules::InferenceRule;
use r#macro::{Set as MacroSet, Source as MacroSource};
@@ -154,6 +158,7 @@ impl<'a> Makefile<'a> {
)
})
.peekable();
+ #[cfg(feature = "full")]
let mut conditional_stack: Vec<ConditionalState> = vec![];
while let Some((line_number, line)) = lines_iter.next() {
let mut line = line?;
@@ -174,6 +179,7 @@ impl<'a> Makefile<'a> {
let line = COMMENT.replace(&line, "").into_owned();
// skip lines if we need to
+ #[cfg(feature = "full")]
if conditional_stack
.last()
.map_or(false, ConditionalState::skipping)
@@ -192,16 +198,20 @@ impl<'a> Makefile<'a> {
for field in fields {
self.and_read_file(field)?;
}
- } else if let Some(line) =
- ConditionalLine::from(&line, |t| self.expand_macros(t, None))?
- {
+ continue;
+ }
+
+ #[cfg(feature = "full")]
+ if let Some(line) = ConditionalLine::from(&line, |t| self.expand_macros(t, None))? {
line.action(
conditional_stack.last(),
|name| self.macros.is_defined(name),
|t| self.expand_macros(t, None),
)?
.apply_to(&mut conditional_stack);
- } else if line.trim().is_empty() {
+ continue;
+ }
+ if line.trim().is_empty() {
// handle blank lines
continue;
} else {
@@ -711,6 +721,7 @@ mod test {
}
}
+ #[cfg(feature = "full")]
#[test]
fn basic_conditionals() -> R {
let file = "
diff --git a/src/makefile/token.rs b/src/makefile/token.rs
index 60cffe0..8bd0179 100644
--- a/src/makefile/token.rs
+++ b/src/makefile/token.rs
@@ -5,13 +5,15 @@ use eyre::WrapErr;
use nom::{
branch::alt,
bytes::complete::{tag, take_till1, take_while1},
- character::complete::{anychar, space1},
+ character::complete::anychar,
combinator::{all_consuming, map, opt, verify},
error::{context, convert_error, ContextError, ParseError, VerboseError},
- multi::{many1, separated_list1},
+ multi::many1,
sequence::{delimited, pair, preceded, separated_pair},
Finish, IResult,
};
+#[cfg(feature = "full")]
+use nom::{character::complete::space1, multi::separated_list1};
trait Err<'a>: 'a + ParseError<&'a str> + ContextError<&'a str> {}
impl<'a, T: 'a + ParseError<&'a str> + ContextError<&'a str>> Err<'a> for T {}
@@ -25,6 +27,7 @@ impl TokenString {
Self(vec![Token::Text(text.into())])
}
+ #[cfg(feature = "full")]
pub fn r#macro(name: impl Into<String>) -> Self {
Self(vec![Token::MacroExpansion {
name: name.into(),
@@ -60,6 +63,7 @@ impl TokenString {
None
}
+ #[cfg(feature = "full")]
pub fn starts_with(&self, pattern: &str) -> bool {
match self.0.first() {
Some(Token::Text(t)) => t.starts_with(pattern),
@@ -74,6 +78,7 @@ impl TokenString {
}
}
+ #[cfg(feature = "full")]
pub fn strip_prefix(&mut self, suffix: &str) {
if let Some(Token::Text(t)) = self.0.first_mut() {
if let Some(x) = t.strip_prefix(suffix) {
@@ -100,6 +105,7 @@ impl TokenString {
}
}
+ #[cfg(feature = "full")]
pub fn trim_end(&mut self) {
if let Some(Token::Text(t)) = self.0.last_mut() {
*t = t.trim_end().into();
@@ -123,6 +129,7 @@ pub enum Token {
name: String,
replacement: Option<(TokenString, TokenString)>,
},
+ #[cfg(feature = "full")]
FunctionCall {
name: String,
args: Vec<TokenString>,
@@ -141,6 +148,7 @@ impl fmt::Display for Token {
name,
replacement: Some((r1, r2)),
} => write!(f, "$({}:{}={})", name, r1, r2),
+ #[cfg(feature = "full")]
Self::FunctionCall { name, args } => write!(
f,
"$({} {})",
@@ -183,6 +191,7 @@ fn macro_expansion_body<'a, E: Err<'a>>(
)
}
+#[cfg(feature = "full")]
fn function_call_body<'a, E: Err<'a>>(
end: char,
) -> impl FnMut(&'a str) -> IResult<&'a str, Token, E> {
@@ -202,20 +211,22 @@ fn function_call_body<'a, E: Err<'a>>(
)
}
+#[cfg(feature = "full")]
+fn macro_body<'a, E: Err<'a>>(end: char) -> impl FnMut(&'a str) -> IResult<&'a str, Token, E> {
+ alt((function_call_body(end), macro_expansion_body(end)))
+}
+
+#[cfg(not(feature = "full"))]
+fn macro_body<'a, E: Err<'a>>(end: char) -> impl FnMut(&'a str) -> IResult<&'a str, Token, E> {
+ macro_expansion_body(end)
+}
+
fn parens_macro_expansion<'a, E: Err<'a>>(input: &'a str) -> IResult<&'a str, Token, E> {
- delimited(
- tag("$("),
- alt((function_call_body(')'), macro_expansion_body(')'))),
- tag(")"),
- )(input)
+ delimited(tag("$("), macro_body(')'), tag(")"))(input)
}
fn braces_macro_expansion<'a, E: Err<'a>>(input: &'a str) -> IResult<&'a str, Token, E> {
- delimited(
- tag("${"),
- alt((function_call_body('}'), macro_expansion_body('}'))),
- tag("}"),
- )(input)
+ delimited(tag("${"), macro_body('}'), tag("}"))(input)
}
fn tiny_macro_expansion<'a, E: Err<'a>>(input: &'a str) -> IResult<&'a str, Token, E> {
@@ -328,6 +339,7 @@ mod test {
}
}
+ #[cfg(feature = "full")]
fn token_function_call(name: impl Into<String>, args: Vec<impl Into<TokenString>>) -> Token {
Token::FunctionCall {
name: name.into(),
@@ -430,6 +442,7 @@ mod test {
Ok(())
}
+ #[cfg(feature = "full")]
#[test]
fn function_hell() -> R {
let text = "$(foo bar, $(baz))";