Import Upstream version 0.8.2
[platform/upstream/mpc.git] / tests / read_data.c
1 /* Read data file and check function.
2
3 Copyright (C) 2008, 2009, 2010 Andreas Enge, Philippe Th\'eveny
4
5 This file is part of the MPC Library.
6
7 The MPC Library is free software; you can redistribute it and/or modify
8 it under the terms of the GNU Lesser General Public License as published by
9 the Free Software Foundation; either version 2.1 of the License, or (at your
10 option) any later version.
11
12 The MPC Library is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
15 License for more details.
16
17 You should have received a copy of the GNU Lesser General Public License
18 along with the MPC Library; see the file COPYING.LIB.  If not, write to
19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
20 MA 02111-1307, USA. */
21
22 #include <stdlib.h>
23 #include <string.h>
24 #include "mpc-tests.h"
25
26 char *pathname;
27 unsigned long line_number;
28    /* file name with complete path and currently read line;
29       kept globally to simplify parameter passing */
30 unsigned long test_line_number;
31    /* start line of data test (which may extend over several lines) */
32 int nextchar;
33    /* character appearing next in the file, may be EOF */
34
35 #define MPC_INEX_CMP(r, i, c)                                 \
36   (((r) == TERNARY_NOT_CHECKED || (r) == MPC_INEX_RE(c))      \
37    && ((i) == TERNARY_NOT_CHECKED || (i) == MPC_INEX_IM (c)))
38
39 #define MPFR_INEX_STR(inex)                     \
40   (inex) == TERNARY_NOT_CHECKED ? "?"           \
41     : (inex) == +1 ? "+1"                       \
42     : (inex) == -1 ? "-1" : "0"
43
44 static const char *mpfr_rnd_mode [] =
45   { "GMP_RNDN", "GMP_RNDZ", "GMP_RNDU", "GMP_RNDD" };
46
47 const char *rnd_mode[] =
48   { "MPC_RNDNN", "MPC_RNDZN", "MPC_RNDUN", "MPC_RNDDN",
49     "undefined", "undefined", "undefined", "undefined", "undefined",
50     "undefined", "undefined", "undefined", "undefined", "undefined",
51     "undefined", "undefined",
52     "MPC_RNDNZ", "MPC_RNDZZ", "MPC_RNDUZ", "MPC_RNDDZ",
53     "undefined", "undefined", "undefined", "undefined", "undefined",
54     "undefined", "undefined", "undefined", "undefined", "undefined",
55     "undefined", "undefined",
56     "MPC_RNDNU", "MPC_RNDZU", "MPC_RNDUU", "MPC_RNDDU",
57     "undefined", "undefined", "undefined", "undefined", "undefined",
58     "undefined", "undefined", "undefined", "undefined", "undefined",
59     "undefined", "undefined",
60     "MPC_RNDND", "MPC_RNDZD", "MPC_RNDUD", "MPC_RNDDD",
61     "undefined", "undefined", "undefined", "undefined", "undefined",
62     "undefined", "undefined", "undefined", "undefined", "undefined",
63     "undefined", "undefined",
64   };
65
66 /* file functions */
67 FILE *
68 open_data_file (const char *file_name)
69 {
70   FILE *fp;
71   char *src_dir;
72   char default_srcdir[] = ".";
73
74   src_dir = getenv ("srcdir");
75   if (src_dir == NULL)
76     src_dir = default_srcdir;
77
78   pathname = (char *) malloc ((strlen (src_dir)) + strlen (file_name) + 2);
79   if (pathname == NULL)
80     {
81       printf ("Cannot allocate memory\n");
82       exit (1);
83     }
84   sprintf (pathname, "%s/%s", src_dir, file_name);
85   fp = fopen (pathname, "r");
86   if (fp == NULL)
87     {
88       fprintf (stderr, "Unable to open %s\n", pathname);
89       exit (1);
90     }
91
92   return fp;
93 }
94
95 void
96 close_data_file (FILE *fp)
97 {
98   free (pathname);
99   fclose (fp);
100 }
101
102 /* read primitives */
103 static void
104 skip_line (FILE *fp)
105    /* skips characters until reaching '\n' or EOF; */
106    /* '\n' is skipped as well                      */
107 {
108    while (nextchar != EOF && nextchar != '\n')
109      nextchar = getc (fp);
110    if (nextchar != EOF)
111      {
112        line_number ++;
113        nextchar = getc (fp);
114      }
115 }
116
117 static void
118 skip_whitespace (FILE *fp)
119    /* skips over whitespace if any until reaching EOF */
120    /* or non-whitespace                               */
121 {
122    while (isspace (nextchar))
123      {
124        if (nextchar == '\n')
125          line_number ++;
126        nextchar = getc (fp);
127      }
128 }
129
130 void
131 skip_whitespace_comments (FILE *fp)
132    /* skips over all whitespace and comments, if any */
133 {
134    skip_whitespace (fp);
135    while (nextchar == '#') {
136       skip_line (fp);
137       if (nextchar != EOF)
138          skip_whitespace (fp);
139    }
140 }
141
142
143 size_t
144 read_string (FILE *fp, char **buffer_ptr, size_t buffer_length, const char *name)
145 {
146   size_t pos;
147   char *buffer;
148
149   pos = 0;
150   buffer = *buffer_ptr;
151
152   if (nextchar == '"')
153     nextchar = getc (fp);
154   else
155     goto error;
156
157   while (nextchar != EOF && nextchar != '"')
158     {
159       if (nextchar == '\n')
160         line_number ++;
161       if (pos + 1 > buffer_length)
162         {
163           buffer = (char *) realloc (buffer, 2 * buffer_length);
164           if (buffer == NULL)
165             {
166               printf ("Cannot allocate memory\n");
167               exit (1);
168             }
169           buffer_length *= 2;
170         }
171       buffer[pos++] = nextchar;
172       nextchar = getc (fp);
173     }
174
175   if (nextchar != '"')
176     goto error;
177
178   if (pos + 1 > buffer_length)
179     {
180       buffer = (char *) realloc (buffer, buffer_length + 1);
181       if (buffer == NULL)
182         {
183           printf ("Cannot allocate memory\n");
184           exit (1);
185         }
186       buffer_length *= 2;
187     }
188   buffer[pos] = '\0';
189
190   nextchar = getc (fp);
191   skip_whitespace_comments (fp);
192
193   buffer_ptr = &buffer;
194
195   return buffer_length;
196
197  error:
198   printf ("Error: Unable to read %s in file '%s' line '%lu'\n",
199           name, pathname, line_number);
200   exit (1);
201 }
202
203 /* All following read routines skip over whitespace and comments; */
204 /* so after calling them, nextchar is either EOF or the beginning */
205 /* of a non-comment token.                                        */
206 void
207 read_ternary (FILE *fp, int* ternary)
208 {
209   switch (nextchar)
210     {
211     case '!':
212       *ternary = TERNARY_ERROR;
213       break;
214     case '?':
215       *ternary = TERNARY_NOT_CHECKED;
216       break;
217     case '+':
218       *ternary = +1;
219       break;
220     case '0':
221       *ternary = 0;
222       break;
223     case '-':
224       *ternary = -1;
225       break;
226     default:
227       printf ("Error: Unexpected ternary value '%c' in file '%s' line %lu\n",
228               nextchar, pathname, line_number);
229       exit (1);
230     }
231
232   nextchar = getc (fp);
233   skip_whitespace_comments (fp);
234 }
235
236 void
237 read_mpfr_rounding_mode (FILE *fp, mpfr_rnd_t* rnd)
238 {
239   switch (nextchar)
240     {
241     case 'n': case 'N':
242       *rnd = GMP_RNDN;
243       break;
244     case 'z': case 'Z':
245       *rnd = GMP_RNDZ;
246       break;
247     case 'u': case 'U':
248       *rnd = GMP_RNDU;
249       break;
250     case 'd': case 'D':
251       *rnd = GMP_RNDD;
252       break;
253     default:
254       printf ("Error: Unexpected rounding mode '%c' in file '%s' line %lu\n",
255               nextchar, pathname, line_number);
256       exit (1);
257     }
258
259     nextchar = getc (fp);
260     if (nextchar != EOF && !isspace (nextchar)) {
261       printf ("Error: Rounding mode not followed by white space in file "
262               "'%s' line %lu\n",
263               pathname, line_number);
264       exit (1);
265     }
266     skip_whitespace_comments (fp);
267 }
268
269 void
270 read_mpc_rounding_mode (FILE *fp, mpc_rnd_t* rnd)
271 {
272    mpfr_rnd_t re, im;
273    read_mpfr_rounding_mode (fp, &re);
274    read_mpfr_rounding_mode (fp, &im);
275    *rnd = RNDC (re, im);
276 }
277
278 void
279 read_int (FILE *fp, int *nread, const char *name)
280 {
281   int n = 0;
282
283   if (nextchar == EOF)
284     {
285       printf ("Error: Unexpected EOF when reading int "
286               "in file '%s' line %lu\n",
287               pathname, line_number);
288       exit (1);
289     }
290   ungetc (nextchar, fp);
291   n = fscanf (fp, "%i", nread);
292   if (ferror (fp) || n == 0 || n == EOF)
293     {
294       printf ("Error: Cannot read %s in file '%s' line %lu\n",
295               name, pathname, line_number);
296       exit (1);
297     }
298   nextchar = getc (fp);
299   skip_whitespace_comments (fp);
300 }
301
302 void
303 read_uint (FILE *fp, unsigned long int *ui)
304 {
305   int n = 0;
306
307   if (nextchar == EOF)
308     {
309       printf ("Error: Unexpected EOF when reading uint "
310               "in file '%s' line %lu\n",
311               pathname, line_number);
312       exit (1);
313     }
314   ungetc (nextchar, fp);
315   n = fscanf (fp, "%lu", ui);
316   if (ferror (fp) || n == 0 || n == EOF)
317     {
318       printf ("Error: Cannot read uint in file '%s' line %lu\n",
319               pathname, line_number);
320       exit (1);
321     }
322   nextchar = getc (fp);
323   skip_whitespace_comments (fp);
324 }
325
326 mpfr_prec_t
327 read_mpfr_prec (FILE *fp)
328 {
329    unsigned long prec;
330    int n;
331
332    if (nextchar == EOF) {
333       printf ("Error: Unexpected EOF when reading mpfr precision "
334               "in file '%s' line %lu\n",
335               pathname, line_number);
336       exit (1);
337    }
338    ungetc (nextchar, fp);
339    n = fscanf (fp, "%lu", &prec);
340    if (ferror (fp)) /* then also n == EOF */
341       perror ("Error when reading mpfr precision");
342    if (n == 0 || n == EOF || prec < MPFR_PREC_MIN || prec > MPFR_PREC_MAX) {
343       printf ("Error: Impossible mpfr precision in file '%s' line %lu\n",
344               pathname, line_number);
345       exit (1);
346    }
347    nextchar = getc (fp);
348    skip_whitespace_comments (fp);
349    return (mpfr_prec_t) prec;
350 }
351
352 static void
353 read_mpfr_mantissa (FILE *fp, mpfr_ptr x)
354 {
355    if (nextchar == EOF) {
356       printf ("Error: Unexpected EOF when reading mpfr mantissa "
357               "in file '%s' line %lu\n",
358               pathname, line_number);
359       exit (1);
360    }
361    ungetc (nextchar, fp);
362    if (mpfr_inp_str (x, fp, 0, GMP_RNDN) == 0) {
363       printf ("Error: Impossible to read mpfr mantissa "
364               "in file '%s' line %lu\n",
365               pathname, line_number);
366       exit (1);
367    }
368    nextchar = getc (fp);
369    skip_whitespace_comments (fp);
370 }
371
372 void
373 read_mpfr (FILE *fp, mpfr_ptr x, int *known_sign)
374 {
375    int sign;
376    mpfr_set_prec (x, read_mpfr_prec (fp));
377    sign = nextchar;
378    read_mpfr_mantissa (fp, x);
379
380    /* the sign always matters for regular values ('+' is implicit),
381       but when no sign appears before 0 or Inf in the data file, it means
382       that only absolute value must be checked. */
383    if (known_sign != NULL)
384      *known_sign =
385        (!mpfr_zero_p (x) && !mpfr_inf_p (x))
386        || sign == '+' || sign == '-';
387 }
388
389 void
390 read_mpc (FILE *fp, mpc_ptr z, known_signs_t *ks)
391 {
392   read_mpfr (fp, MPC_RE (z), ks == NULL ? NULL : &ks->re);
393   read_mpfr (fp, MPC_IM (z), ks == NULL ? NULL : &ks->im);
394 }
395
396 static void
397 check_compatible (int inex, mpfr_t expected, mpfr_rnd_t rnd, char *s)
398 {
399   if ((rnd == GMP_RNDU && inex == -1) ||
400       (rnd == GMP_RNDD && inex == +1) ||
401       (rnd == GMP_RNDZ && mpfr_signbit (expected) == 0 && inex == +1) ||
402       (rnd == GMP_RNDZ && mpfr_signbit (expected) == 1 && inex == -1))
403     {
404       if (s != NULL)
405         printf ("Incompatible ternary value '%c' (%s part) in file '%s' line %lu\n",
406               (inex == 1) ? '+' : '-', s, pathname, test_line_number);
407       else
408         printf ("Incompatible ternary value '%c' in file '%s' line %lu\n",
409               (inex == 1) ? '+' : '-', pathname, test_line_number);
410     }
411 }
412
413 /* read lines of data */
414 static void
415 read_cc (FILE *fp, int *inex_re, int *inex_im, mpc_ptr expected,
416          known_signs_t *signs, mpc_ptr op, mpc_rnd_t *rnd)
417 {
418   test_line_number = line_number;
419   read_ternary (fp, inex_re);
420   read_ternary (fp, inex_im);
421   read_mpc (fp, expected, signs);
422   read_mpc (fp, op, NULL);
423   read_mpc_rounding_mode (fp, rnd);
424   check_compatible (*inex_re, MPC_RE(expected), MPC_RND_RE(*rnd), "real");
425   check_compatible (*inex_im, MPC_IM(expected), MPC_RND_IM(*rnd), "imag");
426 }
427
428 static void
429 read_fc (FILE *fp, int *inex, mpfr_ptr expected, int *sign, mpc_ptr op,
430          mpfr_rnd_t *rnd)
431 {
432   test_line_number = line_number;
433   read_ternary (fp, inex);
434   read_mpfr (fp, expected, sign);
435   read_mpc (fp, op, NULL);
436   read_mpfr_rounding_mode (fp, rnd);
437   check_compatible (*inex, expected, *rnd, NULL);
438 }
439
440 static void
441 read_ccc (FILE *fp, int *inex_re, int *inex_im, mpc_ptr expected,
442           known_signs_t *signs, mpc_ptr op1, mpc_ptr op2, mpc_rnd_t *rnd)
443 {
444   test_line_number = line_number;
445   read_ternary (fp, inex_re);
446   read_ternary (fp, inex_im);
447   read_mpc (fp, expected, signs);
448   read_mpc (fp, op1, NULL);
449   read_mpc (fp, op2, NULL);
450   read_mpc_rounding_mode (fp, rnd);
451   check_compatible (*inex_re, MPC_RE(expected), MPC_RND_RE(*rnd), "real");
452   check_compatible (*inex_im, MPC_IM(expected), MPC_RND_IM(*rnd), "imag");
453 }
454
455 static void
456 read_cfc (FILE *fp, int *inex_re, int *inex_im, mpc_ptr expected,
457           known_signs_t *signs, mpfr_ptr op1, mpc_ptr op2, mpc_rnd_t *rnd)
458 {
459   test_line_number = line_number;
460   read_ternary (fp, inex_re);
461   read_ternary (fp, inex_im);
462   read_mpc (fp, expected, signs);
463   read_mpfr (fp, op1, NULL);
464   read_mpc (fp, op2, NULL);
465   read_mpc_rounding_mode (fp, rnd);
466   check_compatible (*inex_re, MPC_RE(expected), MPC_RND_RE(*rnd), "real");
467   check_compatible (*inex_im, MPC_IM(expected), MPC_RND_IM(*rnd), "imag");
468 }
469
470 static void
471 read_ccf (FILE *fp, int *inex_re, int *inex_im, mpc_ptr expected,
472           known_signs_t *signs, mpc_ptr op1, mpfr_ptr op2, mpc_rnd_t *rnd)
473 {
474   test_line_number = line_number;
475   read_ternary (fp, inex_re);
476   read_ternary (fp, inex_im);
477   read_mpc (fp, expected, signs);
478   read_mpc (fp, op1, NULL);
479   read_mpfr (fp, op2, NULL);
480   read_mpc_rounding_mode (fp, rnd);
481   check_compatible (*inex_re, MPC_RE(expected), MPC_RND_RE(*rnd), "real");
482   check_compatible (*inex_im, MPC_IM(expected), MPC_RND_IM(*rnd), "imag");
483 }
484
485 static void
486 read_ccu (FILE *fp, int *inex_re, int *inex_im, mpc_ptr expected,
487           known_signs_t *signs, mpc_ptr op1, unsigned long int *op2, mpc_rnd_t *rnd)
488 {
489   test_line_number = line_number;
490   read_ternary (fp, inex_re);
491   read_ternary (fp, inex_im);
492   read_mpc (fp, expected, signs);
493   read_mpc (fp, op1, NULL);
494   read_uint (fp, op2);
495   read_mpc_rounding_mode (fp, rnd);
496   check_compatible (*inex_re, MPC_RE(expected), MPC_RND_RE(*rnd), "real");
497   check_compatible (*inex_im, MPC_IM(expected), MPC_RND_IM(*rnd), "imag");
498 }
499
500 /* data_check (function, data_file_name) checks function results against
501  precomputed data in a file.*/
502 void
503 data_check (mpc_function function, const char *file_name)
504 {
505   FILE *fp;
506
507   int inex_re;
508   mpfr_t x1, x2;
509   mpfr_rnd_t mpfr_rnd = GMP_RNDN;
510   int sign_real;
511
512   int inex_im;
513   mpc_t z1, z2, z3, z4;
514   mpc_rnd_t rnd = MPC_RNDNN;
515
516   unsigned long int ui;
517
518   known_signs_t signs;
519   int inex = 0;
520
521   fp = open_data_file (file_name);
522
523   /* 1. init needed variables */
524   mpc_init2 (z1, 2);
525   switch (function.type)
526     {
527     case FC:
528       mpfr_init (x1);
529       mpfr_init (x2);
530       break;
531     case CC: case CCU:
532       mpc_init2 (z2, 2);
533       mpc_init2 (z3, 2);
534       break;
535     case CCC:
536       mpc_init2 (z2, 2);
537       mpc_init2 (z3, 2);
538       mpc_init2 (z4, 2);
539       break;
540     case CFC: case CCF:
541       mpfr_init (x1);
542       mpc_init2 (z2, 2);
543       mpc_init2 (z3, 2);
544       break;
545     default:
546       ;
547     }
548
549   /* 2. read data file */
550   line_number = 1;
551   nextchar = getc (fp);
552   skip_whitespace_comments (fp);
553   while (nextchar != EOF) {
554       /* for each kind of function prototype: */
555       /* 3.1 read a line of data: expected result, parameters, rounding mode */
556       /* 3.2 compute function at the same precision as the expected result */
557       /* 3.3 compare this result with the expected one */
558       switch (function.type)
559         {
560         case FC: /* example mpc_norm */
561           read_fc (fp, &inex_re, x1, &sign_real, z1, &mpfr_rnd);
562           mpfr_set_prec (x2, MPFR_PREC (x1));
563           inex = function.pointer.FC (x2, z1, mpfr_rnd);
564           if ((inex_re != TERNARY_NOT_CHECKED && inex_re != inex)
565               || !same_mpfr_value (x1, x2, sign_real))
566             {
567               mpfr_t got, expected;
568               mpc_t op;
569               op[0] = z1[0];
570               got[0] = x2[0];
571               expected[0] = x1[0];
572               printf ("%s(op) failed (%s:%lu)\nwith rounding mode %s\n",
573                       function.name, file_name, test_line_number,
574                       mpfr_rnd_mode[mpfr_rnd]);
575               if (inex_re != TERNARY_NOT_CHECKED && inex_re != inex)
576                 printf("ternary value: got %s, expected %s\n",
577                        MPFR_INEX_STR (inex), MPFR_INEX_STR (inex_re));
578               OUT (op);
579               printf ("     ");
580               MPFR_OUT (got);
581               MPFR_OUT (expected);
582
583               exit (1);
584             }
585           break;
586
587         case CC: /* example mpc_log */
588           read_cc (fp, &inex_re, &inex_im, z1, &signs, z2, &rnd);
589           mpfr_set_prec (MPC_RE (z3), MPC_PREC_RE (z1));
590           mpfr_set_prec (MPC_IM (z3), MPC_PREC_IM (z1));
591           inex = function.pointer.CC (z3, z2, rnd);
592           if (!MPC_INEX_CMP (inex_re, inex_im, inex)
593               || !same_mpc_value (z3, z1, signs))
594             {
595               mpc_t op, got, expected; /* display sensible variable names */
596               op[0] = z2[0];
597               expected[0]= z1[0];
598               got[0] = z3[0];
599               printf ("%s(op) failed (line %lu)\nwith rounding mode %s\n",
600                       function.name, test_line_number, rnd_mode[rnd]);
601               if (!MPC_INEX_CMP (inex_re, inex_im, inex))
602                 printf("ternary value: got %s, expected (%s, %s)\n",
603                        MPC_INEX_STR (inex),
604                        MPFR_INEX_STR (inex_re), MPFR_INEX_STR (inex_im));
605               OUT (op);
606               printf ("     ");
607               OUT (got);
608               OUT (expected);
609
610               exit (1);
611             }
612           break;
613
614         case CCC: /* example mpc_mul */
615           read_ccc (fp, &inex_re, &inex_im, z1, &signs, z2, z3, &rnd);
616           mpfr_set_prec (MPC_RE(z4), MPC_PREC_RE (z1));
617           mpfr_set_prec (MPC_IM(z4), MPC_PREC_IM (z1));
618           inex = function.pointer.CCC (z4, z2, z3, rnd);
619           if (!MPC_INEX_CMP (inex_re, inex_im, inex)
620               || !same_mpc_value (z4, z1, signs))
621             {
622               /* display sensible variable names */
623               mpc_t op1, op2, got, expected;
624               op1[0] = z2[0];
625               op2[0] = z3[0];
626               expected[0]= z1[0];
627               got[0] = z4[0];
628               printf ("%s(op) failed (line %lu)\nwith rounding mode %s\n",
629                       function.name, test_line_number, rnd_mode[rnd]);
630               if (!MPC_INEX_CMP (inex_re, inex_im, inex))
631                 printf("ternary value: got %s, expected (%s, %s)\n",
632                        MPC_INEX_STR (inex),
633                        MPFR_INEX_STR (inex_re), MPFR_INEX_STR (inex_im));
634               OUT (op1);
635               OUT (op2);
636               printf ("     ");
637               OUT (got);
638               OUT (expected);
639
640               exit (1);
641             }
642           if (function.properties & FUNC_PROP_SYMETRIC)
643             {
644               inex = function.pointer.CCC (z4, z3, z2, rnd);
645               if (!MPC_INEX_CMP (inex_re, inex_im, inex)
646               || !same_mpc_value (z4, z1, signs))
647                 {
648                   /* display sensible variable names */
649                   mpc_t op1, op2, got, expected;
650                   op1[0] = z3[0];
651                   op2[0] = z2[0];
652                   expected[0]= z1[0];
653                   got[0] = z4[0];
654                   printf ("%s(op) failed (line %lu/symetric test)\n"
655                           "with rounding mode %s\n",
656                           function.name, test_line_number, rnd_mode[rnd]);
657                   if (!MPC_INEX_CMP (inex_re, inex_im, inex))
658                     printf("ternary value: got %s, expected (%s, %s)\n",
659                            MPC_INEX_STR (inex),
660                            MPFR_INEX_STR (inex_re), MPFR_INEX_STR (inex_im));
661                   OUT (op1);
662                   OUT (op2);
663                   printf ("     ");
664                   OUT (got);
665                   OUT (expected);
666
667                   exit (1);
668                 }
669             }
670           break;
671
672         case CFC: /* example mpc_fr_div */
673           read_cfc (fp, &inex_re, &inex_im, z1, &signs, x1, z2, &rnd);
674           mpfr_set_prec (MPC_RE(z3), MPC_PREC_RE (z1));
675           mpfr_set_prec (MPC_IM(z3), MPC_PREC_IM (z1));
676           inex = function.pointer.CFC (z3, x1, z2, rnd);
677           if (!MPC_INEX_CMP (inex_re, inex_im, inex)
678               || !same_mpc_value (z3, z1, signs))
679             {
680               /* display sensible variable names */
681               mpc_t op2, got, expected;
682               mpfr_t op1;
683               op1[0] = x1[0];
684               op2[0] = z2[0];
685               expected[0]= z1[0];
686               got[0] = z3[0];
687               printf ("%s(op) failed (line %lu)\nwith rounding mode %s\n",
688                       function.name, test_line_number, rnd_mode[rnd]);
689               if (!MPC_INEX_CMP (inex_re, inex_im, inex))
690                 printf("ternary value: got %s, expected (%s, %s)\n",
691                        MPC_INEX_STR (inex),
692                        MPFR_INEX_STR (inex_re), MPFR_INEX_STR (inex_im));
693               MPFR_OUT (op1);
694               OUT (op2);
695               printf ("     ");
696               OUT (got);
697               OUT (expected);
698
699               exit (1);
700             }
701           break;
702
703         case CCF: /* example mpc_mul_fr */
704           read_ccf (fp, &inex_re, &inex_im, z1, &signs, z2, x1, &rnd);
705           mpfr_set_prec (MPC_RE(z3), MPC_PREC_RE (z1));
706           mpfr_set_prec (MPC_IM(z3), MPC_PREC_IM (z1));
707           inex = function.pointer.CCF (z3, z2, x1, rnd);
708           if (!MPC_INEX_CMP (inex_re, inex_im, inex)
709               || !same_mpc_value (z3, z1, signs))
710             {
711               /* display sensible variable names */
712               mpc_t op1, got, expected;
713               mpfr_t op2;
714               op1[0] = z2[0];
715               op2[0] = x1[0];
716               expected[0]= z1[0];
717               got[0] = z3[0];
718               printf ("%s(op) failed (line %lu)\nwith rounding mode %s\n",
719                       function.name, test_line_number, rnd_mode[rnd]);
720               if (!MPC_INEX_CMP (inex_re, inex_im, inex))
721                 printf("ternary value: got %s, expected (%s, %s)\n",
722                        MPC_INEX_STR (inex),
723                        MPFR_INEX_STR (inex_re), MPFR_INEX_STR (inex_im));
724               OUT (op1);
725               MPFR_OUT (op2);
726               printf ("     ");
727               OUT (got);
728               OUT (expected);
729
730               exit (1);
731             }
732           break;
733
734         case CCU: /* example mpc_pow_ui */
735           read_ccu (fp, &inex_re, &inex_im, z1, &signs, z2, &ui, &rnd);
736           mpfr_set_prec (MPC_RE(z3), MPC_PREC_RE (z1));
737           mpfr_set_prec (MPC_IM(z3), MPC_PREC_IM (z1));
738           inex = function.pointer.CCU (z3, z2, ui, rnd);
739           if (!MPC_INEX_CMP (inex_re, inex_im, inex)
740               || !same_mpc_value (z3, z1, signs))
741             {
742               /* display sensible variable names */
743               mpc_t op1, got, expected;
744               op1[0] = z2[0];
745               expected[0]= z1[0];
746               got[0] = z3[0];
747               printf ("%s(op) failed (line %lu)\nwith rounding mode %s\n",
748                       function.name, test_line_number, rnd_mode[rnd]);
749               if (!MPC_INEX_CMP (inex_re, inex_im, inex))
750                 printf("ternary value: got %s, expected (%s, %s)\n",
751                        MPC_INEX_STR (inex),
752                        MPFR_INEX_STR (inex_re), MPFR_INEX_STR (inex_im));
753               OUT (op1);
754               printf ("op2 %lu\n     ", ui);
755               OUT (got);
756               OUT (expected);
757
758               exit (1);
759             }
760           break;
761
762         default:
763           ;
764         }
765     }
766
767   /* 3. Clear used variables */
768   mpc_clear (z1);
769   switch (function.type)
770     {
771     case FC:
772       mpfr_clear (x1);
773       mpfr_clear (x2);
774       break;
775     case CC: case CCU:
776       mpc_clear (z2);
777       mpc_clear (z3);
778       break;
779     case CCC:
780       mpc_clear (z2);
781       mpc_clear (z3);
782       mpc_clear (z4);
783       break;
784     case CFC: case CCF:
785       mpfr_clear (x1);
786       mpc_clear (z2);
787       mpc_clear (z3);
788       break;
789     default:
790       ;
791     }
792
793   close_data_file (fp);
794 }