src/Env/Param/ParamDB.cpp

説明を見る。
00001 // 
00002 // Copyright (c) 2005-2008 Kenichi Watanabe.
00003 // Copyright (c) 2005-2008 Yasuhiro Watari.
00004 // Copyright (c) 2005-2008 Hironori Ichibayashi.
00005 // Copyright (c) 2008-2009 Kazuo Horio.
00006 // Copyright (c) 2009-2013 Naruki Kurata.
00007 // Copyright (c) 2005-2013 Ryota Shioya.
00008 // Copyright (c) 2005-2013 Masahiro Goshima.
00009 // 
00010 // This software is provided 'as-is', without any express or implied
00011 // warranty. In no event will the authors be held liable for any damages
00012 // arising from the use of this software.
00013 // 
00014 // Permission is granted to anyone to use this software for any purpose,
00015 // including commercial applications, and to alter it and redistribute it
00016 // freely, subject to the following restrictions:
00017 // 
00018 // 1. The origin of this software must not be misrepresented; you must not
00019 // claim that you wrote the original software. If you use this software
00020 // in a product, an acknowledgment in the product documentation would be
00021 // appreciated but is not required.
00022 // 
00023 // 2. Altered source versions must be plainly marked as such, and must not be
00024 // misrepresented as being the original software.
00025 // 
00026 // 3. This notice may not be removed or altered from any source
00027 // distribution.
00028 // 
00029 // 
00030 
00031 
00032 //
00033 // Parameter data base
00034 //
00035 
00036 #include <pch.h>
00037 #include "Env/Param/ParamDB.h"
00038 #include "DefaultParam.h"
00039 #include "Env/Param/ParamXMLPathReductionMap.h"
00040 
00041 using namespace std;
00042 using namespace boost;
00043 
00044 // Global instance
00045 namespace Onikiri
00046 {
00047     ParamDB g_paramDB;
00048 }
00049 
00050 
00051 using namespace Onikiri;
00052 
00053 ParamDB::ParamDB()
00054 {
00055     m_initialized = false;
00056     m_userParamPassed = false;
00057 }
00058 
00059 ParamDB::~ParamDB()
00060 {
00061     
00062 }
00063 
00064 bool ParamDB::Initialize( const String& initialPath )
00065 {
00066     if(m_initialized){
00067         THROW_RUNTIME_ERROR( "Initialize() is called more than once." );
00068     }
00069 
00070     m_initialPath = initialPath;
00071     m_tree.LoadString( g_defaultParam, true, "DefaultParam" );
00072     m_initialized = true;
00073     return true;
00074 }
00075 
00076 void ParamDB::Finalize()
00077 {
00078 }
00079 
00080 const vector<ParamXMLTree::InputInfo>&
00081     ParamDB::GetXMLFileNames()
00082 {
00083     return m_tree.GetInputList();
00084 }
00085 
00086 String ParamDB::CompletePath( const String& target, const String& basePath )
00087 {
00088     using namespace filesystem;
00089     return
00090         absolute( 
00091             path( (const string&)target   ), 
00092             path( (const string&)basePath )
00093         ).string();
00094 }
00095 
00096 // Remove the file name part from the path string
00097 String ParamDB::RemoveFileName(const String& path)
00098 {
00099     String ret;
00100     int indexBs = (int)path.rfind( "\\" );
00101     int indexSl = (int)path.rfind( "/" );
00102     int indexPath = indexSl > indexBs ? indexSl : indexBs;
00103     if(indexPath == -1)
00104         ret = "./";
00105     else
00106         ret.assign(path.begin(), path.begin() + indexPath + 1);
00107     return ret;
00108 }
00109 
00110 // Load one XML file.
00111 void ParamDB::LoadXMLFile(const String& fileName)
00112 {
00113     const String& fileFullPathName = 
00114         CompletePath( fileName, m_initialPath );
00115 
00116     // Import temporary tree
00117     ParamXMLTree curTree;
00118     curTree.LoadXMLFile( fileFullPathName, false );
00119 
00120     // The fileBasePath is always full path.
00121     String fileBasePath = RemoveFileName( fileFullPathName );
00122     ParamXMLPath xmlBasePath( "/Session/Import/" );
00123 
00124     vector<ParamXMLPath> importedPathList;
00125 
00126     for(int i = 0; ;i++){
00127         ParamXMLPath path = xmlBasePath;
00128         path.AddArray( "File", i );
00129         path.AddAttribute( "Path" );
00130         
00131         String importFileName;
00132         bool hit = curTree.Get( path, &importFileName );
00133         if( !hit )
00134             break;
00135 
00136         importedPathList.push_back( path );
00137 
00138         const String& importFullPath = 
00139             CompletePath( importFileName, fileBasePath );
00140         LoadXMLFile( importFullPath );
00141     }
00142 
00143     AddExternalParameterToList( "FileName", fileName );
00144 
00145     // Body
00146     // The file path passed to the m_tree must be full path, 
00147     // because the return value of the m_tree.GetSourceXMLFile() 
00148     // is made from this file path.
00149     m_tree.LoadXMLFile( fileFullPathName, false );
00150     m_isLoaded = true;
00151 
00152     // Touch an attribute for an access footprint
00153     // (XMLNode::accessed
00154     for( size_t i = 0; i < importedPathList.size(); i++ ){
00155         String tmpString;
00156         m_tree.Get( importedPathList[i], &tmpString );
00157     }
00158 
00159     m_userParamPassed = true;
00160 }
00161 
00162 // Load parameters specified by the command line arguments
00163 void ParamDB::LoadParameters(const vector<String>& argList)
00164 {
00165     for( vector<String>::const_iterator i = argList.begin() + 1;
00166          i != argList.end(); 
00167          ++i 
00168     ){
00169         const String& arg = *i;
00170 
00171         if( arg.rfind(".xml") == arg.size() - 4 ){
00172             LoadXMLFile( arg );
00173         }
00174         else if( arg.find("-x") == 0 ){
00175             ++i;
00176             if(i == argList.end())
00177                 THROW_RUNTIME_ERROR("'-x' option requires parameter expression.");
00178             AddParameter( *i );
00179         }
00180     }
00181     m_userParamPassed = true;
00182 }
00183 
00184 // Add a parameter (XML file or command line parameter) to the input list.
00185 void ParamDB::AddExternalParameterToList(const String& name, const String& value)
00186 {
00187     ParamXMLTree::NodeArray* inputList = 
00188         m_tree.GetNodeArray( "/Session/InputList/Input", true );
00189 
00190     ParamXMLTree::NodePtr node = m_tree.CreateNewNode( "Input" );
00191     inputList->push_back( node );
00192 
00193     ParamXMLTree::NodePtr attr = m_tree.CreateNewNode( name );
00194     attr->value = value;
00195     attr->accessed = true;
00196     node->attributes[name] = attr;
00197 }
00198 
00199 // Add a command line parameter to the XML tree.
00200 void ParamDB::AddParameter(const String& paramExp)
00201 {
00202     const vector<String>& exp = paramExp.split("=");
00203     if(exp.size() != 2 || exp[0].size() == 0){
00204         THROW_RUNTIME_ERROR( 
00205             "'%s' is invalid expressoion.", 
00206             paramExp.c_str() );
00207     }
00208 
00209     // Expand the XML path
00210     String strPath;
00211     if(exp[0].at(0) == '/')
00212         strPath = exp[0];
00213     else
00214         strPath = String("/Session/") + exp[0];
00215     
00216     for( int i = 0; i < g_pathReductionMapSize; i++ ){
00217         String reductionPath = g_pathReductionMap[i].reductionPath;
00218         size_t pos =  strPath.find( reductionPath );
00219         if( pos == 0 ){
00220             strPath.replace( 
00221                 pos, reductionPath.length() , 
00222                 g_pathReductionMap[i].fullPath
00223             );
00224         }
00225     }
00226 
00227     ParamXMLPath path = strPath;
00228     
00229     String value;
00230     if( !m_tree.Get( path, &value ) ){
00231         THROW_RUNTIME_ERROR(
00232             "Parameter passed by command line argument is not valid.\n"
00233             "'%s' is not found in default parameter.\n",
00234             path.ToString().c_str() 
00235         );
00236     }
00237 
00238     m_tree.LoadValue( path, exp[1] );
00239 
00240     AddExternalParameterToList( "Expression", paramExp );
00241     m_userParamPassed = true;
00242 }
00243 
00244 // Add a user default parameter (XML string) to the tree.
00245 void ParamDB::AddUserDefaultParam(const String& xmlString)
00246 {
00247     if( m_userParamPassed ){
00248         THROW_RUNTIME_ERROR(
00249             "Added the user defined default parameter after loading user parameters."
00250             "All user defined default parameter must be added before loading user parameters."
00251         );
00252     }
00253 
00254     m_tree.LoadString( xmlString, true, "User" );
00255 }
00256 
00257 // Test whether the 'str' match one of the 'filterList'
00258 bool ParamDB::MatchFilterList( const String& str, const std::vector<String>& filterList ) const
00259 {
00260     for( size_t i = 0; i < filterList.size(); i++ ){
00261         if( str.find( filterList[i] ) != String::npos )
00262             return true;
00263     }
00264 
00265     return false;
00266 }
00267 
00268 void ParamDB::CheckResultXML( const String& path, XMLNodePtr node, int* warningCount )
00269 {
00270     static const int MAX_WARNING_NUM = 8;
00271     if( (*warningCount) > MAX_WARNING_NUM ){
00272         return;
00273     }
00274 
00275     for( XMLChildMap::iterator children = node->children.begin();
00276          children != node->children.end();
00277          ++children
00278      ){
00279          
00280          // Get siblings, which are elements with same name.
00281          XMLNodeArray& siblings = children->second;
00282          for( size_t index = 0; index < siblings.size(); index++ ){
00283 
00284             XMLNodePtr sibling = siblings[ index ];
00285 
00286             // Set the attributes
00287             XMLAttributeMap &attr = sibling->attributes;
00288             for( XMLAttributeMap::iterator i = attr.begin();
00289                  i != attr.end();
00290                  ++i
00291              ){
00292                  if( !i->second->accessed && !IsInException() ){
00293                     (*warningCount)++;
00294                     RUNTIME_WARNING(
00295                          "The attribute '%s' have never been accessed. "
00296                          "The attribute name may be wrong.", 
00297                          (path + sibling->name + "/@"+ i->second->name).c_str()
00298                     );
00299 
00300                     if( (*warningCount) > MAX_WARNING_NUM ){
00301                         RUNTIME_WARNING( "Too many warnings. Omit subsequent warnings...");
00302 
00303                         return;
00304                     }
00305                  }
00306             }
00307 
00308             CheckResultXML( path + sibling->name + "/", sibling, warningCount );
00309          }
00310 
00311     }
00312 }
00313 
00314 // Filter result XML tree recursively
00315 // return whether 'node' has valid children or not
00316 bool ParamDB::FilterResultXML( const String& path, XMLNodePtr node, const vector<String>& filterList )
00317 {
00318     if( MatchFilterList( path + node->name, filterList ) ){
00319         return true;
00320     }
00321 
00322     bool validNode = false;
00323     for( XMLChildMap::iterator children = node->children.begin();
00324          children != node->children.end();
00325      ){
00326          
00327          // Get siblings, which are elements with same name.
00328          XMLNodeArray& siblings = children->second;
00329          bool validChild = false;
00330          for( size_t index = 0; index < siblings.size(); index++ ){
00331 
00332             XMLNodePtr sibling = siblings[ index ];
00333             if( MatchFilterList( path + sibling->name, filterList ) ){
00334                 validChild = true;
00335                 continue;
00336             }
00337             
00338             // Set the attributes
00339             XMLAttributeMap &attr = sibling->attributes;
00340             for( XMLAttributeMap::iterator i = attr.begin();
00341                  i != attr.end();
00342              ){
00343                  if( MatchFilterList( path + i->second->name, filterList ) ){
00344                      ++i;
00345                  }
00346                  else{
00347                      i = attr.erase( i );
00348                  }
00349             }
00350 
00351             bool validChildren = FilterResultXML( path + sibling->name + "/", sibling, filterList );
00352             if( validChildren || attr.size() > 0 ){
00353                 validChild = true;
00354             }
00355          }
00356 
00357          if( validChild ){
00358              validNode = true;
00359              ++children;
00360          }
00361          else{
00362             // printf("%s\n", children->second[0]->name.c_str() );
00363              children = node->children.erase( children );
00364          }
00365     }
00366 
00367     return validNode;
00368 }
00369 
00370 // Dump XML
00371 String ParamDB::DumpResultXML( const String& level, const String& filter  )
00372 {
00373     XMLNodePtr session = m_tree.GetNode( "/Session" );
00374 
00375     // Remove configuration nodes other than the current configuration.
00376     String currentConfigName = 
00377         m_tree.GetNode( "/Session/Simulator/@Configuration" )->value;
00378     XMLNodePtr configNode = 
00379         m_tree.GetNode( "/Session/Simulator/Configurations" );
00380     for( XMLChildMap::iterator child = configNode->children.begin();
00381          child != configNode->children.end();
00382     ){
00383         if( child->first == currentConfigName ){
00384             ++child;
00385         }
00386         else{
00387             child = configNode->children.erase( child );
00388         }
00389     }
00390     
00391     // Check untouched nodes.
00392     int warningCount = 0;
00393     CheckResultXML( "/Session/", session, &warningCount );
00394 
00395     // Apply the filter to the result XML.
00396     vector<String> filterList = filter.split( "," );
00397     if( filterList.size() > 0 ){
00398         FilterResultXML( "/Session/", session, filterList );
00399     }
00400 
00401     if( level == "Minimum" ){
00402         XMLNodePtr session = m_tree.GetNode( "/Session" );
00403         session->children.erase( "Simulator" );
00404         session->children.erase( "Emulator" );
00405         session->children.erase( "Environment" );
00406         session->children.erase( "Import" );
00407 
00408         ParamXMLTree::NodePtr result = m_tree.GetNode( "/Session/Result" );
00409         if( result ){
00410             result->children.erase( "Resource" );
00411         }
00412 
00413         return m_tree.ToXMLString();
00414     }
00415     else if( level == "BasicResult" ){
00416         ParamXMLTree::NodePtr session = m_tree.GetNode( "/Session" );
00417         session->children.erase( "Simulator" );
00418         session->children.erase( "Emulator" );
00419         session->children.erase( "Environment" );
00420         session->children.erase( "Import" );
00421 
00422         ParamXMLTree::NodePtr res = m_tree.GetNode( "/Session/Result/Resource" );
00423         if( res ){
00424             res->children.erase( "PipelinedExecUnit" );
00425             res->children.erase( "ExecUnit" );
00426             res->children.erase( "MemExecUnit" );
00427             res->children.erase( "Core" );
00428             res->children.erase( "CheckpointMaster" );
00429             res->children.erase( "ExecLatencyInfo" );
00430             res->children.erase( "Thread" );
00431             res->children.erase( "PHT" );
00432             res->children.erase( "Scheduler" );
00433             res->children.erase( "GlobalHistory" );
00434             res->children.erase( "GlobalClock" );
00435             res->children.erase( "RAS" );
00436         }
00437     
00438         return m_tree.ToXMLString();
00439     }
00440     else if( level == "Result" ){
00441         ParamXMLTree::NodePtr session = m_tree.GetNode( "/Session" );
00442         session->children.erase( "Simulator" );
00443         session->children.erase( "Emulator" );
00444         session->children.erase( "Environment" );
00445         session->children.erase( "Import" );
00446         return m_tree.ToXMLString();
00447     }
00448     else if( level == "Detail"){
00449         return m_tree.ToXMLString();
00450     }
00451     else{
00452         THROW_RUNTIME_ERROR(
00453             "An unknown ouput level '%s' is specified in the"
00454             "'/Session/Environment/OutputXML/@Level'\n"
00455             "This parameter must be one of the following strings : \n"
00456             "[Detail, BasicResult, Result, Minimum]",
00457             level.c_str()
00458         );
00459         return m_tree.ToXMLString();
00460     }
00461 }
00462 
00463 //
00464 bool ParamDB::GetSourceXMLFile( const ParamXMLPath& parameterPath, String& sourceFile )
00465 {
00466     if(m_isLoaded){
00467         return m_tree.GetSourceXMLFile( parameterPath, sourceFile );
00468     }
00469 
00470     return false;
00471 }
00472 
00473 void ParamDB::Set( const ParamXMLPath& path, const String& val )
00474 {
00475     m_tree.Set( path, val );
00476 }
00477 
00478 bool ParamDB::Get(const ParamXMLPath& path, String* value, bool required)
00479 {
00480     ParamXMLTree::NodeStatus status;
00481     bool ret = m_tree.Get( path, value, &status );
00482 
00483     if( !ret && required && status.stRequireDefault ){
00484         THROW_RUNTIME_ERROR(
00485             "error: %s is not found in the default parameters.",
00486             path.ToString().c_str() 
00487         );
00488     }
00489 
00490     return ret;
00491 }
00492 
00493 size_t ParamDB::GetElementCount(const ParamXMLPath& path)
00494 {
00495     ParamXMLTree::NodeArray* nodeArray =
00496         m_tree.GetNodeArray( path );
00497     if( !nodeArray )
00498         return 0;
00499 
00500     return nodeArray->size();
00501 }
00502 
00503 // Get the XML tree
00504 ParamXMLTree& ParamDB::GetXMLTree()
00505 {
00506     return m_tree;
00507 }
00508 
00509 
00510 
00511 //
00512 // --- Special versions
00513 //
00514 
00515 void ParamDB::ToParam( bool* dst, const ParamXMLPath& path, const String& str )
00516 {
00517     ToParamRaw( dst, path, str );
00518 }
00519 
00520 void ParamDB::ToParam( String* dst, const ParamXMLPath& path, const String& str )
00521 {
00522     ToParamRaw( dst, path, str );
00523 }
00524 
00525 void ParamDB::ToParam( std::string* dst, const ParamXMLPath& path, const String& str )
00526 {
00527     ToParamRaw( dst, path, str );
00528 }

Onikiri2に対してTue Jun 18 14:34:20 2013に生成されました。  doxygen 1.4.7