Profiling trimming characters from a string
;==========================================================================================================================================
; Trim or strip characters from a string, at the left edge, right edge or both edges.
;
; Profiling Performance Contest.
;
;   udfStrStrip  - Version 1, Detlev Dalitz.20030924.20090423.
;   udfStrStrip  - Version 2, Detlev Dalitz.20030924.20090423.20100108.20101219.
;   udfStrStrip  - Version 3, Detlev Dalitz.20101219.20101221.
;   udfStrStrip  - Version 4, Detlev Dalitz.20101220.20101221.
;   udfStrStrip  - Version 5, Detlev Dalitz.20101220.20101221.
;   udfStrStrip  - Version 6, Detlev Dalitz.20101222.
;   strTrimClean - Version 2, 20101219 Lars M. Doornbos.
;
;------------------------------------------------------------------------------------------------------------------------------------------
; (c)Detlev Dalitz.20101220.20101221.20101222.
;==========================================================================================================================================


; How many different test cases?
intContestCaseMax = 3

; How many loops to run?
intContestLoopMax = 200

; What group of contestants to examine?
intContestantMin = 1
intContestantMax = 7

; Previewing of test case results?
blnPreviewResults = @TRUE
;blnPreviewResults = @FALSE


GoSub DEFINE_FUNCTIONS

; Run the contest once and display the results for verifying.
; Then press CANCEL to abort or OK to run complete contest.
If blnPreviewResults
   For intContestCase = 1 To intContestCaseMax
      udsPrepareTestCase (intContestCase)
      udsPrepareCounters ()
      For intContestant = intContestantMin To intContestantMax
         udsRunContestant (intContestant)
      Next
      If @CANCEL == udfArrayDumpToItemList (arrContestResults, intContestantMin, intContestantMax, @LF) Then Goto CANCEL
   Next
EndIf

; Run complete contest.
WinShow ("")
strContestResult = ""
For intContestCase = 1 To intContestCaseMax
   udsPrepareTestCase (intContestCase)
   udsPrepareCounters ()
   For intContestLoop = 1 To intContestLoopMax
      For intContestant = intContestantMin To intContestantMax
         WinTitle ("", "Profiling|Case=" : intContestCaseMax : "." : intContestCase : "|Contestant=" : intContestantMax : "." : intContestant : "|Loop=" : intContestLoopMax : "." : intContestLoop)
         udsRunContestant (intContestant)
      Next
   Next
   strContestResult = strContestResult : @LF : udsResultPerTestCase ()
Next
strContestResult = strContestResult : @LF : strPre : StrFill ("-", intLenSum)
strContestResult = StrSub (strContestResult, 2, -1)

Message (strMsgTitle, strContestResult)
ClipPut (StrReplace (strContestResult, @LF, @CRLF))

:CANCEL
Exit
;==========================================================================================================================================



;==========================================================================================================================================
:DEFINE_FUNCTIONS
;==========================================================================================================================================

;------------------------------------------------------------------------------------------------------------------------------------------
#DefineSubRoutine udsPrepareTestCase (intContestCase)
Switch intContestCase
Case 1
   strString = @TAB : "  " : @CRLF : "  " : @CR : "This is the text" : @TAB : "  " : @CRLF : "  " : @CR
   strStripChars = " exisT" : @CRLF : @TAB
   strBoundary = "L"
   intBoundary = -1
   blnMatchCase = @FALSE
   ; strResult = "his is the text@TAB  @CRLF  @CR"
   Break
Case 2
   strString = @TAB : "  " : @CRLF : "  " : @CR : "This is the text" : @TAB : "  " : @CRLF : "  " : @CR
   strStripChars = " exist" : @CRLF : @TAB
   strBoundary = "R"
   intBoundary = 1
   blnMatchCase = @FALSE
   ; strResult = "@TAB  @CRLF  @CRThis is th"
   Break
Case 3
   strString = @TAB : "  " : @CRLF : "  " : @CR : "This is the text" : @TAB : "  " : @CRLF : "  " : @CR
   strStripChars = " Texist" : @CRLF : @TAB
   strBoundary = "B"
   intBoundary = 0
   blnMatchCase = @TRUE
   ; strResult = "his is th"
   Break
