E$LNG - Check or Extract Literals
- e$lng pgm(<program>) pgmsrc(<library/sourcefile>)
e$lng pgm(<program>) pgmsrc(<library/sourcefile>) action(*extract) [F4]
- pgm (a10)
- Source file member name of the RPG program.
- pgmsrc (a10/a10)
- Source file name and Library name where member pgm can be found.
- dspfsrc (a10/a10)
- Source file name and Library name where the source of the Display file (DSPF) used by member pgm can be found.
- Value: *PGMSRC [default]
- This value instructs the program to copy the source file name and library name from the pgmsrc parameter.
- prtfsrc (a10/a10)
- Source file name and Library name where the source of the Printer file (PRTF) used by member pgm can be found.
- Value: *DSPFSRC [default]
- This value instructs the program to copy the source file name and library name from the dspfsrc parameter.
- action (a8)
- Action the program should perform.
- Value: *CHECK [default]
- This value instructs the program to check the Display and Printer source file members for changed literals. Use this value before the extraction to see if you made no typing errors.
- Value: *EXTRACT
- With this action the program extracts literals from copies of the Display and Printer source file members and converts them into a field and a message.
- cvtmsg (a7) [only with ACTION(*EXTRACT)]
- Instructs the program what to do with the field that is created to hold the extracted literal at runtime.
- Value: *MSGID [default]
- This value instructs the program to create a field that uses the MSGID keyword. This way you only need one Display and/or Printer file and one Message file per language. For Printer files and Subfiles within a Display file, speciale RPG code is created and inserted in a copy of the RPG source file member to emulate the MSGID keyword, because MSGID cannot be used in these situations.
- Value: *MSGCON
- This value instructs the program to create a field that uses the MSGCON keyword. With MSGCON, the field will be replaced by the text from the message file at compile time. This way you need a DSPF-object library per language a message file per language.
- genlib (a10) [only with ACTION(*EXTRACT)]
- The name of the library where E$LNG can create Source files for the modified Source file members. The following Source files will be created:
- This Source file holds the modified RPG source file member, when appropriate. The RPG source file member will only be modified when you use a Printer file or when you use Subfiles within your Display file. You should always compile this member when present, and not the original.
- This Source file holds converted Display source file members (DSPF). You should always compile this member and not the original.
- This Source file holds converted Printer source file members (PRTF). You should always compile this member and not the original.
What it does
The processing program reads the RPG source file and searches for WORKSTN and PRINTER definitions in the F-specifications. When found, the program creates a copy the Display file or Printer file in E$DSPFSRC or E$PRTFSRC and starts to search for literal text, which is text defined between apostrophs:
- 'This is literal text'
It also processes the continuation character (-) when the literal text is spread over more than one line:
- 'This is literal text which is spr-
- ead over more than one line.'
The source lines are removed and replaced by a source line which contains a field definition of type A with the length of the literal text and a MSGID or MSGCON keyword, whatever you chose:
- A E#0001 061 O 23 12MSGID(PKG0001 SCREENMSGF) OVRDTA
The literal text is stored in the file E$LNGREF in your development library for future reference. Each time you make changes to the display file or printer file and run it through E$LNG, E$LNG first checks in file E$LNGREF if the literal text it extracted is already there. When it is, E$LNG uses the existing Message Identifier.
Notice the OVRDTA keyword. It is automatically added when the record level PUTOVR keyword is specified. If you also specified OVRDTA at the record level, the addition of OVRDTA by E$LNG is ignored by the DDS compiler.
Not all literals are extracted and converted to fields, because it is sheer nonsense to translate a '/' from English to French or so. So only words or phrases that contain any of the following characters are extracted:
Note that trailing blanks do not belong to the literal itself, but are counted only for the length of the field to create. So the literals:
- 'File '
result in one definition in E$LNGREF of the word 'File'. The shortest length is saved, because if E$LNG would make you think you have enough room to translate 'File' to 'Dossier', you're mistaken. In the 'File' situation, you would see 'Doss' in your program's screen, because you have not reserved enough space, like with 'File '.
When the literal text is completely new to E$LNG, it first retrieves the next message identifier from file E$LNGDT1 in your development library. It then reads the file E$LNGDT2 in the program object library of your software package for defined languages and stores a new message for every language in the message file defined in E$LNGDT1. So, if you care, you examine your display files before you start an extraction job and search for words that are misspelled or shortened. Often you see situations like:
- 'company . . . :'
All these words mean the same. And E$LNG is case sensitive. You should resolve these kind of words to more clearer versions, or even better, to only one word which is the same in all programs.
For subfiles and printer files that contain literal text to be extracted with the MSGID keyword, RPG source code is generated to load the fields with the text from the message file. Instead of a source line with the MSGID keyword, which is not possible in these situations, the following line is created in place of the literal text:
- A E#0092 003 O 14 11TEXT('PKG01AE SCREENMSGF')
- A E$0092 003 O 14 11TEXT('PKG01AE SCREENMSGF')
The #-sign is used in display files and the $-sign in printer files.
A separate source member is created with the necessary RPG code to load these fields. The name of this member is the name of the RPG program with 'E$' as prefix. The original RPG source member is copied to E$RPGSRC and modified to include the generated RPG code with /COPY and code is added to execute the routine in this E$-source member.
You can modify the behaviour during a run by coding E$LVL keywords in your display files and printer files. The default level of extraction is *PKG (Package). It is the 'highest' level. At the highest level, a literal text that is used more than once, even in other sources within your software package, is only stored once. This way, when you alter this text, the change is visible at once in all programs that had this same text on their screens. That is the power of E$LNG.
The following values apply to the E$LVL keyword:
*PKG Highest level *PGM Program context level *LIT Literal context level *END End further extraction in the Display file or Printer file
There are times that a word spells the same through different programs but that it's context is completely different. And so different, that in another language you will really need two different words. In this case you can opt for the following:
- Look for a different word to reflect the context in your own language.
- Insert a E$LVL keyword with another level (*PGM or *LIT) just before the literal:
Notice that the E$LVL keyword is specified in a comment line. That is because it is not a genuine DDS keyword, but it must be positioned at exactly the same starting position of DDS keywords.
These level names mean nothing but are the only three programmed in E$LNG and give you the possibility to separate identical literals from some general context. The level switch is used once per literal. As soon as the literal is extracted and converted, the program switches back to level *PKG. That means you have to add an E$LVL keyword for each literal you want to have another context than *PKG. These other levels are also 'package-wide', which means that if you have the word 'file' in source A with E$LVL(*PGM) and in file B too with E$LVL(*PGM), E$LNG stores the literal only once and assumes the context is the same in both sources. If it is not, you can leave one 'file'-word at E$LVL(*PGM) and change the other to E$LVL(*LIT). This way you will have three different contexts, three different translations, of the word 'file' with message identifiers like PKGxxxx, PGMxxxx and LITxxxx.
Another situation is when a Printer file (or Display file) already contains foreig language texts. You don't want these texts to be extracted, because you don't need to translate them. So that's where the value *END is for. Wherever you put it in a Display file or Printer file, as soon as E$LNG detects this value, it stops further extraction for that source member.
Here's the original display file in QDSPSRC (or QDDSSRC):
Here's the converted display file in E$DSPFSRC:
And here are the contents of the Language messagefile:
Go to download page