Geant4 Cross Reference |
1 // 2 // ******************************************************************** 3 // * License and Disclaimer * 4 // * * 5 // * The Geant4 software is copyright of the Copyright Holders of * 6 // * the Geant4 Collaboration. It is provided under the terms and * 7 // * conditions of the Geant4 Software License, included in the file * 8 // * LICENSE and available at http://cern.ch/geant4/license . These * 9 // * include a list of copyright holders. * 10 // * * 11 // * Neither the authors of this software system, nor their employing * 12 // * institutes,nor the agencies providing financial support for this * 13 // * work make any representation or warranty, express or implied, * 14 // * regarding this software system or assume any liability for its * 15 // * use. Please see the license in the file LICENSE and URL above * 16 // * for the full disclaimer and the limitation of liability. * 17 // * * 18 // * This code implementation is the result of the scientific and * 19 // * technical work of the GEANT4 collaboration. * 20 // * By using, copying, modifying or distributing the software (or * 21 // * any work based on the software) you agree to acknowledge its * 22 // * use in resulting scientific publications, and indicate your * 23 // * acceptance of all terms of the Geant4 Software license. * 24 // ******************************************************************** 25 // 26 // G4coutFormatters implementation 27 // 28 // Author: A.Dotti (SLAC), April 2017 29 // -------------------------------------------------------------------- 30 31 #include "G4coutFormatters.hh" 32 33 namespace G4coutFormatters 34 { 35 // Internal functions and utilites used to setup default formatters 36 namespace 37 { 38 // Split a single string in an array of strings 39 // 40 String_V split(const G4String& input, char separator = '\n') 41 { 42 String_V output; 43 G4String::size_type prev_pos = 0, pos = 0; 44 while((pos = input.find(separator, pos)) != G4String::npos) 45 { 46 // TBR: shouldn't be worse than push_back+move 47 output.emplace_back(input.substr(prev_pos, pos - prev_pos)); 48 prev_pos = ++pos; 49 } 50 return output; 51 } 52 53 // Return a syslog style message with input message, type identifies 54 // the type of the message 55 // 56 G4bool transform(G4String& input, const G4String& type) 57 { 58 std::time_t result = std::time(nullptr); 59 std::ostringstream newm; 60 #if __GNUC__ >= 5 61 newm << std::put_time(std::localtime(&result), "%d/%b/%Y:%H:%M:%S %z"); 62 #else 63 std::tm* time_ = std::localtime(&result); 64 newm << time_->tm_mday << "/" << time_->tm_mon << "/" << time_->tm_year; 65 newm << ":" << time_->tm_hour << ":" << time_->tm_min << ":" 66 << time_->tm_sec; 67 #endif 68 newm << " " << type << " ["; 69 G4String delimiter = ""; 70 for(const auto& el : split(input)) 71 { 72 if(!el.empty()) 73 { 74 newm << delimiter << el; 75 delimiter = "\\n"; 76 } 77 } 78 newm << " ]" << G4endl; 79 input = newm.str(); 80 return true; 81 } 82 83 // Style used in master thread 84 // 85 G4String masterStyle = ""; 86 87 // Modify output to look like syslog messages: 88 // DATE TIME **LOG|ERROR** [ "multi","line","message"] 89 // 90 SetupStyle_f SysLogStyle = [](G4coutDestination* dest) -> G4int { 91 if(dest != nullptr) 92 { 93 dest->AddCoutTransformer( 94 std::bind(&transform, std::placeholders::_1, "INFO")); 95 dest->AddCerrTransformer( 96 std::bind(&transform, std::placeholders::_1, "ERROR")); 97 } 98 return 0; 99 }; 100 101 // Bring back destination to original state 102 // 103 SetupStyle_f DefaultStyle = [](G4coutDestination* dest) -> G4int { 104 if(dest != nullptr) 105 { 106 dest->ResetTransformers(); 107 } 108 return 0; 109 }; 110 111 std::unordered_map<std::string, SetupStyle_f> transformers = { 112 { ID::SYSLOG, SysLogStyle }, 113 { ID::DEFAULT, DefaultStyle } 114 }; 115 } // namespace 116 117 void SetMasterStyle(const G4String& news) { masterStyle = news; } 118 119 G4String GetMasterStyle() { return masterStyle; } 120 121 void SetupStyleGlobally(const G4String& news) 122 { 123 static G4coutDestination ss; 124 G4iosSetDestination(&ss); 125 G4coutFormatters::HandleStyle(&ss, news); 126 G4coutFormatters::SetMasterStyle(news); 127 } 128 129 String_V Names() 130 { 131 String_V result; 132 for(const auto& el : transformers) 133 { 134 result.push_back(el.first); 135 } 136 return result; 137 } 138 139 G4int HandleStyle(G4coutDestination* dest, const G4String& style) 140 { 141 const auto& handler = transformers.find(style); 142 return (handler != transformers.cend()) ? (handler->second)(dest) : -1; 143 } 144 145 void RegisterNewStyle(const G4String& name, SetupStyle_f& fmt) 146 { 147 if(transformers.find(name) != transformers.cend()) 148 { 149 G4ExceptionDescription msg; 150 msg << "Format Style with name " << name 151 << " already exists. Replacing existing."; 152 G4Exception("G4coutFormatters::RegisterNewStyle()", "FORMATTER001", 153 JustWarning, msg); 154 } 155 // transformers.insert(std::make_pair(name,fmt)); 156 transformers[name] = fmt; 157 } 158 } // namespace G4coutFormatters 159