Index: ChangeLog
from Damien Thivolle <damien(a)lrde.epita.fr>
* tests/main/tests/pow2sup1: New.
* tests/main/tests/pow2sup2: New.
* tests/array: New.
* tests/array/test_array1d.cc: New.
* tests/array/test_array2d.cc: New.
* tests/array/gen_test_utils: New.
* tests/array/gen_test_utils/postlude: New.
* tests/array/gen_test_utils/errors.cc: New.
* tests/array/gen_test_utils/prelude: New.
* tests/array/gen_test_utils/errors.hh: New.
* tests/array/test_array3d.cc: New.
* tests/array/Makefile.am: New.
* tests/array/gen_test.cc: New.
array/Makefile.am | 18 ++
array/gen_test.cc | 346 +++++++++++++++++++++++++++++++++++++++++
array/gen_test_utils/errors.cc | 290 ++++++++++++++++++++++++++++++++++
array/gen_test_utils/errors.hh | 22 ++
array/gen_test_utils/postlude | 8
array/gen_test_utils/prelude | 20 ++
array/test_array1d.cc | 31 +++
array/test_array2d.cc | 35 ++++
array/test_array3d.cc | 44 +++++
main/tests/pow2sup1 | 37 ++++
main/tests/pow2sup2 | 37 ++++
11 files changed, 888 insertions(+)
Index: tests/main/tests/pow2sup1
--- tests/main/tests/pow2sup1 (revision 0)
+++ tests/main/tests/pow2sup1 (revision 0)
@@ -0,0 +1,37 @@
+// -*- c++ -*-
+// Copyright (C) 2004 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library 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
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+// MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#include <mlc/math.hh>
+
+using namespace mlc;
+
+int main()
+{
+ const int i = pow2sup<33>::value; // COMPFAIL
+ return i;
+}
Index: tests/main/tests/pow2sup2
--- tests/main/tests/pow2sup2 (revision 0)
+++ tests/main/tests/pow2sup2 (revision 0)
@@ -0,0 +1,37 @@
+// -*- c++ -*-
+// Copyright (C) 2004 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library 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
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+// MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#include <mlc/math.hh>
+
+using namespace mlc;
+
+int main()
+{
+ const unsigned i = pow2sup<27>::value;
+ return i != 32;
+}
Index: tests/array/test_array1d.cc
--- tests/array/test_array1d.cc (revision 0)
+++ tests/array/test_array1d.cc (revision 0)
@@ -0,0 +1,31 @@
+#include <mlc/array/all.hh>
+#include <iostream>
+using std::cout;
+using std::endl;
+
+#include "check.hh"
+
+using namespace mlc;
+
+#define OK_OR_FAIL \
+ std::cout << "OK" << std::endl; \
+ else \
+ { \
+ std::cout << "FAIL" << std::endl; \
+ fail = true; \
+ }
+
+bool
+check()
+{
+ bool fail = false;
+
+ array1d< array1d_info< 3 >, int > foo = (ints_1d = 1, 2, 3, end);
+ cout << endl << "Source:\n\n" << foo << endl;
+ cout << "After a central symmetry:\n\n" << -foo << endl;
+
+ if (1)
+ OK_OR_FAIL;
+
+ return fail;
+}
Index: tests/array/test_array2d.cc
--- tests/array/test_array2d.cc (revision 0)
+++ tests/array/test_array2d.cc (revision 0)
@@ -0,0 +1,35 @@
+#include <mlc/array/all.hh>
+#include <iostream>
+using std::cout;
+using std::endl;
+
+#include "check.hh"
+
+using namespace mlc;
+
+#define OK_OR_FAIL \
+ std::cout << "OK" << std::endl; \
+ else \
+ { \
+ std::cout << "FAIL" << std::endl; \
+ fail = true; \
+ }
+
+bool
+check()
+{
+ bool fail = false;
+
+ array2d< array2d_info< 3, 4, 2>, int > foo = (ints_2d = 1, 2, x(3), 4,
lbrk,
+ 5, 6, 7, 8,
+ 9, 10, 11, 12, end);
+
+ cout << endl << "Source:\n\n" << foo << endl;
+ cout << "After a transposition:\n\n" << foo.transpose() <<
endl;
+ cout << "After a central symmetry:\n\n" << -foo << endl;
+
+ if (1)
+ OK_OR_FAIL;
+
+ return fail;
+}
Index: tests/array/gen_test_utils/postlude
--- tests/array/gen_test_utils/postlude (revision 0)
+++ tests/array/gen_test_utils/postlude (revision 0)
@@ -0,0 +1,8 @@
+
+ (void) foo;
+
+ if (1)
+ OK_OR_FAIL;
+
+ return fail;
+}
Index: tests/array/gen_test_utils/errors.cc
--- tests/array/gen_test_utils/errors.cc (revision 0)
+++ tests/array/gen_test_utils/errors.cc (revision 0)
@@ -0,0 +1,290 @@
+#include <iostream>
+#include <fstream>
+#include <sstream>
+
+using namespace std;
+
+
+// Warning :
+// ---------
+// - dimension -> 1-indexed
+// - geometry -> 0-indexed
+// - position -> 0-indexed
+
+
+
+//
+// Center
+//
+
+
+// If odd -> center
+// else -> no center
+
+int if_center(ostream& ofs,
+ int dimension,
+ int* geometry,
+ int position)
+{
+ // Checks if one of the sizes is even (-> no automatic center)
+ for (int i = 0; i < dimension; ++i)
+ if ((geometry[i] & 1) == 1) // geometry is 0-indexed !
+ {
+ if (position == 0)
+ ofs << "x(1), ";
+ else
+ ofs << "1, ";
+ return 1;
+ }
+ // All sizes are odd
+ ofs << "1, ";
+ (void) dimension; (void) geometry; (void) position;
+ return 1;
+}
+
+
+// If odd -> middle
+// else -> 1rst position
+
+int one_center(ostream& ofs,
+ int dimension,
+ int* geometry,
+ int position)
+{
+ // Checks if one of the sizes is even (-> no automatic center)
+ for (int i = 0; i < dimension; ++i)
+ if ((geometry[i] & 1) == 1) // geometry is 0-indexed !
+ {
+ if (position == 0)
+ ofs << "x(1), ";
+ else
+ ofs << "1, ";
+ return 1;
+ }
+ // All sizes are odd
+ int middle = geometry[0] + 1;
+ for (int i = dimension - 1; 0 < i; --i)
+ middle *= (geometry[i] + 1);
+ middle = middle >> 1;
+ if (position == middle)
+ ofs << "x(1), ";
+ else
+ ofs << "1, ";
+ return 1;
+}
+
+int all_centers(ostream& ofs,
+ int dimension,
+ int* geometry,
+ int position)
+{
+ ofs << "x(1), ";
+ (void) position;
+ for (--dimension; dimension >= 0; --dimension)
+ if (geometry[dimension] != 0)
+ return 0;
+ return 1;
+}
+
+
+
+//
+// Comma
+//
+
+
+int no_comma(ostream& ofs,
+ int dimension,
+ int* geometry,
+ int position)
+{
+ if (position == 0)
+ ofs << "1 ";
+ else
+ ofs << "1, ";
+ (void) dimension; (void) geometry;
+ return 0;
+}
+
+
+//
+// No element
+//
+
+
+int no_element(ostream& ofs,
+ int dimension,
+ int* geometry,
+ int position)
+{
+ (void) ofs; (void) dimension; (void) geometry; (void) position;
+ return 0;
+}
+
+
+
+//
+// Linebreak
+//
+
+
+int no_lbreak(ostream& ofs,
+ int dimension,
+ int* geometry,
+ int position)
+{
+ (void) ofs; (void) geometry; (void) position;
+ return (dimension != 1) ? 0 : 1;
+}
+
+int one_lbreak(ostream& ofs,
+ int dimension,
+ int* geometry,
+ int position)
+{
+ if (position == geometry[dimension - 1])
+ ofs << "lbrk, ";
+ return (dimension > 1) ? 1 : 0;
+}
+
+int all_lbreak(ostream& ofs,
+ int dimension,
+ int* geometry,
+ int position)
+{
+ if (((position + 1) % (geometry[dimension - 1] + 1)) == 0)
+ ofs << "lbrk, ";
+
+ if (dimension == 1)
+ return 0;
+ for (--(--dimension); dimension >= 0; --dimension)
+ if (geometry[dimension] != 0)
+ return 0;
+ return 1;
+}
+
+int too_much_lbreak(ostream& ofs,
+ int dimension,
+ int* geometry,
+ int position)
+{
+ ofs << "lbrk, ";
+ (void) dimension; (void) geometry; (void) position;
+ if (dimension == 1)
+ return 0;
+ for (--dimension; dimension >= 0; --dimension)
+ if (geometry[dimension] != 0)
+ return 0;
+ return 1;
+}
+
+int twice_lbreak(ostream& ofs,
+ int dimension,
+ int* geometry,
+ int position)
+{
+ if (position == geometry[dimension - 1])
+ ofs << "lbrk, lbrk, ";
+ return 0;
+}
+
+
+//
+// Planebreak
+//
+
+
+int no_pbreak(ostream& ofs,
+ int dimension,
+ int* geometry,
+ int position)
+{
+ (void) ofs; (void) geometry; (void) position;
+ return (dimension > 2) ? 0 : 1;
+}
+
+int one_pbreak(ostream& ofs,
+ int dimension,
+ int* geometry,
+ int position)
+{
+ if (position == (geometry[1] + 1) * (geometry[2] + 1) - 1)
+ ofs << "pbrk, ";
+ return (dimension > 2) ? 1 : 0;
+}
+
+int all_pbreak(ostream& ofs,
+ int dimension,
+ int* geometry,
+ int position)
+{
+ if ((position + 1) % ((geometry[1] + 1) * (geometry[2] + 1)) == 0)
+ ofs << "pbrk, ";
+ return (dimension < 3) ? 0 : ((geometry[0] == 0) ? 1 : 0);
+}
+
+
+
+//
+// End
+//
+
+
+int no_end(ostream& ofs,
+ int dimension,
+ int* geometry,
+ int position)
+{
+ (void) ofs; (void) dimension; (void) geometry; (void) position;
+ return 0;
+}
+
+int normal_end(ostream& ofs,
+ int dimension,
+ int* geometry,
+ int position)
+{
+ ofs << "end);" << endl;
+ (void) dimension; (void) geometry; (void) position;
+ return 1;
+}
+
+int end_elt(ostream& ofs,
+ int dimension,
+ int* geometry,
+ int position)
+{
+ ofs << "end, 1);" << endl;
+ (void) dimension; (void) geometry; (void) position;
+ return 0;
+}
+
+int end_lbrk(ostream& ofs,
+ int dimension,
+ int* geometry,
+ int position)
+{
+ ofs << "end, lbrk);" << endl;
+ (void) dimension; (void) geometry; (void) position;
+ return 0;
+}
+
+int end_center(ostream& ofs,
+ int dimension,
+ int* geometry,
+ int position)
+{
+ ofs << "end, x());" << endl;
+ (void) dimension; (void) geometry; (void) position;
+ return 0;
+}
+
+int end_starter(ostream& ofs,
+ int dimension,
+ int* geometry,
+ int position)
+{
+ ofs << "end, ints = 1);" << endl;
+ (void) dimension; (void) geometry; (void) position;
+ return 0;
+}
Index: tests/array/gen_test_utils/prelude
--- tests/array/gen_test_utils/prelude (revision 0)
+++ tests/array/gen_test_utils/prelude (revision 0)
@@ -0,0 +1,20 @@
+#include <mlc/array/all.hh>
+
+#include <iostream>
+
+#include "check.hh"
+
+using namespace mlc;
+
+#define OK_OR_FAIL \
+ std::cout << "OK" << std::endl; \
+ else \
+ { \
+ std::cout << "FAIL" << std::endl; \
+ fail = true; \
+ }
+
+bool
+check()
+{
+ bool fail = false;
Index: tests/array/gen_test_utils/errors.hh
--- tests/array/gen_test_utils/errors.hh (revision 0)
+++ tests/array/gen_test_utils/errors.hh (revision 0)
@@ -0,0 +1,22 @@
+#include <iostream>
+#include <fstream>
+
+int one_center(std::ostream&, int, int*, int);
+int if_center(std::ostream&, int, int*, int);
+int all_centers(std::ostream&, int, int*, int);
+int no_comma(std::ostream&, int, int*, int);
+int no_element(std::ostream&, int, int*, int);
+int no_lbreak(std::ostream&, int, int*, int);
+int one_lbreak(std::ostream&, int, int*, int);
+int all_lbreak(std::ostream&, int, int*, int);
+int too_much_lbreak(std::ostream&, int, int*, int);
+int twice_lbreak(std::ostream&, int, int*, int);
+int no_pbreak(std::ostream&, int, int*, int);
+int one_pbreak(std::ostream&, int, int*, int);
+int all_pbreak(std::ostream&, int, int*, int);
+int normal_end(std::ostream&, int, int*, int);
+int no_end(std::ostream&, int, int*, int);
+int end_elt(std::ostream&, int, int*, int);
+int end_lbrk(std::ostream&, int, int*, int);
+int end_center(std::ostream&, int, int*, int);
+int end_starter(std::ostream&, int, int*, int);
Index: tests/array/test_array3d.cc
--- tests/array/test_array3d.cc (revision 0)
+++ tests/array/test_array3d.cc (revision 0)
@@ -0,0 +1,44 @@
+#include <mlc/array/all.hh>
+#include <iostream>
+using std::cout;
+using std::endl;
+
+#include "check.hh"
+
+using namespace mlc;
+
+#define OK_OR_FAIL \
+ std::cout << "OK" << std::endl; \
+ else \
+ { \
+ std::cout << "FAIL" << std::endl; \
+ fail = true; \
+ }
+
+bool
+check()
+{
+ bool fail = false;
+
+ array3d< array3d_info< 2, 2, 3, 1>, int > foo = (ints_3d = 1, x(2), 3,
lbrk,
+ 4, 5, 6, pbrk,
+
+ 7, 8, 9,
+ 10, 11, 12, end);
+
+ cout << endl << "Source:\n\n" << foo << endl;
+
+ try {
+ cout << "After a transposition:\n\n" << foo.transpose()
<< endl;
+ }
+ catch (not_implemented_yet) {
+ cout << endl;
+ }
+
+ cout << "After a central symmetry:\n\n" << -foo << endl;
+
+ if (1)
+ OK_OR_FAIL;
+
+ return fail;
+}
Index: tests/array/Makefile.am
--- tests/array/Makefile.am (revision 0)
+++ tests/array/Makefile.am (revision 0)
@@ -0,0 +1,18 @@
+## Process this file through Automake to create Makefile.in -*- Makefile -*-
+
+include ../check/Makefile.check
+
+check_PROGRAMS = test_array1d test_array2d test_array3d gen_test
+
+test_array1d_SOURCES = test_array1d.cc
+test_array2d_SOURCES = test_array2d.cc
+test_array3d_SOURCES = test_array3d.cc
+
+gen_test_SOURCES = gen_test.cc
+gen_test_LDADD = $(LDADD) gen_test_utils/liberrors.a
+
+check_LIBRARIES = gen_test_utils/liberrors.a
+gen_test_utils_liberrors_a_SOURCES = gen_test_utils/errors.cc gen_test_utils/errors.hh
+
+EXTRA_DIST = gen_test_utils/prelude gen_test_utils/postlude
+CLEANFILES = fail.log success.log a.out gentest_array.cc
Index: tests/array/gen_test.cc
--- tests/array/gen_test.cc (revision 0)
+++ tests/array/gen_test.cc (revision 0)
@@ -0,0 +1,346 @@
+#include "config.h"
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <cstdio>
+#include <iostream>
+#include <fstream>
+#include <sstream>
+#include "gen_test_utils/errors.hh"
+#include "srcdir.hh"
+#include "compile.hh"
+
+using namespace std;
+
+#define MIN_DIMENSION 1
+#define MAX_DIMENSION 3
+
+
+static const struct howto
+{
+ typedef int (*displayer)(ostream&, int, int*, int);
+
+ int ok;
+ displayer element;
+ displayer lbreak;
+ displayer pbreak;
+ displayer terminate;
+ const char* verbose;
+} methods[][16] =
+ {
+ {
+ // 1D
+
+ { 1, one_center, no_lbreak, no_pbreak, normal_end ,
+ "one_center, no_lbreak, no_pbreak, normal_end" },
+ { 1, if_center, no_lbreak, no_pbreak, normal_end ,
+ "if_center, no_lbreak, no_pbreak, normal_end" },
+ { 1, all_centers, no_lbreak, no_pbreak, normal_end ,
+ "all_centers!, no_lbreak, no_pbreak, normal_end" },
+ { 1, one_center, one_lbreak, no_pbreak, normal_end ,
+ "one_center, one_lbreak!, no_pbreak, normal_end" },
+ { 1, one_center, no_lbreak, no_pbreak, no_end ,
+ "one_center, no_lbreak, no_pbreak, no_end!" },
+ { 1, one_center, no_lbreak, no_pbreak, end_elt ,
+ "one_center, no_lbreak, no_pbreak, end_elt!" },
+ { 1, one_center, no_lbreak, no_pbreak, end_center ,
+ "one_center, no_lbreak, no_pbreak, end_center!" },
+ { 1, one_center, no_lbreak, no_pbreak, end_starter ,
+ "one_center, no_lbreak, no_pbreak, end_starter!" },
+ { 1, no_comma, no_lbreak, no_pbreak, normal_end ,
+ "no_comma!, no_lbreak, no_pbreak, normal_end" },
+ { 1, no_element, no_lbreak, no_pbreak, normal_end ,
+ "no_element!, no_lbreak, no_pbreak, normal_end" },
+ { 0, 0, 0, 0, 0, 0 }
+ },
+ {
+ // 2D
+
+ { 1, one_center, one_lbreak, no_pbreak, normal_end ,
+ "one_center, one_lbreak, no_pbreak, normal_end" },
+ { 1, if_center, one_lbreak, no_pbreak, normal_end ,
+ "if_center, one_lbreak, no_pbreak, normal_end" },
+ { 1, all_centers, no_lbreak, no_pbreak, normal_end ,
+ "all_centers!, no_lbreak!, no_pbreak, normal_end" },
+ { 1, one_center, all_lbreak, no_pbreak, normal_end ,
+ "one_center, all_lbreak!, no_pbreak, normal_end" },
+ { 1, one_center, too_much_lbreak, no_pbreak, normal_end ,
+ "one_center, too_much_lbreak!, no_pbreak, normal_end" },
+ { 1, one_center, twice_lbreak, no_pbreak, normal_end ,
+ "one_center, twice_lbreak!, no_pbreak, normal_end" },
+ { 1, one_center, one_lbreak, no_pbreak, no_end ,
+ "one_center, one_lbreak, no_pbreak, no_end!" },
+ { 1, one_center, one_lbreak, no_pbreak, end_elt ,
+ "one_center, one_lbreak, no_pbreak, end_elt!" },
+ { 1, one_center, one_lbreak, no_pbreak, end_lbrk ,
+ "one_center, one_lbreak, no_pbreak, end_lbrk!" },
+ { 1, one_center, one_lbreak, no_pbreak, end_center ,
+ "one_center, one_lbreak, no_pbreak, end_center!" },
+ { 1, one_center, one_lbreak, no_pbreak, end_starter ,
+ "one_center, one_lbreak, no_pbreak, end_starter!" },
+ { 1, no_comma, one_lbreak, no_pbreak, normal_end ,
+ "no_comma!, one_lbreak, no_pbreak, normal_end" },
+ { 1, no_element, one_lbreak, no_pbreak, normal_end ,
+ "no_element!, one_lbreak, no_pbreak, normal_end" },
+ { 0, 0, 0, 0, 0, 0 }
+ },
+ {
+ // 3D
+
+ { 1, one_center, one_lbreak, one_pbreak, normal_end ,
+ "one_center, one_lbreak, one_pbreak, normal_end" },
+ { 1, if_center, one_lbreak, one_pbreak, normal_end ,
+ "if_center, one_lbreak, one_pbreak, normal_end" },
+ { 1, one_center, one_lbreak, no_pbreak, normal_end ,
+ "one_center, one_lbreak, no_pbreak!, normal_end" },
+ { 1, one_center, one_lbreak, all_pbreak, normal_end ,
+ "one_center, one_lbreak, all_pbreak!, normal_end" },
+ { 1, all_centers, no_lbreak, one_pbreak, normal_end ,
+ "all_centers!, no_lbreak!, one_pbreak, normal_end" },
+ { 1, one_center, all_lbreak, one_pbreak, normal_end ,
+ "one_center, all_lbreak!, one_pbreak, normal_end" },
+ { 1, one_center, too_much_lbreak, one_pbreak, normal_end ,
+ "one_center, too_much_lbreak!, one_pbreak, normal_end" },
+ { 1, one_center, twice_lbreak, one_pbreak, normal_end ,
+ "one_center, twice_lbreak!, one_pbreak, normal_end" },
+ { 1, one_center, one_lbreak, one_pbreak, no_end ,
+ "one_center, one_lbreak, one_pbreak, no_end!" },
+ { 1, one_center, one_lbreak, one_pbreak, end_elt ,
+ "one_center, one_lbreak, one_pbreak, end_elt!" },
+ { 1, one_center, one_lbreak, one_pbreak, end_lbrk ,
+ "one_center, one_lbreak, one_pbreak, end_lbrk!" },
+ { 1, one_center, one_lbreak, one_pbreak, end_center ,
+ "one_center, one_lbreak, one_pbreak, end_center!" },
+ { 1, one_center, one_lbreak, one_pbreak, end_starter ,
+ "one_center, one_lbreak, one_pbreak, end_starter!" },
+ { 1, no_comma, one_lbreak, one_pbreak, normal_end ,
+ "no_comma!, one_lbreak, one_pbreak, normal_end" },
+ { 1, no_element, one_lbreak, one_pbreak, normal_end ,
+ "no_element!, one_lbreak, one_pbreak, normal_end" },
+ { 0, 0, 0, 0, 0, 0 }
+ }
+ };
+
+
+
+static void
+copyfile (const string & src, ofstream & dest)
+{
+ ifstream ifs (src.c_str (), ios::in);
+ string buffer;
+
+ while (!ifs.eof ())
+ {
+ getline (ifs, buffer);
+ dest << buffer << endl;
+ }
+}
+
+
+static void
+write_prelude (ofstream & ofs, const char *filename)
+{
+ ofs.open (filename, ios::out);
+ ofs << "// -*-C++-*-" << endl
+ << "// This temporary file was generated for testing purpose
only."
+ << endl
+ << "// It's part of Olena, the static generic image processing
library."
+ << endl << endl;
+
+ copyfile (srcdir + "/gen_test_utils/prelude", ofs);
+}
+
+// #include <fstream>
+
+static bool
+write_postlude_and_test (ofstream & ofs,
+ char *filename,
+ int dimension,
+ howto h,
+ int ok,
+ ofstream & success_log,
+ ofstream & fail_log, const stringstream & decl)
+{
+ copyfile (srcdir + "/gen_test_utils/postlude", ofs);
+ ofs.close ();
+
+ pid_t pid;
+ int fd[2];
+ pipe (fd);
+ bool fail = false;
+
+ if ((pid = fork ()) != -1)
+ if (!pid)
+ {
+ dup2 (fd[1], 2);
+ close (fd[0]);
+ close (fd[1]);
+ // FIXME: clean path generation
+ std::string cmdline = compile_cmd(filename, "",
+ Isrcdir ("../..") + ' '
+ + Isrcdir ("../check") + ' '
+ + "-I../../../olena -I../../.. "
+ + "-L../check -lcheck " +
+ cxxflags_strict_errors());
+ int ret = system (cmdline.c_str ());
+ exit (WEXITSTATUS (ret));
+ }
+ else
+ {
+ close (fd[1]);
+ stringstream header;
+ header << endl << "=== Compiling : [" << dimension <<
"D]\t"
+ << h.verbose << endl
+ << "=== Expected : " << (ok ? "PASS" :
"FAIL") << endl << endl;
+
+ stringstream compile_mesg;
+ char buffer[32];
+ {
+ int r;
+ while ((r = read (fd[0], buffer, 32)) != 0)
+ compile_mesg.write (buffer, r);
+ }
+ int status;
+ if (waitpid (pid, &status, 0) == -1)
+ abort ();
+ if ((WEXITSTATUS (status) || ok) && !(WEXITSTATUS (status) && ok))
+ {
+ success_log << header.str () << decl.str ()
+ << endl << compile_mesg.
+ str () << "Exit status = " << WEXITSTATUS (status) <<
endl <<
+
"==========================================================================="
+ << endl;
+ cerr << (ok ? "PASS" : "XFAIL");
+ }
+ else
+ {
+ fail_log << header.str () << decl.str () << endl <<
compile_mesg.
+ str () << "Exit status = " << WEXITSTATUS (status) <<
endl <<
+
"==========================================================================="
+ << endl;
+ cerr << (ok ? "FAIL" : "XPASS");
+ fail = true;
+ }
+ close (fd[0]);
+ cerr << ": [" << dimension << "D]\t" <<
h.verbose << endl;
+ }
+ return fail;
+}
+
+
+
+static int
+fill_array (ostream & ofs, int dimension, int *geometry, howto h)
+{
+ int *cur_dim = (int *) malloc (dimension * sizeof (int));
+ for (int i = dimension - 1; 0 <= i; --i)
+ cur_dim[i] = geometry[i];
+ ++cur_dim[dimension - 1];
+
+ bool finished = false;
+ int position = 0;
+ int ok = h.ok;
+ while (!finished)
+ {
+ for (int d = dimension - 1; 0 <= d; --d)
+ if (0 <= --cur_dim[d])
+ break;
+ else
+ {
+ cur_dim[d] = geometry[d];
+ ofs << endl << "\t\t";
+ }
+
+ ok &= h.element (ofs, dimension, geometry, position);
+ ok &= h.lbreak (ofs, dimension, geometry, position);
+ ok &= h.pbreak (ofs, dimension, geometry, position);
+ ++position;
+ finished = true;
+ for (int i = dimension - 1; 0 <= i; --i)
+ finished &= (cur_dim[i] == 0);
+ }
+ ok &= h.terminate (ofs, dimension, geometry, position);
+ return ok;
+}
+
+
+static bool
+write_file (string filename,
+ int dimension,
+ int *geometry,
+ howto h, ofstream & success_log, ofstream & fail_log)
+{
+ ofstream ofs;
+ write_prelude (ofs, filename.c_str ());
+
+ int middle = geometry[0] + 1;
+ for (int i = dimension - 1; 0 < i; --i)
+ middle *= (geometry[i] + 1);
+ middle = middle >> 1;
+
+ stringstream decl;
+ decl << " array" << dimension << "d< array"
<< dimension << "d_info< ";
+ for (int i = 0; i < dimension; ++i)
+ decl << (geometry[i] + 1) << (i == dimension - 1 ? "" : ",
");
+ for (int i = 0; i < dimension; ++i)
+ if (1 == (geometry[i] & 1))
+ {
+ decl << ", 0";
+ break;
+ }
+ decl << " >, int > foo = (ints_" << dimension <<
"d = " << endl << "\t\t";
+ int ok;
+ ok = fill_array (decl, dimension, geometry, h);
+
+ ofs << decl.str ();
+ return write_postlude_and_test (ofs,
+ const_cast < char *>(filename.c_str ()),
+ dimension, h, ok, success_log, fail_log,
+ decl);
+}
+
+
+bool
+check ()
+{
+ string filename = "gentest_array.cc";
+
+ ofstream success_log ("success.log", ios::out);
+ ofstream fail_log ("fail.log", ios::out);
+
+ bool fail = false;;
+
+ for (int dimension = MIN_DIMENSION; dimension <= MAX_DIMENSION; ++dimension)
+ {
+ int *current_geometry = (int *) malloc (dimension * sizeof (int));
+ for (int i = dimension - 1; i >= 0; --i)
+ current_geometry[i] = 2;
+ current_geometry[dimension - 1] = 3;
+
+ bool finished = false;
+ while (!finished)
+ {
+ for (int i = dimension - 1; i >= 0; --i)
+ if (0 <= --current_geometry[i])
+ break;
+ else
+ current_geometry[i] = 2;
+ finished = true;
+ for (int i = dimension - 1; i >= 0; --i)
+ if (current_geometry[i] > 0)
+ finished = false;
+
+ for (int i = 0; methods[dimension - 1][i].element != 0; ++i)
+ fail |= write_file (filename, dimension, current_geometry,
+ methods[dimension - 1][i],
+ success_log, fail_log);
+ }
+ free (current_geometry);
+ }
+ success_log.close ();
+ fail_log.close ();
+ remove (filename.c_str ());
+ remove ("./a.out");
+ return fail;
+}