#include <stdio.h>
#include <cloog/cloog.h>

/* Generate code that scans part of the parameter domain of
 * a given cloog problem, running both a function called "good"
 * and a function called "test" for each value of the parameters.
 * These functions are assumed to call the "hash" function,
 * which is also generated by this program.
 * If for any given value of the parameters, the final hash
 * value computed by test is different from that computed by
 * good, then an error is reported.
 */

CloogDomain *get_param_domain(CloogOptions *options)
{
	CloogDomain *domain;
	CloogProgram *program;
  
	program = cloog_program_read(stdin, options);

	domain = cloog_domain_copy(program->context);

	cloog_program_free(program);

	return cloog_domain_from_context(domain);
}

static const char preamble[] =
"#include <assert.h>\n"
"#include <stdio.h>\n"
"\n"
"static unsigned h;\n"
"\n"
"void hash(int v)\n"
"{\n"
"	int i;\n"
"	union u {\n"
"		int v;\n"
"		unsigned char c[1];\n"
"	} u;\n"
"	u.v = v;\n"
"	for (i = 0; i < sizeof(int); ++i) {\n"
" 		h *= 16777619;\n"
"		h ^= u.c[i];\n"
"	}\n"
"}\n"
"\n"
"int main()\n"
"{\n"
"	unsigned h_good, h_test;\n";
;

static const char postamble[] =
"	return 0;\n"
"}\n"
;

static const char *call[] = {"good", "test"};

static void print_macros(FILE *file)
{
	fprintf(file, "/* Useful macros. */\n") ;
	fprintf(file,
	    "#define floord(n,d) (((n)<0) ? -((-(n)+(d)-1)/(d)) : (n)/(d))\n");
	fprintf(file,
	    "#define ceild(n,d) (((n)<0) ? -((-(n))/(d)) : ((n)+(d)-1)/(d))\n");
	fprintf(file, "#define max(x,y)    ((x) > (y) ? (x) : (y))\n") ; 
	fprintf(file, "#define min(x,y)    ((x) < (y) ? (x) : (y))\n\n") ; 
}

int main()
{
	int dim;
	int range;
	int i, j;
	CloogState *state = cloog_state_malloc();
	CloogOptions *options = cloog_options_malloc(state);
	CloogDomain *domain;
	CloogDomain *cube, *tmp;
	CloogProgram *p;
	CloogStatement *statement;
	cloog_int_t m, M;

	options->quiet = 1;
	domain = get_param_domain(options);
	dim = cloog_domain_dimension(domain);

	if (dim >= 8)
		range = 4;
	else if (dim >= 5)
		range = 6;
	else
		range = 30;

	cloog_int_init(m);
	cloog_int_init(M);
	cloog_int_set_si(m, 0);
	cloog_int_set_si(M, range);
	cube = cloog_domain_cube(state, dim, m, M);
	domain = cloog_domain_intersection(tmp = domain, cube);
	cloog_domain_free(tmp);
	cloog_domain_free(cube);

	p = cloog_program_malloc();
	assert(p);
	p->names = cloog_names_malloc();
	assert(p->names);
	p->names->nb_iterators = dim;
	p->names->iterators = cloog_names_generate_items(dim, "p", 0);
	p->language = 'c';
	p->context = cloog_domain_universe(state, 0);
	statement = cloog_statement_alloc(state, 1);
	p->loop = cloog_loop_malloc(state);
	p->loop->domain = domain;
	p->loop->block = cloog_block_alloc(statement, 0, NULL, dim);
	p->blocklist = cloog_block_list_alloc(p->loop->block);
	p = cloog_program_generate(p, options);

	printf("%s", preamble);
	for (i = 0; i < dim; ++i)
		printf("\tint %s;\n", p->names->iterators[i]);
	printf("#define S1(");
	for (i = 0; i < dim; ++i) {
		if (i)
			printf(",");
		printf("p%d", i);
	}
	printf(") do {");
	for (j = 0; j < 2; ++j) {
		printf(" h = 2166136261u;");
		printf(" %s(", call[j]);
		for (i = 0; i < dim; ++i) {
			if (i)
				printf(", ");
			printf("p%d", i);
		}
		printf(");");
		printf(" h_%s = h;", call[j]);
	}
	printf(" assert(h_good == h_test);");
	printf(" } while (0)\n");
	print_macros(stdout);
	cloog_program_pprint(stdout, p, options);
	printf("%s", postamble);

	cloog_int_clear(m);
	cloog_int_clear(M);
	cloog_program_free(p);
	cloog_options_free(options);
	cloog_state_free(state);

	return 0;
}
