Merge branch 'master' of /home/noisy3/OpenFOAM/OpenFOAM-dev

This commit is contained in:
andy
2011-03-01 17:14:41 +00:00
41 changed files with 1678 additions and 1039 deletions

View File

@ -140,7 +140,7 @@
+ only files that can be re-read are being checked. Drastic reduction of
number of files to check.
*** *New* #codeStream dictionary entry
Uses on-the-fly compilation of OpenFOAM C++ code to construct dictionary.
Uses dynamic compilation of OpenFOAM C++ code to construct dictionary.
E.g. in blockMeshDict:
#+BEGIN_SRC c++
convertToMeters 0.001;
@ -160,7 +160,7 @@
#};
}
#+END_SRC
See also ./[[doc/changes/codeStream.org]]
See also ./[[doc/changes/dynamicCode.org]]
* Solvers
A number of new solvers have been developed for a range of engineering
@ -191,7 +191,7 @@
+ takes optional fieldName to sample
+ directMapped patch added 'normal' method to calculate sample points
to e.g. sample fields just above wall (e.g. for streaklines)
+ *New* codedFixedValue: Uses the on-the-fly code compilation from #codeStream
+ *New* codedFixedValue: Uses the dynamic code compilation from #codeStream
to provide an in-line fixedValueFvPatchScalarField. E.g.
#+BEGIN_SRC c++
outlet
@ -206,7 +206,7 @@
#};
}
#+END_SRC
See also [[./doc/changes/codeStream.org]]
See also [[./doc/changes/dynamicCode.org]]
* Utilities
There have been some utilities added and updated in this release.

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-2010 OpenCFD Ltd.
\\ / A nd | Copyright (C) 2004-2011 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -47,7 +47,7 @@ cellShape extrudedQuadCellShape
faceList& frontAndBackFaces
)
{
const static cellModel* hexModelPtr_ = NULL;
static const cellModel* hexModelPtr_ = NULL;
if (!hexModelPtr_)
{

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-2010 OpenCFD Ltd.
\\ / A nd | Copyright (C) 2004-2011 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -48,7 +48,7 @@ cellShape extrudedTriangleCellShape
faceList& frontAndBackFaces
)
{
const static cellModel* prismModelPtr_ = NULL;
static const cellModel* prismModelPtr_ = NULL;
if (!prismModelPtr_)
{

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-2010 OpenCFD Ltd.
\\ / A nd | Copyright (C) 2004-2011 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -32,7 +32,7 @@ Description
void sammMesh::calcPointCells() const
{
const static label UNIT_POINT_CELLS = 12;
static const label UNIT_POINT_CELLS = 12;
if (pointCellsPtr_)
{

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-2010 OpenCFD Ltd.
\\ / A nd | Copyright (C) 2004-2011 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -32,7 +32,7 @@ Description
void starMesh::calcPointCells() const
{
const static label UNIT_POINT_CELLS = 12;
static const label UNIT_POINT_CELLS = 12;
if (pointCellsPtr_)
{

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-2010 OpenCFD Ltd.
\\ / A nd | Copyright (C) 2004-2011 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -25,8 +25,8 @@ Class
Foam::readerDatabase
Description
Singleton caching OpenFOAM database and mesh and various. Used in Fv reader
to keep track of data inbetween callbacks.
Singleton caching OpenFOAM database and mesh and various.
Used in Fv reader to keep track of data in between callbacks.
SourceFiles
readerDatabase.C
@ -107,7 +107,7 @@ public:
//- Debug flag. Note: uses envvar instead of controlDict since
// *this is static as well. Might be initialized before controlDict
// read.
const static bool debug_;
static const bool debug_;
// Constructors

View File

@ -57,13 +57,13 @@ cleanTimeDirectories()
#
# Remove codeStream subdirectory if it looks appropriate
# Remove dynamicCode subdirectory if it looks appropriate
#
cleanCodeStream()
cleanDynamicCode()
{
if [ -d system -a -d codeStream ]
if [ -d system -a -d dynamicCode ]
then
rm -rf codeStream > /dev/null 2>&1
rm -rf dynamicCode > /dev/null 2>&1
fi
}
@ -71,7 +71,7 @@ cleanCodeStream()
cleanCase()
{
cleanTimeDirectories
cleanCodeStream
cleanDynamicCode
rm -rf processor* > /dev/null 2>&1
rm -rf probes* > /dev/null 2>&1

View File

@ -1,6 +1,6 @@
# -*- mode: org; -*-
#
#+TITLE: =codeStream=: On-the-fly code compilation
#+TITLE: =dynamicCode=: Dynamic code compilation
#+AUTHOR: OpenCFD Ltd.
#+DATE: TBA
#+LINK: http://www.openfoam.com
@ -13,7 +13,7 @@
provide the actual dictionary entry. The snippet gets provided as three
sections of C++ code which just gets inserted into a template:
- =code= section: the actual body of the code. It gets called with arguments
=const dictionary& dict, OStream& os= and the C++ code can do a
=OStream& os, const dictionary& dict= and the C++ code can do a
=dict.lookup= to find current dictionary values.
- optional =codeInclude= section: any #include statements to include OpenFOAM
files.
@ -47,12 +47,13 @@
=code=, =codeInclude=, =codeOptions= sections (these are just strings) and
calculates the SHA1 checksum of the contents.
- it copies a template file
=($FOAM_CODESTREAM_TEMPLATES/codeStreamTemplate.C)=, substituting all
=(~OpenFOAM/codeTemplates/dynamicCode/codeStreamTemplate.C)= or
=($FOAM_CODE_TEMPLATES/codeStreamTemplate.C)=, substituting all
occurences of =code=, =codeInclude=, =codeOptions=.
- it writes library source files to =codeStream/<SHA1>= and compiles
- it writes library source files to =dynamicCode/<SHA1>= and compiles
it using =wmake libso=.
- the resulting library is generated under
=codeStream/platforms/$WM_OPTIONS/lib= and is loaded (=dlopen=, =dlsym=)
=dynamicCode/platforms/$WM_OPTIONS/lib= and is loaded (=dlopen=, =dlsym=)
and the function executed
- the function will have written its output into the Ostream which then gets
used to construct the entry to replace the whole =#codeStream= section.

View File

@ -44,8 +44,8 @@ extern "C"
{
void ${typeName}
(
const dictionary& dict,
Ostream& os
Ostream& os,
const dictionary& dict
)
{
//{{{ begin code

View File

@ -39,6 +39,9 @@ namespace Foam
extern "C"
{
// dynamicCode:
// SHA1 = ${SHA1sum}
//
// unique function name that can be checked if the correct library version
// has been loaded
bool ${typeName}_${SHA1sum}()
@ -48,7 +51,6 @@ extern "C"
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
${typeName}FixedValueFvPatchScalarField::
@ -108,6 +110,13 @@ ${typeName}FixedValueFvPatchScalarField
{}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
${typeName}FixedValueFvPatchScalarField::
~${typeName}FixedValueFvPatchScalarField()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void ${typeName}FixedValueFvPatchScalarField::updateCoeffs()
@ -124,7 +133,7 @@ void ${typeName}FixedValueFvPatchScalarField::updateCoeffs()
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
makePatchTypeField
makeRemovablePatchTypeField
(
fvPatchScalarField,
${typeName}FixedValueFvPatchScalarField

View File

@ -121,6 +121,9 @@ public:
);
}
//- Destructor
virtual ~${typeName}FixedValueFvPatchScalarField();
// Member functions

View File

@ -39,7 +39,7 @@ InfoSwitches
writePrecision 6;
writeJobInfo 0;
// Allow case-supplied c++ code (#codeStream, codedFixedValue)
// Allow case-supplied C++ code (#codeStream, codedFixedValue)
allowSystemOperations 0;
}

View File

@ -63,8 +63,9 @@ setenv FOAM_SITE_LIBBIN $WM_PROJECT_INST_DIR/site/$WM_PROJECT_VERSION/platforms/
setenv FOAM_USER_APPBIN $WM_PROJECT_USER_DIR/platforms/$WM_OPTIONS/bin
setenv FOAM_USER_LIBBIN $WM_PROJECT_USER_DIR/platforms/$WM_OPTIONS/lib
# codeStream templates
setenv FOAM_CODESTREAM_TEMPLATE_DIR $WM_PROJECT_DIR/etc/codeTemplates/codeStream
# dynamicCode templates
# - default location is the "~OpenFOAM/codeTemplates/dynamicCode" expansion
# setenv FOAM_CODE_TEMPLATES $WM_PROJECT_DIR/etc/codeTemplates/dynamicCode
# convenience
setenv FOAM_APP $WM_PROJECT_DIR/applications

View File

@ -86,8 +86,9 @@ export FOAM_SITE_LIBBIN=$WM_PROJECT_INST_DIR/site/$WM_PROJECT_VERSION/platforms/
export FOAM_USER_APPBIN=$WM_PROJECT_USER_DIR/platforms/$WM_OPTIONS/bin
export FOAM_USER_LIBBIN=$WM_PROJECT_USER_DIR/platforms/$WM_OPTIONS/lib
# codeStream templates
export FOAM_CODESTREAM_TEMPLATE_DIR=$WM_PROJECT_DIR/etc/codeTemplates/codeStream
# dynamicCode templates
# - default location is the "~OpenFOAM/codeTemplates/dynamicCode" expansion
# export FOAM_CODE_TEMPLATES=$WM_PROJECT_DIR/etc/codeTemplates/dynamicCode
# convenience
export FOAM_APP=$WM_PROJECT_DIR/applications

View File

@ -1086,17 +1086,44 @@ bool Foam::dlClose(void* handle)
void* Foam::dlSym(void* handle, const std::string& symbol)
{
// clear any old errors - see manpage dlopen
(void) ::dlerror();
// get address of symbol
void* fun = ::dlsym(handle, symbol.c_str());
char *error;
if ((error = dlerror()) != NULL)
// find error (if any)
char *error = ::dlerror();
if (error)
{
WarningIn("dlSym(void*, const std::string&)")
<< "Cannot lookup symbol " << symbol << " : " << error
<< endl;
}
return fun;
}
bool Foam::dlSymFound(void* handle, const std::string& symbol)
{
if (handle && !symbol.empty())
{
// clear any old errors - see manpage dlopen
(void) ::dlerror();
// get address of symbol
(void) ::dlsym(handle, symbol.c_str());
// symbol can be found if there was no error
return !::dlerror();
}
else
{
return false;
}
}
// ************************************************************************* //

View File

@ -189,8 +189,9 @@ db/objectRegistry/objectRegistry.C
db/CallbackRegistry/CallbackRegistryName.C
dll = db/dynamicLibrary
$(dll)/codeStream/codeStreamTools.C
$(dll)/dlLibraryTable/dlLibraryTable.C
$(dll)/dynamicCode/dynamicCode.C
$(dll)/dynamicCode/dynamicCodeContext.C
db/functionObjects/functionObject/functionObject.C
db/functionObjects/functionObjectList/functionObjectList.C

View File

@ -28,10 +28,9 @@ License
#include "IStringStream.H"
#include "OStringStream.H"
#include "IOstreams.H"
#include "SHA1Digest.H"
#include "OSHA1stream.H"
#include "codeStreamTools.H"
#include "stringOps.H"
#include "dynamicCode.H"
#include "dynamicCodeContext.H"
#include "dlLibraryTable.H"
#include "OSspecific.H"
#include "Time.H"
@ -71,7 +70,7 @@ bool Foam::functionEntries::codeStream::execute
Istream& is
)
{
codeStreamTools::checkSecurity
dynamicCode::checkSecurity
(
"functionEntries::codeStream::execute(..)",
parentDict
@ -81,141 +80,82 @@ bool Foam::functionEntries::codeStream::execute
// must reference parent for stringOps::expand to work nicely
dictionary codeDict("#codeStream", parentDict, is);
// get code, codeInclude, codeOptions
dynamicCodeContext context(codeDict);
// Read three sections of code.
// Remove any leading whitespace - necessary for compilation options,
// convenience for includes and body.
// "codeInclude" is optional
string codeInclude;
if (codeDict.found("codeInclude"))
{
codeInclude = stringOps::trim(codeDict["codeInclude"]);
stringOps::inplaceExpand(codeInclude, codeDict);
}
// "codeOptions" is optional
string codeOptions;
if (codeDict.found("codeOptions"))
{
codeOptions = stringOps::trim(codeDict["codeOptions"]);
stringOps::inplaceExpand(codeOptions, codeDict);
}
// "code" is mandatory
string code = stringOps::trim(codeDict["code"]);
stringOps::inplaceExpand(code, codeDict);
// Create SHA1 digest from the contents
SHA1Digest sha;
{
OSHA1stream os;
os << codeInclude << codeOptions << code;
sha = os.digest();
}
// codeName = prefix + sha1
const fileName codeName = "codeStream_" + sha.str();
// write code into _SHA1 subdir
const fileName codePath = codeStreamTools::codePath("_" + sha.str());
// write library into platforms/$WM_OPTIONS/lib subdir
const fileName libPath = codeStreamTools::libPath(codeName);
// codeName: codeStream + _<sha1>
// codeDir : _<sha1>
dynamicCode dynCode
(
"codeStream" + context.sha1().str(true),
context.sha1().str(true)
);
// Load library if not already loaded
// Version information is encoded in the libPath (encoded with the SHA1)
const fileName libPath = dynCode.libPath();
// see if library is loaded
void* lib = dlLibraryTable::findLibrary(libPath);
// try to load if not already loaded
bool reuseLib = false;
// nothing loaded
// avoid compilation if possible by loading an existing library
if (!lib && dlLibraryTable::open(libPath, false))
{
lib = dlLibraryTable::findLibrary(libPath);
reuseLib = true;
}
// did not load - need to compile it
// create library if required
if (!lib)
{
if (Pstream::master())
{
if (!codeStreamTools::upToDate(codePath, sha))
if (!dynCode.upToDate(context))
{
Info<< "Creating new library in " << libPath << endl;
// filter with this context
dynCode.reset(context);
const fileName fileCsrc
// compile filtered C template
dynCode.addCompileFile(codeTemplateC);
// define Make/options
dynCode.setMakeOptions
(
codeStreamTools::findTemplate
(
codeTemplateC
)
"EXE_INC = -g \\\n"
+ context.options()
+ "\n\nLIB_LIBS ="
);
// not found!
if (fileCsrc.empty())
if (!dynCode.copyOrCreateFiles(true))
{
FatalIOErrorIn
(
"functionEntries::codeStream::execute(..)",
parentDict
) << "Could not find the code template: "
<< codeTemplateC << nl
<< codeStreamTools::searchedLocations()
<< exit(FatalIOError);
}
List<codeStreamTools::fileAndVars> copyFiles(1);
copyFiles[0].file() = fileCsrc;
copyFiles[0].set("codeInclude", codeInclude);
copyFiles[0].set("code", code);
copyFiles[0].set("SHA1sum", sha.str());
List<codeStreamTools::fileAndContent> filesContents(2);
// Write Make/files
filesContents[0].first() = "Make/files";
filesContents[0].second() =
codeTemplateC + "\n\n"
+ codeStreamTools::libTarget(codeName);
// Write Make/options
filesContents[1].first() = "Make/options";
filesContents[1].second() =
"EXE_INC = -g \\\n"
+ codeOptions
+ "\n\nLIB_LIBS =";
codeStreamTools writer(codeName, copyFiles, filesContents);
if (!writer.copyFilesContents(codePath))
{
FatalIOErrorIn
(
"functionEntries::codeStream::execute(..)",
parentDict
) << "Failed writing " <<nl
<< copyFiles << endl
<< filesContents
) << "Failed writing files for" << nl
<< dynCode.libPath() << nl
<< exit(FatalIOError);
}
}
const Foam::string wmakeCmd("wmake libso " + codePath);
Info<< "Invoking " << wmakeCmd << endl;
if (Foam::system(wmakeCmd))
if (!dynCode.wmakeLibso())
{
FatalIOErrorIn
(
"functionEntries::codeStream::execute(..)",
parentDict
) << "Failed " << wmakeCmd
) << "Failed wmake " << libPath
<< exit(FatalIOError);
}
}
// all processes must wait for compile
bool dummy = true;
reduce(dummy, orOp<bool>());
bool waiting = true;
reduce(waiting, orOp<bool>());
if (!dlLibraryTable::open(libPath, false))
{
@ -229,31 +169,35 @@ bool Foam::functionEntries::codeStream::execute
lib = dlLibraryTable::findLibrary(libPath);
}
else
else if (reuseLib)
{
Info<< "Reusing library in " << libPath << endl;
}
// Find the library handle.
void (*function)(const dictionary&, Ostream&);
function = reinterpret_cast<void(*)(const dictionary&, Ostream&)>
// Find the function handle in the library
void (*function)(Ostream&, const dictionary&);
function = reinterpret_cast<void(*)(Ostream&, const dictionary&)>
(
dlSym(lib, codeName)
dlSym(lib, dynCode.codeName())
);
if (!function)
{
FatalIOErrorIn
(
"functionEntries::codeStream::execute(..)",
parentDict
) << "Failed looking up symbol " << codeName
) << "Failed looking up symbol " << dynCode.codeName()
<< " in library " << lib << exit(FatalIOError);
}
// use function to write stream
OStringStream os(is.format());
(*function)(parentDict, os);
(*function)(os, parentDict);
// get the entry from this stream
IStringStream resultStream(os.str());
entry.read(parentDict, resultStream);

View File

@ -135,8 +135,8 @@ public:
static bool execute
(
const dictionary& parentDict,
primitiveEntry& entry,
Istream& is
primitiveEntry&,
Istream&
);
};

View File

@ -1,369 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2011 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM 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 OpenFOAM; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
\*---------------------------------------------------------------------------*/
#include "codeStreamTools.H"
#include "stringOps.H"
#include "IFstream.H"
#include "OFstream.H"
#include "OSspecific.H"
#include "dictionary.H"
#include "dlLibraryTable.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
int Foam::codeStreamTools::allowSystemOperations
(
Foam::debug::infoSwitch("allowSystemOperations", 0)
);
const Foam::word Foam::codeStreamTools::codeTemplateEnvName
= "FOAM_CODESTREAM_TEMPLATES";
const Foam::fileName Foam::codeStreamTools::codeTemplateDirName
= "codeTemplates/codeStream";
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
void Foam::codeStreamTools::checkSecurity
(
const char* title,
const dictionary& context
)
{
if (isAdministrator())
{
FatalIOErrorIn
(
title,
context
) << "This code should not be executed by someone with administrator"
<< " rights due to security reasons." << nl
<< "(it writes a shared library which then gets loaded "
<< "using dlopen)"
<< exit(FatalIOError);
}
}
Foam::fileName Foam::codeStreamTools::codePath(const word& subDirName)
{
return stringOps::expand("$FOAM_CASE/codeStream/" + subDirName);
}
Foam::fileName Foam::codeStreamTools::libPath(const word& codeName)
{
return stringOps::expand
(
"$FOAM_CASE/codeStream/platforms/$WM_OPTIONS/lib/lib"
+ codeName + ".so"
);
}
Foam::string Foam::codeStreamTools::libTarget(const word& codeName)
{
return "LIB = $(PWD)/../platforms/$(WM_OPTIONS)/lib/lib" + codeName;
}
Foam::fileName Foam::codeStreamTools::findTemplate(const word& templateFile)
{
// try to get template from FOAM_CODESTREAM_TEMPLATES
fileName templateDir(Foam::getEnv(codeTemplateEnvName));
fileName file;
if (!templateDir.empty() && isDir(templateDir))
{
file = templateDir/templateFile;
if (!isFile(file, false))
{
file.clear();
}
}
// not found - fallback to ~OpenFOAM expansion
if (file.empty())
{
file = findEtcFile(codeTemplateDirName/templateFile);
}
return file;
}
Foam::string Foam::codeStreamTools::searchedLocations()
{
return
(
"Under the $"
+ codeTemplateDirName
+ " directory or via via the ~OpenFOAM/"
+ codeTemplateDirName
+ " expansion"
);
}
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
void Foam::codeStreamTools::copyAndExpand
(
ISstream& is,
OSstream& os,
const HashTable<string>& mapping
) const
{
if (!is.good())
{
FatalErrorIn
(
"codeStreamTools::copyAndExpand()"
" const"
) << "Failed opening for reading " << is.name()
<< exit(FatalError);
}
if (!os.good())
{
FatalErrorIn
(
"codeStreamTools::copyAndExpand()"
" const"
) << "Failed writing " << os.name()
<< exit(FatalError);
}
// Copy file while rewriting $VARS and ${VARS}
string line;
do
{
is.getLine(line);
// expand according to mapping
// expanding according to env variables might cause too many
// surprises
stringOps::inplaceExpand(line, mapping);
os << line.c_str() << nl;
}
while (is.good());
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::codeStreamTools::codeStreamTools()
{}
Foam::codeStreamTools::codeStreamTools
(
const word& name,
const dictionary& dict
)
:
name_(name)
{
read(dict);
}
Foam::codeStreamTools::codeStreamTools
(
const word& name,
const List<fileAndVars>& copyFiles,
const List<fileAndContent>& filesContents
)
:
name_(name),
copyFiles_(copyFiles),
filesContents_(filesContents)
{}
Foam::codeStreamTools::codeStreamTools(const codeStreamTools& tools)
:
name_(tools.name_),
copyFiles_(tools.copyFiles_),
filesContents_(tools.filesContents_)
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
bool Foam::codeStreamTools::copyFilesContents(const fileName& dir) const
{
if (!allowSystemOperations)
{
FatalErrorIn
(
"codeStreamTools::copyFilesContents(const fileName&) const"
) << "Loading a shared library using case-supplied code is not"
<< " enabled by default" << nl
<< "because of security issues. If you trust the code you can"
<< " enable this" << nl
<< "facility be adding to the InfoSwitches setting in the system"
<< " controlDict:" << nl << nl
<< " allowSystemOperations 1" << nl << nl
<< "The system controlDict is either" << nl << nl
<< " ~/.OpenFOAM/$WM_PROJECT_VERSION/controlDict" << nl << nl
<< "or" << nl << nl
<< " $WM_PROJECT_DIR/etc/controlDict" << nl
<< endl
<< exit(FatalError);
}
// Create dir
mkDir(dir);
// Info<< "set mapping typeName=" << name_ << endl;
// Copy any template files
forAll(copyFiles_, i)
{
const fileName sourceFile(fileName(copyFiles_[i].file()).expand());
const fileName destFile(dir/sourceFile.name());
IFstream is(sourceFile);
//Info<< "Reading from " << is.name() << endl;
if (!is.good())
{
FatalErrorIn
(
"codeStreamTools::copyFilesContents(const fileName&)"
" const"
) << "Failed opening " << sourceFile << exit(FatalError);
}
OFstream os(destFile);
//Info<< "Writing to " << destFile.name() << endl;
if (!os.good())
{
FatalErrorIn
(
"codeStreamTools::copyFilesContents(const fileName&)"
" const"
) << "Failed writing " << destFile << exit(FatalError);
}
// variables mapping
HashTable<string> mapping(copyFiles_[i]);
mapping.set("typeName", name_);
// provide a zero digest if not otherwise specified
if (!mapping.found("SHA1sum"))
{
mapping.insert("SHA1sum", SHA1Digest().str());
}
copyAndExpand(is, os, mapping);
}
// Files that are always written:
forAll(filesContents_, i)
{
const fileName dstFile
(
fileName(dir/filesContents_[i].first()).expand()
);
mkDir(dstFile.path());
OFstream os(dstFile);
//Info<< "Writing to " << filesContents_[i].first() << endl;
if (!os.good())
{
FatalErrorIn
(
"codeStreamTools::copyFilesContents()"
" const"
) << "Failed writing " << dstFile << exit(FatalError);
}
os << filesContents_[i].second().c_str() << endl;
}
return true;
}
bool Foam::codeStreamTools::writeDigest
(
const fileName& dir,
const SHA1Digest& sha1
)
{
OFstream os(dir/"SHA1Digest");
os << sha1;
return os.good();
}
Foam::SHA1Digest Foam::codeStreamTools::readDigest(const fileName& dir)
{
IFstream is(dir/"SHA1Digest");
return SHA1Digest(is);
}
bool Foam::codeStreamTools::upToDate
(
const fileName& dir,
const SHA1Digest& sha1
)
{
if (!exists(dir/"SHA1Digest") || readDigest(dir) != sha1)
{
writeDigest(dir, sha1);
return false;
}
else
{
return true;
}
}
bool Foam::codeStreamTools::read(const dictionary& dict)
{
dict.lookup("copyFiles") >> copyFiles_;
dict.lookup("filesContents") >> filesContents_;
return true;
}
void Foam::codeStreamTools::writeDict(Ostream& os) const
{
os.writeKeyword("copyFiles") << copyFiles_ << token::END_STATEMENT << nl;
os.writeKeyword("filesContents") << filesContents_ << token::END_STATEMENT
<< nl;
}
// ************************************************************************* //

View File

@ -1,215 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2011 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM 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 OpenFOAM; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Class
Foam::codeStreamTools
Description
Base for all things on-the-fly from dictionary
SourceFiles
codeStreamTools.C
\*---------------------------------------------------------------------------*/
#ifndef codeStreamTools_H
#define codeStreamTools_H
#include "Tuple2.H"
#include "Pair.H"
#include "SHA1Digest.H"
#include "HashTable.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// Forward declaration of classes
class ISstream;
class OSstream;
/*---------------------------------------------------------------------------*\
Class codeStreamTools Declaration
\*---------------------------------------------------------------------------*/
class codeStreamTools
{
public:
typedef Tuple2<fileName, string> fileAndContent;
//- Helper class for managing file and variables
class fileAndVars
:
public HashTable<string>
{
// Private data
fileName file_;
public:
//- Construct null
fileAndVars()
{}
//- Return the file name
const fileName& file() const
{
return file_;
}
//- Return the file name
fileName& file()
{
return file_;
}
};
private:
// Private data
//- Name for underlying set
word name_;
//- Files to copy
List<codeStreamTools::fileAndVars> copyFiles_;
//- Direct contents for files
List<fileAndContent> filesContents_;
protected:
void copyAndExpand
(
ISstream&,
OSstream&,
const HashTable<string>& mapping
) const;
public:
// Static data members
//- Name of the code template environment variable
// Used to located the codeTemplateName
static const word codeTemplateEnvName;
//- Name of the code template sub-directory
// Used when locating the codeTemplateName via Foam::findEtcFile
static const fileName codeTemplateDirName;
static int allowSystemOperations;
// Constructors
//- Construct null
codeStreamTools();
//- Construct from dictionary
codeStreamTools(const word& name, const dictionary& dict);
//- Copy from components
codeStreamTools
(
const word& name,
const List<fileAndVars>&,
const List<fileAndContent>&
);
//- Construct copy
codeStreamTools(const codeStreamTools&);
// Member functions
//- Check security for creating dynamic code
static void checkSecurity
(
const char* title,
const dictionary& context
);
//- Local path for specified code name
// Expanded from \$FOAM_CASE/codeStream
static fileName codePath(const word& subDirName);
//- Local library path for specified code name
// Expanded from \$FOAM_CASE/platforms/\$WM_OPTIONS/lib
static fileName libPath(const word& codeName);
//- The library target path for Make/files
static string libTarget(const word& codeName);
//- Find a code-template via the codeTemplateEnvName
// alternatively in the codeTemplateDirName via Foam::findEtcFile
static fileName findTemplate(const word& templateName);
//- List searched locations in a format suitable for display an error
static string searchedLocations();
const word& name() const
{
return name_;
}
const List<fileAndVars>& copyFiles() const
{
return copyFiles_;
}
const List<Tuple2<fileName, string> >& filesContents() const
{
return filesContents_;
}
bool copyFilesContents(const fileName& dir) const;
static void* findLibrary(const fileName& libPath);
static bool writeDigest(const fileName& dir, const SHA1Digest& sha1);
static SHA1Digest readDigest(const fileName& dir);
static bool upToDate(const fileName& dir, const SHA1Digest& sha1);
bool read(const dictionary&);
void writeDict(Ostream&) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,554 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2011 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM 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 OpenFOAM; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
\*---------------------------------------------------------------------------*/
#include "dynamicCode.H"
#include "dynamicCodeContext.H"
#include "stringOps.H"
#include "IFstream.H"
#include "OFstream.H"
#include "OSspecific.H"
#include "dictionary.H"
#include "dlLibraryTable.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
int Foam::dynamicCode::allowSystemOperations
(
Foam::debug::infoSwitch("allowSystemOperations", 0)
);
const Foam::word Foam::dynamicCode::codeTemplateEnvName
= "FOAM_CODE_TEMPLATES";
const Foam::fileName Foam::dynamicCode::codeTemplateDirName
= "codeTemplates/dynamicCode";
const char* Foam::dynamicCode::libTargetRoot =
"LIB = $(PWD)/../platforms/$(WM_OPTIONS)/lib/lib";
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
void Foam::dynamicCode::checkSecurity
(
const char* title,
const dictionary& dict
)
{
if (isAdministrator())
{
FatalIOErrorIn
(
title,
dict
) << "This code should not be executed by someone with administrator"
<< " rights due to security reasons." << nl
<< "(it writes a shared library which then gets loaded "
<< "using dlopen)"
<< exit(FatalIOError);
}
}
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
void Foam::dynamicCode::copyAndFilter
(
ISstream& is,
OSstream& os,
const HashTable<string>& mapping
)
{
if (!is.good())
{
FatalErrorIn
(
"dynamicCode::copyAndFilter()"
" const"
) << "Failed opening for reading " << is.name()
<< exit(FatalError);
}
if (!os.good())
{
FatalErrorIn
(
"dynamicCode::copyAndFilter()"
" const"
) << "Failed writing " << os.name()
<< exit(FatalError);
}
// Copy file while rewriting $VARS and ${VARS}
string line;
do
{
is.getLine(line);
// expand according to mapping
// expanding according to env variables might cause too many
// surprises
stringOps::inplaceExpand(line, mapping);
os.writeQuoted(line, false) << nl;
}
while (is.good());
}
bool Foam::dynamicCode::resolveTemplates
(
const UList<fileName>& templateNames,
DynamicList<fileName>& resolvedFiles,
DynamicList<fileName>& badFiles
)
{
// try to get template from FOAM_CODESTREAM_TEMPLATES
const fileName templateDir(Foam::getEnv(codeTemplateEnvName));
bool allOkay = true;
forAll(templateNames, fileI)
{
const fileName& templateName = templateNames[fileI];
fileName file;
if (!templateDir.empty() && isDir(templateDir))
{
file = templateDir/templateName;
if (!isFile(file, false))
{
file.clear();
}
}
// not found - fallback to ~OpenFOAM expansion
if (file.empty())
{
file = findEtcFile(codeTemplateDirName/templateName);
}
if (file.empty())
{
badFiles.append(templateName);
allOkay = false;
}
else
{
resolvedFiles.append(file);
}
}
return allOkay;
}
bool Foam::dynamicCode::writeCommentSHA1(Ostream& os) const
{
const bool hasSHA1 = filterVars_.found("SHA1sum");
if (hasSHA1)
{
os << "/* dynamicCode:\n * SHA1 = ";
os.writeQuoted(filterVars_["SHA1sum"], false) << "\n */\n";
}
return hasSHA1;
}
bool Foam::dynamicCode::createMakeFiles() const
{
// Create Make/files
if (compileFiles_.empty())
{
return false;
}
const fileName dstFile(this->codePath()/"Make/files");
// Create dir
mkDir(dstFile.path());
OFstream os(dstFile);
//Info<< "Writing to " << dstFile << endl;
if (!os.good())
{
FatalErrorIn
(
"dynamicCode::createMakeFiles()"
" const"
) << "Failed writing " << dstFile
<< exit(FatalError);
}
writeCommentSHA1(os);
// Write compile files
forAll(compileFiles_, fileI)
{
os.writeQuoted(compileFiles_[fileI], false) << nl;
}
os << nl
<< libTargetRoot << codeName_.c_str() << nl;
return true;
}
bool Foam::dynamicCode::createMakeOptions() const
{
// Create Make/options
if (compileFiles_.empty() || makeOptions_.empty())
{
return false;
}
const fileName dstFile(this->codePath()/"Make/options");
// Create dir
mkDir(dstFile.path());
OFstream os(dstFile);
//Info<< "Writing to " << dstFile << endl;
if (!os.good())
{
FatalErrorIn
(
"dynamicCode::createMakeOptions()"
" const"
) << "Failed writing " << dstFile
<< exit(FatalError);
}
writeCommentSHA1(os);
os.writeQuoted(makeOptions_, false) << nl;
return true;
}
bool Foam::dynamicCode::writeDigest(const SHA1Digest& sha1) const
{
const fileName file = digestFile();
mkDir(file.path());
OFstream os(file);
sha1.write(os, true) << nl;
return os.good();
}
bool Foam::dynamicCode::writeDigest(const std::string& sha1) const
{
const fileName file = digestFile();
mkDir(file.path());
OFstream os(file);
os << '_';
os.writeQuoted(sha1, false) << nl;
return os.good();
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::dynamicCode::dynamicCode(const word& codeName, const word& codeDirName)
:
codeRoot_(stringOps::expand("$FOAM_CASE/dynamicCode")),
libSubDir_(stringOps::expand("platforms/$WM_OPTIONS/lib")),
codeName_(codeName),
codeDirName_(codeDirName)
{
if (codeDirName_.empty())
{
codeDirName_ = codeName_;
}
clear();
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::dynamicCode::clear()
{
compileFiles_.clear();
copyFiles_.clear();
createFiles_.clear();
filterVars_.clear();
filterVars_.set("typeName", codeName_);
filterVars_.set("SHA1sum", SHA1Digest().str());
// provide default Make/options
makeOptions_ =
"EXE_INC = -g\n"
"\n\nLIB_LIBS = ";
}
void Foam::dynamicCode::reset
(
const dynamicCodeContext& context
)
{
clear();
setFilterContext(context);
}
void Foam::dynamicCode::addCompileFile(const fileName& name)
{
compileFiles_.append(name);
}
void Foam::dynamicCode::addCopyFile(const fileName& name)
{
copyFiles_.append(name);
}
void Foam::dynamicCode::addCreateFile
(
const fileName& name,
const string& contents
)
{
createFiles_.append(fileAndContent(name, contents));
}
void Foam::dynamicCode::setFilterContext
(
const dynamicCodeContext& context
)
{
filterVars_.set("code", context.code());
filterVars_.set("codeInclude", context.include());
filterVars_.set("SHA1sum", context.sha1().str());
}
void Foam::dynamicCode::setFilterVariable
(
const word& key,
const std::string& value
)
{
filterVars_.set(key, value);
}
void Foam::dynamicCode::setMakeOptions(const std::string& content)
{
makeOptions_ = content;
}
bool Foam::dynamicCode::copyOrCreateFiles(const bool verbose) const
{
if (verbose)
{
Info<< "Creating new library in " << this->libPath() << endl;
}
if (!allowSystemOperations)
{
FatalErrorIn
(
"dynamicCode::copyOrCreateFiles() const"
) << "Loading a shared library using case-supplied code is not"
<< " enabled by default" << nl
<< "because of security issues. If you trust the code you can"
<< " enable this" << nl
<< "facility be adding to the InfoSwitches setting in the system"
<< " controlDict:" << nl << nl
<< " allowSystemOperations 1" << nl << nl
<< "The system controlDict is either" << nl << nl
<< " ~/.OpenFOAM/$WM_PROJECT_VERSION/controlDict" << nl << nl
<< "or" << nl << nl
<< " $WM_PROJECT_DIR/etc/controlDict" << nl
<< endl
<< exit(FatalError);
}
const label nFiles = compileFiles_.size() + copyFiles_.size();
DynamicList<fileName> resolvedFiles(nFiles);
DynamicList<fileName> badFiles(nFiles);
// resolve template, or add to bad-files
resolveTemplates(compileFiles_, resolvedFiles, badFiles);
resolveTemplates(copyFiles_, resolvedFiles, badFiles);
if (!badFiles.empty())
{
FatalErrorIn
(
"dynamicCode::copyFilesContents(..)"
) << "Could not find the code template(s): "
<< badFiles << nl
<< "Under the $" << codeTemplateEnvName
<< " directory or via via the ~OpenFOAM/"
<< codeTemplateDirName << " expansion"
<< exit(FatalError);
}
// Create dir
const fileName outputDir = this->codePath();
// Create dir
mkDir(outputDir);
// Copy/filter files
forAll(resolvedFiles, fileI)
{
const fileName& srcFile = resolvedFiles[fileI];
const fileName dstFile(outputDir/srcFile.name());
IFstream is(srcFile);
//Info<< "Reading from " << is.name() << endl;
if (!is.good())
{
FatalErrorIn
(
"dynamicCode::copyFilesContents(const fileName&)"
" const"
) << "Failed opening " << srcFile
<< exit(FatalError);
}
OFstream os(dstFile);
//Info<< "Writing to " << dstFile.name() << endl;
if (!os.good())
{
FatalErrorIn
(
"dynamicCode::copyFilesContents(const fileName&)"
" const"
) << "Failed writing " << dstFile
<< exit(FatalError);
}
// Copy lines while expanding variables
copyAndFilter(is, os, filterVars_);
}
// Create files:
forAll(createFiles_, fileI)
{
const fileName dstFile
(
outputDir/stringOps::expand(createFiles_[fileI].first())
);
mkDir(dstFile.path());
OFstream os(dstFile);
//Info<< "Writing to " << createFiles_[fileI].first() << endl;
if (!os.good())
{
FatalErrorIn
(
"dynamicCode::copyOrCreateFiles()"
" const"
) << "Failed writing " << dstFile
<< exit(FatalError);
}
os.writeQuoted(createFiles_[fileI].second(), false) << nl;
}
// Create Make/files + Make/options
createMakeFiles();
createMakeOptions();
writeDigest(filterVars_["SHA1sum"]);
return true;
}
bool Foam::dynamicCode::wmakeLibso() const
{
const Foam::string wmakeCmd("wmake libso " + this->codePath());
Info<< "Invoking " << wmakeCmd << endl;
if (Foam::system(wmakeCmd))
{
return false;
}
else
{
return true;
}
}
bool Foam::dynamicCode::upToDate(const SHA1Digest& sha1) const
{
const fileName file = digestFile();
if (!exists(file, false) || SHA1Digest(IFstream(file)()) != sha1)
{
return false;
}
return true;
}
bool Foam::dynamicCode::upToDate(const dynamicCodeContext& context) const
{
return upToDate(context.sha1());
}
// bool Foam::dynamicCode::openLibrary() const
// {
// return dlLibraryTable::openLibrary(this->libPath(), false);
// }
//
//
// bool Foam::dynamicCode::closeLibrary() const
// {
// return dlLibraryTable::closeLibrary(this->libPath(), false);
// }
//
//
// void* Foam::dynamicCode::findLibrary() const
// {
// return dlLibraryTable::findLibrary(this->libPath());
// }
// ************************************************************************* //

View File

@ -0,0 +1,290 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2011 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM 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 OpenFOAM; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Class
Foam::dynamicCode
Description
Tools for handling dynamic code compilation
SourceFiles
dynamicCode.C
\*---------------------------------------------------------------------------*/
#ifndef dynamicCode_H
#define dynamicCode_H
#include "Tuple2.H"
#include "SHA1Digest.H"
#include "HashTable.H"
#include "DynamicList.H"
#include "dlLibraryTable.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// Forward declaration of classes
class dynamicCodeContext;
class ISstream;
class OSstream;
/*---------------------------------------------------------------------------*\
Class dynamicCode Declaration
\*---------------------------------------------------------------------------*/
class dynamicCode
{
public:
typedef Tuple2<fileName, string> fileAndContent;
private:
// Private data
//- Root for dynamic code compilation
fileName codeRoot_;
//- Subdirectory name for loading libraries
const fileName libSubDir_;
//- Name for code
word codeName_;
//- Name for code subdirectory
word codeDirName_;
//- Files to copy and filter
DynamicList<fileName> compileFiles_;
//- Files to copy and filter
DynamicList<fileName> copyFiles_;
//- Direct contents for files
DynamicList<fileAndContent> createFiles_;
//- Variables to use during filtering
HashTable<string> filterVars_;
//- Contents for Make/options
std::string makeOptions_;
// Private Member Functions
//- Disallow default bitwise copy construct
dynamicCode(const dynamicCode&);
//- Disallow default bitwise assignment
void operator=(const dynamicCode&);
protected:
// Static data members
//- Root of the LIB target for Make/files
static const char* libTargetRoot;
// Protected Member Functions
//- Copy lines while expanding variables
static void copyAndFilter
(
ISstream&,
OSstream&,
const HashTable<string>& mapping
);
//- Resolve code-templates via the codeTemplateEnvName
// alternatively in the codeTemplateDirName via Foam::findEtcFile
static bool resolveTemplates
(
const UList<fileName>& templateNames,
DynamicList<fileName>& resolvedFiles,
DynamicList<fileName>& badFiles
);
//- Write SHA1 value as C-comment
bool writeCommentSHA1(Ostream&) const;
//- Copy/create Make/files prior to compilation
bool createMakeFiles() const;
//- Copy/create Make/options prior to compilation
bool createMakeOptions() const;
//- Write digest to Make/SHA1Digest
bool writeDigest(const SHA1Digest&) const;
//- Write digest to Make/SHA1Digest
bool writeDigest(const std::string&) const;
public:
// Static data members
//- Name of the code template environment variable
// Used to located the codeTemplateName
static const word codeTemplateEnvName;
//- Name of the code template sub-directory
// Used when locating the codeTemplateName via Foam::findEtcFile
static const fileName codeTemplateDirName;
//- Flag if system operations are allowed
static int allowSystemOperations;
// Static Member functions
//- Check security for creating dynamic code
static void checkSecurity(const char* title, const dictionary&);
// Constructors
//- Construct for a specified code name and code directory name
// Defaults to using the code name for the code directory name
dynamicCode
(
const word& codeName,
const word& codeDirName = ""
);
// Member functions
//- Return the code-name
const word& codeName() const
{
return codeName_;
}
//- Return the code-dirname
const word& codeDirName() const
{
return codeDirName_;
}
//- Root for dynamic code compilation
// Expanded from \$FOAM_CASE/dynamicCode
const fileName& codeRoot() const
{
return codeRoot_;
}
//- Subdirectory name for loading libraries
// Expanded from platforms/\$WM_OPTIONS/lib
fileName libSubDir() const
{
return libSubDir_;
}
//- Path for specified code name
// Corresponds to codeRoot()/codeDirName()
fileName codePath() const
{
return codeRoot_/codeDirName_;
}
//- Library path for specified code name
// Corresponds to codeRoot()/libSubDir()/lib\<codeName\>.so
fileName libPath() const
{
return codeRoot_/libSubDir_/"lib" + codeName_ + ".so";
}
//- Path for SHA1Digest
// Corresponds to codePath()/Make/SHA1Digest
fileName digestFile() const
{
return codeRoot_/codeDirName_/"Make/SHA1Digest";
}
//- Clear files and variables
void clear();
//- Clear files and reset variables to specified context
void reset(const dynamicCodeContext&);
//- Add a file template name, which will be found and filtered
void addCompileFile(const fileName& name);
//- Add a file template name, which will be found and filtered
void addCopyFile(const fileName& name);
//- Add a file to create with its contents. Will not be filtered
void addCreateFile(const fileName& name, const string& contents);
//- Define filter variables for code, codeInclude, SHA1sum
void setFilterContext(const dynamicCodeContext&);
//- Define a filter variable
void setFilterVariable(const word& key, const std::string& value);
//- Define contents for Make/options
void setMakeOptions(const std::string& content);
//- Verify if the copied code is up-to-date, based on Make/SHA1Digest
bool upToDate(const dynamicCodeContext& context) const;
//- Verify if the copied code is up-to-date, based on Make/SHA1Digest
bool upToDate(const SHA1Digest& sha1) const;
//- Copy/create files prior to compilation
bool copyOrCreateFiles(const bool verbose = false) const;
//- Compile a libso
bool wmakeLibso() const;
// //- Open the libPath() library
// bool openLibrary() const;
//
// //- Close the libPath() library
// bool closeLibrary() const;
//
// //- Find the handle of the libPath() library
// void* findLibrary() const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,69 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2011 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM 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 OpenFOAM; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
\*---------------------------------------------------------------------------*/
#include "dynamicCodeContext.H"
#include "stringOps.H"
#include "OSHA1stream.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::dynamicCodeContext::dynamicCodeContext(const dictionary& dict)
:
dict_(dict),
code_(stringOps::trim(dict["code"])),
include_(),
options_()
{
// expand dictionary entries
stringOps::inplaceExpand(code_, dict);
// note: removes any leading/trailing whitespace
// - necessary for compilation options, convenient for includes
// and body.
// optional
if (dict.found("codeInclude"))
{
include_ = stringOps::trim(dict["codeInclude"]);
stringOps::inplaceExpand(include_, dict);
}
// optional
if (dict.found("codeOptions"))
{
options_ = stringOps::trim(dict["codeOptions"]);
stringOps::inplaceExpand(options_, dict);
}
// calculate SHA1 digest from include, options, code
OSHA1stream os;
os << include_ << options_ << code_;
sha1_ = os.digest();
}
// ************************************************************************* //

View File

@ -0,0 +1,120 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2011 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM 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 OpenFOAM; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Class
Foam::dynamicCodeContext
Description
Encapsulation of dynamic code dictionaries
SourceFiles
dynamicCodeContext.C
\*---------------------------------------------------------------------------*/
#ifndef dynamicCodeContext_H
#define dynamicCodeContext_H
#include "dictionary.H"
#include "SHA1Digest.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class dynamicCodeContext Declaration
\*---------------------------------------------------------------------------*/
class dynamicCodeContext
{
// Private data
//- The parent dictionary context
const dictionary& dict_;
//- Mandatory "code" entry
string code_;
//- Optional "codeInclude" entry
string include_;
//- Optional "codeOptions" entry
string options_;
//- Calculated SHA1Digest
SHA1Digest sha1_;
public:
// Constructors
//- Construct from a dictionary
dynamicCodeContext(const dictionary&);
// Member functions
//- Return the parent dictionary context
const dictionary& dict() const
{
return dict_;
}
//- Return the code-includes
const string& include() const
{
return include_;
}
//- Return the code-options
const string& options() const
{
return options_;
}
//- Return the code
const string& code() const
{
return code_;
}
//- Return SHA1 digest calculated from include, options, code
const SHA1Digest& sha1() const
{
return sha1_;
}
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-2010 OpenCFD Ltd.
\\ / A nd | Copyright (C) 2004-2011 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -21,9 +21,6 @@ License
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
InClass
Foam::runTimeSelectionTables
Description
Macros for easy insertion into run-time selection tables
@ -53,6 +50,26 @@ Description
add_##lookup##_##thisType##argNames##ConstructorTo##baseType##Table_ \
(#lookup)
// add to hash-table of functions with typename as the key
#define addRemovableToRunTimeSelectionTable\
(baseType,thisType,argNames) \
\
/* Add the thisType constructor function to the table */ \
baseType::addRemovable##argNames##ConstructorToTable< thisType > \
addRemovable##thisType##argNames##ConstructorTo##baseType##Table_
// add to hash-table of functions with 'lookup' as the key
#define addRemovableNamedToRunTimeSelectionTable\
(baseType,thisType,argNames,lookup) \
\
/* Add the thisType constructor function to the table, find by lookup */ \
baseType::addRemovable##argNames##ConstructorToTable< thisType > \
addRemovable_##lookup##_##thisType##argNames##ConstructorTo \
##baseType##Table_(#lookup)
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-2010 OpenCFD Ltd.
\\ / A nd | Copyright (C) 2004-2011 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -21,11 +21,8 @@ License
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::runTimeSelectionTables
Description
Macros to enable the easy declaration of run-time selection tables.
Macros to ease declaration of run-time selection tables.
declareRunTimeSelectionTable is used to create a run-time selection table
for a base-class which holds constructor pointers on the table.
@ -62,6 +59,12 @@ Description
/* Construct from argList function pointer table pointer */ \
static argNames##ConstructorTable* argNames##ConstructorTablePtr_; \
\
/* Table constructor called from the table add function */ \
static void construct##argNames##ConstructorTables(); \
\
/* Table destructor called from the table add function destructor */ \
static void destroy##argNames##ConstructorTables(); \
\
/* Class to add constructor from argList to table */ \
template< class baseType##Type > \
class add##argNames##ConstructorToTable \
@ -88,11 +91,41 @@ Description
} \
}; \
\
/* Table constructor called from the table add function */ \
static void construct##argNames##ConstructorTables(); \
/* Class to add constructor from argList to table */ \
/* Remove only the entry (not the table) upon destruction */ \
template< class baseType##Type > \
class addRemovable##argNames##ConstructorToTable \
{ \
/* retain lookup name for later removal */ \
const word& lookup_; \
\
/* Table destructor called from the table add function destructor */ \
static void destroy##argNames##ConstructorTables()
public: \
\
static autoPtr< baseType > New argList \
{ \
return autoPtr< baseType >(new baseType##Type parList); \
} \
\
addRemovable##argNames##ConstructorToTable \
( \
const word& lookup = baseType##Type::typeName \
) \
: \
lookup_(lookup) \
{ \
construct##argNames##ConstructorTables(); \
argNames##ConstructorTablePtr_->set(lookup, New); \
} \
\
~addRemovable##argNames##ConstructorToTable() \
{ \
if (argNames##ConstructorTablePtr_) \
{ \
argNames##ConstructorTablePtr_->erase(lookup_); \
} \
} \
};
// external use:
@ -111,6 +144,12 @@ Description
/* Construct from argList function pointer table pointer */ \
static argNames##ConstructorTable* argNames##ConstructorTablePtr_; \
\
/* Table constructor called from the table add function */ \
static void construct##argNames##ConstructorTables(); \
\
/* Table destructor called from the table add function destructor */ \
static void destroy##argNames##ConstructorTables(); \
\
/* Class to add constructor from argList to table */ \
template< class baseType##Type > \
class add##argNames##ConstructorToTable \
@ -141,11 +180,43 @@ Description
} \
}; \
\
/* Table constructor called from the table add function */ \
static void construct##argNames##ConstructorTables(); \
/* Class to add constructor from argList to table */ \
template< class baseType##Type > \
class addRemovable##argNames##ConstructorToTable \
{ \
/* retain lookup name for later removal */ \
const word& lookup_; \
\
/* Table destructor called from the table add function destructor */ \
static void destroy##argNames##ConstructorTables()
public: \
\
static autoPtr< baseType > New##baseType argList \
{ \
return autoPtr< baseType >(baseType##Type::New parList.ptr()); \
} \
\
addRemovable##argNames##ConstructorToTable \
( \
const word& lookup = baseType##Type::typeName \
) \
: \
lookup_(lookup) \
{ \
construct##argNames##ConstructorTables(); \
argNames##ConstructorTablePtr_->set \
( \
lookup, \
New##baseType \
); \
} \
\
~addRemovable##argNames##ConstructorToTable() \
{ \
if (argNames##ConstructorTablePtr_) \
{ \
argNames##ConstructorTablePtr_->erase(lookup_); \
} \
} \
};
// internal use:
@ -157,13 +228,11 @@ Description
void baseType::construct##argNames##ConstructorTables() \
{ \
static bool constructed = false; \
\
if (!constructed) \
{ \
constructed = true; \
baseType::argNames##ConstructorTablePtr_ \
= new baseType::argNames##ConstructorTable; \
\
constructed = true; \
} \
}
@ -244,13 +313,11 @@ Description
void baseType< Targ >::construct##argNames##ConstructorTables() \
{ \
static bool constructed = false; \
\
if (!constructed) \
{ \
constructed = true; \
baseType< Targ >::argNames##ConstructorTablePtr_ \
= new baseType< Targ >::argNames##ConstructorTable; \
\
constructed = true; \
} \
}

View File

@ -85,6 +85,7 @@ Description
} \
}
// internal use:
// constructor/destructor aid
#define defineGlobalFunctionSelectionTableConstructDestruct\

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-2010 OpenCFD Ltd.
\\ / A nd | Copyright (C) 2004-2011 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -98,13 +98,11 @@ Description
void baseType::construct##memberFunction##argNames##MemberFunctionTables()\
{ \
static bool constructed = false; \
\
if (!constructed) \
{ \
constructed = true; \
baseType::memberFunction##argNames##MemberFunctionTablePtr_ \
= new baseType::memberFunction##argNames##MemberFunctionTable;\
\
constructed = true; \
} \
}
@ -191,14 +189,12 @@ Description
MemberFunctionTables() \
{ \
static bool constructed = false; \
\
if (!constructed) \
{ \
constructed = true; \
baseType<Targ>::memberFunction##argNames##MemberFunctionTablePtr_ \
= new baseType<Targ>::memberFunction##argNames## \
MemberFunctionTable; \
\
constructed = true; \
} \
}
@ -254,6 +250,7 @@ Description
defineTemplatedMemberFunctionSelectionTableDestructor \
(baseType,memberFunction,argNames,Targ)
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif

View File

@ -32,7 +32,7 @@ License
#include "JobInfo.H"
#include "labelList.H"
#include "regIOobject.H"
#include "codeStreamTools.H"
#include "dynamicCode.H"
#include <cctype>
@ -790,7 +790,7 @@ Foam::argList::argList
<< endl;
Info<< "allowSystemOperations : ";
if (codeStreamTools::allowSystemOperations)
if (dynamicCode::allowSystemOperations)
{
Info<< "Allowing user-supplied system call operations" << endl;
}

View File

@ -190,9 +190,12 @@ void* dlOpen(const fileName& lib);
//- Close a dlopened library using handle. Return true if successful
bool dlClose(void*);
//- Lookup a symbol in a dlopened library using handle
//- Lookup a symbol in a dlopened library using handle to library
void* dlSym(void* handle, const std::string& symbol);
//- Report if symbol in a dlopened library could be found
bool dlSymFound(void* handle, const std::string& symbol);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -241,10 +241,10 @@ Foam::SHA1::processBlock(const void *data, size_t len)
while (words < endp)
{
uint32_t tm;
for (int t = 0; t < 16; t++)
for (int t = 0; t < 16; ++t)
{
x[t] = swapBytes(*words);
words++;
++words;
}
R( a, b, c, d, e, F1, K1, x[ 0] );

View File

@ -30,6 +30,8 @@ License
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
const Foam::SHA1Digest Foam::SHA1Digest::null;
//! \cond fileScope
static const char hexChars[] = "0123456789abcdef";
//! \endcond
@ -40,12 +42,18 @@ static const char hexChars[] = "0123456789abcdef";
unsigned char Foam::SHA1Digest::readHexDigit(Istream& is)
{
// Takes into account that 'a' (or 'A') is 10
static const label alphaOffset = toupper('A') - 10;
static const int alphaOffset = toupper('A') - 10;
// Takes into account that '0' is 0
static const label zeroOffset = int('0');
static const int zeroOffset = int('0');
// silently ignore leading or intermediate '_'
char c = 0;
do
{
is.read(c);
}
while (c == '_');
if (!isxdigit(c))
{
@ -101,12 +109,21 @@ bool Foam::SHA1Digest::empty() const
}
std::string Foam::SHA1Digest::str() const
std::string Foam::SHA1Digest::str(const bool prefixed) const
{
std::string buf;
buf.resize(length*2);
unsigned nChar = 0;
if (prefixed)
{
buf.resize(1 + length*2);
buf[nChar++] = '_';
}
else
{
buf.resize(length*2);
}
for (unsigned i = 0; i < length; ++i)
{
buf[nChar++] = hexChars[((v_[i] >> 4) & 0xF)];
@ -117,6 +134,24 @@ std::string Foam::SHA1Digest::str() const
}
Foam::Ostream& Foam::SHA1Digest::write(Ostream& os, const bool prefixed) const
{
if (prefixed)
{
os.write('_');
}
for (unsigned i = 0; i < length; ++i)
{
os.write(hexChars[((v_[i] >> 4) & 0xF)]);
os.write(hexChars[(v_[i] & 0xF)]);
}
os.check("SHA1Digest::write(Ostream&, const bool)");
return os;
}
// * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * * //
bool Foam::SHA1Digest::operator==(const SHA1Digest& rhs) const
@ -141,21 +176,26 @@ bool Foam::SHA1Digest::operator==(const std::string& hexdigits) const
return empty();
}
// skip possible '_' prefix
unsigned charI = 0;
if (hexdigits[0] == '_')
{
++charI;
}
// incorrect length - can never match
if (hexdigits.size() != length*2)
if (hexdigits.size() != charI + length*2)
{
return false;
}
for (unsigned i = 0, charI = 0; i < length; ++i, charI += 2)
for (unsigned i = 0; i < length; ++i)
{
const char c1 = hexChars[((v_[i] >> 4) & 0xF)];
const char c2 = hexChars[(v_[i] & 0xF)];
if (c1 != hexdigits[charI] || c2 != hexdigits[charI+1])
{
return false;
}
if (c1 != hexdigits[charI++]) return false;
if (c2 != hexdigits[charI++]) return false;
}
return true;
@ -170,21 +210,26 @@ bool Foam::SHA1Digest::operator==(const char* hexdigits) const
return empty();
}
// skip possible '_' prefix
unsigned charI = 0;
if (hexdigits[0] == '_')
{
++charI;
}
// incorrect length - can never match
if (strlen(hexdigits) != length*2)
if (strlen(hexdigits) != charI + length*2)
{
return false;
}
for (unsigned i = 0, charI = 0; i < length; ++i, charI += 2)
for (unsigned i = 0; i < length; ++i)
{
const char c1 = hexChars[((v_[i] >> 4) & 0xF)];
const char c2 = hexChars[(v_[i] & 0xF)];
if (c1 != hexdigits[charI] || c2 != hexdigits[charI+1])
{
return false;
}
if (c1 != hexdigits[charI++]) return false;
if (c2 != hexdigits[charI++]) return false;
}
return true;
@ -230,16 +275,7 @@ Foam::Istream& Foam::operator>>(Istream& is, SHA1Digest& dig)
Foam::Ostream& Foam::operator<<(Ostream& os, const SHA1Digest& dig)
{
const unsigned char *v = dig.v_;
for (unsigned i = 0; i < dig.length; ++i)
{
os.write(hexChars[((v[i] >> 4) & 0xF)]);
os.write(hexChars[(v[i] & 0xF)]);
}
os.check("Ostream& operator<<(Ostream&, const SHA1Digest&)");
return os;
return dig.write(os);
}

View File

@ -46,8 +46,8 @@ namespace Foam
{
// Forward declaration of classes
class Ostream;
class Istream;
class Ostream;
// Forward declaration of friend functions and operators
class SHA1;
@ -65,23 +65,40 @@ class SHA1Digest
public:
friend class SHA1;
//- The length of the digest contents
// Static data members
//- The length of the (uncoded) digest contents
static const unsigned length = 20;
//- A null digest (ie, all zero)
static const SHA1Digest null;
// Constructors
//- Construct a zero digest
SHA1Digest();
//- Construct read a digest
SHA1Digest(Istream&);
// Member Functions
//- Reset the digest to zero
void clear();
//- Return true if the digest is empty (ie, all zero).
bool empty() const;
//- Return string representation
std::string str() const;
//- Return (40-byte) text representation, optionally with '_' prefix
std::string str(const bool prefixed=false) const;
//- Write (40-byte) text representation, optionally with '_' prefix
Ostream& write(Ostream&, const bool prefixed=false) const;
// Member Operators
//- Equality operator
bool operator==(const SHA1Digest&) const;
@ -89,11 +106,13 @@ public:
//- Compare to (40-byte) text representation (eg, from sha1sum)
// An %empty string is equivalent to
// "0000000000000000000000000000000000000000"
// The hexdigits may optionally start with a '_' prefix
bool operator==(const std::string& hexdigits) const;
//- Compare to (40-byte) text representation (eg, from sha1sum)
// A %null or %empty string is equivalent to
// "0000000000000000000000000000000000000000"
// The hexdigits may optionally start with a '_' prefix
bool operator==(const char* hexdigits) const;
@ -107,14 +126,27 @@ public:
bool operator!=(const char* hexdigits) const;
friend Ostream& operator<<(Ostream&, const SHA1Digest&);
// IOstream Operators
//- Read (40-byte) text representation
// Since leading and intermediate underscores are skipped, a '_' can
// be prefixed to the text representation to use an unquoted
// SHA1Digest without parsing ambiguities as a number.
friend Istream& operator>>(Istream&, SHA1Digest&);
//- Write (40-byte) text representation, unquoted and without prefix
friend Ostream& operator<<(Ostream&, const SHA1Digest&);
private:
// Private data
//- The digest contents
unsigned char v_[length];
//- Read hexadecimal value, ignoring leading or intermediate '_'
static unsigned char readHexDigit(Istream&);
};

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-2010 OpenCFD Ltd.
\\ / A nd | Copyright (C) 2004-2011 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -33,7 +33,7 @@ Description
void Foam::meshReader::calcPointCells() const
{
const static label UNIT_POINT_CELLS = 12;
static const label UNIT_POINT_CELLS = 12;
if (pointCellsPtr_)
{

View File

@ -24,12 +24,12 @@ License
\*---------------------------------------------------------------------------*/
#include "codeProperties.H"
#include "Time.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
defineTypeNameAndDebug(Foam::codeProperties, 0);
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::codeProperties::codeProperties(const IOobject& io)
@ -41,6 +41,20 @@ Foam::codeProperties::codeProperties(const IOobject& io)
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
bool Foam::codeProperties::modified() const
{
modified_ = modified_ || regIOobject::modified();
return modified_;
}
void Foam::codeProperties::setUnmodified() const
{
modified_ = false;
}
bool Foam::codeProperties::read()
{
if (regIOobject::read())

View File

@ -25,7 +25,7 @@ Class
Foam::codeProperties
Description
IOdictionary + flag whether file has changed.
IOdictionary with an internal flag to explicitly track when a file changed.
SourceFiles
codeProperties.C
@ -35,7 +35,6 @@ SourceFiles
#ifndef codeProperties_H
#define codeProperties_H
#include "MeshObject.H"
#include "IOdictionary.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -53,7 +52,7 @@ class codeProperties
{
// Private data
//- File change
//- Monitor file change
mutable bool modified_;
public:
@ -69,15 +68,12 @@ public:
// Member Functions
bool modified() const
{
return modified_;
}
//- A sticky version of regIOobject::modified()
// Must explicitly clear with setUnmodified()
virtual bool modified() const;
void setUnmodified() const
{
modified_ = false;
}
//- Make modification unsticky
void setUnmodified() const;
//- Read the dictionary
virtual bool read();

View File

@ -33,8 +33,8 @@ License
#include "IFstream.H"
#include "OFstream.H"
#include "SHA1Digest.H"
#include "OSHA1stream.H"
#include "codeStreamTools.H"
#include "dynamicCode.H"
#include "dynamicCodeContext.H"
#include "codeProperties.H"
#include "stringOps.H"
@ -78,221 +78,227 @@ Foam::codedFixedValueFvPatchScalarField::dict() const
}
void Foam::codedFixedValueFvPatchScalarField::writeLibrary
void Foam::codedFixedValueFvPatchScalarField::createLibrary
(
const fileName& codePath,
const fileName& libPath,
const dictionary& dict
)
dynamicCode& dynCode,
const dynamicCodeContext& context
) const
{
// Write files for new library
if (!Pstream::master())
if (Pstream::master() && !dynCode.upToDate(context))
{
return;
}
// filter with this context
dynCode.reset(context);
// "codeInclude" is optional
string codeInclude;
if (dict.found("codeInclude"))
{
codeInclude = stringOps::trim(dict["codeInclude"]);
stringOps::inplaceExpand(codeInclude, dict);
}
// compile filtered C template
dynCode.addCompileFile(codeTemplateC);
// "codeOptions" is optional
string codeOptions;
if (dict.found("codeOptions"))
{
codeOptions = stringOps::trim(dict["codeOptions"]);
stringOps::inplaceExpand(codeOptions, dict);
}
// copy filtered H template
dynCode.addCopyFile(codeTemplateH);
// "code" is mandatory
string code = stringOps::trim(dict["code"]);
stringOps::inplaceExpand(code, dict);
// Create SHA1 digest from the contents
SHA1Digest sha;
{
OSHA1stream os;
os << codeInclude << codeOptions << code;
sha = os.digest();
}
// Info<<"old SHA1: " << sha1_ << nl
// <<"new SHA1: " << sha << endl;
// only use side-effect of writing SHA1Digest for now
(void) codeStreamTools::upToDate(codePath, sha);
// TODO: compile on-demand
if (true)
{
Info<< "Creating new library in " << libPath << endl;
const fileName fileCsrc(codeStreamTools::findTemplate(codeTemplateC));
const fileName fileHsrc(codeStreamTools::findTemplate(codeTemplateH));
// not found!
if (fileCsrc.empty() || fileHsrc.empty())
{
FatalIOErrorIn
// define Make/options
dynCode.setMakeOptions
(
"codedFixedValueFvPatchScalarField::writeLibrary(..)",
dict
) << "Could not find one or both code templates: "
<< codeTemplateC << ", " << codeTemplateH << nl
<< codeStreamTools::searchedLocations()
<< exit(FatalIOError);
}
List<codeStreamTools::fileAndVars> copyFiles(2);
copyFiles[0].file() = fileCsrc;
copyFiles[0].set("codeInclude", codeInclude);
copyFiles[0].set("code", code);
copyFiles[0].set("SHA1sum", sha.str());
copyFiles[1].file() = fileHsrc;
List<codeStreamTools::fileAndContent> filesContents(2);
// Write Make/files
filesContents[0].first() = "Make/files";
filesContents[0].second() =
codeTemplateC + "\n\n"
+ codeStreamTools::libTarget(redirectType_);
// Write Make/options
filesContents[1].first() = "Make/options";
filesContents[1].second() =
"EXE_INC = -g \\\n"
"-I$(LIB_SRC)/finiteVolume/lnInclude\\\n"
+ codeOptions
+ "\n\nLIB_LIBS = ";
+ context.options()
+ "\n\nLIB_LIBS = "
);
codeStreamTools writer(redirectType_, copyFiles, filesContents);
if (!writer.copyFilesContents(codePath))
if (!dynCode.copyOrCreateFiles(true))
{
FatalIOErrorIn
(
"codedFixedValueFvPatchScalarField::writeLibrary(..)",
dict
) << "Failed writing " << nl
<< copyFiles << nl
<< filesContents
context.dict()
) << "Failed writing files for" << nl
<< dynCode.libPath() << nl
<< exit(FatalIOError);
}
}
}
void Foam::codedFixedValueFvPatchScalarField::updateLibrary()
void Foam::codedFixedValueFvPatchScalarField::updateLibrary
(
bool firstTime
) const
{
codeStreamTools::checkSecurity
dynamicCode::checkSecurity
(
"codedFixedValueFvPatchScalarField::updateLibrary()",
dict_
);
// write code into redirectType_ subdir
const fileName codePath = codeStreamTools::codePath(redirectType_);
// use codeProperties or in-line
const bool useCodeProps = !dict_.found("code");
// const fileName oldLibPath = codeStreamTools::libPath
// (
// redirectType_ + "_" + sha1_
// );
// write library into platforms/$WM_OPTIONS/lib subdir
const fileName libPath = codeStreamTools::libPath(redirectType_);
const dictionary& codeDict =
(
useCodeProps
? this->dict().subDict(redirectType_)
: dict_
);
//Info<< "codePath:" << codePath << nl
// << "libPath:" << libPath << endl;
autoPtr<dynamicCodeContext> contextPtr;
// write code into redirectType_ subdir as well
dynamicCode dynCode(redirectType_);
const fileName libPath = dynCode.libPath();
// see if library is loaded
void* lib = dlLibraryTable::findLibrary(libPath);
bool reuseLib = false;
bool waiting = false;
// TODO:
// calculate old/new SHA1 for code
// check if the correct library version was already loaded.
// Find the library handle.
//
// string signatureName(redirectType_ + "_" + sha().str());
// void (*signatureFunction)();
// signatureFunction = reinterpret_cast<void(*)()>(dlSym(lib, signatureName));
if (dict_.found("code"))
if (useCodeProps)
{
if (!lib)
// library may be loaded, but out-of-date
const codeProperties& codeProps = this->dict();
if (codeProps.modified())
{
writeLibrary(codePath, libPath, dict_);
}
}
else
{
const codeProperties& onTheFlyDict = dict();
if (onTheFlyDict.modified())
{
onTheFlyDict.setUnmodified();
codeProps.setUnmodified();
// Remove instantiation of fvPatchField provided by library
redirectPatchFieldPtr_.clear();
// Unload library
contextPtr.reset(new dynamicCodeContext(codeDict));
// unload code
if (lib)
{
if (!dlLibraryTable::close(libPath))
firstTime = false;
reuseLib = false;
lib = 0;
if (!dlLibraryTable::close(libPath, false))
{
FatalIOErrorIn
(
"codedFixedValueFvPatchScalarField::updateLibrary(..)",
onTheFlyDict
) << "Failed unloading library " << libPath
"codedFixedValueFvPatchScalarField::"
"updateLibrary()",
contextPtr().dict()
) << "Failed unloading library "
<< libPath
<< exit(FatalIOError);
}
lib = NULL;
}
const dictionary& codeDict = onTheFlyDict.subDict(redirectType_);
writeLibrary(codePath, libPath, codeDict);
}
}
if (!lib)
// library exists (and was not unloaded) - we can leave now
if (lib)
{
if (Pstream::master())
return;
}
// Remove instantiation of fvPatchField provided by library
redirectPatchFieldPtr_.clear();
if (contextPtr.empty())
{
const Foam::string wmakeCmd("wmake libso " + codePath);
Info<< "Invoking " << wmakeCmd << endl;
if (Foam::system(wmakeCmd))
contextPtr.reset(new dynamicCodeContext(codeDict));
}
// function name serving as version control - based on the SHA1
const string sentinelName
= dynCode.codeName() + contextPtr().sha1().str(true);
// avoid compilation (first time only) by loading an existing library
if (firstTime && dlLibraryTable::open(libPath, false))
{
lib = dlLibraryTable::findLibrary(libPath);
// verify the loaded version and unload if needed
if (lib)
{
reuseLib = dlSymFound(lib, sentinelName);
if (!reuseLib)
{
lib = 0;
if (!dlLibraryTable::close(libPath, false))
{
FatalIOErrorIn
(
"codedFixedValueFvPatchScalarField::updateLibrary()",
dict_
) << "Failed " << wmakeCmd
contextPtr().dict()
) << "Failed unloading library "
<< libPath
<< exit(FatalIOError);
}
}
}
}
// really do need to create library
if (!lib)
{
if (Pstream::master())
{
createLibrary(dynCode, contextPtr());
if (!dynCode.wmakeLibso())
{
FatalIOErrorIn
(
"codedFixedValueFvPatchScalarField::updateLibrary()",
contextPtr().dict()
) << "Failed wmake " << libPath
<< exit(FatalIOError);
}
}
// all processes must wait for compile
bool dummy = true;
reduce(dummy, orOp<bool>());
waiting = true;
reduce(waiting, orOp<bool>());
if (!dlLibraryTable::open(libPath))
if (!dlLibraryTable::open(libPath, false))
{
FatalIOErrorIn
(
"codedFixedValueFvPatchScalarField::updateLibrary()",
dict_
contextPtr().dict()
) << "Failed loading library " << libPath
<< exit(FatalIOError);
}
lib = dlLibraryTable::findLibrary(libPath);
if (!lib)
{
FatalIOErrorIn
(
"codedFixedValueFvPatchScalarField::"
"updateLibrary()",
contextPtr().dict()
) << "Failed to load library " << libPath
<< exit(FatalIOError);
}
//#if 0
// Info<<"check " << libPath << " for " << sentinelName << nl;
// // paranoid - check that signature function is really there
// lib = dlLibraryTable::findLibrary(libPath);
// if (!lib || !dlSymFound(lib, sentinelName))
// {
// FatalIOErrorIn
// (
// "codedFixedValueFvPatchScalarField::"
// "updateLibrary()",
// contextPtr().dict()
// ) << "Failed to load library with correct signature "
// << libPath
// << exit(FatalIOError);
// }
//#endif
}
else if (reuseLib)
{
Info<< "Reusing library in " << libPath << nl;
}
}
@ -307,7 +313,7 @@ codedFixedValueFvPatchScalarField
)
:
fixedValueFvPatchField<scalar>(p, iF),
redirectPatchFieldPtr_(NULL)
redirectPatchFieldPtr_()
{}
@ -323,7 +329,7 @@ codedFixedValueFvPatchScalarField
fixedValueFvPatchField<scalar>(ptf, p, iF, mapper),
dict_(ptf.dict_),
redirectType_(ptf.redirectType_),
redirectPatchFieldPtr_(NULL)
redirectPatchFieldPtr_()
{}
@ -338,9 +344,9 @@ codedFixedValueFvPatchScalarField
fixedValueFvPatchField<scalar>(p, iF, dict),
dict_(dict),
redirectType_(dict.lookup("redirectType")),
redirectPatchFieldPtr_(NULL)
redirectPatchFieldPtr_()
{
updateLibrary();
updateLibrary(true);
}
@ -353,7 +359,7 @@ codedFixedValueFvPatchScalarField
fixedValueFvPatchField<scalar>(ptf),
dict_(ptf.dict_),
redirectType_(ptf.redirectType_),
redirectPatchFieldPtr_(NULL)
redirectPatchFieldPtr_()
{}
@ -367,7 +373,7 @@ codedFixedValueFvPatchScalarField
fixedValueFvPatchField<scalar>(ptf, iF),
dict_(ptf.dict_),
redirectType_(ptf.redirectType_),
redirectPatchFieldPtr_(NULL)
redirectPatchFieldPtr_()
{}
@ -389,6 +395,18 @@ Foam::codedFixedValueFvPatchScalarField::redirectPatchField() const
dictionary dict(is);
Info<< "constructing patchField from :" << dict << endl;
// if (fvPatchScalarField::dictionaryConstructorTablePtr_)
// {
// fvPatchScalarField::dictionaryConstructorPtr funcPtr =
// (
// fvPatchScalarField::dictionaryConstructorTablePtr_->
// find(redirectType_)()
// );
//
// Info<< redirectType_ << " FunctionPtr => "
// << long(funcPtr) << endl;
// }
redirectPatchFieldPtr_.set
(
fvPatchScalarField::New

View File

@ -29,8 +29,6 @@ Description
Constructs on-the-fly a new boundary condition (derived from
fixedValueFvPatchScalarField) which is then used to evaluate.
See also codeStream.
Example:
\verbatim
movingWall
@ -71,7 +69,7 @@ Description
\endverbatim
SeeAlso
Foam::codeStreamTools for constant paths used
Foam::dynamicCode and Foam::functionEntries::codeStream
SourceFiles
codedFixedValueFvPatchScalarField.C
@ -82,14 +80,16 @@ SourceFiles
#define codedFixedValueFvPatchScalarField_H
#include "fixedValueFvPatchFields.H"
#include "SHA1Digest.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// Forward declaration of classes
class codeProperties;
class dynamicCode;
class dynamicCodeContext;
/*---------------------------------------------------------------------------*\
Class codedFixedValueFvPatchScalarField Declaration
@ -104,10 +104,6 @@ class codedFixedValueFvPatchScalarField
//- Dictionary contents for the boundary condition
mutable dictionary dict_;
//- SHA1Digest of the Dictionary contents
// Currently unused, but useful for reloading?
mutable SHA1Digest sha1_;
const word redirectType_;
mutable autoPtr<fvPatchScalarField> redirectPatchFieldPtr_;
@ -117,24 +113,21 @@ class codedFixedValueFvPatchScalarField
const codeProperties& dict() const;
void writeLibrary
(
const fileName& dir,
const fileName& libPath,
const dictionary& dict
);
void createLibrary(dynamicCode&, const dynamicCodeContext&) const;
void updateLibrary();
//- Update library as required
// Use 'firstTime' to alter behaviour
void updateLibrary(bool firstTime=false) const;
public:
// Static data members
//- Name of the C code template to be used
const static word codeTemplateC;
static const word codeTemplateC;
//- Name of the H code template to be used
const static word codeTemplateH;
static const word codeTemplateH;
//- Runtime type information
@ -226,7 +219,7 @@ public:
);
//- Write
virtual void write(Ostream& os) const;
virtual void write(Ostream&) const;
};

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-2010 OpenCFD Ltd.
\\ / A nd | Copyright (C) 2004-2011 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -73,7 +73,7 @@ Ostream& operator<<(Ostream&, const fvPatchField<Type>&);
/*---------------------------------------------------------------------------*\
Class patch Declaration
Class fvPatchField Declaration
\*---------------------------------------------------------------------------*/
template<class Type>
@ -516,11 +516,40 @@ public:
);
// use with caution
#define addRemovableToPatchFieldRunTimeSelection\
(PatchTypeField, typePatchTypeField) \
\
addRemovableToRunTimeSelectionTable \
( \
PatchTypeField, \
typePatchTypeField, \
patch \
); \
addRemovableToRunTimeSelectionTable \
( \
PatchTypeField, \
typePatchTypeField, \
patchMapper \
); \
addRemovableToRunTimeSelectionTable \
( \
PatchTypeField, \
typePatchTypeField, \
dictionary \
);
// for non-templated patch fields
#define makePatchTypeField(PatchTypeField, typePatchTypeField) \
defineTypeNameAndDebug(typePatchTypeField, 0); \
addToPatchFieldRunTimeSelection(PatchTypeField, typePatchTypeField)
// for non-templated patch fields - use with caution
#define makeRemovablePatchTypeField(PatchTypeField, typePatchTypeField) \
defineTypeNameAndDebug(typePatchTypeField, 0); \
addRemovableToPatchFieldRunTimeSelection(PatchTypeField, typePatchTypeField)
// for templated patch fields
#define makeTemplatePatchTypeField(PatchTypeField, typePatchTypeField) \

View File

@ -25,7 +25,7 @@ License
#include "systemCall.H"
#include "Time.H"
#include "codeStreamTools.H"
#include "dynamicCode.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
@ -71,7 +71,7 @@ void Foam::systemCall::read(const dictionary& dict)
<< "no executeCalls, endCalls or writeCalls defined."
<< endl;
}
else if (!codeStreamTools::allowSystemOperations)
else if (!dynamicCode::allowSystemOperations)
{
FatalErrorIn
(

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-2010 OpenCFD Ltd.
\\ / A nd | Copyright (C) 2004-2011 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -194,7 +194,7 @@ public:
//- Tolerance when comparing points. Usually relative to difference
// between start_ and end_
const static scalar tol;
static const scalar tol;
// Constructors