EndSwitch
#EndSubRoutine
;------------------------------------------------------------------------------------------------------------------------------------------


;------------------------------------------------------------------------------------------------------------------------------------------
#DefineSubRoutine udsRunContestant (intContestant)
Exclusive (@ON)
Switch intContestant
Case 1
   arrContestants[intContestant] = "udfStrStrip_1"
   intStart = GetTickCount ()
   arrContestResults[intContestant] = udfStrStrip_1 (strString, strStripChars, strBoundary)
   intStop = GetTickCount ()
   arrContestTicks[intContestant] = arrContestTicks[intContestant] + intStop - intStart
   Break

Case 2
   arrContestants[intContestant] = "udfStrStrip_2"
   intStart = GetTickCount ()
   arrContestResults[intContestant] = udfStrStrip_2 (strString, strStripChars, intBoundary)
   intStop = GetTickCount ()
   arrContestTicks[intContestant] = arrContestTicks[intContestant] + intStop - intStart
   Break

Case 3
   arrContestants[intContestant] = "udfStrStrip_3"
   intStart = GetTickCount ()
   arrContestResults[intContestant] = udfStrStrip_3 (strString, strStripChars, intBoundary, blnMatchCase)
   intStop = GetTickCount ()
   arrContestTicks[intContestant] = arrContestTicks[intContestant] + intStop - intStart
   Break

Case 4
   arrContestants[intContestant] = "udfStrStrip_4"
   intStart = GetTickCount ()
   arrContestResults[intContestant] = udfStrStrip_4 (strString, strStripChars, intBoundary, blnMatchCase)
   intStop = GetTickCount ()
   arrContestTicks[intContestant] = arrContestTicks[intContestant] + intStop - intStart
   Break

Case 5
   arrContestants[intContestant] = "udfStrStrip_5"
   intStart = GetTickCount ()
   arrContestResults[intContestant] = udfStrStrip_5 (strString, strStripChars, intBoundary, blnMatchCase)
   intStop = GetTickCount ()
   arrContestTicks[intContestant] = arrContestTicks[intContestant] + intStop - intStart
   Break

Case 6
   arrContestants[intContestant] = "udfStrStrip_6"
   intStart = GetTickCount ()
   arrContestResults[intContestant] = udfStrStrip_6 (strString, strStripChars, intBoundary, blnMatchCase)
   intStop = GetTickCount ()
   arrContestTicks[intContestant] = arrContestTicks[intContestant] + intStop - intStart
   Break

Case 7
   arrContestants[intContestant] = "strTrimClean"
   intStart = GetTickCount ()
   arrContestResults[intContestant] = strTrimClean (strString, strStripChars, intBoundary)
   intStop = GetTickCount ()
   arrContestTicks[intContestant] = arrContestTicks[intContestant] + intStop - intStart
   Break
EndSwitch
Exclusive (@OFF)
#EndSubRoutine
;------------------------------------------------------------------------------------------------------------------------------------------


;------------------------------------------------------------------------------------------------------------------------------------------
#DefineFunction strTrimClean (sourcestring, characters, iOption)
;------------------------------------------------------------------
; Trim characters from string
;    characters: string of characers to trim (see strClean(...))
;    iOption   : -1=TrimLeft, 1=TrimRight, 0=TrimBoth (thanks Detlev)
;
; 20101219 Lars M. Doornbos
;------------------------------------------------------------------
;-- clean leading
If !iOption || iOption == -1
   While @TRUE
      newstring = StrClean (StrSub (sourcestring, 1, 1), characters, '', @FALSE, 1) : StrSub (sourcestring, 2, -1)
      If newstring == sourcestring Then Break
      sourcestring = newstring
   EndWhile
EndIf
;-- clean trailing
If !iOption || iOption == 1
   While @TRUE
      slen = StrLen (sourcestring)
      newstring = StrSub (sourcestring, 1, slen - 1) : StrClean (StrSub (sourcestring, slen, 1), characters, '', @FALSE, 1)
      If newstring == sourcestring Then Break
      sourcestring = newstring
   EndWhile
