Fix -Wsign-compare warnings in CLI

Make cli_printf() return void (log errors instead)

Better size_t arithmetic in outv_growbuf()
This commit is contained in:
Andrew Bettison 2013-12-10 16:56:23 +10:30
parent 4af6cf9d6a
commit 6cd8df74a4
2 changed files with 32 additions and 20 deletions

3
cli.h
View File

@ -92,8 +92,7 @@ int cli_optional_did(const char *text);
int cli_putchar(struct cli_context *context, char c); int cli_putchar(struct cli_context *context, char c);
int cli_puts(struct cli_context *context, const char *str); int cli_puts(struct cli_context *context, const char *str);
int cli_printf(struct cli_context *context, const char *fmt, ...) void cli_printf(struct cli_context *context, const char *fmt, ...) __attribute__ (( format(printf,2,3) ));
__attribute__ (( format(printf,2,3) ));
int cli_delim(struct cli_context *context, const char *opt); int cli_delim(struct cli_context *context, const char *opt);
void cli_columns(struct cli_context *context, int columns, const char *names[]); void cli_columns(struct cli_context *context, int columns, const char *names[]);
void cli_row_count(struct cli_context *context, int rows); void cli_row_count(struct cli_context *context, int rows);

View File

@ -108,15 +108,19 @@ jmethodID startResultSet, setColumnName, putString, putBlob, putLong, putDouble,
static int outv_growbuf(struct cli_context *context, size_t needed) static int outv_growbuf(struct cli_context *context, size_t needed)
{ {
size_t newsize = (context->outv_limit - context->outv_current < needed) ? (context->outv_limit - context->outv_buffer) + needed : 0; assert(context->outv_current <= context->outv_limit);
if (newsize) { size_t remaining = (size_t)(context->outv_limit - context->outv_current);
if (remaining < needed) {
size_t cursize = context->outv_current - context->outv_buffer;
size_t newsize = cursize + needed;
// Round up to nearest multiple of OUTV_BUFFER_ALLOCSIZE. // Round up to nearest multiple of OUTV_BUFFER_ALLOCSIZE.
newsize = newsize + OUTV_BUFFER_ALLOCSIZE - ((newsize - 1) % OUTV_BUFFER_ALLOCSIZE + 1); newsize = newsize + OUTV_BUFFER_ALLOCSIZE - ((newsize - 1) % OUTV_BUFFER_ALLOCSIZE + 1);
size_t length = context->outv_current - context->outv_buffer; assert(newsize > cursize);
assert((size_t)(newsize - cursize) >= needed);
context->outv_buffer = realloc(context->outv_buffer, newsize); context->outv_buffer = realloc(context->outv_buffer, newsize);
if (context->outv_buffer == NULL) if (context->outv_buffer == NULL)
return WHYF("Out of memory allocating %lu bytes", (unsigned long) newsize); return WHYF("Out of memory allocating %lu bytes", (unsigned long) newsize);
context->outv_current = context->outv_buffer + length; context->outv_current = context->outv_buffer + cursize;
context->outv_limit = context->outv_buffer + newsize; context->outv_limit = context->outv_buffer + newsize;
} }
return 0; return 0;
@ -340,36 +344,45 @@ int cli_puts(struct cli_context *context, const char *str)
} }
/* Write a formatted string to output. If in a JNI call, then this appends the string to the /* Write a formatted string to output. If in a JNI call, then this appends the string to the
current output field, excluding the terminating null. Returns the number of bytes current output field, excluding the terminating null.
written/appended, or -1 on error.
*/ */
int cli_printf(struct cli_context *context, const char *fmt, ...) void cli_printf(struct cli_context *context, const char *fmt, ...)
{ {
int ret = 0;
va_list ap; va_list ap;
#ifdef HAVE_JNI_H #ifdef HAVE_JNI_H
if (context && context->jni_env) { if (context && context->jni_env) {
assert(context->outv_current <= context->outv_limit);
size_t avail = context->outv_limit - context->outv_current; size_t avail = context->outv_limit - context->outv_current;
va_start(ap, fmt); va_start(ap, fmt);
int count = vsnprintf(context->outv_current, avail, fmt, ap); int count = vsnprintf(context->outv_current, avail, fmt, ap);
va_end(ap); va_end(ap);
if (count >= avail) { if (count < 0) {
if (outv_growbuf(context, count) == -1) WHYF("vsnprintf(%p,%zu,%s,...) failed", context->outv_current, avail, alloca_str_toprint(fmt));
return -1; return;
va_start(ap, fmt); } else if ((size_t)count < avail) {
vsprintf(context->outv_current, fmt, ap);
va_end(ap);
}
context->outv_current += count; context->outv_current += count;
ret = count; return;
}
if (outv_growbuf(context, count) == -1)
return;
avail = context->outv_limit - context->outv_current;
va_start(ap, fmt);
count = vsprintf(context->outv_current, fmt, ap);
va_end(ap);
if (count < 0) {
WHYF("vsprintf(%p,%s,...) failed", context->outv_current, alloca_str_toprint(fmt));
return;
}
assert((size_t)count < avail);
context->outv_current += (size_t)count;
} else } else
#endif #endif
{ {
va_start(ap, fmt); va_start(ap, fmt);
ret = vfprintf(stdout, fmt, ap); if (vfprintf(stdout, fmt, ap) < 0)
WHYF("vfprintf(stdout,%s,...) failed", alloca_str_toprint(fmt));
va_end(ap); va_end(ap);
} }
return ret;
} }
void cli_columns(struct cli_context *context, int columns, const char *names[]) void cli_columns(struct cli_context *context, int columns, const char *names[])