libdeflate 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (89) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +17 -0
  3. data/.gitmodules +3 -0
  4. data/.rspec +2 -0
  5. data/.rubocop.yml +1 -0
  6. data/.rubocop_todo.yml +9 -0
  7. data/.travis.yml +5 -0
  8. data/Gemfile +4 -0
  9. data/LICENSE.txt +21 -0
  10. data/README.md +52 -0
  11. data/Rakefile +15 -0
  12. data/bin/console +14 -0
  13. data/bin/setup +8 -0
  14. data/ext/libdeflate/extconf.rb +14 -0
  15. data/ext/libdeflate/libdeflate/.gitignore +19 -0
  16. data/ext/libdeflate/libdeflate/COPYING +21 -0
  17. data/ext/libdeflate/libdeflate/Makefile +231 -0
  18. data/ext/libdeflate/libdeflate/Makefile.msc +64 -0
  19. data/ext/libdeflate/libdeflate/NEWS +57 -0
  20. data/ext/libdeflate/libdeflate/README.md +170 -0
  21. data/ext/libdeflate/libdeflate/common/common_defs.h +351 -0
  22. data/ext/libdeflate/libdeflate/common/compiler_gcc.h +134 -0
  23. data/ext/libdeflate/libdeflate/common/compiler_msc.h +95 -0
  24. data/ext/libdeflate/libdeflate/lib/adler32.c +213 -0
  25. data/ext/libdeflate/libdeflate/lib/adler32_impl.h +281 -0
  26. data/ext/libdeflate/libdeflate/lib/aligned_malloc.c +57 -0
  27. data/ext/libdeflate/libdeflate/lib/aligned_malloc.h +13 -0
  28. data/ext/libdeflate/libdeflate/lib/bt_matchfinder.h +357 -0
  29. data/ext/libdeflate/libdeflate/lib/crc32.c +368 -0
  30. data/ext/libdeflate/libdeflate/lib/crc32_impl.h +286 -0
  31. data/ext/libdeflate/libdeflate/lib/crc32_table.h +526 -0
  32. data/ext/libdeflate/libdeflate/lib/decompress_impl.h +404 -0
  33. data/ext/libdeflate/libdeflate/lib/deflate_compress.c +2817 -0
  34. data/ext/libdeflate/libdeflate/lib/deflate_compress.h +14 -0
  35. data/ext/libdeflate/libdeflate/lib/deflate_constants.h +66 -0
  36. data/ext/libdeflate/libdeflate/lib/deflate_decompress.c +889 -0
  37. data/ext/libdeflate/libdeflate/lib/gzip_compress.c +95 -0
  38. data/ext/libdeflate/libdeflate/lib/gzip_constants.h +45 -0
  39. data/ext/libdeflate/libdeflate/lib/gzip_decompress.c +130 -0
  40. data/ext/libdeflate/libdeflate/lib/hc_matchfinder.h +405 -0
  41. data/ext/libdeflate/libdeflate/lib/lib_common.h +35 -0
  42. data/ext/libdeflate/libdeflate/lib/matchfinder_avx2.h +53 -0
  43. data/ext/libdeflate/libdeflate/lib/matchfinder_common.h +205 -0
  44. data/ext/libdeflate/libdeflate/lib/matchfinder_neon.h +61 -0
  45. data/ext/libdeflate/libdeflate/lib/matchfinder_sse2.h +53 -0
  46. data/ext/libdeflate/libdeflate/lib/unaligned.h +202 -0
  47. data/ext/libdeflate/libdeflate/lib/x86_cpu_features.c +169 -0
  48. data/ext/libdeflate/libdeflate/lib/x86_cpu_features.h +48 -0
  49. data/ext/libdeflate/libdeflate/lib/zlib_compress.c +87 -0
  50. data/ext/libdeflate/libdeflate/lib/zlib_constants.h +21 -0
  51. data/ext/libdeflate/libdeflate/lib/zlib_decompress.c +91 -0
  52. data/ext/libdeflate/libdeflate/libdeflate.h +274 -0
  53. data/ext/libdeflate/libdeflate/programs/benchmark.c +558 -0
  54. data/ext/libdeflate/libdeflate/programs/checksum.c +197 -0
  55. data/ext/libdeflate/libdeflate/programs/detect.sh +62 -0
  56. data/ext/libdeflate/libdeflate/programs/gzip.c +603 -0
  57. data/ext/libdeflate/libdeflate/programs/prog_util.c +530 -0
  58. data/ext/libdeflate/libdeflate/programs/prog_util.h +162 -0
  59. data/ext/libdeflate/libdeflate/programs/test_checksums.c +135 -0
  60. data/ext/libdeflate/libdeflate/programs/tgetopt.c +118 -0
  61. data/ext/libdeflate/libdeflate/tools/afl-fuzz/Makefile +12 -0
  62. data/ext/libdeflate/libdeflate/tools/afl-fuzz/deflate_compress/fuzz.c +40 -0
  63. data/ext/libdeflate/libdeflate/tools/afl-fuzz/deflate_compress/inputs/0 +0 -0
  64. data/ext/libdeflate/libdeflate/tools/afl-fuzz/deflate_decompress/fuzz.c +28 -0
  65. data/ext/libdeflate/libdeflate/tools/afl-fuzz/deflate_decompress/inputs/0 +3 -0
  66. data/ext/libdeflate/libdeflate/tools/afl-fuzz/gzip_decompress/fuzz.c +28 -0
  67. data/ext/libdeflate/libdeflate/tools/afl-fuzz/gzip_decompress/inputs/0 +0 -0
  68. data/ext/libdeflate/libdeflate/tools/afl-fuzz/prepare_for_fuzz.sh +14 -0
  69. data/ext/libdeflate/libdeflate/tools/afl-fuzz/zlib_decompress/fuzz.c +28 -0
  70. data/ext/libdeflate/libdeflate/tools/afl-fuzz/zlib_decompress/inputs/0 +3 -0
  71. data/ext/libdeflate/libdeflate/tools/android_build.sh +104 -0
  72. data/ext/libdeflate/libdeflate/tools/checksum_benchmarks.sh +76 -0
  73. data/ext/libdeflate/libdeflate/tools/exec_tests.sh +30 -0
  74. data/ext/libdeflate/libdeflate/tools/gen_crc32_multipliers.c +108 -0
  75. data/ext/libdeflate/libdeflate/tools/gen_crc32_table.c +100 -0
  76. data/ext/libdeflate/libdeflate/tools/gzip_tests.sh +412 -0
  77. data/ext/libdeflate/libdeflate/tools/make-windows-releases +21 -0
  78. data/ext/libdeflate/libdeflate/tools/mips_build.sh +9 -0
  79. data/ext/libdeflate/libdeflate/tools/msc_test.bat +3 -0
  80. data/ext/libdeflate/libdeflate/tools/pgo_build.sh +23 -0
  81. data/ext/libdeflate/libdeflate/tools/produce_gzip_benchmark_table.sh +37 -0
  82. data/ext/libdeflate/libdeflate/tools/run_tests.sh +305 -0
  83. data/ext/libdeflate/libdeflate/tools/windows_build.sh +10 -0
  84. data/ext/libdeflate/libdeflate_ext.c +389 -0
  85. data/ext/libdeflate/libdeflate_ext.h +8 -0
  86. data/lib/libdeflate.rb +2 -0
  87. data/lib/libdeflate/version.rb +3 -0
  88. data/libdeflate.gemspec +33 -0
  89. metadata +230 -0
