X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fdata%2Fformat.c;h=5fe620b8b0425c224ea4f17a095dbef90d1e857f;hb=86eb95d2cd8b0acde9ace8fb02f3201001a9dedf;hp=a319a182ccf7fb14ef3dba0abe94ea03a56910b7;hpb=aec666288852283bff590537389d92ca88df43ae;p=pspp diff --git a/src/data/format.c b/src/data/format.c index a319a182cc..5fe620b8b0 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 Free Software Foundation, Inc. + Copyright (C) 1997-9, 2000, 2006, 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 @@ -45,7 +45,8 @@ static bool valid_width (enum fmt_type, int width, bool for_input); static int max_digits_for_bytes (int bytes); -void fmt_number_style_init (struct fmt_number_style *style); +static void fmt_number_style_init (struct fmt_number_style *); +static void fmt_number_style_destroy (struct fmt_number_style *); /* Initialize the format module. */ @@ -408,6 +409,61 @@ fmt_resize (struct fmt_spec *fmt, int width) /* Still numeric. */ } } + +/* Adjusts FMT's width and decimal places to be valid for an + input format (if FOR_INPUT) or an output format (if + !FOR_INPUT). */ +void +fmt_fix (struct fmt_spec *fmt, bool for_input) +{ + int min_w, max_w; + int max_d; + + /* Clamp width to those allowed by format. */ + min_w = fmt_min_width (fmt->type, for_input); + max_w = fmt_max_width (fmt->type, for_input); + if (fmt->w < min_w) + fmt->w = min_w; + else if (fmt->w > max_w) + fmt->w = max_w; + + /* First, if FMT has more decimal places than allowed, attempt + to increase FMT's width until that number of decimal places + can be achieved. */ + if (fmt->d > fmt_max_decimals (fmt->type, fmt->w, for_input)) + { + int w; + for (w = fmt->w; w <= max_w; w++) + if (fmt_max_decimals (fmt->type, w, for_input) >= fmt->d) + { + fmt->w = w; + break; + } + } + + /* Clamp decimals to those allowed by format and width. */ + max_d = fmt_max_decimals (fmt->type, fmt->w, for_input); + if (fmt->d < 0) + fmt->d = 0; + else if (fmt->d > max_d) + fmt->d = max_d; +} + +/* Adjusts FMT's width and decimal places to be valid for an + input format. */ +void +fmt_fix_input (struct fmt_spec *fmt) +{ + fmt_fix (fmt, true); +} + +/* Adjusts FMT's width and decimal places to be valid for an + output format. */ +void +fmt_fix_output (struct fmt_spec *fmt) +{ + fmt_fix (fmt, false); +} /* Describes a display format. */ struct fmt_desc @@ -717,15 +773,16 @@ fmt_to_io (enum fmt_type type) bool fmt_from_io (int io, enum fmt_type *fmt_type) { - enum fmt_type type; - - for (type = 0; type < FMT_NUMBER_OF_FORMATS; type++) - if (get_fmt_desc (type)->io == io) - { - *fmt_type = type; - return true; - } - return false; + switch (io) + { +#define FMT(NAME, METHOD, IMIN, OMIN, IO, CATEGORY) \ + case IO: \ + *fmt_type = FMT_##NAME; \ + return true; +#include "format.def" + default: + return false; + } } /* Returns true if TYPE may be used as an input format, @@ -801,9 +858,7 @@ max_digits_for_bytes (int bytes) return map[bytes - 1]; } - - -void +static void fmt_number_style_init (struct fmt_number_style *style) { style->neg_prefix = ss_empty (); @@ -816,7 +871,7 @@ fmt_number_style_init (struct fmt_number_style *style) /* Destroys a struct fmt_number_style. */ -void +static void fmt_number_style_destroy (struct fmt_number_style *style) { if (style != NULL) @@ -923,3 +978,5 @@ get_fmt_desc (enum fmt_type type) assert (is_fmt_type (type)); return &formats[type]; } + +const struct fmt_spec F_8_0 = {FMT_F, 8, 0};