Add string utility functions for suffix handling.
authorTeemu Murtola <teemu.murtola@gmail.com>
Thu, 14 Jun 2012 04:27:13 +0000 (07:27 +0300)
committerTeemu Murtola <teemu.murtola@gmail.com>
Wed, 20 Jun 2012 17:52:53 +0000 (20:52 +0300)
Added endsWith() and stripSuffixIfPresent() functions to stringutil.h.
Allows for much clearer and easier-to-write string manipulation code
where this kind of functionality is needed.

Change-Id: I853234ce3d8a11b88ee50225a66e061302e10de7

src/gromacs/utility/programinfo.cpp
src/gromacs/utility/stringutil.cpp
src/gromacs/utility/stringutil.h
src/gromacs/utility/tests/stringutil.cpp

index 94abd7ee76fe95b0a3dbc3891be3bfa71953b27a..b646b05ee828a642d0c639c7ac18fbeeb2556cb2 100644 (file)
@@ -53,6 +53,7 @@
 #include "gromacs/legacyheaders/statutil.h"
 
 #include "gromacs/utility/path.h"
+#include "gromacs/utility/stringutil.h"
 
 namespace gmx
 {
@@ -90,21 +91,10 @@ ProgramInfo::Impl::Impl(const char *realBinaryName,
       programName_(Path::splitToPathAndFilename(fullInvokedProgram_).second),
       invariantProgramName_(programName_)
 {
-    if (invariantProgramName_.length() >= 4
-        && invariantProgramName_.compare(invariantProgramName_.length() - 4, 4,
-                                         ".exe") == 0)
-    {
-        invariantProgramName_.erase(invariantProgramName_.length() - 4);
-    }
+    invariantProgramName_ = stripSuffixIfPresent(invariantProgramName_, ".exe");
 #ifdef GMX_BINARY_SUFFIX
-    size_t suffixLength = std::strlen(GMX_BINARY_SUFFIX);
-    if (suffixLength > 0 && invariantProgramName_.length() >= suffixLength
-        && invariantProgramName_.compare(
-                invariantProgramName_.length() - suffixLength, suffixLength,
-                GMX_BINARY_SUFFIX) == 0)
-    {
-        invariantProgramName_.erase(invariantProgramName_.length() - suffixLength);
-    }
+    invariantProgramName_ =
+        stripSuffixIfPresent(invariantProgramName_, GMX_BINARY_SUFFIX);
 #endif
     if (realBinaryName == NULL)
     {
index f1bc0445a2e244d3fc1c9f01b423632c6086c2be..a0cf5c13ab56743bf226de63d5a6bdc19e24e8c3 100644 (file)
 namespace gmx
 {
 
+bool endsWith(const std::string &str, const char *suffix)
+{
+    if (suffix == NULL || suffix[0] == '\0')
+    {
+        return true;
+    }
+    size_t length = std::strlen(suffix);
+    return (str.length() >= length
+            && str.compare(str.length() - length, length, suffix) == 0);
+}
+
+std::string stripSuffixIfPresent(const std::string &str, const char *suffix)
+{
+    if (suffix != NULL)
+    {
+        size_t suffixLength = std::strlen(suffix);
+        if (suffixLength > 0 && endsWith(str, suffix))
+        {
+            return str.substr(0, str.length() - suffixLength);
+        }
+    }
+    return str;
+}
+
 std::string formatString(const char *fmt, ...)
 {
     va_list ap;
index 4980f25da48ae8d9cf95a744969e9995ac906a5d..22feb60485914838a370d3d6066a4d4ceb359862 100644 (file)
 namespace gmx
 {
 
+/*! \brief
+ * Tests whether a string ends with another string.
+ *
+ * \param[in] str    String to process.
+ * \param[in] suffix Suffix to find.
+ * \returns   true if \p str ends with suffix.
+ *
+ * Returns true if \p suffix is NULL or empty.
+ * Does not throw.
+ *
+ * \inpublicapi
+ */
+bool endsWith(const std::string &str, const char *suffix);
+
+/*! \brief
+ * Removes a suffix from a string.
+ *
+ * \param[in] str    String to process.
+ * \param[in] suffix Suffix to remove.
+ * \returns   \p str with \p suffix removed, or \p str unmodified if it does
+ *      not end with \p suffix.
+ * \throws    std::bad_alloc if out of memory.
+ *
+ * Returns \p str if \p suffix is NULL or empty.
+ *
+ * \inpublicapi
+ */
+std::string stripSuffixIfPresent(const std::string &str, const char *suffix);
+
 /*! \brief
  * Format a string (snprintf() wrapper).
  *
index 6bd52998c4115203866a1d05c0f522f5b4801c0b..433306268f06e5b28732ec162911c6eb79841f43 100644 (file)
 namespace
 {
 
+/********************************************************************
+ * Tests for simple string utilities
+ */
+
+TEST(StringUtilityTest, EndsWithWorks)
+{
+    EXPECT_TRUE(gmx::endsWith("foobar", "bar"));
+    EXPECT_TRUE(gmx::endsWith("foobar", NULL));
+    EXPECT_TRUE(gmx::endsWith("foobar", ""));
+    EXPECT_FALSE(gmx::endsWith("foobar", "bbar"));
+    EXPECT_FALSE(gmx::endsWith("foobar", "barr"));
+    EXPECT_FALSE(gmx::endsWith("foobar", "foofoobar"));
+}
+
+TEST(StringUtilityTest, StripSuffixIfPresent)
+{
+    EXPECT_EQ("foo", gmx::stripSuffixIfPresent("foobar", "bar"));
+    EXPECT_EQ("foobar", gmx::stripSuffixIfPresent("foobar", NULL));
+    EXPECT_EQ("foobar", gmx::stripSuffixIfPresent("foobar", ""));
+    EXPECT_EQ("foobar", gmx::stripSuffixIfPresent("foobar", "bbar"));
+    EXPECT_EQ("foobar", gmx::stripSuffixIfPresent("foobar", "barr"));
+    EXPECT_EQ("foobar", gmx::stripSuffixIfPresent("foobar", "foofoobar"));
+}
+
 /********************************************************************
  * Tests for formatString()
  */