r16048 - gnucash/trunk/lib/libc - Add Windows-specific code to lib/libc/strptime.c to eat %x, %X and %c.
Andreas Köhler
andi5 at cvs.gnucash.org
Sat May 5 16:44:24 EDT 2007
Author: andi5
Date: 2007-05-05 16:44:24 -0400 (Sat, 05 May 2007)
New Revision: 16048
Trac: http://svn.gnucash.org/trac/changeset/16048
Modified:
gnucash/trunk/lib/libc/Makefile.am
gnucash/trunk/lib/libc/strptime.c
Log:
Add Windows-specific code to lib/libc/strptime.c to eat %x, %X and %c.
Originally, it came from evolution-data-server,
/libedataserver/e-time-utils.c, but was modified to not depend on GLib.
Modified: gnucash/trunk/lib/libc/Makefile.am
===================================================================
--- gnucash/trunk/lib/libc/Makefile.am 2007-05-05 20:29:39 UTC (rev 16047)
+++ gnucash/trunk/lib/libc/Makefile.am 2007-05-05 20:44:24 UTC (rev 16048)
@@ -17,6 +17,10 @@
libc_missing_la_LIBADD = $(LTLIBOBJS)
+if OS_WIN32
+ AM_CFLAGS = -DOS_WIN32
+endif
+
# Not currently used. If added to AC_REPLACE_FUNCS then this line
# should be removed.
EXTRA_DIST = scm_strptime.c
Modified: gnucash/trunk/lib/libc/strptime.c
===================================================================
--- gnucash/trunk/lib/libc/strptime.c 2007-05-05 20:29:39 UTC (rev 16047)
+++ gnucash/trunk/lib/libc/strptime.c 2007-05-05 20:44:24 UTC (rev 16048)
@@ -38,6 +38,166 @@
#include "strptime.h"
+
+#ifdef OS_WIN32
+/* The localtime_r() definition in pthreads-win32's pthread.h doesn't guard
+ * against localtime() returning NULL.
+ */
+#undef localtime_r
+/* The localtime() in Microsoft's C library is MT-safe */
+#define localtime_r(tp,tmp) (localtime(tp)?(*(tmp)=*localtime(tp),(tmp)):0)
+
+#include <windows.h>
+
+static char *
+get_locale_string (int lctype)
+{
+ int nbytes = GetLocaleInfo (GetThreadLocale (), lctype, NULL, 0);
+ char *tem;
+
+ if (nbytes == 0)
+ return "???";
+
+ tem = malloc (nbytes);
+
+ if (GetLocaleInfo (GetThreadLocale (), lctype, tem, nbytes) == 0) {
+ free (tem);
+ tem = malloc (4);
+ strcpy (tem, "???");
+ }
+
+ return tem;
+}
+
+static void
+append_char (char **str, int *size, int *i, char c)
+{
+ if (*size <= *i + 1) {
+ char *new;
+ *size *= 2;
+ new = malloc (*size);
+ strncpy (new, *str, *i);
+ free (*str);
+ *str = new;
+ }
+ (*str)[*i] = c;
+ (*str)[++(*i)] = '\0';
+}
+
+static char *
+translate_picture (const char *picture)
+{
+ int size = strlen (picture) * 2;
+ char *str = malloc (size);
+ int i = 0;
+
+ str[0] = '\0';
+
+ while (*picture) {
+ const char *q = picture + 1;
+ int count;
+
+ while (*picture == *q)
+ q++;
+ count = q - picture;
+
+ switch (*picture) {
+ case '\'':
+ picture++;
+ while (*picture && *picture != '\'') {
+ append_char (&str, &size, &i, *picture);
+ picture++;
+ }
+ break;
+ case 'd':
+ switch (count) {
+ case 1:
+ case 2:
+ append_char (&str, &size, &i, '%');
+ append_char (&str, &size, &i, 'd');
+ break;
+ case 3:
+ case 4:
+ append_char (&str, &size, &i, '%');
+ append_char (&str, &size, &i, 'a');
+ break;
+ }
+ picture += count - 1;
+ break;
+ case 'M':
+ switch (count) {
+ case 1:
+ case 2:
+ append_char (&str, &size, &i, '%');
+ append_char (&str, &size, &i, 'm');
+ break;
+ case 3:
+ case 4:
+ append_char (&str, &size, &i, '%');
+ append_char (&str, &size, &i, 'b');
+ break;
+ }
+ picture += count - 1;
+ break;
+ case 'y':
+ switch (count) {
+ case 1: /* Last digit of year. Ugh... */
+ case 2:
+ append_char (&str, &size, &i, '%');
+ append_char (&str, &size, &i, 'y');
+ break;
+ case 4:
+ append_char (&str, &size, &i, '%');
+ append_char (&str, &size, &i, 'Y');
+ break;
+ }
+ picture += count - 1;
+ break;
+ case 'g':
+ /* Era. Huh. Just ignore, as the era stuff
+ * implementation below depends on glibc.
+ */
+ picture += count - 1;
+ break;
+ case 'h':
+ append_char (&str, &size, &i, '%');
+ append_char (&str, &size, &i, 'I');
+ picture += count - 1;
+ break;
+ case 'H':
+ append_char (&str, &size, &i, '%');
+ append_char (&str, &size, &i, 'H');
+ picture += count - 1;
+ break;
+ case 'm':
+ append_char (&str, &size, &i, '%');
+ append_char (&str, &size, &i, 'M');
+ picture += count - 1;
+ break;
+ case 's':
+ append_char (&str, &size, &i, '%');
+ append_char (&str, &size, &i, 'S');
+ picture += count - 1;
+ break;
+ case 't':
+ append_char (&str, &size, &i, '%');
+ append_char (&str, &size, &i, 'p');
+ picture += count - 1;
+ break;
+ default:
+ append_char (&str, &size, &i, *picture);
+ break;
+ }
+ if (*picture)
+ picture++;
+ }
+
+ return str;
+}
+
+#endif /* OS_WIN32 */
+
+
#ifndef __P
# if defined (__GNUC__) || (defined (__STDC__) && __STDC__)
# define __P(args) args
@@ -332,6 +492,30 @@
break;
}
}
+#elif defined (OS_WIN32)
+ if (*decided !=raw)
+ {
+ char *locale_string = get_locale_string (LOCALE_SDAYNAME1 + cnt);
+ if (match_string (locale_string, rp))
+ {
+ if (*decided == not
+ && strcmp (locale_string, weekday_name[cnt]))
+ *decided = loc;
+ free (locale_string);
+ break;
+ }
+ free (locale_string);
+ locale_string = get_locale_string (LOCALE_SABBREVDAYNAME1 + cnt);
+ if (match_string (locale_string, rp))
+ {
+ if (*decided == not
+ && strcmp (locale_string, ab_weekday_name[cnt]))
+ *decided = loc;
+ free (locale_string);
+ break;
+ }
+ free (locale_string);
+ }
#endif
if (*decided != loc
&& (match_string (weekday_name[cnt], rp)
@@ -373,6 +557,30 @@
break;
}
}
+#elif defined (OS_WIN32)
+ if (*decided !=raw)
+ {
+ char *locale_string = get_locale_string (LOCALE_SMONTHNAME1 + cnt);
+ if (match_string (locale_string, rp))
+ {
+ if (*decided == not
+ && strcmp (locale_string, month_name[cnt]))
+ *decided = loc;
+ free (locale_string);
+ break;
+ }
+ free (locale_string);
+ locale_string = get_locale_string (LOCALE_SABBREVMONTHNAME1 + cnt);
+ if (match_string (locale_string, rp))
+ {
+ if (*decided == not
+ && strcmp (locale_string, ab_month_name[cnt]))
+ *decided = loc;
+ free (locale_string);
+ break;
+ }
+ free (locale_string);
+ }
#endif
if (match_string (month_name[cnt], rp)
|| match_string (ab_month_name[cnt], rp))
@@ -409,6 +617,50 @@
}
*decided = raw;
}
+#elif defined (OS_WIN32)
+ if (*decided != raw)
+ {
+ char *date_locale_string = get_locale_string (LOCALE_SSHORTDATE);
+ char *time_locale_string = get_locale_string (LOCALE_STIMEFORMAT);
+ int date_len = strlen (date_locale_string);
+ int time_len = strlen (time_locale_string);
+ char *d_t_fmt = malloc (date_len + time_len + 2);
+ char *posix_d_t_fmt;
+
+ strncpy (d_t_fmt, date_locale_string, date_len);
+ strncat (d_t_fmt, " ", 1);
+ strncat (d_t_fmt, time_locale_string, time_len);
+ free (date_locale_string);
+ free (time_locale_string);
+
+ posix_d_t_fmt = translate_picture (d_t_fmt);
+
+ free (d_t_fmt);
+
+ if (!recursive (posix_d_t_fmt))
+ {
+ if (*decided == loc)
+ {
+ free (posix_d_t_fmt);
+ return NULL;
+ }
+ else
+ {
+ rp = rp_backup;
+ }
+ }
+ else
+ {
+ if (*decided == not &&
+ strcmp (posix_d_t_fmt, HERE_D_T_FMT))
+ *decided = loc;
+ want_xday = 1;
+ free (posix_d_t_fmt);
+ break;
+ }
+ free (posix_d_t_fmt);
+ *decided = raw;
+ }
#endif
if (!recursive (HERE_D_T_FMT))
return NULL;
@@ -457,6 +709,38 @@
}
*decided = raw;
}
+#elif defined (OS_WIN32)
+ if (*decided != raw)
+ {
+ char *locale_string = get_locale_string (LOCALE_SSHORTDATE);
+ char *posix_d_fmt = translate_picture (locale_string);
+
+ free (locale_string);
+
+ if (!recursive (posix_d_fmt))
+ {
+ if (*decided == loc)
+ {
+ free(posix_d_fmt);
+ return NULL;
+ }
+ else
+ {
+ rp = rp_backup;
+ }
+ }
+ else
+ {
+ if (*decided == not
+ && strcmp (posix_d_fmt, HERE_D_FMT))
+ *decided = loc;
+ want_xday = 1;
+ free(posix_d_fmt);
+ break;
+ }
+ free(posix_d_fmt);
+ *decided = raw;
+ }
#endif
/* Fall through. */
case 'D':
@@ -522,6 +806,30 @@
}
*decided = raw;
}
+#elif defined (OS_WIN32)
+ if (*decided != raw)
+ {
+ char *locale_string = get_locale_string (LOCALE_S1159);
+ if (match_string (locale_string, rp))
+ {
+ if (strcmp (locale_string, HERE_AM_STR))
+ *decided = loc;
+ free (locale_string);
+ break;
+ }
+ free (locale_string);
+ locale_string = get_locale_string (LOCALE_S2359);
+ if (match_string (locale_string, rp))
+ {
+ if (strcmp (locale_string, HERE_PM_STR))
+ *decided = loc;
+ is_pm = 1;
+ free (locale_string);
+ break;
+ }
+ *decided = raw;
+ free (locale_string);
+ }
#endif
if (!match_string (HERE_AM_STR, rp))
if (match_string (HERE_PM_STR, rp))
@@ -550,6 +858,45 @@
}
*decided = raw;
}
+#elif defined (OS_WIN32)
+ if (*decided != raw)
+ {
+ char *locale_string = get_locale_string (LOCALE_STIMEFORMAT);
+ int locale_len = strlen (locale_string);
+ char *t_p_fmt = malloc (locale_len + 4);
+ char *posix_t_p_fmt;
+
+ strncpy (t_p_fmt, locale_string, locale_len);
+ strncat (t_p_fmt, " tt", 3);
+
+ posix_t_p_fmt = translate_picture (t_p_fmt);
+
+ free (t_p_fmt);
+
+ if (!recursive (posix_t_p_fmt))
+ {
+ if (*decided == loc)
+ {
+ free (posix_t_p_fmt);
+ return NULL;
+ }
+ else
+ {
+ rp = rp_backup;
+ }
+ }
+ else
+ {
+ if (*decided == not &&
+ strcmp (posix_t_p_fmt,
+ HERE_T_FMT_AMPM))
+ *decided = loc;
+ free (posix_t_p_fmt);
+ break;
+ }
+ free (posix_t_p_fmt);
+ *decided = raw;
+ }
#endif
if (!recursive (HERE_T_FMT_AMPM))
return NULL;
@@ -604,6 +951,29 @@
}
*decided = raw;
}
+#elif defined (OS_WIN32)
+ if (*decided != raw)
+ {
+ char *locale_string = get_locale_string (LOCALE_STIMEFORMAT);
+ if (!recursive (locale_string))
+ {
+ if (*decided == loc)
+ return NULL;
+ else
+ rp = rp_backup;
+ }
+ else
+ {
+ free (locale_string);
+ locale_string = get_locale_string (LOCALE_STIMEFORMAT);
+ if (strcmp (locale_string, HERE_T_FMT))
+ *decided = loc;
+ free (locale_string);
+ break;
+ }
+ free (locale_string);
+ *decided = raw;
+ }
#endif
/* Fall through. */
case 'T':
@@ -984,6 +1354,8 @@
#ifdef _NL_CURRENT
decided = not;
+#elif defined (OS_WIN32)
+ decided = not;
#else
decided = raw;
#endif
More information about the gnucash-changes
mailing list