Provide new functions to convert long long to string

The previous attempt to use PRI* macros to avoid compiler-specific
printf format specifiers didn't work because we are using raw
long long type, not the uintX_t types.  On systems where long and
long long are the same size, uint64_t might be type "long" and PRId64
is just "ld".

Instead write new functions that convert [unsigned] long long to a
string and call those instead.

* src/makeint.h: Declare make_lltoa() and make_ulltoa().
* src/misc.c (make_lltoa): New function that writes a long long value
into a provided buffer.  Return the buffer for ease-of-use.
(make_ulltoa): Ditto, for unsigned long long.
* src/function.c (func_wordlist): Call these new methods.  Also
rework the error strings so we share the translated string.
* src/dir.c (print_dir_data_base): Call the new methods instead of
using MSVC macros.
This commit is contained in:
Paul Smith 2022-09-25 16:12:21 -04:00
parent c4e232e44f
commit f3640ecf4f
4 changed files with 50 additions and 39 deletions

View File

@ -1102,6 +1102,9 @@ print_dir_data_base (void)
unsigned int impossible;
struct directory **dir_slot;
struct directory **dir_end;
#ifdef WINDOWS32
char buf[INTSTR_LENGTH + 1];
#endif
puts (_("\n# Directories\n"));
@ -1117,24 +1120,19 @@ print_dir_data_base (void)
if (dir->contents == 0)
printf (_("# %s: could not be stat'd.\n"), dir->name);
else if (dir->contents->dirfiles.ht_vec == 0)
{
#ifdef WINDOWS32
printf (_("# %s (key %s, mtime %I64u): could not be opened.\n"),
printf (_("# %s (key %s, mtime %s): could not be opened.\n"),
dir->name, dir->contents->path_key,
(unsigned long long)dir->contents->mtime);
#else /* WINDOWS32 */
#ifdef VMS_INO_T
make_ulltoa ((unsigned long long)dir->contents->mtime, buf));
#elif defined(VMS_INO_T)
printf (_("# %s (device %d, inode [%d,%d,%d]): could not be opened.\n"),
dir->name, dir->contents->dev,
dir->contents->ino[0], dir->contents->ino[1],
dir->contents->ino[2]);
#else
printf (_("# %s (device %ld, inode %ld): could not be opened.\n"),
dir->name, (long int) dir->contents->dev,
(long int) dir->contents->ino);
dir->name, (long) dir->contents->dev, (long) dir->contents->ino);
#endif
#endif /* WINDOWS32 */
}
else
{
unsigned int f = 0;
@ -1156,21 +1154,18 @@ print_dir_data_base (void)
}
}
#ifdef WINDOWS32
printf (_("# %s (key %s, mtime %I64u): "),
printf (_("# %s (key %s, mtime %s): "),
dir->name, dir->contents->path_key,
(unsigned long long)dir->contents->mtime);
#else /* WINDOWS32 */
#ifdef VMS_INO_T
make_ulltoa ((unsigned long long)dir->contents->mtime, buf));
#elif defined(VMS_INO_T)
printf (_("# %s (device %d, inode [%d,%d,%d]): "),
dir->name, dir->contents->dev,
dir->contents->ino[0], dir->contents->ino[1],
dir->contents->ino[2]);
#else
printf (_("# %s (device %ld, inode %ld): "),
dir->name,
printf (_("# %s (device %ld, inode %ld): "), dir->name,
(long)dir->contents->dev, (long)dir->contents->ino);
#endif
#endif /* WINDOWS32 */
if (f == 0)
fputs (_("No"), stdout);
else

View File

@ -816,20 +816,18 @@ func_word (char *o, char **argv, const char *funcname UNUSED)
static char *
func_wordlist (char *o, char **argv, const char *funcname UNUSED)
{
char buf[INTSTR_LENGTH + 1];
long long start, stop, count;
const char* badfirst = _("invalid first argument to 'wordlist' function");
const char* badsecond = _("invalid second argument to 'wordlist' function");
start = parse_numeric (argv[0],
_("invalid first argument to 'wordlist' function"));
stop = parse_numeric (argv[1],
_("invalid second argument to 'wordlist' function"));
start = parse_numeric (argv[0], badfirst);
if (start < 1)
ON (fatal, *expanding_var,
"invalid first argument to 'wordlist' function: '%" PRId64 "'", start);
OSS (fatal, *expanding_var, "%s: '%s'", badfirst, make_lltoa (start, buf));
stop = parse_numeric (argv[1], badsecond);
if (stop < 0)
ON (fatal, *expanding_var,
"invalid second argument to 'wordlist' function: '%" PRId64 "'", stop);
OSS (fatal, *expanding_var, "%s: '%s'", badsecond, make_lltoa (stop, buf));
count = stop - start + 1;

View File

@ -290,14 +290,6 @@ char *strerror (int errnum);
#if HAVE_INTTYPES_H
# include <inttypes.h>
#else
# ifndef PRId64
# ifdef WINDOWS32
# define PRId64 "I64d"
# else
# define PRId64 "lld"
# endif
# endif
#endif
#if HAVE_STDINT_H
# include <stdint.h>
@ -543,6 +535,8 @@ void pfatal_with_name (const char *) NORETURN;
void perror_with_name (const char *, const char *);
#define xstrlen(_s) ((_s)==NULL ? 0 : strlen (_s))
unsigned int make_toui (const char*, const char**);
char *make_lltoa (long long, char *);
char *make_ulltoa (unsigned long long, char *);
pid_t make_pid ();
void *xmalloc (size_t);
void *xcalloc (size_t);

View File

@ -54,6 +54,30 @@ make_toui (const char *str, const char **error)
return val;
}
#if WINDOWS32
/* MSVCRT does not support the 'll' format specifier. */
# define LLFMT "I64"
#else
# define LLFMT "ll"
#endif
/* Convert val into a string, written to buf. buf must be large enough
to hold the largest possible value, plus a nul byte. Returns buf. */
char *
make_lltoa (long long val, char *buf)
{
sprintf (buf, "%" LLFMT "d", val);
return buf;
}
char *
make_ulltoa (unsigned long long val, char *buf)
{
sprintf (buf, "%" LLFMT "u", val);
return buf;
}
/* Compare strings *S1 and *S2.
Return negative if the first is less, positive if it is greater,
zero if they are equal. */