+ print_iteration_domains (stderr, scop, verbosity);
+}
+
+/* Read N integer from FILE. */
+
+int *
+openscop_read_N_int (FILE *file, int N)
+{
+ char s[OPENSCOP_MAX_STRING];
+ char *str;
+ int i, *res = (int *) xmalloc (OPENSCOP_MAX_STRING * sizeof (int));
+
+ /* Skip blank and commented lines. */
+ while (fgets (s, sizeof s, file) == (char *) 0
+ || s[0] == '#'
+ || ISSPACE (s[0]))
+ ;
+
+ str = s;
+
+ for (i = 0; i < N; i++)
+ {
+ sscanf (str, "%d", &res[i]);
+
+ /* Jump the integer that was read. */
+ while ((*str) && !ISSPACE (*str) && (*str != '#'))
+ str++;
+
+ /* Jump spaces. */
+ while ((*str) && ISSPACE (*str) && (*str != '#'))
+ str++;
+ }
+
+ return res;
+}
+
+/* Read one integer from FILE. */
+
+static int
+openscop_read_one_int (FILE *file)
+{
+ int *x = openscop_read_N_int (file, 1);
+ int res = *x;
+
+ free (x);
+ return res;
+}
+
+/* Read N string from FILE. */
+
+static char *
+openscop_read_N_string (FILE *file, int N)
+{
+ int count, i;
+ char str[OPENSCOP_MAX_STRING];
+ char *tmp = (char *) xmalloc (sizeof (char) * OPENSCOP_MAX_STRING);
+ char *s = NULL;
+
+ /* Skip blank and commented lines. */
+ while (fgets (str, sizeof str, file) == (char *) 0
+ || str[0] == '#'
+ || ISSPACE (str[0]))
+ ;
+
+ s = str;
+ count = 0;
+
+ for (i = 0; i < N; i++)
+ {
+ /* Read the first word. */
+ for (; (*s) && (!ISSPACE (*s)) && (*s != '#'); ++count)
+ tmp[count] = *(s++);
+
+ tmp[count] = ' ';
+ count++;
+
+ /* Jump spaces. */
+ while ((*s) && ISSPACE (*s) && (*s != '#'))
+ s++;
+ }
+
+ tmp[count-1] = '\0';
+
+ return tmp;
+}
+
+/* Read one string from FILE. */
+
+static char *
+openscop_read_one_string (FILE *file)
+{
+ return openscop_read_N_string (file, 1);
+}
+
+/* Read from FILE the powerset PS in its OpenScop matrix form. OUTPUT is the
+ number of output dimensions, INPUT is the number of input dimensions,
+ LOCALS is the number of existentially quantified variables and PARAMS is
+ the number of parameters. */
+
+static void
+openscop_read_powerset_matrix (FILE *file,
+ ppl_Pointset_Powerset_C_Polyhedron_t *ps,
+ int *output, int *input, int *locals,
+ int *params)
+{
+ int nb_disjuncts, i;
+
+ nb_disjuncts = openscop_read_one_int (file);
+
+ for (i = 0; i < nb_disjuncts; i++)
+ {
+ ppl_Polyhedron_t ph;
+
+ openscop_read_polyhedron_matrix (file, &ph, output, input, locals,
+ params);
+ if (!ph)
+ *ps = NULL;
+ else if (i == 0)
+ ppl_new_Pointset_Powerset_C_Polyhedron_from_C_Polyhedron (ps, ph);
+ else
+ ppl_Pointset_Powerset_C_Polyhedron_add_disjunct (*ps, ph);
+ }
+}
+
+/* Read a scattering function from FILE and save it to PBB. Return whether
+ the scattering function was provided or not. */
+
+static bool
+graphite_read_scatt (FILE *file, poly_bb_p pbb)
+{
+ bool scattering_provided = false;
+ int output, input, locals, params;
+ ppl_Polyhedron_t newp;
+
+ if (openscop_read_one_int (file) > 0)
+ {
+ /* Read number of disjunct components. */
+ openscop_read_one_int (file);
+
+ /* Read scattering function. */
+ openscop_read_polyhedron_matrix (file, &newp, &output, &input,
+ &locals, ¶ms);
+ store_scattering (PBB_SCOP (pbb));
+ PBB_TRANSFORMED (pbb) = poly_scattering_new ();
+ PBB_TRANSFORMED_SCATTERING (pbb) = newp;
+ PBB_NB_LOCAL_VARIABLES (pbb) = locals;
+
+ /* New scattering dimension. */
+ PBB_NB_SCATTERING_TRANSFORM (pbb) = output;
+
+ scattering_provided = true;
+ }
+
+ return scattering_provided;
+}
+
+/* Read a scop file. Return true if the scop is transformed. */
+
+static bool
+graphite_read_scop_file (FILE *file, scop_p scop)
+{
+ char *tmp, *language;
+ size_t i, j, nb_statements, nbr, nbw;
+ int input, output, locals, params;
+ ppl_Pointset_Powerset_C_Polyhedron_t ps;
+ poly_bb_p pbb;
+ bool transform_done = false;
+
+ /* Ensure that the file is in OpenScop format. */
+ tmp = openscop_read_N_string (file, 2);
+
+ if (strcmp (tmp, "SCoP 1"))
+ {
+ error ("the file is not in OpenScop format");
+ return false;
+ }
+
+ free (tmp);
+
+ /* Read the language. */
+ language = openscop_read_one_string (file);
+
+ if (strcmp (language, "Gimple"))
+ {
+ error ("the language is not recognized");
+ return false;
+ }
+
+ free (language);
+
+ /* Read the context but do not use it. */
+ openscop_read_powerset_matrix (file, &ps, &input, &output, &locals, ¶ms);
+
+ if ((size_t) params != scop->nb_params)
+ {
+ error ("parameters number in the scop file is different from the"
+ " internal scop parameter number");
+ return false;
+ }
+
+ /* Read parameter names if provided. */
+ if (openscop_read_one_int (file))
+ openscop_read_N_string (file, scop->nb_params);
+
+ nb_statements = openscop_read_one_int (file);
+
+ if (nb_statements != VEC_length (poly_bb_p, SCOP_BBS (scop)))
+ {
+ error ("number of statements in the OpenScop file does not match"
+ " the graphite internal statements number");
+ return false;
+ }
+
+ for (i = 0; VEC_iterate (poly_bb_p, SCOP_BBS (scop), i, pbb); i++)
+ {
+ /* Read iteration domain. */
+ openscop_read_powerset_matrix (file, &ps, &input, &output, &locals,
+ ¶ms);
+
+ /* Read scattering. */
+ transform_done = graphite_read_scatt (file, pbb);
+
+ /* Scattering names. */
+ openscop_read_one_int (file);
+
+ /* Read access functions. */
+ if (openscop_read_one_int (file) > 0)
+ {
+ nbr = openscop_read_one_int (file);
+
+ /* Read access functions. */
+ for (j = 0; j < nbr; j++)
+ openscop_read_powerset_matrix (file, &ps, &input, &output, &locals,
+ ¶ms);
+
+ nbw = openscop_read_one_int (file);
+
+ /* Write access functions. */
+ for (j = 0; j < nbw; j++)
+ openscop_read_powerset_matrix (file, &ps, &input, &output, &locals,
+ ¶ms);
+ }
+
+ /* Statement body. */
+ openscop_read_one_int (file);
+ }
+
+ return transform_done;
+}
+
+/* Initialize and return a file that will be used to write a scop. SCOP_NUMBER
+ is a sequential number (identifier) used to differentiate scop files.
+ Examples of the generated file names: dump_base_name.0.graphite,
+ dump_base_name.1.graphite, dump_base_name.2.graphite, etc. */
+
+static FILE *
+init_graphite_out_file (int scop_number)
+{
+ FILE *graphite_out_file;
+ int len = strlen (dump_base_name);
+ char *dumpname = XNEWVEC (char, len + 25);
+ char *s_scop_number = XNEWVEC (char, 15);
+
+ memcpy (dumpname, dump_base_name, len + 1);
+ strip_off_ending (dumpname, len);
+ sprintf (s_scop_number, ".%d", scop_number);
+ strcat (dumpname, s_scop_number);
+ strcat (dumpname, ".graphite");
+ graphite_out_file = fopen (dumpname, "w+b");
+
+ if (graphite_out_file == 0)
+ fatal_error ("can%'t open %s for writing: %m", dumpname);
+
+ free (dumpname);
+
+ return graphite_out_file;
+}
+
+/* Open and return a file used for scop reading. SCOP_NUMBER is a sequential
+ number (identifier) used to differentiate scop files. Examples of the
+ generated file names: dump_base_name.0.graphite, dump_base_name.1.graphite,
+ dump_base_name.2.graphite, etc. */
+
+static FILE *
+init_graphite_in_file (int scop_number)
+{
+ FILE *graphite_in_file;
+ int len = strlen (dump_base_name);
+ char *dumpname = XNEWVEC (char, len + 25);
+ char *s_scop_number = XNEWVEC (char, 15);
+
+ memcpy (dumpname, dump_base_name, len + 1);
+ strip_off_ending (dumpname, len);
+ sprintf (s_scop_number, ".%d", scop_number);
+ strcat (dumpname, s_scop_number);
+ strcat (dumpname, ".graphite");
+ graphite_in_file = fopen (dumpname, "r+b");
+
+ if (graphite_in_file == 0)
+ fatal_error ("can%'t open %s for reading: %m", dumpname);
+
+ free (dumpname);
+
+ return graphite_in_file;