1275970Scy/* read_line.c -- Read line of test data in file.
2275970Scy
3275970ScyCopyright (C) 2012, 2013, 2014 INRIA
4275970Scy
5275970ScyThis file is part of GNU MPC.
6275970Scy
7275970ScyGNU MPC is free software; you can redistribute it and/or modify it under
8275970Scythe terms of the GNU Lesser General Public License as published by the
9330567SgordonFree Software Foundation; either version 3 of the License, or (at your
10275970Scyoption) any later version.
11275970Scy
12275970ScyGNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
13275970ScyWARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14275970ScyFOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
15275970Scymore details.
16275970Scy
17275970ScyYou should have received a copy of the GNU Lesser General Public License
18275970Scyalong with this program. If not, see http://www.gnu.org/licenses/ .
19275970Scy*/
20275970Scy
21275970Scy#include "mpc-tests.h"
22275970Scy
23275970Scystatic void
24275970Scyread_param  (mpc_datafile_context_t* datafile_context,
25275970Scy             mpc_operand_t* p, mpc_param_t t)
26275970Scy{
27275970Scy  switch (t)
28275970Scy    {
29275970Scy    case NATIVE_INT:
30275970Scy      tpl_read_int (datafile_context, &(p->i),"");
31275970Scy      return;
32275970Scy    case NATIVE_UL:
33275970Scy      tpl_read_ui (datafile_context, &(p->ui));
34275970Scy      return;
35275970Scy    case NATIVE_L:
36275970Scy      tpl_read_si (datafile_context, &(p->si));
37275970Scy      return;
38275970Scy
39275970Scy    case NATIVE_D:
40275970Scy    case NATIVE_LD:
41275970Scy      /* TODO */
42275970Scy      fprintf (stderr, "read_param: type not implemented.\n");
43275970Scy      exit (1);
44275970Scy      break;
45275970Scy
46275970Scy    case NATIVE_DC:
47275970Scy    case NATIVE_LDC:
48275970Scy#ifdef _Complex_I
49275970Scy      /* TODO */
50275970Scy      fprintf (stderr, "read_param: type not implemented.\n");
51275970Scy      exit (1);
52275970Scy#endif
53275970Scy      break;
54275970Scy
55275970Scy    case NATIVE_IM:
56275970Scy    case NATIVE_UIM:
57275970Scy#ifdef _MPC_H_HAVE_INTMAX_T
58275970Scy      /* TODO */
59285612Sdelphij      fprintf (stderr, "read_param: type not implemented.\n");
60285612Sdelphij      exit (1);
61275970Scy#endif
62275970Scy      break;
63275970Scy
64275970Scy    case NATIVE_STRING:
65275970Scy      /* TODO */
66275970Scy      fprintf (stderr, "read_param: type not implemented.\n");
67275970Scy      exit (1);
68275970Scy      break;
69275970Scy
70275970Scy    case GMP_Z:
71275970Scy      tpl_read_mpz (datafile_context, p->mpz);
72275970Scy      return;
73275970Scy
74275970Scy    case GMP_Q:
75275970Scy    case GMP_F:
76275970Scy      /* TODO */
77275970Scy      fprintf (stderr, "read_param: type not implemented.\n");
78275970Scy      exit (1);
79275970Scy      break;
80275970Scy
81275970Scy    case MPFR_INEX:
82275970Scy      tpl_read_mpfr_inex (datafile_context, &p->mpfr_inex);
83275970Scy      return;
84275970Scy    case MPFR:
85275970Scy      tpl_read_mpfr (datafile_context,
86275970Scy                     p->mpfr_data.mpfr, &p->mpfr_data.known_sign);
87275970Scy      return;
88275970Scy    case MPFR_RND:
89275970Scy      tpl_read_mpfr_rnd (datafile_context, &p->mpfr_rnd);
90275970Scy      return;
91275970Scy
92275970Scy    case MPC_INEX:
93275970Scy      tpl_read_mpc_inex (datafile_context, &p->mpc_inex_data);
94275970Scy      return;
95275970Scy    case MPC:
96275970Scy      tpl_read_mpc (datafile_context, &p->mpc_data);
97275970Scy      return;
98275970Scy    case MPC_RND:
99275970Scy      tpl_read_mpc_rnd (datafile_context, &p->mpc_rnd);
100275970Scy      return;
101275970Scy
102275970Scy    case MPCC_INEX:
103275970Scy      /* TODO */
104330567Sgordon      fprintf (stderr, "read_param: type not implemented.\n");
105330567Sgordon      exit (1);
106275970Scy      break;
107275970Scy    }
108275970Scy
109330567Sgordon  fprintf (stderr, "read_param: unsupported type.\n");
110330567Sgordon  exit (1);
111275970Scy}
112330567Sgordon
113330567Sgordonstatic void
114330567Sgordonset_precision (mpc_fun_param_t* params, int index)
115330567Sgordon{
116275970Scy  /* set output precision to reference precision */
117275970Scy  int index_ref = index + params->nbout + params->nbin;
118275970Scy
119275970Scy  switch (params->T[index])
120275970Scy    {
121275970Scy    case MPFR:
122330567Sgordon      mpfr_set_prec (params->P[index].mpfr,
123275970Scy                     mpfr_get_prec (params->P[index_ref].mpfr));
124275970Scy      return;
125275970Scy
126330567Sgordon    case MPC:
127275970Scy      mpfr_set_prec (mpc_realref (params->P[index].mpc),
128330567Sgordon                     MPC_PREC_RE (params->P[index_ref].mpc));
129330567Sgordon      mpfr_set_prec (mpc_imagref (params->P[index].mpc),
130275970Scy                     MPC_PREC_IM (params->P[index_ref].mpc));
131330567Sgordon      return;
132330567Sgordon
133275970Scy    case NATIVE_INT:
134275970Scy    case NATIVE_UL:    case NATIVE_L:
135330567Sgordon    case NATIVE_D:     case NATIVE_LD:
136330567Sgordon    case NATIVE_DC:    case NATIVE_LDC:
137330567Sgordon    case NATIVE_IM:    case NATIVE_UIM:
138275970Scy    case NATIVE_STRING:
139330567Sgordon    case GMP_Z:        case GMP_Q:
140275970Scy    case GMP_F:
141330567Sgordon    case MPFR_INEX:    case MPFR_RND:
142330567Sgordon    case MPC_INEX:     case MPC_RND:
143330567Sgordon    case MPCC_INEX:
144330567Sgordon      /* unsupported types */
145330567Sgordon      break;
146330567Sgordon    }
147275970Scy
148275970Scy  fprintf (stderr, "set_precision: unsupported type.\n");
149275970Scy  exit (1);
150275970Scy}
151275970Scy
152275970Scyvoid
153330567Sgordonread_line (mpc_datafile_context_t* datafile_context,
154275970Scy           mpc_fun_param_t* params)
155275970Scy{
156275970Scy  int in, out;
157275970Scy  int total = params->nbout + params->nbin;
158275970Scy
159330567Sgordon  datafile_context->test_line_number = datafile_context->line_number;
160275970Scy
161275970Scy  for (out = 0; out < params->nbout; out++)
162275970Scy
163275970Scy    {
164275970Scy      read_param (datafile_context, &(params->P[total + out]),
165275970Scy                  params->T[total + out]);
166275970Scy      if (params->T[out] == MPFR || params->T[out] == MPC)
167275970Scy        set_precision (params, out);
168275970Scy    }
169275970Scy
170275970Scy  for (in = params->nbout; in < total; in++)
171275970Scy    {
172275970Scy      read_param (datafile_context, &(params->P[in]), params->T[in]);
173275970Scy    }
174275970Scy}
175275970Scy
176275970Scy/* read primitives */
177275970Scystatic void
178275970Scytpl_skip_line (mpc_datafile_context_t* datafile_context)
179275970Scy   /* skips characters until reaching '\n' or EOF; */
180275970Scy   /* '\n' is skipped as well                      */
181275970Scy{
182275970Scy   while (datafile_context->nextchar != EOF && datafile_context->nextchar != '\n')
183275970Scy     datafile_context->nextchar = getc (datafile_context->fd);
184275970Scy   if (datafile_context->nextchar != EOF)
185275970Scy     {
186275970Scy       datafile_context->line_number ++;
187275970Scy       datafile_context->nextchar = getc (datafile_context->fd);
188275970Scy     }
189275970Scy}
190275970Scy
191275970Scystatic void
192275970Scytpl_skip_whitespace (mpc_datafile_context_t* datafile_context)
193275970Scy   /* skips over whitespace if any until reaching EOF */
194275970Scy   /* or non-whitespace                               */
195275970Scy{
196275970Scy   while (isspace (datafile_context->nextchar))
197275970Scy     {
198275970Scy       if (datafile_context->nextchar == '\n')
199275970Scy         datafile_context->line_number ++;
200275970Scy       datafile_context->nextchar = getc (datafile_context->fd);
201275970Scy     }
202275970Scy}
203275970Scy
204275970Scyvoid
205275970Scytpl_skip_whitespace_comments (mpc_datafile_context_t* datafile_context)
206275970Scy   /* skips over all whitespace and comments, if any */
207275970Scy{
208275970Scy   tpl_skip_whitespace (datafile_context);
209275970Scy   while (datafile_context->nextchar == '#') {
210275970Scy      tpl_skip_line (datafile_context);
211275970Scy      if (datafile_context->nextchar != EOF)
212275970Scy         tpl_skip_whitespace (datafile_context);
213275970Scy   }
214275970Scy}
215275970Scy
216275970Scy/* All following read routines skip over whitespace and comments; */
217275970Scy/* so after calling them, nextchar is either EOF or the beginning */
218275970Scy/* of a non-comment token.                                        */
219275970Scyvoid
220275970Scytpl_read_ternary (mpc_datafile_context_t* datafile_context, int* ternary)
221275970Scy{
222275970Scy  switch (datafile_context->nextchar)
223275970Scy    {
224275970Scy    case '!':
225275970Scy      *ternary = TERNARY_ERROR;
226275970Scy      break;
227275970Scy    case '?':
228275970Scy      *ternary = TERNARY_NOT_CHECKED;
229275970Scy      break;
230275970Scy    case '+':
231275970Scy      *ternary = +1;
232275970Scy      break;
233275970Scy    case '0':
234275970Scy      *ternary = 0;
235275970Scy      break;
236275970Scy    case '-':
237275970Scy      *ternary = -1;
238275970Scy      break;
239275970Scy    default:
240275970Scy      printf ("Error: Unexpected ternary value '%c' in file '%s' line %lu\n",
241275970Scy              datafile_context->nextchar,
242275970Scy              datafile_context->pathname,
243275970Scy              datafile_context->line_number);
244275970Scy      exit (1);
245275970Scy    }
246275970Scy
247275970Scy  datafile_context->nextchar = getc (datafile_context->fd);
248275970Scy  tpl_skip_whitespace_comments (datafile_context);
249275970Scy}
250275970Scy