EndIf
Return sourcestring
#EndFunction
;------------------------------------------------------------------------------------------------------------------------------------------


;------------------------------------------------------------------------------------------------------------------------------------------
#DefineFunction udfStrStrip_1 (strString, strStripChars, strBoundary)
If strString == "" Then Return strString
If strStripChars == "" Then Return strString

strDelim = Num2Char (1) ; Helper char for space char trimming.

strBoundary = StrLower (StrSub (strBoundary, 1, 1))
If !StrScan (strBoundary, "lrb", 1, @FWDSCAN) Then strBoundary = "b"
intBound = StrIndex ("lrb", strBoundary, 1, @FWDSCAN)

While @TRUE
   strBoundaryChars = ""
   Switch intBound
   Case 1
   Case 3
      strBoundaryChars = StrSub (strString, 1, 1)
      Continue
   Case 2
   Case 3
      strBoundaryChars = StrCat (strBoundaryChars, StrSub (strString, StrLen (strString), 1))
      Break
   EndSwitch
   intPos = StrScan (strStripChars, strBoundaryChars, 0, @FWDSCAN)
   If intPos == 0 Then Break
   strChar = StrSub (strStripChars, intPos, 1)

   Switch @TRUE
   Case strChar == " "
      Switch intBound
      Case 1
         strString = ItemExtract (1, StrTrim (StrCat (strString, strDelim)), strDelim) ; Trim left.
         Break
      Case 2
         strString = ItemExtract (2, StrTrim (StrCat (strDelim, strString)), strDelim) ; Trim right.
         Break
      Case 3
         strString = StrTrim (strString)
         Break
      EndSwitch
      Break
   Case @TRUE
      Switch intBound
      Case 1
      Case 3
         intPos = 1
         While StrSub (strString, intPos, 1) == strChar
            intPos = intPos + 1
         EndWhile
         strString = StrSub (strString, intPos, -1)
         If strString == "" Then Break
         Continue
      Case 2
      Case 3
         intPos = StrLen (strString)
         While StrSub (strString, intPos, 1) == strChar
            intPos = intPos - 1
         EndWhile
         strString = StrSub (strString, 1, intPos)
         Break
      EndSwitch
      Break
   EndSwitch
   If strString == "" Then Break
EndWhile
Return strString
;..........................................................................................................................................
; This UDF "udfStrStrip" returns a substring from the given strString.
;
; Depending on whether parameter "intBoundary" is "L" ("Left"), "R" ("Right"), or "B" ("Both"),
; the leading, trailing, or both leading and trailing occurrences of "strStripChars"
; will be deleted and the result string will be returned.
;
; Examples:
;   udfStrStrip ('  text  ', ' '   , 'B')   ==> 'text'
;   udfStrStrip ('  text  ', ' '   , 'L')   ==> 'text  '
;   udfStrStrip ('  text  ', ' '   , 'R')   ==> '  text'
;   udfStrStrip ('--text--', '-'   , 'B')   ==> 'text'
;   udfStrStrip ('  text  ', ' t'  , 'B')   ==> 'ex'
;   udfStrStrip ('  text  ', ' t'  , 'L')   ==> 'ext  '
;   udfStrStrip ('  text  ', ' t'  , 'R')   ==> '  tex'
;   udfStrStrip ('  text  ', 'txe' , 'B')   ==> '  text  '
;   udfStrStrip ('  text  ', ' txe', 'R')   ==> ''
;..........................................................................................................................................
; Detlev Dalitz.20030924.20090423.
;..........................................................................................................................................
#EndFunction
;------------------------------------------------------------------------------------------------------------------------------------------


;------------------------------------------------------------------------------------------------------------------------------------------
#DefineFunction udfStrStrip_2 (strString, strStripChars, intBoundary)
If strString == "" Then Return strString
If strStripChars == "" Then Return strString

strDelim = Num2Char (1) ; Helper char for space char trimming.

intBoundary = Min (Max (intBoundary, -1), 1) ; -1 = Left, 0 = Left+Right, 1 = Right.

