Skip to content

Commit

Permalink
Merge branch 'master' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
madonuko authored Jun 28, 2024
2 parents 156f516 + 589b5b2 commit f117e04
Show file tree
Hide file tree
Showing 9 changed files with 72 additions and 52 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
name = "rpmspec"
description = "An RPM spec file parser"
version = "0.4.0"
authors = ["Fyra Labs <[email protected]>"]
authors = ["Fyra Labs <[email protected]>", "madonuko <[email protected]>"]
readme = "README.md"
repository = "https://github.com/rpm-rs/rpmspec-rs"
keywords = ["rpmspec", "rpm", "packaging"]
Expand Down
7 changes: 4 additions & 3 deletions rpmexpr/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@
name = "rpmexpr"
description = "A parser for %[RPM expressions]"
version = "0.1.0"
edition = "2021"
authors = ["Fyra Labs <[email protected]>"]
authors = ["Fyra Labs <[email protected]>", "madonuko <[email protected]>"]
readme = "README.md"
repository = "https://github.com/rpm-rs/rpmspec-rs"
keywords = ["rpmspec", "rpm", "packaging"]
categories = ["parser-implementations", "parsing"]
edition = "2021"
license = "MIT"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
Expand All @@ -15,7 +16,7 @@ license = "MIT"
chumsky = "0.9.2"
# color-eyre = "0.6.2"
parking_lot = "0.12.1"
rpmspec-common = { path = "../rpmspec-common" }
rpmspec-common = { version = "0.1.0", path = "../rpmspec-common" }
smartstring = "1.0.1"
thiserror = "1.0.50"

3 changes: 3 additions & 0 deletions rpmexpr/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# rpmexpr

This is an library for parsing `%["rpm expressions"]`, designed to be used with the `rpmspec` crate.
7 changes: 7 additions & 0 deletions rpmspec-common/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
[package]
name = "rpmspec-common"
description = "Helper structs and functions for the rpmspec/rpmexpr crate"
version = "0.1.0"
authors = ["Fyra Labs <[email protected]>", "madonuko <[email protected]>"]
readme = "README.md"
repository = "https://github.com/rpm-rs/rpmspec-rs"
keywords = ["rpmspec", "rpm", "packaging"]
categories = ["parser-implementations", "parsing"]
edition = "2021"
license = "MIT"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

Expand Down
5 changes: 5 additions & 0 deletions rpmspec-common/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# rpmspec-common

This library contains utility structs, functions, etc. for the `rpmexpr` and `rpmspec` crates.

Therefore, you are not supposed to directly list this crate as a dependency in your project.
5 changes: 3 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
//! defined in the spec files and various other files in the macros directory.
//! They are also picked up from ~/.rpmrc and /etc/rpmrc.
//!
//! To get started, see [`SpecParser::parse()`].
#![warn(clippy::disallowed_types)]
#![warn(missing_docs)]
#![warn(clippy::complexity)]
Expand All @@ -33,11 +34,11 @@
#![allow(clippy::blanket_clippy_restriction_lints)]
#![allow(clippy::pattern_type_mismatch)]

pub mod parse;
pub mod lua;
pub mod macros;
pub mod parse;

pub use parse::RPMSpec;
pub use parse::{RPMSpec, SpecParser};
pub use rpmspec_common::{error, util};

