summaryrefslogtreecommitdiff
path: root/tests/templates.h
blob: 404ca0f803ee93c71fe7559b7590278681b83748 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
/* templates.h -- Templated parameters functions.

Copyright (C) 2012, 2013 INRIA

This file is part of GNU MPC.

GNU MPC is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser General Public License as published by the
Free Software Foundation; either version 3 of the License, or (at your
option) any later version.

GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
more details.

You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see http://www.gnu.org/licenses/ .
*/

#ifndef __TEMPLATES_H
#define __TEMPLATES_H

#include <stdio.h>
#include <stdlib.h>
#include "config.h"
#include "mpc-tests.h"

/*
  function descriptions
*/

/* type for return, output and input parameters */
typedef enum {
  NATIVE_INT,          /* int */
  NATIVE_UL,           /* unsigned long */
  NATIVE_L,            /* signed long */
  NATIVE_D,            /* double */
  NATIVE_LD,           /* long double */
  NATIVE_DC,           /* double _Complex */
  NATIVE_LDC,          /* long double _Complex */
  NATIVE_IM,           /* intmax_t */
  NATIVE_UIM,          /* uintmax_t */
  NATIVE_STRING,       /* char* */
  GMP_Z,               /* mpz_t */
  GMP_Q,               /* mpq_t */
  GMP_F,               /* mpf_t */
  MPFR_INEX,           /* mpfr_inex */
  MPFR,                /* mpfr_t  */
  MPFR_RND,            /* mpfr_rnd_t */
  MPC_INEX,            /* mpc_inex */
  MPC,                 /* mpc_t */
  MPC_RND              /* mpc_rnd_t */
} mpc_param_t;

/* additional information for checking mpfr_t result */
typedef struct {
  mpfr_t              mpfr; /* skip space for the variable */
  int                 known_sign;
} mpfr_data_t;

#define TERNARY_NOT_CHECKED 255
/* special value to indicate that the ternary value is not checked */
#define TERNARY_ERROR 254
/* special value to indicate that an error occurred in an mpc function */

/* mpc nonary value as a pair of ternary value for data from a file */
typedef struct {
  int                real;
  int                imag;
} mpc_inex_data_t;

/* additional information for checking mpc_t result */
typedef struct {
  mpc_t               mpc; /* skip space */
  int                 known_sign_real;
  int                 known_sign_imag;
} mpc_data_t;

/* string buffer information */
typedef struct {
  char*               string; /* skip space */
  int                 length;
} string_info_t;

/* abstract parameter type

   Let consider an abstract parameter p, which is declared as follows:
   mpc_operand_t p;
   we use the fact that a mpfr_t (respectively mpc_t) value can be accessed as
   'p.mpfr' (resp. 'p.mpc') as well as 'p.mpfr_info.mpfr'
   (resp. 'p.mpc_info.mpc'), the latter form permitting access to the
   'known_sign' field(s).
   Similarly, if the abstract parameter represent a string variable, we can
   access its value with 'p.string' or 'p.string_info.string' and its size
   with 'p.string_info.length'.

   The user uses the simple form when adding a test, the second form is used by the
   test suite itself when reading reference data and checking result against them.
*/
typedef union {
  int                  i;
  unsigned long        ui;
  signed long          si;
  double               d;
  long double          ld;
#ifdef _MPC_H_HAVE_INTMAX_T
  intmax_t             im;
  uintmax_t            uim;
#endif
#ifdef _Complex_I
  double _Complex      dc;
  long double _Complex ldc;
#endif
  char *               string;
  string_info_t        string_info;
  mpz_t                mpz;
  mpq_t                mpq;
  mpf_t                mpf;
  mpfr_t               mpfr;
  mpfr_data_t          mpfr_data;
  mpfr_rnd_t           mpfr_rnd;
  int                  mpfr_inex;
  mpc_t                mpc;
  mpc_data_t           mpc_data;
  mpc_rnd_t            mpc_rnd;
  int                  mpc_inex;
  mpc_inex_data_t      mpc_inex_data;
} mpc_operand_t;

#define PARAMETER_ARRAY_SIZE 10

/* function name plus parameters */
typedef struct {
  char         *name;  /* name of the function */
  int           nbout; /* number of output parameters */
  int           nbin;  /* number of input parameters */
  mpc_operand_t P[PARAMETER_ARRAY_SIZE]; /* value of parameters */
  mpc_param_t   T[PARAMETER_ARRAY_SIZE]; /* type of parameters */
} mpc_fun_param_t;


void        read_description    (mpc_fun_param_t* param, const char *file);
const char* read_description_findname (mpc_param_t e);

/* file functions */
typedef struct {
  char *pathname;
  FILE *fd;
  unsigned long line_number;
  unsigned long test_line_number;
  int nextchar;
} mpc_datafile_context_t;

void    open_datafile       (mpc_datafile_context_t* datafile_context,
                             const char * data_filename);
void    close_datafile      (mpc_datafile_context_t *dc);

/* data file functions */
void    read_line           (mpc_datafile_context_t* datafile_context,
                             mpc_fun_param_t* params);
void    check_data          (mpc_datafile_context_t* datafile_context,
                             mpc_fun_param_t* params,
                             int index_reused_operand);

/* parameters templated functions */
int     data_check_template (const char* descr_file, const char * data_file);

void    init_parameters     (mpc_fun_param_t *params);
void    clear_parameters    (mpc_fun_param_t *params);
void    print_parameter     (mpc_fun_param_t *params, int index);
int     copy_parameter      (mpc_fun_param_t *params,
                             int index_dest, int index_src);

void    tpl_read_int        (mpc_datafile_context_t* datafile_context,
                             int *nread, const char *name);
void    tpl_read_ui         (mpc_datafile_context_t* datafile_context,
                             unsigned long int *ui);
void    tpl_read_si         (mpc_datafile_context_t* datafile_context,
                             long int *si);
void    tpl_read_mpz        (mpc_datafile_context_t* datafile_context,
                             mpz_t z);
void    tpl_skip_whitespace_comments (mpc_datafile_context_t* datafile_context);
void    tpl_read_ternary    (mpc_datafile_context_t* datafile_context,
                             int* ternary);
void    tpl_read_mpfr       (mpc_datafile_context_t* datafile_context,
                             mpfr_ptr x, int* known_sign);
void    tpl_read_mpfr_rnd   (mpc_datafile_context_t* datafile_context,
                             mpfr_rnd_t* rnd);
void    tpl_read_mpfr_inex  (mpc_datafile_context_t* datafile_context,
                             int *ternary);
void    tpl_read_mpc_inex   (mpc_datafile_context_t* datafile_context,
                             mpc_inex_data_t* ternarypair);
void    tpl_read_mpc        (mpc_datafile_context_t* datafile_context,
                             mpc_data_t* z);
void    tpl_read_mpc_rnd    (mpc_datafile_context_t* datafile_context,
                             mpc_rnd_t* rnd);

int     tpl_same_mpz_value  (mpz_ptr n1, mpz_ptr n2);
int     tpl_same_mpfr_value (mpfr_ptr x1, mpfr_ptr x2, int known_sign);
int     tpl_check_mpfr_data (mpfr_t got, mpfr_data_t expected);
int     tpl_check_mpc_data  (mpc_ptr got, mpc_data_t expected);

void    tpl_copy_int        (int *dest, const int * const src);
void    tpl_copy_ui         (unsigned long int *dest,
                             const unsigned long int * const src);
void    tpl_copy_si         (long int *dest, const long int * const src);
void    tpl_copy_d          (double *dest, const double * const src);
void    tpl_copy_mpz        (mpz_ptr dest, mpz_srcptr src);
void    tpl_copy_mpfr       (mpfr_ptr dest, mpfr_srcptr src);
void    tpl_copy_mpc        (mpc_ptr dest, mpc_srcptr src);

int     double_rounding     (mpc_fun_param_t *params);

/* iterating over rounding modes */
void    first_rnd_mode      (mpc_fun_param_t *params);
int     is_valid_rnd_mode   (mpc_fun_param_t *params);
void    next_rnd_mode       (mpc_fun_param_t *params);

/* parameter precision */
void    set_output_precision    (mpc_fun_param_t *params, mpfr_prec_t prec);
void    set_input_precision     (mpc_fun_param_t *params, mpfr_prec_t prec);
void    set_reference_precision (mpc_fun_param_t *params, mpfr_prec_t prec);

#endif /*__TEMPLATES_H*/