diff options
author | Donovan Baarda <abo@minkirri.apana.org.au> | 2020-06-04 23:03:02 +1000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-06-04 23:03:02 +1000 |
commit | d1938c387e86ab5bbf7cb2e84244229c5bbd5ebf (patch) | |
tree | fa22d2598102c12efbfa3c28206f1101138fce58 | |
parent | d6e4055b1d3c96d1e683c44fbb58f2ba756693fd (diff) | |
parent | 849893045f56f08d59532b743f5da4eebf7ad7aa (diff) | |
download | librsync-d1938c387e86ab5bbf7cb2e84244229c5bbd5ebf.tar.gz |
Merge pull request #208 from dbaarda/travis-windows1
Add a Windows build target to Travis checks and fix all problems it identified.
-rw-r--r-- | .travis.yml | 4 | ||||
-rw-r--r-- | CMakeLists.txt | 16 | ||||
-rw-r--r-- | NEWS.md | 10 | ||||
-rw-r--r-- | src/base64.c | 10 | ||||
-rw-r--r-- | src/buf.c | 18 | ||||
-rw-r--r-- | src/config.h.cmake | 3 | ||||
-rw-r--r-- | src/delta.c | 4 | ||||
-rw-r--r-- | src/emit.c | 9 | ||||
-rw-r--r-- | src/fileutil.c | 20 | ||||
-rw-r--r-- | src/hashtable.c | 8 | ||||
-rw-r--r-- | src/hashtable.h | 4 | ||||
-rw-r--r-- | src/job.h | 5 | ||||
-rw-r--r-- | src/mdfour.c | 42 | ||||
-rw-r--r-- | src/mksum.c | 4 | ||||
-rw-r--r-- | src/netint.c | 6 | ||||
-rw-r--r-- | src/patch.c | 79 | ||||
-rw-r--r-- | src/prototab.h | 2 | ||||
-rw-r--r-- | src/rabinkarp.c | 4 | ||||
-rw-r--r-- | src/rdiff.c | 2 | ||||
-rw-r--r-- | src/stats.c | 21 | ||||
-rw-r--r-- | src/stream.c | 137 | ||||
-rw-r--r-- | src/stream.h | 69 | ||||
-rw-r--r-- | src/sumset.c | 32 | ||||
-rw-r--r-- | src/sumset.h | 6 | ||||
-rw-r--r-- | src/trace.c | 8 | ||||
-rw-r--r-- | src/tube.c | 84 | ||||
-rw-r--r-- | src/util.c | 2 | ||||
-rw-r--r-- | src/whole.c | 4 | ||||
-rw-r--r-- | tests/checksum_test.c | 2 | ||||
-rw-r--r-- | tests/rabinkarp_test.c | 2 | ||||
-rw-r--r-- | tests/rollsum_test.c | 2 | ||||
-rw-r--r-- | tests/sumset_test.c | 2 |
32 files changed, 258 insertions, 363 deletions
diff --git a/.travis.yml b/.travis.yml index 691f375..78e2f9e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -22,10 +22,12 @@ addons: update: true script: - - make check + - cmake --build . --target check matrix: include: + - os: windows + - os: osx compiler: clang diff --git a/CMakeLists.txt b/CMakeLists.txt index 3a05c83..eef942b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -61,6 +61,7 @@ check_include_files ( sys/file.h HAVE_SYS_FILE_H ) check_include_files ( sys/stat.h HAVE_SYS_STAT_H ) check_include_files ( sys/types.h HAVE_SYS_TYPES_H ) check_include_files ( unistd.h HAVE_UNISTD_H ) +check_include_files ( io.h HAVE_IO_H ) check_include_files ( fcntl.h HAVE_FCNTL_H ) check_include_files ( mcheck.h HAVE_MCHECK_H ) check_include_files ( zlib.h HAVE_ZLIB_H ) @@ -100,7 +101,7 @@ if(WIN32) # CheckCSourceRuns checking for "%zu" succeeds but still gives warnings on win32. set(HAVE_PRINTF_Z OFF) # Not using unsupported %zu generates warnings about using %I64 with MinGW. - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-format") + # set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-format") message (STATUS "Compiling to Win32 - printf \"%zu\" size_t formatting support disabled") elseif(CMAKE_CROSSCOMPILING) # CheckCSourceRuns doesn't work when cross-compiling; assume C99 compliant support. @@ -133,9 +134,14 @@ if(APPLE) endif() if (CMAKE_C_COMPILER_ID MATCHES "(Clang|Gnu|GNU)") - # TODO: Set for MSVC and other compilers. # TODO: Set -Werror when the build is clean. set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -std=c99 -pedantic") + if (CMAKE_C_COMPILER_ID MATCHES "Clang") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wconversion") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-sign-conversion") + endif() +elseif(CMAKE_C_COMPILER_ID MATCHES "MSVC") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /D_CRT_SECURE_NO_WARNINGS") endif() site_name(BUILD_HOSTNAME) @@ -242,7 +248,8 @@ add_test(NAME isprefix_test COMMAND isprefix_test) add_executable(netint_test tests/netint_test.c src/netint.c src/util.c src/trace.c src/tube.c - src/scoop.c src/stream.c) + src/scoop.c) +target_compile_options(netint_test PRIVATE -DLIBRSYNC_STATIC_DEFINE) add_test(NAME netint_test COMMAND netint_test) add_executable(rollsum_test @@ -297,7 +304,7 @@ if (BUILD_RDIFF) else (BUILD_RDIFF) set(LAST_TARGET rsync) endif (BUILD_RDIFF) -add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND}) +add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND} -C Debug) add_dependencies(check ${LAST_TARGET} isprefix_test netint_test @@ -346,7 +353,6 @@ set(rsync_LIB_SRCS src/rabinkarp.c src/scoop.c src/stats.c - src/stream.c src/sumset.c src/trace.c src/tube.c @@ -4,6 +4,16 @@ NOT RELEASED YET + * Add Travis Windows checks and improve compatibility. Turn on `-Wconversion + -Wno-sign-conversion` warnings for clang. Add MSVC compiler flags to turn + off posix warnings. Make all code compile clean with no warnings on all + Travis platforms. Added cmake config checking for windows `io.h` and + improve `fileutil.c` for MSVC. Fix broken error handling in + `rs_file_copy_cb()`. Improved trace output, making it less spamy and more + consistent. Add patch checking for invalid literal lengths. Improve + internal variable and argument types. Add explicit type conversions. + (dbaarda, https://github.com/librsync/librsync/pull/208) + * Fix a bug so patch will now fail returning RS_CORRUPT on encountering a zero length copy command instead of hanging. Make copy_cb() copying more data than requested an assert-fail on debug builds, and a log-warning for diff --git a/src/base64.c b/src/base64.c index 41b2616..bd3e60f 100644 --- a/src/base64.c +++ b/src/base64.c @@ -41,20 +41,18 @@ size_t rs_unbase64(char *s) idx = (int)(p - b64); byte_offset = (i * 6) / 8; bit_offset = (i * 6) % 8; - d[byte_offset] &= ~((1 << (8 - bit_offset)) - 1); + d[byte_offset] &= (unsigned char)~((1 << (8 - bit_offset)) - 1); if (bit_offset < 3) { - d[byte_offset] |= (idx << (2 - bit_offset)); + d[byte_offset] |= (unsigned char)(idx << (2 - bit_offset)); n = byte_offset + 1; } else { - d[byte_offset] |= (idx >> (bit_offset - 2)); - d[byte_offset + 1] = 0; - d[byte_offset + 1] |= (idx << (8 - (bit_offset - 2))) & 0xFF; + d[byte_offset] |= (unsigned char)(idx >> (bit_offset - 2)); + d[byte_offset + 1] = (unsigned char)(idx << (8 - (bit_offset - 2))); n = byte_offset + 2; } s++; i++; } - return n; } @@ -60,7 +60,6 @@ rs_filebuf_t *rs_filebuf_new(FILE *f, size_t buf_len) pf->buf = rs_alloc(buf_len, "file buffer"); pf->buf_len = buf_len; pf->f = f; - return pf; } @@ -92,7 +91,6 @@ rs_result rs_infilebuf_fill(rs_job_t *job, rs_buffers_t *buf, void *opaque) if (buf->eof_in || (buf->eof_in = feof(f))) { rs_trace("seen end of file on input"); - buf->eof_in = 1; return RS_DONE; } @@ -119,9 +117,7 @@ rs_result rs_infilebuf_fill(rs_job_t *job, rs_buffers_t *buf, void *opaque) } buf->avail_in = len; buf->next_in = fb->buf; - job->stats.in_bytes += len; - return RS_DONE; } @@ -129,7 +125,6 @@ rs_result rs_infilebuf_fill(rs_job_t *job, rs_buffers_t *buf, void *opaque) some buffered output now. Write this out to F, and reset the buffer cursor. */ rs_result rs_outfilebuf_drain(rs_job_t *job, rs_buffers_t *buf, void *opaque) { - int present; rs_filebuf_t *fb = (rs_filebuf_t *)opaque; FILE *f = fb->f; @@ -137,10 +132,8 @@ rs_result rs_outfilebuf_drain(rs_job_t *job, rs_buffers_t *buf, void *opaque) buffer could possibly be BUF. */ if (buf->next_out == NULL) { assert(buf->avail_out == 0); - buf->next_out = fb->buf; buf->avail_out = fb->buf_len; - return RS_DONE; } @@ -148,23 +141,16 @@ rs_result rs_outfilebuf_drain(rs_job_t *job, rs_buffers_t *buf, void *opaque) assert(buf->next_out >= fb->buf); assert(buf->next_out <= fb->buf + fb->buf_len); - present = buf->next_out - fb->buf; + size_t present = buf->next_out - fb->buf; if (present > 0) { - int result; - - assert(present > 0); - - result = fwrite(fb->buf, 1, present, f); + size_t result = fwrite(fb->buf, 1, present, f); if (present != result) { rs_error("error draining buf to file: %s", strerror(errno)); return RS_IO_ERROR; } - buf->next_out = fb->buf; buf->avail_out = fb->buf_len; - job->stats.out_bytes += result; } - return RS_DONE; } diff --git a/src/config.h.cmake b/src/config.h.cmake index 477e149..d5b6392 100644 --- a/src/config.h.cmake +++ b/src/config.h.cmake @@ -18,6 +18,9 @@ /* Define to 1 if you have the <unistd.h> header file. */ #cmakedefine HAVE_UNISTD_H 1 +/* Define to 1 if you have the <io.h> header file. */ +#cmakedefine HAVE_IO_H 1 + /* Define to 1 if you have the <fcntl.h> header file. */ #cmakedefine HAVE_FCNTL_H 1 diff --git a/src/delta.c b/src/delta.c index 812ad6c..d2facaf 100644 --- a/src/delta.c +++ b/src/delta.c @@ -305,7 +305,7 @@ static inline rs_result rs_appendflush(rs_job_t *job) /* else if last is a miss, emit and process it */ } else if (job->scoop_pos) { rs_trace("got " FMT_SIZE " bytes of literal data", job->scoop_pos); - rs_emit_literal_cmd(job, job->scoop_pos); + rs_emit_literal_cmd(job, (int)job->scoop_pos); return rs_processmiss(job); } /* otherwise, nothing to flush so we are done */ @@ -360,7 +360,7 @@ static rs_result rs_delta_s_slack(rs_job_t *job) if (avail) { rs_trace("emit slack delta for " FMT_SIZE " available bytes", avail); - rs_emit_literal_cmd(job, avail); + rs_emit_literal_cmd(job, (int)avail); rs_tube_copy(job, avail); return RS_RUNNING; } else if (rs_job_input_is_ending(job)) { @@ -64,7 +64,7 @@ void rs_emit_literal_cmd(rs_job_t *job, int len) rs_trace("emit LITERAL_N4(len=%d), cmd_byte=%#04x", len, cmd); } - rs_squirt_byte(job, cmd); + rs_squirt_byte(job, (rs_byte_t)cmd); if (param_len) rs_squirt_netint(job, len, param_len); @@ -95,7 +95,6 @@ void rs_emit_copy_cmd(rs_job_t *job, rs_long_t where, rs_long_t len) assert(where_bytes == 1); cmd = RS_OP_COPY_N1_N1; } - if (len_bytes == 1) ; else if (len_bytes == 2) cmd += 1; @@ -108,15 +107,13 @@ void rs_emit_copy_cmd(rs_job_t *job, rs_long_t where, rs_long_t len) rs_trace("emit COPY_N%d_N%d(where=" FMT_LONG ", len=" FMT_LONG "), cmd_byte=%#04x", where_bytes, len_bytes, where, len, cmd); - rs_squirt_byte(job, cmd); + rs_squirt_byte(job, (rs_byte_t)cmd); rs_squirt_netint(job, where, where_bytes); rs_squirt_netint(job, len, len_bytes); stats->copy_cmds++; stats->copy_bytes += len; stats->copy_cmdbytes += 1 + where_bytes + len_bytes; - - /* \todo All the stats */ } /** Write an END command. */ @@ -125,5 +122,5 @@ void rs_emit_end_cmd(rs_job_t *job) int cmd = RS_OP_END; rs_trace("emit END, cmd_byte=%#04x", cmd); - rs_squirt_byte(job, cmd); + rs_squirt_byte(job, (rs_byte_t)cmd); } diff --git a/src/fileutil.c b/src/fileutil.c index 2918c89..2e7f069 100644 --- a/src/fileutil.c +++ b/src/fileutil.c @@ -41,6 +41,9 @@ #ifdef HAVE_SYS_STAT_H # include <sys/stat.h> #endif +#ifdef HAVE_IO_H +# include <io.h> +#endif #include "librsync.h" #include "trace.h" @@ -68,8 +71,8 @@ # define S_ISREG(x) ((x) & _S_IFREG) #endif -/* Use _fileno if it exists and fileno doesn't. */ -#if !defined(HAVE_FILENO) && defined(HAVE__FILENO) +/* Use and prefer _fileno if it exists. */ +#ifdef HAVE__FILENO # define fileno(f) _fileno((f)) #endif @@ -129,23 +132,20 @@ rs_long_t rs_file_size(FILE *f) rs_result rs_file_copy_cb(void *arg, rs_long_t pos, size_t *len, void **buf) { - int got; FILE *f = (FILE *)arg; if (fseek(f, pos, SEEK_SET)) { rs_error("seek failed: %s", strerror(errno)); return RS_IO_ERROR; } - - got = fread(*buf, 1, *len, f); - if (got == -1) { + *len = fread(*buf, 1, *len, f); + if (*len) { + return RS_DONE; + } else if (ferror(f)) { rs_error("read error: %s", strerror(errno)); return RS_IO_ERROR; - } else if (got == 0) { + } else { rs_error("unexpected eof on fd%d", fileno(f)); return RS_INPUT_ENDED; - } else { - *len = got; - return RS_DONE; } } diff --git a/src/hashtable.c b/src/hashtable.c index 7c27750..4ffd9bf 100644 --- a/src/hashtable.c +++ b/src/hashtable.c @@ -36,19 +36,19 @@ hashtable_t *_hashtable_new(int size) { hashtable_t *t; - int size2, bits2; + unsigned size2, bits2; /* Adjust requested size to account for max load factor. */ size = 1 + size * HASHTABLE_LOADFACTOR_DEN / HASHTABLE_LOADFACTOR_NUM; /* Use next power of 2 larger than the requested size and get mask bits. */ - for (size2 = 2, bits2 = 1; size2 < size; size2 <<= 1, bits2++) ; + for (size2 = 2, bits2 = 1; (int)size2 < size; size2 <<= 1, bits2++) ; if (!(t = calloc(1, sizeof(hashtable_t)+ size2 * sizeof(unsigned)))) return NULL; if (!(t->etable = calloc(size2, sizeof(void *)))) { _hashtable_free(t); return NULL; } - t->size = size2; + t->size = (int)size2; t->count = 0; t->tmask = size2 - 1; #ifndef HASHTABLE_NBLOOM @@ -56,7 +56,7 @@ hashtable_t *_hashtable_new(int size) _hashtable_free(t); return NULL; } - t->bshift = sizeof(unsigned) * 8 - bits2; + t->bshift = (unsigned)sizeof(unsigned) * 8 - bits2; assert(t->tmask == (unsigned)-1 >> t->bshift); #endif #ifndef HASHTABLE_NSTATS diff --git a/src/hashtable.h b/src/hashtable.h index f70c097..8a88840 100644 --- a/src/hashtable.h +++ b/src/hashtable.h @@ -157,7 +157,7 @@ static inline void hashtable_setbloom(hashtable_t *t, unsigned const h) { /* Use upper bits for a "different hash". */ unsigned const i = h >> t->bshift; - t->kbloom[i / 8] |= 1 << (i % 8); + t->kbloom[i / 8] |= (unsigned char)(1 << (i % 8)); } static inline bool hashtable_getbloom(hashtable_t *t, unsigned const h) @@ -182,7 +182,7 @@ static inline unsigned mix32(unsigned h) /** Ensure hash's are never zero. */ static inline unsigned nozero(unsigned h) { - return h ? h : -1; + return h ? h : (unsigned)-1; } #endif /* _HASHTABLE_H_ */ @@ -82,11 +82,11 @@ struct rs_job { /** If USED is >0, then buf contains that much write data to be sent out. */ rs_byte_t write_buf[36]; - int write_len; + size_t write_len; /** If \p copy_len is >0, then that much data should be copied through * from the input. */ - rs_long_t copy_len; + size_t copy_len; /** Copy from the basis position. */ rs_long_t basis_pos, basis_len; @@ -94,7 +94,6 @@ struct rs_job { /** Callback used to copy data from the basis into the output. */ rs_copy_cb *copy_cb; void *copy_arg; - }; rs_job_t *rs_job_new(const char *, rs_result (*statefn)(rs_job_t *)); diff --git a/src/mdfour.c b/src/mdfour.c index bbdea07..180cd80 100644 --- a/src/mdfour.c +++ b/src/mdfour.c @@ -52,8 +52,8 @@ #define lshift(x,s) (((x)<<(s)) | ((x)>>(32-(s)))) #define ROUND1(a,b,c,d,k,s) a = lshift(a + F(b,c,d) + X[k], s) -#define ROUND2(a,b,c,d,k,s) a = lshift(a + G(b,c,d) + X[k] + 0x5A827999,s) -#define ROUND3(a,b,c,d,k,s) a = lshift(a + H(b,c,d) + X[k] + 0x6ED9EBA1,s) +#define ROUND2(a,b,c,d,k,s) a = lshift(a + G(b,c,d) + X[k] + 0x5A827999U, s) +#define ROUND3(a,b,c,d,k,s) a = lshift(a + H(b,c,d) + X[k] + 0x6ED9EBA1U, s) /** padding data used for finalising */ static unsigned char PADDING[64] = { @@ -162,10 +162,10 @@ static void rs_mdfour64(rs_mdfour_t *m, const void *p) * instead. */ inline static void copy4( /* @out@ */ unsigned char *out, uint32_t const x) { - out[0] = x; - out[1] = x >> 8; - out[2] = x >> 16; - out[3] = x >> 24; + out[0] = (unsigned char)(x); + out[1] = (unsigned char)(x >> 8); + out[2] = (unsigned char)(x >> 16); + out[3] = (unsigned char)(x >> 24); } /* We need this if there is a uint64 */ @@ -173,14 +173,14 @@ inline static void copy4( /* @out@ */ unsigned char *out, uint32_t const x) #ifdef UINT64_MAX inline static void copy8( /* @out@ */ unsigned char *out, uint64_t const x) { - out[0] = x; - out[1] = x >> 8; - out[2] = x >> 16; - out[3] = x >> 24; - out[4] = x >> 32; - out[5] = x >> 40; - out[6] = x >> 48; - out[7] = x >> 56; + out[0] = (unsigned char)(x); + out[1] = (unsigned char)(x >> 8); + out[2] = (unsigned char)(x >> 16); + out[3] = (unsigned char)(x >> 24); + out[4] = (unsigned char)(x >> 32); + out[5] = (unsigned char)(x >> 40); + out[6] = (unsigned char)(x >> 48); + out[7] = (unsigned char)(x >> 56); } #endif /* UINT64_MAX */ @@ -191,7 +191,9 @@ inline static void copy64( /* @out@ */ uint32_t *M, unsigned char const *in) int i = 16; while (i--) { - *M++ = (in[3] << 24) | (in[2] << 16) | (in[1] << 8) | in[0]; + *M++ = + (((uint32_t)in[3] << 24) | ((uint32_t)in[2] << 16) | + ((uint32_t)in[1] << 8) | (uint32_t)in[0]); in += 4; } } @@ -241,10 +243,10 @@ inline static void rs_mdfour_block(rs_mdfour_t *md, void const *p) void rs_mdfour_begin(rs_mdfour_t *md) { memset(md, 0, sizeof(*md)); - md->A = 0x67452301; - md->B = 0xefcdab89; - md->C = 0x98badcfe; - md->D = 0x10325476; + md->A = 0x67452301U; + md->B = 0xefcdab89U; + md->C = 0x98badcfeU; + md->D = 0x10325476U; #ifdef UINT64_MAX md->totalN = 0; #else @@ -320,7 +322,7 @@ void rs_mdfour_update(rs_mdfour_t *md, void const *in_void, size_t n) /* Put remaining bytes onto tail */ if (n) { memcpy(&md->tail[md->tail_len], in, n); - md->tail_len += n; + md->tail_len += (int)n; } } diff --git a/src/mksum.c b/src/mksum.c index da34940..9eb11eb 100644 --- a/src/mksum.c +++ b/src/mksum.c @@ -117,7 +117,7 @@ rs_job_t *rs_sig_begin(size_t block_len, size_t strong_len, job->signature = rs_alloc_struct(rs_signature_t); job->job_owns_sig = 1; job->sig_magic = sig_magic; - job->sig_block_len = block_len; - job->sig_strong_len = strong_len; + job->sig_block_len = (int)block_len; + job->sig_strong_len = (int)strong_len; return job; } diff --git a/src/netint.c b/src/netint.c index d426fa7..0ee716e 100644 --- a/src/netint.c +++ b/src/netint.c @@ -69,7 +69,7 @@ rs_result rs_squirt_netint(rs_job_t *job, rs_long_t val, int len) assert(len <= RS_MAX_INT_BYTES); /* Fill the output buffer with a bigendian representation of the number. */ for (i = len - 1; i >= 0; i--) { - buf[i] = val; /* truncated */ + buf[i] = (rs_byte_t)val; /* truncated */ val >>= 8; } rs_tube_write(job, buf, len); @@ -101,7 +101,7 @@ rs_result rs_suck_netint(rs_job_t *job, rs_long_t *val, int len) if ((result = rs_scoop_read(job, len, (void **)&buf)) == RS_DONE) { *val = 0; for (i = 0; i < len; i++) - *val = *val << 8 | buf[i]; + *val = (*val << 8) | (rs_long_t)buf[i]; } return result; } @@ -112,7 +112,7 @@ rs_result rs_suck_n4(rs_job_t *job, int *val) rs_long_t buf; if ((result = rs_suck_netint(job, &buf, 4)) == RS_DONE) - *val = buf; + *val = (int)buf; return result; } diff --git a/src/patch.c b/src/patch.c index 77b8309..7f51470 100644 --- a/src/patch.c +++ b/src/patch.c @@ -50,19 +50,15 @@ static rs_result rs_patch_s_cmdbyte(rs_job_t *job) if ((result = rs_suck_byte(job, &job->op)) != RS_DONE) return result; - job->cmd = &rs_prototab[job->op]; - - rs_trace("got command %#04x (%s), len_1=" FMT_SIZE "", job->op, - rs_op_kind_name(job->cmd->kind), job->cmd->len_1); - + rs_trace("got command %#04x (%s), len_1=%d, len_2=%d", job->op, + rs_op_kind_name(job->cmd->kind), job->cmd->len_1, job->cmd->len_2); if (job->cmd->len_1) job->statefn = rs_patch_s_params; else { job->param1 = job->cmd->immediate; job->statefn = rs_patch_s_run; } - return RS_RUNNING; } @@ -71,27 +67,22 @@ static rs_result rs_patch_s_cmdbyte(rs_job_t *job) static rs_result rs_patch_s_params(rs_job_t *job) { rs_result result; - int len = job->cmd->len_1 + job->cmd->len_2; + const size_t len = (size_t)(job->cmd->len_1 + job->cmd->len_2); void *p; assert(len); - result = rs_scoop_readahead(job, len, &p); if (result != RS_DONE) return result; - /* we now must have LEN bytes buffered */ result = rs_suck_netint(job, &job->param1, job->cmd->len_1); /* shouldn't fail, since we already checked */ assert(result == RS_DONE); - if (job->cmd->len_2) { result = rs_suck_netint(job, &job->param2, job->cmd->len_2); assert(result == RS_DONE); } - job->statefn = rs_patch_s_run; - return RS_RUNNING; } @@ -99,20 +90,16 @@ static rs_result rs_patch_s_params(rs_job_t *job) static rs_result rs_patch_s_run(rs_job_t *job) { rs_trace("running command %#04x", job->op); - switch (job->cmd->kind) { case RS_KIND_LITERAL: job->statefn = rs_patch_s_literal; return RS_RUNNING; - case RS_KIND_END: return RS_DONE; /* so we exit here; trying to continue causes an error */ - case RS_KIND_COPY: job->statefn = rs_patch_s_copy; return RS_RUNNING; - default: rs_error("bogus command %#04x", job->op); return RS_CORRUPT; @@ -122,53 +109,42 @@ static rs_result rs_patch_s_run(rs_job_t *job) /** Called when trying to copy through literal data. */ static rs_result rs_patch_s_literal(rs_job_t *job) { - rs_long_t len = job->param1; + const rs_long_t len = job->param1; rs_stats_t *stats = &job->stats; - rs_trace("LITERAL(len=" FMT_LONG ")", len); - - if (len < 0) { + rs_trace("LITERAL(length=" FMT_LONG ")", len); + if (len <= 0 || len > SIZE_MAX) { rs_error("invalid length=" FMT_LONG " on LITERAL command", len); return RS_CORRUPT; } - stats->lit_cmds++; stats->lit_bytes += len; stats->lit_cmdbytes += 1 + job->cmd->len_1; - - rs_tube_copy(job, len); - + rs_tube_copy(job, (size_t)len); job->statefn = rs_patch_s_cmdbyte; return RS_RUNNING; } static rs_result rs_patch_s_copy(rs_job_t *job) { - rs_long_t where, len; + const rs_long_t pos = job->param1; + const rs_long_t len = job->param2; rs_stats_t *stats = &job->stats; - where = job->param1; - len = job->param2; - - rs_trace("COPY(where=" FMT_LONG ", len=" FMT_LONG ")", where, len); - + rs_trace("COPY(position=" FMT_LONG ", length=" FMT_LONG ")", pos, len); if (len <= 0) { rs_error("invalid length=" FMT_LONG " on COPY command", len); return RS_CORRUPT; } - - if (where < 0) { - rs_error("invalid where=" FMT_LONG " on COPY command", where); + if (pos < 0) { + rs_error("invalid position=" FMT_LONG " on COPY command", pos); return RS_CORRUPT; } - - job->basis_pos = where; - job->basis_len = len; - stats->copy_cmds++; stats->copy_bytes += len; stats->copy_cmdbytes += 1 + job->cmd->len_1 + job->cmd->len_2; - + job->basis_pos = pos; + job->basis_len = len; job->statefn = rs_patch_s_copying; return RS_RUNNING; } @@ -179,44 +155,40 @@ static rs_result rs_patch_s_copying(rs_job_t *job) { rs_result result; rs_buffers_t *buffs = job->stream; - size_t req = job->basis_len; + rs_long_t req = job->basis_len; size_t len = buffs->avail_out; void *ptr = buffs->next_out; /* We are blocked if there is no space left to copy into. */ if (!len) return RS_BLOCKED; - - /* Adjust lengths to min of amount requested and space available. */ - req = len = (len < req) ? len : req; - rs_trace("copy " FMT_SIZE " bytes from basis at offset " FMT_LONG "", len, + /* Adjust request to min of amount requested and space available. */ + if (len < req) + req = (rs_long_t)len; + rs_trace("copy " FMT_LONG " bytes from basis at offset " FMT_LONG "", req, job->basis_pos); - + len = (size_t)req; result = (job->copy_cb) (job->copy_arg, job->basis_pos, &len, &ptr); if (result != RS_DONE) { rs_trace("copy callback returned %s", rs_strerror(result)); return result; } rs_trace("got " FMT_SIZE " bytes back from basis callback", len); - /* Actual copied length cannot be greater than requested length. */ assert(len <= req); /* Backwards-compatible defensively handle this for NDEBUG builds. */ if (len > req) { rs_warn("copy_cb() returned more than the requested length"); - len = req; + len = (size_t)req; } - /* copy back to out buffer only if the callback has used its own buffer */ if (ptr != buffs->next_out) memcpy(buffs->next_out, ptr, len); - /* Update buffs and copy for copied data. */ buffs->next_out += len; buffs->avail_out -= len; - job->basis_pos += len; - job->basis_len -= len; - + job->basis_pos += (rs_long_t)len; + job->basis_len -= (rs_long_t)len; if (!job->basis_len) { /* Nothing left to copy, we are done! */ job->statefn = rs_patch_s_cmdbyte; @@ -232,16 +204,13 @@ static rs_result rs_patch_s_header(rs_job_t *job) if ((result = rs_suck_n4(job, &v)) != RS_DONE) return result; - if (v != RS_DELTA_MAGIC) { rs_error("got magic number %#x rather than expected value %#x", v, RS_DELTA_MAGIC); return RS_BAD_MAGIC; } else rs_trace("got patch magic %#x", v); - job->statefn = rs_patch_s_cmdbyte; - return RS_RUNNING; } @@ -251,8 +220,6 @@ rs_job_t *rs_patch_begin(rs_copy_cb * copy_cb, void *copy_arg) job->copy_cb = copy_cb; job->copy_arg = copy_arg; - rs_mdfour_begin(&job->output_md4); - return job; } diff --git a/src/prototab.h b/src/prototab.h index 857799b..7195d53 100644 --- a/src/prototab.h +++ b/src/prototab.h @@ -34,7 +34,7 @@ typedef struct rs_prototab_ent { enum rs_op_kind kind; int immediate; - size_t len_1, len_2; + int len_1, len_2; } rs_prototab_ent_t; extern const rs_prototab_ent_t rs_prototab[]; diff --git a/src/rabinkarp.c b/src/rabinkarp.c index 32d731f..085b549 100644 --- a/src/rabinkarp.c +++ b/src/rabinkarp.c @@ -21,7 +21,7 @@ #include "rabinkarp.h" /* Constant for RABINKARP_MULT^2. */ -#define RABINKARP_MULT2 (RABINKARP_MULT*RABINKARP_MULT) +#define RABINKARP_MULT2 0xa5b71959U /* Macros for doing 16 bytes with 2 mults that can be done in parallel. Testing showed this as a performance sweet spot vs 16x1, 8x2, 4x4 1x16 alternative @@ -100,5 +100,5 @@ void rabinkarp_update(rabinkarp_t *sum, const unsigned char *buf, size_t len) } sum->hash = hash; sum->count += len; - sum->mult *= rabinkarp_pow(len); + sum->mult *= rabinkarp_pow((uint32_t)len); } diff --git a/src/rdiff.c b/src/rdiff.c index b1bc6ce..d3ea32d 100644 --- a/src/rdiff.c +++ b/src/rdiff.c @@ -195,7 +195,7 @@ static rs_result rdiff_sig(poptContext opcon) FILE *basis_file, *sig_file; rs_stats_t stats; rs_result result; - rs_long_t sig_magic; + rs_magic_number sig_magic; basis_file = rs_file_open(poptGetArg(opcon), "rb", file_force); sig_file = rs_file_open(poptGetArg(opcon), "wb", file_force); diff --git a/src/stats.c b/src/stats.c index e0c5a3c..faacc59 100644 --- a/src/stats.c +++ b/src/stats.c @@ -41,7 +41,7 @@ char *rs_format_stats(rs_stats_t const *stats, char *buf, size_t size) { char const *op = stats->op; int len, sec; - double mbps_in, mbps_out; + double mb_in, mb_out; if (!op) op = "noop"; @@ -50,7 +50,7 @@ char *rs_format_stats(rs_stats_t const *stats, char *buf, size_t size) if (stats->lit_cmds) { len += - snprintf(buf + len, size - len, + snprintf(buf + len, size - (size_t)len, "literal[%d cmds, " FMT_LONG " bytes, " FMT_LONG " cmdbytes] ", stats->lit_cmds, stats->lit_bytes, stats->lit_cmdbytes); @@ -58,14 +58,14 @@ char *rs_format_stats(rs_stats_t const *stats, char *buf, size_t size) if (stats->sig_cmds) { len += - snprintf(buf + len, size - len, + snprintf(buf + len, size - (size_t)len, "in-place-signature[" FMT_LONG " cmds, " FMT_LONG " bytes] ", stats->sig_cmds, stats->sig_bytes); } if (stats->copy_cmds || stats->false_matches) { len += - snprintf(buf + len, size - len, + snprintf(buf + len, size - (size_t)len, "copy[" FMT_LONG " cmds, " FMT_LONG " bytes, " FMT_LONG " cmdbytes, %d false]", stats->copy_cmds, stats->copy_bytes, stats->copy_cmdbytes, @@ -74,21 +74,20 @@ char *rs_format_stats(rs_stats_t const *stats, char *buf, size_t size) if (stats->sig_blocks) { len += - snprintf(buf + len, size - len, + snprintf(buf + len, size - (size_t)len, "signature[" FMT_LONG " blocks, " FMT_SIZE " bytes per block]", stats->sig_blocks, stats->block_len); } - sec = (stats->end - stats->start); + sec = (int)(stats->end - stats->start); if (sec == 0) sec = 1; // avoid division by zero - mbps_in = stats->in_bytes / 1e6 / sec; - mbps_out = stats->out_bytes / 1e6 / sec; + mb_in = (double)stats->in_bytes / 1e6; + mb_out = (double)stats->out_bytes / 1e6; len += - snprintf(buf + len, size - len, + snprintf(buf + len, size - (size_t)len, " speed[%.1f MB (%.1f MB/s) in, %.1f MB (%.1f MB/s) out, %d sec]", - (stats->in_bytes / 1e6), mbps_in, (stats->out_bytes / 1e6), - mbps_out, sec); + mb_in, mb_in / sec, mb_out, mb_out / sec, sec); return buf; } diff --git a/src/stream.c b/src/stream.c deleted file mode 100644 index 8ce4177..0000000 --- a/src/stream.c +++ /dev/null @@ -1,137 +0,0 @@ -/*= -*- c-basic-offset: 4; indent-tabs-mode: nil; -*- - * - * librsync -- dynamic caching and delta update in HTTP - * - * Copyright (C) 2000, 2001 by Martin Pool <mbp@sourcefrog.net> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * as published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - - /*= - | Programming languages should be designed not - | by piling feature on top of feature, but by - | removing the weaknesses and restrictions that - | make additional features appear necessary. - | -- Revised^5 Report on Scheme - */ - -/** \file stream.c - * Manage librsync streams of IO. - * - * See \sa scoop.c and \sa tube.c for related code for input and output - * respectively. - * - * OK, so I'll admit IO here is a little complex. The most important player - * here is the stream, which is an object for managing filter operations. It - * has both input and output sides, both of which is just a (pointer,len) pair - * into a buffer provided by the client. The code controlling the stream - * handles however much data it wants, and the client provides or accepts - * however much is convenient. - * - * At the same time as being friendly to the client, we also try to be very - * friendly to the internal code. It wants to be able to ask for arbitrary - * amounts of input or output and get it without having to keep track of - * partial completion. So there are functions which either complete, or queue - * whatever was not sent and return RS_BLOCKED. - * - * The output buffer is a little more clever than simply a data buffer. Instead - * it knows that we can send either literal data, or data copied through from - * the input of the stream. - * - * In buf.c you will find functions that then map buffers onto stdio files. - * - * So on return from an encoding function, either the input or the output or - * possibly both will have no more bytes available. - * - * librsync never does IO or memory allocation, but relies on the caller. This - * is very nice for integration, but means that we have to be fairly flexible - * as to when we can `read' or `write' stuff internally. - * - * librsync basically does two types of IO. It reads network integers of - * various lengths which encode command and control information such as - * versions and signatures. It also does bulk data transfer. - * - * IO of network integers is internally buffered, because higher levels of the - * code need to see them transmitted atomically: it's no good to read half of a - * uint32. So there is a small and fixed length internal buffer which - * accumulates these. Unlike previous versions of the library, we don't require - * that the caller hold the start until the whole thing has arrived, which - * guarantees that we can always make progress. - * - * On each call into a stream iterator, it should begin by trying to flush - * output. This may well use up all the remaining stream space, in which case - * nothing else can be done. - * - * \todo Kill this file and move the vestigial code remaining closer to where - * it's used. */ - -#include "config.h" -#include <assert.h> -#include <stdlib.h> -#include <string.h> -#include "librsync.h" -#include "stream.h" -#include "trace.h" - -/** Copy up to \p max_len bytes from input of \b stream to its output. - * - * \return the number of bytes actually copied, which may be less than LEN if - * there is not enough space in one or the other stream. - * - * This always does the copy immediately. Most functions should call - * rs_tube_copy() to cause the copy to happen gradually as space becomes - * available. */ -int rs_buffers_copy(rs_buffers_t *stream, int max_len) -{ - int len = max_len; - - assert(len > 0); - - if ((unsigned)len > stream->avail_in) { - rs_trace("copy limited to " FMT_SIZE " available input bytes", - stream->avail_in); - len = stream->avail_in; - } - - if ((unsigned)len > stream->avail_out) { - rs_trace("copy limited to " FMT_SIZE " available output bytes", - stream->avail_out); - len = stream->avail_out; - } - - if (!len) - return 0; - /* rs_trace("stream copied chunk of %d bytes", len); */ - - memcpy(stream->next_out, stream->next_in, len); - - stream->next_out += len; - stream->avail_out -= len; - - stream->next_in += len; - stream->avail_in -= len; - - return len; -} - -/** Assert input is empty or output is full. - * - * Whenever a stream processing function exits, it should have done so because - * it has either consumed all the input or has filled the output buffer. This - * function checks that simple postcondition. */ -void rs_buffers_check_exit(rs_buffers_t const *stream) -{ - assert(stream->avail_in == 0 || stream->avail_out == 0); -} diff --git a/src/stream.h b/src/stream.h index b52ac48..61a75b9 100644 --- a/src/stream.h +++ b/src/stream.h @@ -27,20 +27,63 @@ | And sons who died on the Burma Railway. */ -int rs_buffers_is_empty(rs_buffers_t *stream); -int rs_buffers_copy(rs_buffers_t *stream, int len); +/** \file stream.h + * Manage librsync streams of IO. + * + * See \sa scoop.c and \sa tube.c for related code for input and output + * respectively. + * + * OK, so I'll admit IO here is a little complex. The most important player + * here is the stream, which is an object for managing filter operations. It + * has both input and output sides, both of which is just a (pointer,len) pair + * into a buffer provided by the client. The code controlling the stream + * handles however much data it wants, and the client provides or accepts + * however much is convenient. + * + * At the same time as being friendly to the client, we also try to be very + * friendly to the internal code. It wants to be able to ask for arbitrary + * amounts of input or output and get it without having to keep track of + * partial completion. So there are functions which either complete, or queue + * whatever was not sent and return RS_BLOCKED. + * + * The output buffer is a little more clever than simply a data buffer. Instead + * it knows that we can send either literal data, or data copied through from + * the input of the stream. + * + * In buf.c you will find functions that then map buffers onto stdio files. + * + * So on return from an encoding function, either the input or the output or + * possibly both will have no more bytes available. + * + * librsync never does IO or memory allocation, but relies on the caller. This + * is very nice for integration, but means that we have to be fairly flexible + * as to when we can `read' or `write' stuff internally. + * + * librsync basically does two types of IO. It reads network integers of + * various lengths which encode command and control information such as + * versions and signatures. It also does bulk data transfer. + * + * IO of network integers is internally buffered, because higher levels of the + * code need to see them transmitted atomically: it's no good to read half of a + * uint32. So there is a small and fixed length internal buffer which + * accumulates these. Unlike previous versions of the library, we don't require + * that the caller hold the start until the whole thing has arrived, which + * guarantees that we can always make progress. + * + * On each call into a stream iterator, it should begin by trying to flush + * output. This may well use up all the remaining stream space, in which case + * nothing else can be done. */ -int rs_tube_catchup(rs_job_t *); -void rs_tube_write(rs_job_t *, void const *buf, size_t len); -void rs_tube_copy(rs_job_t *, int len); -int rs_tube_is_idle(rs_job_t const *); -void rs_check_tube(rs_job_t *); +size_t rs_buffers_copy(rs_buffers_t *stream, size_t len); -void rs_buffers_check_exit(rs_buffers_t const *); +rs_result rs_tube_catchup(rs_job_t *job); +int rs_tube_is_idle(rs_job_t const *job); +void rs_tube_write(rs_job_t *job, void const *buf, size_t len); +void rs_tube_copy(rs_job_t *job, size_t len); -void rs_scoop_advance(rs_job_t *, size_t len); -rs_result rs_scoop_readahead(rs_job_t *, size_t len, void **ptr); -rs_result rs_scoop_read(rs_job_t *, size_t len, void **ptr); -rs_result rs_scoop_read_rest(rs_job_t *, size_t *len, void **ptr); -size_t rs_scoop_total_avail(rs_job_t *job); void rs_scoop_input(rs_job_t *job, size_t len); +void rs_scoop_advance(rs_job_t *job, size_t len); +rs_result rs_scoop_readahead(rs_job_t *job, size_t len, void **ptr); +rs_result rs_scoop_read(rs_job_t *job, size_t len, void **ptr); +rs_result rs_scoop_read_rest(rs_job_t *job, size_t *len, void **ptr); +size_t rs_scoop_total_avail(rs_job_t *job); diff --git a/src/sumset.c b/src/sumset.c index e736f36..8860762 100644 --- a/src/sumset.c +++ b/src/sumset.c @@ -34,7 +34,7 @@ static void rs_block_sig_init(rs_block_sig_t *sig, rs_weak_sum_t weak_sum, { sig->weak_sum = weak_sum; if (strong_sum) - memcpy(sig->strong_sum, strong_sum, strong_len); + memcpy(sig->strong_sum, strong_sum, (size_t)strong_len); } static inline unsigned rs_block_sig_hash(const rs_block_sig_t *sig) @@ -74,7 +74,7 @@ static inline int rs_block_match_cmp(rs_block_match_t *match, match->buf = NULL; } return memcmp(&match->block_sig.strong_sum, &block_sig->strong_sum, - match->signature->strong_sum_len); + (size_t)match->signature->strong_sum_len); } /* Disable mix32() in the hashtable because RabinKarp doesn't need it. We @@ -89,13 +89,10 @@ static inline int rs_block_match_cmp(rs_block_match_t *match, /* Get the size of a packed rs_block_sig_t. */ static inline size_t rs_block_sig_size(const rs_signature_t *sig) { - /* Round up to next multiple of sizeof(weak_sum) to align memory correctly. - */ - return offsetof(rs_block_sig_t, - strong_sum) + ((sig->strong_sum_len + - sizeof(rs_weak_sum_t)- - 1) / sizeof(rs_weak_sum_t)) * - sizeof(rs_weak_sum_t); + /* Round up to multiple of sizeof(weak_sum) to align memory correctly. */ + const size_t mask = sizeof(rs_weak_sum_t)- 1; + return (offsetof(rs_block_sig_t, strong_sum) + + (((size_t)sig->strong_sum_len + mask) & ~mask)); } /* Get the pointer to the block_sig_t from a block index. */ @@ -110,8 +107,8 @@ static inline rs_block_sig_t *rs_block_sig_ptr(const rs_signature_t *sig, static inline int rs_block_sig_idx(const rs_signature_t *sig, rs_block_sig_t *block_sig) { - return ((char *)block_sig - - (char *)sig->block_sigs) / rs_block_sig_size(sig); + return (int)(((char *)block_sig - + (char *)sig->block_sigs) / rs_block_sig_size(sig)); } rs_result rs_sig_args(rs_long_t old_fsize, rs_magic_number * magic, @@ -195,8 +192,8 @@ rs_result rs_signature_init(rs_signature_t *sig, rs_magic_number magic, return result; /* Set attributes from args. */ sig->magic = magic; - sig->block_len = block_len; - sig->strong_sum_len = strong_len; + sig->block_len = (int)block_len; + sig->strong_sum_len = (int)strong_len; sig->count = 0; /* Calculate the number of blocks if we have the signature file size. */ /* Magic+header is 12 bytes, each block thereafter is 4 bytes @@ -266,11 +263,12 @@ void rs_signature_log_stats(rs_signature_t const *sig) "match statistics: signature[%ld searches, %ld (%.3f%%) matches, " "%ld (%.3fx) weak sum compares, %ld (%.3f%%) strong sum compares, " "%ld (%.3f%%) strong sum calcs]", t->find_count, t->match_count, - 100.0 * (double)t->match_count / t->find_count, t->hashcmp_count, - (double)t->hashcmp_count / t->find_count, t->entrycmp_count, - 100.0 * (double)t->entrycmp_count / t->find_count, + 100.0 * (double)t->match_count / (double)t->find_count, + t->hashcmp_count, (double)t->hashcmp_count / (double)t->find_count, + t->entrycmp_count, + 100.0 * (double)t->entrycmp_count / (double)t->find_count, sig->calc_strong_count, - 100.0 * (double)sig->calc_strong_count / t->find_count); + 100.0 * (double)sig->calc_strong_count / (double)t->find_count); #endif } diff --git a/src/sumset.h b/src/sumset.h index 592ba01..52bd7c4 100644 --- a/src/sumset.h +++ b/src/sumset.h @@ -83,12 +83,12 @@ rs_long_t rs_signature_find_match(rs_signature_t *sig, rs_weak_sum_t weak_sum, * We don't use a static inline function here so that assert failure output * points at where rs_sig_args_check() was called from. */ #define rs_sig_args_check(magic, block_len, strong_len) do {\ - assert(((magic) & 0xffffff00) == (RS_MD4_SIG_MAGIC & 0xffffff00));\ + assert(((magic) & ~0xff) == (RS_MD4_SIG_MAGIC & ~0xff));\ assert(((magic) & 0xf0) == 0x30 || ((magic) & 0xf0) == 0x40);\ assert((((magic) & 0x0f) == 0x06 &&\ - (strong_len) <= RS_MD4_SUM_LENGTH) ||\ + (int)(strong_len) <= RS_MD4_SUM_LENGTH) ||\ (((magic) & 0x0f) == 0x07 &&\ - (strong_len) <= RS_BLAKE2_SUM_LENGTH));\ + (int)(strong_len) <= RS_BLAKE2_SUM_LENGTH));\ assert(0 < (block_len));\ assert(0 < (strong_len) && (strong_len) <= RS_MAX_STRONG_SUM_LENGTH);\ } while (0) diff --git a/src/trace.c b/src/trace.c index f4bc5df..0cbc738 100644 --- a/src/trace.c +++ b/src/trace.c @@ -62,12 +62,12 @@ static const char *rs_severities[] = { * perhaps, and an error dialog for a browser. * * \todo Do we really need such fine-grained control, or just yes/no tracing? */ -LIBRSYNC_EXPORT void rs_trace_to(rs_trace_fn_t *new_impl) +void rs_trace_to(rs_trace_fn_t *new_impl) { rs_trace_impl = new_impl; } -LIBRSYNC_EXPORT void rs_trace_set_level(rs_loglevel level) +void rs_trace_set_level(rs_loglevel level) { rs_trace_level = level; } @@ -102,12 +102,12 @@ void rs_log0(int level, char const *fn, char const *fmt, ...) va_end(va); } -LIBRSYNC_EXPORT void rs_trace_stderr(rs_loglevel UNUSED(level), char const *msg) +void rs_trace_stderr(rs_loglevel UNUSED(level), char const *msg) { fputs(msg, stderr); } -LIBRSYNC_EXPORT int rs_supports_trace(void) +int rs_supports_trace(void) { #ifdef DO_RS_TRACE return 1; @@ -63,24 +63,22 @@ static void rs_tube_catchup_write(rs_job_t *job) { rs_buffers_t *stream = job->stream; - int len = job->write_len; + size_t len = job->write_len; assert(len > 0); - if ((size_t)len > stream->avail_out) + if (len > stream->avail_out) len = stream->avail_out; - if (!stream->avail_out) { - rs_trace("no output space available"); - return; - } - memcpy(stream->next_out, job->write_buf, len); - stream->next_out += len; - stream->avail_out -= len; - job->write_len -= len; - if (job->write_len > 0) { - /* Still something left in the tube, shuffle it to the front. */ - memmove(job->write_buf, job->write_buf + len, job->write_len); + if (len) { + memcpy(stream->next_out, job->write_buf, len); + stream->next_out += len; + stream->avail_out -= len; + job->write_len -= len; + if (job->write_len > 0) + /* Still something left in the tube, shuffle it to the front. */ + memmove(job->write_buf, job->write_buf + len, job->write_len); } - rs_trace("wrote %d bytes from tube, %d remaining", len, job->write_len); + rs_trace("wrote " FMT_SIZE " bytes from tube, " FMT_SIZE " left to write", + len, job->write_len); } /** Execute a copy command, taking data from the scoop. @@ -96,15 +94,43 @@ static void rs_tube_copy_from_scoop(rs_job_t *job) len = job->scoop_avail; if (len > stream->avail_out) len = stream->avail_out; - memcpy(stream->next_out, job->scoop_next, len); - stream->next_out += len; - stream->avail_out -= len; - job->scoop_avail -= len; - job->scoop_next += len; - job->copy_len -= len; - rs_trace("caught up on " FMT_SIZE " copied bytes from scoop, " FMT_SIZE - " remain there, " FMT_LONG " remain to be copied", len, - job->scoop_avail, job->copy_len); + if (len) { + memcpy(stream->next_out, job->scoop_next, len); + stream->next_out += len; + stream->avail_out -= len; + job->scoop_avail -= len; + job->scoop_next += len; + job->copy_len -= len; + } + rs_trace("copied " FMT_SIZE " bytes from scoop, " FMT_SIZE + " left in scoop, " FMT_SIZE " left to copy", len, job->scoop_avail, + job->copy_len); +} + +/** Execute a copy command, taking data from the stream. + * + * \sa rs_tube_catchup_copy() */ +static void rs_tube_copy_from_stream(rs_job_t *job) +{ + rs_buffers_t *stream = job->stream; + size_t len = job->copy_len; + + assert(len > 0); + if (len > stream->avail_in) + len = stream->avail_in; + if (len > stream->avail_out) + len = stream->avail_out; + if (len) { + memcpy(stream->next_out, stream->next_in, len); + stream->next_out += len; + stream->avail_out -= len; + stream->next_in += len; + stream->avail_in -= len; + job->copy_len -= len; + } + rs_trace("copied " FMT_SIZE " bytes from stream, " FMT_SIZE + "left in stream, " FMT_SIZE " left to copy", len, stream->avail_in, + job->copy_len); } /** Catch up on an outstanding copy command. @@ -122,10 +148,7 @@ static void rs_tube_catchup_copy(rs_job_t *job) } /* If there's more to copy and we emptied the scoop, send input. */ if (job->copy_len && !job->scoop_avail) { - size_t this_copy = rs_buffers_copy(job->stream, job->copy_len); - job->copy_len -= this_copy; - rs_trace("copied " FMT_SIZE " bytes from input buffer, " FMT_LONG - " remain to be copied", this_copy, job->copy_len); + rs_tube_copy_from_stream(job); } } @@ -133,7 +156,7 @@ static void rs_tube_catchup_copy(rs_job_t *job) * * \return RS_DONE if the tube is now empty and ready to accept another * command, RS_BLOCKED if there is still stuff waiting to go out. */ -int rs_tube_catchup(rs_job_t *job) +rs_result rs_tube_catchup(rs_job_t *job) { if (job->write_len) { rs_tube_catchup_write(job); @@ -146,8 +169,7 @@ int rs_tube_catchup(rs_job_t *job) if (job->copy_len) { if (job->stream->eof_in && !job->stream->avail_in && !job->scoop_avail) { - rs_error - ("reached end of file while copying literal data through buffers"); + rs_error("reached end of file while copying data"); return RS_INPUT_ENDED; } return RS_BLOCKED; @@ -175,7 +197,7 @@ int rs_tube_is_idle(rs_job_t const *job) * \todo Try to do the copy immediately, and return a result. Then, people can * try to continue if possible. Is this really required? Callers can just go * out and back in again after flushing the tube. */ -void rs_tube_copy(rs_job_t *job, int len) +void rs_tube_copy(rs_job_t *job, size_t len) { assert(job->copy_len == 0); @@ -90,5 +90,5 @@ int rs_long_sqrt(rs_long_t v) if (n * n > v) n ^= b; } - return n; + return (int)n; } diff --git a/src/whole.c b/src/whole.c index e7034c6..20cb9b7 100644 --- a/src/whole.c +++ b/src/whole.c @@ -94,8 +94,8 @@ rs_result rs_sig_file(FILE *old_file, FILE *sig_file, size_t block_len, return r; job = rs_sig_begin(block_len, strong_len, sig_magic); /* Size inbuf for 4 blocks, outbuf for header + 4 blocksums. */ - r = rs_whole_run(job, old_file, sig_file, 4 * block_len, - 12 + 4 * (4 + strong_len)); + r = rs_whole_run(job, old_file, sig_file, 4 * (int)block_len, + 12 + 4 * (4 + (int)strong_len)); if (stats) memcpy(stats, &job->stats, sizeof *stats); rs_job_free(job); diff --git a/tests/checksum_test.c b/tests/checksum_test.c index de12444..fdef2f3 100644 --- a/tests/checksum_test.c +++ b/tests/checksum_test.c @@ -35,7 +35,7 @@ int main(int argc, char **argv) /* Initialize buf for use by tests. */ for (int i = 0; i < 256; i++) - buf[i] = i; + buf[i] = (unsigned char)i; /* RS_ROLLSUM weaksum tests. */ diff --git a/tests/rabinkarp_test.c b/tests/rabinkarp_test.c index 65f03bc..d0ac6c4 100644 --- a/tests/rabinkarp_test.c +++ b/tests/rabinkarp_test.c @@ -70,7 +70,7 @@ int main(int argc, char **argv) /* Test rabinkarp_update() */ for (i = 0; i < 256; i++) - buf[i] = i; + buf[i] = (unsigned char)i; rabinkarp_update(&r, buf, 256); assert(rabinkarp_digest(&r) == 0xc1972381); return 0; diff --git a/tests/rollsum_test.c b/tests/rollsum_test.c index 6310a06..109d9fc 100644 --- a/tests/rollsum_test.c +++ b/tests/rollsum_test.c @@ -72,7 +72,7 @@ int main(int argc, char **argv) /* Test RollsumUpdate() */ for (i = 0; i < 256; i++) - buf[i] = i; + buf[i] = (unsigned char)i; RollsumUpdate(&r, buf, 256); assert(RollsumDigest(&r) == 0x3a009e80); return 0; diff --git a/tests/sumset_test.c b/tests/sumset_test.c index e7bf9e0..ad8cf28 100644 --- a/tests/sumset_test.c +++ b/tests/sumset_test.c @@ -39,7 +39,7 @@ int main(int argc, char **argv) /* Initialize test buffer. */ for (i = 0; i < 256; i++) - buf[i] = i; + buf[i] = (unsigned char)i; /* Test rs_sig_args() */ rs_magic_number magic; |