[Top][All Lists]
[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
- [PATCH 0/5] more var-type-dialog improvements, Ben Pfaff, 2012/07/17
- [PATCH 1/5] var-type-dialog: Avoid string copy setting up currency treeview., Ben Pfaff, 2012/07/17
- [PATCH 2/5] var-type-dialog: Fix possible memory leaks., Ben Pfaff, 2012/07/17
- [PATCH 4/5] format: Make fmt_date_template() human-friendly, respect field width.,
Ben Pfaff <=
- [PATCH 5/5] var-type-dialog: Use fmt_date_template() to reduce duplication., Ben Pfaff, 2012/07/17
- [PATCH 3/5] var-type-dialog: Use G_TYPE_INT to store an int., Ben Pfaff, 2012/07/17
- Re: [PATCH 0/5] more var-type-dialog improvements, John Darrington, 2012/07/17