[PATCHv3,1/3] Refactor tst-strtod-round.c

Message ID bc4fe14cc1086e590ea4f86f6e1522a38f29f53b.1464041464.git.murphyp@linux.vnet.ibm.com
State Committed
Headers

Commit Message

Paul E. Murphy May 23, 2016, 10:18 p.m. UTC
  This file is partially generated.  To make updates a little
simpler, I have moved the generated code into a partially
contained header to simplify regeneration.

gen-tst-strtod-round.c now takes two, mandatory arguments.
These arguments specify the input test data and the output
destination, respectively.

NOTE: I've stripped the changes to tst-strtod-round.c and
tst-strtod-round-data.h.  You will need to manually remove
the test object, and replace it with:

/* Include the generated test data.  */
#include "tst-strtod-round-data.h"

	* stdlib/gen-tst-strtod-round.c (main):
	  Change usage to more closely match the generated
	  output.  Add usage and compilation instructions.
	  (string_to_fp): Add and use FILE* parameter as
	  output target.
	  (print_fp): Likewise.
	  (round_str): Likewise.
	  (round_for_all): Likewise.
	* stdlib/tst-strtod-round.c (tests): Move into
	* stdlib/tst-strtod-round-data.h: New file.
---
 stdlib/gen-tst-strtod-round.c  |    86 +-
 stdlib/tst-strtod-round-data.h | 12334 ++++++++++++++++++++++++++++++++++++++
 stdlib/tst-strtod-round.c      | 12338 +--------------------------------------
 3 files changed, 12401 insertions(+), 12357 deletions(-)
 create mode 100644 stdlib/tst-strtod-round-data.h
  

Comments

Joseph Myers May 24, 2016, 3:12 p.m. UTC | #1
On Mon, 23 May 2016, Paul E. Murphy wrote:

> +  char *fin_name = argv[1];
> +  char *fout_name = argv[2];
> +
> +  if (argc < 3)
> +    {
> +      fprintf (stderr, "Usage: %s [input] [output]\n", basename (argv[0]));
> +      return EXIT_FAILURE;
> +    }

The check for argc < 3 should take place before you access argv[1] and 
argv[2] (if no arguments are passed, argv[2] doesn't exist).  And you 
shouldn't have [] around "input" and "output" in the message since that 
suggests they are optional, which they aren't (cf. gen-auto-libm-tests 
using <>).

OK with those changes.
  
Paul E. Murphy May 24, 2016, 7:44 p.m. UTC | #2
On 05/24/2016 10:12 AM, Joseph Myers wrote:
> On Mon, 23 May 2016, Paul E. Murphy wrote:
> 
>> +  char *fin_name = argv[1];
>> +  char *fout_name = argv[2];
>> +
>> +  if (argc < 3)
>> +    {
>> +      fprintf (stderr, "Usage: %s [input] [output]\n", basename (argv[0]));
>> +      return EXIT_FAILURE;
>> +    }
> 
> The check for argc < 3 should take place before you access argv[1] and 
> argv[2] (if no arguments are passed, argv[2] doesn't exist).  And you 
> shouldn't have [] around "input" and "output" in the message since that 
> suggests they are optional, which they aren't (cf. gen-auto-libm-tests 
> using <>).
> 
> OK with those changes.
> 

Requested changes made.  Pushed as 118fbf0.
  

Patch

