Hi,

I wrote a patch that adds functionality to string SUBSTRING command:

string(SUBSTRING <string> <begin> <length> <output variable> [TRUNCATE])

When TRUNCATE is set this is valid:

cmake_minimum_required (VERSION 3.0)
project(string_test)
set(test_str "abcd")
string(SUBSTRING ${test_str} 2 6 substr TRUNCATE)
message(${test_str})
message(${substr})

If length is set to a higher value than the length of the original
string the substring is still created but its end is the end of
original string.

If this functionality would be welcome I'll write the tests and documentation.

TRUNCATE could also be renamed to SHORTEN or something more
appropriate since we aren't truncating the string but are just
lowering the length parameter. Suggestions are welcome.

Thanks,
Domen
From 48f3fdf0ae306db7f51db4ababa2ddc8332da052 Mon Sep 17 00:00:00 2001
From: Domen Vrankar <[email protected]>
Date: Wed, 12 Nov 2014 00:07:24 +0100
Subject: [PATCH] String substring truncate

Extends string SUBSTRING command with TRUNCATE mode
which allows substrings to be shorter than the provided
length if length points past original string end.
---
 Source/cmStringCommand.cxx | 29 ++++++++++++++++++++++++++---
 1 file changed, 26 insertions(+), 3 deletions(-)

diff --git a/Source/cmStringCommand.cxx b/Source/cmStringCommand.cxx
index 90a8f85..b949e51 100644
--- a/Source/cmStringCommand.cxx
+++ b/Source/cmStringCommand.cxx
@@ -690,9 +690,23 @@ bool cmStringCommand::HandleReplaceCommand(std::vector<std::string> const&
 bool cmStringCommand::HandleSubstringCommand(std::vector<std::string> const&
                                              args)
 {
-  if(args.size() != 5)
+  if(args.size() != 5 && args.size() != 6)
     {
-    this->SetError("sub-command SUBSTRING requires four arguments.");
+    this->SetError("sub-command SUBSTRING requires at least four arguments.");
+    return false;
+    }
+
+  // check if the reverse flag was set or not
+  bool truncateMode = false;
+  if(args.size() == 6 && args[5] == "TRUNCATE")
+    {
+    truncateMode = true;
+    }
+
+  // if we have 6 arguments the last one must be TRUNCATE
+  if(args.size() == 6 && args[5] != "TRUNCATE")
+    {
+    this->SetError("sub-command FIND: unknown last parameter");
     return false;
     }
 
@@ -701,6 +715,15 @@ bool cmStringCommand::HandleSubstringCommand(std::vector<std::string> const&
   int end = atoi(args[3].c_str());
   const std::string& variableName = args[4];
 
+  // ensure that the user cannot accidentally specify TRUNCATE as a variable
+  if(variableName == "TRUNCATE")
+    {
+    this->SetError("sub-command SUBSTRING does not allow to select TRUNCATE "
+                   "as the output variable.  "
+                   "Maybe you missed the actual output variable?");
+    return false;
+    }
+
   size_t stringLength = stringValue.size();
   int intStringLength = static_cast<int>(stringLength);
   if ( begin < 0 || begin > intStringLength )
@@ -712,7 +735,7 @@ bool cmStringCommand::HandleSubstringCommand(std::vector<std::string> const&
     return false;
     }
   int leftOverLength = intStringLength - begin;
-  if ( end < -1 || end > leftOverLength )
+  if ( end < -1 || ( end > leftOverLength && !truncateMode ) )
     {
     cmOStringStream ostr;
     ostr << "end index: " << end << " is out of range -1 - "
-- 
2.1.0

-- 

Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: 
http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more 
information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at 
http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
http://public.kitware.com/mailman/listinfo/cmake-developers

Reply via email to