diff --git a/ReleaseNotes-dev b/ReleaseNotes-dev index cb57f5cf9f..7583a3d999 100644 --- a/ReleaseNotes-dev +++ b/ReleaseNotes-dev @@ -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. diff --git a/applications/utilities/mesh/conversion/fluentMeshToFoam/extrudedQuadCellShape.C b/applications/utilities/mesh/conversion/fluentMeshToFoam/extrudedQuadCellShape.C index 52725b34fa..901243eaad 100644 --- a/applications/utilities/mesh/conversion/fluentMeshToFoam/extrudedQuadCellShape.C +++ b/applications/utilities/mesh/conversion/fluentMeshToFoam/extrudedQuadCellShape.C @@ -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_) { diff --git a/applications/utilities/mesh/conversion/fluentMeshToFoam/extrudedTriangleCellShape.C b/applications/utilities/mesh/conversion/fluentMeshToFoam/extrudedTriangleCellShape.C index 954906998c..5d21940f31 100644 --- a/applications/utilities/mesh/conversion/fluentMeshToFoam/extrudedTriangleCellShape.C +++ b/applications/utilities/mesh/conversion/fluentMeshToFoam/extrudedTriangleCellShape.C @@ -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_) { diff --git a/applications/utilities/mesh/conversion/sammToFoam/calcPointCells.C b/applications/utilities/mesh/conversion/sammToFoam/calcPointCells.C index 70466aad5e..b38fd92071 100644 --- a/applications/utilities/mesh/conversion/sammToFoam/calcPointCells.C +++ b/applications/utilities/mesh/conversion/sammToFoam/calcPointCells.C @@ -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_) { diff --git a/applications/utilities/mesh/conversion/star3ToFoam/calcPointCells.C b/applications/utilities/mesh/conversion/star3ToFoam/calcPointCells.C index f3f4c36ef6..a76c8db4e4 100644 --- a/applications/utilities/mesh/conversion/star3ToFoam/calcPointCells.C +++ b/applications/utilities/mesh/conversion/star3ToFoam/calcPointCells.C @@ -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_) { diff --git a/applications/utilities/postProcessing/graphics/fieldview9Reader/readerDatabase.H b/applications/utilities/postProcessing/graphics/fieldview9Reader/readerDatabase.H index 771e6cd6bd..607b891be9 100644 --- a/applications/utilities/postProcessing/graphics/fieldview9Reader/readerDatabase.H +++ b/applications/utilities/postProcessing/graphics/fieldview9Reader/readerDatabase.H @@ -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 @@ -54,7 +54,7 @@ class fileName; class instant; /*---------------------------------------------------------------------------*\ - Class readerDatabase Declaration + Class readerDatabase Declaration \*---------------------------------------------------------------------------*/ class readerDatabase @@ -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 diff --git a/bin/tools/CleanFunctions b/bin/tools/CleanFunctions index 458fdc026e..3c1c9412d9 100644 --- a/bin/tools/CleanFunctions +++ b/bin/tools/CleanFunctions @@ -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 diff --git a/doc/changes/codeStream.org b/doc/changes/dynamicCode.org similarity index 92% rename from doc/changes/codeStream.org rename to doc/changes/dynamicCode.org index 6e26ba9810..9ea400ef4b 100644 --- a/doc/changes/codeStream.org +++ b/doc/changes/dynamicCode.org @@ -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/= and compiles + - it writes library source files to =dynamicCode/= 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. diff --git a/etc/codeTemplates/codeStream/codeStreamTemplate.C b/etc/codeTemplates/dynamicCode/codeStreamTemplate.C similarity index 97% rename from etc/codeTemplates/codeStream/codeStreamTemplate.C rename to etc/codeTemplates/dynamicCode/codeStreamTemplate.C index 50a47e1b1a..35ff81f476 100644 --- a/etc/codeTemplates/codeStream/codeStreamTemplate.C +++ b/etc/codeTemplates/dynamicCode/codeStreamTemplate.C @@ -44,8 +44,8 @@ extern "C" { void ${typeName} ( - const dictionary& dict, - Ostream& os + Ostream& os, + const dictionary& dict ) { //{{{ begin code diff --git a/etc/codeTemplates/codeStream/fixedValueFvPatchScalarFieldTemplate.C b/etc/codeTemplates/dynamicCode/fixedValueFvPatchScalarFieldTemplate.C similarity index 93% rename from etc/codeTemplates/codeStream/fixedValueFvPatchScalarFieldTemplate.C rename to etc/codeTemplates/dynamicCode/fixedValueFvPatchScalarFieldTemplate.C index 76a31e9fb0..d1213a4bea 100644 --- a/etc/codeTemplates/codeStream/fixedValueFvPatchScalarFieldTemplate.C +++ b/etc/codeTemplates/dynamicCode/fixedValueFvPatchScalarFieldTemplate.C @@ -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 diff --git a/etc/codeTemplates/codeStream/fixedValueFvPatchScalarFieldTemplate.H b/etc/codeTemplates/dynamicCode/fixedValueFvPatchScalarFieldTemplate.H similarity index 98% rename from etc/codeTemplates/codeStream/fixedValueFvPatchScalarFieldTemplate.H rename to etc/codeTemplates/dynamicCode/fixedValueFvPatchScalarFieldTemplate.H index b6ef87c8bc..c9a2d1c160 100644 --- a/etc/codeTemplates/codeStream/fixedValueFvPatchScalarFieldTemplate.H +++ b/etc/codeTemplates/dynamicCode/fixedValueFvPatchScalarFieldTemplate.H @@ -121,6 +121,9 @@ public: ); } + //- Destructor + virtual ~${typeName}FixedValueFvPatchScalarField(); + // Member functions diff --git a/etc/controlDict b/etc/controlDict index 4aa8a3ec0a..cc45466672 100644 --- a/etc/controlDict +++ b/etc/controlDict @@ -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; } diff --git a/etc/settings.csh b/etc/settings.csh index a48a188382..48b234a337 100644 --- a/etc/settings.csh +++ b/etc/settings.csh @@ -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 diff --git a/etc/settings.sh b/etc/settings.sh index 9281ffba95..beebfacf74 100644 --- a/etc/settings.sh +++ b/etc/settings.sh @@ -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 diff --git a/src/OSspecific/POSIX/POSIX.C b/src/OSspecific/POSIX/POSIX.C index 4909d08244..e6e54c32c0 100644 --- a/src/OSspecific/POSIX/POSIX.C +++ b/src/OSspecific/POSIX/POSIX.C @@ -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; + } +} + + // ************************************************************************* // diff --git a/src/OpenFOAM/Make/files b/src/OpenFOAM/Make/files index 09e342c3e7..432f6ccc0e 100644 --- a/src/OpenFOAM/Make/files +++ b/src/OpenFOAM/Make/files @@ -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 diff --git a/src/OpenFOAM/db/dictionary/functionEntries/codeStream/codeStream.C b/src/OpenFOAM/db/dictionary/functionEntries/codeStream/codeStream.C index 6144653367..92a6b444f1 100644 --- a/src/OpenFOAM/db/dictionary/functionEntries/codeStream/codeStream.C +++ b/src/OpenFOAM/db/dictionary/functionEntries/codeStream/codeStream.C @@ -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 + _ + // codeDir : _ + 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 copyFiles(1); - copyFiles[0].file() = fileCsrc; - copyFiles[0].set("codeInclude", codeInclude); - copyFiles[0].set("code", code); - copyFiles[0].set("SHA1sum", sha.str()); - - List 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 " <()); + bool waiting = true; + reduce(waiting, orOp()); 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 + // Find the function handle in the library + void (*function)(Ostream&, const dictionary&); + function = reinterpret_cast ( - 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); diff --git a/src/OpenFOAM/db/dictionary/functionEntries/codeStream/codeStream.H b/src/OpenFOAM/db/dictionary/functionEntries/codeStream/codeStream.H index e04bdceaa4..10e3262ca1 100644 --- a/src/OpenFOAM/db/dictionary/functionEntries/codeStream/codeStream.H +++ b/src/OpenFOAM/db/dictionary/functionEntries/codeStream/codeStream.H @@ -135,8 +135,8 @@ public: static bool execute ( const dictionary& parentDict, - primitiveEntry& entry, - Istream& is + primitiveEntry&, + Istream& ); }; diff --git a/src/OpenFOAM/db/dynamicLibrary/codeStream/codeStreamTools.C b/src/OpenFOAM/db/dynamicLibrary/codeStream/codeStreamTools.C deleted file mode 100644 index cf252d1f8b..0000000000 --- a/src/OpenFOAM/db/dynamicLibrary/codeStream/codeStreamTools.C +++ /dev/null @@ -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& 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& copyFiles, - const List& 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 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; -} - - -// ************************************************************************* // diff --git a/src/OpenFOAM/db/dynamicLibrary/codeStream/codeStreamTools.H b/src/OpenFOAM/db/dynamicLibrary/codeStream/codeStreamTools.H deleted file mode 100644 index 8df397cc15..0000000000 --- a/src/OpenFOAM/db/dynamicLibrary/codeStream/codeStreamTools.H +++ /dev/null @@ -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 fileAndContent; - - //- Helper class for managing file and variables - class fileAndVars - : - public HashTable - { - // 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 copyFiles_; - - //- Direct contents for files - List filesContents_; - -protected: - - void copyAndExpand - ( - ISstream&, - OSstream&, - const HashTable& 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&, - const List& - ); - - //- 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& copyFiles() const - { - return copyFiles_; - } - - const List >& 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 - -// ************************************************************************* // diff --git a/src/OpenFOAM/db/dynamicLibrary/dynamicCode/dynamicCode.C b/src/OpenFOAM/db/dynamicLibrary/dynamicCode/dynamicCode.C new file mode 100644 index 0000000000..2493ad8d16 --- /dev/null +++ b/src/OpenFOAM/db/dynamicLibrary/dynamicCode/dynamicCode.C @@ -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& 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& templateNames, + DynamicList& resolvedFiles, + DynamicList& 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 resolvedFiles(nFiles); + DynamicList 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()); +// } + + +// ************************************************************************* // diff --git a/src/OpenFOAM/db/dynamicLibrary/dynamicCode/dynamicCode.H b/src/OpenFOAM/db/dynamicLibrary/dynamicCode/dynamicCode.H new file mode 100644 index 0000000000..af7f996c08 --- /dev/null +++ b/src/OpenFOAM/db/dynamicLibrary/dynamicCode/dynamicCode.H @@ -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 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 compileFiles_; + + //- Files to copy and filter + DynamicList copyFiles_; + + //- Direct contents for files + DynamicList createFiles_; + + //- Variables to use during filtering + HashTable 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& mapping + ); + + //- Resolve code-templates via the codeTemplateEnvName + // alternatively in the codeTemplateDirName via Foam::findEtcFile + static bool resolveTemplates + ( + const UList& templateNames, + DynamicList& resolvedFiles, + DynamicList& 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\.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 + +// ************************************************************************* // diff --git a/src/OpenFOAM/db/dynamicLibrary/dynamicCode/dynamicCodeContext.C b/src/OpenFOAM/db/dynamicLibrary/dynamicCode/dynamicCodeContext.C new file mode 100644 index 0000000000..44ca8f6fda --- /dev/null +++ b/src/OpenFOAM/db/dynamicLibrary/dynamicCode/dynamicCodeContext.C @@ -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(); +} + + +// ************************************************************************* // diff --git a/src/OpenFOAM/db/dynamicLibrary/dynamicCode/dynamicCodeContext.H b/src/OpenFOAM/db/dynamicLibrary/dynamicCode/dynamicCodeContext.H new file mode 100644 index 0000000000..2aa248c20f --- /dev/null +++ b/src/OpenFOAM/db/dynamicLibrary/dynamicCode/dynamicCodeContext.H @@ -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 + +// ************************************************************************* // diff --git a/src/OpenFOAM/db/runTimeSelection/construction/addToRunTimeSelectionTable.H b/src/OpenFOAM/db/runTimeSelection/construction/addToRunTimeSelectionTable.H index f0978ed635..5535ad7510 100644 --- a/src/OpenFOAM/db/runTimeSelection/construction/addToRunTimeSelectionTable.H +++ b/src/OpenFOAM/db/runTimeSelection/construction/addToRunTimeSelectionTable.H @@ -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 . -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) + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // diff --git a/src/OpenFOAM/db/runTimeSelection/construction/runTimeSelectionTables.H b/src/OpenFOAM/db/runTimeSelection/construction/runTimeSelectionTables.H index 4ca3c15f55..977e0f124a 100644 --- a/src/OpenFOAM/db/runTimeSelection/construction/runTimeSelectionTables.H +++ b/src/OpenFOAM/db/runTimeSelection/construction/runTimeSelectionTables.H @@ -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 . -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; \ } \ } diff --git a/src/OpenFOAM/db/runTimeSelection/globalFunctions/globalFunctionSelectionTables.H b/src/OpenFOAM/db/runTimeSelection/globalFunctions/globalFunctionSelectionTables.H index 76481db279..1601c172a0 100644 --- a/src/OpenFOAM/db/runTimeSelection/globalFunctions/globalFunctionSelectionTables.H +++ b/src/OpenFOAM/db/runTimeSelection/globalFunctions/globalFunctionSelectionTables.H @@ -85,13 +85,14 @@ Description } \ } + // internal use: // constructor/destructor aid #define defineGlobalFunctionSelectionTableConstructDestruct\ (memberFunction,argNames) \ \ /* Table constructor called from the table add function */ \ - void construct##memberFunction##argNames##MemberFunctionTables()\ + void construct##memberFunction##argNames##MemberFunctionTables() \ { \ static bool constructed = false; \ if (!constructed) \ @@ -103,7 +104,7 @@ Description } \ \ /* Table destructor called from the table add function destructor */ \ - void destroy##memberFunction##argNames##MemberFunctionTables()\ + void destroy##memberFunction##argNames##MemberFunctionTables() \ { \ if (memberFunction##argNames##MemberFunctionTablePtr_) \ { \ diff --git a/src/OpenFOAM/db/runTimeSelection/memberFunctions/memberFunctionSelectionTables.H b/src/OpenFOAM/db/runTimeSelection/memberFunctions/memberFunctionSelectionTables.H index 13835fbb3c..16a3accd41 100644 --- a/src/OpenFOAM/db/runTimeSelection/memberFunctions/memberFunctionSelectionTables.H +++ b/src/OpenFOAM/db/runTimeSelection/memberFunctions/memberFunctionSelectionTables.H @@ -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::memberFunction##argNames##MemberFunctionTablePtr_ \ = new baseType::memberFunction##argNames## \ MemberFunctionTable; \ - \ - constructed = true; \ } \ } @@ -254,6 +250,7 @@ Description defineTemplatedMemberFunctionSelectionTableDestructor \ (baseType,memberFunction,argNames,Targ) + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // #endif diff --git a/src/OpenFOAM/global/argList/argList.C b/src/OpenFOAM/global/argList/argList.C index 08cc78f762..f055011bce 100644 --- a/src/OpenFOAM/global/argList/argList.C +++ b/src/OpenFOAM/global/argList/argList.C @@ -32,7 +32,7 @@ License #include "JobInfo.H" #include "labelList.H" #include "regIOobject.H" -#include "codeStreamTools.H" +#include "dynamicCode.H" #include @@ -790,7 +790,7 @@ Foam::argList::argList << endl; Info<< "allowSystemOperations : "; - if (codeStreamTools::allowSystemOperations) + if (dynamicCode::allowSystemOperations) { Info<< "Allowing user-supplied system call operations" << endl; } diff --git a/src/OpenFOAM/include/OSspecific.H b/src/OpenFOAM/include/OSspecific.H index 38b0d14a10..d68ae1661d 100644 --- a/src/OpenFOAM/include/OSspecific.H +++ b/src/OpenFOAM/include/OSspecific.H @@ -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); + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // diff --git a/src/OpenFOAM/primitives/hashes/SHA1/SHA1.C b/src/OpenFOAM/primitives/hashes/SHA1/SHA1.C index 5a54e10d6e..5c97cee6c4 100644 --- a/src/OpenFOAM/primitives/hashes/SHA1/SHA1.C +++ b/src/OpenFOAM/primitives/hashes/SHA1/SHA1.C @@ -151,7 +151,7 @@ void Foam::SHA1::processBytes(const void *data, size_t len) // while (len > 64) while (len >= 64) { - processBlock(memcpy (buffer_, data, 64), 64); + processBlock(memcpy(buffer_, data, 64), 64); data = reinterpret_cast(data) + 64; len -= 64; } @@ -177,7 +177,7 @@ void Foam::SHA1::processBytes(const void *data, size_t len) { processBlock(buffer_, 64); remaining -= 64; - memcpy (buffer_, &buffer_[16], remaining); + memcpy(buffer_, &buffer_[16], remaining); } bufLen_ = remaining; } @@ -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++; + x[t] = swapBytes(*words); + ++words; } R( a, b, c, d, e, F1, K1, x[ 0] ); @@ -343,11 +343,11 @@ void Foam::SHA1::calcDigest(SHA1Digest& dig) const { unsigned char *r = dig.v_; - set_uint32 (r + 0 * sizeof(uint32_t), swapBytes(hashsumA_)); - set_uint32 (r + 1 * sizeof(uint32_t), swapBytes(hashsumB_)); - set_uint32 (r + 2 * sizeof(uint32_t), swapBytes(hashsumC_)); - set_uint32 (r + 3 * sizeof(uint32_t), swapBytes(hashsumD_)); - set_uint32 (r + 4 * sizeof(uint32_t), swapBytes(hashsumE_)); + set_uint32(r + 0 * sizeof(uint32_t), swapBytes(hashsumA_)); + set_uint32(r + 1 * sizeof(uint32_t), swapBytes(hashsumB_)); + set_uint32(r + 2 * sizeof(uint32_t), swapBytes(hashsumC_)); + set_uint32(r + 3 * sizeof(uint32_t), swapBytes(hashsumD_)); + set_uint32(r + 4 * sizeof(uint32_t), swapBytes(hashsumE_)); } else { diff --git a/src/OpenFOAM/primitives/hashes/SHA1/SHA1Digest.C b/src/OpenFOAM/primitives/hashes/SHA1/SHA1Digest.C index 16dbd838cd..bf0730d2e4 100644 --- a/src/OpenFOAM/primitives/hashes/SHA1/SHA1Digest.C +++ b/src/OpenFOAM/primitives/hashes/SHA1/SHA1Digest.C @@ -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; - is.read(c); + 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); } diff --git a/src/OpenFOAM/primitives/hashes/SHA1/SHA1Digest.H b/src/OpenFOAM/primitives/hashes/SHA1/SHA1Digest.H index dca6adc367..e93a72b020 100644 --- a/src/OpenFOAM/primitives/hashes/SHA1/SHA1Digest.H +++ b/src/OpenFOAM/primitives/hashes/SHA1/SHA1Digest.H @@ -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; @@ -57,7 +57,7 @@ Istream& operator>>(Istream&, SHA1Digest&); /*---------------------------------------------------------------------------*\ - Class SHA1Digest Declaration + Class SHA1Digest Declaration \*---------------------------------------------------------------------------*/ class SHA1Digest @@ -65,57 +65,89 @@ class SHA1Digest public: friend class SHA1; - //- The length of the digest contents - static const unsigned length = 20; + // Static data members - //- Construct a zero digest - SHA1Digest(); + //- The length of the (uncoded) digest contents + static const unsigned length = 20; - //- Construct read a digest - SHA1Digest(Istream&); - - //- 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; - - //- Equality operator - bool operator==(const SHA1Digest&) const; - - //- Compare to (40-byte) text representation (eg, from sha1sum) - // An %empty string is equivalent to - // "0000000000000000000000000000000000000000" - 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" - bool operator==(const char* hexdigits) const; + //- A null digest (ie, all zero) + static const SHA1Digest null; - //- Inequality operator - bool operator!=(const SHA1Digest&) const; + // Constructors - //- Inequality operator - bool operator!=(const std::string& hexdigits) const; + //- Construct a zero digest + SHA1Digest(); - //- Inequality operator - bool operator!=(const char* hexdigits) const; + //- Construct read a digest + SHA1Digest(Istream&); - friend Ostream& operator<<(Ostream&, const SHA1Digest&); - friend Istream& operator>>(Istream&, SHA1Digest&); + // Member Functions + + //- Reset the digest to zero + void clear(); + + //- Return true if the digest is empty (ie, all zero). + bool empty() 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; + + //- 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; + + + //- Inequality operator + bool operator!=(const SHA1Digest&) const; + + //- Inequality operator + bool operator!=(const std::string& hexdigits) const; + + //- Inequality operator + bool operator!=(const char* hexdigits) const; + + + + + // 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]; + //- The digest contents + unsigned char v_[length]; - static unsigned char readHexDigit(Istream&); + //- Read hexadecimal value, ignoring leading or intermediate '_' + static unsigned char readHexDigit(Istream&); }; diff --git a/src/conversion/meshReader/calcPointCells.C b/src/conversion/meshReader/calcPointCells.C index 948d15ce81..a1e0f92285 100644 --- a/src/conversion/meshReader/calcPointCells.C +++ b/src/conversion/meshReader/calcPointCells.C @@ -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_) { diff --git a/src/finiteVolume/fields/fvPatchFields/derived/codedFixedValue/codeProperties.C b/src/finiteVolume/fields/fvPatchFields/derived/codedFixedValue/codeProperties.C index e56fc33635..c104d3d71b 100644 --- a/src/finiteVolume/fields/fvPatchFields/derived/codedFixedValue/codeProperties.C +++ b/src/finiteVolume/fields/fvPatchFields/derived/codedFixedValue/codeProperties.C @@ -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()) diff --git a/src/finiteVolume/fields/fvPatchFields/derived/codedFixedValue/codeProperties.H b/src/finiteVolume/fields/fvPatchFields/derived/codedFixedValue/codeProperties.H index 6916fa362f..f8d855274f 100644 --- a/src/finiteVolume/fields/fvPatchFields/derived/codedFixedValue/codeProperties.H +++ b/src/finiteVolume/fields/fvPatchFields/derived/codedFixedValue/codeProperties.H @@ -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(); diff --git a/src/finiteVolume/fields/fvPatchFields/derived/codedFixedValue/codedFixedValueFvPatchScalarField.C b/src/finiteVolume/fields/fvPatchFields/derived/codedFixedValue/codedFixedValueFvPatchScalarField.C index 8b19852db8..8175f1b5ed 100644 --- a/src/finiteVolume/fields/fvPatchFields/derived/codedFixedValue/codedFixedValueFvPatchScalarField.C +++ b/src/finiteVolume/fields/fvPatchFields/derived/codedFixedValue/codedFixedValueFvPatchScalarField.C @@ -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 - ( - "codedFixedValueFvPatchScalarField::writeLibrary(..)", - dict - ) << "Could not find one or both code templates: " - << codeTemplateC << ", " << codeTemplateH << nl - << codeStreamTools::searchedLocations() - << exit(FatalIOError); - } - - - - List 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 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() = + // define Make/options + dynCode.setMakeOptions + ( "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 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(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); } } + + // library exists (and was not unloaded) - we can leave now + if (lib) + { + return; + } + + + // Remove instantiation of fvPatchField provided by library + redirectPatchFieldPtr_.clear(); + + if (contextPtr.empty()) + { + 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()", + contextPtr().dict() + ) << "Failed unloading library " + << libPath + << exit(FatalIOError); + } + } + } + } + + + // really do need to create library if (!lib) { if (Pstream::master()) { - const Foam::string wmakeCmd("wmake libso " + codePath); - Info<< "Invoking " << wmakeCmd << endl; - if (Foam::system(wmakeCmd)) + createLibrary(dynCode, contextPtr()); + + if (!dynCode.wmakeLibso()) { FatalIOErrorIn ( "codedFixedValueFvPatchScalarField::updateLibrary()", - dict_ - ) << "Failed " << wmakeCmd + contextPtr().dict() + ) << "Failed wmake " << libPath << exit(FatalIOError); } } // all processes must wait for compile - bool dummy = true; - reduce(dummy, orOp()); + waiting = true; + reduce(waiting, orOp()); - 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(p, iF), - redirectPatchFieldPtr_(NULL) + redirectPatchFieldPtr_() {} @@ -323,7 +329,7 @@ codedFixedValueFvPatchScalarField fixedValueFvPatchField(ptf, p, iF, mapper), dict_(ptf.dict_), redirectType_(ptf.redirectType_), - redirectPatchFieldPtr_(NULL) + redirectPatchFieldPtr_() {} @@ -338,9 +344,9 @@ codedFixedValueFvPatchScalarField fixedValueFvPatchField(p, iF, dict), dict_(dict), redirectType_(dict.lookup("redirectType")), - redirectPatchFieldPtr_(NULL) + redirectPatchFieldPtr_() { - updateLibrary(); + updateLibrary(true); } @@ -353,7 +359,7 @@ codedFixedValueFvPatchScalarField fixedValueFvPatchField(ptf), dict_(ptf.dict_), redirectType_(ptf.redirectType_), - redirectPatchFieldPtr_(NULL) + redirectPatchFieldPtr_() {} @@ -367,7 +373,7 @@ codedFixedValueFvPatchScalarField fixedValueFvPatchField(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 diff --git a/src/finiteVolume/fields/fvPatchFields/derived/codedFixedValue/codedFixedValueFvPatchScalarField.H b/src/finiteVolume/fields/fvPatchFields/derived/codedFixedValue/codedFixedValueFvPatchScalarField.H index d08059be3a..7b0ef5a642 100644 --- a/src/finiteVolume/fields/fvPatchFields/derived/codedFixedValue/codedFixedValueFvPatchScalarField.H +++ b/src/finiteVolume/fields/fvPatchFields/derived/codedFixedValue/codedFixedValueFvPatchScalarField.H @@ -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 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; }; diff --git a/src/finiteVolume/fields/fvPatchFields/fvPatchField/fvPatchField.H b/src/finiteVolume/fields/fvPatchFields/fvPatchField/fvPatchField.H index c534d3e83c..a91f61c577 100644 --- a/src/finiteVolume/fields/fvPatchFields/fvPatchField/fvPatchField.H +++ b/src/finiteVolume/fields/fvPatchFields/fvPatchField/fvPatchField.H @@ -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&); /*---------------------------------------------------------------------------*\ - Class patch Declaration + Class fvPatchField Declaration \*---------------------------------------------------------------------------*/ template @@ -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) \ diff --git a/src/postProcessing/functionObjects/systemCall/systemCall.C b/src/postProcessing/functionObjects/systemCall/systemCall.C index 0a9d825644..90c34dd286 100644 --- a/src/postProcessing/functionObjects/systemCall/systemCall.C +++ b/src/postProcessing/functionObjects/systemCall/systemCall.C @@ -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 ( diff --git a/src/sampling/sampledSet/sampledSet/sampledSet.H b/src/sampling/sampledSet/sampledSet/sampledSet.H index dbaf107070..7b2cd177b1 100644 --- a/src/sampling/sampledSet/sampledSet/sampledSet.H +++ b/src/sampling/sampledSet/sampledSet/sampledSet.H @@ -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 @@ -56,7 +56,7 @@ class polyMesh; class meshSearch; /*---------------------------------------------------------------------------*\ - Class sampledSet Declaration + Class sampledSet Declaration \*---------------------------------------------------------------------------*/ class sampledSet @@ -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