From: Tim Kientzle Date: Sun, 1 Nov 2009 02:14:14 +0000 (-0400) Subject: Trying to figure out what printf modifiers to use on what platforms to X-Git-Tag: v2.8.0~253 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7206f0a8ade6b53e28ec876da90ca700a21d76be;p=thirdparty%2Flibarchive.git Trying to figure out what printf modifiers to use on what platforms to display 64-bit values is getting to be real PITA. Just roll our own conversion and use that. SVN-Revision: 1562 --- diff --git a/tar/bsdtar.h b/tar/bsdtar.h index ff1aff566..5e8dc7f89 100644 --- a/tar/bsdtar.h +++ b/tar/bsdtar.h @@ -142,6 +142,7 @@ int need_report(void); int pathcmp(const char *a, const char *b); void safe_fprintf(FILE *, const char *fmt, ...); void set_chdir(struct bsdtar *, const char *newdir); +const char *tar_i64toa(int64_t); void tar_mode_c(struct bsdtar *bsdtar); void tar_mode_r(struct bsdtar *bsdtar); void tar_mode_t(struct bsdtar *bsdtar); diff --git a/tar/bsdtar_platform.h b/tar/bsdtar_platform.h index 627683924..d86391337 100644 --- a/tar/bsdtar_platform.h +++ b/tar/bsdtar_platform.h @@ -93,25 +93,6 @@ # endif #endif - -/* - * We need to be able to display a filesize using printf(). The type - * and format string here must be compatible with one another and - * large enough for any file. - */ -#if HAVE_UINTMAX_T -#define BSDTAR_FILESIZE_TYPE uintmax_t -#define BSDTAR_FILESIZE_PRINTF "%ju" -#else -#if HAVE_UNSIGNED_LONG_LONG -#define BSDTAR_FILESIZE_TYPE unsigned long long -#define BSDTAR_FILESIZE_PRINTF "%llu" -#else -#define BSDTAR_FILESIZE_TYPE unsigned long -#define BSDTAR_FILESIZE_PRINTF "%lu" -#endif -#endif - #if HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC #define ARCHIVE_STAT_CTIME_NANOS(st) (st)->st_ctimespec.tv_nsec #define ARCHIVE_STAT_MTIME_NANOS(st) (st)->st_mtimespec.tv_nsec diff --git a/tar/read.c b/tar/read.c index c5a8718c2..9816ed359 100644 --- a/tar/read.c +++ b/tar/read.c @@ -99,7 +99,7 @@ progress_func(void *cookie) struct bsdtar *bsdtar = progress_data->bsdtar; struct archive *a = progress_data->archive; struct archive_entry *entry = progress_data->entry; - uintmax_t comp, uncomp; + uint64_t comp, uncomp; if (!need_report()) return; @@ -110,16 +110,16 @@ progress_func(void *cookie) comp = archive_position_compressed(a); uncomp = archive_position_uncompressed(a); fprintf(stderr, - "In: %ju bytes, compression %d%%;", - comp, (int)((uncomp - comp) * 100 / uncomp)); - fprintf(stderr, " Out: %d files, %ju bytes\n", - archive_file_count(a), uncomp); + "In: %s bytes, compression %d%%;", + tar_i64toa(comp), (int)((uncomp - comp) * 100 / uncomp)); + fprintf(stderr, " Out: %d files, %s bytes\n", + archive_file_count(a), tar_i64toa(uncomp)); } if (entry != NULL) { - safe_fprintf(stderr, "Current: %s (%ju bytes)", - archive_entry_pathname(entry), - (uintmax_t)archive_entry_size(entry)); - fprintf(stderr, "\n"); + safe_fprintf(stderr, "Current: %s", + archive_entry_pathname(entry)); + fprintf(stderr, " (%s bytes)\n", + tar_i64toa(archive_entry_size(entry))); } } @@ -403,13 +403,7 @@ list_item_verbose(struct bsdtar *bsdtar, FILE *out, struct archive_entry *entry) (unsigned long)archive_entry_rdevmajor(entry), (unsigned long)archive_entry_rdevminor(entry)); } else { - /* - * Note the use of platform-dependent macros to format - * the filesize here. We need the format string and the - * corresponding type for the cast. - */ - sprintf(tmp, BSDTAR_FILESIZE_PRINTF, - (BSDTAR_FILESIZE_TYPE)archive_entry_size(entry)); + strcpy(tmp, tar_i64toa(archive_entry_size(entry))); } if (w + strlen(tmp) >= bsdtar->gs_width) bsdtar->gs_width = w+strlen(tmp)+1; diff --git a/tar/util.c b/tar/util.c index a55692384..2b0751aea 100644 --- a/tar/util.c +++ b/tar/util.c @@ -487,6 +487,28 @@ edit_pathname(struct bsdtar *bsdtar, struct archive_entry *entry) return (0); } +/* + * It would be nice to just use printf() for formatting large numbers, + * but the compatibility problems are quite a headache. Hence the + * following simple utility function. + */ +const char * +tar_i64toa(int64_t n0) +{ + static char buff[24]; + int64_t n = n0 < 0 ? -n0 : n0; + char *p = buff + sizeof(buff); + + *--p = '\0'; + do { + *--p = '0' + (n % 10); + n /= 10; + } while (n > 0); + if (n0 < 0) + *--p = '-'; + return p; +} + /* * Like strcmp(), but try to be a little more aware of the fact that * we're comparing two paths. Right now, it just handles leading diff --git a/tar/write.c b/tar/write.c index 1d41bb36f..d4f20bca0 100644 --- a/tar/write.c +++ b/tar/write.c @@ -498,8 +498,8 @@ cleanup: bsdtar->diskreader = NULL; if (bsdtar->option_totals) { - fprintf(stderr, "Total bytes written: " BSDTAR_FILESIZE_PRINTF "\n", - (BSDTAR_FILESIZE_TYPE)archive_position_compressed(a)); + fprintf(stderr, "Total bytes written: %s\n", + tar_i64toa(archive_position_compressed(a))); } archive_write_finish(a); @@ -956,21 +956,22 @@ static void report_write(struct bsdtar *bsdtar, struct archive *a, struct archive_entry *entry, int64_t progress) { - uintmax_t comp, uncomp; + uint64_t comp, uncomp; if (bsdtar->verbose) fprintf(stderr, "\n"); comp = archive_position_compressed(a); uncomp = archive_position_uncompressed(a); - fprintf(stderr, "In: %d files, %ju bytes;", - archive_file_count(a), uncomp); + fprintf(stderr, "In: %d files, %s bytes;", + archive_file_count(a), tar_i64toa(uncomp)); fprintf(stderr, - " Out: %ju bytes, compression %d%%\n", - comp, (int)((uncomp - comp) * 100 / uncomp)); - safe_fprintf(stderr, "Current: %s (%ju/%ju bytes)", + " Out: %s bytes, compression %d%%\n", + tar_i64toa(comp), (int)((uncomp - comp) * 100 / uncomp)); + /* Can't have two calls to tar_i64toa() pending, so split the output. */ + safe_fprintf(stderr, "Current: %s (%s", archive_entry_pathname(entry), - (uintmax_t)progress, - (uintmax_t)archive_entry_size(entry)); - fprintf(stderr, "\n"); + tar_i64toa(progress)); + fprintf(stderr, "/%s bytes)\n", + tar_i64toa(archive_entry_size(entry))); }