00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
00032 
00033 
00034 
00035 
00036 
00037 
00038 
00039 
00040 
00041 
00042 
00043 
00044 
00045 
00046 
00047 
00048 
00049 
00050 
00051 
00052 
00053 
00054 
00055 
00056 
00057 
00058 
00059 
00060 
00061 
00062 
00063 
00064 
00065 
00066 
00067 
00068 
00069 
00070 
00071 
00072 
00073 
00074 
00075 
00076 
00077 
00078 
00079 
00080 
00081 
00082 
00083 #include <OpenFOAM/argList.H>
00084 #include <OpenFOAM/IOobjectList.H>
00085 #include <OpenFOAM/IOPtrList.H>
00086 #include <finiteVolume/volFields.H>
00087 #include <OpenFOAM/stringListOps.H>
00088 
00089 using namespace Foam;
00090 
00091 
00092 
00093 namespace Foam
00094 {
00095     defineTemplateTypeNameAndDebug(IOPtrList<entry>, 0);
00096 }
00097 
00098 
00099 
00100 
00101 bool merge(dictionary&, const dictionary&, const bool);
00102 
00103 
00104 
00105 bool addEntry
00106 (
00107     dictionary& thisDict,
00108     entry& thisEntry,
00109     const entry& mergeEntry,
00110     const bool literalRE
00111 )
00112 {
00113     bool changed = false;
00114 
00115     
00116     
00117     if (thisEntry.isDict() && mergeEntry.isDict())
00118     {
00119         if
00120         (
00121             merge
00122             (
00123                 const_cast<dictionary&>(thisEntry.dict()),
00124                 mergeEntry.dict(),
00125                 literalRE
00126             )
00127         )
00128         {
00129             changed = true;
00130         }
00131     }
00132     else
00133     {
00134         
00135         thisDict.add(mergeEntry.clone(thisDict).ptr(), true);
00136         changed = true;
00137     }
00138 
00139     return changed;
00140 }
00141 
00142 
00143 
00144 
00145 
00146 
00147 
00148 bool merge
00149 (
00150     dictionary& thisDict,
00151     const dictionary& mergeDict,
00152     const bool literalRE
00153 )
00154 {
00155     static bool wildCardInMergeDict = false;
00156 
00157     bool changed = false;
00158 
00159     
00160     HashSet<word> thisKeysSet;
00161     {
00162         List<keyType> keys = thisDict.keys(false);
00163         forAll(keys, i)
00164         {
00165             thisKeysSet.insert(keys[i]);
00166         }
00167     }
00168 
00169     
00170 
00171     forAllConstIter(IDLList<entry>, mergeDict, mergeIter)
00172     {
00173         const keyType& key = mergeIter().keyword();
00174 
00175         if (literalRE || !key.isPattern())
00176         {
00177             entry* entryPtr = thisDict.lookupEntryPtr
00178             (
00179                 key,
00180                 false,              
00181                 false               
00182             );
00183 
00184             if (entryPtr)
00185             {
00186 
00187                 
00188                 
00189                 thisKeysSet.erase(entryPtr->keyword());
00190 
00191                 if
00192                 (
00193                     addEntry
00194                     (
00195                         thisDict,
00196                        *entryPtr,
00197                         mergeIter(),
00198                         literalRE
00199                     )
00200                 )
00201                 {
00202                     changed = true;
00203                 }
00204             }
00205             else
00206             {
00207                 
00208                 thisDict.add(mergeIter().clone(thisDict).ptr());
00209                 changed = true;
00210             }
00211         }
00212     }
00213 
00214 
00215     
00216 
00217     if (!literalRE && thisKeysSet.size() > 0)
00218     {
00219         wordList thisKeys(thisKeysSet.toc());
00220 
00221         forAllConstIter(IDLList<entry>, mergeDict, mergeIter)
00222         {
00223             const keyType& key = mergeIter().keyword();
00224 
00225             if (key.isPattern())
00226             {
00227                 
00228 
00229                 if (!wildCardInMergeDict)
00230                 {
00231                     wildCardInMergeDict = true;
00232                     WarningIn("changeDictionary()")
00233                         << "Detected wildcard " << key
00234                         << " in changeDictionaryDict" << endl
00235                         << "The behaviour of wildcards has changed -"
00236                         << " they are now interpreted by changeDictionary."
00237                         << endl << "Please take care or use the -literalRE"
00238                         << " command line option to revert to"
00239                         << " previous behaviour." << endl;
00240                 }
00241 
00242                 labelList matches = findStrings(key, thisKeys);
00243 
00244                 forAll(matches, i)
00245                 {
00246                     label matchI = matches[i];
00247 
00248                     entry& thisEntry = const_cast<entry&>
00249                     (
00250                         thisDict.lookupEntry(thisKeys[matchI], false, false)
00251                     );
00252 
00253                     if
00254                     (
00255                         addEntry
00256                         (
00257                             thisDict,
00258                             thisEntry,
00259                             mergeIter(),
00260                             literalRE
00261                         )
00262                     )
00263                     {
00264                         changed = true;
00265                     }
00266                 }
00267             }
00268         }
00269     }
00270 
00271     return changed;
00272 }
00273 
00274 
00275 
00276 
00277 int main(int argc, char *argv[])
00278 {
00279     argList::validOptions.insert("instance", "instance");
00280     argList::validOptions.insert("literalRE", "");
00281     #include <OpenFOAM/addRegionOption.H>
00282 
00283     #include <OpenFOAM/setRootCase.H>
00284     #include <OpenFOAM/createTime.H>
00285     #include <OpenFOAM/createNamedMesh.H>
00286 
00287     bool literalRE = args.optionFound("literalRE");
00288 
00289     if (literalRE)
00290     {
00291         Info<< "Not interpreting any regular expressions (RE)"
00292             << " in the changeDictionaryDict." << endl
00293             << "Instead they are handled as any other entry, i.e. added if"
00294             << " not present." << endl;
00295     }
00296 
00297 
00298     fileName regionPrefix = "";
00299     if (regionName != fvMesh::defaultRegion)
00300     {
00301         regionPrefix = regionName;
00302     }
00303 
00304     word instance = runTime.timeName();
00305     if (args.options().found("instance"))
00306     {
00307         instance = args.options()["instance"];
00308     }
00309 
00310     
00311     IOdictionary dict
00312     (
00313         IOobject
00314         (
00315             "changeDictionaryDict",
00316             runTime.system(),
00317             mesh,
00318             IOobject::MUST_READ,
00319             IOobject::NO_WRITE
00320         )
00321     );
00322     const dictionary& replaceDicts = dict.subDict("dictionaryReplacement");
00323     Info<< "Read dictionary " << dict.name()
00324         << " with replacements for dictionaries "
00325         << replaceDicts.toc() << endl;
00326 
00327 
00328     
00329 
00330     forAllConstIter(dictionary, replaceDicts, fieldIter)
00331     {
00332         const word& fieldName = fieldIter().keyword();
00333         Info<< "Replacing entries in dictionary " << fieldName << endl;
00334 
00335         
00336         
00337         
00338         if (fieldName == "boundary")
00339         {
00340             Info<< "Special handling of " << fieldName
00341                 << " as polyMesh/boundary file." << endl;
00342 
00343             
00344             const word oldTypeName = IOPtrList<entry>::typeName;
00345             const_cast<word&>(IOPtrList<entry>::typeName) = word::null;
00346             IOPtrList<entry> dictList
00347             (
00348                 IOobject
00349                 (
00350                     fieldName,
00351                     runTime.findInstance
00352                     (
00353                         regionPrefix/polyMesh::meshSubDir,
00354                         fieldName
00355                     ),
00356                     polyMesh::meshSubDir,
00357                     mesh,
00358                     IOobject::MUST_READ,
00359                     IOobject::NO_WRITE,
00360                     false
00361                 )
00362             );
00363             const_cast<word&>(IOPtrList<entry>::typeName) = oldTypeName;
00364             
00365             const_cast<word&>(dictList.type()) = dictList.headerClassName();
00366 
00367             
00368             dictionary fieldDict;
00369             forAll(dictList, i)
00370             {
00371                 fieldDict.add(dictList[i].keyword(), dictList[i].dict());
00372             }
00373 
00374             Info<< "Loaded dictionary " << fieldName
00375                 << " with entries " << fieldDict.toc() << endl;
00376 
00377             
00378             const dictionary& replaceDict = fieldIter().dict();
00379             Info<< "Merging entries from " << replaceDict.toc() << endl;
00380 
00381             
00382             merge(fieldDict, replaceDict, literalRE);
00383 
00384             Info<< "fieldDict:" << fieldDict << endl;
00385 
00386             
00387             wordList doneKeys(dictList.size());
00388 
00389             label nEntries = fieldDict.size();
00390             forAll(dictList, i)
00391             {
00392                 doneKeys[i] = dictList[i].keyword();
00393                 dictList.set
00394                 (
00395                     i,
00396                     fieldDict.lookupEntry
00397                     (
00398                         doneKeys[i],
00399                         false,
00400                         true
00401                     ).clone()
00402                 );
00403                 fieldDict.remove(doneKeys[i]);
00404             }
00405             
00406             label sz = dictList.size();
00407             dictList.setSize(nEntries);
00408             forAllConstIter(dictionary, fieldDict, iter)
00409             {
00410                 dictList.set(sz, iter().clone());
00411             }
00412 
00413             Info<< "Writing modified fieldDict " << fieldName << endl;
00414             dictList.write();
00415         }
00416         else
00417         {
00418             
00419             
00420             Info<< "Loading dictionary " << fieldName << endl;
00421             const word oldTypeName = IOdictionary::typeName;
00422             const_cast<word&>(IOdictionary::typeName) = word::null;
00423 
00424             IOdictionary fieldDict
00425             (
00426                 IOobject
00427                 (
00428                     fieldName,
00429                     instance,
00430                     mesh,
00431                     IOobject::MUST_READ,
00432                     IOobject::NO_WRITE,
00433                     false
00434                 )
00435             );
00436             const_cast<word&>(IOdictionary::typeName) = oldTypeName;
00437             
00438             const_cast<word&>(fieldDict.type()) = fieldDict.headerClassName();
00439 
00440             Info<< "Loaded dictionary " << fieldName
00441                 << " with entries " << fieldDict.toc() << endl;
00442 
00443             
00444             const dictionary& replaceDict = fieldIter().dict();
00445             Info<< "Merging entries from " << replaceDict.toc() << endl;
00446 
00447             
00448             merge(fieldDict, replaceDict, literalRE);
00449 
00450             Info<< "Writing modified fieldDict " << fieldName << endl;
00451             fieldDict.regIOobject::write();
00452         }
00453     }
00454 
00455     Info<< endl;
00456 
00457     Info<< "End\n" << endl;
00458 
00459     return 0;
00460 }
00461 
00462 
00463