Commit c72f7f68 authored by Michael Lee's avatar Michael Lee Committed by facebook-github-bot-1

Switch stripLeftMargin to not use boost::regex

Summary: Remove boost regex from `stripLeftMargin`. We can shrink some binaries by not including it in the core folly library.

Reviewed By: yfeldblum

Differential Revision: D2922415

fb-gh-sync-id: cee89164c650706f0e5c07eed3d40500831918cd
shipit-source-id: cee89164c650706f0e5c07eed3d40500831918cd
parent 4dc763b4
......@@ -16,7 +16,6 @@
#include <folly/String.h>
#include <boost/regex.hpp>
#include <folly/Format.h>
#include <folly/ScopeGuard.h>
......@@ -550,22 +549,47 @@ size_t hexDumpLine(const void* ptr, size_t offset, size_t size,
} // namespace detail
std::string stripLeftMargin(std::string s) {
using namespace boost;
static const auto kPre = regex(R"(\A[ \t]*\n)");
static const auto kPost = regex(R"([ \t]+\z)");
static const auto kScan = regex(R"(^[ \t]*(?=\S))");
s = regex_replace(s, kPre, "");
s = regex_replace(s, kPost, "");
std::vector<StringPiece> pieces;
split("\n", s, pieces);
auto piecer = range(pieces);
auto piece = (piecer.end() - 1);
auto needle = std::find_if(piece->begin(),
piece->end(),
[](char c) { return c != ' ' && c != '\t'; });
if (needle == piece->end()) {
(piecer.end() - 1)->clear();
}
piece = piecer.begin();
needle = std::find_if(piece->begin(),
piece->end(),
[](char c) { return c != ' ' && c != '\t'; });
if (needle == piece->end()) {
piecer.erase(piecer.begin(), piecer.begin() + 1);
}
const auto sentinel = std::numeric_limits<size_t>::max();
auto indent = sentinel;
sregex_iterator it(s.cbegin(), s.cend(), kScan);
sregex_iterator itend;
for (; it != itend; ++it) {
indent = std::min<size_t>(indent, it->length());
size_t max_length = 0;
for (auto piece = piecer.begin(); piece != piecer.end(); piece++) {
needle = std::find_if(piece->begin(),
piece->end(),
[](char c) { return c != ' ' && c != '\t'; });
if (needle != piece->end()) {
indent = std::min<size_t>(indent, needle - piece->begin());
} else {
max_length = std::max<size_t>(piece->size(), max_length);
}
}
indent = indent == sentinel ? max_length : indent;
for (auto& piece : piecer) {
if (piece.size() < indent) {
piece.clear();
} else {
piece.erase(piece.begin(), piece.begin() + indent);
}
}
indent = indent == sentinel ? 0 : indent;
s = regex_replace(s, regex(sformat(R"(^[ \t]{{0,{0}}})", indent)), "");
return s;
return join("\n", piecer);
}
} // namespace folly
......
......@@ -1135,6 +1135,12 @@ TEST(String, whitespace) {
EXPECT_EQ("", rtrimWhitespace("\r "));
}
TEST(String, stripLeftMargin_really_empty) {
auto input = "";
auto expected = "";
EXPECT_EQ(expected, stripLeftMargin(input));
}
TEST(String, stripLeftMargin_empty) {
auto input = R"TEXT(
)TEXT";
......@@ -1142,6 +1148,30 @@ TEST(String, stripLeftMargin_empty) {
EXPECT_EQ(expected, stripLeftMargin(input));
}
TEST(String, stripLeftMargin_only_whitespace) {
// using ~ as a marker
string input = R"TEXT(
~
)TEXT";
input = boost::regex_replace(input, boost::regex("~"), "");
EXPECT_EQ("\n \n ", input);
auto expected = "\n";
EXPECT_EQ(expected, stripLeftMargin(input));
}
TEST(String, stripLeftMargin_only_uneven_whitespace) {
// using ~ as a marker1
string input = R"TEXT(
~
~
)TEXT";
input = boost::regex_replace(input, boost::regex("~"), "");
EXPECT_EQ("\n \n \n ", input);
auto expected = "\n\n";
EXPECT_EQ(expected, stripLeftMargin(input));
}
TEST(String, stripLeftMargin_one_line) {
auto input = R"TEXT(
hi there bob!
......@@ -1241,6 +1271,30 @@ TEST(String, stripLeftMargin_interstitial_indented_whiteline) {
EXPECT_EQ(expected, stripLeftMargin(input));
}
TEST(String, stripLeftMargin_no_pre_whitespace) {
// using ~ as a marker
string input = R"TEXT( hi there bob!
~
so long!
)TEXT";
input = boost::regex_replace(input, boost::regex("~"), "");
EXPECT_EQ(" hi there bob!\n \n so long!\n ", input);
auto expected = "hi there bob!\n \nso long!\n";
EXPECT_EQ(expected, stripLeftMargin(input));
}
TEST(String, stripLeftMargin_no_post_whitespace) {
// using ~ as a marker
string input = R"TEXT(
hi there bob!
~
so long! )TEXT";
input = boost::regex_replace(input, boost::regex("~"), "");
EXPECT_EQ("\n hi there bob!\n \n so long! ", input);
auto expected = "hi there bob!\n \nso long! ";
EXPECT_EQ(expected, stripLeftMargin(input));
}
const folly::StringPiece kTestUTF8 = "This is \U0001F602 stuff!";
TEST(UTF8StringPiece, valid_utf8) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment