[libgda] Added date, time and timestamp parsing tests
- From: Vivien Malerba <vivien src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libgda] Added date, time and timestamp parsing tests
- Date: Thu, 21 Oct 2010 18:23:32 +0000 (UTC)
commit fb8a1153b2c71bcef21e135e71a37e35be469631
Author: Vivien Malerba <malerba gnome-db org>
Date: Thu Oct 21 20:23:01 2010 +0200
Added date, time and timestamp parsing tests
doc/C/libgda-sections.txt | 1 +
libgda/gda-util.c | 300 ++++++++++++---------
libgda/handlers/gda-handler-time.c | 271 +++++++++++--------
libgda/libgda.symbols | 1 +
tests/.gitignore | 1 +
tests/Makefile.am | 11 +-
tests/test-input-parsers.c | 522 ++++++++++++++++++++++++++++++++++++
7 files changed, 865 insertions(+), 242 deletions(-)
---
diff --git a/doc/C/libgda-sections.txt b/doc/C/libgda-sections.txt
index 355e9a1..6ac52dc 100644
--- a/doc/C/libgda-sections.txt
+++ b/doc/C/libgda-sections.txt
@@ -852,6 +852,7 @@ GdaHandlerTimePriv
gda_handler_time_new
gda_handler_time_new_no_locale
gda_handler_time_set_sql_spec
+gda_handler_time_set_str_spec
gda_handler_time_get_format
<SUBSECTION Standard>
GDA_HANDLER_TIME
diff --git a/libgda/gda-util.c b/libgda/gda-util.c
index 941c641..cfa3384 100644
--- a/libgda/gda-util.c
+++ b/libgda/gda-util.c
@@ -27,6 +27,7 @@
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
+#include <ctype.h>
#include <string.h>
#include <glib/gi18n-lib.h>
#include <libgda/gda-log.h>
@@ -2516,37 +2517,48 @@ gda_connection_string_split (const gchar *string, gchar **out_cnc_params, gchar
gda_rfc1738_decode (*out_password);
}
-/**
- * gda_parse_iso8601_date
- * @gdate: a pointer to a #GDate structure which will be filled
- * @value: a string
- *
- * Extracts date parts from @value, and sets @gdate's contents
- *
- * Accepted date format is "YYYY-MM-DD".
- *
- * Returns: TRUE if no error occurred
- */
-gboolean
-gda_parse_iso8601_date (GDate *gdate, const gchar *value)
+static gboolean
+_parse_iso8601_date (GDate *gdate, const gchar *value, char **out_endptr)
{
GDateYear year;
GDateMonth month;
GDateDay day;
- gint tmp;
+ unsigned long int tmp;
+ char *endptr;
+
+ g_date_clear (gdate, 1);
- tmp = atoi (value); /* Flawfinder: ignore */
- year = tmp > 0 ? tmp : 0;
- value += 5;
- tmp = atoi (value); /* Flawfinder: ignore */
+ if (! isdigit (*value))
+ return FALSE;
+ tmp = strtoul (value, &endptr, 10);
+ if (tmp <= G_MAXUINT16)
+ year = tmp;
+ else
+ return FALSE;
+ if (*endptr != '-')
+ return FALSE;
+
+ value = endptr + 1;
+ if (! isdigit (*value))
+ return FALSE;
+ tmp = strtoul (value, &endptr, 10);
month = tmp > 0 ? (tmp <= G_DATE_DECEMBER ? tmp : G_DATE_BAD_MONTH) : G_DATE_BAD_MONTH;
- value += 3;
- tmp = atoi (value); /* Flawfinder: ignore */
+ if (month == G_DATE_BAD_MONTH)
+ return FALSE;
+ if (*endptr != '-')
+ return FALSE;
+
+ value = endptr + 1;
+ if (! isdigit (*value))
+ return FALSE;
+ tmp = strtoul (value, &endptr, 10);
day = tmp > 0 ? (tmp <= G_MAXUINT8 ? tmp : G_DATE_BAD_DAY) : G_DATE_BAD_DAY;
-
- g_date_clear (gdate, 1);
+ if (day == G_DATE_BAD_DAY)
+ return FALSE;
+
if (g_date_valid_dmy (day, month, year)) {
g_date_set_dmy (gdate, day, month, year);
+ *out_endptr = endptr;
return TRUE;
}
else {
@@ -2556,69 +2568,126 @@ gda_parse_iso8601_date (GDate *gdate, const gchar *value)
}
/**
- * gda_parse_iso8601_time
- * @timegda: a pointer to a #GdaTime structure which will be filled
+ * gda_parse_iso8601_date
+ * @gdate: a pointer to a #GDate structure which will be filled
* @value: a string
*
- * Extracts time parts from @value, and sets @timegda's contents
+ * Extracts date parts from @value, and sets @gdate's contents
*
- * Accepted date format is "HH:MM:SS[.ms][TZ]" where TZ is +hour or -hour
+ * Accepted date format is "YYYY-MM-DD" (more or less than 4 digits for years and
+ * less than 2 digits for month and day are accepted). Years must be in the 1-65535 range,
+ * a limitation imposed by #GDate.
*
- * Returns: TRUE if no error occurred
+ * Returns: %TRUE if no error occurred
*/
gboolean
-gda_parse_iso8601_time (GdaTime *timegda, const gchar *value)
+gda_parse_iso8601_date (GDate *gdate, const gchar *value)
+{
+ g_return_val_if_fail (gdate, FALSE);
+
+ char *endptr;
+ if (!value)
+ return FALSE;
+
+ if (! _parse_iso8601_date (gdate, value, &endptr))
+ return FALSE;
+ if (*endptr)
+ return FALSE;
+ return TRUE;
+}
+
+static gboolean
+_parse_iso8601_time (GdaTime *timegda, const gchar *value, char **out_endptr)
{
- gint tmp;
+ unsigned long int tmp;
+ char *endptr;
memset (timegda, 0, sizeof (GdaTime));
+ timegda->timezone = GDA_TIMEZONE_INVALID;
- tmp = atoi (value); /* Flawfinder: ignore */
- if ((tmp < 0) || (tmp > 24))
+ if (! isdigit (*value))
return FALSE;
- timegda->hour = tmp;
- value += 3;
- tmp = atoi (value); /* Flawfinder: ignore */
- if ((tmp < 0) || (tmp > 60))
+ tmp = strtoul (value, &endptr, 10);
+ if (tmp <= 23)
+ timegda->hour = tmp;
+ else
return FALSE;
- timegda->minute = tmp;
- value += 3;
- tmp = atoi (value); /* Flawfinder: ignore */
- if ((tmp < 0) || (tmp > 60))
+ if (*endptr != ':')
+ return FALSE;
+
+ value = endptr + 1;
+ if (! isdigit (*value))
+ return FALSE;
+ tmp = strtoul (value, &endptr, 10);
+ if (tmp < 60)
+ timegda->minute = tmp;
+ else
+ return FALSE;
+ if (*endptr != ':')
return FALSE;
- timegda->second = tmp;
- value += 2;
- if (*value != '.') {
- timegda->fraction = 0;
- } else {
- gint ndigits = 0;
- gint64 fraction;
-
- value++;
- fraction = atol (value); /* Flawfinder: ignore */
- if (fraction < 0)
- return FALSE;
- while (*value && (*value != '+') && (*value != '-')) {
- value++;
- ndigits++;
- }
+ value = endptr + 1;
+ if (! isdigit (*value))
+ return FALSE;
+ tmp = strtoul (value, &endptr, 10);
+ if (tmp < 60)
+ timegda->second = tmp;
+ else
+ return FALSE;
- while (fraction > 0 && ndigits > 3) {
- fraction /= 10;
- ndigits--;
- }
-
- timegda->fraction = fraction;
+ if (*endptr && (*endptr != '.') && (*endptr != '+') && (*endptr != '-')) {
+ *out_endptr = endptr;
+ return TRUE; /* end of the parsing */
}
- if (*value) {
- tmp = atol (value); /* Flawfinder: ignore */
- if ((tmp < 0) || (tmp >= 24))
+ if (*endptr == '.') {
+ value = endptr + 1;
+ if (! isdigit (*value))
+ return FALSE;
+ tmp = strtoul (value, &endptr, 10);
+ if (tmp < G_MAXULONG)
+ timegda->fraction = tmp;
+ else
return FALSE;
- timegda->timezone = tmp * 60 * 60;
}
+ if ((*endptr == '+') || (*endptr == '-')) {
+ long int stmp;
+ value = endptr;
+ stmp = strtol (value, &endptr, 10);
+ if ((stmp >= -24) && (stmp <= 24))
+ timegda->timezone = stmp * 60 * 60;
+ else
+ return FALSE;
+ }
+
+ *out_endptr = endptr;
+ return TRUE;
+}
+
+/**
+ * gda_parse_iso8601_time
+ * @timegda: a pointer to a #GdaTime structure which will be filled
+ * @value: a string
+ *
+ * Extracts time parts from @value, and sets @timegda's contents
+ *
+ * Accepted date format is "HH:MM:SS[.ms][TZ]" where TZ is +hour or -hour
+ *
+ * Returns: TRUE if no error occurred
+ */
+gboolean
+gda_parse_iso8601_time (GdaTime *timegda, const gchar *value)
+{
+ g_return_val_if_fail (timegda, FALSE);
+
+ char *endptr;
+ if (!value)
+ return FALSE;
+ if (! _parse_iso8601_time (timegda, value, &endptr))
+ return FALSE;
+ if (*endptr)
+ return FALSE;
return TRUE;
}
@@ -2636,78 +2705,51 @@ gda_parse_iso8601_time (GdaTime *timegda, const gchar *value)
gboolean
gda_parse_iso8601_timestamp (GdaTimestamp *timestamp, const gchar *value)
{
- GDateYear year;
- GDateMonth month;
- GDateDay day;
- gint tmp;
+ g_return_val_if_fail (timestamp, FALSE);
+
+ gboolean retval = TRUE;
+ char *endptr;
+ GDate gdate;
+ GdaTime timegda;
memset (timestamp, 0, sizeof (GdaTimestamp));
+ memset (&timegda, 0, sizeof (GdaTime));
+ timegda.timezone = GDA_TIMEZONE_INVALID;
- /* date part */
- tmp = atoi (value); /* Flawfinder: ignore */
- year = tmp > 0 ? tmp : 0;
- value += 5;
- tmp = atoi (value); /* Flawfinder: ignore */
- month = tmp > 0 ? (tmp <= G_DATE_DECEMBER ? tmp : G_DATE_BAD_MONTH) : G_DATE_BAD_MONTH;
- value += 3;
- tmp = atoi (value); /* Flawfinder: ignore */
- day = tmp > 0 ? (tmp <= G_MAXUINT8 ? tmp : G_DATE_BAD_DAY) : G_DATE_BAD_DAY;
- value += 3;
-
- if (g_date_valid_dmy (day, month, year)) {
- timestamp->year = year;
- timestamp->month = month;
- timestamp->day = day;
- }
- else
+ if (!value)
return FALSE;
- /* time part */
- tmp = atoi (value); /* Flawfinder: ignore */
- if ((tmp < 0) || (tmp > 24))
- return FALSE;
- timestamp->hour = tmp;
- value += 3;
- tmp = atoi (value); /* Flawfinder: ignore */
- if ((tmp < 0) || (tmp > 60))
- return FALSE;
- timestamp->minute = tmp;
- value += 3;
- tmp = atoi (value); /* Flawfinder: ignore */
- if ((tmp < 0) || (tmp > 60))
- return FALSE;
- timestamp->second = tmp;
- value += 2;
- if (*value != '.') {
- timestamp->fraction = 0;
- } else {
- gint ndigits = 0;
- gint64 fraction;
-
- value++;
- fraction = atol (value); /* Flawfinder: ignore */
- if (fraction < 0)
- return FALSE;
+ /* date part */
+ if (! _parse_iso8601_date (&gdate, value, &endptr)) {
+ retval = FALSE;
+ goto out;
+ }
+ timestamp->year = g_date_get_year (&gdate);
+ timestamp->month = g_date_get_month (&gdate);
+ timestamp->day = g_date_get_day (&gdate);
- while (*value && (*value != '+') && (*value != '-')) {
- value++;
- ndigits++;
- }
+ /* separator */
+ if (!*endptr)
+ goto out;
- while (fraction > 0 && ndigits > 3) {
- fraction /= 10;
- ndigits--;
- }
-
- timestamp->fraction = fraction;
+ if (*endptr != ' ') {
+ retval = FALSE;
+ goto out;
}
+ value = endptr + 1;
+ if (!*value)
+ goto out;
- if (*value) {
- tmp = atol (value); /* Flawfinder: ignore */
- if ((tmp < 0) || (tmp >= 24))
- return FALSE;
- timestamp->timezone = tmp * 60 * 60;
- }
+ /* time part */
+ if (! _parse_iso8601_time (&timegda, value, &endptr) ||
+ *endptr)
+ retval = FALSE;
+ out:
+ timestamp->hour = timegda.hour;
+ timestamp->minute = timegda.minute;
+ timestamp->second = timegda.second;
+ timestamp->fraction = timegda.fraction;
+ timestamp->timezone = timegda.timezone;
- return TRUE;
+ return retval;
}
diff --git a/libgda/handlers/gda-handler-time.c b/libgda/handlers/gda-handler-time.c
index 6f2286d..39e54af 100644
--- a/libgda/handlers/gda-handler-time.c
+++ b/libgda/handlers/gda-handler-time.c
@@ -20,6 +20,7 @@
#include "gda-handler-time.h"
#include <string.h>
+#include <ctype.h>
#include <glib/gi18n-lib.h>
static void gda_handler_time_class_init (GdaHandlerTimeClass *class);
@@ -263,6 +264,41 @@ gda_handler_time_set_sql_spec (GdaHandlerTime *dh, GDateDMY first, GDateDMY sec
dh->priv->sql_locale->separator = separator;
}
+/**
+ * gda_handler_time_set_str_spec
+ * @dh: a #GdaHandlerTime object
+ * @first: what comes first in the date representation
+ * @sec: what comes second in the date representation
+ * @third: what comes third in the date representation
+ * @separator: separator character used between year, month and day
+ * @twodigits_years: TRUE if year part of date must be rendered on 2 digits
+ *
+ * Specifies the human readable output style of the @dh data handler.
+ * The general format is "FIRSTsSECsTHIRD"
+ * where FIRST, SEC and THIRD are specified by @first, @sec and @trird and 's' is the separator,
+ * specified by @separator.
+ *
+ * The default implementation depends on the current locale, except if @dh was created
+ * using gda_handler_time_new_no_locale().
+ *
+ * Since: 4.2.1
+ */
+void
+gda_handler_time_set_str_spec (GdaHandlerTime *dh, GDateDMY first, GDateDMY sec,
+ GDateDMY third, gchar separator, gboolean twodigits_years)
+{
+ g_return_if_fail (GDA_IS_HANDLER_TIME (dh));
+ g_return_if_fail (dh->priv);
+ g_return_if_fail (first != sec);
+ g_return_if_fail (sec != third);
+ g_return_if_fail (first != third);
+
+ dh->priv->str_locale->dmy_order[0] = first;
+ dh->priv->str_locale->dmy_order[1] = sec;
+ dh->priv->str_locale->dmy_order[2] = third;
+ dh->priv->str_locale->twodigit_years = twodigits_years;
+ dh->priv->str_locale->separator = separator;
+}
static void
handler_compute_locale (GdaHandlerTime *hdl)
@@ -744,7 +780,8 @@ gda_handler_time_get_value_from_str (GdaDataHandler *iface, const gchar *sql, GT
static gboolean make_timestamp (GdaHandlerTime *hdl, GdaTimestamp *timestamp,
const gchar *value, LocaleSetting *locale);
-static gboolean make_date (GdaHandlerTime *hdl, GDate *date, const gchar *value, LocaleSetting *locale);
+static gboolean make_date (GdaHandlerTime *hdl, GDate *date, const gchar *value,
+ LocaleSetting *locale, const gchar **out_endptr);
static gboolean make_time (GdaHandlerTime *hdl, GdaTime *timegda, const gchar *value);
static GValue *
gda_handler_time_get_value_from_locale (GdaDataHandler *iface, const gchar *sql,
@@ -762,7 +799,7 @@ gda_handler_time_get_value_from_locale (GdaDataHandler *iface, const gchar *sql,
g_return_val_if_fail (hdl->priv, NULL);
if (type == G_TYPE_DATE) {
- if (make_date (hdl, &date, sql, locale)) {
+ if (make_date (hdl, &date, sql, locale, NULL)) {
value = g_value_init (g_new0 (GValue, 1), G_TYPE_DATE);
g_value_set_boxed (value, (gconstpointer) &date);
}
@@ -793,30 +830,29 @@ static gboolean
make_timestamp (GdaHandlerTime *hdl, GdaTimestamp *timestamp, const gchar *value, LocaleSetting *locale)
{
gboolean retval;
- gchar *str, *ptr;
+ const gchar *end_ptr;
GDate vdate;
GdaTime vtime;
- char *buff;
+ memset (&vtime, 0, sizeof (GdaTime));
+ vtime.timezone = GDA_TIMEZONE_INVALID;
+
+ retval = make_date (hdl, &vdate, value, locale, &end_ptr);
+ timestamp->day = vdate.day;
+ timestamp->month = vdate.month;
+ timestamp->year = vdate.year;
- str = g_strdup (value);
- ptr = strtok_r (str, " ", &buff);
- retval = make_date (hdl, &vdate, ptr, locale);
if (retval) {
- ptr = strtok_r (NULL, " ", &buff);
- retval = make_time (hdl, &vtime, ptr);
- if (retval) {
- timestamp->day = vdate.day;
- timestamp->month = vdate.month;
- timestamp->year = vdate.year;
-
- timestamp->hour = vtime.hour;
- timestamp->minute = vtime.minute;
- timestamp->second = vtime.second;
- timestamp->fraction = vtime.fraction;
- timestamp->timezone = vtime.timezone;
- }
+ if (*end_ptr != ' ')
+ retval = FALSE;
+ else
+ retval = make_time (hdl, &vtime, end_ptr + 1);
}
- g_free (str);
+
+ timestamp->hour = vtime.hour;
+ timestamp->minute = vtime.minute;
+ timestamp->second = vtime.second;
+ timestamp->fraction = vtime.fraction;
+ timestamp->timezone = vtime.timezone;
/*g_print ("Value #%s# => %d\n", value, retval);*/
@@ -829,7 +865,7 @@ get_uint_from_string (const gchar *str, guint16 *out_int)
long int li;
char *endptr = NULL;
li = strtol (str, &endptr, 10);
- if (!*endptr && (li >= 0) && (li < G_MAXUINT16)) {
+ if (!*endptr && (li >= 0) && (li <= G_MAXUINT16)) {
*out_int = (guint16) li;
return TRUE;
}
@@ -839,9 +875,14 @@ get_uint_from_string (const gchar *str, guint16 *out_int)
}
}
-/* Makes a GDate from a string like "24-12-2003" */
+/* Makes a GDate from a string like "24-12-2003"
+ * If @out_endptr is %NULL, then all the @value has to be consumed and there must not
+ * be any character left. If it's not %NULL, then it will point on the first unused character
+ * of @value.
+ */
static gboolean
-make_date (G_GNUC_UNUSED GdaHandlerTime *hdl, GDate *date, const gchar *value, LocaleSetting *locale)
+make_date (G_GNUC_UNUSED GdaHandlerTime *hdl, GDate *date, const gchar *value,
+ LocaleSetting *locale, const gchar **out_endptr)
{
gboolean retval = TRUE;
guint16 nums[3];
@@ -849,6 +890,9 @@ make_date (G_GNUC_UNUSED GdaHandlerTime *hdl, GDate *date, const gchar *value, L
gchar *ptr, *numstart, *tofree;
gint i;
+ if (out_endptr)
+ *out_endptr = NULL;
+
if (!value)
return FALSE;
@@ -871,40 +915,51 @@ make_date (G_GNUC_UNUSED GdaHandlerTime *hdl, GDate *date, const gchar *value, L
/* 2nd number */
if (!error) {
- ptr++;
- numstart = ptr;
- while (*ptr && g_ascii_isdigit (*ptr))
+ if (value [ptr-tofree] != locale->separator)
+ error = TRUE;
+ else {
ptr++;
- if ((ptr != numstart) && *ptr) {
- *ptr = 0;
- if (! get_uint_from_string (numstart, &(nums[1])))
+ numstart = ptr;
+ while (*ptr && g_ascii_isdigit (*ptr))
+ ptr++;
+ if ((ptr != numstart) && *ptr) {
+ *ptr = 0;
+ if (! get_uint_from_string (numstart, &(nums[1])))
+ error = TRUE;
+ }
+ else
error = TRUE;
}
- else
- error = TRUE;
}
/* 3rd number */
if (!error) {
- ptr++;
- numstart = ptr;
- while (*ptr && g_ascii_isdigit (*ptr))
+ if (value [ptr-tofree] != locale->separator)
+ error = TRUE;
+ else {
ptr++;
- *ptr = 0;
- if (ptr != numstart) {
- if (! get_uint_from_string (numstart, &(nums[2])))
+ numstart = ptr;
+ while (*ptr && g_ascii_isdigit (*ptr))
+ ptr++;
+ *ptr = 0;
+ if (ptr != numstart) {
+ if (! get_uint_from_string (numstart, &(nums[2])))
+ error = TRUE;
+ }
+ else
error = TRUE;
}
- else
- error = TRUE;
}
+ /* test if there are some characters left */
if (!error) {
- ptr++;
- if (*ptr)
+ if (out_endptr)
+ *out_endptr = value + (ptr-tofree);
+ else if (value [ptr-tofree])
error = TRUE;
}
+ /* analyse what's parsed */
if (!error) {
for (i=0; i<3; i++) {
switch (locale->dmy_order[i]) {
@@ -957,101 +1012,95 @@ make_time (G_GNUC_UNUSED GdaHandlerTime *hdl, GdaTime *timegda, const gchar *val
{
const gchar *ptr;
+ memset (timegda, 0, sizeof (GdaTime));
+ timegda->timezone = GDA_TIMEZONE_INVALID;
+
if (!value)
return FALSE;
/* hour */
- timegda->fraction = 0;
- timegda->timezone = GDA_TIMEZONE_INVALID;
ptr = value;
- if ((*ptr >= '0') && (*ptr <= '9') &&
- (*(ptr+1) >= '0') && (*(ptr+1) <= '9')) {
- timegda->hour = (*ptr - '0') * 10 + *(ptr+1) - '0';
- ptr += 2;
- }
- else if ((*ptr >= '0') && (*ptr <= '9') && (ptr[1] == ':')) {
- timegda->hour = *ptr - '0';
+ if (!isdigit (*ptr))
+ return FALSE;
+
+ timegda->hour = *ptr - '0';
+ ptr++;
+ if (isdigit (*ptr)) {
+ timegda->hour = timegda->hour * 10 + (*ptr - '0');
ptr++;
}
- else if (*ptr == ':')
- timegda->hour = 0;
- else
+ if (timegda->hour >= 24)
return FALSE;
- /* minute */
- if (! *ptr)
- return FALSE;
if (*ptr == ':')
ptr++;
- if ((*ptr >= '0') && (*ptr <= '9') &&
- (*(ptr+1) >= '0') && (*(ptr+1) <= '9')) {
- timegda->minute = (*ptr - '0') * 10 + *(ptr+1) - '0';
- ptr += 2;
- }
- else if ((*ptr >= '0') && (*ptr <= '9') && (ptr[1] == ':')) {
- timegda->minute = *ptr - '0';
- ptr++;
- }
- else if (*ptr == ':')
- timegda->minute = 0;
- else
+ else if (!isdigit (*ptr))
return FALSE;
- /* second */
- timegda->second = 0;
- if (! *ptr) {
- if ((timegda->hour > 24) || (timegda->minute > 60))
- return FALSE;
- else
- return TRUE;
+ /* minute */
+ timegda->minute = *ptr - '0';
+ ptr++;
+ if (isdigit (*ptr)) {
+ timegda->minute = timegda->minute * 10 + (*ptr - '0');
+ ptr++;
}
+ if (timegda->minute >= 60)
+ return FALSE;
if (*ptr == ':')
ptr++;
- if ((*ptr >= '0') && (*ptr <= '9') &&
- (*(ptr+1) >= '0') && (*(ptr+1) <= '9')) {
- timegda->second = (*ptr - '0') * 10 + *(ptr+1) - '0';
- ptr += 2;
- }
- else if ((*ptr >= '0') && (*ptr <= '9')) {
- timegda->second = *ptr - '0';
+ else if (!isdigit (*ptr))
+ return FALSE;
+
+ /* second */
+ timegda->second = *ptr - '0';
+ ptr++;
+ if (isdigit (*ptr)) {
+ timegda->second = timegda->second * 10 + (*ptr - '0');
ptr++;
}
- else if (*ptr == ':')
- timegda->second = 0;
-
- /* extra */
- if (! *ptr) {
- if ((timegda->hour > 24) || (timegda->minute > 60) ||
- (timegda->second > 60))
- return FALSE;
- else
- return TRUE;
- }
+ if (timegda->second >= 60)
+ return FALSE;
+ /* fraction */
+ if (*ptr && (*ptr != '.') && (*ptr != '+') && (*ptr != '-'))
+ return FALSE;
if (*ptr == '.') {
- ptr ++;
- while (*ptr && (*ptr >= '0') && (*ptr <= '9')) {
- timegda->fraction = timegda->fraction * 10 + *ptr - '0';
+ ptr++;
+ if (!isdigit (*ptr))
+ return FALSE;
+ while (isdigit (*ptr)) {
+ unsigned long long lu;
+ lu = timegda->fraction * 10 + (*ptr - '0');
+ if (lu < G_MAXULONG)
+ timegda->fraction = lu;
+ else
+ return FALSE;
ptr++;
}
}
-
- if ((*ptr == '+') || (*ptr == '-')) {
- glong sign = (*ptr == '+') ? 1 : -1;
- ptr ++;
- timegda->timezone = 0;
- while (*ptr && (*ptr >= '0') && (*ptr <= '9')) {
- timegda->timezone = timegda->timezone * 10 + sign * ((*ptr) - '0');
+
+ /* timezone */
+ if ((*ptr == '-') || (*ptr == '+')) {
+ gint sign = (*ptr == '+') ? 1 : -1;
+ ptr++;
+ if (!isdigit (*ptr))
+ return FALSE;
+ timegda->timezone = sign * (*ptr - '0');
+ ptr++;
+ if (isdigit (*ptr)) {
+ timegda->timezone = timegda->minute * 10 + sign * (*ptr - '0');
ptr++;
}
- timegda->timezone *= 3600;
+ if (*ptr)
+ return FALSE;
+ if ((timegda->timezone >= -24) && (timegda->timezone <= 24))
+ timegda->timezone *= 60*60;
+ else {
+ timegda->timezone = 0;
+ return FALSE;
+ }
}
-
- /* checks */
- if ((timegda->hour > 24) || (timegda->minute > 60) || (timegda->second > 60))
- return FALSE;
- else
- return TRUE;
+ return TRUE;
}
diff --git a/libgda/libgda.symbols b/libgda/libgda.symbols
index 357cfcb..6e749fb 100644
--- a/libgda/libgda.symbols
+++ b/libgda/libgda.symbols
@@ -353,6 +353,7 @@
gda_handler_time_new
gda_handler_time_new_no_locale
gda_handler_time_set_sql_spec
+ gda_handler_time_set_str_spec
gda_handler_type_get_type
gda_handler_type_new
gda_holder_attributes_manager
diff --git a/tests/.gitignore b/tests/.gitignore
index 746b555..a56365c 100644
--- a/tests/.gitignore
+++ b/tests/.gitignore
@@ -4,3 +4,4 @@ test-sql-identifier
test-identifiers-quotes
test-sql-builder
test-connection-string-split
+test-input-parsers
diff --git a/tests/Makefile.am b/tests/Makefile.am
index d0aeb48..1ba8ee4 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -1,6 +1,6 @@
noinst_LTLIBRARIES = libgda-test-4.0.la
-TESTS = test-ddl-creator test-bin-converter test-sql-identifier test-identifiers-quotes test-sql-builder test-connection-string-split
-check_PROGRAMS = test-ddl-creator test-bin-converter test-sql-identifier test-identifiers-quotes test-sql-builder test-connection-string-split
+TESTS = test-ddl-creator test-bin-converter test-sql-identifier test-identifiers-quotes test-sql-builder test-connection-string-split test-input-parsers
+check_PROGRAMS = test-ddl-creator test-bin-converter test-sql-identifier test-identifiers-quotes test-sql-builder test-connection-string-split test-input-parsers
SUBDIRS = providers parser value-holders meta-store data-models multi-threading
@@ -75,4 +75,11 @@ test_connection_string_split_LDADD = \
$(top_builddir)/libgda/libgda-4.0.la \
$(LIBGDA_LIBS)
+test_input_parsers_SOURCES = \
+ test-input-parsers.c
+
+test_input_parsers_LDADD = \
+ $(top_builddir)/libgda/libgda-4.0.la \
+ $(LIBGDA_LIBS)
+
EXTRA_DIST = dbstruct.xml
\ No newline at end of file
diff --git a/tests/test-input-parsers.c b/tests/test-input-parsers.c
new file mode 100644
index 0000000..cd26a5a
--- /dev/null
+++ b/tests/test-input-parsers.c
@@ -0,0 +1,522 @@
+/*
+ * Copyright (C) 2010 The GNOME Foundation.
+ *
+ * AUTHORS:
+ * Vivien Malerba <malerba gnome-db org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <libgda/libgda.h>
+static gboolean test_parse_iso8601_date (void);
+static gboolean test_parse_iso8601_time (void);
+static gboolean test_parse_iso8601_timestamp (void);
+static gboolean test_date_handler (void);
+static gboolean test_time_handler (void);
+static gboolean test_timestamp_handler (void);
+
+int
+main (int argc, char** argv)
+{
+ gint nfailed = 0;
+
+ if (! test_parse_iso8601_date ())
+ nfailed++;
+ if (! test_parse_iso8601_time ())
+ nfailed++;
+ if (! test_parse_iso8601_timestamp ())
+ nfailed++;
+
+ gda_init ();
+ if (! test_date_handler ())
+ nfailed++;
+ if (! test_time_handler ())
+ nfailed++;
+ if (! test_timestamp_handler ())
+ nfailed++;
+
+ if (nfailed > 0) {
+ g_print ("FAILED: %d tests failed\n", nfailed);
+ return EXIT_FAILURE;
+ }
+ else {
+ g_print ("All tests passed\n");
+ return EXIT_SUCCESS;
+ }
+}
+
+typedef struct {
+ gchar *in_string;
+ gboolean exp_retval;
+ gint exp_day;
+ gint exp_month;
+ gint exp_year;
+} TestDate;
+
+TestDate datedata[] = {
+ {"1996-11-22", TRUE, 22, 11, 1996},
+ {"1996-22-23", FALSE, 0, 0, 0},
+ {"96-7-23", TRUE, 23, 7, 96},
+ {"2050-12-31", TRUE, 31, 12, 2050},
+ {"2050-11-31", FALSE, 0, 0, 0},
+ {"1996-02-29", TRUE, 29, 2, 1996},
+ {"1997-02-29", FALSE, 0, 0, 0},
+ {"1900-5-22", TRUE, 22, 5, 1900},
+ {"1900.05-22", FALSE, 0, 0, 0},
+ {"1900-05.22", FALSE, 0, 0, 0},
+ {"1900-05-22 ", FALSE, 0, 0, 0},
+ {" 1900-05-22", FALSE, 0, 0, 0},
+ {"1900 -05-22", FALSE, 0, 0, 0},
+ {"1900- 05-22", FALSE, 0, 0, 0},
+ {"1900-05 -22", FALSE, 0, 0, 0},
+ {"1900-05- 22", FALSE, 0, 0, 0},
+ {"65535-05-22", TRUE, 22, 5, 65535},
+ {"1-05-22", TRUE, 22, 5, 1},
+ {"65536-05-22", FALSE, 0, 0, 0},
+};
+
+static gboolean
+test_parse_iso8601_date (void)
+{
+ gint i;
+
+ for (i = 0; i < sizeof (datedata) / sizeof (TestDate); i++) {
+ TestDate td = datedata[i];
+ GDate date;
+ /*g_print ("[%s]\n", td.in_string);*/
+ if (gda_parse_iso8601_date (&date, td.in_string) != td.exp_retval) {
+ g_print ("Wrong result for gda_parse_iso8601_date (\"%s\"): got %s\n",
+ td.in_string, td.exp_retval ? "FALSE" : "TRUE");
+ return FALSE;
+ }
+ if (td.exp_retval &&
+ ((g_date_get_day (&date) != td.exp_day) ||
+ (g_date_get_month (&date) != td.exp_month) ||
+ (g_date_get_year (&date) != td.exp_year))) {
+ g_print ("Wrong result for gda_parse_iso8601_date (\"%s\"):\n"
+ " exp: DD=%d MM=%d YYYY=%d\n"
+ " got: DD=%d MM=%d YYYY=%d\n",
+ td.in_string, td.exp_day, td.exp_month, td.exp_year,
+ g_date_get_day (&date), g_date_get_month (&date),
+ g_date_get_year (&date));
+ return FALSE;
+ }
+ }
+ g_print ("All %d iso8601 date parsing tests passed\n", i);
+
+ return TRUE;
+}
+
+typedef struct {
+ gchar *in_string;
+ gboolean exp_retval;
+ GdaTime exp_time;
+} TestTime;
+
+TestTime timedata[] = {
+ {"11:22:56", TRUE, {11, 22, 56, 0, GDA_TIMEZONE_INVALID}},
+ {"1:22:56", TRUE, {1, 22, 56, 0, GDA_TIMEZONE_INVALID}},
+ {"1:22:60", FALSE, {1, 22, 0, 0, GDA_TIMEZONE_INVALID}},
+ {"1:60:45", FALSE, {1, 0, 0, 0, GDA_TIMEZONE_INVALID}},
+ {"24:23:45", FALSE, {0, 0, 0, 0, GDA_TIMEZONE_INVALID}},
+ {"23:59:59", TRUE, {23, 59, 59, 0, GDA_TIMEZONE_INVALID}},
+ {"0:0:00", TRUE, {0, 0, 0, 0, GDA_TIMEZONE_INVALID}},
+ {"12:1:0", TRUE, {12, 1, 0, 0, GDA_TIMEZONE_INVALID}},
+ {" 12:00:00", FALSE, {0, 0, 0, 0, GDA_TIMEZONE_INVALID}},
+ {"12 :00:00", FALSE, {12, 0, 0, 0, GDA_TIMEZONE_INVALID}},
+ {"12: 00:00", FALSE, {12, 0, 0, 0, GDA_TIMEZONE_INVALID}},
+ {"12: 00:00", FALSE, {12, 0, 0, 0, GDA_TIMEZONE_INVALID}},
+ {"12:1 :00", FALSE, {12, 1, 0, 0, GDA_TIMEZONE_INVALID}},
+ {"12:1:2 ", FALSE, {12, 1, 2, 0, GDA_TIMEZONE_INVALID}},
+ {"12:1:2.", FALSE, {12, 1, 2, 0, GDA_TIMEZONE_INVALID}},
+ {"12:1:2:", FALSE, {12, 1, 2, 0, GDA_TIMEZONE_INVALID}},
+ {"12:1:2.123", TRUE, {12, 1, 2, 123, GDA_TIMEZONE_INVALID}},
+ {"12:1:2-2", TRUE, {12, 1, 2, 0, -2*60*60}},
+ {"12:1:2+11", TRUE, {12, 1, 2, 0, 11*60*60}},
+ {"12:1:2.1234+11", TRUE, {12, 1, 2, 1234, 11*60*60}},
+ {"12:1:2.12345678-3", TRUE, {12, 1, 2, 12345678, -3*60*60}},
+};
+
+static gboolean
+test_parse_iso8601_time (void)
+{
+ gint i;
+
+ for (i = 0; i < sizeof (timedata) / sizeof (TestTime); i++) {
+ TestTime td = timedata[i];
+ GdaTime time;
+ /*g_print ("[%s]\n", td.in_string);*/
+ if (gda_parse_iso8601_time (&time, td.in_string) != td.exp_retval) {
+ g_print ("Wrong result for gda_parse_iso8601_time (\"%s\"): got %s\n",
+ td.in_string, td.exp_retval ? "FALSE" : "TRUE");
+ return FALSE;
+ }
+ if ((time.hour != td.exp_time.hour) ||
+ (time.minute != td.exp_time.minute) ||
+ (time.second != td.exp_time.second) ||
+ (time.fraction != td.exp_time.fraction) ||
+ (time.timezone != td.exp_time.timezone)) {
+ g_print ("Wrong result for gda_parse_iso8601_time (\"%s\"):\n"
+ " exp: HH=%d MM=%d SS=%d FF=%ld TZ=%ld\n"
+ " got: HH=%d MM=%d SS=%d FF=%ld TZ=%ld\n",
+ td.in_string,
+ td.exp_time.hour, td.exp_time.minute, td.exp_time.second,
+ td.exp_time.fraction, td.exp_time.timezone,
+ time.hour, time.minute, time.second,
+ time.fraction, time.timezone);
+ return FALSE;
+ }
+ }
+ g_print ("All %d iso8601 time parsing tests passed\n", i);
+
+ return TRUE;
+}
+
+static gboolean
+test_parse_iso8601_timestamp (void)
+{
+ gint idate, itime;
+
+ for (idate = 0; idate < sizeof (datedata) / sizeof (TestTime); idate++) {
+ TestDate td = datedata [idate];
+ for (itime = 0; itime < sizeof (timedata) / sizeof (TestTime); itime++) {
+ TestTime tt = timedata[itime];
+ gchar *str;
+ str = g_strdup_printf ("%s %s", td.in_string, tt.in_string);
+
+ GdaTimestamp timestamp;
+ gboolean exp_result = td.exp_retval && tt.exp_retval;
+ /*g_print ("[%s]\n", str);*/
+ if (gda_parse_iso8601_timestamp (×tamp, str) != exp_result) {
+ g_print ("Wrong result for gda_parse_iso8601_timestamp (\"%s\"): got %s\n",
+ td.in_string, exp_result ? "FALSE" : "TRUE");
+ return FALSE;
+ }
+
+ if ((td.exp_retval &&
+ ((timestamp.year != td.exp_year) ||
+ (timestamp.month != td.exp_month) ||
+ (timestamp.day != td.exp_day))) &&
+ (((timestamp.hour != tt.exp_time.hour) ||
+ (timestamp.minute != tt.exp_time.minute) ||
+ (timestamp.second != tt.exp_time.second) ||
+ (timestamp.fraction != tt.exp_time.fraction) ||
+ (timestamp.timezone != tt.exp_time.timezone)))) {
+ g_print ("Wrong result for gda_parse_iso8601_timestamp (\"%s\"):\n"
+ " exp: DD=%d MM=%d YYYY=%d HH=%d MM=%d SS=%d FF=%ld TZ=%ld\n"
+ " got: DD=%d MM=%d YYYY=%d HH=%d MM=%d SS=%d FF=%ld TZ=%ld\n",
+ str, td.exp_day, td.exp_month, td.exp_year,
+ tt.exp_time.hour, tt.exp_time.minute, tt.exp_time.second, tt.exp_time.fraction, tt.exp_time.timezone,
+ timestamp.year, timestamp.month, timestamp.day, timestamp.hour, timestamp.minute,
+ timestamp.second, timestamp.fraction, timestamp.timezone);
+
+ g_free (str);
+ return FALSE;
+ }
+ g_free (str);
+ }
+ }
+ g_print ("All %d iso8601 timestamp parsing tests passed\n", idate * itime);
+
+ return TRUE;
+}
+
+
+static gboolean
+test_date_handler (void)
+{
+ GdaDataHandler *dh;
+ gint i;
+ dh = gda_handler_time_new_no_locale ();
+ gda_handler_time_set_str_spec (GDA_HANDLER_TIME (dh),
+ G_DATE_YEAR, G_DATE_MONTH, G_DATE_DAY, '-', FALSE);
+
+ for (i = 0; i < sizeof (datedata) / sizeof (TestDate); i++) {
+ TestDate td = datedata[i];
+ GValue *value;
+ /*g_print ("[%s]\n", td.in_string);*/
+
+ value = gda_data_handler_get_value_from_str (dh, td.in_string, G_TYPE_DATE);
+ if ((!value && td.exp_retval) ||
+ (value && !td.exp_retval)) {
+ g_print ("Wrong result for gda_data_handler_get_value_from_str (\"%s\", G_TYPE_DATE): got %s\n",
+ td.in_string, td.exp_retval ? "FALSE" : "TRUE");
+ g_object_unref (dh);
+ return FALSE;
+ }
+
+ if (! td.exp_retval)
+ continue;
+ GDate *pdate, date;
+ pdate = g_value_get_boxed (value);
+ date = *pdate;
+ gda_value_free (value);
+
+ if ((g_date_get_day (&date) != td.exp_day) ||
+ (g_date_get_month (&date) != td.exp_month) ||
+ (g_date_get_year (&date) != td.exp_year)) {
+ g_print ("Wrong result for gda_parse_iso8601_date (\"%s\"):\n"
+ " exp: DD=%d MM=%d YYYY=%d\n"
+ " got: DD=%d MM=%d YYYY=%d\n",
+ td.in_string, td.exp_day, td.exp_month, td.exp_year,
+ g_date_get_day (&date), g_date_get_month (&date),
+ g_date_get_year (&date));
+ g_object_unref (dh);
+ return FALSE;
+ }
+ }
+ g_print ("All %d GdaDataHandler (G_TYPE_DATE) parsing tests passed\n", i);
+ g_object_unref (dh);
+ return TRUE;
+}
+
+TestTime timedata2[] = {
+ {"112256", TRUE, {11, 22, 56, 0, GDA_TIMEZONE_INVALID}},
+ {"012256", TRUE, {1, 22, 56, 0, GDA_TIMEZONE_INVALID}},
+ {"012260", FALSE, {1, 22, 0, 0, GDA_TIMEZONE_INVALID}},
+ {"016045", FALSE, {1, 0, 0, 0, GDA_TIMEZONE_INVALID}},
+ {"242345", FALSE, {0, 0, 0, 0, GDA_TIMEZONE_INVALID}},
+ {"235959", TRUE, {23, 59, 59, 0, GDA_TIMEZONE_INVALID}},
+ {"000000", TRUE, {0, 0, 0, 0, GDA_TIMEZONE_INVALID}},
+ {"120100", TRUE, {12, 1, 0, 0, GDA_TIMEZONE_INVALID}},
+ {" 120000", FALSE, {0, 0, 0, 0, GDA_TIMEZONE_INVALID}},
+ {"12 0000", FALSE, {12, 0, 0, 0, GDA_TIMEZONE_INVALID}},
+ {"12 0000", FALSE, {12, 0, 0, 0, GDA_TIMEZONE_INVALID}},
+ {"12 0000", FALSE, {12, 0, 0, 0, GDA_TIMEZONE_INVALID}},
+ {"1201 00", FALSE, {12, 1, 0, 0, GDA_TIMEZONE_INVALID}},
+ {"120102 ", FALSE, {12, 1, 2, 0, GDA_TIMEZONE_INVALID}},
+ {"120102.", FALSE, {12, 1, 2, 0, GDA_TIMEZONE_INVALID}},
+ {"120102:", FALSE, {12, 1, 2, 0, GDA_TIMEZONE_INVALID}},
+ {"120102.123", TRUE, {12, 1, 2, 123, GDA_TIMEZONE_INVALID}},
+ {"120102-2", TRUE, {12, 1, 2, 0, -2*60*60}},
+ {"120102+11", TRUE, {12, 1, 2, 0, 11*60*60}},
+ {"120102.1234+11", TRUE, {12, 1, 2, 1234, 11*60*60}},
+ {"120102.12345678-3", TRUE, {12, 1, 2, 12345678, -3*60*60}},
+};
+
+static gboolean
+test_time_handler (void)
+{
+ GdaDataHandler *dh;
+ gint i, j;
+ dh = gda_get_default_handler (GDA_TYPE_TIME);
+ g_assert (dh);
+
+ for (i = 0; i < sizeof (timedata) / sizeof (TestTime); i++) {
+ TestTime td = timedata[i];
+ GValue *value;
+ /*g_print ("[%s]\n", td.in_string);*/
+
+ value = gda_data_handler_get_value_from_str (dh, td.in_string, GDA_TYPE_TIME);
+ if ((!value && td.exp_retval) ||
+ (value && !td.exp_retval)) {
+ g_print ("Wrong result for gda_data_handler_get_value_from_str (\"%s\", GDA_TYPE_TIME): got %s\n",
+ td.in_string, td.exp_retval ? "FALSE" : "TRUE");
+ g_object_unref (dh);
+ return FALSE;
+ }
+
+ if (! td.exp_retval)
+ continue;
+ const GdaTime *ptime;
+ GdaTime time;
+ ptime = gda_value_get_time (value);
+ time = *ptime;
+ gda_value_free (value);
+
+ if ((time.hour != td.exp_time.hour) ||
+ (time.minute != td.exp_time.minute) ||
+ (time.second != td.exp_time.second) ||
+ (time.fraction != td.exp_time.fraction) ||
+ (time.timezone != td.exp_time.timezone)) {
+ g_print ("Wrong result forgda_data_handler_get_value_from_str (\"%s\", GDA_TYPE_TIME):\n"
+ " exp: HH=%d MM=%d SS=%d FF=%ld TZ=%ld\n"
+ " got: HH=%d MM=%d SS=%d FF=%ld TZ=%ld\n",
+ td.in_string,
+ td.exp_time.hour, td.exp_time.minute, td.exp_time.second,
+ td.exp_time.fraction, td.exp_time.timezone,
+ time.hour, time.minute, time.second,
+ time.fraction, time.timezone);
+ return FALSE;
+ }
+ }
+
+ for (j = 0; j < sizeof (timedata2) / sizeof (TestTime); j++) {
+ TestTime td = timedata2[j];
+ GValue *value;
+ /*g_print ("[%s]\n", td.in_string);*/
+
+ value = gda_data_handler_get_value_from_str (dh, td.in_string, GDA_TYPE_TIME);
+ if ((!value && td.exp_retval) ||
+ (value && !td.exp_retval)) {
+ g_print ("Wrong result for gda_data_handler_get_value_from_str (\"%s\", GDA_TYPE_TIME): got %s\n",
+ td.in_string, td.exp_retval ? "FALSE" : "TRUE");
+ g_object_unref (dh);
+ return FALSE;
+ }
+
+ if (! td.exp_retval)
+ continue;
+ const GdaTime *ptime;
+ GdaTime time;
+ ptime = gda_value_get_time (value);
+ time = *ptime;
+ gda_value_free (value);
+
+ if ((time.hour != td.exp_time.hour) ||
+ (time.minute != td.exp_time.minute) ||
+ (time.second != td.exp_time.second) ||
+ (time.fraction != td.exp_time.fraction) ||
+ (time.timezone != td.exp_time.timezone)) {
+ g_print ("Wrong result forgda_data_handler_get_value_from_str (\"%s\", GDA_TYPE_TIME):\n"
+ " exp: HH=%d MM=%d SS=%d FF=%ld TZ=%ld\n"
+ " got: HH=%d MM=%d SS=%d FF=%ld TZ=%ld\n",
+ td.in_string,
+ td.exp_time.hour, td.exp_time.minute, td.exp_time.second,
+ td.exp_time.fraction, td.exp_time.timezone,
+ time.hour, time.minute, time.second,
+ time.fraction, time.timezone);
+ return FALSE;
+ }
+ }
+
+ g_print ("All %d GdaDataHandler (GDA_TYPE_TIME) parsing tests passed\n", i + j);
+ g_object_unref (dh);
+ return TRUE;
+}
+
+static gboolean
+test_timestamp_handler (void)
+{
+ GdaDataHandler *dh;
+ gint idate, itime, itime2;
+ dh = gda_handler_time_new_no_locale ();
+ gda_handler_time_set_str_spec (GDA_HANDLER_TIME (dh),
+ G_DATE_YEAR, G_DATE_MONTH, G_DATE_DAY, '-', FALSE);
+
+ for (idate = 0; idate < sizeof (datedata) / sizeof (TestTime); idate++) {
+ TestDate td = datedata [idate];
+ for (itime = 0; itime < sizeof (timedata) / sizeof (TestTime); itime++) {
+ TestTime tt = timedata[itime];
+ gchar *str;
+ str = g_strdup_printf ("%s %s", td.in_string, tt.in_string);
+
+ GValue *value;
+ gboolean exp_result = td.exp_retval && tt.exp_retval;
+ /*g_print ("[%s]\n", str);*/
+
+ value = gda_data_handler_get_value_from_str (dh, str, GDA_TYPE_TIMESTAMP);
+ if ((!value && exp_result) ||
+ (value && !exp_result)) {
+ g_print ("Wrong result for gda_data_handler_get_value_from_str (\"%s\", GDA_TYPE_TIMESTAMP): got %s\n",
+ str, exp_result ? "FALSE" : "TRUE");
+ g_object_unref (dh);
+ return FALSE;
+ }
+
+ if (! exp_result) {
+ g_free (str);
+ continue;
+ }
+ const GdaTimestamp *ptimestamp;
+ GdaTimestamp timestamp;
+ ptimestamp = gda_value_get_timestamp (value);
+ timestamp = *ptimestamp;
+ gda_value_free (value);
+
+ if ((td.exp_retval &&
+ ((timestamp.year != td.exp_year) ||
+ (timestamp.month != td.exp_month) ||
+ (timestamp.day != td.exp_day))) &&
+ ((tt.exp_retval) &&
+ ((timestamp.hour != tt.exp_time.hour) ||
+ (timestamp.minute != tt.exp_time.minute) ||
+ (timestamp.second != tt.exp_time.second) ||
+ (timestamp.fraction != tt.exp_time.fraction) ||
+ (timestamp.timezone != tt.exp_time.timezone)))) {
+ g_print ("Wrong result for gda_data_handler_get_value_from_str (\"%s\", GDA_TYPE_TIMESTAMP):\n"
+ " exp: DD=%d MM=%d YYYY=%d HH=%d MM=%d SS=%d FF=%ld TZ=%ld\\n"
+ " got: DD=%d MM=%d YYYY=%d HH=%d MM=%d SS=%d FF=%ld TZ=%ld\\n",
+ str, td.exp_day, td.exp_month, td.exp_year,
+ tt.exp_time.hour, tt.exp_time.minute, tt.exp_time.second, tt.exp_time.fraction, tt.exp_time.timezone,
+ timestamp.year, timestamp.month, timestamp.day, timestamp.hour, timestamp.minute,
+ timestamp.second, timestamp.fraction, timestamp.timezone);
+
+ g_object_unref (dh);
+ g_free (str);
+ return FALSE;
+ }
+ g_free (str);
+ }
+ }
+
+ for (idate = 0; idate < sizeof (datedata) / sizeof (TestTime); idate++) {
+ TestDate td = datedata [idate];
+ for (itime2 = 0; itime2 < sizeof (timedata2) / sizeof (TestTime); itime2++) {
+ TestTime tt = timedata2[itime2];
+ gchar *str;
+ str = g_strdup_printf ("%s %s", td.in_string, tt.in_string);
+
+ GValue *value;
+ gboolean exp_result = td.exp_retval && tt.exp_retval;
+ /*g_print ("[%s]\n", str);*/
+
+ value = gda_data_handler_get_value_from_str (dh, str, GDA_TYPE_TIMESTAMP);
+ if ((!value && exp_result) ||
+ (value && !exp_result)) {
+ g_print ("Wrong result for gda_data_handler_get_value_from_str (\"%s\", GDA_TYPE_TIMESTAMP): got %s\n",
+ str, exp_result ? "FALSE" : "TRUE");
+ g_object_unref (dh);
+ return FALSE;
+ }
+
+ if (! exp_result) {
+ g_free (str);
+ continue;
+ }
+ const GdaTimestamp *ptimestamp;
+ GdaTimestamp timestamp;
+ ptimestamp = gda_value_get_timestamp (value);
+ timestamp = *ptimestamp;
+ gda_value_free (value);
+
+ if ((timestamp.year != td.exp_year) ||
+ (timestamp.month != td.exp_month) ||
+ (timestamp.day != td.exp_day) ||
+ (timestamp.hour != tt.exp_time.hour) ||
+ (timestamp.minute != tt.exp_time.minute) ||
+ (timestamp.second != tt.exp_time.second) ||
+ (timestamp.fraction != tt.exp_time.fraction) ||
+ (timestamp.timezone != tt.exp_time.timezone)) {
+ g_print ("Wrong result for gda_data_handler_get_value_from_str (\"%s\", GDA_TYPE_TIMESTAMP):\n"
+ " exp: DD=%d MM=%d YYYY=%d HH=%d MM=%d SS=%d FF=%ld TZ=%ld\\n"
+ " got: DD=%d MM=%d YYYY=%d HH=%d MM=%d SS=%d FF=%ld TZ=%ld\\n",
+ str, td.exp_day, td.exp_month, td.exp_year,
+ tt.exp_time.hour, tt.exp_time.minute, tt.exp_time.second, tt.exp_time.fraction, tt.exp_time.timezone,
+ timestamp.year, timestamp.month, timestamp.day, timestamp.hour, timestamp.minute,
+ timestamp.second, timestamp.fraction, timestamp.timezone);
+
+ g_object_unref (dh);
+ g_free (str);
+ return FALSE;
+ }
+ g_free (str);
+ }
+ }
+
+ g_print ("All %d GdaDataHandler (GDA_TYPE_TIMESTAMP) parsing tests passed\n", idate * (itime + itime2));
+ g_object_unref (dh);
+ return TRUE;
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]