Welcome, Guest |
This public forum is meant for questions and discussions about Visual FoxPro
TOPIC:
VFP *TRIM() functions 20 May 2020 21:20 #14652
|
As an experiment on varying number of parameters in a function declaration, a proposal of the implementation of *Trim() functions:
TRIM() = RTRIM(), so a header file could be used to add it to the list. Testing (but no stress test): Procedure Trim_Test ()
? 'Alltrim(" ") == ""', IIF(Alltrim(" ") == "", "OK", "Fail")
? 'Alltrim(e" \n ", 0, " ", CHR(9), CHR(10), CHR(13)) == ""', IIF(Alltrim(e" \n ", 0, " ", CHR(9), CHR(10), CHR(13)) == "", "OK", "Fail")
? 'Alltrim("Test ") == "Test"', IIF(Alltrim("Test ") == "Test", "OK", "Fail")
? 'Alltrim(e"Test \n ", 0, " ", CHR(9), CHR(10), CHR(13)) == "Test"', IIF(Alltrim(e"Test \n ", 0, " ", CHR(9), CHR(10), CHR(13)) == "Test", "OK", "Fail")
? 'Alltrim("TeTeTest", 0, "te") == "TeTeTest"', IIF(Alltrim("TeTeTest", 0, "te") == "TeTeTest", "OK", "Fail")
? 'Alltrim("TeTeTest", 1, "te") == "st"', IIF(Alltrim("TeTeTest", 1, "te") == "st", "OK", "Fail")
? 'Alltrim("TeTeTest", 0, "t", "e") == "TeTeTes"', IIF(Alltrim("TeTeTest", 0, "t", "e") == "TeTeTes", "OK", "Fail")
? 'Alltrim("TeTeTest", 1, "t", "e") == "s"', IIF(Alltrim("TeTeTest", 1, "t", "e") == "s", "OK", "Fail")
? 'Alltrim("***abc*", 0, "*") == "abc"', IIF(Alltrim("***abc*", 0, "*") == "abc", "OK", "Fail")
? 'Ltrim("***abc*", 0, "*") == "abc*"', IIF(Ltrim("***abc*", 0, "*") == "abc*", "OK", "Fail")
? 'Rtrim("***abc*", 0, "*") == "***abc"', IIF(Rtrim("***abc*", 0, "*") == "***abc", "OK", "Fail")
? 'Alltrim("abcdefghab", 1, "AB", "B") == "cdefgh"', IIF(Alltrim("abcdefghab", 1, "AB", "B") == "cdefgh", "OK", "Fail")
? 'Alltrim("abcdefghab", 1, "B", "AB") == "cdefgha"', IIF(Alltrim("abcdefghab", 1, "B", "AB") == "cdefgha", "OK", "Fail")
// ? 'ISNULL(Rtrim(NULL))', IIF(ISNULL(Rtrim(NULL)), "OK", "Fail")
End Proc Result: The functions set: Function Alltrim (Expression AS String) AS String
Return _trim(.T., .T., Expression, 0, " ")
End Function
Function Alltrim (Expression AS String, Flags AS Int, TrimChars PARAMS String[]) AS String STRICT
Return _trim(.T., .T., Expression, Flags, TrimChars)
End Function
Function Ltrim (Expression AS String) AS String
Return _trim(.T., .F., Expression, 0, " ")
End Function
Function Ltrim (Expression AS String, Flags AS Int, TrimChars PARAMS String[]) AS String STRICT
Return _trim(.T., .F., Expression, Flags, TrimChars)
End Function
Function Rtrim (Expression AS String) AS String
Return _trim(.F., .T., Expression, 0, " ")
End Function
Function Rtrim (Expression AS String, Flags AS Int, TrimChars PARAMS String[]) AS String STRICT
Return _trim(.F., .T., Expression, Flags, TrimChars)
End Function
STATIC Function _trim (TrimLeft AS Boolean, TrimRight AS Boolean, Expression As String, Flags As Int, TrimChars PARAMS String[]) AS String STRICT
LOCAL parmNdx AS Int
LOCAL Trimmed = .T. AS Boolean
LOCAL LRTrimmed AS Int
LOCAL comparison = StringComparison.Ordinal
LOCAL compared AS String
IF Expression = NULL
Return Expression
END IF
IF Flags = 1
comparison = StringComparison.OrdinalIgnoreCase
END IF
DO WHILE Trimmed
Trimmed = .F.
FOR parmNdx = 1 TO TrimChars:Length
IF TrimLeft
LRTrimmed = 0
compared = TrimChars[parmNdx]
DO WHILE Expression:StartsWith(compared, comparison)
LRTrimmed = compared:Length
compared = String.Concat(compared, TrimChars[parmNdx])
END DO
IF LRTrimmed > 0
Expression = Expression:Substring(LRTrimmed)
Trimmed = .T.
END IF
END IF
IF TrimRight
LRTrimmed = 0
compared = TrimChars[parmNdx]
DO WHILE Expression:EndsWith(compared, comparison)
LRTrimmed = compared:Length
compared = String.Concat(compared, TrimChars[parmNdx])
END DO
IF LRTrimmed > 0
Expression = Expression:Substring(0, Expression:Length - LRTrimmed)
Trimmed = .T.
END IF
END IF
NEXT
END DO
Return Expression
End Function |
Please Log in or Create an account to join the conversation. |
VFP *TRIM() functions 21 May 2020 17:17 #14667
|
Hi Antonio, Thanks a lot for your contribution! Will add it to the runtime, will just need to make small adjustments so that it can co-exist with the already existing implementation of AllTrim() etc. Fortunately the versions with no params at all seem to have the same behavior in both FoxPro and VO. It should be possible to improve the performance by somehow avoiding creating many new strings while the function runs, but this can be improved later. XSharp Development Team chris(at)xsharp.eu |
Please Log in or Create an account to join the conversation. |
VFP *TRIM() functions 22 May 2020 12:03 #14675
|
Hi Antonio, nice work and interesting to see how many trim options VFP offers ! About the Trim() function: Simply add it to your existing functions. FUNCTION Trim (Expression AS STRING) AS STRING
RETURN RTrim (Expression )
FUNCTION Trim (Expression AS STRING, Flags AS INT, TrimChars PARAMS STRING[]) AS STRING STRICT
RETURN RTrim (Expression , Flags, TrimChars ) regards Karl-Heinz |
Please Log in or Create an account to join the conversation. |
VFP *TRIM() functions 22 May 2020 15:19 #14676
|
Thank you, Chris & Karl-Heinz. Like Matt, Thomas, Kevin, and others that are contributing to the X# VFP runtime, we hope that these steps may add to the potential of X# as a viable or interesting option for the VFP community, humble as they might be. Before moving to something else, I reduced a little bit the need for the creation of new strings: STATIC Function TrimHelper (TrimLeft AS Boolean, TrimRight AS Boolean, Expression As String, Flags As Int, TrimChars PARAMS String[]) AS String STRICT
LOCAL parmNdx AS Int
LOCAL Trimmed = .T. AS Boolean
LOCAL LRTrimmed AS Int
LOCAL comparison = StringComparison.Ordinal AS System.StringComparison
LOCAL compared AS String
IF Expression = NULL
Return Expression
END IF
IF Flags = 1
comparison = StringComparison.OrdinalIgnoreCase
END IF
DO WHILE Trimmed
Trimmed = .F.
FOR parmNdx = 1 TO TrimChars:Length
compared = TrimChars[parmNdx]
IF TrimLeft
LRTrimmed = 0
DO WHILE String.Compare(Expression, LRTrimmed, compared, 0, compared:Length, comparison) = 0
LRTrimmed += compared:Length
END DO
IF LRTrimmed > 0
Expression = Expression:Substring(LRTrimmed)
Trimmed = .T.
END IF
END IF
IF TrimRight
LRTrimmed = Expression:Length - compared:Length
DO WHILE LRTrimmed >= 0 AND String.Compare(Expression, LRTrimmed, compared, 0, compared:Length, comparison) = 0
LRTrimmed -= compared:Length
END DO
IF LRTrimmed < (Expression:Length - compared:Length)
Expression = Expression:Substring(0, LRTrimmed + compared:Length)
Trimmed = .T.
END IF
END IF
NEXT
END DO
Return Expression
End Function |
Please Log in or Create an account to join the conversation. |
VFP *TRIM() functions 22 May 2020 17:48 #14684
|
Hi Antonio, Thanks, looks perfect to me now! I have updated the source in Git. XSharp Development Team chris(at)xsharp.eu |
Please Log in or Create an account to join the conversation. |