Skip to content

Commit

Permalink
Add test for checking the total order of fn compare_src_locs
Browse files Browse the repository at this point in the history
Also included some code suggestions by Khyber.

Co-authored-by: Khyber Sen <[email protected]>
  • Loading branch information
Kriskras99 and kkysen committed Sep 23, 2024
1 parent a7f643a commit b562165
Showing 1 changed file with 274 additions and 12 deletions.
286 changes: 274 additions & 12 deletions c2rust-transpile/src/c_ast/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -213,30 +213,30 @@ impl TypedAstContext {
let path_b = &self.include_map[self.file_map[b.fileid as usize]];

// Find the first include that does not match between the two
for (include_a, include_b) in path_a.iter().zip(path_b.iter()) {
let order = include_a.cmp(include_b);
if order != Equal {
return order;
}
let common_len = path_a.len().min(path_b.len());
let order = path_a[..common_len].cmp(&path_b[..common_len]);
if order != Equal {
return order;
}

// Either all parent includes are the same, or the include paths are of different lengths
// because .zip() stops when one of the iterators is empty.
match path_a.len().cmp(&path_b.len()) {
let (a, b) = match path_a.len().cmp(&path_b.len()) {
Less => {
// a has the shorter path, which means b was included in a's file
// so extract that include and compare the position to a
let b = path_b.get(path_a.len()).unwrap();
a.cmp(b)
let b = &path_b[path_a.len()];
(a, b)
}
Equal => a.cmp(b), // a and b have the same include path and are thus in the same file
Equal => (a, b), // a and b have the same include path and are thus in the same file
Greater => {
// b has the shorter path, which means a was included in b's file
// so extract that include and compare the position to b
let a = path_a.get(path_b.len()).unwrap();
a.cmp(b)
let a = &path_a[path_b.len()];
(a, b)
}
}
};
a.cmp(b)
}

pub fn get_file_include_line_number(&self, file: FileId) -> Option<u64> {
Expand Down Expand Up @@ -1870,3 +1870,265 @@ impl CTypeKind {
Some(ty)
}
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn test_compare_src_locs_ord() {
let ctx = TypedAstContext {
c_types: Default::default(),
c_exprs: Default::default(),
c_stmts: Default::default(),
c_decls: Default::default(),
c_decls_top: vec![],
c_main: None,
parents: Default::default(),
files: vec![],
file_map: vec![0, 1, 2, 3, 4, 5, 4, 5],
include_map: vec![
vec![],
vec![],
vec![SrcLoc {
fileid: 2,
line: 6,
column: 10,
}],
vec![],
vec![],
vec![SrcLoc {
fileid: 5,
line: 6,
column: 10,
}],
],
label_names: Default::default(),
macro_invocations: Default::default(),
macro_expansions: Default::default(),
macro_expansion_text: Default::default(),
comments: vec![],
prenamed_decls: Default::default(),
va_list_kind: BuiltinVaListKind::CharPtrBuiltinVaList,
target: "".to_string(),
};
let locs = &mut [
SrcLoc {
fileid: 5,
line: 5,
column: 1,
},
SrcLoc {
fileid: 5,
line: 5,
column: 1,
},
SrcLoc {
fileid: 1,
line: 5,
column: 1,
},
SrcLoc {
fileid: 1,
line: 5,
column: 1,
},
SrcLoc {
fileid: 1,
line: 10,
column: 1,
},
SrcLoc {
fileid: 1,
line: 5,
column: 1,
},
SrcLoc {
fileid: 2,
line: 4,
column: 1,
},
SrcLoc {
fileid: 5,
line: 3,
column: 7,
},
SrcLoc {
fileid: 5,
line: 3,
column: 1,
},
SrcLoc {
fileid: 5,
line: 3,
column: 1,
},
SrcLoc {
fileid: 5,
line: 5,
column: 7,
},
SrcLoc {
fileid: 5,
line: 5,
column: 1,
},
SrcLoc {
fileid: 5,
line: 5,
column: 1,
},
SrcLoc {
fileid: 5,
line: 5,
column: 7,
},
SrcLoc {
fileid: 5,
line: 7,
column: 7,
},
SrcLoc {
fileid: 5,
line: 7,
column: 1,
},
SrcLoc {
fileid: 5,
line: 7,
column: 1,
},
SrcLoc {
fileid: 5,
line: 9,
column: 7,
},
SrcLoc {
fileid: 5,
line: 9,
column: 1,
},
SrcLoc {
fileid: 5,
line: 9,
column: 1,
},
SrcLoc {
fileid: 5,
line: 5,
column: 7,
},
SrcLoc {
fileid: 5,
line: 5,
column: 1,
},
SrcLoc {
fileid: 5,
line: 5,
column: 1,
},
SrcLoc {
fileid: 5,
line: 8,
column: 3,
},
SrcLoc {
fileid: 5,
line: 8,
column: 1,
},
SrcLoc {
fileid: 5,
line: 7,
column: 1,
},
SrcLoc {
fileid: 5,
line: 0,
column: 4,
},
SrcLoc {
fileid: 5,
line: 0,
column: 1,
},
SrcLoc {
fileid: 5,
line: 2,
column: 1,
},
SrcLoc {
fileid: 5,
line: 98,
column: 3,
},
SrcLoc {
fileid: 5,
line: 98,
column: 1,
},
SrcLoc {
fileid: 5,
line: 202,
column: 1,
},
SrcLoc {
fileid: 5,
line: 202,
column: 1,
},
SrcLoc {
fileid: 7,
line: 1,
column: 1,
},
SrcLoc {
fileid: 7,
line: 3,
column: 1,
},
];

let n = locs.len();
for i in 0..n {
let a = locs[i];
for j in 0..n {
let b = locs[j];
for k in 0..n {
let c = locs[k];
if ctx.compare_src_locs(&a, &b) == Ordering::Less
&& ctx.compare_src_locs(&b, &c) == Ordering::Less
{
assert_eq!(
ctx.compare_src_locs(&a, &b),
Ordering::Less,
"Total order has been violated"
);
}
if ctx.compare_src_locs(&a, &b) == Ordering::Greater
&& ctx.compare_src_locs(&b, &c) == Ordering::Greater
{
assert_eq!(
ctx.compare_src_locs(&a, &b),
Ordering::Greater,
"Total order has been violated"
);
}
if ctx.compare_src_locs(&a, &b) == Ordering::Equal
&& ctx.compare_src_locs(&b, &c) == Ordering::Equal
{
assert_eq!(
ctx.compare_src_locs(&a, &b),
Ordering::Equal,
"Total order has been violated"
);
}
}
}
}

// This should not panic
locs.sort_unstable_by(|a, b| ctx.compare_src_locs(a, b));
}
}

0 comments on commit b562165

Please sign in to comment.