* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
+
+/*
+ * MT safe
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
#include "glib.h"
#include <time.h>
memset (d, 0x0, ndates*sizeof (GDate));
}
+G_LOCK_DECLARE_STATIC (g_date_global);
+
/* These are for the parser, output to the user should use *
* g_date_strftime () - this creates more never-freed memory to annoy
* all those memory debugger users. :-)
#define NUM_LEN 10
+/* HOLDS: g_date_global_lock */
static void
g_date_fill_parse_tokens (const gchar *str, GDateParseTokens *pt)
{
if (found != NULL)
{
pt->month = i;
- return;
+ return;
}
}
return;
}
}
-
+
++i;
- }
+ }
}
}
+/* HOLDS: g_date_global_lock */
static void
g_date_prepare_to_parse (const gchar *str, GDateParseTokens *pt)
{
/* Determine DMY order */
- g_date_set_dmy (&d, 4, 7, 1776); /* had to pick a random day */
+ /* had to pick a random day - don't change this, some strftimes
+ * are broken on some days, and this one is good so far. */
+ g_date_set_dmy (&d, 4, 7, 1976);
g_date_strftime (buf, 127, "%x", &d);
break;
case 76:
using_twodigit_years = TRUE; /* FALL THRU */
- case 1776:
+ case 1976:
dmy_order[i] = G_DATE_YEAR;
break;
default:
/* set invalid */
g_date_clear (d, 1);
+ G_LOCK (g_date_global);
+
g_date_prepare_to_parse (str, &pt);
#ifdef G_ENABLE_DEBUG
#endif
- if (pt.num_ints == 4) return; /* presumably a typo; bail out. */
+ if (pt.num_ints == 4)
+ {
+ G_UNLOCK (g_date_global);
+ return; /* presumably a typo; bail out. */
+ }
if (pt.num_ints > 1)
{
else
g_message ("Rejected DMY %u %u %u", day, m, y);
#endif
+ G_UNLOCK (g_date_global);
}
void
GTime time)
{
time_t t = time;
- struct tm *tm;
+ struct tm tm;
g_return_if_fail (d != NULL);
- tm = localtime (&t);
+#ifdef HAVE_LOCALTIME_R
+ localtime_r (&t, &tm);
+#else
+# ifdef G_THREADS_ENABLED
+# warning "the `g_date_set_time' function will not be MT-safe"
+# warning "because there is no `localtime_r' on your system."
+# endif
+ {
+ struct tm *ptm = localtime (&t);
+ g_assert (ptm);
+ memcpy ((void *) &tm, (void *) ptm, sizeof(struct tm));
+ }
+#endif
- if (tm)
- {
- d->julian = FALSE;
-
- d->month = tm->tm_mon + 1;
- d->day = tm->tm_mday;
- d->year = tm->tm_year + 1900;
-
- g_return_if_fail (g_date_valid_dmy (d->day, d->month, d->year));
-
- d->dmy = TRUE;
- }
- else
- {
- g_date_clear (d, 1);
- }
+ d->julian = FALSE;
+
+ d->month = tm.tm_mon + 1;
+ d->day = tm.tm_mday;
+ d->year = tm.tm_year + 1900;
+
+ g_return_if_fail (g_date_valid_dmy (d->day, d->month, d->year));
+
+ d->dmy = TRUE;
}
void
{
g_return_if_fail (d != NULL);
g_return_if_fail (g_date_valid_month (m));
-
+
+ if (d->julian && !d->dmy) g_date_update_dmy(d);
d->julian = FALSE;
d->month = m;
g_return_if_fail (d != NULL);
g_return_if_fail (g_date_valid_day (day));
+ if (d->julian && !d->dmy) g_date_update_dmy(d);
d->julian = FALSE;
d->day = day;
g_return_if_fail (d != NULL);
g_return_if_fail (g_date_valid_year (y));
+ if (d->julian && !d->dmy) g_date_update_dmy(d);
d->julian = FALSE;
d->year = y;