diff --git a/stdlib/gen-tst-strtod-round.c b/stdlib/gen-tst-strtod-round.c
index 3ef4506..26c2ec2 100644
--- a/stdlib/gen-tst-strtod-round.c
+++ b/stdlib/gen-tst-strtod-round.c
@@ -17,11 +17,25 @@ 
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
+/* Compile this program as:
+
+   gcc -std=gnu11 -O2 -Wall -Wextra gen-tst-strtod-round.c -lmpfr
+     -o gen-tst-strtod-round
+
+   (use of current MPFR version recommended) and run it as:
+
+   gen-tst-strtod-round tst-strtod-round-data tst-strtod-round-data.h
+
+   The output file will be generated as tst-strtod-round-data.h
+*/
+
+
 #define _GNU_SOURCE
 #include <assert.h>
 #include <stdbool.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <string.h>
 #include <mpfr.h>
 
 /* Work around incorrect ternary value from mpfr_strtofr
@@ -47,16 +61,17 @@  string_to_fp (mpfr_t f, const char *s, mpfr_rnd_t rnd)
 }
 
 static void
-print_fp (mpfr_t f, const char *suffix, const char *suffix2)
+print_fp (FILE *fout, mpfr_t f, const char *suffix, const char *suffix2)
 {
   if (mpfr_inf_p (f))
-    mpfr_printf ("\t%sINFINITY%s", mpfr_signbit (f) ? "-" : "", suffix2);
+    mpfr_fprintf (fout, "\t%sINFINITY%s", mpfr_signbit (f) ? "-" : "",
+		  suffix2);
   else
-    mpfr_printf ("\t%Ra%s%s", f, suffix, suffix2);
+    mpfr_fprintf (fout, "\t%Ra%s%s", f, suffix, suffix2);
 }
 
 static void
-round_str (const char *s, const char *suffix,
+round_str (FILE *fout, const char *s, const char *suffix,
 	   int prec, int emin, int emax, bool ibm_ld)
 {
   mpfr_t f;
@@ -78,19 +93,19 @@  round_str (const char *s, const char *suffix,
 	r = 1;
       mpfr_clear (max_value);
     }
-  mpfr_printf ("\t%s,\n", r ? "false" : "true");
-  print_fp (f, suffix, ",\n");
+  mpfr_fprintf (fout, "\t%s,\n", r ? "false" : "true");
+  print_fp (fout, f, suffix, ",\n");
   string_to_fp (f, s, MPFR_RNDN);
-  print_fp (f, suffix, ",\n");
+  print_fp (fout, f, suffix, ",\n");
   string_to_fp (f, s, MPFR_RNDZ);
-  print_fp (f, suffix, ",\n");
+  print_fp (fout, f, suffix, ",\n");
   string_to_fp (f, s, MPFR_RNDU);
-  print_fp (f, suffix, "");
+  print_fp (fout, f, suffix, "");
   mpfr_clear (f);
 }
 
 static void
-round_for_all (const char *s)
+round_for_all (FILE *fout, const char *s)
 {
   static const struct fmt {
     const char *suffix;
@@ -109,39 +124,68 @@  round_for_all (const char *s)
     { "L", 106, -1073, 1024, true },
     { "L", 113, -16493, 16384, false },
   };
-  mpfr_printf ("  TEST (\"");
+  mpfr_fprintf (fout, "  TEST (\"");
   const char *p;
   for (p = s; *p; p++)
     {
-      putchar (*p);
+      fputc (*p, fout);
       if ((p - s) % 60 == 59 && p[1])
-	mpfr_printf ("\"\n\t\"");
+	mpfr_fprintf (fout, "\"\n\t\"");
     }
-  mpfr_printf ("\",\n");
+  mpfr_fprintf (fout, "\",\n");
   int i;
   for (i = 0; i < 7; i++)
     {
-      round_str (s, formats[i].suffix, formats[i].prec,
+      round_str (fout, s, formats[i].suffix, formats[i].prec,
 		 formats[i].emin, formats[i].emax, formats[i].ibm_ld);
       if (i < 6)
-	mpfr_printf (",\n");
+	mpfr_fprintf (fout, ",\n");
     }
-  mpfr_printf ("),\n");
+  mpfr_fprintf (fout, "),\n");
 }
 
 int
-main (void)
+main (int argc, char **argv)
 {
   char *p = NULL;
   size_t len;
   ssize_t nbytes;
-  while ((nbytes = getline (&p, &len, stdin)) != -1)
+  FILE *fin, *fout;
+  char *fin_name = argv[1];
+  char *fout_name = argv[2];
+
+  if (argc < 3)
+    {
+      fprintf (stderr, "Usage: %s [input] [output]\n", basename (argv[0]));
+      return EXIT_FAILURE;
+    }
+
+  fin = fopen (fin_name, "r");
+  if (fin == NULL)
+    {
+      perror ("Could not open input for reading");
+      return EXIT_FAILURE;
+    }
+
+  fout = fopen (fout_name, "w");
+  if (fout == NULL)
+    {
+      perror ("Could not open output for writing");
+      return EXIT_FAILURE;
+    }
+
+  fprintf (fout, "/* This file was generated by %s from %s.  */\n",
+	  __FILE__, fin_name);
+  fputs ("static const struct test tests[] = {\n", fout);
+  while ((nbytes = getline (&p, &len, fin)) != -1)
     {
       if (p[nbytes - 1] == '\n')
 	p[nbytes - 1] = 0;
-      round_for_all (p);
+      round_for_all (fout, p);
       free (p);
       p = NULL;
     }
-  return 0;
+  fputs ("};\n", fout);
+
+  return EXIT_SUCCESS;
 }