pspp-dev
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH 4/5] format: Make fmt_date_template() human-friendly, respect fie


From: Ben Pfaff
Subject: [PATCH 4/5] format: Make fmt_date_template() human-friendly, respect field width.
Date: Mon, 16 Jul 2012 23:45:55 -0700

The strings that fmt_date_template() returned were almost but not
quite the kind of strings that humans expect to see.  For one, they
always used "yy", even though the code uses 4-digit years ("yyyy")
when the field width is sufficient.  Similarly, they never included
seconds (i.e. omitted ":SS").  Finally, FMT_MOYR had an "X" where
one would expect a space.

This commit corrects all of the above issues.  Future commits will
make more use of fmt_date_template().
---
 src/data/data-in.c  |   14 ++++++---
 src/data/data-out.c |   17 +++++-------
 src/data/format.c   |   73 ++++++++++++++++++++++++++++++++++++++++----------
 src/data/format.h   |    2 +-
 4 files changed, 75 insertions(+), 31 deletions(-)

diff --git a/src/data/data-in.c b/src/data/data-in.c
index e72d1b6..14a24ff 100644
--- a/src/data/data-in.c
+++ b/src/data/data-in.c
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 1997-9, 2000, 2006, 2009, 2010, 2011 Free Software 
Foundation, Inc.
+   Copyright (C) 1997-9, 2000, 2006, 2009, 2010, 2011, 2012 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
@@ -1123,7 +1123,7 @@ parse_date (struct data_in *i)
   double time = 0, date = 0;
   enum time_sign time_sign = SIGN_NO_TIME;
 
-  const char *template = fmt_date_template (i->format);
+  const char *template = fmt_date_template (i->format, 0);
   size_t template_width = strlen (template);
   char *error;
 
@@ -1180,14 +1180,18 @@ parse_date (struct data_in *i)
         case '-':
         case '/':
         case '.':
-        case 'X':
           error = parse_date_delimiter (i);
           break;
         case ':':
           error = parse_time_delimiter (i);
         case ' ':
-          parse_spaces (i);
-          error = NULL;
+          if (i->format != FMT_MOYR)
+            {
+              parse_spaces (i);
+              error = NULL;
+            }
+          else
+            error = parse_date_delimiter (i);
           break;
         default:
           assert (count == 1);
