chiark / gitweb /
ini: wip new module
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Sat, 7 Aug 2021 19:40:37 +0000 (20:40 +0100)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Sat, 7 Aug 2021 19:40:37 +0000 (20:40 +0100)
Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
src/ini.rs [new file with mode: 0644]
src/lib.rs

diff --git a/src/ini.rs b/src/ini.rs
new file mode 100644 (file)
index 0000000..a8c9558
--- /dev/null
@@ -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<PathBuf>,
+  pub line: usize,
+  pub section: Option<Arc<String>>,
+}
+
+#[derive(Debug,Clone)]
+pub struct RawVal {
+  pub raw: String,
+  pub loc: Loc,
+}
+
+pub type Parsed = HashMap<Arc<String>, Section>;
+
+pub struct Section {
+  /// Location of first encounter
+  pub loc: Loc,
+  pub values: HashMap<String, RawVal>,
+}
+
+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())?
+  }
+}
index 7f5a854bb4c673bc56f177e8a515ebe451f1bb61..1327974c7ae46f96d9257597ce949c92a392cd6a 100644 (file)
@@ -12,3 +12,5 @@ pub mod reporter;
 pub mod queue;
 pub mod types;
 pub mod utils;
+
+//mod ini;