X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fdata%2Fformat.c;h=113d52592eea46f5593e598bd06693633eaa3510;hb=0fc606c52d7cec253af9b7463b15baabfbc9a33a;hp=dc546af84577e41917220635a20a3c3f8fd3438a;hpb=3328de5b6568b4dc85562b25add87c068b579cda;p=pspp diff --git a/src/data/format.c b/src/data/format.c index dc546af845..113d52592e 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 @@ -33,6 +33,7 @@ #include "libpspp/misc.h" #include "libpspp/str.h" +#include "gl/c-strcase.h" #include "gl/minmax.h" #include "gl/xalloc.h" @@ -68,7 +69,7 @@ fmt_settings_create (void) int t; settings = xzalloc (sizeof *settings); - for (t = 0 ; t < FMT_NUMBER_OF_FORMATS ; ++t ) + for (t = 0 ; t < FMT_NUMBER_OF_FORMATS ; ++t) fmt_number_style_init (&settings->styles[t]); fmt_settings_set_decimal (settings, '.'); @@ -83,7 +84,7 @@ fmt_settings_destroy (struct fmt_settings *settings) { int t; - for (t = 0 ; t < FMT_NUMBER_OF_FORMATS ; ++t ) + for (t = 0 ; t < FMT_NUMBER_OF_FORMATS ; ++t) fmt_number_style_destroy (&settings->styles[t]); free (settings->styles); @@ -98,7 +99,7 @@ fmt_settings_clone (const struct fmt_settings *old) int t; new = xmalloc (sizeof *new); - for (t = 0 ; t < FMT_NUMBER_OF_FORMATS ; ++t ) + for (t = 0 ; t < FMT_NUMBER_OF_FORMATS ; ++t) fmt_number_style_clone (&new->styles[t], &old->styles[t]); return new; @@ -292,6 +293,16 @@ fmt_for_output_from_input (const struct fmt_spec *input) case FMT_MONTH: break; + case FMT_MTIME: + if (input->d) + output.w = MAX (input->w, input->d + 6); + break; + + case FMT_YMDHMS: + if (input->w) + output.w = MAX (input->w, input->d + 20); + break; + default: NOT_REACHED (); } @@ -474,8 +485,10 @@ fmt_equal (const struct fmt_spec *a, const struct fmt_spec *b) return a->type == b->type && a->w == b->w && a->d == b->d; } -/* Adjusts FMT to be valid for a value of the given WIDTH. */ -void +/* Adjusts FMT to be valid for a value of the given WIDTH if necessary. + If nothing needed to be changed the return value is false + */ +bool fmt_resize (struct fmt_spec *fmt, int width) { if ((width > 0) != fmt_is_string (fmt->type)) @@ -493,7 +506,9 @@ fmt_resize (struct fmt_spec *fmt, int width) else { /* Still numeric. */ + return false; } + return true; } /* Adjusts FMT's width and decimal places to be valid for USE. */ @@ -581,7 +596,7 @@ fmt_from_name (const char *name, enum fmt_type *type) int i; for (i = 0; i < FMT_NUMBER_OF_FORMATS; i++) - if (!strcasecmp (name, get_fmt_desc (i)->name)) + if (!c_strcasecmp (name, get_fmt_desc (i)->name)) { *type = i; return true; @@ -714,6 +729,14 @@ fmt_max_decimals (enum fmt_type type, int width, enum fmt_use use) max_d = width - 21; break; + case FMT_YMDHMS: + max_d = width - 20; + break; + + case FMT_MTIME: + max_d = width - 6; + break; + case FMT_TIME: max_d = width - 9; break; @@ -872,6 +895,40 @@ fmt_from_io (int io, enum fmt_type *fmt_type) } } +/* Translate U32, which is in the form found in SAV and SPV files, into a + format specification, and stores the new specification in *F. + + If LOOSE is false, checks that the format specification is appropriate as an + output format for a variable with the given WIDTH and reports an error if + not. If LOOSE is true, instead adjusts the format's width and decimals as + necessary to be suitable. + + Return true if successful, false if there was an error.. */ +bool +fmt_from_u32 (uint32_t u32, int width, bool loose, struct fmt_spec *f) +{ + uint8_t raw_type = u32 >> 16; + uint8_t w = u32 >> 8; + uint8_t d = u32; + + msg_disable (); + f->w = w; + f->d = d; + bool ok = fmt_from_io (raw_type, &f->type); + if (ok) + { + if (loose) + fmt_fix_output (f); + else + ok = fmt_check_output (f); + } + if (ok) + ok = fmt_check_width_compat (f, width); + msg_enable (); + + return ok; +} + /* Returns true if TYPE may be used as an input format, false otherwise. */ bool @@ -881,38 +938,91 @@ 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_YMDHMS: + s1 = "yyyy-mm-dd HH:MM"; + s2 = "yyyy-mm-dd HH:MM:SS"; + break; + + case FMT_MTIME: + s1 = "MM"; + s2 = "MM:SS"; + break; + case FMT_TIME: - return "H:MM"; + s1 = "HH:MM"; + s2 = "HH: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. */ @@ -942,6 +1052,8 @@ fmt_gui_name (enum fmt_type type) case FMT_MOYR: case FMT_WKYR: case FMT_DATETIME: + case FMT_YMDHMS: + case FMT_MTIME: case FMT_TIME: case FMT_DTIME: case FMT_WKDAY: @@ -1110,3 +1222,6 @@ get_fmt_desc (enum fmt_type type) } const struct fmt_spec F_8_0 = {FMT_F, 8, 0}; +const struct fmt_spec F_8_2 = {FMT_F, 8, 2}; +const struct fmt_spec F_4_3 = {FMT_F, 4, 3}; +const struct fmt_spec F_5_1 = {FMT_F, 5, 1};