mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
ENH: add fileName::validate static method (issue #628)
- similar to word::validate to allow stripping of invalid characters without triggering a FatalError. - use this validated fileName in Foam::readDir to avoid problems when a directory contains files with invalid characters in their names - adjust rmDir to handle filenames with invalid characters - fileName::equals() static method to compare strings while ignoring any differences that are solely due to duplicate slashes
This commit is contained in:
@ -3,7 +3,7 @@
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||
\\/ M anipulation | Copyright (C) 2016 OpenCFD Ltd.
|
||||
\\/ M anipulation | Copyright (C) 2016-2017 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -39,15 +39,135 @@ Description
|
||||
#include "POSIX.H"
|
||||
#include "Switch.H"
|
||||
#include "etcFiles.H"
|
||||
#include "Pair.H"
|
||||
#include "Tuple2.H"
|
||||
#include <fstream>
|
||||
|
||||
using namespace Foam;
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
unsigned testStrip
|
||||
(
|
||||
const bool doClean,
|
||||
std::initializer_list
|
||||
<
|
||||
Tuple2<bool, std::string>
|
||||
> tests
|
||||
)
|
||||
{
|
||||
Info<< nl << "Checking with clean=" << Switch(doClean) << nl << endl;
|
||||
|
||||
unsigned nFail = 0;
|
||||
|
||||
for (const Tuple2<bool, std::string>& test : tests)
|
||||
{
|
||||
const bool expected = test.first();
|
||||
const std::string& input = test.second();
|
||||
|
||||
fileName output(fileName::validate(input, doClean));
|
||||
|
||||
// Check for real failure (invalid chars) vs.
|
||||
// spurious failure (removed double slashes with 'doClean').
|
||||
|
||||
const bool same =
|
||||
(
|
||||
doClean
|
||||
? fileName::equals(input, output)
|
||||
: (input == output)
|
||||
);
|
||||
|
||||
if (same)
|
||||
{
|
||||
if (expected)
|
||||
{
|
||||
Info<< "(pass) validated " << input << " = " << output << nl;
|
||||
}
|
||||
else
|
||||
{
|
||||
++nFail;
|
||||
Info<< "(fail) unexpected success for " << input << nl;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (expected)
|
||||
{
|
||||
++nFail;
|
||||
Info<< "(fail) unexpected";
|
||||
}
|
||||
else
|
||||
{
|
||||
Info<< "(pass) expected";
|
||||
}
|
||||
|
||||
Info<< " failure for " << input << nl;
|
||||
}
|
||||
}
|
||||
|
||||
return nFail;
|
||||
}
|
||||
|
||||
|
||||
unsigned testEquals
|
||||
(
|
||||
std::initializer_list
|
||||
<
|
||||
Tuple2<bool, Pair<std::string>>
|
||||
> tests
|
||||
)
|
||||
{
|
||||
Info<< nl << "Checking fileName::equals()" << nl << endl;
|
||||
|
||||
unsigned nFail = 0;
|
||||
|
||||
for (const Tuple2<bool, Pair<std::string>>& test : tests)
|
||||
{
|
||||
const bool expected = test.first();
|
||||
const std::string& s1 = test.second().first();
|
||||
const std::string& s2 = test.second().second();
|
||||
|
||||
const bool same = fileName::equals(s1, s2);
|
||||
|
||||
if (same)
|
||||
{
|
||||
if (expected)
|
||||
{
|
||||
Info<< "(pass) success";
|
||||
}
|
||||
else
|
||||
{
|
||||
++nFail;
|
||||
Info<< "(fail) unexpected success";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (expected)
|
||||
{
|
||||
++nFail;
|
||||
Info<< "(fail) unexpected failure";
|
||||
}
|
||||
else
|
||||
{
|
||||
Info<< "(pass) expected failure";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Info<< " for " << s1 << " == " << s2 << nl;
|
||||
}
|
||||
return nFail;
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
// Main program:
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
argList::noParallel();
|
||||
argList::addBoolOption("validate", "test fileName::validate");
|
||||
argList::addBoolOption("ext", "test handing of file extensions");
|
||||
argList::addBoolOption("construct", "test constructors");
|
||||
argList::addBoolOption("default", "reinstate default tests");
|
||||
@ -235,6 +355,69 @@ int main(int argc, char *argv[])
|
||||
Info<< nl;
|
||||
}
|
||||
|
||||
|
||||
if (args.optionFound("validate"))
|
||||
{
|
||||
unsigned nFail = 0;
|
||||
Info<< nl << "Test fileName::validate" << nl;
|
||||
|
||||
// Without clean
|
||||
nFail += testEquals
|
||||
(
|
||||
{
|
||||
{ true, { "abc", "abc/" } },
|
||||
{ true, { "///abc/", "//abc///" } },
|
||||
{ false, { " ab //c/", "ab/c" } },
|
||||
}
|
||||
);
|
||||
|
||||
Info<< nl << "Test fileName::validate" << nl;
|
||||
|
||||
// Without clean
|
||||
nFail += testStrip
|
||||
(
|
||||
false,
|
||||
{
|
||||
{ true, "abc/" },
|
||||
{ true, "/", },
|
||||
{ true, "//", },
|
||||
{ true, "/abc/def", },
|
||||
{ true, "/abc/def/", },
|
||||
{ false, "/abc def" },
|
||||
{ true, "/abc////def///", },
|
||||
{ false, "/abc//// def///" },
|
||||
}
|
||||
);
|
||||
|
||||
// With clean
|
||||
nFail += testStrip
|
||||
(
|
||||
true,
|
||||
{
|
||||
{ true, "abc/" },
|
||||
{ true, "/" },
|
||||
{ true, "//" },
|
||||
{ true, "/abc/def" },
|
||||
{ true, "/abc/def/" },
|
||||
{ false, "/abc def" },
|
||||
{ true, "/abc////def///" },
|
||||
{ false, "/abc//// def///" },
|
||||
}
|
||||
);
|
||||
|
||||
Info<< nl;
|
||||
if (nFail)
|
||||
{
|
||||
Info<< "failed " << nFail;
|
||||
}
|
||||
else
|
||||
{
|
||||
Info<< "passed all";
|
||||
}
|
||||
Info<< " fileName::validate tests" << nl;
|
||||
}
|
||||
|
||||
|
||||
if (!defaultTests)
|
||||
{
|
||||
return 0;
|
||||
@ -312,10 +495,32 @@ int main(int argc, char *argv[])
|
||||
Foam::rm(lnB);
|
||||
Foam::rmDir(dirB);
|
||||
|
||||
Info<< nl << "=========================" << nl
|
||||
<< "Test some copying and deletion" << endl;
|
||||
|
||||
|
||||
Info<< "Creating directory " << dirA << endl;
|
||||
Foam::mkDir(dirA);
|
||||
|
||||
Info<< "Populating with various files" << endl;
|
||||
for
|
||||
(
|
||||
const std::string name
|
||||
: { "file-1", "file-2", "bad name one", "bad name 2" }
|
||||
)
|
||||
{
|
||||
// Full path, but without any stripping
|
||||
const fileName file
|
||||
(
|
||||
(static_cast<const std::string&>(dirA) + "/" + name),
|
||||
false
|
||||
);
|
||||
|
||||
Info<<" create: " << file << endl;
|
||||
|
||||
std::ofstream os(file);
|
||||
os << "file=<" << file << ">" << nl;
|
||||
}
|
||||
|
||||
const int oldPosix = POSIX::debug;
|
||||
POSIX::debug = 1;
|
||||
@ -362,7 +567,7 @@ int main(int argc, char *argv[])
|
||||
<< " but is " << lnB.type(true) << exit(FatalError);
|
||||
}
|
||||
|
||||
// Delete
|
||||
// Delete (link)
|
||||
Foam::rm(lnB);
|
||||
}
|
||||
|
||||
@ -379,12 +584,13 @@ int main(int argc, char *argv[])
|
||||
<< " but is " << lnB.type(false) << exit(FatalError);
|
||||
}
|
||||
|
||||
// Delete
|
||||
Foam::rm(lnB);
|
||||
// Delete (directory, not link)
|
||||
Foam::rmDir(lnB);
|
||||
}
|
||||
|
||||
POSIX::debug = oldPosix;
|
||||
|
||||
// Verify that rmDir works with bad names too
|
||||
Foam::rmDir(dirA);
|
||||
Foam::rm(lnA);
|
||||
}
|
||||
|
||||
@ -51,7 +51,10 @@ template<class TYPE>
|
||||
unsigned testParsing
|
||||
(
|
||||
TYPE (*function)(const std::string&),
|
||||
const List<Tuple2<std::string, bool>>& tests
|
||||
std::initializer_list
|
||||
<
|
||||
Tuple2<bool, std::string>
|
||||
> tests
|
||||
)
|
||||
{
|
||||
unsigned nFail = 0;
|
||||
@ -60,10 +63,10 @@ unsigned testParsing
|
||||
// Expect some failures
|
||||
const bool prev = FatalIOError.throwExceptions();
|
||||
|
||||
for (const Tuple2<std::string, bool>& test : tests)
|
||||
for (const Tuple2<bool, std::string>& test : tests)
|
||||
{
|
||||
const std::string& str = test.first();
|
||||
const bool expected = test.second();
|
||||
const bool expected = test.first();
|
||||
const std::string& str = test.second();
|
||||
|
||||
bool parsed = true;
|
||||
|
||||
@ -124,18 +127,18 @@ int main(int argc, char *argv[])
|
||||
(
|
||||
&readDouble,
|
||||
{
|
||||
{ "", false },
|
||||
{ " ", false },
|
||||
{ " xxx ", false },
|
||||
{ " 1234E-", false },
|
||||
{ " 1234E junk", false },
|
||||
{ " 3.14159 ", true },
|
||||
{ " 31.4159E-1 " , true },
|
||||
{ " 100E1000 " , false },
|
||||
{ " 1E-40 " , true },
|
||||
{ " 1E-305 " , true },
|
||||
{ " 1E-37 " , true },
|
||||
{ " 1E-300 " , true },
|
||||
{ false, "" },
|
||||
{ false, " " },
|
||||
{ false, " xxx " },
|
||||
{ false, " 1234E-" },
|
||||
{ false, " 1234E junk" },
|
||||
{ true, " 3.14159 " },
|
||||
{ true, " 31.4159E-1 " },
|
||||
{ false, " 100E1000 " },
|
||||
{ true, " 1E-40 " },
|
||||
{ true, " 1E-305 " },
|
||||
{ true, " 1E-37 " },
|
||||
{ true, " 1E-300 " },
|
||||
}
|
||||
);
|
||||
}
|
||||
@ -148,14 +151,14 @@ int main(int argc, char *argv[])
|
||||
(
|
||||
&readFloat,
|
||||
{
|
||||
{ " 3.14159 ", true },
|
||||
{ " 31.4159E-1 " , true },
|
||||
{ " 31.4159E200 " , false },
|
||||
{ " 31.4159E20 " , true },
|
||||
{ " 1E-40 " , true },
|
||||
{ " 1E-305 " , true },
|
||||
{ " 1E-37 " , true },
|
||||
{ " 1E-300 " , true },
|
||||
{ true, " 3.14159 " },
|
||||
{ true, " 31.4159E-1 " },
|
||||
{ false, " 31.4159E200 " },
|
||||
{ true, " 31.4159E20 " },
|
||||
{ true, " 1E-40 " },
|
||||
{ true, " 1E-305 " },
|
||||
{ true, " 1E-37 " },
|
||||
{ true, " 1E-300 " },
|
||||
}
|
||||
);
|
||||
}
|
||||
@ -166,15 +169,15 @@ int main(int argc, char *argv[])
|
||||
(
|
||||
&readNasScalar,
|
||||
{
|
||||
{ " 3.14159 ", true },
|
||||
{ " 31.4159E-1 " , true },
|
||||
{ " 314.159-2 " , true },
|
||||
{ " 31.4159E200 " , true },
|
||||
{ " 31.4159E20 " , true },
|
||||
{ " 1E-40 " , true },
|
||||
{ " 1E-305 " , true },
|
||||
{ " 1E-37 " , true },
|
||||
{ " 1E-300 " , true },
|
||||
{ true, " 3.14159 " },
|
||||
{ true, " 31.4159E-1 " },
|
||||
{ true, " 314.159-2 " },
|
||||
{ true, " 31.4159E200 " },
|
||||
{ true, " 31.4159E20 " },
|
||||
{ true, " 1E-40 " },
|
||||
{ true, " 1E-305 " },
|
||||
{ true, " 1E-37 " },
|
||||
{ true, " 1E-300 " },
|
||||
}
|
||||
);
|
||||
}
|
||||
@ -185,12 +188,12 @@ int main(int argc, char *argv[])
|
||||
(
|
||||
&readInt32,
|
||||
{
|
||||
{ " 3.14159 ", false },
|
||||
{ " 31E1 ", false },
|
||||
{ " 31.4159E-1 " , false },
|
||||
{ "100" , true },
|
||||
{ " 2147483644" , true },
|
||||
{ " 2147483700 " , false },
|
||||
{ false, " 3.14159 " },
|
||||
{ false, " 31E1 " },
|
||||
{ false, " 31.4159E-1 " },
|
||||
{ true, "100" },
|
||||
{ true, " 2147483644" },
|
||||
{ false, " 2147483700 " },
|
||||
}
|
||||
);
|
||||
}
|
||||
@ -202,10 +205,10 @@ int main(int argc, char *argv[])
|
||||
(
|
||||
&readUint32,
|
||||
{
|
||||
{ " 2147483644" , true },
|
||||
{ " 2147483700 " , true },
|
||||
{ " 4294967295 " , true },
|
||||
{ " 4294968000 " , false },
|
||||
{ true, "\t2147483644" },
|
||||
{ true, " 2147483700 " },
|
||||
{ true, " 4294967295 " },
|
||||
{ false, " 4294968000 " },
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user