summaryrefslogtreecommitdiff
path: root/xdelta3
diff options
context:
space:
mode:
Diffstat (limited to 'xdelta3')
-rw-r--r--xdelta3/xdelta3-main.h253
1 files changed, 162 insertions, 91 deletions
diff --git a/xdelta3/xdelta3-main.h b/xdelta3/xdelta3-main.h
index 7210267..1e30e27 100644
--- a/xdelta3/xdelta3-main.h
+++ b/xdelta3/xdelta3-main.h
@@ -50,7 +50,7 @@
50 * again with a more general error message. 50 * again with a more general error message.
51 */ 51 */
52 52
53/******************************************************************************************/ 53/*********************************************************************/
54 54
55#ifndef XD3_POSIX 55#ifndef XD3_POSIX
56#define XD3_POSIX 0 56#define XD3_POSIX 0
@@ -90,7 +90,8 @@ const char* xd3_mainerror(int err_num);
90 90
91/* this is used as in XPR(NT XD3_LIB_ERRMSG (stream, ret)) to print an 91/* this is used as in XPR(NT XD3_LIB_ERRMSG (stream, ret)) to print an
92 * error message from the library. */ 92 * error message from the library. */
93#define XD3_LIB_ERRMSG(stream, ret) "%s: %s\n", xd3_errstring (stream), xd3_mainerror (ret) 93#define XD3_LIB_ERRMSG(stream, ret) "%s: %s\n", \
94 xd3_errstring (stream), xd3_mainerror (ret)
94 95
95#include <stdio.h> /* fprintf */ 96#include <stdio.h> /* fprintf */
96 97
@@ -205,9 +206,12 @@ struct _main_file
205#endif 206#endif
206 207
207 int mode; /* XO_READ and XO_WRITE */ 208 int mode; /* XO_READ and XO_WRITE */
208 const char *filename; /* File name or /dev/stdin, /dev/stdout, /dev/stderr. */ 209 const char *filename; /* File name or /dev/stdin,
209 char *filename_copy; /* File name or /dev/stdin, /dev/stdout, /dev/stderr. */ 210 * /dev/stdout, /dev/stderr. */
210 const char *realname; /* File name or /dev/stdin, /dev/stdout, /dev/stderr. */ 211 char *filename_copy; /* File name or /dev/stdin,
212 * /dev/stdout, /dev/stderr. */
213 const char *realname; /* File name or /dev/stdin,
214 * /dev/stdout, /dev/stderr. */
211 const main_extcomp *compressor; /* External compression struct. */ 215 const main_extcomp *compressor; /* External compression struct. */
212 int flags; /* RD_FIRST, RD_NONEXTERNAL, ... */ 216 int flags; /* RD_FIRST, RD_NONEXTERNAL, ... */
213 xoff_t nread; /* for input position */ 217 xoff_t nread; /* for input position */
@@ -270,7 +274,7 @@ static int option_use_checksum = 1;
270static int option_use_altcodetable = 0; 274static int option_use_altcodetable = 0;
271static char* option_smatch_config = NULL; 275static char* option_smatch_config = NULL;
272static int option_no_compress = 0; 276static int option_no_compress = 0;
273static int option_no_output = 0; /* do not open or write output */ 277static int option_no_output = 0; /* do not write output */
274static const char *option_source_filename = NULL; 278static const char *option_source_filename = NULL;
275 279
276static int option_level = XD3_DEFAULT_LEVEL; 280static int option_level = XD3_DEFAULT_LEVEL;
@@ -304,7 +308,7 @@ static usize_t lru_size = 0;
304static main_blklru *lru = NULL; /* array of lru_size elts */ 308static main_blklru *lru = NULL; /* array of lru_size elts */
305static main_blklru_list lru_list; 309static main_blklru_list lru_list;
306static main_blklru_list lru_free; 310static main_blklru_list lru_free;
307static int do_not_lru = 0; /* set to avoid lru, instead discard oldest */ 311static int do_not_lru = 0; /* set to avoid lru */
308 312
309static int lru_hits = 0; 313static int lru_hits = 0;
310static int lru_misses = 0; 314static int lru_misses = 0;
@@ -316,18 +320,19 @@ static int allow_fake_source = 0;
316/* State for xdelta3 recode */ 320/* State for xdelta3 recode */
317static xd3_stream *recode_stream = NULL; 321static xd3_stream *recode_stream = NULL;
318 322
319/* This array of compressor types is compiled even if EXTERNAL_COMPRESSION is false just so 323/* This array of compressor types is compiled even if EXTERNAL_COMPRESSION is
320 * the program knows the mapping of IDENT->NAME. */ 324 * false just so the program knows the mapping of IDENT->NAME. */
321static main_extcomp extcomp_types[] = 325static main_extcomp extcomp_types[] =
322{ 326{
323 /* The entry for xdelta3 must be 0 because the program_name is set there. */ 327 /* The entry for xdelta3 must be 0 because the program_name is set there. */
324 { "xdelta3", "-cfq", "xdelta3", "-dcfq", "X", "\xd6\xc3\xc4", 3, RD_NONEXTERNAL }, 328 { "xdelta3", "-cfq", "xdelta3", "-dcfq", "X", "\xd6\xc3\xc4", 3,
329 RD_NONEXTERNAL },
325 { "bzip2", "-cf", "bzip2", "-dcf", "B", "BZh", 3, 0 }, 330 { "bzip2", "-cf", "bzip2", "-dcf", "B", "BZh", 3, 0 },
326 { "gzip", "-cf", "gzip", "-dcf", "G", "\037\213", 2, 0 }, 331 { "gzip", "-cf", "gzip", "-dcf", "G", "\037\213", 2, 0 },
327 { "compress", "-cf", "uncompress", "-cf", "Z", "\037\235", 2, 0 }, 332 { "compress", "-cf", "uncompress", "-cf", "Z", "\037\235", 2, 0 },
328 333
329 /* TODO: add commandline support for magic-less formats */ 334 /* TODO: add commandline support for magic-less formats */
330 /*{ "lzma", "-cf", "lzma", "-dcf", "M", "]\000", 2, 0 },*/ 335 /*{ "lzma", "-cf", "lzma", "-dcf", "M", "]\000", 2, 0 },*/
331}; 336};
332 337
333// }; 338// };
@@ -504,7 +509,8 @@ xd3_mainerror(int err_num) {
504 return x; 509 return x;
505 } 510 }
506 memset (err_buf, 0, 256); 511 memset (err_buf, 0, 256);
507 FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, 512 FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM |
513 FORMAT_MESSAGE_IGNORE_INSERTS,
508 NULL, err_num, 514 NULL, err_num,
509 MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), 515 MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT),
510 err_buf, 256, NULL); 516 err_buf, 256, NULL);
@@ -658,7 +664,8 @@ main_atou (const char* arg, usize_t *xo, usize_t low,
658 664
659#define XOPEN_OPNAME (xfile->mode == XO_READ ? "read" : "write") 665#define XOPEN_OPNAME (xfile->mode == XO_READ ? "read" : "write")
660#define XOPEN_STDIO (xfile->mode == XO_READ ? "rb" : "wb") 666#define XOPEN_STDIO (xfile->mode == XO_READ ? "rb" : "wb")
661#define XOPEN_POSIX (xfile->mode == XO_READ ? O_RDONLY : O_WRONLY | O_CREAT | O_TRUNC) 667#define XOPEN_POSIX (xfile->mode == XO_READ ? \
668 O_RDONLY : O_WRONLY | O_CREAT | O_TRUNC)
662#define XOPEN_MODE (xfile->mode == XO_READ ? 0 : 0666) 669#define XOPEN_MODE (xfile->mode == XO_READ ? 0 : 0666)
663 670
664#define XF_ERROR(op, name, ret) \ 671#define XF_ERROR(op, name, ret) \
@@ -672,13 +679,17 @@ main_atou (const char* arg, usize_t *xo, usize_t low,
672 679
673#elif XD3_POSIX 680#elif XD3_POSIX
674#define XFNO(f) f->file 681#define XFNO(f) f->file
675#define XSTDOUT_XF(f) { (f)->file = STDOUT_FILENO; (f)->filename = "/dev/stdout"; } 682#define XSTDOUT_XF(f) \
676#define XSTDIN_XF(f) { (f)->file = STDIN_FILENO; (f)->filename = "/dev/stdin"; } 683 { (f)->file = STDOUT_FILENO; (f)->filename = "/dev/stdout"; }
684#define XSTDIN_XF(f) \
685 { (f)->file = STDIN_FILENO; (f)->filename = "/dev/stdin"; }
677 686
678#elif XD3_WIN32 687#elif XD3_WIN32
679#define XFNO(f) -1 688#define XFNO(f) -1
680#define XSTDOUT_XF(f) { (f)->file = winStartupInfo.hStdOutput; (f)->filename = "(stdout)"; } 689#define XSTDOUT_XF(f) \
681#define XSTDIN_XF(f) { (f)->file = winStartupInfo.hStdInput; (f)->filename = "(stdin)"; } 690 { (f)->file = winStartupInfo.hStdOutput; (f)->filename = "(stdout)"; }
691#define XSTDIN_XF(f) \
692 { (f)->file = winStartupInfo.hStdInput; (f)->filename = "(stdin)"; }
682#endif 693#endif
683 694
684static void 695static void
@@ -794,7 +805,8 @@ main_file_open (main_file *xfile, const char* name, int mode)
794 (mode == XO_READ) ? GENERIC_READ : GENERIC_WRITE, 805 (mode == XO_READ) ? GENERIC_READ : GENERIC_WRITE,
795 FILE_SHARE_READ, 806 FILE_SHARE_READ,
796 NULL, 807 NULL,
797 (mode == XO_READ) ? OPEN_EXISTING : (option_force ? CREATE_ALWAYS : CREATE_NEW), 808 (mode == XO_READ) ? OPEN_EXISTING :
809 (option_force ? CREATE_ALWAYS : CREATE_NEW),
798 FILE_ATTRIBUTE_NORMAL, 810 FILE_ATTRIBUTE_NORMAL,
799 NULL); 811 NULL);
800 if (xfile->file == INVALID_HANDLE_VALUE) { 812 if (xfile->file == INVALID_HANDLE_VALUE) {
@@ -860,7 +872,8 @@ main_file_exists (main_file *xfile)
860typedef int (xd3_posix_func) (int fd, uint8_t *buf, usize_t size); 872typedef int (xd3_posix_func) (int fd, uint8_t *buf, usize_t size);
861 873
862static int 874static int
863xd3_posix_io (int fd, uint8_t *buf, usize_t size, xd3_posix_func *func, usize_t *nread) 875xd3_posix_io (int fd, uint8_t *buf, usize_t size,
876 xd3_posix_func *func, usize_t *nread)
864{ 877{
865 int ret; 878 int ret;
866 usize_t nproc = 0; 879 usize_t nproc = 0;
@@ -931,7 +944,8 @@ main_file_read (main_file *ifile,
931 } 944 }
932 else 945 else
933 { 946 {
934 if (option_verbose > 3) { XPR(NT "main read: %s: %u\n", ifile->filename, (*nread)); } 947 if (option_verbose > 3) { XPR(NT "main read: %s: %u\n",
948 ifile->filename, (*nread)); }
935 ifile->nread += (*nread); 949 ifile->nread += (*nread);
936 } 950 }
937 951
@@ -971,7 +985,8 @@ main_file_write (main_file *ofile, uint8_t *buf, usize_t size, const char *msg)
971 } 985 }
972 else 986 else
973 { 987 {
974 if (option_verbose > 3) { XPR(NT "main write: %s: %u\n", ofile->filename, size); } 988 if (option_verbose > 3) { XPR(NT "main write: %s: %u\n",
989 ofile->filename, size); }
975 ofile->nwrite += size; 990 ofile->nwrite += size;
976 } 991 }
977 992
@@ -987,7 +1002,8 @@ main_file_seek (main_file *xfile, xoff_t pos)
987 if (fseek (xfile->file, pos, SEEK_SET) != 0) { ret = get_errno (); } 1002 if (fseek (xfile->file, pos, SEEK_SET) != 0) { ret = get_errno (); }
988 1003
989#elif XD3_POSIX 1004#elif XD3_POSIX
990 if ((xoff_t) lseek (xfile->file, pos, SEEK_SET) != pos) { ret = get_errno (); } 1005 if ((xoff_t) lseek (xfile->file, pos, SEEK_SET) != pos)
1006 { ret = get_errno (); }
991 1007
992#elif XD3_WIN32 1008#elif XD3_WIN32
993 LARGE_INTEGER move, out; 1009 LARGE_INTEGER move, out;
@@ -1014,7 +1030,8 @@ main_write_output (xd3_stream* stream, main_file *ofile)
1014 int ret; 1030 int ret;
1015 1031
1016 if (stream->avail_out > 0 && 1032 if (stream->avail_out > 0 &&
1017 (ret = main_file_write (ofile, stream->next_out, stream->avail_out, "write failed"))) 1033 (ret = main_file_write (ofile, stream->next_out,
1034 stream->avail_out, "write failed")))
1018 { 1035 {
1019 return ret; 1036 return ret;
1020 } 1037 }
@@ -1296,7 +1313,9 @@ main_print_func (xd3_stream* stream, main_file *xfile)
1296 main_file i, o, s; 1313 main_file i, o, s;
1297 XD3_ASSERT (apphead != NULL); 1314 XD3_ASSERT (apphead != NULL);
1298 VC(UT "VCDIFF application header: ")VE; 1315 VC(UT "VCDIFF application header: ")VE;
1299 if ((ret = main_file_write (xfile, apphead, appheadsz, "print")) != 0) { return ret; } 1316 if ((ret = main_file_write (xfile, apphead,
1317 appheadsz, "print")) != 0)
1318 { return ret; }
1300 VC(UT "\n")VE; 1319 VC(UT "\n")VE;
1301 1320
1302 main_file_init (& i); 1321 main_file_init (& i);
@@ -1305,8 +1324,10 @@ main_print_func (xd3_stream* stream, main_file *xfile)
1305 option_quiet = 1; 1324 option_quiet = 1;
1306 main_get_appheader (stream, &i, & o, & s); 1325 main_get_appheader (stream, &i, & o, & s);
1307 option_quiet = sq; 1326 option_quiet = sq;
1308 if ((ret = main_print_vcdiff_file (xfile, & o, "output"))) { return ret; } 1327 if ((ret = main_print_vcdiff_file (xfile, & o, "output")))
1309 if ((ret = main_print_vcdiff_file (xfile, & s, "source"))) { return ret; } 1328 { return ret; }
1329 if ((ret = main_print_vcdiff_file (xfile, & s, "source")))
1330 { return ret; }
1310 main_file_cleanup (& i); 1331 main_file_cleanup (& i);
1311 main_file_cleanup (& o); 1332 main_file_cleanup (& o);
1312 main_file_cleanup (& s); 1333 main_file_cleanup (& s);
@@ -1328,7 +1349,8 @@ main_print_func (xd3_stream* stream, main_file *xfile)
1328 1349
1329 if ((stream->dec_win_ind & VCD_ADLER32) != 0) 1350 if ((stream->dec_win_ind & VCD_ADLER32) != 0)
1330 { 1351 {
1331 VC(UT "VCDIFF adler32 checksum: %08X\n", (usize_t)stream->dec_adler32)VE; 1352 VC(UT "VCDIFF adler32 checksum: %08X\n",
1353 (usize_t)stream->dec_adler32)VE;
1332 } 1354 }
1333 1355
1334 if (stream->dec_del_ind != 0) 1356 if (stream->dec_del_ind != 0)
@@ -1348,16 +1370,23 @@ main_print_func (xd3_stream* stream, main_file *xfile)
1348 1370
1349 if (SRCORTGT (stream->dec_win_ind)) 1371 if (SRCORTGT (stream->dec_win_ind))
1350 { 1372 {
1351 VC(UT "VCDIFF copy window length: %u\n", (usize_t)stream->dec_cpylen)VE; 1373 VC(UT "VCDIFF copy window length: %u\n",
1352 VC(UT "VCDIFF copy window offset: %"Q"u\n", stream->dec_cpyoff)VE; 1374 (usize_t)stream->dec_cpylen)VE;
1375 VC(UT "VCDIFF copy window offset: %"Q"u\n",
1376 stream->dec_cpyoff)VE;
1353 } 1377 }
1354 1378
1355 VC(UT "VCDIFF delta encoding length: %u\n", (usize_t)stream->dec_enclen)VE; 1379 VC(UT "VCDIFF delta encoding length: %u\n",
1356 VC(UT "VCDIFF target window length: %u\n", (usize_t)stream->dec_tgtlen)VE; 1380 (usize_t)stream->dec_enclen)VE;
1381 VC(UT "VCDIFF target window length: %u\n",
1382 (usize_t)stream->dec_tgtlen)VE;
1357 1383
1358 VC(UT "VCDIFF data section length: %u\n", (usize_t)stream->data_sect.size)VE; 1384 VC(UT "VCDIFF data section length: %u\n",
1359 VC(UT "VCDIFF inst section length: %u\n", (usize_t)stream->inst_sect.size)VE; 1385 (usize_t)stream->data_sect.size)VE;
1360 VC(UT "VCDIFF addr section length: %u\n", (usize_t)stream->addr_sect.size)VE; 1386 VC(UT "VCDIFF inst section length: %u\n",
1387 (usize_t)stream->inst_sect.size)VE;
1388 VC(UT "VCDIFF addr section length: %u\n",
1389 (usize_t)stream->addr_sect.size)VE;
1361 1390
1362 ret = 0; 1391 ret = 0;
1363 if ((stream->flags & XD3_JUST_HDR) != 0) 1392 if ((stream->flags & XD3_JUST_HDR) != 0)
@@ -1536,7 +1565,8 @@ main_pipe_write (int outfd, uint8_t *exist_buf, usize_t remain)
1536{ 1565{
1537 int ret; 1566 int ret;
1538 1567
1539 if ((ret = xd3_posix_io (outfd, exist_buf, remain, (xd3_posix_func*) &write, NULL))) 1568 if ((ret = xd3_posix_io (outfd, exist_buf, remain,
1569 (xd3_posix_func*) &write, NULL)))
1540 { 1570 {
1541 XPR(NT "pipe write failed: %s", xd3_mainerror (ret)); 1571 XPR(NT "pipe write failed: %s", xd3_mainerror (ret));
1542 return ret; 1572 return ret;
@@ -1617,7 +1647,8 @@ main_pipe_copier (uint8_t *pipe_buf,
1617 break; 1647 break;
1618 } 1648 }
1619 1649
1620 if ((ret = main_file_read (ifile, pipe_buf, pipe_bufsize, & nread, "pipe read failed")) < 0) 1650 if ((ret = main_file_read (ifile, pipe_buf, pipe_bufsize,
1651 & nread, "pipe read failed")) < 0)
1621 { 1652 {
1622 return ret; 1653 return ret;
1623 } 1654 }
@@ -1641,9 +1672,10 @@ main_input_decompress_setup (const main_extcomp *decomp,
1641 usize_t pipe_avail, 1672 usize_t pipe_avail,
1642 usize_t *nread) 1673 usize_t *nread)
1643{ 1674{
1644 int outpipefd[2], inpipefd[2]; /* The two pipes: input and output file descriptors. */ 1675 /* The two pipes: input and output file descriptors. */
1645 int input_fd = -1; /* The resulting input_fd (output of decompression). */ 1676 int outpipefd[2], inpipefd[2];
1646 pid_t decomp_id, copier_id; /* The two subprocs. */ 1677 int input_fd = -1; /* The resulting input_fd (output of decompression). */
1678 pid_t decomp_id, copier_id; /* The two subprocs. */
1647 int ret; 1679 int ret;
1648 1680
1649 outpipefd[0] = outpipefd[1] = -1; 1681 outpipefd[0] = outpipefd[1] = -1;
@@ -1695,10 +1727,12 @@ main_input_decompress_setup (const main_extcomp *decomp,
1695 int exitval = 0; 1727 int exitval = 0;
1696 1728
1697 if (close (inpipefd[PIPE_READ_FD]) || 1729 if (close (inpipefd[PIPE_READ_FD]) ||
1698 main_pipe_copier (pipe_buf, pipe_bufsize, pipe_avail, ifile, inpipefd[PIPE_WRITE_FD]) || 1730 main_pipe_copier (pipe_buf, pipe_bufsize, pipe_avail,
1731 ifile, inpipefd[PIPE_WRITE_FD]) ||
1699 close (inpipefd[PIPE_WRITE_FD])) 1732 close (inpipefd[PIPE_WRITE_FD]))
1700 { 1733 {
1701 XPR(NT "child copier process failed: %s\n", xd3_mainerror (get_errno ())); 1734 XPR(NT "child copier process failed: %s\n",
1735 xd3_mainerror (get_errno ()));
1702 exitval = 1; 1736 exitval = 1;
1703 } 1737 }
1704 1738
@@ -1707,7 +1741,8 @@ main_input_decompress_setup (const main_extcomp *decomp,
1707 1741
1708 ext_subprocs[1] = copier_id; 1742 ext_subprocs[1] = copier_id;
1709 1743
1710 /* The parent closes both pipes after duplicating the output of compression. */ 1744 /* The parent closes both pipes after duplicating the output of
1745 * compression. */
1711 input_fd = dup (outpipefd[PIPE_READ_FD]); 1746 input_fd = dup (outpipefd[PIPE_READ_FD]);
1712 1747
1713 if (input_fd < 0 || 1748 if (input_fd < 0 ||
@@ -1736,7 +1771,8 @@ main_input_decompress_setup (const main_extcomp *decomp,
1736 ifile->compressor = decomp; 1771 ifile->compressor = decomp;
1737 1772
1738 /* Now the input file is decompressed. */ 1773 /* Now the input file is decompressed. */
1739 return main_file_read (ifile, input_buf, input_bufsize, nread, "input decompression failed"); 1774 return main_file_read (ifile, input_buf, input_bufsize,
1775 nread, "input decompression failed");
1740 1776
1741 pipe_cleanup: 1777 pipe_cleanup:
1742 close (input_fd); 1778 close (input_fd);
@@ -1787,7 +1823,8 @@ main_decompress_input_check (main_file *ifile,
1787 if ((check_nread > decomp->magic_size) && 1823 if ((check_nread > decomp->magic_size) &&
1788 /* The following expr skips decompression if we are trying 1824 /* The following expr skips decompression if we are trying
1789 * to read a VCDIFF input and that is the magic number. */ 1825 * to read a VCDIFF input and that is the magic number. */
1790 !((decomp->flags & RD_NONEXTERNAL) && (ifile->flags & RD_NONEXTERNAL)) && 1826 !((decomp->flags & RD_NONEXTERNAL) &&
1827 (ifile->flags & RD_NONEXTERNAL)) &&
1791 memcmp (check_buf, decomp->magic, decomp->magic_size) == 0) 1828 memcmp (check_buf, decomp->magic, decomp->magic_size) == 0)
1792 { 1829 {
1793 if (! option_quiet) 1830 if (! option_quiet)
@@ -1840,7 +1877,10 @@ main_decompress_source (main_file *sfile, xd3_source *source)
1840 /* Make a template for mkstmp() */ 1877 /* Make a template for mkstmp() */
1841 if (tmpdir == NULL) { tmpdir = "/tmp"; } 1878 if (tmpdir == NULL) { tmpdir = "/tmp"; }
1842 if ((tmpname = 1879 if ((tmpname =
1843 (char*) main_malloc (strlen (tmpdir) + sizeof (tmpl) + 1)) == NULL) { return ENOMEM; } 1880 (char*) main_malloc (strlen (tmpdir) + sizeof (tmpl) + 1)) == NULL)
1881 {
1882 return ENOMEM;
1883 }
1844 sprintf (tmpname, "%s%s", tmpdir, tmpl); 1884 sprintf (tmpname, "%s%s", tmpdir, tmpl);
1845 1885
1846 XD3_ASSERT (ext_tmpfile == NULL); 1886 XD3_ASSERT (ext_tmpfile == NULL);
@@ -1849,7 +1889,8 @@ main_decompress_source (main_file *sfile, xd3_source *source)
1849 /* Open the output FD. */ 1889 /* Open the output FD. */
1850 if ((output_fd = mkstemp (tmpname)) < 0) 1890 if ((output_fd = mkstemp (tmpname)) < 0)
1851 { 1891 {
1852 XPR(NT "mkstemp failed: %s: %s", tmpname, xd3_mainerror (ret = get_errno ())); 1892 XPR(NT "mkstemp failed: %s: %s",
1893 tmpname, xd3_mainerror (ret = get_errno ()));
1853 goto cleanup; 1894 goto cleanup;
1854 } 1895 }
1855 1896
@@ -1886,7 +1927,8 @@ main_decompress_source (main_file *sfile, xd3_source *source)
1886 /* Setup pipes: write to the output file, read from the pipe. */ 1927 /* Setup pipes: write to the output file, read from the pipe. */
1887 if (dup2 (input_fd, STDIN_FILENO) < 0 || 1928 if (dup2 (input_fd, STDIN_FILENO) < 0 ||
1888 dup2 (output_fd, STDOUT_FILENO) < 0 || 1929 dup2 (output_fd, STDOUT_FILENO) < 0 ||
1889 execlp (decomp->decomp_cmdname, decomp->decomp_cmdname, decomp->decomp_options, NULL)) 1930 execlp (decomp->decomp_cmdname, decomp->decomp_cmdname,
1931 decomp->decomp_options, NULL))
1890 { 1932 {
1891 XPR(NT "child process %s failed to execute: %s\n", 1933 XPR(NT "child process %s failed to execute: %s\n",
1892 decomp->decomp_cmdname, xd3_mainerror (get_errno ())); 1934 decomp->decomp_cmdname, xd3_mainerror (get_errno ()));
@@ -2323,7 +2365,8 @@ main_open_output (xd3_stream *stream, main_file *ofile)
2323 * application header is received. Stream may be NULL, in which case 2365 * application header is received. Stream may be NULL, in which case
2324 * xd3_set_source is not called. */ 2366 * xd3_set_source is not called. */
2325static int 2367static int
2326main_set_source (xd3_stream *stream, int cmd, main_file *sfile, xd3_source *source) 2368main_set_source (xd3_stream *stream, int cmd,
2369 main_file *sfile, xd3_source *source)
2327{ 2370{
2328 int ret = 0; 2371 int ret = 0;
2329 usize_t i; 2372 usize_t i;
@@ -2448,7 +2491,8 @@ main_set_source (xd3_stream *stream, int cmd, main_file *sfile, xd3_source *sour
2448 XPR(NT "source block size: %u\n", source->blksize); 2491 XPR(NT "source block size: %u\n", source->blksize);
2449 } 2492 }
2450 2493
2451 if ((lru = (main_blklru*) main_malloc (sizeof (main_blklru) * lru_size)) == NULL) 2494 if ((lru = (main_blklru*)
2495 main_malloc (sizeof (main_blklru) * lru_size)) == NULL)
2452 { 2496 {
2453 ret = ENOMEM; 2497 ret = ENOMEM;
2454 goto error; 2498 goto error;
@@ -2610,13 +2654,14 @@ main_getblk_func (xd3_stream *stream,
2610 { 2654 {
2611 if (blru->blkno != (xoff_t)-1) 2655 if (blru->blkno != (xoff_t)-1)
2612 { 2656 {
2613 XPR(NT "source block %"Q"u ejects %"Q"u (lru_hits=%u, lru_misses=%u, lru_filled=%u)\n", 2657 XPR(NT "source block %"Q"u ejects %"Q"u (lru_hits=%u, "
2658 "lru_misses=%u, lru_filled=%u)\n",
2614 blkno, blru->blkno, lru_hits, lru_misses, lru_filled); 2659 blkno, blru->blkno, lru_hits, lru_misses, lru_filled);
2615 } 2660 }
2616 else 2661 else
2617 { 2662 {
2618 XPR(NT "source block %"Q"u read (lru_hits=%u, lru_misses=%u, lru_filled=%u)\n", 2663 XPR(NT "source block %"Q"u read (lru_hits=%u, lru_misses=%u, "
2619 blkno, lru_hits, lru_misses, lru_filled); 2664 "lru_filled=%u)\n", blkno, lru_hits, lru_misses, lru_filled);
2620 } 2665 }
2621 } 2666 }
2622 2667
@@ -2769,11 +2814,16 @@ main_input (xd3_cmd cmd,
2769 stream_flags |= XD3_NOCOMPRESS; 2814 stream_flags |= XD3_NOCOMPRESS;
2770 config.smatch_cfg = XD3_SMATCH_FASTEST; 2815 config.smatch_cfg = XD3_SMATCH_FASTEST;
2771 } 2816 }
2772 else if (option_level == 1) { config.smatch_cfg = XD3_SMATCH_FASTEST; } 2817 else if (option_level == 1)
2773 else if (option_level == 2) { config.smatch_cfg = XD3_SMATCH_FASTER; } 2818 { config.smatch_cfg = XD3_SMATCH_FASTEST; }
2774 else if (option_level <= 5) { config.smatch_cfg = XD3_SMATCH_FAST; } 2819 else if (option_level == 2)
2775 else if (option_level == 6) { config.smatch_cfg = XD3_SMATCH_DEFAULT; } 2820 { config.smatch_cfg = XD3_SMATCH_FASTER; }
2776 else { config.smatch_cfg = XD3_SMATCH_SLOW; } 2821 else if (option_level <= 5)
2822 { config.smatch_cfg = XD3_SMATCH_FAST; }
2823 else if (option_level == 6)
2824 { config.smatch_cfg = XD3_SMATCH_DEFAULT; }
2825 else
2826 { config.smatch_cfg = XD3_SMATCH_SLOW; }
2777 } 2827 }
2778 break; 2828 break;
2779#endif 2829#endif
@@ -2841,7 +2891,8 @@ main_input (xd3_cmd cmd,
2841 2891
2842 try_read = (usize_t) min ((xoff_t) config.winsize, input_remain); 2892 try_read = (usize_t) min ((xoff_t) config.winsize, input_remain);
2843 2893
2844 if ((ret = main_read_primary_input (ifile, main_bdata, try_read, & nread))) 2894 if ((ret = main_read_primary_input (ifile, main_bdata,
2895 try_read, & nread)))
2845 { 2896 {
2846 return EXIT_FAILURE; 2897 return EXIT_FAILURE;
2847 } 2898 }
@@ -2881,9 +2932,10 @@ main_input (xd3_cmd cmd,
2881 { 2932 {
2882 XD3_ASSERT (stream.current_window == 0); 2933 XD3_ASSERT (stream.current_window == 0);
2883 2934
2884 /* Need to process the appheader as soon as possible. It may contain a 2935 /* Need to process the appheader as soon as possible. It may
2885 * suggested default filename/decompression routine for the ofile, and it may 2936 * contain a suggested default filename/decompression routine for
2886 * contain default/decompression routine for the sources. */ 2937 * the ofile, and it may contain default/decompression routine for
2938 * the sources. */
2887 if (cmd == CMD_DECODE) 2939 if (cmd == CMD_DECODE)
2888 { 2940 {
2889 int have_src = sfile->filename != NULL; 2941 int have_src = sfile->filename != NULL;
@@ -2895,14 +2947,15 @@ main_input (xd3_cmd cmd,
2895 2947
2896 recv_src = sfile->filename != NULL; 2948 recv_src = sfile->filename != NULL;
2897 2949
2898 /* Check if the user expected a source to be required although it was not. */ 2950 /* Check if the user expected a source to be required although
2951 * it was not. */
2899 if (have_src && ! need_src && ! option_quiet) 2952 if (have_src && ! need_src && ! option_quiet)
2900 { 2953 {
2901 XPR(NT "warning: output window %"Q"u does not copy source\n", stream.current_window); 2954 XPR(NT "warning: output window %"Q"u does not "
2955 "copy source\n", stream.current_window);
2902 } 2956 }
2903 2957
2904 /* Check if we have no source name and need one. */ 2958 /* Check if we have no source name and need one. */
2905 /* TODO: this doesn't fire due to cpyblocks_ calculation check? */
2906 if (need_src && ! recv_src) 2959 if (need_src && ! recv_src)
2907 { 2960 {
2908 XPR(NT "input requires a source file, use -s\n"); 2961 XPR(NT "input requires a source file, use -s\n");
@@ -2910,7 +2963,8 @@ main_input (xd3_cmd cmd,
2910 } 2963 }
2911 2964
2912 /* Now open the source file. */ 2965 /* Now open the source file. */
2913 if (need_src && (ret = main_set_source (& stream, cmd, sfile, & source))) 2966 if (need_src &&
2967 (ret = main_set_source (& stream, cmd, sfile, & source)))
2914 { 2968 {
2915 return EXIT_FAILURE; 2969 return EXIT_FAILURE;
2916 } 2970 }
@@ -2920,7 +2974,8 @@ main_input (xd3_cmd cmd,
2920 cmd == CMD_PRINTDELTA || 2974 cmd == CMD_PRINTDELTA ||
2921 cmd == CMD_RECODE) 2975 cmd == CMD_RECODE)
2922 { 2976 {
2923 if (xd3_decoder_needs_source (& stream) && sfile->filename == NULL) 2977 if (xd3_decoder_needs_source (& stream) &&
2978 sfile->filename == NULL)
2924 { 2979 {
2925 allow_fake_source = 1; 2980 allow_fake_source = 1;
2926 sfile->filename = "<placeholder>"; 2981 sfile->filename = "<placeholder>";
@@ -2951,7 +3006,8 @@ main_input (xd3_cmd cmd,
2951 { 3006 {
2952 return EXIT_FAILURE; 3007 return EXIT_FAILURE;
2953 } 3008 }
2954 if ((ret = output_func (& stream, ofile)) && (ret != PRINTHDR_SPECIAL)) 3009 if ((ret = output_func (& stream, ofile)) &&
3010 (ret != PRINTHDR_SPECIAL))
2955 { 3011 {
2956 return EXIT_FAILURE; 3012 return EXIT_FAILURE;
2957 } 3013 }
@@ -2972,21 +3028,25 @@ main_input (xd3_cmd cmd,
2972 { 3028 {
2973 if (IS_ENCODE (cmd) || cmd == CMD_DECODE || cmd == CMD_RECODE) 3029 if (IS_ENCODE (cmd) || cmd == CMD_DECODE || cmd == CMD_RECODE)
2974 { 3030 {
2975 if (! option_quiet && IS_ENCODE (cmd) && main_file_isopen (sfile)) 3031 if (! option_quiet && IS_ENCODE (cmd) &&
3032 main_file_isopen (sfile))
2976 { 3033 {
2977 /* Warn when no source copies are found */ 3034 /* Warn when no source copies are found */
2978 if (! xd3_encoder_used_source (& stream)) 3035 if (! xd3_encoder_used_source (& stream))
2979 { 3036 {
2980 XPR(NT "warning: input window %"Q"u..%"Q"u has no source copies\n", 3037 XPR(NT "warning: input window %"Q"u..%"Q"u has "
3038 "no source copies\n",
2981 stream.current_window * option_winsize, 3039 stream.current_window * option_winsize,
2982 (stream.current_window+1) * option_winsize); 3040 (stream.current_window+1) * option_winsize);
2983 } 3041 }
2984 3042
2985 /* Limited instruction buffer size affects source copies */ 3043 /* Limited i-buffer size affects source copies */
2986 if (option_verbose > 1 && stream.i_slots_used > stream.iopt_size) 3044 if (option_verbose > 1 &&
3045 stream.i_slots_used > stream.iopt_size)
2987 { 3046 {
2988 XPR(NT "warning: input position %"Q"u overflowed instruction buffer, " 3047 XPR(NT "warning: input position %"Q"u overflowed "
2989 "needed %u (vs. %u), consider raising -I\n", 3048 "instruction buffer, needed %u (vs. %u), "
3049 "consider raising -I\n",
2990 stream.current_window * option_winsize, 3050 stream.current_window * option_winsize,
2991 stream.i_slots_used, stream.iopt_size); 3051 stream.i_slots_used, stream.iopt_size);
2992 } 3052 }
@@ -2998,14 +3058,17 @@ main_input (xd3_cmd cmd,
2998 char rdb[32], wdb[32]; 3058 char rdb[32], wdb[32];
2999 char trdb[32], twdb[32]; 3059 char trdb[32], twdb[32];
3000 long millis = get_millisecs_since (); 3060 long millis = get_millisecs_since ();
3001 usize_t this_read = (usize_t)(stream.total_in - last_total_in); 3061 usize_t this_read = (usize_t)(stream.total_in -
3002 usize_t this_write = (usize_t)(stream.total_out - last_total_out); 3062 last_total_in);
3063 usize_t this_write = (usize_t)(stream.total_out -
3064 last_total_out);
3003 last_total_in = stream.total_in; 3065 last_total_in = stream.total_in;
3004 last_total_out = stream.total_out; 3066 last_total_out = stream.total_out;
3005 3067
3006 if (option_verbose > 1) 3068 if (option_verbose > 1)
3007 { 3069 {
3008 XPR(NT "%"Q"u: in %s (%s): out %s (%s): total in %s: out %s: %s\n", 3070 XPR(NT "%"Q"u: in %s (%s): out %s (%s): "
3071 "total in %s: out %s: %s\n",
3009 stream.current_window, 3072 stream.current_window,
3010 main_format_bcnt (this_read, rdb), 3073 main_format_bcnt (this_read, rdb),
3011 main_format_rate (this_read, millis, rrateavg), 3074 main_format_rate (this_read, millis, rrateavg),
@@ -3017,7 +3080,8 @@ main_input (xd3_cmd cmd,
3017 } 3080 }
3018 else 3081 else
3019 { 3082 {
3020 XPR(NT "%"Q"u: in %s: out %s: total in %s: out %s: %s\n", 3083 XPR(NT "%"Q"u: in %s: out %s: total in %s: "
3084 "out %s: %s\n",
3021 stream.current_window, 3085 stream.current_window,
3022 main_format_bcnt (this_read, rdb), 3086 main_format_bcnt (this_read, rdb),
3023 main_format_bcnt (this_write, wdb), 3087 main_format_bcnt (this_write, wdb),
@@ -3089,8 +3153,10 @@ done:
3089 3153
3090 if (option_verbose > 2) 3154 if (option_verbose > 2)
3091 { 3155 {
3092 XPR(NT "source copies: %"Q"u (%"Q"u bytes)\n", stream.n_scpy, stream.l_scpy); 3156 XPR(NT "source copies: %"Q"u (%"Q"u bytes)\n",
3093 XPR(NT "target copies: %"Q"u (%"Q"u bytes)\n", stream.n_tcpy, stream.l_tcpy); 3157 stream.n_scpy, stream.l_scpy);
3158 XPR(NT "target copies: %"Q"u (%"Q"u bytes)\n",
3159 stream.n_tcpy, stream.l_tcpy);
3094 XPR(NT "adds: %"Q"u (%"Q"u bytes)\n", stream.n_add, stream.l_add); 3160 XPR(NT "adds: %"Q"u (%"Q"u bytes)\n", stream.n_add, stream.l_add);
3095 XPR(NT "runs: %"Q"u (%"Q"u bytes)\n", stream.n_run, stream.l_run); 3161 XPR(NT "runs: %"Q"u (%"Q"u bytes)\n", stream.n_run, stream.l_run);
3096 } 3162 }
@@ -3220,7 +3286,8 @@ main (int argc, char **argv)
3220 main_file ifile; 3286 main_file ifile;
3221 main_file ofile; 3287 main_file ofile;
3222 main_file sfile; 3288 main_file sfile;
3223 static const char *flags = "0123456789cdefhnqvDJNORTVs:B:C:E:F:I:L:O:M:P:W:A::S::"; 3289 static const char *flags =
3290 "0123456789cdefhnqvDJNORTVs:B:C:E:F:I:L:O:M:P:W:A::S::";
3224 int my_optind; 3291 int my_optind;
3225 char *my_optarg; 3292 char *my_optarg;
3226 char *my_optstr; 3293 char *my_optstr;
@@ -3256,11 +3323,12 @@ main (int argc, char **argv)
3256 takearg: 3323 takearg:
3257 my_optarg = NULL; 3324 my_optarg = NULL;
3258 my_optstr = argv[my_optind]; 3325 my_optstr = argv[my_optind];
3259 /* This doesn't use getopt() because it makes trouble for -P & python which reenter 3326
3260 * main() and thus care about freeing all memory. I never had much trust for getopt 3327 /* This doesn't use getopt() because it makes trouble for -P & python which
3261 * anyway, it's too opaque. This implements a fairly standard non-long-option getopt 3328 * reenter main() and thus care about freeing all memory. I never had much
3262 * with support for named operations (e.g., "xdelta3 [encode|decode|printhdr...] < in > 3329 * trust for getopt anyway, it's too opaque. This implements a fairly
3263 * out"). */ 3330 * standard non-long-option getopt with support for named operations (e.g.,
3331 * "xdelta3 [encode|decode|printhdr...] < in > out"). */
3264 if (my_optstr) 3332 if (my_optstr)
3265 { 3333 {
3266 if (*my_optstr == '-') { my_optstr += 1; } 3334 if (*my_optstr == '-') { my_optstr += 1; }
@@ -3273,12 +3341,12 @@ main (int argc, char **argv)
3273 my_optarg = NULL; 3341 my_optarg = NULL;
3274 if ((ret = *my_optstr++) == 0) { my_optind += 1; goto takearg; } 3342 if ((ret = *my_optstr++) == 0) { my_optind += 1; goto takearg; }
3275 3343
3276 /* Option handling: first check for one ':' following the option in flags, then 3344 /* Option handling: first check for one ':' following the option in
3277 * check for two. The syntax allows: 3345 * flags, then check for two. The syntax allows:
3278 * 3346 *
3279 * 1. -Afoo defines optarg="foo" 3347 * 1. -Afoo defines optarg="foo"
3280 * 2. -A foo defines optarg="foo" 3348 * 2. -A foo defines optarg="foo"
3281 * 3. -A "" defines optarg="" (allows optional empty-string) 3349 * 3. -A "" defines optarg="" (allows empty-string)
3282 * 4. -A [EOA or -moreargs] error (mandatory case) 3350 * 4. -A [EOA or -moreargs] error (mandatory case)
3283 * 5. -A [EOA -moreargs] defines optarg=NULL (optional case) 3351 * 5. -A [EOA -moreargs] defines optarg=NULL (optional case)
3284 * 6. -A=foo defines optarg="foo" 3352 * 6. -A=foo defines optarg="foo"
@@ -3529,7 +3597,8 @@ main (int argc, char **argv)
3529 /* Check for conflicting arguments. */ 3597 /* Check for conflicting arguments. */
3530 if (option_stdout && ! option_quiet) 3598 if (option_stdout && ! option_quiet)
3531 { 3599 {
3532 XPR(NT "warning: -c option overrides output filename: %s\n", argv[1]); 3600 XPR(NT "warning: -c option overrides output filename: %s\n",
3601 argv[1]);
3533 } 3602 }
3534 3603
3535 if (! option_stdout) { ofile.filename = argv[1]; } 3604 if (! option_stdout) { ofile.filename = argv[1]; }
@@ -3603,7 +3672,8 @@ main_help (void)
3603 DP(RINT "special command names:\n"); 3672 DP(RINT "special command names:\n");
3604 DP(RINT " config prints xdelta3 configuration\n"); 3673 DP(RINT " config prints xdelta3 configuration\n");
3605 DP(RINT " decode decompress the input\n"); 3674 DP(RINT " decode decompress the input\n");
3606 DP(RINT " encode compress the input%s\n", XD3_ENCODER ? "" : " [Not compiled]"); 3675 DP(RINT " encode compress the input%s\n",
3676 XD3_ENCODER ? "" : " [Not compiled]");
3607#if REGRESSION_TEST 3677#if REGRESSION_TEST
3608 DP(RINT " test run the builtin tests\n"); 3678 DP(RINT " test run the builtin tests\n");
3609#endif 3679#endif
@@ -3618,7 +3688,8 @@ main_help (void)
3618 DP(RINT " -0 .. -9 compression level\n"); 3688 DP(RINT " -0 .. -9 compression level\n");
3619 DP(RINT " -c use stdout\n"); 3689 DP(RINT " -c use stdout\n");
3620 DP(RINT " -d decompress\n"); 3690 DP(RINT " -d decompress\n");
3621 DP(RINT " -e compress%s\n", XD3_ENCODER ? "" : " [Not compiled]"); 3691 DP(RINT " -e compress%s\n",
3692 XD3_ENCODER ? "" : " [Not compiled]");
3622 DP(RINT " -f force overwrite\n"); 3693 DP(RINT " -f force overwrite\n");
3623 DP(RINT " -h show help\n"); 3694 DP(RINT " -h show help\n");
3624 DP(RINT " -q be quiet\n"); 3695 DP(RINT " -q be quiet\n");