While @TRUE
   strBoundaryChars = ""
   Switch intBoundary
   Case -1
   Case 0
      strBoundaryChars = StrSub (strString, 1, 1)
      Continue
   Case 1
   Case 0
      strBoundaryChars = strBoundaryChars : StrSub (strString, StrLen (strString), 1)
      Break
   EndSwitch
   intPos = StrScan (strStripChars, strBoundaryChars, 0, @FWDSCAN)
   If intPos == 0 Then Break
   strChar = StrSub (strStripChars, intPos, 1)

   Switch @TRUE
   Case strChar == " "
      Switch intBoundary
      Case 0
         strString = StrTrim (strString) ; Trim left and right.
         Break
      Case 1
         strString = ItemExtract (2, StrTrim (strDelim : strString), strDelim) ; Trim right.
         Break
      Case - 1
         strString = ItemExtract (1, StrTrim (strString : strDelim), strDelim) ; Trim left.
         Break
      EndSwitch
      Break
   Case @TRUE
      Switch intBoundary
      Case -1
      Case 0
         intPos = 1
         While StrIndex (strString, strChar, intPos, @FWDSCAN) == intPos
            intPos = intPos + 1
         EndWhile
         strString = StrSub (strString, intPos, -1)
         If strString == "" Then Break
         Continue
      Case 1
      Case 0
         intPos = StrLen (strString)
         While StrIndex (strString, strChar, intPos, @FWDSCAN) == intPos
            intPos = intPos - 1
         EndWhile
         strString = StrSub (strString, 1, intPos)
         Break
      EndSwitch
      Break
   EndSwitch
   If strString == "" Then Break
EndWhile
Return strString
;..........................................................................................................................................
; This UDF "udfStrStrip" returns a substring from the given strString.
; Depending on whether parameter "intBoundary" is -1 (left edge), 1 (right edge) or 0 (both edges),
; the leading, trailing, or both leading and trailing occurrences of "strStripChars"
; will be deleted and the result string will be returned.
;
; Examples:
;   udfStrStrip ('  text  ', ' '   , 0)   ==> 'text'
;   udfStrStrip ('  text  ', ' '   , -1)  ==> 'text  '
;   udfStrStrip ('  text  ', ' '   , 1)   ==> '  text'
;   udfStrStrip ('--text--', '-'   , 0)   ==> 'text'
;   udfStrStrip ('  text  ', ' t'  , 0)   ==> 'ex'
;   udfStrStrip ('  text  ', ' t'  , -1)  ==> 'ext  '
;   udfStrStrip ('  text  ', ' t'  , 1)   ==> '  tex'
;   udfStrStrip ('  text  ', 'txe' , 0)   ==> '  text  '
;   udfStrStrip ('  text  ', ' txe', 1)   ==> ''
;..........................................................................................................................................
; Detlev Dalitz.20030924.20090423.20100108.20101219.
;..........................................................................................................................................
#EndFunction
;------------------------------------------------------------------------------------------------------------------------------------------


;------------------------------------------------------------------------------------------------------------------------------------------
#DefineFunction udfStrStrip_3 (strString, strStripChars, intBoundary, blnMatchCase)
If strString == "" Then Return strString
If strStripChars == "" Then Return strString
intBoundary = Min (Max (intBoundary, -1), 1) ; -1 = Left, 0 = Left+Right, 1 = Right.
Switch intBoundary
Case -1 ; Strip leading chars.
Case 0
   intLen = StrLen (strString) + 1
   intPos = 1
   While intPos < intLen
      If StrClean (StrSub (strString, intPos, 1), strStripChars, "", blnMatchCase, 1) != "" Then Break
      intPos = intPos + 1
   EndWhile
   strString = StrSub (strString, intPos, -1)
   If strString == "" Then Return ""
   Continue
Case 1 ; Strip trailing chars.
Case 0
   intLen = StrLen (strString)
   intPos = intLen
   While intPos > 0
      If StrClean (StrSub (strString, intPos, 1), strStripChars, "", blnMatchCase, 1) != "" Then Break
      intPos = intPos - 1
   EndWhile
   strString = StrSub (strString, 1, intPos)
