xref: /netbsd-src/external/lgpl3/mpc/dist/tests/read_description.c (revision 39f28e1e142c5bfb6be935a49cb55e2287fec7ea)
1 /* read_description.c -- read parameters from description 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 <string.h>
22 #include "mpc-tests.h"
23 
24 static size_t read_keyworddesc (mpc_datafile_context_t* datafile_context,
25                                 char **buffer_ptr, size_t buffer_length);
26 
27 /* tuple to link name with the enum value */
28 typedef struct  {
29   const char * name;  /* type name */
30   mpc_param_t  val;   /* type enum */
31 } param_typeval_t;
32 
33 /* available types for function description */
34 static const param_typeval_t sparam_typeval[]= {
35   { "int"                 , NATIVE_INT  },
36   { "unsigned long int"   , NATIVE_UL   },
37   { "unsigned long"       , NATIVE_UL   },
38   { "long int"            , NATIVE_L    },
39   { "long"                , NATIVE_L    },
40   { "double"              , NATIVE_D    },
41   { "long double"         , NATIVE_LD   },
42   { "double _Complex"     , NATIVE_DC   },
43   { "long double _Complex", NATIVE_LDC  },
44   { "intmax_t"            , NATIVE_IM   },
45   { "uintmax_t"           , NATIVE_UIM  },
46   { "mpz_ptr"             , GMP_Z       },
47   { "mpz_srcptr"          , GMP_Z       },
48   { "mpq_ptr"             , GMP_Q       },
49   { "mpq_srcptr"          , GMP_Q       },
50   { "mpf_ptr"             , GMP_F       },
51   { "mpf_srcptr"          , GMP_F       },
52   { "mpfr_inex"           , MPFR_INEX   },
53   { "mpfr_ptr"            , MPFR        },
54   { "mpfr_srcptr"         , MPFR        },
55   { "mpfr_rnd_t"          , MPFR_RND    },
56   { "mpc_inex"            , MPC_INEX    },
57   { "mpc_ptr"             , MPC         },
58   { "mpc_srcptr"          , MPC         },
59   { "mpc_rnd_t"           , MPC_RND     },
60   { "mpcc_inex"           , MPCC_INEX   }
61 };
62 
63 /* read primitives */
64 
65 static size_t
read_keyworddesc(mpc_datafile_context_t * datafile_context,char ** buffer_ptr,size_t buffer_length)66 read_keyworddesc (mpc_datafile_context_t* datafile_context,
67                   char **buffer_ptr,
68                   size_t buffer_length)
69 {
70   size_t pos;
71   char *buffer;
72 
73   pos = 0;
74   buffer = *buffer_ptr;
75 
76   while (datafile_context->nextchar != EOF
77          && datafile_context->nextchar != '#'
78          && datafile_context->nextchar != '\n')
79     {
80       if (pos + 1 > buffer_length)
81         {
82           if (buffer_length == 0)
83             buffer_length = pos + 1;
84           buffer = (char *) realloc (buffer, 2 * buffer_length);
85           buffer_length *= 2;
86           if (buffer == NULL)
87             {
88               printf ("Cannot allocate memory\n");
89               exit (1);
90             }
91         }
92       buffer[pos++] = (char) datafile_context->nextchar;
93       datafile_context->nextchar = getc (datafile_context->fd);
94     }
95   while (pos>0 && isspace(buffer[pos-1])) pos--;
96 
97   if (pos + 1 > buffer_length)
98     {
99       buffer = (char *) realloc (buffer, buffer_length + 1);
100       buffer_length++;
101       if (buffer == NULL)
102         {
103           printf ("Cannot allocate memory\n");
104           exit (1);
105         }
106     }
107   buffer[pos] = '\0';
108 
109   *buffer_ptr = buffer;
110 
111   return buffer_length;
112 }
113 
114 /* return the enum associated to name */
115 static mpc_param_t
description_findtype(const char * name)116 description_findtype (const char *name)
117 {
118 
119   mpc_param_t r = sparam_typeval[0].val;
120   size_t s = 0;
121   const size_t send = sizeof (sparam_typeval) / sizeof (param_typeval_t);
122 
123   while (s < send && strcmp (sparam_typeval[s].name, name) != 0)
124     s++;
125 
126   if (s < send)
127     r = sparam_typeval[s].val;
128   else
129     {
130       printf ("Error: Unable to find the type  '%s'\n",name);
131       exit (1);
132     }
133   return r;
134 }
135 
136 /* return the name  associated to the enum */
137 const char*
read_description_findname(mpc_param_t e)138 read_description_findname (mpc_param_t e)
139 {
140 
141   const char * name = NULL;
142   size_t s = 0;
143   const size_t send = sizeof (sparam_typeval) / sizeof (param_typeval_t);
144 
145   while (s < send && sparam_typeval[s].val != e)
146     s++;
147 
148   if (s<send)
149     name = sparam_typeval[s].name;
150   else
151     {
152       printf ("Error: Unable to find the enum type\n");
153       exit (1);
154     }
155   return name;
156 }
157 
158 
159 /* read the description file and fill param */
160 void
read_description(mpc_fun_param_t * param,const char * filename)161 read_description (mpc_fun_param_t* param, const char *filename)
162 {
163   mpc_datafile_context_t datafile_context;
164   const char *pathname = filename;
165   char *namestr = NULL;
166   char *buffer = NULL;
167   size_t len = 0;
168   int nbout = 0;
169   int nbin = 0;
170   int rnd_mode = 0;
171   int j;
172 
173   open_datafile (&datafile_context, filename);
174 
175   /* read NAME fields */
176   tpl_skip_whitespace_comments(&datafile_context);
177   len = read_keyworddesc (&datafile_context, &namestr, len);
178   if (namestr == NULL || strcmp (namestr,"NAME:") != 0)
179     {
180       printf ("Error: Unable to read 'NAME:' in file '%s'\n",
181               filename);
182       exit (1);
183     }
184 
185   tpl_skip_whitespace_comments (&datafile_context);
186   read_keyworddesc (&datafile_context, &namestr, len);
187   if (namestr == NULL)
188     {
189       printf ("Error: Unable to read the name of the function in file '%s'\n",
190               filename);
191       exit (1);
192     }
193   param->name = namestr;
194   namestr = NULL;
195 
196   /* read RETURN fields */
197   tpl_skip_whitespace_comments (&datafile_context);
198   len = 0;
199   len = read_keyworddesc (&datafile_context, &buffer, len);
200   if (buffer == NULL || strcmp (buffer,"RETURN:") != 0)
201     {
202       printf ("Error: Unable to read 'RETURN:' in file '%s'\n",
203               pathname);
204       exit (1);
205     }
206 
207   tpl_skip_whitespace_comments (&datafile_context);
208   len = read_keyworddesc (&datafile_context, &buffer, len);
209   if (buffer == NULL)
210     {
211       printf ("Error: Unable to read the return type of the function"
212               " in file '%s'\n", pathname);
213       exit (1);
214     }
215   param->T[nbout++] = description_findtype (buffer);
216 
217   /* read OUPUT fields */
218   tpl_skip_whitespace_comments (&datafile_context);
219   len = read_keyworddesc (&datafile_context, &buffer, len);
220   if (buffer == NULL || strcmp (buffer,"OUTPUT:")!=0)
221     {
222       printf ("Error: Unable to read 'OUTPUT:' in file '%s'\n",
223               pathname);
224       exit (1);
225     }
226 
227   while (!feof (datafile_context.fd))
228     {
229       tpl_skip_whitespace_comments (&datafile_context);
230       len = read_keyworddesc (&datafile_context, &buffer, len);
231       if (buffer == NULL)
232         {
233           printf ("Error: Unable to read the output type of the function"
234                   " in file '%s'\n", pathname);
235           exit (1);
236         }
237       if (strcmp (buffer, "INPUT:") == 0)
238         break; /* exit the output loop */
239       param->T[nbout++] = description_findtype (buffer);
240     }
241 
242   /* read INPUT fields */
243   while (!feof (datafile_context.fd))
244     {
245       tpl_skip_whitespace_comments (&datafile_context);
246       len = read_keyworddesc (&datafile_context, &buffer, len);
247       if (buffer == NULL)
248         {
249           printf ("Error: Unable to read the input type of the function"
250                   " in file '%s'\n", pathname);
251           exit (1);
252         }
253       if (strlen (buffer) == 0 && feof (datafile_context.fd))
254         break;
255       param->T[nbout+nbin] = description_findtype (buffer);
256       if (param->T[nbout+nbin] == MPC_RND || param->T[nbout+nbin] == MPFR_RND)
257         rnd_mode++;
258       nbin++;
259     }
260   free (buffer);
261 
262   param->nbout = nbout;
263   param->nbin  = nbin;
264   param->nbrnd = rnd_mode;
265 
266   /* duplicate output parameters at the end for the expected values */
267   for (j = 0; j < param->nbout; j++)
268     {
269       MPC_ASSERT (nbout + nbin + j < PARAMETER_ARRAY_SIZE);
270       param->T[nbout + nbin + j] = param->T[j];
271     }
272 
273   close_datafile(&datafile_context);
274 }
275