Home | History | Annotate | Line # | Download | only in tests
      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