diff --git a/src/data/data-out.c b/src/data/data-out.c
index df447a6..2a0dd0a 100644
--- a/src/data/data-out.c
+++ b/src/data/data-out.c
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 1997-9, 2000, 2006, 2009, 2011 Free Software Foundation, Inc.
+   Copyright (C) 1997-9, 2000, 2006, 2009, 2011, 2012 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
@@ -387,14 +387,11 @@ output_date (const union value *input, const struct 
fmt_spec *format,
   double number = input->f;
   int year, month, day, yday;
 
-  const char *template = fmt_date_template (format->type);
-  size_t template_width = strlen (template);
-  int excess_width = format->w - template_width;
+  const char *template = fmt_date_template (format->type, format->w);
 
   char tmp[64];
   char *p = tmp;
 
-  assert (format->w >= template_width);
   if (number == SYSMIS)
     goto missing;
 
@@ -411,6 +408,8 @@ output_date (const union value *input, const struct 
fmt_spec *format,
 
   while (*template != '\0')
     {
+      int excess_width;
+
       int ch = *template;
       int count = 1;
       while (template[count] == ch)
@@ -439,7 +438,7 @@ output_date (const union value *input, const struct 
fmt_spec *format,
             }
           break;
         case 'y':
-          if (count >= 4 || excess_width >= 2)
+          if (count >= 4)
             {
               if (year <= 9999)
                 p += sprintf (p, "%04d", year);
@@ -499,10 +498,7 @@ output_date (const union value *input, const struct 
fmt_spec *format,
                 }
               p += strlen (p);
             }
-          break;
-        case 'X':
-          *p++ = ' ';
-          break;
+          goto done;
         default:
           assert (count == 1);
           *p++ = ch;
@@ -510,6 +506,7 @@ output_date (const union value *input, const struct 
fmt_spec *format,
         }
     }
 
+ done:
   buf_copy_lpad (output, format->w, tmp, p - tmp, ' ');
   output[format->w] = '\0';
   return;
diff --git a/src/data/format.c b/src/data/format.c
index dc546af..58e16d3 100644
--- a/src/data/format.c
+++ b/src/data/format.c
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 1997-9, 2000, 2006, 2010, 2011 Free Software Foundation, Inc.
+   Copyright (C) 1997-9, 2000, 2006, 2010, 2011, 2012 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
@@ -881,38 +881,81 @@ fmt_usable_for_input (enum fmt_type type)
   return fmt_get_category (type) != FMT_CAT_CUSTOM;
 }
 
-/* For time and date formats, returns a template used for input
-   and output. */
+/* For time and date formats, returns a template used for input and output in a
+   field of the given WIDTH.
+
+   WIDTH only affects whether a 2-digit year or a 4-digit year is used, that
+   is, whether the returned string contains "yy" or "yyyy", and whether seconds
+   are include, that is, whether the returned string contains ":SS".  A caller
+   that doesn't care whether the returned string contains "yy" or "yyyy" or
+   ":SS" can just specify 0 to omit them. */
 const char *
-fmt_date_template (enum fmt_type type)
+fmt_date_template (enum fmt_type type, int width)
 {
+  const char *s1, *s2;
+
   switch (type)
     {
     case FMT_DATE:
-      return "dd-mmm-yy";
+      s1 = "dd-mmm-yy";
+      s2 = "dd-mmm-yyyy";
+      break;
+
     case FMT_ADATE:
-      return "mm/dd/yy";
+      s1 = "mm/dd/yy";
+      s2 = "mm/dd/yyyy";
+      break;
+
     case FMT_EDATE:
-      return "dd.mm.yy";
+      s1 = "dd.mm.yy";
+      s2 = "dd.mm.yyyy";
+      break;
+
     case FMT_JDATE:
-      return "yyddd";
+      s1 = "yyddd";
+      s2 = "yyyyddd";
+      break;
+
     case FMT_SDATE:
-      return "yy/mm/dd";
+      s1 = "yy/mm/dd";
+      s2 = "yyyy/mm/dd";
+      break;
+
     case FMT_QYR:
-      return "q Q yy";
+      s1 = "q Q yy";
+      s2 = "q Q yyyy";
+      break;
+
     case FMT_MOYR:
-      return "mmmXyy";
+      s1 = "mmm yy";
+      s2 = "mmm yyyy";
+      break;
+
     case FMT_WKYR:
-      return "ww WK yy";
+      s1 = "ww WK yy";
+      s2 = "ww WK yyyy";
+      break;
+
     case FMT_DATETIME:
-      return "dd-mmm-yyyy HH:MM";
+      s1 = "dd-mmm-yyyy HH:MM";
+      s2 = "dd-mmm-yyyy HH:MM:SS";
+      break;
+
     case FMT_TIME:
-      return "H:MM";
+      s1 = "H:MM";
+      s2 = "H:MM:SS";
+      break;
+
     case FMT_DTIME:
-      return "D HH:MM";
+      s1 = "D HH:MM";
+      s2 = "D HH:MM:SS";
+      break;
+
     default:
       NOT_REACHED ();
     }
+
+  return width >= strlen (s2) ? s2 : s1;
 }
 
 /* Returns a string representing the format TYPE for use in a GUI dialog. */
diff --git a/src/data/format.h b/src/data/format.h
index 1744bec..def3cdc 100644
--- a/src/data/format.h
+++ b/src/data/format.h
@@ -134,7 +134,7 @@ bool fmt_usable_for_input (enum fmt_type) PURE_FUNCTION;
 int fmt_to_io (enum fmt_type) PURE_FUNCTION;
 bool fmt_from_io (int io, enum fmt_type *);
 
-const char *fmt_date_template (enum fmt_type) PURE_FUNCTION;
+const char *fmt_date_template (enum fmt_type, int width) PURE_FUNCTION;
 const char *fmt_gui_name (enum fmt_type);
 
 /* Format settings.
-- 
1.7.2.5




reply via email to

[Prev in Thread] Current Thread [Next in Thread]