26 unsigned _splitSimple( std::string_view line_r,
const WordConsumer& fnc_r )
32 const char *
const eol = line_r.data() + line_r.size();
33 const char * searchfrom = line_r.data();
36 auto isSep = [](
char ch )->
bool {
return ch ==
' '|| ch ==
'\t'; };
38 auto skipSep = [eol,&isSep](
const char *& ptr )->
bool {
39 while ( ptr < eol && isSep( *ptr ) )
44 auto skipWord = [eol,&isSep](
const char *& ptr )->
void {
45 while ( ptr < eol && ! isSep( *ptr ) )
51 std::string_view word;
53 while ( skipSep( searchfrom ) ) {
54 const char * wordstart = searchfrom;
56 if ( ! word.empty() ) {
58 if ( ! fnc_r( word, fncCall,
false ) ) {
61 const char * wordend = eol;
62 while ( isSep( *(wordend-1) ) )
64 word = std::string_view( wordstart, wordend-wordstart );
73 skipWord( searchfrom );
74 word = std::string_view( wordstart, searchfrom-wordstart );
78 if ( ! word.empty() ) {
80 fnc_r( word, fncCall,
true );
89 unsigned detail::_split( std::string_view line_r, std::string_view sep_r, Trim trim_r, WordConsumer && fnc_r )
92 return _splitSimple( line_r, std::move( fnc_r ) );
98 using size_type = std::string_view::size_type;
99 size_type wordstart = 0;
100 size_type searchfrom = 0;
103 searchfrom = line_r.find( sep_r, searchfrom );
104 if ( fncStop || searchfrom == line_r.npos ) {
110 if ( ! fnc_r( trim( line_r.substr(wordstart,searchfrom-wordstart), trim_r ), fncCall,
false ) )
116 searchfrom += sep_r.size();
117 wordstart = searchfrom;
118 }
while( wordstart < line_r.size() );
122 if ( wordstart < line_r.size() )
123 fnc_r(
trim( line_r.substr(wordstart,line_r.size()-wordstart), trim_r ), fncCall,
true );
125 fnc_r( std::string_view( line_r.data()+line_r.size(), 0 ), fncCall,
true );
131 unsigned detail::_splitRx( std::string_view line_r,
const regex & rx_r,
const WordConsumer& fnc_r )
134 bool fncStop =
false;
135 unsigned fncCall = 0;
138 const char *
const eol = line_r.data() + line_r.size();
139 bool trailingNL = line_r.size() && *(eol-1) ==
'\n';
140 const char * wordstart = line_r.data();
141 const char * searchfrom = line_r.data();
144 auto matchAtBOL = [&]() {
145 return searchfrom == line_r.data() || *(searchfrom-1) ==
'\n' ? regex::none : regex::not_bol;
149 if ( fncStop || ! rx_r.matches( searchfrom, match, matchAtBOL() ) ) {
152 if ( trailingNL && searchfrom+match.begin(0) == eol )
155 if ( match.end(0) == 0 && searchfrom == wordstart && searchfrom != line_r.data() ) {
164 if ( ! fnc_r( std::string_view( wordstart, searchfrom+match.begin(0) - wordstart ), fncCall,
false ) )
170 wordstart = searchfrom+match.end(0);
171 searchfrom += match.end(0) ? match.end(0) : 1;
173 }
while ( searchfrom <= eol );
177 if ( wordstart < eol )
178 fnc_r( std::string_view( wordstart, eol-wordstart ), fncCall,
true );
180 fnc_r( std::string_view( eol, 0 ), fncCall,
true );
187 std::string
doBSEscape( std::string_view word_r, std::string_view special_r )
191 for (
char c : word_r ) {
192 if ( c ==
'\\' || special_r.find(c) != std::string_view::npos ) {
197 if (extra == 0)
return std::string(word_r);
201 result.reserve( word_r.size() + extra );
203 for (
char c : word_r ) {
204 if ( c ==
'\\' || special_r.find(c) != std::string_view::npos ) {
205 result.push_back(
'\\' );
207 result.push_back( c );
216 result.reserve( word_r.size() );
218 for (
size_t i = 0; i < word_r.size(); ++i ) {
219 if ( word_r[i] ==
'\\' ) {
221 if ( ++i < word_r.size() ) {
222 result.push_back( word_r[i] );
225 result.push_back( word_r[i] );
228 result.shrink_to_fit();
232 std::vector<std::string>
unBSEscape(
const std::vector<std::string_view> & words_r )
234 std::vector<std::string> result;
235 result.reserve( words_r.size() );
237 for (
const auto& word : words_r ) {
243 std::vector<std::string_view>
splitBSEscaped( std::string_view line_r, std::string_view chars_r,
unsigned maxSplits_r )
245 std::vector<std::string_view> fragments;
246 unsigned splitsDone = 0;
249 for (
size_t i = 0; i < line_r.size(); ++i ) {
251 if ( maxSplits_r > 0 && splitsDone >= maxSplits_r ) {
255 if ( line_r[i] ==
'\\' ) {
256 if ( ++i < line_r.size() ) {
262 if ( chars_r.find( line_r[i] ) != std::string_view::npos ) {
264 fragments.emplace_back( line_r.substr( start, i - start ) );
270 fragments.emplace_back( line_r.substr( start ) );