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)
}
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;
}
}
/* 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);
}
#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);
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);
\f
/* 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)
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
\f
/* 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;
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)
/* 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
}
}
- 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 */
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)
{
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
{
int y, m, d, yd;
double output;
+ char *error;
calendar_offset_to_gregorian (date / DAY_S, &y, &m, &d, &yd);
y += months / 12;
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;
}