pub(crate) mod macrohelpers;
Expand Down
80 changes: 40 additions & 40 deletions src/macrohelpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,48 +129,48 @@ macro_rules! preamble_maker {
macro_rules! gen_render_pop {
($dollar:tt$spec:ident$self:ident) => {
macro_rules! render_pop {
(@self) => {$self};
(@self $a:ident) => {$a};
($preamble:expr, $val:expr) => {{
let preamble = $preamble;
let padding = 14 - preamble.len();
write!($spec, "{preamble}:{}{}\n", " ".repeat(padding), $val).unwrap();
}};
($preamble:expr => $dollar(~$cur:ident.)?$attr:ident) => {{
if let Some(val) = &render_pop!(@self $dollar($cur)?).$attr {
render_pop!($preamble, val);
}
}};
($preamble:expr => $dollar(~$cur:ident.)?$attr:ident or $default:expr) => {{
render_pop!($preamble, render_pop!(@self $dollar($cur)?).$attr.as_ref().map_or($default, |s| s));
(@self) => {$self};
(@self $a:ident) => {$a};
($preamble:expr, $val:expr) => {{
let preamble = $preamble;
let padding = 14 - preamble.len();
write!($spec, "{preamble}:{}{}\n", " ".repeat(padding), $val).unwrap();
}};
($preamble:expr => $dollar(~$cur:ident.)?$attr:ident) => {{
if let Some(val) = &render_pop!(@self $dollar($cur)?).$attr {
render_pop!($preamble, val);
}
}};
($preamble:expr => $dollar(~$cur:ident.)?$attr:ident or $default:expr) => {{
render_pop!($preamble, render_pop!(@self $dollar($cur)?).$attr.as_ref().map_or($default, |s| s));
}};
($preamble:expr => ..$dollar(~$cur:ident.)?$attr:ident) => {{
if !render_pop!(@self $dollar($cur)?).$attr.is_empty() {
render_pop!($preamble, &render_pop!(@self $dollar($cur)?).$attr.iter().map(|pkg| Box::new(lzf!("{pkg}"))).join(" "));
}
}};
($preamble:ident: $dollar($x:tt)*) => {
render_pop!(stringify!($preamble) => $dollar($x)*);
};
($preamble:expr => $b:block) => {{
render_pop!($preamble, $b);
}};
(@use) => { "" };
(@use $subpackage:expr, $header:expr) => { $header:expr };
(@in $scriptlets:ident $dollar(for $header:expr)?) => {
render_pop!(%(pre post preun postun pretrans posttrans verify triggerprein triggerin triggerun triggerpostun filetriggerin filetriggerun filetriggerpostun transfiletriggerin transfiletriggerun transfiletriggerpostun) in $scriptlets $dollar(for $header)?);
};
(@header) => { "" };
(@header $header:expr) => { lzf!(" {}", $header) };
(%($dollar($section:ident)*) in $scriptlets:ident $dollar(for $header:expr)?) => {
// we need this because rust doesn't support macro nesting with $()? inside $()*
let header = render_pop!(@header $dollar($header)?);
$dollar(
if let Some(s) = &$scriptlets.$section {
write!($spec, "\n\n%{}{header}\n{s}", stringify!($section)).unwrap();
}
)*
};
if !render_pop!(@self $dollar($cur)?).$attr.is_empty() {
render_pop!($preamble, &render_pop!(@self $dollar($cur)?).$attr.iter().map(|pkg| Box::new(lzf!("{pkg}"))).join(" "));
}
}};
($preamble:ident: $dollar($x:tt)*) => {
render_pop!(stringify!($preamble) => $dollar($x)*);
};
($preamble:expr => $b:block) => {{
render_pop!($preamble, $b);
}};
(@use) => { "" };
(@use $subpackage:expr, $header:expr) => { $header:expr };
(@in $scriptlets:ident $dollar(for $header:expr)?) => {
render_pop!(%(pre post preun postun pretrans posttrans verify triggerprein triggerin triggerun triggerpostun filetriggerin filetriggerun filetriggerpostun transfiletriggerin transfiletriggerun transfiletriggerpostun) in $scriptlets $dollar(for $header)?);
};
(@header) => { "" };
(@header $header:expr) => { lzf!(" {}", $header) };
(%($dollar($section:ident)*) in $scriptlets:ident $dollar(for $header:expr)?) => {
// we need this because rust doesn't support macro nesting with $()? inside $()*
let header = render_pop!(@header $dollar($header)?);
$dollar(
if let Some(s) = &$scriptlets.$section {
write!($spec, "\n\n%{}{header}\n{s}", stringify!($section)).unwrap();
}
)*
};
}
};
}
Expand Down
2 changes: 1 addition & 1 deletion src/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ __internal_macros!(
let content = content.lines().map(|line| line.trim_end().trim_end_matches('\\')).join("\n");
let parser = Arc::new(RwLock::new(std::mem::take(p)));
let out = crate::lua::run(&parser, &content)?;
std::mem::swap(p, &mut Arc::try_unwrap(parser).expect("Cannot unwrap Arc for print() output in lua").into_inner()); // break down Arc then break down RwLock
std::mem::swap(p, &mut Arc::try_unwrap(parser).expect("cannot unwrap Arc rpmparser in %lua").into_inner());
o.push_str(&out);
Ok(())
}
Expand Down
13 changes: 8 additions & 5 deletions src/parse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1392,7 +1392,7 @@ impl SpecParser {
Ok(true)
}

/// Loads all macros defined in a file.
/// Load and parse all macros defined in a macro definition file.
///
/// # Errors
/// - [`io::Error`] when it fails open/read the file
Expand Down Expand Up @@ -1432,7 +1432,11 @@ impl SpecParser {
csm.skip_til_eot()?; // eot is end of definition
trace!(pos = csm.pos, "finished parsing macro definition");
trace!(?name, "Insert macro");
let m = MacroType::Runtime { file: Arc::clone(&csm.file), s: Arc::clone(&csm.s), param, offset, len: csm.pos - offset };
let len = csm.pos - offset - 1;
// ^^^^^^^ (start) ┬
// (end) │
// we also need to remove the new line char
let m = MacroType::Runtime { file: Arc::clone(&csm.file), s: Arc::clone(&csm.s), param, offset, len };
if let Some(v) = self.macros.get_mut(&name) {
v.push(m);
continue;
Expand Down Expand Up @@ -1460,12 +1464,11 @@ impl SpecParser {
/// macros with the same name, and when you undefine it the old one recovers (stack?). I don't think
/// it is a good idea to do it like that (it is simply ridiculous and inefficient) but you can try.
pub fn load_macros(&mut self) -> ParseResult<()> {
// run rpm --showrc | grep "^Macro path"
// TODO: don't use rpm because that's cheating
let binding = Command::new("sh").args(["-c", "rpm --showrc|grep '^Macro path'|sed 's/Macro path: //'"]).output()?;
let binding = core::str::from_utf8(&binding.stdout)?;
let paths = binding.trim().split(':');

// TODO: use Consumer::read_til_EOL() instead
for path in paths {
let path = path.replace("%{_target}", ARCH);
debug!(": {path}");
Expand Down Expand Up @@ -1746,7 +1749,7 @@ impl SpecParser {
} else if ["Source", "Patch"].contains(&&cap[1]) {
self.add_list_preamble(&cap[1], 0, &cap[2])?;
} else {
let offset = consumer.pos - cap[2].len();
let offset = consumer.pos - cap[2].len() - 1;
self.add_preamble(&cap[1], cap[2].into(), offset, &mut consumer)?;
}
},
Expand Down

0 comments on commit f117e04

Please sign in to comment.