]> git.lizzy.rs Git - rust.git/blob - src/fuzzer/ivec_fuzz.rs
Get these files compiling again
[rust.git] / src / fuzzer / ivec_fuzz.rs
1 /*
2
3 Idea: provide functions for 'exhaustive' and 'random' modification of vecs.
4
5   two functions, "return all edits" and "return a random edit" <-- leaning toward this model
6     or
7   two functions, "return the number of possible edits" and "return edit #n"
8
9 It would be nice if this could be data-driven, so the two functions could share information:
10   type vec_modifier = rec(fn (<T> v, uint i) -> [T] fun, uint lo, uint di);
11   const [vec_modifier] vec_modifiers = ~[rec(fun=vec_omit, 0u, 1u), ...];
12 But that gives me "error: internal compiler error unimplemented consts that's not a plain literal".
13 https://github.com/graydon/rust/issues/570
14
15 vec_edits is not an iter because iters might go away.
16
17 */
18
19 use std;
20 import vec;
21 import vec::slice;
22 import vec::len;
23 import int;
24
25 fn vec_omit<T: copy>(v: [T], i: uint) -> [T] {
26     slice(v, 0u, i) + slice(v, i + 1u, len(v))
27 }
28 fn vec_dup<T: copy>(v: [T], i: uint) -> [T] {
29     slice(v, 0u, i) + [v[i]] + slice(v, i, len(v))
30 }
31 fn vec_swadj<T: copy>(v: [T], i: uint) -> [T] {
32     slice(v, 0u, i) + [v[i + 1u], v[i]] + slice(v, i + 2u, len(v))
33 }
34 fn vec_prefix<T: copy>(v: [T], i: uint) -> [T] { slice(v, 0u, i) }
35 fn vec_suffix<T: copy>(v: [T], i: uint) -> [T] { slice(v, i, len(v)) }
36
37 fn vec_poke<T: copy>(v: [T], i: uint, x: T) -> [T] {
38     slice(v, 0u, i) + [x] + slice(v, i + 1u, len(v))
39 }
40 fn vec_insert<T: copy>(v: [T], i: uint, x: T) -> [T] {
41     slice(v, 0u, i) + [x] + slice(v, i, len(v))
42 }
43
44 // Iterates over 0...length, skipping the specified number on each side.
45 fn ix(skip_low: uint, skip_high: uint, length: uint, it: block(uint)) {
46     let i: uint = skip_low;
47     while i + skip_high <= length { it(i); i += 1u; }
48 }
49
50 // Returns a bunch of modified versions of v, some of which introduce new elements (borrowed from xs).
51 fn vec_edits<T: copy>(v: [T], xs: [T]) -> [[T]] {
52     let edits: [[T]] = [];
53     let Lv: uint = len(v);
54
55     if Lv != 1u {
56         // When Lv == 1u, this is redundant with omit.
57         edits += [[]];
58     }
59     if Lv >= 3u {
60         // When Lv == 2u, this is redundant with swap.
61         edits += [vec::reversed(v)];
62     }
63     ix(0u, 1u, Lv) {|i| edits += [vec_omit(v, i)]; }
64     ix(0u, 1u, Lv) {|i| edits += [vec_dup(v, i)]; }
65     ix(0u, 2u, Lv) {|i| edits += [vec_swadj(v, i)]; }
66     ix(1u, 2u, Lv) {|i| edits += [vec_prefix(v, i)]; }
67     ix(2u, 1u, Lv) {|i| edits += [vec_suffix(v, i)]; }
68
69     ix(0u, 1u, len(xs)) {|j|
70         ix(0u, 1u, Lv) {|i|
71             edits += [vec_poke(v, i, xs[j])];
72         }
73         ix(0u, 0u, Lv) {|i|
74             edits += [vec_insert(v, i, xs[j])];
75         }
76     }
77
78     edits
79 }
80
81 // Would be nice if this were built in: https://github.com/graydon/rust/issues/424
82 fn vec_to_str(v: [int]) -> str {
83     let i = 0u;
84     let s = "[";
85     while i < len(v) {
86         s += int::str(v[i]);
87         if i + 1u < len(v) { s += ", "; }
88         i += 1u;
89     }
90     ret s + "]";
91 }
92
93 fn show_edits(a: [int], xs: [int]) {
94     log(error, "=== Edits of " + vec_to_str(a) + " ===");
95     let b = vec_edits(a, xs);
96     ix(0u, 1u, len(b)) {|i| log(error, vec_to_str(b[i])); }
97 }
98
99 fn demo_edits() {
100     let xs = [7, 8];
101     show_edits([], xs);
102     show_edits([1], xs);
103     show_edits([1, 2], xs);
104     show_edits([1, 2, 3], xs);
105     show_edits([1, 2, 3, 4], xs);
106 }
107
108 fn main() { demo_edits(); }