Datetime compiler problems with long strings
by Wil van Antwerpen
Summary
This article discusses the problem your compiler has with long strings in expressions and general datetime functions. (VDF15.1 and earlier) |
No Files Available |
Date Created: |
12/03/2010 |
Date Updated: |
12/01/2016 |
Author: |
Wil van Antwerpen
|
Company: |
Antwise Solutions |
DateTime problem with long strings
March 12, 2010
Please note that this problem was specific for Visual DataFlex 15.1 and earlier.
This appears to have been fixed in Visual DataFlex16.0
What's the problem?
Ok, so you might wonder... how can you have a problem with datetime arithmetic and strings?
What is the link between these two?
Well if you have a string literal in an expression that is over 296 characters long in your application then the compiler chokes on the code:
DateTime dtVar
Move (CurrentDateTime()) To dtVar
and also on:
DateTime dtVar
Move (NullDateTime()) To dtVar
I'm not the first person that bumped into this, see also this forum thread: Another compiler oddity..
It is a very weird limitation as the string length itself doesn't make much sense, 297 characters are a problem!
All you need to do to get the error, is include the following method in your application:
Procedure Testme
String sMessage
DateTime dtVar
Move ("very long string bla bla bla bla kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkddddddddddddddddddddddddddddddddddddddddkkksssss") to sMessage
Move (CurrentDateTime()) to dtVar
End_Procedure
With that code in place, the compiler no longer recognizes global datetime functions like CurrentDateTime and NullDateTime.
Remove 1 character from the long string and there's no problem.
It's the 296 character string limit compiler problem
It is important to note that it is not a variable length runtime problem, you can make your strings much bigger as that as long as you break them up in shorter literals.
How to fix it?
Well the fix is pretty simple, just make sure that your application doesn't have any string literals longer as 255 characters.
Exceeding that limit might give weird side effects.
It is not common for most programs to have string literals of that size and if you break them up in smaller chunks then there is no problem.
So for the example above that would be:
Procedure Testme
String sMessage
DateTime dtVar
Move ("very long string bla bla bla bla kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk") to sMessage
Move (sMessage+"ddddddddddddddddddddddddddddddddddddddddkkksssss") to sMessage
Move (CurrentDateTime()) to dtVar
End_Procedure
Wait... a simple solution, but what if your application contains more as 100 lines of code?
How are you going to find those long strings then?
I wrote a quick and dirty application for this, give it the .prn filename of the application you want to check, the length of the string you want to find.
Run it and it will show you which lines to amend so you can get rid of this annoying compiler error.
This problem still exists in VDF15.1
The program
String gsFileName gsOK
Move "Order.prn" to gsFileName
Function LongString String sLine String sQuoteID Integer iOpenPos Integer iMaxLen Returns Integer
Integer iLength
Integer iClosePos
String sRemove
Move 0 to iLength
Move (Left(sLine,iOpenPos)) to sRemove
Move (Replace(sRemove,sLine,"")) to sLine
Move (Pos(sQuoteID,sLine)) to iClosePos
If (iClosePos>iMaxLen) Move iClosePos to iLength
Function_Return iLength
End_Function // LongString
Procedure FindLongStrings String sPrnFile Integer iMaxLen
String sLine
Integer iLine
Integer iCommentPos
Integer iDQuotPos
Integer iSQuotPos
Integer iPos
Integer iLength
Boolean bInspectCloser
Move 0 to iLine
Direct_Input channel 3 sPrnFile
While not (SeqEof)
Readln channel 3 sLine
Move False to bInspectCloser
Move 0 to iPos
Move 0 to iLength
Increment iLine
Move (Pos('"',sLine)) to iDQuotPos
Move (Pos("'",sLine)) to iSQuotPos
Move (Pos('//',sLine)) to iCommentPos
If (iDQuotPos<>0) Begin
If (iCommentPos<>0 and iCommentPos>iDQuotPos) Move True to bInspectCloser
If (iCommentPos=0) Move True to bInspectCloser
End
If (iSQuotPos<>0) Begin
If (iCommentPos<>0 and iCommentPos>iSQuotPos) Move True to bInspectCloser
If (iCommentPos=0) Move True to bInspectCloser
End
If (bInspectCloser) Begin
If (iSQuotPos=0) Begin
Get LongString sLine '"' iDQuotPos iMaxLen to iLength
Move iDQuotPos to iPos
End
If (iDQuotPos=0) Begin
Get LongString sLine "'" iSQuotPos iMaxLen to iLength
Move iSQuotPos to iPos
End
If (iSQuotPos>0 and iDQuotPos>0) Begin
If (iSQuotPos<iDQuotPos) Begin
Get LongString sLine "'" iSQuotPos iMaxLen to iLength
Move iSQuotPos to iPos
End
Else Begin
Get LongString sLine '"' iDQuotPos iMaxLen to iLength
Move iDQuotPos to iPos
End
End
If (iLength>0) Begin
Showln ("Line :"*Trim(iLine)* "String length :"*trim(iLength) )
Showln ("="*sLine)
End
End
Loop
Close_Input channel 3
End_Procedure
Send Info_Box "Click to START" "Click OK To start searching for the loooong string"
Send FindLongStrings gsFilename 250
Winput "Done searching. Click OK To Quit" gsOK
With special thanks to Peter H. van Wijk for telling me to use the .prn file to scan and Sonny Falk for improving the text on the article
|