| 1 | module main |
| 2 | |
| 3 | import compress.deflate |
| 4 | import os |
| 5 | |
| 6 | fn choose_cc() string { |
| 7 | for cc in ['cc', 'gcc', 'clang'] { |
| 8 | if os.execute('${cc} --version').exit_code == 0 { |
| 9 | return cc |
| 10 | } |
| 11 | } |
| 12 | return '' |
| 13 | } |
| 14 | |
| 15 | fn compile_c_ref(workdir string) !string { |
| 16 | cc := choose_cc() |
| 17 | if cc == '' { |
| 18 | return error('no C compiler found') |
| 19 | } |
| 20 | src := os.join_path(@DIR, 'deflate_ref.c') |
| 21 | bin := os.join_path(workdir, 'deflate_cross_validate') |
| 22 | res := os.execute('${cc} -O2 ${os.quoted_path(src)} -lz -o ${os.quoted_path(bin)}') |
| 23 | if res.exit_code != 0 { |
| 24 | return error('C compile failed: ${res.output}') |
| 25 | } |
| 26 | return bin |
| 27 | } |
| 28 | |
| 29 | fn main() { |
| 30 | base_tmp := os.join_path(os.temp_dir(), 'v_deflate_interop') |
| 31 | os.mkdir_all(base_tmp) or { |
| 32 | eprintln('could not create base temp dir: ${err.msg()}') |
| 33 | exit(1) |
| 34 | } |
| 35 | workdir := os.join_path(base_tmp, 'run_${os.getpid()}') |
| 36 | os.mkdir_all(workdir) or { |
| 37 | eprintln('could not create work dir: ${err.msg()}') |
| 38 | exit(1) |
| 39 | } |
| 40 | defer { |
| 41 | os.rmdir_all(workdir) or {} |
| 42 | } |
| 43 | |
| 44 | bin := compile_c_ref(workdir) or { |
| 45 | eprintln('Skipping C cross-validation: ${err.msg()}') |
| 46 | return |
| 47 | } |
| 48 | |
| 49 | input := 'deflate C cross-validation payload'.repeat(50).bytes() |
| 50 | ip := os.join_path(workdir, 'xval_in.bin') |
| 51 | cp := os.join_path(workdir, 'xval_c_zlib.bin') |
| 52 | gp := os.join_path(workdir, 'xval_c_gzip.bin') |
| 53 | vp := os.join_path(workdir, 'xval_v_zlib.bin') |
| 54 | vgp := os.join_path(workdir, 'xval_v_gzip.bin') |
| 55 | dp := os.join_path(workdir, 'xval_dec.bin') |
| 56 | |
| 57 | os.write_file_array(ip, input) or { |
| 58 | eprintln('write input failed: ${err.msg()}') |
| 59 | exit(1) |
| 60 | } |
| 61 | |
| 62 | res1 := |
| 63 | os.execute('${os.quoted_path(bin)} compress ${os.quoted_path(ip)} ${os.quoted_path(cp)}') |
| 64 | if res1.exit_code != 0 { |
| 65 | eprintln('C zlib compress failed: ${res1.output}') |
| 66 | exit(1) |
| 67 | } |
| 68 | c_zlib := os.read_bytes(cp) or { |
| 69 | eprintln('read C zlib stream failed: ${err.msg()}') |
| 70 | exit(1) |
| 71 | } |
| 72 | v_decoded_zlib := deflate.decompress(c_zlib) or { |
| 73 | eprintln('V decompress of C zlib failed: ${err.msg()}') |
| 74 | exit(1) |
| 75 | } |
| 76 | if v_decoded_zlib != input { |
| 77 | eprintln('C zlib -> V mismatch') |
| 78 | exit(1) |
| 79 | } |
| 80 | println('OK: C zlib -> V decompress') |
| 81 | |
| 82 | res2 := os.execute('${os.quoted_path(bin)} gzip ${os.quoted_path(ip)} ${os.quoted_path(gp)}') |
| 83 | if res2.exit_code != 0 { |
| 84 | eprintln('C gzip failed: ${res2.output}') |
| 85 | exit(1) |
| 86 | } |
| 87 | c_gzip := os.read_bytes(gp) or { |
| 88 | eprintln('read C gzip stream failed: ${err.msg()}') |
| 89 | exit(1) |
| 90 | } |
| 91 | v_decoded_gzip := deflate.decompress(c_gzip) or { |
| 92 | eprintln('V decompress of C gzip failed: ${err.msg()}') |
| 93 | exit(1) |
| 94 | } |
| 95 | if v_decoded_gzip != input { |
| 96 | eprintln('C gzip -> V mismatch') |
| 97 | exit(1) |
| 98 | } |
| 99 | println('OK: C gzip -> V decompress') |
| 100 | |
| 101 | v_zlib := deflate.compress(input) or { |
| 102 | eprintln('V zlib compress failed: ${err.msg()}') |
| 103 | exit(1) |
| 104 | } |
| 105 | os.write_file_array(vp, v_zlib) or { |
| 106 | eprintln('write V zlib failed: ${err.msg()}') |
| 107 | exit(1) |
| 108 | } |
| 109 | res3 := |
| 110 | os.execute('${os.quoted_path(bin)} decompress ${os.quoted_path(vp)} ${os.quoted_path(dp)}') |
| 111 | if res3.exit_code != 0 { |
| 112 | eprintln('C decompress of V zlib failed: ${res3.output}') |
| 113 | exit(1) |
| 114 | } |
| 115 | c_unzlib := os.read_bytes(dp) or { |
| 116 | eprintln('read C zlib decompressed output failed: ${err.msg()}') |
| 117 | exit(1) |
| 118 | } |
| 119 | if c_unzlib != input { |
| 120 | eprintln('V zlib -> C mismatch') |
| 121 | exit(1) |
| 122 | } |
| 123 | println('OK: V zlib -> C decompress') |
| 124 | |
| 125 | v_gzip := deflate.compress(input, format: .gzip) or { |
| 126 | eprintln('V gzip compress failed: ${err.msg()}') |
| 127 | exit(1) |
| 128 | } |
| 129 | os.write_file_array(vgp, v_gzip) or { |
| 130 | eprintln('write V gzip failed: ${err.msg()}') |
| 131 | exit(1) |
| 132 | } |
| 133 | res4 := os.execute('${os.quoted_path(bin)} gunzip ${os.quoted_path(vgp)} ${os.quoted_path(dp)}') |
| 134 | if res4.exit_code != 0 { |
| 135 | eprintln('C gunzip of V gzip failed: ${res4.output}') |
| 136 | exit(1) |
| 137 | } |
| 138 | c_ungzip := os.read_bytes(dp) or { |
| 139 | eprintln('read C gzip decompressed output failed: ${err.msg()}') |
| 140 | exit(1) |
| 141 | } |
| 142 | if c_ungzip != input { |
| 143 | eprintln('V gzip -> C mismatch') |
| 144 | exit(1) |
| 145 | } |
| 146 | println('OK: V gzip -> C decompress') |
| 147 | |
| 148 | if os.execute('python3 --version').exit_code == 0 { |
| 149 | py_src := os.join_path(@DIR, 'deflate_ref.py') |
| 150 | py_driver := os.join_path(workdir, 'deflate_ref.py') |
| 151 | os.cp(py_src, py_driver) or { |
| 152 | eprintln('copy Python reference script failed: ${err.msg()}') |
| 153 | exit(1) |
| 154 | } |
| 155 | |
| 156 | py_zp := os.join_path(workdir, 'xval_py_zlib.bin') |
| 157 | py_gp := os.join_path(workdir, 'xval_py_gzip.bin') |
| 158 | |
| 159 | res5 := |
| 160 | os.execute('python3 ${os.quoted_path(py_driver)} compress ${os.quoted_path(ip)} ${os.quoted_path(py_zp)}') |
| 161 | if res5.exit_code != 0 { |
| 162 | eprintln('Python zlib compress failed: ${res5.output}') |
| 163 | exit(1) |
| 164 | } |
| 165 | py_zlib := os.read_bytes(py_zp) or { |
| 166 | eprintln('read Python zlib stream failed: ${err.msg()}') |
| 167 | exit(1) |
| 168 | } |
| 169 | if deflate.decompress(py_zlib) or { []u8{} } != input { |
| 170 | eprintln('Python zlib -> V mismatch') |
| 171 | exit(1) |
| 172 | } |
| 173 | println('OK: Python zlib -> V decompress') |
| 174 | |
| 175 | res6 := |
| 176 | os.execute('python3 ${os.quoted_path(py_driver)} gzip ${os.quoted_path(ip)} ${os.quoted_path(py_gp)}') |
| 177 | if res6.exit_code != 0 { |
| 178 | eprintln('Python gzip failed: ${res6.output}') |
| 179 | exit(1) |
| 180 | } |
| 181 | py_gzip := os.read_bytes(py_gp) or { |
| 182 | eprintln('read Python gzip stream failed: ${err.msg()}') |
| 183 | exit(1) |
| 184 | } |
| 185 | if deflate.decompress(py_gzip) or { []u8{} } != input { |
| 186 | eprintln('Python gzip -> V mismatch') |
| 187 | exit(1) |
| 188 | } |
| 189 | println('OK: Python gzip -> V decompress') |
| 190 | |
| 191 | py_unz := os.join_path(workdir, 'xval_py_unz.bin') |
| 192 | res7 := |
| 193 | os.execute('python3 ${os.quoted_path(py_driver)} decompress ${os.quoted_path(vp)} ${os.quoted_path(py_unz)}') |
| 194 | if res7.exit_code != 0 { |
| 195 | eprintln('Python decompress of V zlib failed: ${res7.output}') |
| 196 | exit(1) |
| 197 | } |
| 198 | if (os.read_bytes(py_unz) or { []u8{} }) != input { |
| 199 | eprintln('V zlib -> Python mismatch') |
| 200 | exit(1) |
| 201 | } |
| 202 | println('OK: V zlib -> Python decompress') |
| 203 | |
| 204 | py_ungz := os.join_path(workdir, 'xval_py_ungz.bin') |
| 205 | res8 := |
| 206 | os.execute('python3 ${os.quoted_path(py_driver)} gunzip ${os.quoted_path(vgp)} ${os.quoted_path(py_ungz)}') |
| 207 | if res8.exit_code != 0 { |
| 208 | eprintln('Python gunzip of V gzip failed: ${res8.output}') |
| 209 | exit(1) |
| 210 | } |
| 211 | if (os.read_bytes(py_ungz) or { []u8{} }) != input { |
| 212 | eprintln('V gzip -> Python mismatch') |
| 213 | exit(1) |
| 214 | } |
| 215 | println('OK: V gzip -> Python decompress') |
| 216 | } else { |
| 217 | eprintln('Skipping Python cross-validation: python3 not found') |
| 218 | } |
| 219 | } |
| 220 | |