EndSwitch
Return strString
;..........................................................................................................................................
; This UDF "udfStrStrip" returns a substring from the given strString.
;
; Depending on whether parameter "intBoundary" is -1 (left edge), 1 (right edge) or 0 (both edges),
; the leading, trailing, or both leading and trailing occurrences of "strStripChars"
; will be deleted and the result string will be returned.
;
; Depending on whether parameter "blnMatchCase" is @TRUE or @FALSE,
; character casing will be respected or not.
;..........................................................................................................................................
; Detlev Dalitz.20101219.20101221.
;..........................................................................................................................................
#EndFunction
;------------------------------------------------------------------------------------------------------------------------------------------


;------------------------------------------------------------------------------------------------------------------------------------------
#DefineFunction udfStrStrip_4 (strString, strStripChars, intBoundary, blnMatchCase)
If strString == "" Then Return strString
If strStripChars == "" Then Return strString
intBoundary = Min (Max (intBoundary, -1), 1) ; -1 = Left, 0 = Left+Right, 1 = Right.
arrS = ArrayFromStr (strString)
Switch intBoundary
Case -1 ; Strip leading chars.
Case 0
   While ArrInfo (arrS, 1) > 0
      If StrClean (arrS[0], strStripChars, "", blnMatchCase, 1) != "" Then Break
      ArrayRemove (arrS, 0)
   EndWhile
   If ArrInfo (arrS, 1) == 0 Then Return ""
   Continue
Case 1 ; Strip trailing chars.
Case 0
   While ArrInfo (arrS, 1) > 0
      intLast = ArrInfo (arrS, 1) - 1
      If StrClean (arrS[intLast], strStripChars, "", blnMatchCase, 1) != "" Then Break
      ArrayRemove (arrS, intLast)
   EndWhile
EndSwitch
If ArrInfo (arrS, 1) == 0 Then Return ""
Return ArrayToStr (arrS)
;..........................................................................................................................................
; This UDF "udfStrStrip" returns a substring from the given strString.
;
; Depending on whether parameter "intBoundary" is -1 (left edge), 1 (right edge) or 0 (both edges),
; the leading, trailing, or both leading and trailing occurrences of "strStripChars"
; will be deleted and the result string will be returned.
;
; Depending on whether parameter "blnMatchCase" is @TRUE or @FALSE,
; character casing will be respected or not.
;..........................................................................................................................................
; Detlev Dalitz.20101220.
;..........................................................................................................................................
#EndFunction
;------------------------------------------------------------------------------------------------------------------------------------------


;------------------------------------------------------------------------------------------------------------------------------------------
#DefineFunction udfStrStrip_5 (strString, strStripChars, intBoundary, blnMatchCase)
If strString == "" Then Return strString
If strStripChars == "" Then Return strString
intBoundary = Min (Max (intBoundary, -1), 1) ; -1 = Left, 0 = Left+Right, 1 = Right.
arrS = ArrayFromStr (strString)
Switch intBoundary
Case -1 ; Strip leading chars.
Case 0
   While ArrInfo (arrS, 1) > 0
      If StrClean (arrS[0], strStripChars, "", blnMatchCase, 1) != "" Then Break
      ArrayRemove (arrS, 0)
   EndWhile
   If ArrInfo (arrS, 1) == 0 Then Return ""
   Continue
Case 1 ; Strip trailing chars.
Case 0
   intLast = ArrInfo (arrS, 1) - 1
   While intLast > -1
      If StrClean (arrS[intLast], strStripChars, "", blnMatchCase, 1) != "" Then Break
      intLast = intLast - 1
   EndWhile
   ArrayRedim (arrS, intLast + 1)
EndSwitch
If ArrInfo (arrS, 1) == 0 Then Return ""
Return ArrayToStr (arrS)
;..........................................................................................................................................
; This UDF "udfStrStrip" returns a substring from the given strString.
;
; Depending on whether parameter "intBoundary" is -1 (left edge), 1 (right edge) or 0 (both edges),
; the leading, trailing, or both leading and trailing occurrences of "strStripChars"
; will be deleted and the result string will be returned.
;
; Depending on whether parameter "blnMatchCase" is @TRUE or @FALSE,
; character casing will be respected or not.
;..........................................................................................................................................
; Detlev Dalitz.20101220.
;..........................................................................................................................................
#EndFunction
;------------------------------------------------------------------------------------------------------------------------------------------


