From: Ben Pfaff <blp@gnu.org>
Date: Wed, 5 Mar 2008 05:53:46 +0000 (+0000)
Subject: Patch #6441.  Reviewed by John Darrington.
X-Git-Tag: v0.6.0~79
X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4e13be9f4b4beb036e6f3aa662eb80b60761b082;p=pspp-builds.git

Patch #6441.  Reviewed by John Darrington.

(fmt_fix): New function.
(fmt_fix_input): New function.
(fmt_fix_output): New function.
---

diff --git a/src/data/ChangeLog b/src/data/ChangeLog
index 9c68bb3b..bb4d7414 100644
--- a/src/data/ChangeLog
+++ b/src/data/ChangeLog
@@ -1,3 +1,11 @@
+2008-03-04  Ben Pfaff  <blp@gnu.org>
+
+	Patch #6441.  Reviewed by John Darrington.
+
+	* format.c (fmt_fix): New function.
+	(fmt_fix_input): New function.
+	(fmt_fix_output): New function.
+
 2008-02-18  Ben Pfaff  <blp@gnu.org>
 
 	Patch #6426.  Reviewed by John Darrington.
diff --git a/src/data/format.c b/src/data/format.c
index a319a182..ecf41487 100644
--- a/src/data/format.c
+++ b/src/data/format.c
@@ -408,6 +408,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
diff --git a/src/data/format.h b/src/data/format.h
index 0bb8a60b..15d13ef9 100644
--- a/src/data/format.h
+++ b/src/data/format.h
@@ -110,6 +110,10 @@ char *fmt_to_string (const struct fmt_spec *, char s[FMT_STRING_LEN_MAX + 1]);
 bool fmt_equal (const struct fmt_spec *, const struct fmt_spec *);
 void fmt_resize (struct fmt_spec *, int new_width);
 
+void fmt_fix (struct fmt_spec *, bool for_input);
+void fmt_fix_input (struct fmt_spec *);
+void fmt_fix_output (struct fmt_spec *);
+
 /* Format types. */
 const char *fmt_name (enum fmt_type) PURE_FUNCTION;
 bool fmt_from_name (const char *name, enum fmt_type *);