1#include <ctype.h>
2#include <stdio.h>
3#include <stdlib.h>
4#include "../include/cloog/cloog.h"
5
6#ifdef OSL_SUPPORT
7#include <osl/scop.h>
8#endif
9
10#define ALLOC(type) (type*)malloc(sizeof(type))
11
12static char *next_line(FILE *input, char *line, unsigned len)
13{
14	char *p;
15
16	do {
17		if (!(p = fgets(line, len, input)))
18			return NULL;
19		while (isspace(*p) && *p != '\n')
20			++p;
21	} while (*p == '#' || *p == '\n');
22
23	return p;
24}
25
26#ifdef OSL_SUPPORT
27/**
28 * This function translates an OpenScop scop to a CLooG input.
29 * \param[in,out] state CLooG state.
30 * \param[in]     scop  Scop to translate.
31 * \return A CloogInput corresponding to the scop input.
32 */
33CloogInput *cloog_input_from_osl_scop(CloogState *state, osl_scop_p scop) {
34  CloogInput *input    = NULL;
35  CloogDomain *context = NULL;
36  CloogUnionDomain *ud = NULL;
37
38  if (scop) {
39    /* Extract the context. */
40    context = cloog_domain_from_osl_relation(state, scop->context);
41
42    /* Extract the union of domains. */
43    ud = cloog_union_domain_from_osl_scop(state, scop);
44
45    /* Build and return the input. */
46    input = cloog_input_alloc(context, ud);
47  }
48
49  return input;
50}
51#endif
52
53/**
54 * Read input from a .cloog file, putting most of the information
55 * in the returned CloogInput.  The chosen language is put in
56 * options->language.
57 */
58CloogInput *cloog_input_read(FILE *file, CloogOptions *options)
59{
60	char line[MAX_STRING];
61	char language;
62	CloogDomain *context;
63	CloogUnionDomain *ud;
64	int nb_par;
65
66#ifdef OSL_SUPPORT
67	if (options->openscop) {
68		osl_scop_p scop = osl_scop_read(file);
69		CloogInput * input = cloog_input_from_osl_scop(options->state,
70		                                               scop);
71		cloog_options_copy_from_osl_scop(scop, options);
72		return input;
73	}
74#endif
75
76	/* First of all, we read the language to use. */
77	if (!next_line(file, line, sizeof(line)))
78		cloog_die("Input error.\n");
79	if (sscanf(line, "%c", &language) != 1)
80		cloog_die("Input error.\n");
81
82	if (language == 'f')
83		options->language = CLOOG_LANGUAGE_FORTRAN;
84	else
85		options->language = CLOOG_LANGUAGE_C;
86
87	/* We then read the context data. */
88	context = cloog_domain_read_context(options->state, file);
89	nb_par = cloog_domain_parameter_dimension(context);
90
91	ud = cloog_union_domain_read(file, nb_par, options);
92
93	return cloog_input_alloc(context, ud);
94}
95
96/**
97 * Create a CloogInput from a CloogDomain context and a CloogUnionDomain.
98 */
99CloogInput *cloog_input_alloc(CloogDomain *context, CloogUnionDomain *ud)
100{
101	CloogInput *input;
102
103	input = ALLOC(CloogInput);
104	if (!input)
105		cloog_die("memory overflow.\n");
106
107	input->context = context;
108	input->ud = ud;
109
110	return input;
111}
112
113void cloog_input_free(CloogInput *input)
114{
115	cloog_domain_free(input->context);
116	cloog_union_domain_free(input->ud);
117	free(input);
118}
119
120static void print_names(FILE *file, CloogUnionDomain *ud,
121	enum cloog_dim_type type, const char *name)
122{
123	int i;
124
125	fprintf(file, "\n%d # %s name(s)\n", ud->name[type] ? 1 : 0, name);
126	if (!ud->name[type])
127		return;
128
129	for (i = 0; i < ud->n_name[type]; i++)
130		fprintf(file, "%s ", ud->name[type][i]);
131
132	fprintf(file, "\n");
133}
134
135/**
136 * Dump the .cloog description of a CloogInput and a CloogOptions data structure
137 * into a file. The generated .cloog file will contain the same information as
138 * the data structures. The file can be used to run the cloog program on the
139 * example.
140 */
141void cloog_input_dump_cloog(FILE *file, CloogInput *input, CloogOptions *opt)
142{
143        int i, num_statements;
144        CloogUnionDomain *ud = input->ud;
145        CloogNamedDomainList *ndl = ud->domain;
146
147        fprintf(file,
148                "# CLooG -> CLooG\n"
149                "# This is an automatic dump of a CLooG input file from a "
150                "CloogInput data\n"
151                "# structure.\n\n");
152
153        /* Language. */
154        if (opt->language == CLOOG_LANGUAGE_FORTRAN) {
155                fprintf(file, "# Language: FORTRAN\n");
156                fprintf(file, "f\n\n");
157        } else {
158                fprintf(file, "# Language: C\n");
159                fprintf(file, "c\n\n");
160        }
161
162        /* Context. */
163        fprintf(file, "# Context:\n");
164        cloog_domain_print_constraints(file, input->context, 1);
165
166	print_names(file, ud, CLOOG_PARAM, "Parameter");
167
168        /* Statement number. */
169        i = 0;
170        while (ndl != NULL) {
171        	i++;
172        	ndl = ndl->next;
173        }
174        num_statements = i;
175        fprintf(file, "\n# Statement number:\n%d\n\n", num_statements);
176
177        /* Iteration domains. */
178        i = 1;
179        ndl = ud->domain;
180        while (ndl != NULL) {
181                fprintf(file, "# Iteration domain of statement %d (%s).\n", i,
182                        ndl->name);
183
184                cloog_domain_print_constraints(file, ndl->domain, 1);
185                fprintf(file,"\n0 0 0 # For future options.\n\n");
186
187                i++;
188                ndl = ndl->next;
189        }
190
191	print_names(file, ud, CLOOG_ITER, "Iterator");
192
193        /* Exit, if no scattering is supplied. */
194        if (!ud->domain || !ud->domain->scattering) {
195                fprintf(file, "# No scattering functions.\n0\n\n");
196                return;
197        }
198
199        /* Scattering relations. */
200        fprintf(file,
201                "# --------------------- SCATTERING --------------------\n");
202
203        fprintf(file, "%d # Scattering functions\n", num_statements);
204
205        i = 1;
206        ndl = ud->domain;
207        while (ndl != NULL) {
208                fprintf(file, "\n# Scattering of statement %d (%s).\n", i,
209                        ndl->name);
210
211                cloog_scattering_print_constraints(file, ndl->scattering);
212
213                i++;
214                ndl = ndl->next;
215        }
216
217	print_names(file, ud, CLOOG_SCAT, "Scattering dimension");
218}
219