Skip to content

Commit 8c619dd

Browse files
committed
Generalize existing functions for indenting and prefixing
1 parent 09ea29b commit 8c619dd

File tree

12 files changed

+89
-73
lines changed

12 files changed

+89
-73
lines changed

libsolutil/StringUtils.cpp

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@
2323
*/
2424

2525
#include <libsolutil/StringUtils.h>
26+
27+
#include <boost/algorithm/string/trim.hpp>
28+
29+
#include <sstream>
2630
#include <string>
2731
#include <vector>
2832

@@ -190,3 +194,34 @@ std::string solidity::util::formatNumberReadable(bigint const& _value, bool _use
190194
return sign + str;
191195
}
192196

197+
std::string solidity::util::prefixLines(
198+
std::string const& _input,
199+
std::string const& _prefix,
200+
bool _trimPrefix
201+
)
202+
{
203+
std::ostringstream output;
204+
printPrefixed(output, _input, _prefix, _trimPrefix, false /* _ensureFinalNewline */);
205+
return output.str();
206+
}
207+
208+
void solidity::util::printPrefixed(
209+
std::ostream& _output,
210+
std::string const& _input,
211+
std::string const& _prefix,
212+
bool _trimPrefix,
213+
bool _ensureFinalNewline
214+
)
215+
{
216+
std::istringstream input(_input);
217+
std::string line;
218+
while (std::getline(input, line))
219+
{
220+
if (line.empty() && _trimPrefix)
221+
_output << boost::trim_right_copy(_prefix);
222+
else
223+
_output << _prefix << line;
224+
if (!input.eof() || _ensureFinalNewline)
225+
_output << '\n';
226+
}
227+
}

libsolutil/StringUtils.h

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,12 +168,44 @@ inline bool isDigit(char _c)
168168
return isdigit(_c, std::locale::classic());
169169
}
170170

171-
// Checks if character is printable using classic "C" locale
171+
/// Checks if character is printable using classic "C" locale
172172
/// @param _c character to be checked
173173
/// @return true if _c is a printable character, false otherwise.
174174
inline bool isPrint(char _c)
175175
{
176176
return isprint(_c, std::locale::classic());
177177
}
178178

179+
/// Adds a prefix to every line in the input.
180+
/// @see printPrefixed()
181+
std::string prefixLines(
182+
std::string const& _input,
183+
std::string const& _prefix,
184+
bool _trimPrefix = true
185+
);
186+
187+
/// Prints to a stream, adding a prefix to every line in the input.
188+
/// Assumes \n as the line separator.
189+
/// @param _trimPrefix If true, the function avoids introducing trailing whitespace on empty lines.
190+
/// This is achieved by removing trailing spaces from the prefix on such lines.
191+
/// Note that tabs and newlines are not removed, only spaces are.
192+
/// @param _finalNewline If true, an extra \n will be printed at the end of @a _input if it does
193+
/// not already end with one.
194+
void printPrefixed(
195+
std::ostream& _output,
196+
std::string const& _input,
197+
std::string const& _prefix,
198+
bool _trimPrefix = true,
199+
bool _ensureFinalNewline = true
200+
);
201+
202+
/// Adds a standard indent of 4 spaces to every line in the input.
203+
/// Assumes \n as the line separator.
204+
/// @param _indentEmptyLines If true, the indent will be applied to empty lines as well, resulting
205+
/// such lines containing trailing whitespace.
206+
inline std::string indent(std::string const& _input, bool _indentEmptyLines = false)
207+
{
208+
return prefixLines(_input, " ", !_indentEmptyLines);
209+
}
210+
179211
}

libyul/Object.cpp

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,6 @@
3030
#include <libsolutil/StringUtils.h>
3131

3232
#include <boost/algorithm/string.hpp>
33-
#include <boost/algorithm/string/split.hpp>
34-
#include <boost/algorithm/string/replace.hpp>
3533

3634
#include <range/v3/view/transform.hpp>
3735

@@ -40,18 +38,6 @@ using namespace solidity::langutil;
4038
using namespace solidity::util;
4139
using namespace solidity::yul;
4240

