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