adb: win32: fix StringPrintf format string checking of %zd and PRIu64
At runtime, vsnprintf (and android::base::StringPrintf which calls it) call a mingw version of vsnprintf, not the vsnprintf from MSVCRT.DLL. The mingw version properly understands %zd and PRIu64 (the latter, provided that you #include <inttypes.h>). The problem was that android::base::StringPrintf was causing compile-time errors saying that %zd and PRIu64 were not recognized. It seems that this was because the attribute on the function prototypes specified `printf' instead of `gnu_printf'. Once that was fixed to match vsnprintf's attribute, the warnings went away. This uses similar preprocessor techniques as <android/log.h>. Also restore a %zd usage to avoid a static_cast<>, and make print_transfer_progress()'s format string compile-time checkable (and tweak some types and %llu => PRIu64). Change-Id: I80b31b9994858a28cb7c6847143b86108b8ab842 Signed-off-by: Spencer Low <CompareAndSwap@gmail.com>
This commit is contained in:
parent
74f0a578a8
commit
6001c87cbc
4 changed files with 26 additions and 20 deletions
|
@ -145,8 +145,8 @@ bool adb_status(int fd, std::string* error) {
|
|||
int _adb_connect(const std::string& service, std::string* error) {
|
||||
D("_adb_connect: %s\n", service.c_str());
|
||||
if (service.empty() || service.size() > 1024) {
|
||||
*error = android::base::StringPrintf("bad service name length (%d)",
|
||||
static_cast<int>(service.size()));
|
||||
*error = android::base::StringPrintf("bad service name length (%zd)",
|
||||
service.size());
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
|
@ -1593,11 +1593,7 @@ static int install_multiple_app(TransportType transport, const char* serial, int
|
|||
return 1;
|
||||
}
|
||||
|
||||
#if defined(_WIN32) // Remove when we're using clang for Win32.
|
||||
std::string cmd = android::base::StringPrintf("exec:pm install-create -S %u", (unsigned) total_size);
|
||||
#else
|
||||
std::string cmd = android::base::StringPrintf("exec:pm install-create -S %" PRIu64, total_size);
|
||||
#endif
|
||||
for (i = 1; i < first_apk; i++) {
|
||||
cmd += " " + escape_arg(argv[i]);
|
||||
}
|
||||
|
@ -1638,15 +1634,9 @@ static int install_multiple_app(TransportType transport, const char* serial, int
|
|||
goto finalize_session;
|
||||
}
|
||||
|
||||
#if defined(_WIN32) // Remove when we're using clang for Win32.
|
||||
std::string cmd = android::base::StringPrintf(
|
||||
"exec:pm install-write -S %u %d %d_%s -",
|
||||
(unsigned) sb.st_size, session_id, i, get_basename(file));
|
||||
#else
|
||||
std::string cmd = android::base::StringPrintf(
|
||||
"exec:pm install-write -S %" PRIu64 " %d %d_%s -",
|
||||
static_cast<uint64_t>(sb.st_size), session_id, i, get_basename(file));
|
||||
#endif
|
||||
|
||||
int localFd = adb_open(file, O_RDONLY);
|
||||
if (localFd < 0) {
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
#include <dirent.h>
|
||||
#include <errno.h>
|
||||
#include <inttypes.h>
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
@ -63,13 +64,12 @@ static void END()
|
|||
total_bytes, (t / 1000000LL), (t % 1000000LL) / 1000LL);
|
||||
}
|
||||
|
||||
static const char* transfer_progress_format = "\rTransferring: %llu/%llu (%d%%)";
|
||||
|
||||
static void print_transfer_progress(unsigned long long bytes_current,
|
||||
unsigned long long bytes_total) {
|
||||
static void print_transfer_progress(uint64_t bytes_current,
|
||||
uint64_t bytes_total) {
|
||||
if (bytes_total == 0) return;
|
||||
|
||||
fprintf(stderr, transfer_progress_format, bytes_current, bytes_total,
|
||||
fprintf(stderr, "\rTransferring: %" PRIu64 "/%" PRIu64 " (%d%%)",
|
||||
bytes_current, bytes_total,
|
||||
(int) (bytes_current * 100 / bytes_total));
|
||||
|
||||
if (bytes_current == bytes_total) {
|
||||
|
|
|
@ -23,16 +23,32 @@
|
|||
namespace android {
|
||||
namespace base {
|
||||
|
||||
// These printf-like functions are implemented in terms of vsnprintf, so they
|
||||
// use the same attribute for compile-time format string checking. On Windows,
|
||||
// if the mingw version of vsnprintf is used, use `gnu_printf' which allows z
|
||||
// in %zd and PRIu64 (and related) to be recognized by the compile-time
|
||||
// checking.
|
||||
#define FORMAT_ARCHETYPE __printf__
|
||||
#ifdef __USE_MINGW_ANSI_STDIO
|
||||
#if __USE_MINGW_ANSI_STDIO
|
||||
#undef FORMAT_ARCHETYPE
|
||||
#define FORMAT_ARCHETYPE gnu_printf
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Returns a string corresponding to printf-like formatting of the arguments.
|
||||
std::string StringPrintf(const char* fmt, ...)
|
||||
__attribute__((__format__(__printf__, 1, 2)));
|
||||
__attribute__((__format__(FORMAT_ARCHETYPE, 1, 2)));
|
||||
|
||||
// Appends a printf-like formatting of the arguments to 'dst'.
|
||||
void StringAppendF(std::string* dst, const char* fmt, ...)
|
||||
__attribute__((__format__(__printf__, 2, 3)));
|
||||
__attribute__((__format__(FORMAT_ARCHETYPE, 2, 3)));
|
||||
|
||||
// Appends a printf-like formatting of the arguments to 'dst'.
|
||||
void StringAppendV(std::string* dst, const char* format, va_list ap);
|
||||
void StringAppendV(std::string* dst, const char* format, va_list ap)
|
||||
__attribute__((__format__(FORMAT_ARCHETYPE, 2, 0)));
|
||||
|
||||
#undef FORMAT_ARCHETYPE
|
||||
|
||||
} // namespace base
|
||||
} // namespace android
|
||||
|
|
Loading…
Reference in a new issue