#ifdef HAVE_PWD_H
# include <pwd.h>
#endif
-#include <limits.h>
+#ifdef HAVE_LIMITS_H
+# include <limits.h>
+#endif
#ifdef HAVE_UTIME_H
# include <utime.h>
#endif
#endif
#include <fcntl.h>
#include <assert.h>
+#ifdef WGET_USE_STDARG
+# include <stdarg.h>
+#else
+# include <varargs.h>
+#endif
/* For TIOCGWINSZ and friends: */
#ifdef HAVE_SYS_IOCTL_H
return res;
}
\f
+#ifdef WGET_USE_STDARG
+# define VA_START(args, arg1) va_start (args, arg1)
+#else
+# define VA_START(args, ignored) va_start (args)
+#endif
+
+/* Like sprintf, but allocates a string of sufficient size with malloc
+ and returns it. GNU libc has a similar function named asprintf,
+ which requires the pointer to the string to be passed. */
+
+char *
+aprintf (const char *fmt, ...)
+{
+ /* This function is implemented using vsnprintf, which we provide
+ for the systems that don't have it. Therefore, it should be 100%
+ portable. */
+
+ int size = 32;
+ char *str = xmalloc (size);
+
+ while (1)
+ {
+ int n;
+ va_list args;
+
+ /* See log_vprintf_internal for explanation why it's OK to rely
+ on the return value of vsnprintf. */
+
+ VA_START (args, fmt);
+ n = vsnprintf (str, size, fmt, args);
+ va_end (args);
+
+ /* If the printing worked, return the string. */
+ if (n > -1 && n < size)
+ return str;
+
+ /* Else try again with a larger buffer. */
+ if (n > -1) /* C99 */
+ size = n + 1; /* precisely what is needed */
+ else
+ size <<= 1; /* twice the old size */
+ str = xrealloc (str, size);
+ }
+ return NULL; /* unreached */
+}
+\f
/* Return pointer to a static char[] buffer in which zero-terminated
string-representation of TM (in form hh:mm:ss) is printed.
return cnt;
}
-/* A half-assed implementation of INT_MAX on machines that don't
- bother to define one. */
+/* Attempt to calculate INT_MAX on machines that don't bother to
+ define it. */
#ifndef INT_MAX
-# define INT_MAX ((int) ~((unsigned)1 << 8 * sizeof (int) - 1))
+# ifndef CHAR_BIT
+# define CHAR_BIT 8
+# endif
+# define INT_MAX ((int) ~((unsigned)1 << CHAR_BIT * sizeof (int) - 1))
#endif
#define ONE_DIGIT(figure) *p++ = n / (figure) + '0'
#endif
struct wget_timer {
+ /* Whether the start time has been initialized. */
+ int initialized;
+
/* The starting point in time which, subtracted from the current
time, yields elapsed time. */
wget_sys_time start;
double elapsed_pre_start;
};
-/* Allocate a timer. It is not legal to do anything with a freshly
- allocated timer, except call wtimer_reset() or wtimer_delete(). */
+/* Allocate a timer. Calling wtimer_read on the timer will return
+ zero. It is not legal to call wtimer_update with a freshly
+ allocated timer -- use wtimer_reset first. */
struct wget_timer *
wtimer_allocate (void)
{
struct wget_timer *wt = xnew (struct wget_timer);
+ xzero (*wt);
return wt;
}
wtimer_sys_set (&wt->start);
wt->elapsed_last = 0;
wt->elapsed_pre_start = 0;
+ wt->initialized = 1;
}
static double
wget_sys_time now;
double elapsed;
+ assert (wt->initialized != 0);
+
wtimer_sys_set (&now);
elapsed = wt->elapsed_pre_start + wtimer_sys_diff (&now, &wt->start);