mirror of
https://github.com/Gnucash/gnucash.git
synced 2026-09-03 20:53:02 -05:00
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. git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@16048 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
@@ -17,6 +17,10 @@ LTLIBOBJS = $(shell echo "$(LIBOBJS)" | sed '@LIBOBJS_SEDSCRIPT@' | \
|
||||
|
||||
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
|
||||
|
||||
@@ -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 @@ strptime_internal (rp, fmt, tm, decided, era_cnt)
|
||||
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 @@ strptime_internal (rp, fmt, tm, decided, era_cnt)
|
||||
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 @@ strptime_internal (rp, fmt, tm, decided, era_cnt)
|
||||
}
|
||||
*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 @@ strptime_internal (rp, fmt, tm, decided, era_cnt)
|
||||
}
|
||||
*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 @@ strptime_internal (rp, fmt, tm, decided, era_cnt)
|
||||
}
|
||||
*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 @@ strptime_internal (rp, fmt, tm, decided, era_cnt)
|
||||
}
|
||||
*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 @@ strptime_internal (rp, fmt, tm, decided, era_cnt)
|
||||
}
|
||||
*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 @@ strptime (buf, format, tm)
|
||||
|
||||
#ifdef _NL_CURRENT
|
||||
decided = not;
|
||||
#elif defined (OS_WIN32)
|
||||
decided = not;
|
||||
#else
|
||||
decided = raw;
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user