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 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 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 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 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 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 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 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