@@ -0,0 +1,412 @@
1
+ #!/bin/bash
2
+ #
3
+ # Test script for libdeflate's gzip and gunzip programs.
4
+ #
5
+ # To run, you must set GZIP and GUNZIP in the environment to the absolute paths
6
+ # to the gzip and gunzip programs to test. All tests should pass regardless of
7
+ # whether the GNU versions or the libdeflate versions, or a combination, of
8
+ # these programs are used.
9
+ #
10
+ # The environmental variable SMOKEDATA must also be set to a file containing
11
+ # test data.
12
+ #
13
+
14
+ set -eu -o pipefail
15
+
16
+ export -n GZIP GUNZIP SMOKEDATA
17
+
18
+ TMPDIR="$(mktemp -d)"
19
+ CURRENT_TEST=
20
+
21
+ cleanup() {
22
+ if [ -n "$CURRENT_TEST" ]; then
23
+ echo "TEST FAILED: \"$CURRENT_TEST\""
24
+ fi
25
+ rm -rf -- "$TMPDIR"
26
+ }
27
+
28
+ trap cleanup EXIT
29
+
30
+ SMOKEDATA="$(realpath "$SMOKEDATA")"
31
+ cd "$TMPDIR"
32
+
33
+ begin_test() {
34
+ CURRENT_TEST="$1"
35
+ rm -rf -- "$TMPDIR"/*
36
+ cp "$SMOKEDATA" file
37
+ }
38
+
39
+ gzip() {
40
+ $GZIP "$@"
41
+ }
42
+
43
+ gunzip() {
44
+ $GUNZIP "$@"
45
+ }
46
+
47
+ assert_status() {
48
+ local expected_status="$1"
49
+ local expected_msg="$2"
50
+ shift 2
51
+ (
52
+ set +e
53
+ eval "$*" 2>&1 >/dev/null
54
+ local actual_status=$?
55
+ if [ $actual_status -ne $expected_status ]; then
56
+ echo 1>&2 "Command '$*' exited with status" \
57
+ "$actual_status but expected status" \
58
+ "$expected_status"
59
+ exit 1
60
+ fi
61
+ exit 0
62
+ ) > command_output
63
+ if ! egrep -q "$expected_msg" command_output; then
64
+ echo 1>&2 "Expected output of command '$*' to match regex" \
65
+ "'$expected_msg'"
66
+ echo 1>&2 "Actual output was:"
67
+ echo 1>&2 "---------------------------------------------------"
68
+ cat 1>&2 command_output
69
+ echo 1>&2 "---------------------------------------------------"
70
+ return 1
71
+ fi
72
+ }
73
+
74
+ assert_error() {
75
+ assert_status 1 "$@"
76
+ }
77
+
78
+ assert_warning() {
79
+ assert_status 2 "$@"
80
+ }
81
+
82
+ assert_skipped() {
83
+ assert_warning '\<(ignored|skipping|unchanged)\>' "$@"
84
+ }
85
+
86
+
87
+ begin_test 'Basic compression and decompression works'
88
+ cp file orig
89
+ gzip file
90
+ [ ! -e file -a -e file.gz ]
91
+ gunzip file.gz
92
+ [ -e file -a ! -e file.gz ]
93
+ cmp file orig
94
+
95
+
96
+ begin_test 'gzip -d is gunzip'
97
+ cp file orig
98
+ gzip file
99
+ gzip -d file.gz
100
+ cmp file orig
101
+
102
+
103
+ begin_test '-k (keep original file) works'
104
+ cp file orig
105
+ gzip -k file
106
+ cmp file orig
107
+ rm file
108
+ cp file.gz orig.gz
109
+ gunzip -k file.gz
110
+ cmp file.gz orig.gz
111
+
112
+
113
+ begin_test '-c (write to stdout) works'
114
+ cp file orig
115
+ gzip -k file
116
+ gzip -c file > 2.gz
117
+ cmp file orig
118
+ cmp file.gz 2.gz
119
+ gunzip -c 2.gz > file
120
+ cmp file.gz 2.gz
121
+ cmp file orig
122
+
123
+
124
+ begin_test 'Reading from stdin works'
125
+ gzip < file > 1.gz
126
+ gzip - < file > 2.gz
127
+ cat file | gzip > 3.gz
128
+ cat file | gzip - > 4.gz
129
+ cmp file <(gunzip < 1.gz)
130
+ cmp file <(gunzip - < 2.gz)
131
+ cmp file <(cat 3.gz | gunzip)
132
+ cmp file <(cat 4.gz | gunzip -)
133
+
134
+
135
+ begin_test '-n option is accepted'
136
+ gzip -n file
137
+ gunzip -n file.gz
138
+
139
+
140
+ begin_test 'can specify multiple options'
141
+ gzip -fk1 file
142
+ cmp <(gzip -c -1 file) file.gz
143
+ gunzip -kfd file.gz
144
+
145
+
146
+ begin_test 'Compression levels'
147
+ if [ "$GZIP" = /usr/bin/gzip ]; then
148
+ assert_error '\<invalid option\>' gzip -10
149
+ max_level=9
150
+ else
151
+ for level in 13 99999 1a; do
152
+ assert_error '\<Invalid compression level\>' gzip -$level
153
+ done
154
+ max_level=12
155
+ fi
156
+ for level in `seq 1 $max_level`; do
157
+ gzip -c -$level file > file$level
158
+ cmp file <(gunzip -c file$level)
159
+ done
160
+ rm file command_output
161
+ cmp <(ls -S) <(ls -v) # file,file{1..max_level} have decreasing size
162
+
163
+
164
+ begin_test 'Overwriting output file requires -f'
165
+ cp file orig
166
+ echo -n > file.gz
167
+ gzip -c file > 2.gz
168
+ assert_warning 'already exists' gzip file </dev/null
169
+ cmp file.gz /dev/null
170
+ gzip -f file
171
+ cmp 2.gz file.gz
172
+ echo -n > file
173
+ assert_warning 'already exists' gunzip file.gz </dev/null
174
+ gunzip -f file.gz
175
+ cmp file orig
176
+
177
+
178
+ begin_test 'Nonexistent input file fails, even with -f'
179
+ for prog in 'gzip' 'gzip -f' 'gunzip' 'gunzip -f'; do
180
+ assert_error 'No such file or directory' $prog NONEXISTENT
181
+ done
182
+
183
+
184
+ begin_test 'Compressing already-suffixed file requires -f or -c'
185
+ gzip file
186
+ gzip -c file.gz > c.gz
187
+ gzip file.gz 2>&1 >/dev/null | grep -q 'already has .gz suffix'
188
+ [ -e file.gz -a ! -e file.gz.gz ]
189
+ gzip -f file.gz
190
+ [ ! -e file.gz -a -e file.gz.gz ]
191
+ cmp file.gz.gz c.gz
192
+
193
+
194
+ begin_test 'Decompressing unsuffixed file only works with -c'
195
+ gzip file && mv file.gz file
196
+ assert_skipped gunzip file
197
+ assert_skipped gunzip -f file
198
+ gunzip -c file > orig
199
+ mv file file.gz && gunzip file.gz && cmp file orig
200
+
201
+
202
+ begin_test '... unless there is a corresponding suffixed file'
203
+ cp file orig
204
+ gzip file
205
+ [ ! -e file -a -e file.gz ]
206
+ gunzip -c file > tmp
207
+ cmp tmp orig
208
+ rm tmp
209
+ ln -s NONEXISTENT file
210
+ gunzip -c file > tmp
211
+ cmp tmp orig
212
+ rm tmp file
213
+ gunzip file
214
+ [ -e file -a ! -e file.gz ]
215
+ cmp file orig
216
+
217
+
218
+ begin_test 'Directory is skipped, even with -f'
219
+ mkdir dir
220
+ mkdir dir.gz
221
+ for opt in '' '-f' '-c'; do
222
+ assert_skipped gzip $opt dir
223
+ done
224
+ #assert_skipped gzip dir.gz # XXX: GNU gzip warns, libdeflate gzip no-ops
225
+ for opt in '' '-f' '-c'; do
226
+ for name in dir dir.gz; do
227
+ assert_skipped gunzip $opt $name
228
+ done
229
+ done
230
+
231
+
232
+ begin_test '(gzip) symlink is rejected without -f or -c'
233
+ ln -s file symlink1
234
+ ln -s file symlink2
235
+ assert_error 'Too many levels of symbolic links' gzip symlink1
236
+ [ -e file -a -e symlink1 -a ! -e symlink1.gz ]
237
+ gzip -f symlink1
238
+ [ -e file -a ! -e symlink1 -a -e symlink1.gz ]
239
+ gzip -c symlink2 > /dev/null
240
+
241
+
242
+ begin_test '(gunzip) symlink is rejected without -f or -c'
243
+ gzip file
244
+ ln -s file.gz symlink1.gz
245
+ ln -s file.gz symlink2.gz
246
+ assert_error 'Too many levels of symbolic links' gunzip symlink1
247
+ [ -e file.gz -a -e symlink1.gz -a ! -e symlink1 ]
248
+ gunzip -f symlink1.gz
249
+ [ -e file.gz -a ! -e symlink1.gz -a -e symlink1 ]
250
+ gunzip -c symlink2.gz > /dev/null
251
+
252
+
253
+ begin_test 'FIFO is skipped, even with -f'
254
+ mkfifo foo
255
+ mkfifo foo.gz
256
+ assert_skipped gzip foo
257
+ assert_skipped gzip -f foo
258
+ #assert_skipped gzip -c foo # XXX: works with GNU gzip, not libdeflate's
259
+ assert_skipped gunzip foo.gz
260
+ assert_skipped gunzip -f foo.gz
261
+ #assert_skipped gunzip -c foo.gz # XXX: works with GNU gzip, not libdeflate's
262
+
263
+
264
+ begin_test '(gzip) overwriting symlink does not follow symlink'
265
+ echo 1 > 1
266
+ echo 2 > 2
267
+ gzip 1
268
+ ln -s 1.gz 2.gz
269
+ gzip -f 2
270
+ gunzip 1.gz
271
+ cmp <(echo 1) 1
272
+
273
+
274
+ begin_test '(gunzip) overwriting symlink does not follow symlink'
275
+ echo 1 > 1
276
+ echo 2 > 2
277
+ gzip 2
278
+ ln -s 1 2
279
+ gunzip -f 2.gz
280
+ cmp <(echo 1) 1
281
+ cmp <(echo 2) 2
282
+
283
+
284
+ begin_test '(gzip) hard linked file skipped without -f or -c'
285
+ cp file orig
286
+ ln file link
287
+ [ $(stat -c %h file) -eq 2 ]
288
+ assert_skipped gzip file
289
+ gzip -c file > /dev/null
290
+ [ $(stat -c %h file) -eq 2 ]
291
+ gzip -f file
292
+ [ $(stat -c %h link) -eq 1 ]
293
+ [ $(stat -c %h file.gz) -eq 1 ]
294
+ cmp link orig
295
+ # XXX: GNU gzip skips hard linked files with -k, libdeflate's doesn't
296
+
297
+
298
+ begin_test '(gunzip) hard linked file skipped without -f or -c'
299
+ gzip file
300
+ ln file.gz link.gz
301
+ cp file.gz orig.gz
302
+ [ $(stat -c %h file.gz) -eq 2 ]
303
+ assert_skipped gunzip file.gz
304
+ gunzip -c file.gz > /dev/null
305
+ [ $(stat -c %h file.gz) -eq 2 ]
306
+ gunzip -f file
307
+ [ $(stat -c %h link.gz) -eq 1 ]
308
+ [ $(stat -c %h file) -eq 1 ]
309
+ cmp link.gz orig.gz
310
+
311
+
312
+ begin_test 'Multiple files'
313
+ cp file file2
314
+ gzip file file2
315
+ [ ! -e file -a ! -e file2 -a -e file.gz -a -e file2.gz ]
316
+ gunzip file.gz file2.gz
317
+ [ -e file -a -e file2 -a ! -e file.gz -a ! -e file2.gz ]
318
+
319
+
320
+ begin_test 'Multiple files, continue on warning'
321
+ mkdir 1
322
+ cp file 2
323
+ assert_skipped gzip 1 2
324
+ [ ! -e 1.gz ]
325
+ cmp file <(gunzip -c 2.gz)
326
+ rmdir 1
327
+ mkdir 1.gz
328
+ assert_skipped gunzip 1.gz 2.gz
329
+ [ ! -e 1 ]
330
+ cmp 2 file
331
+
332
+
333
+ begin_test 'Multiple files, continue on error'
334
+ cp file 1
335
+ cp file 2
336
+ chmod -r 1
337
+ assert_error 'Permission denied' gzip 1 2
338
+ [ ! -e 1.gz ]
339
+ cmp file <(gunzip -c 2.gz)
340
+ rm -f 1
341
+ cp 2.gz 1.gz
342
+ chmod -r 1.gz
343
+ assert_error 'Permission denied' gunzip 1.gz 2.gz
344
+ [ ! -e 1 ]
345
+ cmp 2 file
346
+
347
+
348
+ begin_test 'Compressing empty file'
349
+ echo -n > empty
350
+ gzip empty
351
+ gunzip empty.gz
352
+ cmp /dev/null empty
353
+
354
+
355
+ begin_test 'Decompressing malformed file'
356
+ echo -n > foo.gz
357
+ assert_error '\<(not in gzip format|unexpected end of file)\>' \
358
+ gunzip foo.gz
359
+ echo 1 > foo.gz
360
+ assert_error '\<not in gzip format\>' gunzip foo.gz
361
+ echo abcdefgh > foo.gz
362
+ assert_error '\<not in gzip format\>' gunzip foo.gz
363
+ xxd -r > foo.gz <<-EOF
364
+ 00000000: 1f8b 0800 0000 0000 00ff 4b4c 4a4e 4924 ..........KLJNI$
365
+ 00000010: 1673 0100 6c5b a262 2e00 0000 .s..l[.b....
366
+ EOF
367
+ assert_error '\<(not in gzip format|crc error)\>' gunzip foo.gz
368
+
369
+
370
+ for suf in .foo foo .blaaaaaaaaaaaaaaaargh; do
371
+ begin_test "Custom suffix: $suf"
372
+ gzip -S $suf file
373
+ [ ! -e file -a ! -e file.gz -a -e file$suf ]
374
+ assert_skipped gunzip file$suf
375
+ gunzip -S $suf file$suf
376
+ [ -e file -a ! -e file.gz -a ! -e file$suf ]
377
+ done
378
+ # DIFFERENCE: GNU gzip lower cases suffix, we don't
379
+
380
+
381
+ begin_test 'Empty suffix is rejected'
382
+ assert_error '\<invalid suffix\>' gzip -S '""' file
383
+ assert_error '\<invalid suffix\>' gunzip -S '""' file
384
+
385
+
386
+ begin_test 'Timestamps and mode are preserved'
387
+ chmod 777 file
388
+ orig_stat="$(stat -c '%a;%x;%y' file)"
389
+ gzip file
390
+ sleep 1
391
+ gunzip file.gz
392
+ [ "$(stat -c '%a;%x;%y' file)" = "$orig_stat" ]
393
+
394
+
395
+ begin_test 'Help option'
396
+ gzip -h 2>&1 | grep -q 'Usage'
397
+ gunzip -h 2>&1 | grep -q 'Usage'
398
+
399
+
400
+ begin_test 'Incorrect usage'
401
+ for prog in gzip gunzip; do
402
+ for opt in '--invalid-option' '-0'; do
403
+ assert_error '\<(unrecognized|invalid) option\>' $prog $opt
404
+ done
405
+ done
406
+
407
+
408
+ begin_test 'Version information'
409
+ gzip -V | grep -q Copyright
410
+ gunzip -V | grep -q Copyright
411
+
412
+ CURRENT_TEST=
@@ -0,0 +1,21 @@
1
+ #!/bin/bash
2
+
3
+ set -eu
4
+
5
+ for arch in 'i686' 'x86_64'; do
6
+ make clean
7
+ make -j CC=${arch}-w64-mingw32-gcc CFLAGS="-Werror" all \
8
+ benchmark.exe checksum.exe
9
+ dir=libdeflate-$(git describe --tags | tr -d v)-windows-${arch}-bin
10
+ rm -rf $dir ${dir}.zip
11
+ mkdir $dir
12
+ cp libdeflate.dll libdeflate.lib libdeflate.h *.exe $dir
13
+ ${arch}-w64-mingw32-strip ${dir}/libdeflate.dll ${dir}/*.exe
14
+ for file in COPYING NEWS; do
15
+ sed < $file > ${dir}/${file}.txt -e 's/$/\r/g'
16
+ done
17
+ for file in README.md; do
18
+ sed < $file > ${dir}/${file} -e 's/$/\r/g'
19
+ done
20
+ (cd ${dir} && zip -r ../${dir}.zip .)
21
+ done
@@ -0,0 +1,9 @@
1
+ #!/bin/bash
2
+
3
+ set -eu
4
+
5
+ TOOLCHAIN_DIR=$HOME/src/ddwrt-toolchains/toolchain-mips_34kc_gcc-5.1.0_musl-1.1.9
6
+
7
+ make -j$(grep -c processor /proc/cpuinfo) test_programs \
8
+ CC="$TOOLCHAIN_DIR/bin/mips-openwrt-linux-musl-gcc" \
9
+ CFLAGS="-DNEED_PRINTF -Werror"
@@ -0,0 +1,3 @@
1
+ nmake /f Makefile.msc clean
2
+ nmake /f Makefile.msc
3
+ copy /y *.exe j:\exe\