From 6549c9aced0949b16abb372257772fc0893e02bb Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Fri, 17 Sep 2010 17:10:44 -0700 Subject: [PATCH] calendar: Use sensible error reporting in calendar_gregorian_to_offset(). --- src/data/calendar.c | 18 +++++++---- src/data/calendar.h | 5 +--- src/data/data-in.c | 48 ++++++++++-------------------- src/data/psql-reader.c | 5 ++-- src/language/expressions/helpers.c | 37 ++++++++++------------- 5 files changed, 46 insertions(+), 67 deletions(-) diff --git a/src/data/calendar.c b/src/data/calendar.c index eb9e67250a..ef6aa6755e 100644 --- a/src/data/calendar.c +++ b/src/data/calendar.c @@ -52,8 +52,7 @@ raw_gregorian_to_offset (int y, int m, int d) Gregorian calendar. Returns SYSMIS for dates before 14 Oct 1582. */ double -calendar_gregorian_to_offset (int y, int m, int d, - calendar_error_func *error, void *aux) +calendar_gregorian_to_offset (int y, int m, int d, char **errorp) { /* Normalize year. */ if (y >= 0 && y < 100) @@ -78,7 +77,9 @@ calendar_gregorian_to_offset (int y, int m, int d, } else { - error (aux, _("Month %d is not in acceptable range of 0 to 13."), m); + if (errorp != NULL) + *errorp = xasprintf (_("Month %d is not in acceptable range of " + "0 to 13."), m); return SYSMIS; } } @@ -86,19 +87,24 @@ calendar_gregorian_to_offset (int y, int m, int d, /* Normalize day. */ if (d < 0 || d > 31) { - error (aux, _("Day %d is not in acceptable range of 0 to 31."), d); + if (errorp != NULL) + *errorp = xasprintf (_("Day %d is not in acceptable range of " + "0 to 31."), d); return SYSMIS; } /* Validate date. */ if (y < 1582 || (y == 1582 && (m < 10 || (m == 10 && d < 15)))) { - error (aux, _("Date %04d-%d-%d is before the earliest acceptable " - "date of 1582-10-15."), y, m, d); + if (errorp != NULL) + *errorp = xasprintf (_("Date %04d-%d-%d is before the earliest " + "acceptable date of 1582-10-15."), y, m, d); return SYSMIS; } /* Calculate offset. */ + if (errorp != NULL) + *errorp = NULL; return raw_gregorian_to_offset (y, m, d); } diff --git a/src/data/calendar.h b/src/data/calendar.h index 06d2fd3a49..5535690447 100644 --- a/src/data/calendar.h +++ b/src/data/calendar.h @@ -1,10 +1,7 @@ #ifndef CALENDAR_H #define CALENDAR_H 1 -typedef void calendar_error_func (void *aux, const char *, ...); - -double calendar_gregorian_to_offset (int y, int m, int d, - calendar_error_func *, void *aux); +double calendar_gregorian_to_offset (int y, int m, int d, char **errorp); void calendar_offset_to_gregorian (int ofs, int *y, int *m, int *d, int *yd); int calendar_offset_to_year (int ofs); int calendar_offset_to_month (int ofs); diff --git a/src/data/data-in.c b/src/data/data-in.c index 35a725d577..2b842b8dcd 100644 --- a/src/data/data-in.c +++ b/src/data/data-in.c @@ -74,8 +74,6 @@ typedef bool data_in_parser_func (struct data_in *); static data_in_parser_func parse_##METHOD; #include "format.def" -static void vdata_warning (const struct data_in *, const char *, va_list) - PRINTF_FORMAT (2, 0); static void data_warning (const struct data_in *, const char *, ...) PRINTF_FORMAT (2, 3); @@ -1019,19 +1017,6 @@ parse_weekday (struct data_in *i, long *weekday) /* Date & time formats. */ -/* Helper function for passing to - calendar_gregorian_to_offset. */ -static void -calendar_error (void *i_, const char *format, ...) -{ - struct data_in *i = i_; - va_list args; - - va_start (args, format); - vdata_warning (i, format, args); - va_end (args); -} - /* Parses WKDAY format. */ static bool parse_WKDAY (struct data_in *i) @@ -1162,10 +1147,16 @@ parse_date (struct data_in *i) if (year != INT_MIN) { - double ofs = calendar_gregorian_to_offset (year, month, day, - calendar_error, i); + char *error; + double ofs; + + ofs = calendar_gregorian_to_offset (year, month, day, &error); if (ofs == SYSMIS) - return false; + { + data_warning (i, "%s", error); + free (error); + return false; + } date = (yday - 1 + ofs) * 60. * 60. * 24.; } else @@ -1177,18 +1168,21 @@ parse_date (struct data_in *i) /* Utility functions. */ -/* Outputs FORMAT with the given ARGS as a warning for input - I. */ +/* Outputs FORMAT with as a warning for input I. */ static void -vdata_warning (const struct data_in *i, const char *format, va_list args) +data_warning (const struct data_in *i, const char *format, ...) { + va_list args; struct msg m; struct string text; ds_init_empty (&text); ds_put_char (&text, '('); ds_put_format (&text, _("%s field) "), fmt_name (i->format)); + + va_start (args, format); ds_put_vformat (&text, format, args); + va_end (args); m.category = MSG_C_DATA; m.severity = MSG_S_WARNING; @@ -1201,18 +1195,6 @@ vdata_warning (const struct data_in *i, const char *format, va_list args) msg_emit (&m); } -/* Outputs FORMAT with the given ARGS as a warning for input - I. */ -static void -data_warning (const struct data_in *i, const char *format, ...) -{ - va_list args; - - va_start (args, format); - vdata_warning (i, format, args); - va_end (args); -} - /* Apply implied decimal places to output. */ static void apply_implied_decimals (struct data_in *i) diff --git a/src/data/psql-reader.c b/src/data/psql-reader.c index b86cf4ed6c..76b4674dc9 100644 --- a/src/data/psql-reader.c +++ b/src/data/psql-reader.c @@ -1,5 +1,5 @@ /* PSPP - a program for statistical analysis. - Copyright (C) 2008, 2009 Free Software Foundation, Inc. + Copyright (C) 2008, 2009, 2010 Free Software Foundation, Inc. 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 @@ -286,8 +286,7 @@ psql_open_reader (struct psql_read_info *info, struct dictionary **dict) } } - r->postgres_epoch = - calendar_gregorian_to_offset (2000, 1, 1, NULL, NULL); + r->postgres_epoch = calendar_gregorian_to_offset (2000, 1, 1, NULL); /* Create the dictionary and populate it */ diff --git a/src/language/expressions/helpers.c b/src/language/expressions/helpers.c index 08f787fea2..ac17c1cece 100644 --- a/src/language/expressions/helpers.c +++ b/src/language/expressions/helpers.c @@ -24,31 +24,14 @@ const struct substring empty_string = {NULL, 0}; -static void -expr_error (void *aux UNUSED, const char *format, ...) -{ - struct msg m; - va_list args; - - m.category = MSG_C_SYNTAX; - m.severity = MSG_S_ERROR; - va_start (args, format); - m.text = xvasprintf (format, args); - m.where.file_name = NULL; - m.where.line_number = 0; - m.where.first_column = 0; - m.where.last_column = 0; - va_end (args); - - msg_emit (&m); -} - double expr_ymd_to_ofs (double year, double month, double day) { int y = year; int m = month; int d = day; + char *error; + double ofs; if (y != year || m != month || d != day) { @@ -57,7 +40,13 @@ expr_ymd_to_ofs (double year, double month, double day) return SYSMIS; } - return calendar_gregorian_to_offset (y, m, d, expr_error, NULL); + ofs = calendar_gregorian_to_offset (y, m, d, &error); + if (error != NULL) + { + msg (SE, "%s", error); + free (error); + } + return ofs; } double @@ -348,6 +337,7 @@ add_months (double date, int months, enum date_sum_method method) { int y, m, d, yd; double output; + char *error; calendar_offset_to_gregorian (date / DAY_S, &y, &m, &d, &yd); y += months / 12; @@ -367,9 +357,14 @@ add_months (double date, int months, enum date_sum_method method) if (method == SUM_CLOSEST && d > calendar_days_in_month (y, m)) d = calendar_days_in_month (y, m); - output = calendar_gregorian_to_offset (y, m, d, expr_error, NULL); + output = calendar_gregorian_to_offset (y, m, d, &error); if (output != SYSMIS) output = (output * DAY_S) + fmod (date, DAY_S); + else + { + msg (SE, "%s", error); + free (error); + } return output; } -- 2.30.2