Fixed problem in merger with deeper-than-1 include levels, now avec tests

This commit is contained in:
Noah Santschi-Cooney 2021-01-14 01:44:08 +00:00
parent 6c0a1f9b57
commit 5aa7f4dc03
No known key found for this signature in database
GPG key ID: 3B22282472C8AE48
8 changed files with 195 additions and 73 deletions

View file

@ -1,4 +1,4 @@
use std::collections::{HashMap, LinkedList};
use std::collections::{HashMap, LinkedList, VecDeque};
use std::iter::Peekable;
use core::slice::Iter;
@ -28,7 +28,10 @@ pub fn generate_merge_list<'a>(
last_offset_set.insert(first_path.clone(), 0);
create_merge_views(nodes_iter, &mut merge_list, &mut last_offset_set, graph, sources, &mut line_directives);
// stack to keep track of the depth first traversal
let mut stack = VecDeque::<NodeIndex>::new();
create_merge_views(&mut nodes_iter, &mut merge_list, &mut last_offset_set, graph, sources, &mut line_directives, &mut stack);
// now we add a view of the remainder of the root file
let offset = *last_offset_set.get(&first_path).unwrap();
@ -48,59 +51,73 @@ pub fn generate_merge_list<'a>(
}
fn create_merge_views<'a>(
mut nodes: Peekable<Iter<(NodeIndex, Option<NodeIndex>)>>,
nodes: &mut Peekable<Iter<(NodeIndex, Option<NodeIndex>)>>,
merge_list: &mut LinkedList<&'a str>,
last_offset_set: &mut HashMap<String, usize>,
graph: &'a CachedStableGraph,
sources: &'a HashMap<String, String>,
line_directives: &mut Vec<String>
line_directives: &mut Vec<String>,
stack: &mut VecDeque<NodeIndex>,
) {
let n = match nodes.next() {
Some(n) => n,
None => return,
};
let parent = n.1.unwrap();
let child = n.0;
let edge = graph.get_edge_meta(parent, child);
let parent_path = graph.get_node(parent).clone();
let child_path = graph.get_node(child).clone();
let source = sources.get(&parent_path).unwrap();
let (char_for_line, char_following_line) = char_offset_for_line(edge.line, source);
let offset = *last_offset_set.insert(parent_path.clone(), char_following_line).get_or_insert(0);
merge_list.push_back(&source[offset..char_for_line]);
add_opening_line_directive(&child_path, merge_list, line_directives);
loop {
let n = match nodes.next() {
Some(n) => n,
None => return,
};
let parent = n.1.unwrap();
let child = n.0;
let edge = graph.get_edge_meta(parent, child);
let parent_path = graph.get_node(parent).clone();
let child_path = graph.get_node(child).clone();
let parent_source = sources.get(&parent_path).unwrap();
let (char_for_line, char_following_line) = char_offset_for_line(edge.line, parent_source);
let offset = *last_offset_set.insert(parent_path.clone(), char_following_line).get_or_insert(0);
//eprintln!("offset={} char_for_line={} len={} path={}", offset, char_for_line, parent_source.len(), parent_path);
merge_list.push_back(&parent_source[offset..char_for_line]);
add_opening_line_directive(&child_path, merge_list, line_directives);
match nodes.peek() {
Some(next) => {
let next = *next;
// if the next element is not a child of this element, we dump the rest of this elements source
if next.1.unwrap() != child {
let source = sources.get(&child_path).unwrap();
merge_list.push_back(&source[..]);
// +2 because edge.line is 0 indexed but #line is 1 indexed and references the *following* line
add_closing_line_directive(edge.line+2, &parent_path, merge_list, line_directives);
}
create_merge_views(nodes, merge_list, last_offset_set, graph, sources, line_directives);
if next.1.unwrap() == child {
let offset = *last_offset_set.get(&child_path).unwrap();
let source = sources.get(&child_path).unwrap();
if offset <= source.len() {
merge_list.push_back(&source[offset..]);
match nodes.peek() {
Some(next) => {
let next = *next;
// if the next pair's parent is not a child of the current pair, we dump the rest of this childs source
if next.1.unwrap() != child {
let child_source = sources.get(&child_path).unwrap();
merge_list.push_back(&child_source[..]);
// +2 because edge.line is 0 indexed but #line is 1 indexed and references the *following* line
add_closing_line_directive(edge.line+2, &parent_path, merge_list, line_directives);
// if the next pair's parent is not the current pair's parent, we need to bubble up
if stack.contains(&next.1.unwrap()) {
return;
}
continue;
}
stack.push_back(parent);
create_merge_views(nodes, merge_list, last_offset_set, graph, sources, line_directives, stack);
stack.pop_back();
if next.1.unwrap() == child {
let offset = *last_offset_set.get(&child_path).unwrap();
let child_source = sources.get(&child_path).unwrap();
if offset <= child_source.len() {
merge_list.push_back(&child_source[offset..]);
}
// +2 because edge.line is 0 indexed but #line is 1 indexed and references the *following* line
add_closing_line_directive(edge.line+2, &parent_path, merge_list, line_directives);
}
},
None => {
let child_source = sources.get(&child_path).unwrap();
merge_list.push_back(&child_source[..]);
// +2 because edge.line is 0 indexed but #line is 1 indexed and references the *following* line
add_closing_line_directive(edge.line+2, &parent_path, merge_list, line_directives);
}
},
None => {
let source = sources.get(&child_path).unwrap();
merge_list.push_back(&source[..]);
// +2 because edge.line is 0 indexed but #line is 1 indexed and references the *following* line
add_closing_line_directive(edge.line+2, &parent_path, merge_list, line_directives);
}
}
}

View file

@ -839,13 +839,9 @@ fn test_generate_merge_list_01() {
let (_tmp_dir, tmp_path) = copy_to_and_set_root("./testdata/01", &mut server);
let final_idx = server
.graph
.borrow_mut()
let final_idx = server.graph.borrow_mut()
.add_node(&format!("{}/shaders/{}", tmp_path, "final.fsh"));
let common_idx = server
.graph
.borrow_mut()
let common_idx = server.graph.borrow_mut()
.add_node(&format!("{}/shaders/{}", tmp_path, "common.glsl"));
server.graph.borrow_mut().add_edge(
@ -881,21 +877,13 @@ fn test_generate_merge_list_02() {
let (_tmp_dir, tmp_path) = copy_to_and_set_root("./testdata/02", &mut server);
let final_idx = server
.graph
.borrow_mut()
let final_idx = server.graph.borrow_mut()
.add_node(&format!("{}/shaders/{}", tmp_path, "final.fsh"));
let test_idx = server
.graph
.borrow_mut()
let test_idx = server.graph.borrow_mut()
.add_node(&format!("{}/shaders/utils/{}", tmp_path, "test.glsl"));
let burger_idx = server
.graph
.borrow_mut()
let burger_idx = server.graph.borrow_mut()
.add_node(&format!("{}/shaders/utils/{}", tmp_path, "burger.glsl"));
let sample_idx = server
.graph
.borrow_mut()
let sample_idx = server.graph.borrow_mut()
.add_node(&format!("{}/shaders/utils/{}", tmp_path, "sample.glsl"));
server.graph.borrow_mut().add_edge(
@ -959,21 +947,13 @@ fn test_generate_merge_list_03() {
let (_tmp_dir, tmp_path) = copy_to_and_set_root("./testdata/03", &mut server);
let final_idx = server
.graph
.borrow_mut()
let final_idx = server.graph.borrow_mut()
.add_node(&format!("{}/shaders/{}", tmp_path, "final.fsh"));
let test_idx = server
.graph
.borrow_mut()
let test_idx = server.graph.borrow_mut()
.add_node(&format!("{}/shaders/utils/{}", tmp_path, "test.glsl"));
let burger_idx = server
.graph
.borrow_mut()
let burger_idx = server.graph.borrow_mut()
.add_node(&format!("{}/shaders/utils/{}", tmp_path, "burger.glsl"));
let sample_idx = server
.graph
.borrow_mut()
let sample_idx = server.graph.borrow_mut()
.add_node(&format!("{}/shaders/utils/{}", tmp_path, "sample.glsl"));
server.graph.borrow_mut().add_edge(
@ -1030,3 +1010,86 @@ fn test_generate_merge_list_03() {
server.endpoint.request_shutdown();
}
#[test]
fn test_generate_merge_list_04() {
let mut server = new_temp_server();
let (_tmp_dir, tmp_path) = copy_to_and_set_root("./testdata/04", &mut server);
let final_idx = server.graph.borrow_mut()
.add_node(&format!("{}/shaders/{}", tmp_path, "final.fsh"));
let utilities_idx = server.graph.borrow_mut()
.add_node(&format!("{}/shaders/utils/{}", tmp_path, "utilities.glsl"));
let stuff1_idx = server.graph.borrow_mut()
.add_node(&format!("{}/shaders/utils/{}", tmp_path, "stuff1.glsl"));
let stuff2_idx = server.graph.borrow_mut()
.add_node(&format!("{}/shaders/utils/{}", tmp_path, "stuff2.glsl"));
let matrices_idx = server.graph.borrow_mut()
.add_node(&format!("{}/shaders/lib/{}", tmp_path, "matrices.glsl"));
server.graph.borrow_mut().add_edge(
final_idx,
utilities_idx,
IncludePosition {
line: 2,
start: 0,
end: 0,
},
);
server.graph.borrow_mut().add_edge(
utilities_idx,
stuff1_idx,
IncludePosition {
line: 0,
start: 0,
end: 0,
},
);
server.graph.borrow_mut().add_edge(
utilities_idx,
stuff2_idx,
IncludePosition {
line: 1,
start: 0,
end: 0,
},
);
server.graph.borrow_mut().add_edge(
final_idx,
matrices_idx,
IncludePosition {
line: 3,
start: 0,
end: 0,
},
);
let nodes = server.get_dfs_for_node(final_idx).unwrap();
let sources = server.load_sources(&nodes).unwrap();
let graph_borrow = server.graph.borrow();
let result = merge_views::generate_merge_list(&nodes, &sources, &graph_borrow);
let merge_file = tmp_path.clone() + "/shaders/final.fsh.merge";
let mut truth = fs::read_to_string::<String>(merge_file).unwrap();
for file in &[
"utils/utilities.glsl",
"utils/stuff1.glsl",
"utils/utilities.glsl",
"utils/stuff2.glsl",
"utils/utilities.glsl",
"final.fsh",
"lib/matrices.glsl",
"final.fsh"
] {
let path = tmp_path.clone();
truth = truth.replacen("!!", &format!("{}/shaders/{}", path, file), 1);
}
server.endpoint.request_shutdown();
assert_that!(result, eq(truth));
}

8
server/testdata/04/final.fsh vendored Normal file
View file

@ -0,0 +1,8 @@
#version 120
#include "/utils/utilities.glsl"
#include "/utils/matricies.glsl"
void main() {
}

23
server/testdata/04/final.fsh.merge vendored Normal file
View file

@ -0,0 +1,23 @@
#version 120
#line 1 "!!"
#line 1 "!!"
void stuff1() {
}
#line 2 "!!"
#line 1 "!!"
void stuff2() {
}
#line 3 "!!"
#line 4 "!!"
#line 1 "!!"
void matrix() {
}
#line 5 "!!"
void main() {
}

3
server/testdata/04/lib/matrices.glsl vendored Normal file
View file

@ -0,0 +1,3 @@
void matrix() {
}

3
server/testdata/04/utils/stuff1.glsl vendored Normal file
View file

@ -0,0 +1,3 @@
void stuff1() {
}

3
server/testdata/04/utils/stuff2.glsl vendored Normal file
View file

@ -0,0 +1,3 @@
void stuff2() {
}

View file

@ -0,0 +1,2 @@
#include "/utils/stuff1.glsl"
#include "/utils/stuff2.glsl"