43-
namespace
44-
{
45-
46-
std::string indent(std::string const& _input)
47-
{
48-
if (_input.empty())
49-
return _input;
50-
return boost::replace_all_copy(" " + _input, "\n", "\n ");
51-
}
52-
53-
}
54-
5541
std::string Data::toString(Dialect const*, DebugInfoSelection const&, CharStreamProvider const*) const
5642
{
5743
return "data \"" + name.str() + "\" hex\"" + util::toHex(data) + "\"";
@@ -86,7 +72,7 @@ std::string Object::toString(
8672
for (auto const& obj: subObjects)
8773
inner += "\n" + obj->toString(_dialect, _debugInfoSelection, _soliditySourceProvider);
8874

89-
return useSrcComment + "object \"" + name.str() + "\" {\n" + indent(inner) + "\n}";
75+
return useSrcComment + "object \"" + name.str() + "\" {\n" + indent(inner, true /* _indentEmptyLines */) + "\n}";
9076
}
9177

9278
Json::Value Data::toJson() const

test/CommonSyntaxTest.cpp

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include <test/Common.h>
2121
#include <test/TestCase.h>
2222
#include <libsolutil/CommonIO.h>
23+
#include <libsolutil/StringUtils.h>
2324
#include <boost/algorithm/string.hpp>
2425
#include <boost/algorithm/string/predicate.hpp>
2526
#include <boost/test/unit_test.hpp>
@@ -144,11 +145,8 @@ void CommonSyntaxTest::printSource(ostream& _stream, string const& _linePrefix,
144145
else
145146
{
146147
if (outputSourceNames)
147-
_stream << _linePrefix << "==== Source: " + name << " ====" << endl;
148-
stringstream stream(source);
149-
string line;
150-
while (getline(stream, line))
151-
_stream << _linePrefix << line << endl;
148+
printPrefixed(_stream, "==== Source: " + name + " ====", _linePrefix);
149+
printPrefixed(_stream, source, _linePrefix);
152150
}
153151
}
154152

test/TestCase.cpp

Lines changed: 6 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@
2020
#include <test/TestCase.h>
2121

2222
#include <libsolutil/AnsiColorized.h>
23+
#include <libsolutil/StringUtils.h>
2324

24-
#include <boost/algorithm/string.hpp>
2525
#include <boost/algorithm/string/predicate.hpp>
2626

2727
#include <iostream>
@@ -31,6 +31,7 @@ using namespace std;
3131
using namespace solidity;
3232
using namespace solidity::frontend;
3333
using namespace solidity::frontend::test;
34+
using namespace solidity::util;
3435

3536
void TestCase::printSettings(ostream& _stream, const string& _linePrefix, const bool)
3637
{
@@ -69,26 +70,14 @@ void TestCase::expect(string::iterator& _it, string::iterator _end, string::valu
6970
++_it;
7071
}
7172

72-
void TestCase::printIndented(ostream& _stream, string const& _output, string const& _linePrefix) const
73-
{
74-
stringstream output(_output);
75-
string line;
76-
while (getline(output, line))
77-
if (line.empty())
78-
// Avoid trailing spaces.
79-
_stream << boost::trim_right_copy(_linePrefix) << endl;
80-
else
81-
_stream << _linePrefix << line << endl;
82-
}
83-
8473
void TestCase::printSource(ostream& _stream, string const& _linePrefix, bool const) const
8574
{
86-
printIndented(_stream, m_source, _linePrefix);
75+
printPrefixed(_stream, m_source, _linePrefix);
8776
}
8877

8978
void TestCase::printUpdatedExpectations(ostream& _stream, string const& _linePrefix) const
9079
{
91-
printIndented(_stream, m_obtainedResult, _linePrefix);
80+
printPrefixed(_stream, m_obtainedResult, _linePrefix);
9281
}
9382

9483
TestCase::TestResult TestCase::checkResult(std::ostream& _stream, const std::string& _linePrefix, bool const _formatted)
@@ -99,10 +88,10 @@ TestCase::TestResult TestCase::checkResult(std::ostream& _stream, const std::str
9988
util::AnsiColorized(_stream, _formatted, {util::formatting::BOLD, util::formatting::CYAN})
10089
<< _linePrefix << "Expected result:" << endl;
10190
// TODO could compute a simple diff with highlighted lines
102-
printIndented(_stream, m_expectation, nextIndentLevel);
91+
printPrefixed(_stream, m_expectation, nextIndentLevel);
10392
util::AnsiColorized(_stream, _formatted, {util::formatting::BOLD, util::formatting::CYAN})
10493
<< _linePrefix << "Obtained result:" << endl;
105-
printIndented(_stream, m_obtainedResult, nextIndentLevel);
94+
printPrefixed(_stream, m_obtainedResult, nextIndentLevel);
10695
return TestResult::Failure;
10796
}
10897
return TestResult::Success;

test/TestCase.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,6 @@ class TestCase
100100
++_it;
101101
}
102102

103-
void printIndented(std::ostream& _stream, std::string const& _output, std::string const& _linePrefix = "") const;
104103
TestCase::TestResult checkResult(std::ostream& _stream, const std::string& _linePrefix, bool const _formatted);
105104

106105
std::string m_source;

test/libsolidity/ASTJSONTest.cpp

Lines changed: 4 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -270,25 +270,15 @@ bool ASTJSONTest::runTest(
270270
"Expected result" <<
271271
(!_variant.name().empty() ? " (" + _variant.name() + "):" : ":") <<
272272
std::endl;
273-
{
274-
std::istringstream stream(_variant.expectation);
275-
std::string line;
276-
while (getline(stream, line))
277-
_stream << nextIndentLevel << line << std::endl;
278-
}
273+
printPrefixed(_stream, _variant.expectation, nextIndentLevel);
279274
_stream << std::endl;
280275

281276
AnsiColorized(_stream, _formatted, {BOLD, CYAN}) <<
282277
_linePrefix <<
283278
"Obtained result" <<
284279
(!_variant.name().empty() ? " (" + _variant.name() + "):" : ":") <<
285280
std::endl;
286-
{
287-
std::istringstream stream(_variant.result);
288-
std::string line;
289-
while (getline(stream, line))
290-
_stream << nextIndentLevel << line << std::endl;
291-
}
281+
printPrefixed(_stream, _variant.result, nextIndentLevel);
292282
_stream << std::endl;
293283
return false;
294284
}
@@ -301,11 +291,8 @@ void ASTJSONTest::printSource(std::ostream& _stream, std::string const& _linePre
301291
for (auto const& source: m_sources)
302292
{
303293
if (m_sources.size() > 1 || source.first != "a")
304-
_stream << _linePrefix << sourceDelimiter << source.first << " ====" << std::endl << std::endl;
305-
std::stringstream stream(source.second);
306-
std::string line;
307-
while (getline(stream, line))
308-
_stream << _linePrefix << line << std::endl;
294+
printPrefixed(_stream, sourceDelimiter + source.first + " ====\n", _linePrefix);
295+
printPrefixed(_stream, source.second, _linePrefix);
309296
_stream << std::endl;
310297
}
311298
}

test/libsolidity/GasTest.cpp

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -158,11 +158,3 @@ TestCase::TestResult GasTest::run(std::ostream& _stream, std::string const& _lin
158158
return TestResult::Failure;
159159
}
160160
}
161-
162-
void GasTest::printSource(std::ostream& _stream, std::string const& _linePrefix, bool) const
163-
{
164-
std::string line;
165-
std::istringstream input(m_source);
166-
while (getline(input, line))
167-
_stream << _linePrefix << line << std::endl;
168-
}

