Update all #include directives to the currently preferred style.
[pspp-builds.git] / src / data / calendar.c
index 3a38f1265fae0b3013d68840a8ea62aaae609b4d..a2bb7e600004c6cd025c90e0c26641e12fe30ce0 100644 (file)
@@ -1,9 +1,28 @@
+/* PSPP - a program for statistical analysis.
+   Copyright (C) 2006, 2007, 2008, 2010, 2011 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
+   the Free Software Foundation, either version 3 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, see <http://www.gnu.org/licenses/>. */
+
 #include <config.h>
-#include "calendar.h"
+
+#include "data/calendar.h"
+
 #include <assert.h>
 #include <stdbool.h>
-#include "settings.h"
-#include "value.h"
+
+#include "data/settings.h"
+#include "data/val-type.h"
 
 #include "gettext.h"
 #define _(msgid) gettext (msgid)
@@ -13,7 +32,7 @@
 
 /* Calculates and returns floor(a/b) for integer b > 0. */
 static int
-floor_div (int a, int b) 
+floor_div (int a, int b)
 {
   assert (b > 0);
   return (a >= 0 ? a : a - b + 1) / b;
@@ -22,7 +41,7 @@ floor_div (int a, int b)
 /* Calculates floor(a/b) and the corresponding remainder and
    stores them into *Q and *R. */
 static void
-floor_divmod (int a, int b, int *q, int *r) 
+floor_divmod (int a, int b, int *q, int *r)
 {
   *q = floor_div (a, b);
   *r = a - b * *q;
@@ -30,13 +49,13 @@ floor_divmod (int a, int b, int *q, int *r)
 
 /* Returns true if Y is a leap year, false otherwise. */
 static bool
-is_leap_year (int y) 
+is_leap_year (int y)
 {
   return y % 4 == 0 && (y % 100 != 0 || y % 400 == 0);
 }
 
 static int
-raw_gregorian_to_offset (int y, int m, int d) 
+raw_gregorian_to_offset (int y, int m, int d)
 {
   return (EPOCH - 1
           + 365 * (y - 1)
@@ -52,62 +71,68 @@ 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) 
+  if (y >= 0 && y < 100)
     {
-      int epoch = get_epoch ();
+      int epoch = settings_get_epoch ();
       int century = epoch / 100 + (y < epoch % 100);
       y += century * 100;
     }
 
   /* Normalize month. */
-  if (m < 1 || m > 12) 
+  if (m < 1 || m > 12)
     {
-      if (m == 0) 
+      if (m == 0)
         {
           y--;
           m = 12;
         }
-      else if (m == 13) 
+      else if (m == 13)
         {
           y++;
           m = 1;
         }
       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) 
+  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)))) 
+  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);
 }
 
 /* Returns the number of days in the given YEAR from January 1 up
    to (but not including) the first day of MONTH. */
 static int
-cum_month_days (int year, int month) 
+cum_month_days (int year, int month)
 {
-  static const int cum_month_days[12] = 
+  static const int cum_month_days[12] =
     {
       0,
       31, /* Jan */
@@ -131,7 +156,7 @@ cum_month_days (int year, int month)
    Gregorian calendar year it is in.  Dates both before and after
    the epoch are supported. */
 int
-calendar_offset_to_year (int ofs) 
+calendar_offset_to_year (int ofs)
 {
   int d0;
   int n400, d1;
@@ -194,7 +219,7 @@ calendar_offset_to_wday (int ofs)
 /* Takes a count of days from 14 Oct 1582 and returns the month
    it is in. */
 int
-calendar_offset_to_month (int ofs) 
+calendar_offset_to_month (int ofs)
 {
   int y, m, d, yd;
   calendar_offset_to_gregorian (ofs, &y, &m, &d, &yd);
@@ -204,9 +229,20 @@ calendar_offset_to_month (int ofs)
 /* Takes a count of days from 14 Oct 1582 and returns the
    corresponding day of the month. */
 int
-calendar_offset_to_mday (int ofs) 
+calendar_offset_to_mday (int ofs)
 {
   int y, m, d, yd;
   calendar_offset_to_gregorian (ofs, &y, &m, &d, &yd);
   return d;
 }
+
+/* Returns the number of days in the specified month. */
+int
+calendar_days_in_month (int y, int m)
+{
+  static const int days_per_month[12]
+    = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
+
+  assert (m >= 1 && m <= 12);
+  return m == 2 && is_leap_year (y) ? 29 : days_per_month[m - 1];
+}