Mike Gerwitz

Activist for User Freedom

aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMike Gerwitz <mike.gerwitz@ryansg.com>2020-01-09 10:56:24 -0500
committerMike Gerwitz <mike.gerwitz@ryansg.com>2020-02-25 16:46:27 -0500
commita8726918f7d473948c920f8076584e482ed0b875 (patch)
tree3cfac9fb5f901fefb111e416e70076eb94670e08 /tamer/src/ld/poc.rs
parenta929c8cae49ff5ce667e35878a75d14c6c5c4d4c (diff)
downloadtame-a8726918f7d473948c920f8076584e482ed0b875.tar.gz
tame-a8726918f7d473948c920f8076584e482ed0b875.tar.bz2
tame-a8726918f7d473948c920f8076584e482ed0b875.zip
TAMER: poc: Use xmlo reader
TODO: More information
Diffstat (limited to 'tamer/src/ld/poc.rs')
-rw-r--r--tamer/src/ld/poc.rs169
1 files changed, 44 insertions, 125 deletions
diff --git a/tamer/src/ld/poc.rs b/tamer/src/ld/poc.rs
index 2cf0100..289c63a 100644
--- a/tamer/src/ld/poc.rs
+++ b/tamer/src/ld/poc.rs
@@ -18,16 +18,16 @@
//! **This is a poorly-written proof of concept; do not use!** It has been
//! banished to its own file to try to make that more clear.
+use crate::obj::xmlo::reader::{XmloEvent, XmloReader};
+use crate::sym::{DefaultInterner, Interner};
use fixedbitset::FixedBitSet;
use petgraph::graph::{DiGraph, EdgeIndex, Neighbors, NodeIndex};
use petgraph::visit::{DfsPostOrder, GraphBase, IntoNeighbors, Visitable};
-use quick_xml::events::Event;
-use quick_xml::Reader;
use std::collections::hash_map::{Entry, Iter};
use std::collections::{HashMap, HashSet};
use std::error::Error;
use std::fs;
-use std::io::BufRead;
+use std::io::BufReader;
use std::ops::{Deref, Index};
use std::rc::Rc;
@@ -214,8 +214,9 @@ enum SymEntry {
pub fn main() -> Result<(), Box<dyn Error>> {
let mut pkgs_seen = HashSet::<String>::new();
- let mut fragments = HashMap::<String, String>::new();
+ let mut fragments = HashMap::<&str, String>::new();
let mut depgraph = DepGraph::new();
+ let interner = DefaultInterner::new();
let package_path = std::env::args().nth(1).expect("Missing argument");
let abs_path = fs::canonicalize(package_path).unwrap();
@@ -227,6 +228,7 @@ pub fn main() -> Result<(), Box<dyn Error>> {
&mut pkgs_seen,
&mut fragments,
&mut depgraph,
+ &interner,
)?;
// println!(
@@ -246,11 +248,12 @@ pub fn main() -> Result<(), Box<dyn Error>> {
Ok(())
}
-fn load_xmlo<'a>(
+fn load_xmlo<'a, 'i, I: Interner<'i>>(
path_str: &'a str,
pkgs_seen: &mut HashSet<String>,
- fragments: &mut HashMap<String, String>,
+ fragments: &mut HashMap<&'i str, String>,
depgraph: &mut DepGraph,
+ interner: &'i I,
) -> Result<(), Box<dyn Error>> {
let path = fs::canonicalize(path_str)?;
let path_str = path.to_str().unwrap();
@@ -259,80 +262,44 @@ fn load_xmlo<'a>(
return Ok(());
}
- println!("processing {}", path_str);
-
- let mut found = HashSet::<String>::new();
-
- match Reader::from_file(&path) {
- Ok(mut reader) => loop {
- let mut buf = Vec::new();
-
- // we know that the XML produced by Saxon is valid
- reader.check_end_names(false);
-
- match reader.read_event(&mut buf) {
- Ok(Event::Start(ele)) | Ok(Event::Empty(ele)) => {
- let mut attrs = ele.attributes();
- let mut filtered =
- attrs.with_checks(false).filter_map(Result::ok);
-
- match ele.name() {
- b"preproc:sym-dep" => filtered
- .find(|attr| attr.key == b"name")
- .map(|attr| attr.value)
- .and_then(|mut name| {
- read_deps(&mut reader, depgraph, name.to_mut())
- })
- .ok_or("Missing name"),
-
- b"preproc:sym" => {
- filtered
- .find(|attr| attr.key == b"src")
- .map(|attr| attr.value.to_owned())
- .and_then(|src| {
- let path_str =
- std::str::from_utf8(&src).unwrap();
-
- found.insert(path_str.to_string());
- Some(())
- });
- Ok(())
- }
-
- b"preproc:fragment" => filtered
- .find(|attr| attr.key == b"id")
- .map(|attr| String::from_utf8(attr.value.to_vec()))
- .and_then(|id| {
- let fragment = reader
- .read_text(ele.name(), &mut Vec::new())
- .unwrap_or("".to_string());
-
- fragments.insert(id.unwrap(), fragment);
- Some(())
- })
- .ok_or("Missing fragment id"),
- _ => Ok(()),
- }
- }
- Ok(Event::End(ele)) => {
- match ele.name() {
- // We don't need to read any further than the end of
- // the fragments (symtable, sym-deps, fragments)
- b"preproc:fragments" => break (),
- _ => Ok(()),
- }
+ //println!("processing {}", path_str);
+
+ let mut found = HashSet::<&str>::new();
+
+ let file = fs::File::open(&path)?;
+ let reader = BufReader::new(file);
+ let mut xmlo = XmloReader::new(reader, interner);
+
+ loop {
+ match xmlo.read_event()? {
+ XmloEvent::SymDeps(sym, deps) => {
+ // TODO: API needs to expose whether a symbol is already
+ // known so that we can warn on them
+ //
+ // note: using from_utf8_unchecked here did _not_ improve
+ // performance
+ let sym_node = depgraph.declare(sym);
+
+ for dep_sym in deps {
+ let dep_node = depgraph.declare(dep_sym);
+ depgraph.declare_dep(sym_node, dep_node);
}
- Ok(Event::Eof) => break (),
- Err(e) => {
- panic!("Error at {}: {:?}", reader.buffer_position(), e);
+ }
+
+ XmloEvent::SymDecl(_sym, attrs) => {
+ if let Some(sym_src) = attrs.src {
+ found.insert(sym_src);
}
- _ => Ok(()),
}
- .unwrap_or_else(|r| panic!("Parse error: {:?}", r));
- buf.clear();
- },
- Err(e) => panic!("Error {:?}", e),
+ XmloEvent::Fragment(sym, text) => {
+ fragments.insert(sym, text);
+ }
+
+ // We don't need to read any further than the end of the
+ // header (symtable, sym-deps, fragments)
+ XmloEvent::Eoh => break,
+ }
}
let mut dir = path.clone();
@@ -347,60 +314,12 @@ fn load_xmlo<'a>(
let path_abs = path_buf.canonicalize().unwrap();
let path = path_abs.to_str().unwrap();
- load_xmlo(path, pkgs_seen, fragments, depgraph)?;
+ load_xmlo(path, pkgs_seen, fragments, depgraph, interner)?;
}
Ok(())
}
-fn read_deps<B>(
- reader: &mut Reader<B>,
- depgraph: &mut DepGraph,
- name: &[u8],
-) -> Option<()>
-where
- B: BufRead,
-{
- // TODO: API needs to expose whether a symbol is already known so that
- // we can warn on them
- // note: using from_utf8_unchecked here did _not_ improve performance
- let sym_node = depgraph.declare(std::str::from_utf8(name).unwrap());
-
- //println!("processing deps for {}", sym_name);
-
- loop {
- match reader.read_event(&mut Vec::new()) {
- Ok(Event::Start(ele)) | Ok(Event::Empty(ele)) => {
- let mut attrs = ele.attributes();
- let mut filtered =
- attrs.with_checks(false).filter_map(Result::ok);
-
- filtered.find(|attr| attr.key == b"name").and_then(
- |mut attr| {
- let name = attr.value.to_mut();
- let str = std::str::from_utf8(name).unwrap();
-
- let dep_node = depgraph.declare(&str);
- depgraph.declare_dep(sym_node, dep_node);
-
- Some(())
- },
- );
-
- //println!("{:?}", ele.attributes().collect::<Vec<_>>());
- }
-
- Ok(Event::Eof) | Ok(Event::End(_)) => break Some(()),
-
- Err(e) => {
- panic!("Error at {}: {:?}", reader.buffer_position(), e);
- }
-
- _ => (),
- }
- }
-}
-
fn sort_deps(depgraph: &DepGraph) -> Vec<&SymEntry> {
// @type=meta, @preproc:elig-class-yields
// @type={ret}map{,:head,:tail}