2
This file is part of hugin.
4
hugin is free software: you can redistribute it and/or modify
5
it under the terms of the GNU General Public License as published by
6
the Free Software Foundation, either version 2 of the License, or
7
(at your option) any later version.
9
hugin is distributed in the hope that it will be useful,
10
but WITHOUT ANY WARRANTY; without even the implied warranty of
11
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
GNU General Public License for more details.
14
You should have received a copy of the GNU General Public License
15
along with hugin. If not, see <http://www.gnu.org/licenses/>.
19
* @file test_filenames.cpp
20
* @brief Tester that tries to feed a lot of possible characters
21
* as filenames into the makefilelib, make, and the filesystem.
23
* Created on: Jul 16, 2010
24
* @author Florian Achleitner <florian.achleitner.2.6.31@gmail.com>
27
#include "char_type.h"
31
#include "VariableDef.h"
32
#include "VariableRef.h"
33
#include "MakefileItem.h"
35
#include "AutoVariable.h"
38
#include "Conditional.h"
39
#include "StringAdapter.h"
41
#include "test_util.h"
46
using namespace makefile;
47
using namespace makefile::tester;
48
namespace fs = boost::filesystem;
51
ostream& cout = std::wcout;
52
ostream& cerr = std::wcerr;
54
ostream& cout = std::cout;
55
ostream& cerr = std::cerr;
61
* Prints the tested characters.
65
void printchars(ostream& out, wchar_t limit)
68
for(c = 0x20; c < limit; c++)
75
* Tries to create files with names from 0x20 to limit using boost::filesystem.
77
* @param limit Upper limit for filenames
78
* @return Filenames that couldn't be found after creation.
80
std::vector<path> createfiles_direct(const path dir, uchar_type limit)
82
std::vector<path> miss;
83
char_type c[] = cstr("X.1");
84
for(*c = START; static_cast<uchar_type>(*c) < limit; (*c)++)
87
ofstream file(dir / filename);
89
if(!fs::exists(dir / filename))
91
miss.push_back(filename);
97
* Tries to create files with names from 0x20 to limit by calling make.
98
* It first writes a makefile of this structure:
105
* Afterwards make is called with system() and creates the file by executing touch.
108
* @param limit Upper limit for filenames
109
* @return Filenames that couldn't be found after creation.
111
std::vector<path> createfiles_make(const path dir, uchar_type limit)
113
const path makefile(cstr("makefile"));
114
std::vector<path> miss;
115
char_type c[] = cstr("X.1");
116
for(*c = START; static_cast<uchar_type>(*c) < limit; (*c)++)
120
// If the filename cannot be stored in a Variable, theres no chance to bring it through.
122
makefile::Variable mffilename(cstr("FILENAME"), (dir / filename).string(), makefile::Makefile::SHELL);
124
makefile::Rule touch;
125
touch.addTarget(cstr("all"));
126
touch.addCommand(cstr("@touch ") + mffilename.getRef().toString());
128
mffilename.getDef().add();
131
string dirstring = dir.string();
132
std::stringbuf makeout, makeerr;
133
int ret = exec_make(makeout, makeerr);
138
std::cerr << "make returned " << ret << std::endl;
139
std::cout << makeout.str();
140
std::cerr << makeerr.str();
143
catch(std::exception& e) {
144
std::cerr << "Variable exception: " << e.what() << std::endl;
147
if(!fs::exists(dir / filename))
149
miss.push_back(filename);
155
* Removes and recreates the output directories.
157
* @return 0 on success, 1 on error.
159
int cleandir(path dir)
161
if(fs::is_directory(dir))
163
if(!fs::create_directories(dir))
165
cerr << cstr("Error creating directory ") << dir.string() << std::endl;
171
void printmiss(std::vector<path>::iterator start, std::vector<path>::iterator end)
173
for(std::vector<path>::iterator i = start; i != end; i++)
175
string s = i->string();
176
unsigned long first = 0;
177
first = static_cast<uchar_type>(s[0]);
178
cout << s << cstr("\t (0x") << std::hex << first << cstr(")\n");
182
int main(int argc, char *argv[])
187
std::cerr << "Specify a limit as first argument" << std::endl;
190
limit = std::atoi(argv[1]);
192
std::cout << "Creating " << static_cast<unsigned long>(limit) - START << " files in" << std::endl;
194
path basepath(fs::initial_path<path>() / cstr("chartest_direct"));
195
path basepathmake(fs::initial_path<path>() / cstr("chartest_make"));
197
cout << basepath.string() << std::endl;
198
cout << basepathmake.string() << std::endl;
200
if(cleandir(basepath) || cleandir(basepathmake))
203
// ofstream outfile(basepath / cstr("tf.out"));
204
// printchars(outfile, limit);
206
std::vector<path> miss_direct = createfiles_direct(basepath, limit);
207
cout << cstr("Direct: Missing files ") << miss_direct.size() << std::endl;
208
printmiss(miss_direct.begin(), miss_direct.end());
211
std::vector<path> miss_make = createfiles_make(basepathmake, limit);
212
cout << cstr("Make: Missing files ") << miss_make.size() << std::endl;
213
printmiss(miss_make.begin(), miss_make.end());