aboutsummaryrefslogtreecommitdiff
path: root/src/utilstrencodings.cpp
diff options
context:
space:
mode:
authorLuke Dashjr <luke-jr+git@utopios.org>2016-02-03 05:16:49 +0000
committerLuke Dashjr <luke-jr+git@utopios.org>2016-02-03 05:38:43 +0000
commitcc2095ecae3f4ff57d3981b5992e032e564ba65d (patch)
tree2e56a00c71225539366255f67cd64b3945cfeec3 /src/utilstrencodings.cpp
parentcddffaf5e60f638b2acf4d33a4eb43c984825bba (diff)
downloadbitcoin-cc2095ecae3f4ff57d3981b5992e032e564ba65d.tar.xz
Rewrite FormatParagraph to handle newlines within input strings correctly
Diffstat (limited to 'src/utilstrencodings.cpp')
-rw-r--r--src/utilstrencodings.cpp56
1 files changed, 31 insertions, 25 deletions
diff --git a/src/utilstrencodings.cpp b/src/utilstrencodings.cpp
index c5a2b5cdbb..a098c3e0a6 100644
--- a/src/utilstrencodings.cpp
+++ b/src/utilstrencodings.cpp
@@ -478,34 +478,40 @@ bool ParseDouble(const std::string& str, double *out)
std::string FormatParagraph(const std::string& in, size_t width, size_t indent)
{
std::stringstream out;
- size_t col = 0;
size_t ptr = 0;
- while(ptr < in.size())
+ size_t indented = 0;
+ while (ptr < in.size())
{
- // Find beginning of next word
- ptr = in.find_first_not_of(' ', ptr);
- if (ptr == std::string::npos)
- break;
- // Find end of next word
- size_t endword = in.find_first_of(' ', ptr);
- if (endword == std::string::npos)
- endword = in.size();
- // Add newline and indentation if this wraps over the allowed width
- if (col > 0)
- {
- if ((col + endword - ptr) > width)
- {
- out << '\n';
- for(size_t i=0; i<indent; ++i)
- out << ' ';
- col = 0;
- } else
- out << ' ';
+ size_t lineend = in.find_first_of('\n', ptr);
+ if (lineend == std::string::npos) {
+ lineend = in.size();
+ }
+ const size_t linelen = lineend - ptr;
+ const size_t rem_width = width - indented;
+ if (linelen <= rem_width) {
+ out << in.substr(ptr, linelen + 1);
+ ptr = lineend + 1;
+ indented = 0;
+ } else {
+ size_t finalspace = in.find_last_of(" \n", ptr + rem_width);
+ if (finalspace == std::string::npos || finalspace < ptr) {
+ // No place to break; just include the entire word and move on
+ finalspace = in.find_first_of("\n ", ptr);
+ if (finalspace == std::string::npos) {
+ // End of the string, just add it and break
+ out << in.substr(ptr);
+ break;
+ }
+ }
+ out << in.substr(ptr, finalspace - ptr) << "\n";
+ if (in[finalspace] == '\n') {
+ indented = 0;
+ } else if (indent) {
+ out << std::string(indent, ' ');
+ indented = indent;
+ }
+ ptr = finalspace + 1;
}
- // Append word
- out << in.substr(ptr, endword - ptr);
- col += endword - ptr + 1;
- ptr = endword;
}
return out.str();
}