;------------------------------------------------------------------------------------------------------------------------------------------
#DefineFunction udfStrStrip_6 (strString, strStripChars, intBoundary, blnMatchCase)
If strString == "" Then Return strString
If strStripChars == "" Then Return strString
intBoundary = Min (Max (intBoundary, -1), 1) ; -1 = Left, 0 = Left+Right, 1 = Right.
objRegExp = ObjectCreate ("VBScript.RegExp")
objRegExp.Global = @TRUE
objRegExp.MultiLine = @FALSE
objRegExp.IgnoreCase = !blnMatchCase
Switch intBoundary
Case -1 ; Strip leading chars.
   objRegExp.Pattern = "^[" : strStripChars : "]+"
   Break
Case 1  ; Strip trailing chars.
   objRegExp.Pattern = "[" : strStripChars : "]+$"
   Break
Case 0  ; Strip leading and trailing chars.
   objRegExp.Pattern = "^[" : strStripChars : "]+|[" : strStripChars : "]+$"
EndSwitch
Return "" : objRegExp.Replace(strString, "") ; Return a WB string (no BSTR).
;..........................................................................................................................................
; This UDF "udfStrStrip" returns a substring from the given strString.
;
; Depending on whether parameter "intBoundary" is -1 (left edge), 1 (right edge) or 0 (both edges),
; the leading, trailing, or both leading and trailing occurrences of "strStripChars"
; will be deleted and the result string will be returned.
;
; Depending on whether parameter "blnMatchCase" is @TRUE or @FALSE,
; character casing will be respected or not.
;..........................................................................................................................................
; Detlev Dalitz.20101222.
;..........................................................................................................................................
#EndFunction
;------------------------------------------------------------------------------------------------------------------------------------------


;------------------------------------------------------------------------------------------------------------------------------------------
#DefineFunction udfArrayDumpToItemList (arrArray, intFirst, intLast, strDelimiter)
If !ArrInfo (arrArray, -1) Then Return "*ARRAY_IS_INVALID*" ; No Array, return invalid itemlist, i. e. empty string "".
If ArrInfo (arrArray, 0) != 1 Then Return "*ARRAY_IS_NOT_DIM_1*" ; Array is not a dim-1 array, return invalid itemlist, i. e. empty string "".
intElements = ArrInfo (arrArray, 1)
If intElements == 0 Then Return "*ARRAY_HAS_NO_ELEMENTS*" ; Array has no element.
intFirst = Min (Max (intFirst, 0), intElements - 1)
intLast = Min (Max (intLast, 0), intElements - 1)
strItemList = ""
intFixSize = StrLen (intLast)
For intI = intFirst To intLast
   If !!VarType (arrArray [intI])
      If arrArray [intI] == ""
         strItemList = ItemInsert (StrFixLeft (intI, "0", intFixSize) : "|" : "*ARRAY_ELEMENT_IS_EMPTY_STRING*", -1, strItemList, strDelimiter)
      Else
         arrArray [intI] = StrReplace (StrReplace (StrReplace (StrReplace (arrArray [intI], @CRLF, "@CRLF"), @CR, "@CR"), @LF, "@LF"), @TAB, "@TAB") ; Make WB style.
         arrArray [intI] = StrSub (arrArray [intI], 1, 200) ; Special truncation just for the small buffer of AskItemList.
         strItemList = ItemInsert (StrFixLeft (intI, "0", intFixSize) : "|" : arrArray [intI], -1, strItemList, strDelimiter)
      EndIf
   Else
      strItemList = ItemInsert (StrFixLeft (intI, "0", intFixSize) : "|" : "*ARRAY_ELEMENT_IS_UNDEFINED*", -1, strItemList, strDelimiter)
   EndIf
