CALL literal with trailing spaces - does *any* COBOL compiler tries to use these or do they always trim?

GnuCOBOL
2016-08-19
2016-11-13
  • Simon Sobisch

    Simon Sobisch - 2016-08-19

    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, ...).

    End result:

           01  CONST-PROG              PIC X(06)  VALUE 'PROG '.
               CALL CONST-PROG USING STUFF
    

    and

               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 اللغة العربية"?

     
    Last edit: Simon Sobisch 2016-08-19
  • Edward Hart

    Edward Hart - 2016-08-19

    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.

     
  • Bill Woodger

    Bill Woodger - 2016-08-19

    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...).

     
    • Simon Sobisch

      Simon Sobisch - 2016-08-19

      What error is issued for CALL 'PROG ' at compile time?

      Are you sure you would get an runtime error for the follwing code?

      MOVE 'PROG ' TO X5-ITEM
      CALL X5-ITEM
      
       
  • Bill Woodger

    Bill Woodger - 2016-08-22

    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.

     
    • Simon Sobisch

      Simon Sobisch - 2016-08-22

      Hi Bill,
      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?

      Thank you,
      Simon

       
  • Bill Woodger

    Bill Woodger - 2016-08-23

    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).

     
    • Bill Woodger

      Bill Woodger - 2016-08-23

      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).

       
      • Arnold Trembley

        Arnold Trembley - 2016-11-13

        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.

         
        Last edit: Bill Woodger 2016-11-13
        • Bill Woodger

          Bill Woodger - 2016-11-13

          Yes.

          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.

           
  • Ron Norman

    Ron Norman - 2016-11-12

    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.

     
    • Simon Sobisch

      Simon Sobisch - 2016-11-12

      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.

      Simon

       
  • Ron Norman

    Ron Norman - 2016-11-13

    This issue has now been resolved in the reportwriter branch and Simon will merge into 2.0 when he is able.

     
  • Zema Cyrineu

    Zema Cyrineu - 2017-02-15

    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.

     
    Last edit: Zema Cyrineu 2017-02-15

Log in to post a comment.

Get latest updates about Open Source Projects, Conferences and News.

Sign up for the SourceForge newsletter:





No, thanks