Moved format_string from variant.cpp to string.cpp (it is declared in string.hpp), added handling of recursion errors

This commit is contained in:
Peter Conrad 2018-03-09 18:49:21 +01:00
parent d24bee8bf4
commit 527daab6b7
4 changed files with 83 additions and 67 deletions

View file

@ -162,7 +162,14 @@ namespace fc
for( auto itr = my->_elog.begin(); itr != my->_elog.end(); )
{
ss << itr->get_message() <<"\n"; //fc::format_string( itr->get_format(), itr->get_data() ) <<"\n";
ss << " " << json::to_string( itr->get_data() )<<"\n";
try
{
ss << " " << json::to_string( itr->get_data() )<<"\n";
}
catch( const fc::assert_exception& e )
{
ss << "ERROR: Failed to convert log data to string!\n";
}
ss << " " << itr->get_context().to_string();
++itr;
if( itr != my->_elog.end() ) ss<<"\n";
@ -256,10 +263,16 @@ namespace fc
("source_lineno", lineno)
("expr", expr)
;
std::cout
<< "FC_ASSERT triggered: "
<< fc::json::to_string( assert_trip_info ) << "\n";
return;
try
{
std::cout
<< "FC_ASSERT triggered: "
<< fc::json::to_string( assert_trip_info ) << "\n";
}
catch( const fc::assert_exception& e )
{ // this should never happen. assert_trip_info is flat.
std::cout << "ERROR: Failed to convert info to string?!\n";
}
}
bool enable_record_assert_trip = false;

View file

@ -128,8 +128,15 @@ namespace fc
if (!context.get_task_name().empty())
gelf_message["_task_name"] = context.get_task_name();
string gelf_message_as_string = json::to_string(gelf_message);
//unsigned uncompressed_size = gelf_message_as_string.size();
string gelf_message_as_string;
try
{
gelf_message_as_string = json::to_string(gelf_message);
}
catch( const fc::assert_exception& e )
{
gelf_message_as_string = "{\"level\":3,\"short_message\":\"ERROR while generating log message\"}";
}
gelf_message_as_string = zlib_compress(gelf_message_as_string);
// graylog2 expects the zlib header to be 0x78 0x9c

View file

@ -2,6 +2,8 @@
#include <fc/utility.hpp>
#include <fc/fwd_impl.hpp>
#include <fc/exception/exception.hpp>
#include <fc/io/json.hpp>
#include <fc/io/sstream.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/algorithm/string.hpp>
@ -256,6 +258,60 @@ namespace fc {
}
}
string format_string( const string& format, const variant_object& args )
{
stringstream ss;
size_t prev = 0;
auto next = format.find( '$' );
while( prev < format.size() )
{
ss << format.substr( prev, next == string::npos ? string::npos : next - prev );
// if we got to the end, return it.
if( next == size_t(string::npos) || next == format.size() )
return ss.str();
// if we are not at the end, then update the start
prev = next + 1;
if( format[prev] == '{' )
{
// if the next char is a open, then find close
next = format.find( '}', prev );
// if we found close...
if( next != string::npos )
{
// the key is between prev and next
string key = format.substr( prev+1, (next-prev-1) );
auto val = args.find( key );
if( val != args.end() )
{
if( val->value().is_object() || val->value().is_array() )
{
try
{
ss << json::to_string( val->value() );
}
catch( const fc::assert_exception& e )
{
ss << "[\"ERROR_WHILE_CONVERTING_VALUE_TO_STRING\"]";
}
}
else
ss << val->value().as_string();
}
else
ss << "${"<<key<<"}";
prev = next + 1;
}
}
else
ss << format[next];
next = format.find( '$', prev );
}
return ss.str();
}
} // namespace fc

View file

@ -669,66 +669,6 @@ void from_variant( const variant& var, std::vector<char>& vo )
// vo = std::vector<char>( b64.c_str(), b64.c_str() + b64.size() );
}
string format_string( const string& format, const variant_object& args )
{
stringstream ss;
size_t prev = 0;
auto next = format.find( '$' );
while( prev != size_t(string::npos) && prev < size_t(format.size()) )
{
ss << format.substr( prev, size_t(next-prev) );
// if we got to the end, return it.
if( next == size_t(string::npos) )
return ss.str();
// if we are not at the end, then update the start
prev = next + 1;
if( format[prev] == '{' )
{
// if the next char is a open, then find close
next = format.find( '}', prev );
// if we found close...
if( next != size_t(string::npos) )
{
// the key is between prev and next
string key = format.substr( prev+1, (next-prev-1) );
auto val = args.find( key );
if( val != args.end() )
{
if( val->value().is_object() || val->value().is_array() )
{
ss << json::to_string( val->value() );
}
else
{
ss << val->value().as_string();
}
}
else
{
ss << "${"<<key<<"}";
}
prev = next + 1;
// find the next $
next = format.find( '$', prev );
}
else
{
// we didn't find it.. continue to while...
}
}
else
{
ss << format[prev];
++prev;
next = format.find( '$', prev );
}
}
return ss.str();
}
#ifdef __APPLE__
#elif !defined(_MSC_VER)
void to_variant( long long int s, variant& v ) { v = variant( int64_t(s) ); }