From 72ea9ac39bc434b156fe0b413695c1e0f01a7efc Mon Sep 17 00:00:00 2001
From: Ruud Overeem <overeem@astron.nl>
Date: Sat, 16 Dec 2006 00:54:57 +0000
Subject: [PATCH] BugID: 679 Added 'compactedArrayString' function that
 recognizes ascending ranges in array and replaces them with xx..yy.

---
 .../include/APL/APLCommon/APLUtilities.h      |  2 +
 MAC/APL/APLCommon/src/APLUtilities.cc         | 92 +++++++++++++++++--
 MAC/APL/APLCommon/test/Makefile.am            |  7 +-
 3 files changed, 92 insertions(+), 9 deletions(-)

diff --git a/MAC/APL/APLCommon/include/APL/APLCommon/APLUtilities.h b/MAC/APL/APLCommon/include/APL/APLCommon/APLUtilities.h
index a28138e6223..697f58e6284 100644
--- a/MAC/APL/APLCommon/include/APL/APLCommon/APLUtilities.h
+++ b/MAC/APL/APLCommon/include/APL/APLCommon/APLUtilities.h
@@ -81,6 +81,8 @@ public:
 								   const string& localFile);
     static string	getTempFileName(const string&	format="");
 
+	static string 	compactedArrayString(const string&	orgStr);
+
 protected:
     // protected copy constructor
     APLUtilities(const APLUtilities&);
diff --git a/MAC/APL/APLCommon/src/APLUtilities.cc b/MAC/APL/APLCommon/src/APLUtilities.cc
index b5741fa6ca6..b8debeb4960 100644
--- a/MAC/APL/APLCommon/src/APLUtilities.cc
+++ b/MAC/APL/APLCommon/src/APLUtilities.cc
@@ -61,18 +61,14 @@ void APLUtilities::string2Vector(const string& parametersString, vector<string>&
   unsigned int parametersStringLen=parametersString.length();
   unsigned int delim(0);
   unsigned int nextDelim;
-  do
-  {
+  do {
     nextDelim=parametersString.find(delimiter,delim);
-    if(nextDelim==string::npos)
-    {
+    if(nextDelim==string::npos) {
       nextDelim=parametersStringLen; // no delim found
     }
-    if(nextDelim>delim)
-    {
+    if(nextDelim>delim) {
       string param(parametersString.substr(delim,nextDelim-delim));
-      if(param.length()>0)
-      {
+      if(param.length()>0) {
         parameters.push_back(param);
       }
       delim=nextDelim+1;
@@ -306,3 +302,83 @@ string APLUtilities::getTempFileName(const string&	format)
 	return string(tempFileName);
 }
 
+//
+// compactedArrayString(string)
+//
+// Given een array string ( '[ xx, xx, xx ]' ) this utility compacts the string
+// by replacing series with range.
+// Eg. [ lii001, lii002, lii003, lii005 ] --> [ lii001..lii003, lii005 ]
+//
+string APLUtilities::compactedArrayString(const string&	orgStr)
+{
+	string	baseString(orgStr);			// destroyable copy
+	ltrim(baseString, " 	[");		// strip of brackets
+	rtrim(baseString, " 	]");
+
+	// and split into a vector
+	vector<string>	strVector = StringUtil::split(baseString, ',');
+	if (strVector.size() < 2) {
+		return (orgStr);
+	}
+
+	// note: we assume that the format of each element is [xxxx]9999
+	string::size_type	firstDigit(strVector[0].find_first_of("0123456789"));
+	if (firstDigit == string::npos) {	// no digits? then return org string
+		return (orgStr);
+	}
+	string	elemName(strVector[0].substr(0,firstDigit));
+	string	scanMask(elemName+"%ld");
+	string	outMask (formatString("%s%%0%dld", elemName.c_str(), 
+											strVector[0].length() - elemName.length()));
+
+	string 	result("[");
+	long 	prevValue(-2);
+	bool	firstElem(true);
+	bool	endOfArray(false);
+	int		elemsInRange(0);
+	int		nrElems(strVector.size());
+	for (int idx = 0; idx < nrElems; idx++) {
+		long	value;
+		if (sscanf(strVector[idx].c_str(), scanMask.c_str(), &value) != 1) {
+			LOG_DEBUG_STR("Element " << strVector[idx] << "does not match mask " 
+						<< scanMask << ". Returning orignal string");
+			return (orgStr);
+		}
+
+		if (value == prevValue+1) {		// contiquous numbering?
+			elemsInRange++;
+			prevValue = value;
+			if (idx < nrElems-1) {		// when elements left
+				continue;
+			}
+			endOfArray = true;
+		}
+
+		// broken range
+		if (firstElem) {
+			result += formatString(outMask.c_str(), value);
+			firstElem = false;
+		}
+		else {
+			if (elemsInRange == 1) {
+				result += "," + formatString(outMask.c_str(), value);
+			}
+			else {
+				if (elemsInRange == 2) {
+					result += "," + formatString(outMask.c_str(), prevValue);
+				}
+				else {
+					result += ".." + formatString(outMask.c_str(), prevValue);
+				}
+				if (!endOfArray) {
+					result += "," + formatString(outMask.c_str(), value);
+				}
+			}
+		}
+		elemsInRange = 1;
+		prevValue    = value;
+	}
+
+	return (result+"]");
+}
+
diff --git a/MAC/APL/APLCommon/test/Makefile.am b/MAC/APL/APLCommon/test/Makefile.am
index 8392472486d..687141176e8 100755
--- a/MAC/APL/APLCommon/test/Makefile.am
+++ b/MAC/APL/APLCommon/test/Makefile.am
@@ -1,9 +1,13 @@
-check_PROGRAMS				= tControllerDefines tOutOfBand
+check_PROGRAMS				= tControllerDefines tAPLUtilities tOutOfBand
 
 tControllerDefines_SOURCES	= tControllerDefines.cc
 tControllerDefines_LDADD	= ../src/libaplcommon.la
 tControllerDefines_DEPENCIES= ../src/libaplcommon.la $(LOFAR_DEPEND)
 
+tAPLUtilities_SOURCES		= tAPLUtilities.cc
+tAPLUtilities_LDADD			= ../src/libaplcommon.la
+tAPLUtilities_DEPENCIES		= ../src/libaplcommon.la $(LOFAR_DEPEND)
+
 tOutOfBand_SOURCES			= tOutOfBand.cc
 tOutOfBand_LDADD			= ../src/libaplcommon.la
 tOutOfBand_DEPENCIES		= ../src/libaplcommon.la $(LOFAR_DEPEND)
@@ -14,6 +18,7 @@ TESTSCRIPTS					= tControllerDefines_test.sh
 TESTS						= $(TESTSCRIPTS)
 
 EXTRA_DIST					= tControllerDefines.log_prop \
+							  tAPLUtilities.log_prop \
 							  tOutOfBand.log_prop \
 							  ResourceAllocatorTest.log_prop \
 							  $(TESTSCRIPTS)
-- 
GitLab