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