mirror of
https://github.com/ToruNiina/toml11.git
synced 2025-09-18 02:08:09 +08:00
refactor: avoid string construct in format_ul
This commit is contained in:
@@ -107,17 +107,20 @@ inline std::string format_underline(const std::string& message,
|
|||||||
const std::vector<std::string>& helps = {},
|
const std::vector<std::string>& helps = {},
|
||||||
const bool colorize = TOML11_ERROR_MESSAGE_COLORIZED)
|
const bool colorize = TOML11_ERROR_MESSAGE_COLORIZED)
|
||||||
{
|
{
|
||||||
assert(!loc_com.empty());
|
std::size_t line_num_width = 0;
|
||||||
|
for(const auto& lc : loc_com)
|
||||||
const auto line_num_width = static_cast<int>(std::to_string(std::max_element(
|
{
|
||||||
loc_com.begin(), loc_com.end(),
|
std::uint_least32_t line = lc.first.line();
|
||||||
[](std::pair<source_location, std::string> const& lhs,
|
std::size_t digit = 0;
|
||||||
std::pair<source_location, std::string> const& rhs)
|
while(line != 0)
|
||||||
{
|
{
|
||||||
return std::to_string(lhs.first.line()).size() <
|
line /= 10;
|
||||||
std::to_string(rhs.first.line()).size();
|
digit += 1;
|
||||||
}
|
}
|
||||||
)->first.line()).size());
|
line_num_width = (std::max)(line_num_width, digit);
|
||||||
|
}
|
||||||
|
// 1 is the minimum width
|
||||||
|
line_num_width = std::max<std::size_t>(line_num_width, 1);
|
||||||
|
|
||||||
std::ostringstream retval;
|
std::ostringstream retval;
|
||||||
|
|
||||||
@@ -142,58 +145,78 @@ inline std::string format_underline(const std::string& message,
|
|||||||
<< color::bold << message << color::reset << '\n';
|
<< color::bold << message << color::reset << '\n';
|
||||||
}
|
}
|
||||||
|
|
||||||
for(auto iter = loc_com.begin(); iter != loc_com.end(); ++iter)
|
const auto format_one_location = [line_num_width]
|
||||||
|
(std::ostringstream& oss,
|
||||||
|
const source_location& loc, const std::string& comment) -> void
|
||||||
|
{
|
||||||
|
oss << ' ' << color::bold << color::blue
|
||||||
|
<< std::setw(static_cast<int>(line_num_width))
|
||||||
|
<< std::right << loc.line() << " | " << color::reset
|
||||||
|
<< loc.line_str() << '\n';
|
||||||
|
|
||||||
|
oss << make_string(line_num_width + 1, ' ')
|
||||||
|
<< color::bold << color::blue << " | " << color::reset
|
||||||
|
<< make_string(loc.column()-1 /*1-origin*/, ' ');
|
||||||
|
|
||||||
|
if(loc.region() == 1)
|
||||||
|
{
|
||||||
|
// invalid
|
||||||
|
// ^------
|
||||||
|
oss << color::bold << color::red << "^---" << color::reset;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// invalid
|
||||||
|
// ~~~~~~~
|
||||||
|
const auto underline_len = (std::min)(
|
||||||
|
static_cast<std::size_t>(loc.region()), loc.line_str().size());
|
||||||
|
oss << color::bold << color::red
|
||||||
|
<< make_string(underline_len, '~') << color::reset;
|
||||||
|
}
|
||||||
|
oss << ' ';
|
||||||
|
oss << comment;
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
assert(!loc_com.empty());
|
||||||
|
|
||||||
|
// --> example.toml
|
||||||
|
// |
|
||||||
|
retval << color::bold << color::blue << " --> " << color::reset
|
||||||
|
<< loc_com.front().first.file_name() << '\n';
|
||||||
|
retval << make_string(line_num_width + 1, ' ')
|
||||||
|
<< color::bold << color::blue << " | " << color::reset << '\n';
|
||||||
|
// 1 | key value
|
||||||
|
// | ^--- missing =
|
||||||
|
format_one_location(retval, loc_com.front().first, loc_com.front().second);
|
||||||
|
|
||||||
|
// process the rest of the locations
|
||||||
|
for(std::size_t i=1; i<loc_com.size(); ++i)
|
||||||
{
|
{
|
||||||
|
const auto& prev = loc_com.at(i-1);
|
||||||
|
const auto& curr = loc_com.at(i);
|
||||||
|
|
||||||
|
retval << '\n';
|
||||||
// if the filenames are the same, print "..."
|
// if the filenames are the same, print "..."
|
||||||
if(iter != loc_com.begin() &&
|
if(prev.first.file_name() == curr.first.file_name())
|
||||||
std::prev(iter)->first.file_name() == iter->first.file_name())
|
|
||||||
{
|
{
|
||||||
retval << color::bold << color::blue << "\n ...\n" << color::reset;
|
retval << color::bold << color::blue << " ...\n" << color::reset;
|
||||||
}
|
}
|
||||||
else // if filename differs, print " --> filename.toml"
|
else // if filename differs, print " --> filename.toml" again
|
||||||
{
|
{
|
||||||
if(iter != loc_com.begin()) {retval << '\n';}
|
|
||||||
|
|
||||||
retval << color::bold << color::blue << " --> " << color::reset
|
retval << color::bold << color::blue << " --> " << color::reset
|
||||||
<< iter->first.file_name() << '\n';
|
<< curr.first.file_name() << '\n';
|
||||||
// add one almost-empty line for readability
|
retval << make_string(line_num_width + 1, ' ')
|
||||||
retval << make_string(static_cast<std::size_t>(line_num_width + 1), ' ')
|
<< color::bold << color::blue << " |\n" << color::reset;
|
||||||
<< color::bold << color::blue << " | " << color::reset << '\n';
|
|
||||||
}
|
}
|
||||||
const source_location& loc = iter->first;
|
|
||||||
const std::string& comment = iter->second;
|
|
||||||
|
|
||||||
retval << ' ' << color::bold << color::blue << std::setw(line_num_width)
|
format_one_location(retval, curr.first, curr.second);
|
||||||
<< std::right << loc.line() << " | " << color::reset
|
|
||||||
<< loc.line_str() << '\n';
|
|
||||||
|
|
||||||
retval << make_string(static_cast<std::size_t>(line_num_width + 1), ' ')
|
|
||||||
<< color::bold << color::blue << " | " << color::reset
|
|
||||||
<< make_string(loc.column()-1 /*1-origin*/, ' ');
|
|
||||||
|
|
||||||
if(loc.region() == 1)
|
|
||||||
{
|
|
||||||
// invalid
|
|
||||||
// ^------
|
|
||||||
retval << color::bold << color::red << "^---" << color::reset;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// invalid
|
|
||||||
// ~~~~~~~
|
|
||||||
const auto underline_len = (std::min)(
|
|
||||||
static_cast<std::size_t>(loc.region()), loc.line_str().size());
|
|
||||||
retval << color::bold << color::red
|
|
||||||
<< make_string(underline_len, '~') << color::reset;
|
|
||||||
}
|
|
||||||
retval << ' ';
|
|
||||||
retval << comment;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!helps.empty())
|
if(!helps.empty())
|
||||||
{
|
{
|
||||||
retval << '\n';
|
retval << '\n';
|
||||||
retval << make_string(static_cast<std::size_t>(line_num_width + 1), ' ');
|
retval << make_string(line_num_width + 1, ' ');
|
||||||
retval << color::bold << color::blue << " | " << color::reset;
|
retval << color::bold << color::blue << " | " << color::reset;
|
||||||
for(const auto& help : helps)
|
for(const auto& help : helps)
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user