################################################################################ # TSL-LIBRARY: EMOS_STD_string_Lib ################################################################################ # Copyright (C) 2000 EMOS Computer Consulting GmbH # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public # License as published by the Free Software Foundation; either # version 2.1 of the License, or (at your option) any later version. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public # License along with this library; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # For further information please contact: # # Dean Rajovic # EMOS Computer Consulting GmbH # Oskar-Messter-Straße 25 # 85737 Ismaning # Germany # tel.: +49 89 608 765-0 # mailto:drajovic@emos.de # http://www.emos.de ################################################################################ # $Revision: 1.2 $ # $Author: drajovic $ # $Date: 2005/01/28 11:18:43 $ # $Archive: /MERCURY/TSL_PROJECTS/EMOS_GPL/STD/emos_std_string_lib/script $ # $NoKeywords: $ ################################################################################ #**# #* This library contains some useful string manipulation routines. #*/ #** #* This functions concatenates all elements of the array <arr> into a string. #* Elements are separated by <code>sep</code>. #*<p> NOTE! #* Iy the <code>arr</code> is not sequentially inexed (starting from 0), then either the #* <code>count</code> should NOT be defined (in operator will be used) or <code>start</code> must #* be defined (sequential from then on). #* @param arr[] (inout) array to be "streamed" #* @param sep (in) (optional) separator, [default: comma] #* @param count (in) (optional) number of elements in the array [default: 0] #* @param start (in) (optional) starting index [default: 0] #* @return #* streamed array #*/ public function arr2str ( inout arr[], in sep, in count, in start ) { auto i, end, str = ""; if ( sep == "" ) sep = ","; if ( count == "" ) { count = 0; for ( i in arr ) count++; for ( i in arr ) str = str & arr[i] & ((--count) ? sep : ""); } else { end = start*1+count; for( i = start*1; i<end; i++ ) str = str & arr[i] & ((--count) ? sep : ""); } return str; } #** #* Replaces all <code>delchr</code> characters with <code>insstr</code> string. #*<p> NOTE1! #* This function internally uses split() to process the string. Unfortunatelly, #* split() has an undocumented "feature" that it trims blanks from the given #* string before splitting. This has the effect that replace() does the same. #* If you don't want the string to be trimmed, use replace1(). #*<p> NOTE2! #* The replace() replaces each occurence of individual characters within #* <code>delchr</code> with the complete string <code>insstr</code>. It does NOT replace string #* <code>delchr</code> with the string <code>insstr</code>. #* @param str (in) string to be processed #* @param delchr (in) character(s) to be replaced #* @param insstr (in) string to be used as replacement #* @return #* converted string #*/ public function replace ( in str, in delchr, in insstr ) { auto count, i, arr[], outstr; count = split( str, arr, delchr ); if ( count == 0 ) return str; outstr = arr[1]; for( i=2; i <= count; i++ ) outstr = outstr & insstr & arr[i]; return outstr; } static function test_replace() { auto i, test[], j=0; test[j++] = ""; test[j++] = "x"; test[j++] = "xxx"; test[j++] = "xa"; test[j++] = "ax"; test[j++] = "axa"; test[j++] = "xxaxx"; test[j++] = "axxa"; test[j++] = "aaa"; print(""); for ( i=0; i<j-1; i++ ) print ( test[i] & "-->" & replace( test[i],"x","|" ) ); print(""); for ( i=0; i<j-1; i++ ) print ( test[i] & "-->" & replace( test[i],"x","" ) ); print(""); for ( i=0; i<j-1; i++ ) print ( test[i] & "-->" & replace( test[i],"xx","||" ) ); } static const DEFZAP = " "; #** #* Removes all occuences of <code>zap</code> from the end of <code>str</code> (right trim). #* @param str (in) string to be processed #* @param zap (in) (optional) string to be removed [default: " "] #* @return #* converted string #*/ public function strip_trail ( in str, in zap ) { auto slen, zlen; if ( zap == "" ) zap = DEFZAP; slen = length( str ); zlen = length( zap ); if ( slen && substr( str, (slen-zlen+1) ) == zap ) str = strip_trail( substr( str, 1, slen-zlen ) ); return str; } #** #* Removes all occuences of <code>zap</code> from the front of <code>str</code> (left trim). #* @param str (in) string to be processed #* @param zap (in) (optional) string to be removed [default: " "] #* @return #* converted string #*/ public function strip_front ( in str, in zap ) { auto slen, zlen; if ( zap == "" ) zap = DEFZAP; slen = length( str ); zlen = length( zap ); if ( slen && substr( str, 1, zlen ) == zap ) str = strip_front( substr( str, 1+zlen ) ); return str; } #** #* Removes all occuences of <code>zap</code> from both sides of <code>str</code> (trim). #* @param str (in) string to be processed #* @param zap (in) (optional) string to be removed [default: " "] #* @return #* converted string #*/ public function strip_both ( in str, in zap ) { return strip_front( strip_trail ( str, zap ), zap ); } #** #* Splits a <code>path</code> string into a <code>directory</code> and <code>file</code> parts. The path #* separator can be defined with <code>sep</code> (default: backslash) #*<p> NOTE! #* The function does not analyse whether the <code>file</code> part is indeed a file name. #* Anything following the last <sep</code> is treated as <code>file</code>. Anything before is #* treated as <code>dir</code>. # NOTE2! # <code>dir</code> does not end with <code>sep</code>. #* @param path (in) string to be processed #* @param dir (out) directory-part (up until the last <code>sep</code>) #* @param file (out) name-part (anything after the last <code>sep</code>) #* @param sep (in) (optional) separator (default: backslash) #* @return #* E_OK: success #* !E_OK: error (do not ust the out variables!) #*/ public function split_path( in path, out dir, out file, in sep ) { auto count, i; auto arr[]; if ( sep == "" ) { # assuming backslash is more frequent path = replace( path, "/", "\\" ); sep = "\\"; } count = split( path, arr, sep ); switch ( count ) { case 0: return E_BAD_PATH; case 1: dir = ""; file = arr[1]; return E_OK; default: dir = arr[1]; for ( i=2; i<count; i++ ) dir = dir & sep & arr[i]; file = arr[count]; return E_OK; } } #** #* Diese Funktion fügt zwei Pfadteile zusammen. Dabei werden <code>sep</code> konvertiert #* "/-->\ bzw. \-->/). Standardmeßig werden \ durch / ersetzt. #* Eventuell nicht oder merfach vorhandene Separatoren in der Join-Stelle #* werden auf ein <sep> gesetzt. #*<p> EXAMPLE: #*<pre> #* join_path( "C:\aaa", "bbb.xxx" ) ==> "C:/aaa/bbb.xxx" #* join_path( "C:\aaa\", "\bbb.xxx" ) ==> "C:/aaa/bbb.xxx" #* join_path( "", "bbb.xxx" ) ==> "/bbb.xxx" #* join_path( "C:/aaa" ) ==> "C:/aaa/" #*</pre> #* @param part1 (in) erster Teil der Pfadangabe #* @param part2 (in) zweiter Teil der Pfadangabe #* @param sep (in) (optional) Pathseparator to use [default: /] #* @return #* concatenated path #*/ public function join_path( in part1, in part2, in sep ) { auto sep2; switch (sep) { case "": sep="/"; # merke, kein break! case "/": sep2 = "\\"; break; case "\\": sep2 = "/"; break; default: sep2 = sep; } part1 = strip_both( part1, " " ); part1 = replace( part1, sep2, sep ); part2 = strip_both( part2, " " ); part2 = replace( part2, sep2, sep ); if ( part1 == "" ) return part2; if ( part2 == "" ) return part1; part1 = strip_trail( part1, sep ); part2 = strip_front( part2, sep ); return part1 & sep & part2; } #=============================================================================== # FUNCTION: trim #=============================================================================== # DESCRIPTION/PURPOSE: # Diese Funktion entfernt alle Vorkommen Blank vom Ende des <str1>. # PARAMETERS: # in str: String, das "gestrippt" werden soll # RETURN VALUE: # umgewandelter String # BEISPIEL: # s = "1234 "; # x = "<" & trim(s) & ">"; ==> x = "<1234>" #=============================================================================== public function trim(in str1) { static i; for(i=length(str1); i > 0; i--) if(substr(str1,i,1) != " ") break; return(substr(str1,1,i)); } #=============================================================================== # FUNCTION: ltrim #=============================================================================== # DESCRIPTION/PURPOSE: # Diese Funktion entfernt alle Vorkommen Blank vom Anfang des <str1>. # PARAMETERS: # in str: String, das "gestrippt" werden soll # RETURN VALUE: # umgewandelter String # BEISPIEL: # s = " 1234"; # x = "<" & ltrim(s) & ">"; ==> x = "<1234>" #=============================================================================== public function ltrim(in str1) { static i,j1,j2; j1 = length(str1); for(i=1; i <= j1; i++) if(substr(str1,i,1) != " ") break; if (i <= j1) return(substr(str1,i)); else return(str1); } #=============================================================================== # FUNCTION: alltrim #=============================================================================== # DESCRIPTION/PURPOSE: # Diese Funktion entfernt alle Vorkommen Blank vom Anfang und vom Ende # des <str1>. # PARAMETERS: # in str: String, das "gestrippt" werden soll # RETURN VALUE: # umgewandelter String # BEISPIEL: # s = " 1234 "; # x = "<" & alltrim(s) & ">"; ==> x = "<1234>" #=============================================================================== public function alltrim(in str1) { return(ltrim(trim(str1))); } #=============================================================================== # FUNCTION: random_arr - Vorbereitung Random-Array. #=============================================================================== # DESCRIPTION/PURPOSE: # Vorbereitung Random-Array. # PARAMETERS: # inout arr[]: belibige Array # in nnn: Dimension von Array # RETURN VALUE: # inout arr[]: Array zufälliger Zahlen # BEISPIEL: # random_arr(arr1,100); # for(i=1; i <= 100; i++) # print(arr1[i]); #=============================================================================== public function random_arr(inout arr1[], in nnn) { static i, ind1; for (i = 1; i <= nnn; i++) arr1[i] = 0; for (i = 1; i <= nnn; i++) { ind1 = int(rand() * nnn) + 1; while( arr1[ind1] != 0 ) ind1 = int(rand() * nnn) + 1; arr1[ind1] = i; } } #=============================================================================== # FUNCTION: replace1 #=============================================================================== # DESCRIPTION/PURPOSE: # Diese Funktion ersetzt alle Vorkommen <s2> durch <s3> in <s1>. # PARAMETERS: # in s1: String, das "gestrippt" werden soll # in s2: String, das ersetzt werden sollen # in s3: String, das engefügt werden sol # RETURN VALUE: # umgewandelter String # BEISPIEL: # s1 = replace1("1234567890","34","abcd"); ==> s1 = "12abcd567890" # s1 = replace1("1234567890","3456","a"); ==> s1 = "12a7890" # s1 = replace1("1234567890","3456",""); ==> s1 = "127890" #=============================================================================== public function replace1(in s1, in s2, in s3) { static i,i1,i2,len2; static t1,t2,j1,j2; static s1x; j1 = 1; if (s1 == "" || s2 == "") return(s1); i1 = index(s1,s2); if (i1 == 0) return(s1); s1x = s1; s1 = ""; len2 = length(s2); i2 = index1(s1x,s2); for(i = 1; i <= i2; i++) { i1 = index(s1x, s2); if (i1 != 1) s1 = s1 & substr(s1x, 1, i1-1); s1 = s1 & s3; if (i1 + len2 <= length(s1x) ) s1x = substr(s1x, i1 + len2); else s1x = ""; } return( s1 & s1x ); } #=============================================================================== # FUNCTION: substr1 #=============================================================================== # DESCRIPTION/PURPOSE: # Diese Funktion gibt substring aus <str1> vom Anfang <s1> bis zum Ende <s3> # zurück. # PARAMETERS: # in str1: String, das untersucht werden soll # in s2: String, das den Anfang bestimmt # in s3: String, das das Ende bestimmt # RETURN VALUE: # substring # BEISPIEL: # x = substr1("123<<<abcd>>>45678","<<<",">>>"); ==> x = "abcd" # x = substr1("123##abcdef##45678","##","##"); ==> x = "abcdef" #=============================================================================== public function substr1(in str1, in s1, in s2) { static j1,j2,j3,j4,j5; j1 = index(str1,s1); if (j1 == 0) return(""); if (s1 == s2) { j4 = index1(str1,s1); if (j4 <= 1) return(""); j4 = index2(str1,s1,1) + length(s1); j5 = index2(str1,s1,2) - j4; return(substr(str1,j4,j5)); } j3 = j1 + length(s1); if (s2 == "") return(substr(str1,j3)); else { j2 = index(substr(str1,j3),s2); if (j2 == 0) return(""); return(substr(str1,j3,j2-1)); } } #=============================================================================== # FUNCTION: index1 #=============================================================================== # DESCRIPTION/PURPOSE: # Diese Funktion gibt den Anzahl alle Vorkommen <s2> in <s1> zurück. # PARAMETERS: # in s1: String, das untersucht werden soll # in s2: subtring, das sucht werden soll # RETURN VALUE: # Zahl # BEISPIEL: # rc = index1("123ab4567ab890","ab"); ==> rc = 2 # rc = index1("123ab4567ababa","ab"); ==> rc = 3 #=============================================================================== public function index1(in s1, in s2) { static i,i1,i2; i=1; i1=0; i2=0; while(1) { i1 = index(substr(s1,i),s2); if (i1 == 0) return(i2); i2++; i = i + i1 - 1 + length(s2); } } #=============================================================================== # FUNCTION: index2 #=============================================================================== # DESCRIPTION/PURPOSE: # Diese Funktion gibt die Position des Vorkommens <s2> in <s1> # mit Nummer <n1> zurück. # PARAMETERS: # in s1: String, das untersucht werden soll # in s2: subtring, das sucht werden soll # in n1: Zahl - Nummer des Vorkommens # RETURN VALUE: # Anzahl # BEISPIEL: # Pos: 123456789012345678 # s1 = "12ab345ab6ab789ab0"; # N = index2(s1,"ab",1); ==> N = 3 # N = index2(s1,"ab",2); ==> N = 8 # Letztes Vorkommen: # N = index2(s1,"ab",index1(s1,"ab")); ==> N = 16 #=============================================================================== public function index2(in s1, in s2, in n1) { static i,i1,i2; i=1; i1=0; i2=0; if (s1 == "" || s2 == "" || n1 == "" || n1 == 0) return(0); while(1) { i1 = index(substr(s1, i),s2); if (i1 == 0) return(0); if (++i2 == n1) return(i + i1 - 1); i = i + i1 - 1 + length(s2); } } #=============================================================================== # FUNCTION: split1 #=============================================================================== # DESCRIPTION/PURPOSE: # Änlich wie builtin-Funktion split() außer: statt Field_separators # ganzes String. # PARAMETERS: # Änlich wie builtin-Funktion split() # RETURN VALUE: # Änlich wie builtin-Funktion split() # BEISPIEL: # rc = split1("123##45##6789##0",arr1,"##"); ==> rc = 4 # ==> arr1[1] = "123" # ==> arr1[2] = "45" # ==> arr1[3] = "6789" # ==> arr1[4] = "0" #=============================================================================== public function split1(in s1, inout arr1[], in s2) { static i,i1,len2; for(i in arr1) arr1[i]= ""; if (index(s1,s2) == 0) return(0); len2 = length(s2); if (substr(s1,1,len2) != s2) s1 = s2 & s1; i1 = index1(s1,s2); if (substr(s1,length(s1) - len2 + 1, len2) != s2) s1 = s1 & s2; else i1--; for (i=1; i <= i1; i++) arr1[i]= substr1(substr(s1,index2(s1,s2,i)),s2,s2); return(i1); } #/** #* Converts the integer returned by the get_time function to a string formatted as YYYYMMDD. #* This function converts the integer argument (time) returned by the get_time function to a string, #* in the format "YYYYMMDD" For example, the string "19981205", is the return value of the function. #* @param time (in) [optional] integer returned by get_time() or any other integer that is interpreted #* as number of seconds passes since 1.Jan.1970. [default: today] #* @return string formatted to YYYYMMDD or empty string if date could not be interpreted. #*/ public function yyyymmdd_str( in time ) { auto t = (time=="" ? time_str() : time_str( time )); auto arr[]; auto count; auto mm; count = split( t, arr, " " ); if ( count != 5 ) return ""; switch ( arr[2] ) { case "Jan": mm = 1; break; case "Feb": mm = 2; break; case "Mar": mm = 3; break; case "Apr": mm = 4; break; case "May": mm = 5; break; case "Jun": mm = 6; break; case "Jul": mm = 7; break; case "Aug": mm = 8; break; case "Sep": mm = 9; break; case "Oct": mm = 10; break; case "Nov": mm = 11; break; case "Dec": mm = 12; break; default: return ""; } return sprintf("%04d%02d%02d", arr[5], mm, arr[3] ); } ########################################################################### # TSL-LIBRARY: EMOS_STD_string_Lib ###########################################################################