1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
//! DECY-135: Linked List Patterns
//!
//! Tests for linked list struct transformation.
//! Note: Full Option<Box<T>> transformation requires detecting heap allocation
//! patterns. Stack-allocated linked lists (like the corpus example) cannot
//! safely use Option<Box<T>>.
use decy_core::transpile;
/// Test that linked list struct compiles (uses raw pointers for now).
///
/// C: struct Node { int value; struct Node *next; };
/// Current: pub next: *mut Node (raw pointer preserved for safety)
///
/// Note: Option<Box<T>> transformation deferred - requires detecting
/// malloc patterns vs stack allocation.
#[test]
fn test_linked_list_struct_compiles() {
let c_code = r#"
struct Node {
int value;
struct Node *next;
};
int main() {
struct Node n;
n.value = 10;
n.next = 0;
return n.value;
}
"#;
let result = transpile(c_code).expect("Transpilation should succeed");
println!("Generated Rust code:\n{}", result);
// Should have Node struct with next field
assert!(
result.contains("pub struct Node"),
"Should generate Node struct\nGenerated:\n{}",
result
);
assert!(result.contains("pub next:"), "Should have next field\nGenerated:\n{}", result);
}
/// Test that NULL assignment to pointer field generates null_mut.
///
/// C: n.next = 0;
/// Rust: n.next = std::ptr::null_mut();
#[test]
fn test_null_assignment_to_pointer_field() {
let c_code = r#"
struct Node {
int value;
struct Node *next;
};
int main() {
struct Node n;
n.next = 0;
return 0;
}
"#;
let result = transpile(c_code).expect("Transpilation should succeed");
println!("Generated Rust code:\n{}", result);
// NULL assignment generates null_mut (raw pointer)
assert!(
result.contains("null_mut()"),
"NULL assignment should generate null_mut()\nGenerated:\n{}",
result
);
}
/// Test that linked list traversal compiles (may use unsafe).
///
/// Note: Eliminating unsafe from linked list traversal requires
/// detecting that nodes are heap-allocated with malloc, then
/// transforming to Option<Box<T>> pattern.
#[test]
fn test_linked_list_traversal_compiles() {
let c_code = r#"
struct Node {
int value;
struct Node *next;
};
int sum_list(struct Node *head) {
int sum = 0;
struct Node *current = head;
while (current != 0) {
sum = sum + current->value;
current = current->next;
}
return sum;
}
int main() {
return 0;
}
"#;
let result = transpile(c_code).expect("Transpilation should succeed");
println!("Generated Rust code:\n{}", result);
// Should have sum_list function
assert!(
result.contains("fn sum_list"),
"Should generate sum_list function\nGenerated:\n{}",
result
);
}