summaryrefslogtreecommitdiff
path: root/tests/read_description.c
diff options
context:
space:
mode:
Diffstat (limited to 'tests/read_description.c')
-rw-r--r--tests/read_description.c267
1 files changed, 267 insertions, 0 deletions
diff --git a/tests/read_description.c b/tests/read_description.c
new file mode 100644
index 0000000..899a600
--- /dev/null
+++ b/tests/read_description.c
@@ -0,0 +1,267 @@
+/* read_description.c -- read parameters from description file
+
+Copyright (C) 2012, 2013 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include <string.h>
+#include "mpc-tests.h"
+
+static size_t read_keyworddesc (mpc_datafile_context_t* datafile_context,
+ char **buffer_ptr, size_t buffer_length);
+
+/* tuple to link name with the enum value */
+typedef struct {
+ const char *typename; /* type name */
+ mpc_param_t typeval ; /* type enum */
+} param_typeval_t;
+
+/* available types for function description */
+static const param_typeval_t sparam_typeval[]= {
+ { "int" , NATIVE_INT },
+ { "unsigned long int" , NATIVE_UL },
+ { "unsigned long" , NATIVE_UL },
+ { "long int" , NATIVE_L },
+ { "long" , NATIVE_L },
+ { "double" , NATIVE_D },
+ { "long double" , NATIVE_LD },
+ { "double _Complex" , NATIVE_DC },
+ { "long double _Complex", NATIVE_LDC },
+ { "intmax_t" , NATIVE_IM },
+ { "uintmax_t" , NATIVE_UIM },
+ { "mpz_ptr" , GMP_Z },
+ { "mpz_srcptr" , GMP_Z },
+ { "mpq_ptr" , GMP_Q },
+ { "mpq_srcptr" , GMP_Q },
+ { "mpf_ptr" , GMP_F },
+ { "mpf_srcptr" , GMP_F },
+ { "mpfr_inex" , MPFR_INEX },
+ { "mpfr_ptr" , MPFR },
+ { "mpfr_srcptr" , MPFR },
+ { "mpfr_rnd_t" , MPFR_RND },
+ { "mpc_inex" , MPC_INEX },
+ { "mpc_ptr" , MPC },
+ { "mpc_srcptr" , MPC },
+ { "mpc_rnd_t" , MPC_RND }
+};
+
+/* read primitives */
+
+static size_t
+read_keyworddesc (mpc_datafile_context_t* datafile_context,
+ char **buffer_ptr,
+ size_t buffer_length)
+{
+ size_t pos;
+ char *buffer;
+
+ pos = 0;
+ buffer = *buffer_ptr;
+
+ while (datafile_context->nextchar != EOF
+ && datafile_context->nextchar != '#'
+ && datafile_context->nextchar != '\n')
+ {
+ if (pos + 1 > buffer_length)
+ {
+ if (buffer_length == 0)
+ buffer_length = pos + 1;
+ buffer = (char *) realloc (buffer, 2 * buffer_length);
+ buffer_length *= 2;
+ if (buffer == NULL)
+ {
+ printf ("Cannot allocate memory\n");
+ exit (1);
+ }
+ }
+ buffer[pos++] = (char) datafile_context->nextchar;
+ datafile_context->nextchar = getc (datafile_context->fd);
+ }
+ while (pos>0 && isspace(buffer[pos-1])) pos--;
+
+ if (pos + 1 > buffer_length)
+ {
+ buffer = (char *) realloc (buffer, buffer_length + 1);
+ buffer_length++;
+ if (buffer == NULL)
+ {
+ printf ("Cannot allocate memory\n");
+ exit (1);
+ }
+ }
+ buffer[pos] = '\0';
+
+ *buffer_ptr = buffer;
+
+ return buffer_length;
+}
+
+/* return the enum associated to name */
+static mpc_param_t
+description_findtype (const char *name)
+{
+
+ mpc_param_t r = sparam_typeval[0].typeval;
+ size_t s = 0;
+ const size_t send = sizeof (sparam_typeval) / sizeof (param_typeval_t);
+
+ while (s < send && strcmp (sparam_typeval[s].typename, name) != 0)
+ s++;
+
+ if (s < send)
+ r = sparam_typeval[s].typeval;
+ else
+ {
+ printf ("Error: Unable to find the type '%s'\n",name);
+ exit (1);
+ }
+ return r;
+}
+
+/* return the name associated to the enum */
+const char*
+read_description_findname (mpc_param_t e)
+{
+
+ const char * name = NULL;
+ size_t s = 0;
+ const size_t send = sizeof (sparam_typeval) / sizeof (param_typeval_t);
+
+ while (s < send && sparam_typeval[s].typeval != e)
+ s++;
+
+ if (s<send)
+ name = sparam_typeval[s].typename;
+ else
+ {
+ printf ("Error: Unable to find the enum type\n");
+ exit (1);
+ }
+ return name;
+}
+
+
+/* read the description file and fill param */
+void
+read_description (mpc_fun_param_t* param, const char *filename)
+{
+ mpc_datafile_context_t datafile_context;
+ const char *pathname = filename;
+ char *namestr = NULL;
+ char *buffer = NULL;
+ size_t len = 0;
+ int nbout = 0;
+ int nbin = 0;
+ int j;
+
+ open_datafile (&datafile_context, filename);
+
+ /* read NAME fields */
+ tpl_skip_whitespace_comments(&datafile_context);
+ len = read_keyworddesc (&datafile_context, &namestr, len);
+ if (namestr == NULL || strcmp (namestr,"NAME:") != 0)
+ {
+ printf ("Error: Unable to read 'NAME:' in file '%s'\n",
+ filename);
+ exit (1);
+ }
+
+ tpl_skip_whitespace_comments (&datafile_context);
+ read_keyworddesc (&datafile_context, &namestr, len);
+ if (namestr == NULL)
+ {
+ printf ("Error: Unable to read the name of the function in file '%s'\n",
+ filename);
+ exit (1);
+ }
+ param->name = namestr;
+ namestr = NULL;
+
+ /* read RETURN fields */
+ tpl_skip_whitespace_comments (&datafile_context);
+ len = 0;
+ len = read_keyworddesc (&datafile_context, &buffer, len);
+ if (buffer == NULL || strcmp (buffer,"RETURN:") != 0)
+ {
+ printf ("Error: Unable to read 'RETURN:' in file '%s'\n",
+ pathname);
+ exit (1);
+ }
+
+ tpl_skip_whitespace_comments (&datafile_context);
+ len = read_keyworddesc (&datafile_context, &buffer, len);
+ if (buffer == NULL)
+ {
+ printf ("Error: Unable to read the return type of the function"
+ " in file '%s'\n", pathname);
+ exit (1);
+ }
+ param->T[nbout++] = description_findtype (buffer);
+
+ /* read OUPUT fields */
+ tpl_skip_whitespace_comments (&datafile_context);
+ len = read_keyworddesc (&datafile_context, &buffer, len);
+ if (buffer == NULL || strcmp (buffer,"OUTPUT:")!=0)
+ {
+ printf ("Error: Unable to read 'OUTPUT:' in file '%s'\n",
+ pathname);
+ exit (1);
+ }
+
+ while (!feof (datafile_context.fd))
+ {
+ tpl_skip_whitespace_comments (&datafile_context);
+ len = read_keyworddesc (&datafile_context, &buffer, len);
+ if (buffer == NULL)
+ {
+ printf ("Error: Unable to read the output type of the function"
+ " in file '%s'\n", pathname);
+ exit (1);
+ }
+ if (strcmp (buffer, "INPUT:") == 0)
+ break; /* exit the output loop */
+ param->T[nbout++] = description_findtype (buffer);
+ }
+
+ /* read INPUT fields */
+ while (!feof (datafile_context.fd))
+ {
+ tpl_skip_whitespace_comments (&datafile_context);
+ len = read_keyworddesc (&datafile_context, &buffer, len);
+ if (buffer == NULL)
+ {
+ printf ("Error: Unable to read the input type of the function"
+ " in file '%s'\n", pathname);
+ exit (1);
+ }
+ if (strlen (buffer) == 0 && feof (datafile_context.fd))
+ break;
+ param->T[nbout+nbin] = description_findtype (buffer);
+ nbin++;
+ }
+ free (buffer);
+
+ param->nbout = nbout;
+ param->nbin = nbin;
+
+ /* duplicate output parameters at the end for the expected values */
+ for (j = 0; j < param->nbout; j++)
+ {
+ MPC_ASSERT (nbout + nbin + j < PARAMETER_ARRAY_SIZE);
+ param->T[nbout + nbin + j] = param->T[j];
+ }
+}