From: Ian Jackson Date: Sat, 7 Aug 2021 19:40:37 +0000 (+0100) Subject: ini: wip new module X-Git-Tag: hippotat/1.0.0~262 X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ian/git?a=commitdiff_plain;h=20425df4a7b0e15c659a09a6492a0f99079350b8;p=hippotat.git ini: wip new module Signed-off-by: Ian Jackson --- diff --git a/src/ini.rs b/src/ini.rs new file mode 100644 index 0000000..a8c9558 --- /dev/null +++ b/src/ini.rs @@ -0,0 +1,94 @@ +// Copyright 2021 Ian Jackson and contributors to Hippotat +// SPDX-License-Identifier: GPL-3.0-or-later +// There is NO WARRANTY. + +pub struct Loc { + pub file: Arc, + pub line: usize, + pub section: Option>, +} + +#[derive(Debug,Clone)] +pub struct RawVal { + pub raw: String, + pub loc: Loc, +} + +pub type Parsed = HashMap, Section>; + +pub struct Section { + /// Location of first encounter + pub loc: Loc, + pub values: HashMap, +} + +impl Display for Loc { + #[throws(fmt::Error)] + fn fmt(&self, f: &mut fmt::Formatter) { + write!(f, "{}:{}", &self.file, self.line)?; + if let Some(s) = &self.section { + let dbg = format!("{:?}", &m); + if let Some(mid) = (||{ + let mid = dbg.strip_prefix(r#"""#)?; + let mid = mid.strip_suffix(r#"""#)?; + Some(mid) + })() { + write!(f, "[{}]", mid)?; + } else { + write!(f, "{}", dbg)?; + } + } + } +} + +#[throws(AE)] +pub fn read(parsed: &mut Parsed, file: &dyn BufRead, path_for_loc: &Path) { + let path = path_for_loc.to_owned().into(); + let section: Option<&mut Section> = None; + for (lno, line) in file.lines().enumerate() { + let line = line.context("read")?; + (||{ + let line = line.trim(); + + if line.is_empty() { continue } + if regex_is_match!(r#"^ [;#] "#x, line) { continue } + + let mut loc = Loc { + line, + file: path.clone(), + section: section.as_ref().map(|s| s.section.clone()), + }; + + if let Some((_,section,)) = + regex_captures!(r#"^ \[ \s* (.+?) \s* \] $"#x, line) + { + let sname = Some(section.to_owned().into()); + section = Some(parsed.entry(sname.clone()) + .get_or_insert_with(|| { + Section { + loc: Loc { section: sname, ..loc }, + values: default(), + } + })); + continue; + } + + if let Some((_,k,v)) = + regex_captures!(r#"^ ( [^\[] .*? ) \s* = \s* (.*) $"#, line) + { + section.values.insert(k.into(), RawVal { + loc, + raw: v.into(), + }); + continue; + } + + throw!(if line.starts_with("[") { + anyhow!(r#"syntax error (section missing final "]"?)"#) + } else { + anyhow!(r#"syntax error (setting missing "="?)"#) + }) + + })().with_context(|| loc().to_string())? + } +} diff --git a/src/lib.rs b/src/lib.rs index 7f5a854..1327974 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -12,3 +12,5 @@ pub mod reporter; pub mod queue; pub mod types; pub mod utils; + +//mod ini;