PageRenderTime 16ms CodeModel.GetById 1ms app.highlight 12ms RepoModel.GetById 1ms app.codeStats 0ms

/src/fuzzer/ivec_fuzz.rs

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