Commit 17d9969a authored by Mark Olesen's avatar Mark Olesen
Browse files

ENH: stringOps::findTrim helper

- finds beg/end indices of string trimmed of leading/trailing whitespace
parent b61d4ab4
......@@ -2,8 +2,10 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2019 OpenCFD Ltd.
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2019 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
......@@ -93,6 +95,30 @@ void testNumericEvaluation(const std::string& s)
}
// Test findTrim - uses '<' and '>' as pseudo-placeholders
void testFindTrim(const std::string& s)
{
auto pos = s.find('<');
auto len = s.find('>');
// Conform with expected value for substr
if (pos == std::string::npos) pos = 0; else ++pos;
if (len != std::string::npos) len = (len - pos);
const auto pts = stringOps::findTrim(s, pos, len);
Info<< "input" << nl
<< "========" << nl
<< s << nl
<< "pos=" << pos << " len=" << int(len) << nl
<< s.substr(pos, len) << nl
<< "trim=" << pts.first << " to " << pts.second << nl
<< s.substr(pts.first, pts.second-pts.first) << nl
<< "========" << nl;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Main program:
......@@ -150,6 +176,28 @@ int main(int argc, char *argv[])
}
// Test findTrim - uses '<' and '>' as pseudo-placeholders
{
Info<< nl << "Test findTrim" << nl;
for
(
const auto& cstr
:
{
"", // Empty
" \n\t ", // whitespace only
" Leading and trailing ",
" Alt end and trai>ling ",
" Alt start< space ",
}
)
{
testFindTrim(cstr);
}
}
Info<< "\nEnd\n" << endl;
return 0;
}
......
......@@ -947,15 +947,17 @@ Foam::string Foam::stringOps::trimLeft(const std::string& s)
{
if (!s.empty())
{
std::string::size_type beg = 0;
while (beg < s.size() && std::isspace(s[beg]))
std::string::size_type pos = 0;
const auto end = s.length();
while (pos < end && std::isspace(s[pos]))
{
++beg;
++pos;
}
if (beg)
if (pos)
{
return s.substr(beg);
return s.substr(pos);
}
}
......@@ -967,15 +969,17 @@ void Foam::stringOps::inplaceTrimLeft(std::string& s)
{
if (!s.empty())
{
std::string::size_type beg = 0;
while (beg < s.size() && std::isspace(s[beg]))
std::string::size_type pos = 0;
const auto end = s.length();
while (pos < end && std::isspace(s[pos]))
{
++beg;
++pos;
}
if (beg)
if (pos)
{
s.erase(0, beg);
s.erase(0, pos);
}
}
}
......@@ -985,15 +989,15 @@ Foam::string Foam::stringOps::trimRight(const std::string& s)
{
if (!s.empty())
{
auto n = s.size();
while (n && std::isspace(s[n-1]))
auto end = s.length();
while (end && std::isspace(s[end-1]))
{
--n;
--end;
}
if (n < s.size())
if (end < s.length())
{
return s.substr(0, n);
return s.substr(0, end);
}
}
......@@ -1005,35 +1009,74 @@ void Foam::stringOps::inplaceTrimRight(std::string& s)
{
if (!s.empty())
{
auto n = s.size();
while (n && std::isspace(s[n-1]))
auto end = s.length();
while (end && std::isspace(s[end-1]))
{
--end;
}
s.erase(end);
}
}
std::pair<std::size_t, std::size_t>
Foam::stringOps::findTrim
(
const std::string& s,
std::size_t pos,
std::size_t len
)
{
size_t end = s.length();
if (pos >= end)
{
pos = end;
}
else if (len != std::string::npos)
{
len += pos;
if (len < end)
{
--n;
end = len;
}
}
s.resize(n);
// Right = last
while (pos < end && std::isspace(s[end-1]))
{
--end;
}
// Left = first
while (pos < end && std::isspace(s[pos]))
{
++pos;
}
return std::pair<std::size_t, std::size_t>(pos, end);
}
Foam::string Foam::stringOps::trim(const std::string& str)
{
std::string::size_type beg = 0;
std::string::size_type end = str.size();
std::string::size_type pos = 0;
std::string::size_type end = str.length();
// Right
while (beg < end && std::isspace(str[end-1]))
while (pos < end && std::isspace(str[end-1]))
{
--end;
}
// Left
while (beg < end && std::isspace(str[beg]))
while (pos < end && std::isspace(str[pos]))
{
++beg;
++pos;
}
return str.substr(beg, end-beg);
return str.substr(pos, end-pos);
}
......
......@@ -36,6 +36,7 @@ SourceFiles
stringOpsTemplates.C
\*---------------------------------------------------------------------------*/
#ifndef stringOps_H
#define stringOps_H
......@@ -48,6 +49,7 @@ SourceFiles
#include "stringOpsSort.H"
#include "stringOpsEvaluate.H"
#include "wordRes.H"
#include <utility>
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
......@@ -257,6 +259,16 @@ namespace stringOps
bool inplaceReplaceVar(std::string& s, const word& varName);
//- Find (first, last) non-space locations in string or sub-string.
// This may change to std::string_view in the future.
std::pair<size_t, size_t>
findTrim
(
const std::string& s,
size_t pos = 0,
size_t len = std::string::npos
);
//- Return string trimmed of leading whitespace
string trimLeft(const std::string& s);
......
......@@ -42,42 +42,16 @@ Foam::string Foam::stringOps::evaluate
{
/// InfoErr<< "Evaluate " << str.substr(pos, len) << nl;
size_t end = str.length();
if (pos > end)
{
pos = end;
}
else if (len != std::string::npos)
{
len += pos;
if (len < end)
{
end = len;
}
}
// Adjust like inplaceTrim
const auto trimPoints = stringOps::findTrim(str, pos, len);
// Right
while (pos < end && std::isspace(str[end-1]))
{
--end;
}
// Left
while (pos < end && std::isspace(str[pos]))
{
++pos;
}
pos = trimPoints.first;
len = (trimPoints.second - trimPoints.first);
if ((pos >= end) || std::isspace(str[pos]))
if (!len)
{
return "";
}
len = (end - pos);
/// InfoErr<< "Evaluate " << str.substr(pos, len) << nl;
expressions::exprResult result;
......
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