Next
IntControl (28, 1, 0, 0, 0)
IntControl (63, 050, 200, 950, 800)
Return AskItemlist ("Profiling|Preview Contestant Result", strItemList, strDelimiter, @UNSORTED, @SINGLE) ; This returns a Unicode string of VarType=128.
:CANCEL
Return @CANCEL
;..........................................................................................................................................
; This UDF "udfArrayDumpToItemList" reads a dim-1 array and returns an itemlist of all array cell items within an AskItemList dialog..
;
; Return values:
; "*ARRAY_IS_INVALID*"              ... Invalid array resp. this is no array.
; "*ARRAY_IS_NOT_DIM_1*"            ... Array is not a dim-1 array.
; "*ARRAY_HAS_NO_ELEMENTS*"         ... Array has no element.
; "*ARRAY_ELEMENT_IS_EMPTY_STRING*" ... Array element has vartype STRING but is empty.
; "*ARRAY_ELEMENT_IS UNDEFINED*"    ... Array element has undefined VarType.
; value                             ... Current value of the array element.
;
; Example: strItemList = udfArrayDumpToItemList (arrArray, 0, 19, @TAB)
;
; Detlev Dalitz.20090515.20100122.20101222.
;..........................................................................................................................................
#EndFunction
;------------------------------------------------------------------------------------------------------------------------------------------


;------------------------------------------------------------------------------------------------------------------------------------------
#DefineSubRoutine udsPrepareCounters ()
arrContestants = ArrDimension (1 + intContestantMax)    ; Array index 0 will not be used.
arrContestResults = ArrDimension (1 + intContestantMax) ; Array index 0 will not be used.
arrContestTicks = ArrDimension (1 + intContestantMax)   ; Array index 0 will be used for the sum.
arrContestPct = ArrDimension (1 + intContestantMax)     ; Array index 0 will not be used.
ArrInitialize (arrContestants, "")
ArrInitialize (arrContestResults, "")
ArrInitialize (arrContestTicks, 0)
ArrInitialize (arrContestPct, 0.0)
#EndSubRoutine
;------------------------------------------------------------------------------------------------------------------------------------------


;------------------------------------------------------------------------------------------------------------------------------------------
#DefineSubRoutine udsResultPerTestCase ()
Decimals (1)
For intContestant = intContestantMin To intContestantMax
   arrContestTicks[0] = arrContestTicks[0] + arrContestTicks[intContestant]
Next
intContestTicksMin = arrContestTicks[0]
For intContestant = intContestantMin To intContestantMax
   intContestTicksMin = Min (intContestTicksMin, arrContestTicks[intContestant])
Next
If arrContestTicks[0] < 1 Then arrContestTicks[0] = 1 ; To prevent dividing by zero.
For intContestant = intContestantMin To intContestantMax
   arrContestPct[intContestant] = 100.0 * arrContestTicks[intContestant] / arrContestTicks[0]
Next

; Format output.
strMsgTitle = "Performance Contest Result"
strTest = "Test"
strTicks = "Ticks"
strPct = "Pct"
strContestant = "Contestant"
strSep = "  "
strPre = "; "
strWinner = "<== The Winner"
intLenTest = Max (StrLen (strTest), StrLen (intContestantMax))
intLenTicks = StrLen (strTicks)
intLenPct = StrLen (strPct)
intLenContestant = StrLen (strContestant)
intLenSep = StrLen (strSep)
intLenWinner = StrLen (strWinner)
For intContestant = intContestantMin To intContestantMax
   intLenTicks = Max (intLenTicks, StrLen (arrContestTicks[intContestant]))
   intLenPct = Max (intLenPct, StrLen (arrContestPct[intContestant]))
   intLenContestant = Max (intLenContestant, StrLen (arrContestants[intContestant]))
