I have several dlls that generate report outputs in french or english. Currently I am managing this through compilation directives leading to 2 dlls (one for each language). My source files contain generally two blocks of format statements enclosed in compiler directives. This allows me to change the formats without affecting the main block of code.
In the future, I am considering managing the language with only one dll. I would like to know if you have been facing this type of problem and what is your experience in doing this. I have already studied some possibilities but I am actually a bit stuck with formats which expand on several lines using continuation directives.
Looking forward to hear from you,
The method I use is to have all text strings supplied by a single function that has a 'string number' as a parameter. Within that function you can set the string according to what language is set and can easily change the implementation of where the string comes from (data files / case statement /specific dll etc ) in one place or indeed add other languages. I have 'tokens' in the strings where variable values can be inserted in the main code after the string has been aquired from the function.
Thanks Andrew for your prompt reply,
This is one of the possibilities I was investigating. Remplacing the format number of the write statement by a function returning the format string but what I am interesting in is more about the storage or definition of the format strings. You mentionned data files or case statements but there could be dll resources and probably a lot of other possibilities (as you also say). May me the case statement is a good choice because it avoids storing the formats strings in external media and allows multi-line format statement declarations.
I use a case statement for internal (default) strings but strings that come from an external file just get packed into a large (32K) character string with an index that has the start and length for string number 'n' so the string function can extract the relevant one as and when required.
A recently converted all my dialogs and menus to work with Unicode and a change to the underlying data structure and a couple of new utility routines was all that was needed to upgrade my "string function".
I guess if you have to hard code the strings a large case statement if probably the best way to have the string data.
This is what I am starting to work with. Fortunately, the use of "regular expressions" is very usefull in converting the formats statements into case statements.
Thanks for sharing your experince.
Another issue comes up when trying to manage default formatting.
Assuming that a format does not exist how to return a format string producing the same result as a FREE-FORMAT? I have tried "(*)" or "*" but one of them worked.
Is that possible?
It is quite possible to write data to a string via list-directed output:
write( string, * ) 1, 2, 'Oho'
Just make sure the string is long enough to hold the information.
It not exactly what I would like to do. I have a function that returns a string containing a format specification depending on an integer variable passed as argument. I have a select case..end select bloc which handles the various possible formats, however I would like to add a case default statement to handle the undesired case where the format is unknown. In this particular case I would like to return a string that can lead to the same results as a free-formatting (*). Note that the function does not know anything about the I/O-list.
Here is the example:
character(len=1024) function sFmt(fmtNum) result(s) use IFWIN use Systools, only: Language implicit none integer(4), intent(in) :: fmtNum ! How to initialize s to return a format string that can produce same output as a free-format ! in the case the fmtNum does not match a case statement below? s = ????? select case (Language) case (LANG_FRENCH) select case (fmtNum) case (100) s = "('LIGNE = ',I2)" case (200) s = "('COLONNE = ',I2)" end select case default select case (fmtNum) case (100) s = "('ROW = ',I2)" case (200) s = "('COLUMN = ',I2)" end select end select end function sFmt
Here is an example of what I would like to do (of course the formats can be more complex with possible mix of integer, strrings or float values to be printed):
character(len=1024) function sFmt(fmtNum) result(s) use IFWIN use Systools, only: Language implicit none integer(4), intent(in) :: fmtNum ! How to initialize s to return a format string that can produce same output as a free-format s = ???? select case (Language) case (LANG_FRENCH) select case (fmtNum) case (100) s = "('LIGNE = ',I2)" case (200) s = "('COLONNE = ',I2)" end select case default select case (fmtNum) case (100) s = "('ROW = ',I2)" case (200) s = "('COLUMN = ',I2)" end select end select end function sFmt
Thanks Steve, that's exactly what I was looking for. I had already tried but unsuccessfully with *G0 but I forgot the parenthesis and it works better with them !