test/libsolidity/GasTest.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@ class GasTest: AnalysisFramework, public TestCase
4141

4242
TestResult run(std::ostream& _stream, std::string const& _linePrefix = "", bool _formatted = false) override;
4343

44-
void printSource(std::ostream &_stream, std::string const &_linePrefix = "", bool _formatted = false) const override;
4544
void printUpdatedExpectations(std::ostream& _stream, std::string const& _linePrefix) const override;
4645

4746
protected:

test/libsolidity/NatspecJSONTest.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,8 +100,9 @@ void NatspecJSONTest::printExpectedResult(std::ostream& _stream, std::string con
100100
if (!m_expectedNatspecJSON.empty())
101101
{
102102
_stream << _linePrefix << "----" << std::endl;
103-
printIndented(_stream, formatNatspecExpectations(m_expectedNatspecJSON), _linePrefix);
103+
printPrefixed(_stream, formatNatspecExpectations(m_expectedNatspecJSON), _linePrefix);
104104
}
105+
105106
}
106107

107108
void NatspecJSONTest::printObtainedResult(std::ostream& _stream, std::string const& _linePrefix, bool _formatted) const
@@ -114,7 +115,7 @@ void NatspecJSONTest::printObtainedResult(std::ostream& _stream, std::string con
114115
_stream << _linePrefix << "----" << std::endl;
115116
// TODO: Diff both versions and highlight differences.
116117
// We should have a helper for doing that in newly defined test cases without much effort.
117-
printIndented(_stream, formatNatspecExpectations(natspecJSON), _linePrefix);
118+
printPrefixed(_stream, formatNatspecExpectations(natspecJSON), _linePrefix);
118119
}
119120
}
120121

0 commit comments

Comments
 (0)