Hi -
Long ago (maybe 3 years ago?) Manoj generated a patch for 1.3 which added
some widely used formats which were not implemented in the libc
implementation of strftime on win32.
Well, I think apr should be doing the same thing (i.e. trying to add
support for as many of these formats as possible).
this patch is almost exactly the same as manoj's patch (which was for
1.3), modified in just a couple of places, so its not my implementation,
but it seems it would be a good start to add this back in.
Ideally we would continue to implement formats as necessary (or should we spend
some
time implementing them all?).
thoughts?
sterling
Index: srclib/apr/time/win32/timestr.c
===================================================================
RCS file: /home/cvspublic/apr/time/win32/timestr.c,v
retrieving revision 1.14
diff -u -r1.14 timestr.c
--- srclib/apr/time/win32/timestr.c 16 Feb 2001 04:16:23 -0000 1.14
+++ srclib/apr/time/win32/timestr.c 16 Jan 2002 00:55:35 -0000
@@ -54,6 +54,7 @@
#include "win32/atime.h"
#include "apr_portable.h"
+#include "apr_strings.h"
APR_DECLARE_DATA const char apr_month_snames[12][4] =
{
@@ -154,6 +155,69 @@
return APR_SUCCESS;
}
+int win32_strftime_extra(char *s, size_t max, const char *format,
+ const struct tm *tm) {
+ /* If the new format string is bigger than max, the result string won't fit
+ * anyway. If format strings are added, made sure the padding below is
+ * enough */
+ char *new_format = (char *) malloc(max + 11);
+ size_t i, j, format_length = strlen(format);
+ int return_value;
+ int length_written;
+
+ for (i = 0, j = 0; (i < format_length && j < max);) {
+ if (format[i] != '%') {
+ new_format[j++] = format[i++];
+ continue;
+ }
+ switch (format[i+1]) {
+ case 'C':
+ length_written = apr_snprintf(new_format + j, max - j, "%2d",
+ (tm->tm_year + 1970)/100);
+ j = (length_written == -1) ? max : (j + length_written);
+ i += 2;
+ break;
+ case 'D':
+ /* Is this locale dependent? Shouldn't be...
+ Also note the year 2000 exposure here */
+ memcpy(new_format + j, "%m/%d/%y", 8);
+ i += 2;
+ j += 8;
+ break;
+ case 'r':
+ memcpy(new_format + j, "%I:%M:%S %p", 11);
+ i += 2;
+ j += 11;
+ break;
+ case 'T':
+ memcpy(new_format + j, "%H:%M:%S", 8);
+ i += 2;
+ j += 8;
+ break;
+ case 'e':
+ length_written = apr_snprintf(new_format + j, max - j, "%2d",
+ tm->tm_mday);
+ j = (length_written == -1) ? max : (j + length_written);
+ i += 2;
+ break;
+ default:
+ /* We know we can advance two characters forward here. Also
+ * makes sure that %% is preserved. */
+ new_format[j++] = format[i++];
+ new_format[j++] = format[i++];
+ }
+ }
+ if (j >= max) {
+ *s = '\0'; /* Defensive programming, okay since output is undefined*/
+ return_value = 0;
+ } else {
+ new_format[j] = '\0';
+ return_value = strftime(s, max, new_format, tm);
+ }
+ free(new_format);
+ return return_value;
+ }
+
APR_DECLARE(apr_status_t) apr_strftime(char *s, apr_size_t *retsize,
apr_size_t max, const char *format,
apr_exploded_time_t *xt)
@@ -168,7 +232,7 @@
tm.tm_year = xt->tm_year;
tm.tm_wday = xt->tm_wday;
tm.tm_yday = xt->tm_yday;
- tm.tm_isdst = xt->tm_isdst;
- (*retsize) = strftime(s, max, format, &tm);
+ tm.tm_isdst = xt->tm_isdst;
+ (*retsize) = win32_strftime_extra(s, max, format, &tm);
return APR_SUCCESS;
}