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