format: Make fmt_number_style_init(), fmt_number_style_destroy() static.
[pspp] / src / data / format.c
index a319a182ccf7fb14ef3dba0abe94ea03a56910b7..5fe620b8b0425c224ea4f17a095dbef90d1e857f 100644 (file)
@@ -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);
+}
 \f
 /* 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];
 }
 \f
-
-
-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};