The following error occured in a production environment after a "minimal update":
some.cbl:3588: libcob: Cannot find module 'PROG '
It took me about an hour to find the problem ias I've checked for the wrong issues (file exists, access is granted, ...).
01 CONST-PROG PIC X(06) VALUE 'PROG '.
CALL CONST-PROG USING STUFF
CALL 'PROG ' USING STUFF
are NOT the same in OpenCOBOL/GnuCOBOL. Trailing spaces from variables are trimmed, trailing spaces from a literal are not.
Doesn't look very COBOL-like to me.
Can you please check on the standard on this (the only thing I've found is about user-defined words) and with other compilers how they behave?
GC2 will either get a warning or remove the trailing spaces.
What do the standard and ohter compilers say about CALL "WHO DOES THIS" USING STUFF / CALL "UTF-8 اللغة العربية"?
CALL "WHO DOES THIS" USING STUFF
CALL "UTF-8 اللغة العربية"
The standard and the Enterprise COBOL docs says that the literal/identifier must be the program-name. This suggests any extra spaces cause an error.
The Visual COBOL docs say the literal/identifier must contain the program-name, which might mean they trim the given literal/identifier before using it.
I think this issue should be referred to the standards committee for clarification.
Space is not valid in a program name. With Enterprise COBOL you get a compile error for a literal containing a space (anywhere) and for a data-name, you'd get a runtime error because the module would not be found (on z/OS anyway).
This is not specified as at variance to the 1985 Standard.
There is a compiler option PGMNAME, which has a MIXED parameter, which allows any value in the range X'41' to X'FE' for each byte of the name. This affects the PROGRAM-ID (and if you want to use the program somewhere else...).
What error is issued for CALL 'PROG ' at compile time?
CALL 'PROG '
Are you sure you would get an runtime error for the follwing code?
MOVE 'PROG ' TO X5-ITEM
Sorry Simon missed this.
Yes. I don't use CALLdata-name (there is a compile option to get a dynamic CALL) so I had to check. It fails.
I may check some more.
please do further checks:
MOVE 'PROG' TO X4-ITEM
CALL X4-ITEM *> works?
MOVE 'PROG ' TO X5-ITEM
CALL X5-ITEM *> fails? what error message?
MOVE 'PROG' TO X5-ITEM
MOVE x'00' TO X5-ITEM (5:)
CALL X5-ITEM *> fails? what error message?
CALL 'PROG' *> works!
CALL 'PROG ' *> fails on compile time? what error message?
What of these parts depend on a compile time option? Which?
Can you point out the specific parts in the documentation covering this?
X4-ITEM works (expected).
X5-ITEM with one trailing blank, works (expected really, explanation shortly)
X5-ITEM with on trailing binary zero, fails (S806 system abend, "can't find module")
'PROG' compiles and works (expected).
'PROG ' fails to compile, IGYPS0025-E Name "'PROG '" was invalid. It was processed as "PROG".
Enterprise COBOL does nothing with the content of the data-item for a dynamic call. The compiler "pads" to eight bytes when the data-item is shorter than eight bytes. It is then up to the run-time program loading as to whether the CALL succeeds or not.
For the CALL 'literal', the compiler normalises to eight characters after verifying. So the item actually has trailing blanks for the CALL, even if they are rejected by the compiler when explicitly specified.
If you have some code which was working on a Mainframe and which doesn't work with GnuCOBOL then either: a) it wasn't running on an IBM Mainframe (maybe a Midrange/iSeries/AS/400, or a non-IBM Mainframe); b) they were running executables with E-level errors (highly unusual, but possible, it would work for this type of case); c) perhaps a much older IBM compiler behaved slightly differently (OS/390 COBOL or OS/VS COBOL II) - possible, but it should be covered in a Migration Guide if so (I haven't looked yet); d) perhaps Micro Focus Mainframe-like issue?; e) something else without enough information to guess.
In summary: the Enterprise COBOL run-time (actually it is a separate multi-language run-time, Language Environment) does nothing but pass on the eight-character name to the program-loading process; the compiler "pads" where necessary either a data-name shorter than eight or a literal - all CALLed programs will appear to the run-time as eight bytes with trailing blanks where necessary.
Compiler option DYNAM/NODYNAM controls whether a CALL "literal" is a dynamical or static call. All CALL data-name are dynamic.
If data-names used for CALLs are actually "constants" (VALUE clause and not the target of anything) and the OPTimizer is used, and DYNAM is used, then effectively the CALL data-name is treated as CALL "literal" with the literal being the content of the data-name, normalised to eight bytes if necessary.
CALL "PROG " should not compile without a diagnostic. Normally the level of diagnostic would prevent the preparation of the executable program (compiler would give a return-code of eight, normally linkedit/binder will only execute on return-code of four or lower (but this is just a setting in the JCL, so can be changed).
Forgot about the question on the documentation. Other than what I've already listed, it is not documented in the Enterprise COBOL manuals. I suspect that there is little in the Standard either, because it is so implementation-dependent. This does lead to the opportunity for interpretation amongst vendors. The correct formation of library members is documented elsewhere in IBM manuals. Their formation is independent of COBOL, but I suppose COBOL may have influenced things originally (you'd not want to limit your library members to things which excluded valid names in COBOL).
The way I remember it is that all member names (program names) in IBM PDS libraries (Partitioned Data Sets) were 8 bytes long. So if a PDS member name was shorter than 8 bytes it would be left-justified and padded with spaces on the right in the PDS directory. If we put a program name into a COBOL variable, the variable was always defined as PIC X(08), and we treated it as left-justified and padded with spaces. Certainly leading spaces or embedded spaces would not work in IMM MVS/OS390/zOS PDS member names or IBM COBOL program names.
To add a few things.
If using a data-name, the length does not actually matter - the compiler will pad/truncate as necessary (can be extra code generated, executed for each CALL).
The compiler "translates" so that any lower-case in the data-name becomes upper-case (although probably 99.9% of people using a data-name for the CALL are probably typing it in upper-case anyway). Does GnuCOBOL do that for "IBM conf"?
Long PROGRAM-ID and names in CALLs are now allowed. These obviously don't reference traditional loadmodule members in a PDS. Can be either UPPER or MIXED, the latter presumably not translating to upper. Mmm.... must look at that.
The problem here is in the routine cb_encode_program_id of typeck.c.
When CALL " literal " is being used, the spaces are handled as random characters and emited as _ hh where hh is the hex value. 20 is a space.
This routine should certainly remove trailing SPACES or even better just skip SPACES completely.
A simple fix.
You are allowed to do CALL myfield where myfield contains the subroutine name and SPACES and the SPACES do get ignored in that case.
I don't think that leading spaces will be removed, will they? Therefore I think that the best option is a check + a warning "%s literal includes leading/trailing spaces" where %s can be CALL or PROGRAM-ID.
"%s literal includes leading/trailing spaces"
This issue has now been resolved in the reportwriter branch and Simon will merge into 2.0 when he is able.
The difference is that if you call a program by literal, the called program will be 'linked' in the same .exe code. If you call from a variable, it will be not linked and the called program will be dynamically executed. When you compile, your compiler knows where is the called program. When you execute using the dynamic way, the called program must be in one defined path way.
Log in to post a comment.
Sign up for the SourceForge newsletter:
You seem to have CSS turned off.
Please don't fill out this field.