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 @@ ...@@ -16,7 +16,6 @@
#include <folly/String.h> #include <folly/String.h>
#include <boost/regex.hpp>
#include <folly/Format.h> #include <folly/Format.h>
#include <folly/ScopeGuard.h> #include <folly/ScopeGuard.h>
...@@ -550,22 +549,47 @@ size_t hexDumpLine(const void* ptr, size_t offset, size_t size, ...@@ -550,22 +549,47 @@ size_t hexDumpLine(const void* ptr, size_t offset, size_t size,
} // namespace detail } // namespace detail
std::string stripLeftMargin(std::string s) { std::string stripLeftMargin(std::string s) {
using namespace boost; std::vector<StringPiece> pieces;
static const auto kPre = regex(R"(\A[ \t]*\n)"); split("\n", s, pieces);
static const auto kPost = regex(R"([ \t]+\z)"); auto piecer = range(pieces);
static const auto kScan = regex(R"(^[ \t]*(?=\S))");
s = regex_replace(s, kPre, ""); auto piece = (piecer.end() - 1);
s = regex_replace(s, kPost, ""); 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(); const auto sentinel = std::numeric_limits<size_t>::max();
auto indent = sentinel; auto indent = sentinel;
sregex_iterator it(s.cbegin(), s.cend(), kScan); size_t max_length = 0;
sregex_iterator itend; for (auto piece = piecer.begin(); piece != piecer.end(); piece++) {
for (; it != itend; ++it) { needle = std::find_if(piece->begin(),
indent = std::min<size_t>(indent, it->length()); 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; return join("\n", piecer);
s = regex_replace(s, regex(sformat(R"(^[ \t]{{0,{0}}})", indent)), "");
return s;
} }
} // namespace folly } // namespace folly
......
...@@ -1135,6 +1135,12 @@ TEST(String, whitespace) { ...@@ -1135,6 +1135,12 @@ TEST(String, whitespace) {
EXPECT_EQ("", rtrimWhitespace("\r ")); EXPECT_EQ("", rtrimWhitespace("\r "));
} }
TEST(String, stripLeftMargin_really_empty) {
auto input = "";
auto expected = "";
EXPECT_EQ(expected, stripLeftMargin(input));
}
TEST(String, stripLeftMargin_empty) { TEST(String, stripLeftMargin_empty) {
auto input = R"TEXT( auto input = R"TEXT(
)TEXT"; )TEXT";
...@@ -1142,6 +1148,30 @@ TEST(String, stripLeftMargin_empty) { ...@@ -1142,6 +1148,30 @@ TEST(String, stripLeftMargin_empty) {
EXPECT_EQ(expected, stripLeftMargin(input)); 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) { TEST(String, stripLeftMargin_one_line) {
auto input = R"TEXT( auto input = R"TEXT(
hi there bob! hi there bob!
...@@ -1241,6 +1271,30 @@ TEST(String, stripLeftMargin_interstitial_indented_whiteline) { ...@@ -1241,6 +1271,30 @@ TEST(String, stripLeftMargin_interstitial_indented_whiteline) {
EXPECT_EQ(expected, stripLeftMargin(input)); 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!"; const folly::StringPiece kTestUTF8 = "This is \U0001F602 stuff!";
TEST(UTF8StringPiece, valid_utf8) { 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