1 /* read_line.c -- Read line of test data in file.
2
3 Copyright (C) 2012, 2013, 2014 INRIA
4
5 This file is part of GNU MPC.
6
7 GNU MPC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU Lesser General Public License as published by the
9 Free Software Foundation; either version 3 of the License, or (at your
10 option) any later version.
11
12 GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
15 more details.
16
17 You should have received a copy of the GNU Lesser General Public License
18 along with this program. If not, see http://www.gnu.org/licenses/ .
19 */
20
21 #include "mpc-tests.h"
22
23 static void
read_param(mpc_datafile_context_t * datafile_context,mpc_operand_t * p,mpc_param_t t)24 read_param (mpc_datafile_context_t* datafile_context,
25 mpc_operand_t* p, mpc_param_t t)
26 {
27 switch (t)
28 {
29 case NATIVE_INT:
30 tpl_read_int (datafile_context, &(p->i),"");
31 return;
32 case NATIVE_UL:
33 tpl_read_ui (datafile_context, &(p->ui));
34 return;
35 case NATIVE_L:
36 tpl_read_si (datafile_context, &(p->si));
37 return;
38
39 case NATIVE_D:
40 case NATIVE_LD:
41 /* TODO */
42 fprintf (stderr, "read_param: type not implemented.\n");
43 exit (1);
44 break;
45
46 case NATIVE_DC:
47 case NATIVE_LDC:
48 #ifdef _Complex_I
49 /* TODO */
50 fprintf (stderr, "read_param: type not implemented.\n");
51 exit (1);
52 #endif
53 break;
54
55 case NATIVE_IM:
56 case NATIVE_UIM:
57 #ifdef _MPC_H_HAVE_INTMAX_T
58 /* TODO */
59 fprintf (stderr, "read_param: type not implemented.\n");
60 exit (1);
61 #endif
62 break;
63
64 case NATIVE_STRING:
65 /* TODO */
66 fprintf (stderr, "read_param: type not implemented.\n");
67 exit (1);
68 break;
69
70 case GMP_Z:
71 tpl_read_mpz (datafile_context, p->mpz);
72 return;
73
74 case GMP_Q:
75 case GMP_F:
76 /* TODO */
77 fprintf (stderr, "read_param: type not implemented.\n");
78 exit (1);
79 break;
80
81 case MPFR_INEX:
82 tpl_read_mpfr_inex (datafile_context, &p->mpfr_inex);
83 return;
84 case MPFR:
85 tpl_read_mpfr (datafile_context,
86 p->mpfr_data.mpfr, &p->mpfr_data.known_sign);
87 return;
88 case MPFR_RND:
89 tpl_read_mpfr_rnd (datafile_context, &p->mpfr_rnd);
90 return;
91
92 case MPC_INEX:
93 tpl_read_mpc_inex (datafile_context, &p->mpc_inex_data);
94 return;
95 case MPC:
96 tpl_read_mpc (datafile_context, &p->mpc_data);
97 return;
98 case MPC_RND:
99 tpl_read_mpc_rnd (datafile_context, &p->mpc_rnd);
100 return;
101
102 case MPCC_INEX:
103 /* TODO */
104 fprintf (stderr, "read_param: type not implemented.\n");
105 exit (1);
106 break;
107 }
108
109 fprintf (stderr, "read_param: unsupported type.\n");
110 exit (1);
111 }
112
113 static void
set_precision(mpc_fun_param_t * params,int index)114 set_precision (mpc_fun_param_t* params, int index)
115 {
116 /* set output precision to reference precision */
117 int index_ref = index + params->nbout + params->nbin;
118
119 switch (params->T[index])
120 {
121 case MPFR:
122 mpfr_set_prec (params->P[index].mpfr,
123 mpfr_get_prec (params->P[index_ref].mpfr));
124 return;
125
126 case MPC:
127 mpfr_set_prec (mpc_realref (params->P[index].mpc),
128 MPC_PREC_RE (params->P[index_ref].mpc));
129 mpfr_set_prec (mpc_imagref (params->P[index].mpc),
130 MPC_PREC_IM (params->P[index_ref].mpc));
131 return;
132
133 case NATIVE_INT:
134 case NATIVE_UL: case NATIVE_L:
135 case NATIVE_D: case NATIVE_LD:
136 case NATIVE_DC: case NATIVE_LDC:
137 case NATIVE_IM: case NATIVE_UIM:
138 case NATIVE_STRING:
139 case GMP_Z: case GMP_Q:
140 case GMP_F:
141 case MPFR_INEX: case MPFR_RND:
142 case MPC_INEX: case MPC_RND:
143 case MPCC_INEX:
144 /* unsupported types */
145 break;
146 }
147
148 fprintf (stderr, "set_precision: unsupported type.\n");
149 exit (1);
150 }
151
152 void
read_line(mpc_datafile_context_t * datafile_context,mpc_fun_param_t * params)153 read_line (mpc_datafile_context_t* datafile_context,
154 mpc_fun_param_t* params)
155 {
156 int in, out;
157 int total = params->nbout + params->nbin;
158
159 datafile_context->test_line_number = datafile_context->line_number;
160
161 for (out = 0; out < params->nbout; out++)
162
163 {
164 read_param (datafile_context, &(params->P[total + out]),
165 params->T[total + out]);
166 if (params->T[out] == MPFR || params->T[out] == MPC)
167 set_precision (params, out);
168 }
169
170 for (in = params->nbout; in < total; in++)
171 {
172 read_param (datafile_context, &(params->P[in]), params->T[in]);
173 }
174 }
175
176 /* read primitives */
177 static void
tpl_skip_line(mpc_datafile_context_t * datafile_context)178 tpl_skip_line (mpc_datafile_context_t* datafile_context)
179 /* skips characters until reaching '\n' or EOF; */
180 /* '\n' is skipped as well */
181 {
182 while (datafile_context->nextchar != EOF && datafile_context->nextchar != '\n')
183 datafile_context->nextchar = getc (datafile_context->fd);
184 if (datafile_context->nextchar != EOF)
185 {
186 datafile_context->line_number ++;
187 datafile_context->nextchar = getc (datafile_context->fd);
188 }
189 }
190
191 static void
tpl_skip_whitespace(mpc_datafile_context_t * datafile_context)192 tpl_skip_whitespace (mpc_datafile_context_t* datafile_context)
193 /* skips over whitespace if any until reaching EOF */
194 /* or non-whitespace */
195 {
196 while (isspace (datafile_context->nextchar))
197 {
198 if (datafile_context->nextchar == '\n')
199 datafile_context->line_number ++;
200 datafile_context->nextchar = getc (datafile_context->fd);
201 }
202 }
203
204 void
tpl_skip_whitespace_comments(mpc_datafile_context_t * datafile_context)205 tpl_skip_whitespace_comments (mpc_datafile_context_t* datafile_context)
206 /* skips over all whitespace and comments, if any */
207 {
208 tpl_skip_whitespace (datafile_context);
209 while (datafile_context->nextchar == '#') {
210 tpl_skip_line (datafile_context);
211 if (datafile_context->nextchar != EOF)
212 tpl_skip_whitespace (datafile_context);
213 }
214 }
215
216 /* All following read routines skip over whitespace and comments; */
217 /* so after calling them, nextchar is either EOF or the beginning */
218 /* of a non-comment token. */
219 void
tpl_read_ternary(mpc_datafile_context_t * datafile_context,int * ternary)220 tpl_read_ternary (mpc_datafile_context_t* datafile_context, int* ternary)
221 {
222 switch (datafile_context->nextchar)
223 {
224 case '!':
225 *ternary = TERNARY_ERROR;
226 break;
227 case '?':
228 *ternary = TERNARY_NOT_CHECKED;
229 break;
230 case '+':
231 *ternary = +1;
232 break;
233 case '0':
234 *ternary = 0;
235 break;
236 case '-':
237 *ternary = -1;
238 break;
239 default:
240 printf ("Error: Unexpected ternary value '%c' in file '%s' line %lu\n",
241 datafile_context->nextchar,
242 datafile_context->pathname,
243 datafile_context->line_number);
244 exit (1);
245 }
246
247 datafile_context->nextchar = getc (datafile_context->fd);
248 tpl_skip_whitespace_comments (datafile_context);
249 }
250