Next
intLenSum = intLenTest + intLenTicks + intLenPct + intLenContestant + intLenWinner + 4 * intLenSep
strTest = StrFixLeft (strTest, " ", intLenTest)
strTicks = StrFixLeft (strTicks, " ", intLenTicks)
strPct = StrFixLeft (strPct, " ", intLenPct)
strResult = strPre : StrFill ("-", intLenSum) : @LF : strPre : strMsgTitle
strResult = strResult : @LF : strPre : "Contest Case = " : intContestCase
strResult = strResult : @LF : strPre : "Iterations = " : intContestLoopMax
strResult = strResult : @LF : strPre : strTest : strSep : strTicks : strSep : strPct : strSep : strContestant
For intContestant = intContestantMin To intContestantMax
   strTest = StrFixLeft (intContestant, " ", intLenTest)
   strTicks = StrFixLeft (arrContestTicks[intContestant], " ", intLenTicks)
   strPct = StrFixLeft (arrContestPct[intContestant], " ", intLenPct)
   strContestant = StrFix (arrContestants[intContestant], " ", intLenContestant)
   If arrContestTicks[intContestant] == intContestTicksMin Then strContestant = strContestant : strSep : strWinner
   strResult = strResult : @LF : strPre : strTest : strSep : strTicks : strSep : strPct : strSep : strContestant
Next
Return strResult : @LF : strPre : "DateTime = " : TimeYmdHms ()
#EndSubRoutine
;------------------------------------------------------------------------------------------------------------------------------------------

;==========================================================================================================================================
Return ; from GoSub DEFINE_FUNCTIONS
;==========================================================================================================================================

; ------------------------------------------------
; Performance Contest Result
; Contest Case = 1
; Iterations = 100
; Test  Ticks   Pct  Contestant
;    1   1699  30.2  udfStrStrip_1
;    2   1750  31.1  udfStrStrip_2
;    3    575  10.2  udfStrStrip_3
;    4    469   8.3  udfStrStrip_4
;    5    452   8.0  udfStrStrip_5
;    6    157   2.8  udfStrStrip_6  <== The Winner
;    7    532   9.4  strTrimClean
; DateTime = 2010:12:23:15:57:56
; ------------------------------------------------
; Performance Contest Result
; Contest Case = 2
; Iterations = 100
; Test  Ticks   Pct  Contestant
;    1   2691  30.8  udfStrStrip_1
;    2   2733  31.3  udfStrStrip_2
;    3    717   8.2  udfStrStrip_3
;    4    830   9.5  udfStrStrip_4
;    5    578   6.6  udfStrStrip_5
;    6    249   2.9  udfStrStrip_6  <== The Winner
;    7    933  10.7  strTrimClean
; DateTime = 2010:12:23:15:58:06
; ------------------------------------------------
; Performance Contest Result
; Contest Case = 3
; Iterations = 100
; Test  Ticks   Pct  Contestant
;    1   3626  30.3  udfStrStrip_1
;    2   3705  30.9  udfStrStrip_2
;    3   1064   8.9  udfStrStrip_3
;    4   1094   9.1  udfStrStrip_4
;    5    908   7.6  udfStrStrip_5
;    6    282   2.4  udfStrStrip_6  <== The Winner
;    7   1297  10.8  strTrimClean
; DateTime = 2010:12:23:15:58:20
; ------------------------------------------------

; ------------------------------------------------
; Performance Contest Result
; Contest Case = 1
; Iterations = 100
; Test  Ticks   Pct  Contestant
;    3    546  25.0  udfStrStrip_3
;    4    421  19.3  udfStrStrip_4
;    5    514  23.5  udfStrStrip_5
;    6    250  11.4  udfStrStrip_6  <== The Winner
;    7    454  20.8  strTrimClean
; DateTime = 2010:12:23:15:58:55
; ------------------------------------------------
; Performance Contest Result
; Contest Case = 2
; Iterations = 100
; Test  Ticks   Pct  Contestant
;    3    720  22.3  udfStrStrip_3
;    4    877  27.1  udfStrStrip_4
;    5    484  15.0  udfStrStrip_5
;    6    314   9.7  udfStrStrip_6  <== The Winner
;    7    840  26.0  strTrimClean
; DateTime = 2010:12:23:15:59:00
; ------------------------------------------------
; Performance Contest Result
; Contest Case = 3
; Iterations = 100
; Test  Ticks   Pct  Contestant
;    3   1018  21.0  udfStrStrip_3
;    4   1109  22.9  udfStrStrip_4
;    5    953  19.7  udfStrStrip_5
;    6    393   8.1  udfStrStrip_6  <== The Winner
;    7   1369  28.3  strTrimClean
; DateTime = 2010:12:23:15:59:06
; ------------------------------------------------;;;