Welcome to the Fourth Issue of the C/370 Newsletter

IBM Corp 1993

                  370 370 370 370 370 370 370 370 370 370
              370 370 370 370 370 370 370 370 370 370 370 370
              370 370 370 370 370 370 370 370 370 370 370 370 370
         370 370 370 370 370 370 370 370 370 370 370 370 370 370
         370 370 370 370 370 370 370 370 370 370 370 370 370 370
         370 370 370 370 370 370 370 370 370 370 370 370 370 370
         370 370 370
         370 370 370
         370 370 370
         370 370 370
         370 370 370 370 370 370 370 370 370 370 370 370 370 370
         370 370 370 370 370 370 370 370 370 370 370 370 370 370
         370 370 370 370 370 370 370 370 370 370 370 370 370 370
             370 370 370 370 370 370 370 370 370 370 370 370 370
             370 370 370 370 370 370 370 370 370 370 370 370
                  370 370 370 370 370 370 370 370 370 370

C/370(TM) Compiler News

December 1993 Volume 1 Number 4


Table of Contents

Welcome to the Fourth Issue of the C/370 Newsletter

  • In This Issue
  • C/370 and MVS/ESA 4.3 OpenEdition Services
    Portability
  • Identifiers
  • Mapping Variant Characters for C/370
  • Displaying Hexadecimal Values
  • Displaying When Using XEDIT on VM
  • Displaying When Using ISPF
  • Using The CBRACKET Macro
  • Procedure for Mapping on 3279
    You ask, we answer
    Missed our Previous Editions?
    A word from your editor
    Coming Soon
  • Reader's Comment Form

  • Welcome to the Fourth Issue of the C/370 Newsletter

    This issue represents the last issue for 1993. We have managed to keep it going for a full year thanks to your support. It's been quite a year for all of us involved in bringing C/370 to you and 1994 appears to be just as busy. Thanks for using C/370 in 1993 and all the best from the C/370 Team to you in 1994.

    In This Issue


    C/370 and MVS/ESA 4.3 OpenEdition Services

    In case you haven't heard the announcements, or seen the presentations from our friends in the Large Scale Systems Division (LSCD) on the exciting news for MVS/ESA OpenEdition Services, here's it is:

    We announced in February 1993 that in March 1994, support for the MVS/ESA 4.3 OpenEdition Services would be provided with the then-current levels of the AD/Cycle ® C/370 Compiler and AD/Cycle Language Environment/370, or their equivalent.

    What does this mean to you as a C programmer? Whether or not you are using C on other POSIX (TM) platforms, such as AIX/6000 or UNIX (TM) , you will see a number of benefits. We can't tell you all the details now, so stay tuned for further announcements. We can tell you that the MVS/ESA OpenEdition Services together with the C/370 support will provide you with the following highlights:


    Portability

    Identifiers

    The following table shows the maximum number of characters that are significant for identifiers in the different IBM C Products:

       C Product    Internal Identifiers  External Identifiers
    
       C/Set++ (TM)        255                   255
       XL C/6000           250                   250
       C/400               255                   255
       C/370               255                   255
    

    The minimum length of internal identifiers is 250 and the minimum length of external identifiers is 250. Longer identifiers may be truncated and this truncation may make two identifiers look the same, even if you wanted them to be treated as distinct. If you want your code to be portable on IBM platforms, you should not give internal identifiers the same first 250 characters Similarly, no two external identifiers should have their first 250 characters the same.

    Note: If you compile your C source code with the NOLONGNAME option on the 370, your external identifiers will be truncated to 8 characters and uppercased. You should always compile your code with the LONGNAME option if possible, since it is very difficult to write external identifiers that are all distinct in the first 8 characters.

    If you need to refer to external identifiers with special characters that are not valid in identifiers (such as @), you can use the #pragma map directive. For instance, if you have an OS linkage function that is called @@FRED, you can code the following:

      int __FRED(int, const char*);    /* prototype for @@FRED */
      #pragma map(__FRED, "@@FRED")
      #pragma linkage(__FRED, "OS")
    

    If you want to refer to @@FRED you could code it as follows:

      int x;
      x = __FRED(1, "Hello there");
    

    Mapping Variant Characters for C/370

    We know that some of you have had problems entering and displaying characters such as the square bracket characters, [ and ], and the caret character, ^, for the host environment. If you use a programmable workstation or a 3270 terminal you can follow the documented procedures to map the keys on your keyboard to send the correct variant character hexadecimal values to the host system for the IBM compiler. Here are some hints and tips we have gathered to enter and display square brackets on a host editor.

    Displaying Hexadecimal Values

    If you are not sure whether your current keys generate correct hexadecimal values for the C/370 compiler and its library, you can use the following C program to show their hexadecimal values on the display. This program displays the hexadecimal values for the variant characters that your current setup uses and what the compiler and library expect.

    Example

    The following sample program reads the ten characters from the input file MYFILE.DAT and displays the character values in hexadecimal notation. These ten variant characters are selected because they are syntactically important to the C compiler.

    Create a file, MYFILE DAT A under VM/CMS or TSOid.myfile.dat under TSO. You must type them in MYFILE.DAT in this order on one single line and without spaces between them:

    As follows

         \][}{^~!#|
    

    You can use the sample program to display the character values and then reset your environment to generate the codes as shown in the column expected by the compiler. Consult your system programmer for the code page that your installation uses. After re-editing your input file, you can run this program again. If you are running under TSO, the data file containing the ten variant characters is TSOid.myfile.dat.

    #include <stdlib.h>
    
    void read_user_data(char *, int);
    
    void main() {
      char  *user_char, *compiler_char;
    
      struct variant *compiler_var_char;
      int num_var_char, index;
      char *code_set;
      char *char_names[]={"backslash",
                          "right bracket",
                          "left bracket",
                          "right brace",
                          "left_brace",
                          "circumflex",
                          "tilde",
                          "exclamation mark",
                          "number sign",
                          "vertical line"};
    
      num_var_char=sizeof(char_names)/sizeof(char *);
      if ((user_char=calloc(num_var_char, 1)) == NULL)
      {
        printf("Error: Unable to allocate the storage\n");
        exit(99);
      }
    
      read_user_data(user_char, num_var_char);
      /* managed to read the users' characters from the file */
    
      code_set="default IBM-293";
      compiler_char="\xe0\xbd\xad\xd0\xc0\x5f\xa1\x5a\x7b\x4f";
                                        /* standard compiler code page */
    
      printf("Compiler and library code page is : %s\n\n", code_set);
      printf("                           Variant character values:\n");   printf(" %16s     expected by compiler    your current\n", "");   for (index=0; index<num_var_char; index++)     printf(" %16s  .:       %X                      %X\n",
                 char_names[index], compiler_char[index], user_char
      exit(0);
    }
    
    
    void read_user_data(char* char_array, int num_var_char)
    {
      FILE  *stream;
      int num;
    
      if (stream = fopen ("myfile.dat", "rb"))
        if(!(num = fread(char_array, 1, num_var_char, stream)))
        {
          printf("Error: Unable to read from the file\n");
          exit(99);
        }
        else { ;}
      else
      {
        printf("Error: Unable to open the file\n");
        exit(99);
      }
      fclose(stream);
      return;
    }
    

    Note:

    After executing this program, you can use some of the following procedures to make sure that your special characters on the keyboard generate the hexadecimal values expected by the C/370 compiler.

    Displaying When Using XEDIT on VM

    If you know that the hexadecimal values of the square brackets that you key in are not those accepted by the C/370 compiler as square brackets, you can add SET INPUT commands in your XEDIT profile to convert the hexadecimal values of the keyed-in square brackets to ones that the C/370 compiler recognizes. This conversion will then happen during your XEDIT session. If you know that the square brackets that you key in are written correctly into the source file but are not displayed as square brackets you can add SET OUTPUT commands to correctly display the keyed-in square brackets during the XEDIT session. The following are three samples of XEDIT Profile changes that you can make to make sure that XEDIT writes out C/370 compiler hexadecimal values recognized as square brackets by the C/370 Compiler and displays the [ and ] characters correctly during the XEDIT session.

    Example One (For Keyboard with [ and ] Keys)

    The following can be added to your XEDIT PROFILE if:

    1. Your keyboard has [ and ] keys and it generates code page 37 characters
    2. The [ key generates x'BA'
    3. The ] key generates x'BB'
    4. The C/370 compiler recognizes x'AD' as the [ (code page 293)
    5. The C/370 compiler recognizes x'BD' as the ] (code page 293)
    6. XEDIT displays x'BA' as the [
    7. XEDIT displays x'BB' as the ]
    /*--------------------------------------------------------------------*/
    /* Display: read x'AD' and x'BD' in the source file and display      */
    /*          them as square brackets                                  */
    /*--------------------------------------------------------------------*/
    /*                                                                   */
    /* XEDIT displays x'BA' which is a left square bracket when it       */
    /* encounters x'AD' in the source file                               */
        Address COMMAND 'SET OUTPUT AD' 'BA'x /* Left square bracket */
    /*                                                                   */
    /* XEDIT displays x'BB' which is a right square bracket when it      */
    /* encounters x'BD' in the source file                               */
        Address COMMAND 'SET OUTPUT BD' 'BB'x /* Right square bracket*/
    /*--------------------------------------------------------------------*/
    /* Write: gets x'BA' and x'BB' from keyboard and writes them in the  */
    /*        file as the hexadecimal values that the C/370              */
    /*        compiler recognizes as the left and right square           */
    /*        brackets                                                   */
    /*--------------------------------------------------------------------*/
    /*                                                                   */
    /* XEDIT writes out x'AD' when it gets x'BA' from the keyboard       */
        Address COMMAND 'SET INPUT BA AD'     /* Left square bracket */
        Address COMMAND 'SET INPUT BB BD'     /* Right square bracket*/
    /*                                                                   */
    /*--------------------------------------------------------------------*/
    /* Turn off text and APL characters for this XEDIT session           */
    /*--------------------------------------------------------------------*/
    /*                                                                   */
        Address XEDIT 'SET TEXT OFF'
        Address XEDIT 'SET APL OFF'
    /*                                                                   */
    /*--------------------------------------------------------------------*/
    /*Turn off text and APL characters at CP level for this logon session*/
    /*--------------------------------------------------------------------*/
    /*                                                                   */
        Address COMMAND 'CP TERMINAL TEXT OFF'
        Address COMMAND 'CP TERMINAL APL OFF'
    
    

    Example Two (For Keyboard with No [ and ] Keys)

    The following can be added to your XEDIT PROFILE if:

    1. Your keyboard has no [ and ] keys
    2. You have not remapped @ and $ by using your host emulation software
    3. You want the @ and $ keys to generate square brackets x'AD' and x'BD' during XEDIT
    4. The C/370 compiler recognizes x'AD' as the [ (code page 293)
    5. The C/370 compiler recognizes x'BD' as the ] (code page 293)
    6. XEDIT displays x'BA' as the [
    7. XEDIT displays x'BB' as the ]
    /*--------------------------------------------------------------------*/
    /* Display: read x'AD' and x'BD' in the source file and display      */
    /*          them as square brackets                                  */
    /*--------------------------------------------------------------------*/
    /*                                                                   */
    /* XEDIT displays x'BA' which is a left square bracket when it       */
    /* encounters x'AD' in the source file                               */
        Address COMMAND 'SET OUTPUT AD' 'BA'x /* Left square bracket */
    /*                                                                   */
    /* XEDIT displays x'BB' which is a right square bracket when it      */
    /* encounters x'BD' in the source file                               */
        Address COMMAND 'SET OUTPUT BD' 'BB'x /* Right square bracket*/
    /*--------------------------------------------------------------------*/
    /* Write: gets x'AD' and x'BD' from keyboard and writes them in the  */
    /*        file as correct hexadecimal values that the C/370          */
    /*        compiler recognizes as the left and right square           */
    /*        brackets                                                   */
    /*--------------------------------------------------------------------*/
    /*                                                                   */
    /* XEDIT writes out x'AD' when it gets x'7C' from the keyboard       */
        Address COMMAND 'SET INPUT 7C AD'     /* Left square bracket */
    /* XEDIT writes out x'BD' when it gets x'5B' from the keyboard       */
        Address COMMAND 'SET INPUT 5B BD'     /* Right square bracket*/
    /*                                                                   */
    /*--------------------------------------------------------------------*/
    /* Turn off text and APL characters for this XEDIT session           */
    /*--------------------------------------------------------------------*/
    /*                                                                   */
        Address XEDIT 'SET TEXT OFF'
        Address XEDIT 'SET APL OFF'
    /*                                                                   */
    /*--------------------------------------------------------------------*/
    /*Turn off text and APL characters at CP level for this logon session*/
    /*--------------------------------------------------------------------*/
    /*                                                                   */
        Address COMMAND 'CP TERMINAL TEXT OFF'
        Address COMMAND 'CP TERMINAL APL OFF'
    

    Example Three (For Keyboard with No [ and ] Keys)

    The following can be added to your XEDIT PROFILE if:

    1. Your keyboard has no [ and ] keys
    2. You have remapped @ and $, respectively, using your host emulation software to generate x'AD' and x'BD' which are [ and ]
    3. The C/370 compiler recognizes x'AD' as the [ (code page 293)
    4. The C/370 compiler recognizes x'BD' as the ] (code page 293)
    5. XEDIT displays x'BA' as the [
    6. XEDIT displays x'BB' as the ]
    /*--------------------------------------------------------------------*/
    /* Display: read x'AD' and x'BD' in the source file                  */
    /*          or gets them from the keyboard and displays              */
    /*          them as left and right square brackets                   */
    /*--------------------------------------------------------------------*/
    /*                                                                   */
    /* XEDIT displays x'BA' which is a left square bracket when it       */
    /* encounters x'AD' in the source file                               */
        Address COMMAND 'SET OUTPUT AD' 'BA'x /* Left square bracket */
    /*                                                                   */
    /* XEDIT displays x'BB' which is a right square bracket when it      */
    /* encounters x'BD' in the source file                               */
        Address COMMAND 'SET OUTPUT BD' 'BB'x /* Right square bracket*/
    /*                                                                   */
    /*--------------------------------------------------------------------*/
    /* Set Input is not necessary                                        */
    /*--------------------------------------------------------------------*/
    /*--------------------------------------------------------------------*/
    /* Turn off text and APL characters for this XEDIT session           */
    /*--------------------------------------------------------------------*/
    /*                                                                   */
        Address XEDIT 'SET TEXT OFF'
        Address XEDIT 'SET APL OFF'
    /*                                                                   */
    /*--------------------------------------------------------------------*/
    /*Turn off text and APL characters at CP level for this logon session*/
    /*--------------------------------------------------------------------*/
    /*                                                                   */
        Address COMMAND 'CP TERMINAL TEXT OFF'
        Address COMMAND 'CP TERMINAL APL OFF'
    
    

    Note: You can use QUERY INPUT and QUERY OUTPUT to find out the existing settings for your XEDIT session. You can also create your own EXEC with SET INPUT and SET OUTPUT to clear settings or reset them. :enote.


    Displaying When Using ISPF

    When your PS/2 or 3270 terminal is sending correct hexadecimal values for the square brackets to the host system, you may still find that the ISPF editor is not correctly displaying them when you key them in. The following is a sample ISPF macro that enables you to view the [ and ] characters in text form, trigraph form or hex form, and toggle between the three settings. This macro must be included in a regular CLIST library concatenated to ISPF SYSPROG. The sample macro is named CBRACKET:

    PROC 0
    ISREDIT MACRO
    
    SET RP = &STR())
     /* Symbolic values for 6 C language symbols.
     /* 1. left  bracket, ebcdic hex value
     /* 2. right bracket, ebcdic hex value
     /* 3. left  bracket, trigraph
     /* 4. right bracket, trigraph
     /* 5. left  bracket, square
     /* 6. right bracket, square
    SET LBRACKET_HEX = X'AD'
    SET RBRACKET_HEX = X'BD'
    SET LBRACKET_TRI = &STR(??(
    SET RBRACKET_TRI = &STR(??&RP)
    SET LBRACKET_SQR = [           /* LBRACKET_SQR = HEX AB */
    SET RBRACKET_SQR = ]           /* RBRACKET_SQR = HEX AD */
    
    ISREDIT FIND &LBRACKET_HEX ALL NX
    ISREDIT (N1) = FIND_COUNTS
    ISREDIT FIND &RBRACKET_HEX ALL NX
    ISREDIT (N2) = FIND_COUNTS
    IF (&N1 ª= &N2) THEN WRITE ........UNBALANCED HEX BRACKETS
    IF (&N1 > 0) THEN DO
       ISREDIT CHANGE &LBRACKET_HEX &LBRACKET_TRI ALL NX
       ISREDIT CHANGE &RBRACKET_HEX &RBRACKET_TRI ALL NX
       EXIT
    END
    
    ISREDIT FIND &LBRACKET_TRI ALL NX
    ISREDIT (N1) = FIND_COUNTS
    ISREDIT FIND &RBRACKET_TRI ALL NX
    ISREDIT (N2) = FIND_COUNTS
    IF (&N1 ª= &N2) THEN WRITE ........UNBALANCED TRIGRAPH
    IF (&N1 > 0) THEN DO
       ISREDIT CHANGE &LBRACKET_TRI &LBRACKET_SQR ALL NX
       ISREDIT CHANGE &RBRACKET_TRI &RBRACKET_SQR ALL NX
       EXIT
    END
    
    ISREDIT FIND &LBRACKET_SQR ALL NX
    ISREDIT (N1) = FIND_COUNTS
    ISREDIT FIND &RBRACKET_SQR ALL NX
    ISREDIT (N2) = FIND_COUNTS
    IF (&N1 ª= &N2) THEN WRITE ........UNBALANCED SQUARE BRACKETS
    IF (&N1 > 0) THEN DO
       ISREDIT CHANGE &LBRACKET_SQR &LBRACKET_HEX ALL NX
       ISREDIT CHANGE &RBRACKET_SQR &RBRACKET_HEX ALL NX
       EXIT
    END
    

    Using The CBRACKET Macro

    Follow these steps to use the CBRACKET macro:
    1. Invoke ISPF to edit the C source file.
    2. Run the CBRACKET macro before editing to convert the compiler recognizable hexadecimal values of the square brackets to trigraphs.
    3. Run the CBRACKET macro again to convert the trigraphs to displayable characters.
    4. Edit your C source code.
    5. Run the CBRACKET macro again to convert the displayable characters back to original hexadecimal values.
    6. Save or file the C source file.

    Note: This macro may not need to be used with your host emulation software keyboard remapping. Apply your host emulation software keyboard remap first. If this does not enable correct display of [ and ] on ISPF then try this macro.


    Procedure for Mapping on 3279

    Follow this procedure if you are using a 3279-S3G-1 with ISPF, MVS or TSO. You should have the APL keys on your keyboards.


    You ask, we answer

    These questions are culled from a variety of sources: from various question and answer databases, from customer calls, and from our own experiences.

    If you have a question you like to ask us, have a comment about C/370, or just want to subscribe to this newsletter, please use the Reader's Comment Form at the back of this newsletter.

    Question- How can I share VSAM datasets using C/370 ?

    Answer

    If your cluster is defined with shareoptions 1, VSAM supports multiple readers or a single writer, and ensures read and write integrity.

    If your cluster is defined with shareoptions 2, VSAM supports multiple readers and a single writer, and ensures write integrity. The C/370 library doesn't guarantee read integrity. You can ensure read integrity by writing assembler functions to perform ENQs and DEQs, and calling them from you C/370 program (this is discussed further in the MVS Application Development Macro Reference, and Managing VSAM Data Sets).

    If your cluster is defined with shareoptions 3, VSAM supports multiple readers and multiple writers. Neither VSAM nor C/370 can ensure read or write integrity. But again, you could ensure read/write integrity by writing assembler functions to perform ENQs and DEQs, and calling them from his C/370 program.

    If your cluster is defined with shareoptions 4, VSAM supports multiple readers and multiple writers. Neither VSAM nor C/370 can ensure read or write integrity. But again, you can ensure read/write integrity by writing assembler functions to perform ENQs and DEQs, and calling them from your C/370 program. This is easier to do with Shareoptions 4 because VSAM provides the additional service of updating buffers for each direct request.

    You can issue ENQs and DEQs against the data set name. C/370 does not use Control Interval Access, so ENQ'ing on the CI wouldn't be useful. ENQ'ing on the record key could potentially result in a loss of data if two writers attempt to write two different records into the same CI at the same time. If you are working with a PATH to an AIX, try ENQ'ing on the Base Cluster name, and once that ENQ is successful, ENQ on the PATH name.

    Question- Strange compile error ...

    Can anyone explain what this error message means? I can't find it in any of my manuals.

    ERROR EDC1301 Spill size for function bfssdelf must be greater than 272
    
    My listing shows a complete list of the source code, with no errors of any sort, and the error summary followed by this message. The assembler listing (though requested) is not present. Optimization was set to level 2.

    Answer

    According to the CC HELPCMS file ( same applies to MVS ) SPILL is a compiler option.

    SPill(size)
         SP(128) is the default.  SPILL specifies the maximum size the
         spill area can be.  You will receive a compile-time message if
                             ------------------------------------------
         you need to specify this option.
         -------------------------------
    

    Using this compiler option should clear up this error message.

    Question- Concatenation of 3 partitioned datasets

    I am trying to concatenate 3 partitioned datasets with include files on the SYSLIB statement of a compilation:

      //COMPILE EXEC PGM=EDCCOMP,REGION=1536K,COND=(8,LE),
      //  PARM=(SOURCE,LONGNAME,NOSEQUENCE,NOMARGINS)
      //STEPLIB   DD DSN=SYS1.EDC.SEDCLINK,DISP=SHR
      //          DD DSN=SYS1.PLI.SIBMLINK,DISP=SHR
      //          DD DSN=SYS1.EDC.SEDCCOMP,DISP=SHR
      //SYSLIB    DD DSN=SYS1.EDC.SEDCHDRS,DISP=SHR
      //          DD DSN=NSPCICS.C.H,DISP=SHR
      //          DD DSN=NSPCICS.KK.C.H,DISP=SHR
    etc.
    
    This gets me the following error message:
    
         131       |#include <kk.h>
       *=SEVERE==========>     EDC0901 Unable to read DD:SYSLIB(KK).
    

    The kk.h file is in the 3rd SYSLIB dataset. The datasets have different record lengths. The first one is FB,80,3120 and the other 2 are VB,104,3120. Changing the record format of the latter 2 datasets to FB,100,3120 did not help. Only changing them to exactly the same format as the first dataset (FB,80,3120) did help.

    I don't like changing to FB,80, because this is one of many programs that I am migrating to MVS, with lots of lines longer than 80. I know that the #include <kk.h> should really be #include "kk.h", but again, I would rather not change all of the occurrences throughout the code. Any hints or tips on how to solve this problem?

    Answer

    You have discovered that the datasets must have the same characteristics in order to be used in a concatenation. This is not a C restriction, but an MVS restriction.

    You will probably have to remove the dataset from the concatenation and use the SEARCH option to find it.

    Question- SQL Calls in C/370

    I need to know whether I can imbed SQL calls in c/370.

    Answer

    SQL statements can be imbedded in C programs. The SQL translator converts the statements into C code which performs the assignments and calls a database language interface module.

    Question- Reading a line that has "\n" (hex 15) in it.

    I'm writing a program to read another program's output, a bunch of structures with each structure taking up a line. Unfortunately some of the structures have hex 15, which is \n, in them. This causes FGETS to think that the line has stopped and therefore I get only part of the line that I need. Is there any way around this problem? I cannot use scanf() because I don't know which structure I'm reading ahead of time and can't specify the format.

    Answer

    Use fread(), which is meant for binary files. The C/370 Programming Guide explains this in Chapter 24 (Record I/O).

    Question- __4kmalc()

    Page 466 of the Programming Guide (V2R1) states that the __4kmalc() memory management function is available only in the systems programming environment.

    I have a C source file that contains normal C functions called by a main function and system exit routine functions called as I/O interrupt handlers. The system exit routines are defined with the #pragma environment directive.

    I want to use __4kmalc () from both the normal functions and the system exit routines. Can I?

    If I include EDCXMEM TEXT in the module, will the systems programming versions of the other memory allocation functions (like malloc() and free()) work in the normal C functions as well?

    Answer

    You cannot mix the SPC memory functions with the Common Library or AD/Cycle Environments. The control blocks that define the environments are different.

    If you try to allocate the memory in the function (coded as SPC exit) and pass it to the Common Library main(), you get in trouble as well: the SPC environment is established at entry to the function and taken down when you leave it. Thus allocated memory is freed, and you might be passing something that you do not own.

    Consider using the persistent environment concept to do what you want. Your main() with its Common Library environment could call EDCXHOTC and establish an SPC environment for your exits. Then use EDCXHOTU to call the functions. One of these functions could allocate the storage using __4kmalc() and you could pass a pointer to the storage back to your main(). Before you terminated the main(), you could call EDCXHOTU for a function that frees the storage and then call EDCXHOTT to kill the SPC environment. Performance should be improved this way if you call more than one exit.

    Question- Dynamic calling

    I need to know how to dynamically call a C/370 program (MVS) that resides in a separate load module. I have reviewed the manuals, and cannot find out how to do this. Could you tell us how to do it, or give us the manual number/page # that tells us how?

    Answer

    Use a system() call. Make sure that the load module is in the STEPLIB. See page 411 in the V2R1 Programming Guide. (SC09-1384-00)

    Question- Errno

    If I want to interrogate the errno value, can I just do an if check on the field errno? That is , can I do the following?

              .
     int testvalue=4;
              .
     if (errno == testvalue)
              .
    

    Answer

    Yes.

    Question- Record I/O with C/370

    I am trying to read a recfm=VB file. I would like to know where records end and begin. If I uses fopen(file ,"r,recfm=VB"), and fread(buffer, 1, rec_size, file)... I get the number of characters I requested.

    Is there any way to use C/370 with record I/O? I'd like to know what the actual record length is of the record I've read.

    Answer

    Use fopen(file, "rb,type=record"). For record I/O, you need to open the file in a binary mode, i.e., "rb". Since you're opening for read, fopen() will figure out that the file is recfm=VB, so you don't have to mention it.

    Then call fread(buffer, 1, rec_size, file). This will return the number of bytes in the record read. The next fread() will get the next record and so on. fread() doesn't add a null at the end of the record, so if you want to treat the record like a null-terminated string and the records on the disk aren't null terminated, make the buffer big enough and add a null yourself.

    Question- SAA AD/CYCLE C/370 prelink ends with a warning

    I have MVS/ESA SP 4.3, CICS/ESA 3.3, SAA AD/CYCLE C/370 V1R1, LE/370 V1R1M1 installed and running.

    When I compile any batch C program, I get a warning at the prelink step. The Installation Guide says that the prelink IVP will give that warning and it is not an error. I am still worried and expecting a good explanation if it is really ok to get that warning at the prelink step.

    Warning EDC4015: Unresolved References are detected:
    CEEBETBL EDCROOT DFHEXEC CEESG003 @@TRT STRNCPY SPRINTF
    

    Does anyone know what is causing this warning and how it can be fixed?

    Answer

    When you prelink, you are prelinking only your own code, not your code as well as library code. Some of the unresolved references are to general library code (those routines starting with CEE and EDC) as well as C/370 library routines (SPRINTF, STRNCPY). @@TRT is a table used by the C/370 compiler for certain functions.

    Question- Access to TTIME

    I am writing a transaction control program for a service machine on VM/ESA. This program is written in C/370. It needs to access the system TTIME for billing purposes. Because the control program is complex, I don't want to write the whole thing in assembler.

    The most efficient way that I can see to do this is to call an external assembler routine that issues a DIAG C and stores two integers in locations provided by the C caller. I am assuming that this will give me the information that I need with the minimum of runtime overhead.

    My problem is in creating a MODULE that will run on VM/CMS. I compile and link according to the book but the module will not run. I have included my console session below. Testasm is the C/370 mainline that calls the ttime routine, which is written in assembler. The ttime routine has been previously assembled into a TEXT deck by the assembler programmer. The mainline routine uses #pragma linkage(TTIME, OS).

    ----------------------console file------------------------------------------
    Ready; T=0.01/0.01 16:13:17
    compile testasm
    Compiling C program TESTASM
    Compile completed with return code 0
    Ready; T=0.29/0.43 16:13:22
    global txtlib edcbase ibmlib cmslib
    Ready; T=0.01/0.01 16:13:37
    load testasm ttime (clear rld reset ceestart
    Ready; T=0.01/0.02 16:13:52
    genmod testasm (from ceestart
    Ready; T=0.01/0.01 16:14:01
    testasm
    IBM004I PROGRAM TERMINATED, USER CODE = 2052
       DURING INITIALIZATION.
    IBM019I . NO SUITABLE DUMP FILE DEFINITION
    DMSABE155T User abend 2052 called from 00079DE2 reason code 00000000
    CMS
    ----------------------------------------------------------------------------
    

    Any help would be appreciated.

    Answer

    On page 156 of the V2R1 manual, you will find a description of error codes from C/370. A 2052 means you have an AMODE 24 program and the library is loaded above the line. You can fix this by either

    Question- How do I preserve case between REXX and C/370?

    I am calling a C/370 program from a REXX program. I am passing mixed case parameters with the ARGV parameter to the C program. The first thing the C program does is display the ARGV, and it is all in lower case. This application is case-sensitive, and needs these parameters to be in their original state when sent to the C program. How can I do this?

    Answer

    When a CALL command invokes a C program the arguments are passed as lower case. This is done to comply with ANSI. If you wish to pass mixed case, you can specify the option 'asis' in the CALL command. A table is given on page 136 of the IBM C/370 Programming Guide, SC09-1384-00 describing the cases of passed arguments.

    Question- Command line parms

    Is there any way to access the unparsed command line (what reg 1 points to when CEESTART is called)? I have a program that has some significant whitespace in the parameter list, and I don't want it parsed. This program is loaded and called by another program (SCLM), so I can't change the parm list or add quotes around it.

    Answer

    Try using '#pragma runopts(noargparse)'. This runtime option disables argument parsing. It is described in the V2R1 programming guide on page 361.

    Question- Fetching from system exits

    I have an MVS subtask written as a C/370 system exit routine (page 478), and attached with the MVS ATTACHX macro. I also have a reentrant C module, which has writable static and must be able to be loaded from a normal C main program or an MVS subtask.

    The problem is that the fetch() function is not supported in a systems programming environment (page 467). I assume it is the fetch() library function that would allocate the writable static for the loaded module.

    The reentrant module is compiled with the RENT compile-time option, prelinked, and then linked to create the load module. When I issue the MVS LOAD macro from a normal C main program, the loaded reentrant module seems to get some C/370 heap storage where it expects to find its static strings. (A pointer to a string constant instead points to the characters "FREE", which looks like an malloc header.) I use a function name as the entry point of the load module.

    What can I do to load a reentrant module with writable static from an MVS subtask? Page numbers refer to the IBM C/370 Programming Guide Version 2 Release 1.0.

    Answer

    You are correct about fetch() performing the allocation of your writable static. What happens when you just load it is that your generated code is expecting to find the address of writable static off of R12. It has offsets it expects from certain variables (including strings not compiled with #pragma strings(readonly)) and since you have no writable static set up, it won't work.

    What you might try is building the routine you want to fetch as a main() and linking it as a fully operational C module. You can then system() call or LINK the module. This will transfer control to normal initialization which will allocate the writable static. To pass parameters other than char strings, use the LINK macro and on the other side, use __sysplist to access them. You also have to specify NOREDIR and NOARGPARSE as runopts to prevent inadvertent parsing of your arguments.

    Question- DEF text folding to lower case

    My C source under MVS passes a compile option "DEF(MACH_TYPE=MVS_AUSSIM)" in uper case. When I compile this source, the option is converted to lower case, which is not what I want. Is there a way to control the DEF text so that it gets folded UP?

    Here are the contents of my CLIST used to compile the C source:

    CC 'ECSUID2.TEST.C(CHIPROOT)'     +
       OBJ('''ECSUID2.AUSPUDV.OBJLIB(CHIPROOT)''')     +
       COPT('LANGLVL(ANSI),DEF(MACH_TYPE=MVS_AUSSIM),+ <===Entered upper==
       MARGINS(1,80),NOSEQ,GONUM,XREF,SOURCE,TEST(ALL)')
    
    Here is the C listing, showing the options used by the CC compiler:
    
    15688187 V2 R1 M00 IBM C/370                        ECSUID2.TEST.C(CHIPROOT)
    
      Command options:
         Program name. . . . . . . . . : ECSUID2.TEST.C(CHIPROOT)
         Compiler options. . . . . . . : *GONUMBER   *NOALIAS    *NODECK     *NORENT
                                       : *XREF       *NOAGGR     *NOPPONLY   *NOEXPM
                                       : *NOCSECT    *NOLONGNAME *START
                                       : *TARGET()   *FLAG(I)    *TEST(SYM,BLOCK,LIN
                                       : *NOINLINE(AUTO,NOREPORT,250,1000)   *NESTIN
                                       : *NOCHECKOUT(NOPPTRACE,PPCHECK,GOTO,ACCURACY
                                       : *           NOEXTERNAL,TRUNC,INIT,NOPORT,GE
                                       : *NOSEARCH
                                       : *NOLSEARCH
                                       : *OBJECT
     ===Folded to Lower=========>      : *DEFINE(mach_type=mvs_aussim)
         Language level. . . . . . . . : *ANSI
         Source margins. . . . . . . . :
           Varying length. . . . . . . : 1 - 80
           Fixed length  . . . . . . . : 1 - 80
         Sequence columns. . . . . . . :
           Varying length. . . . . . . : none
           Fixed length. . . . . . . . : none
    

    As you can see the DEFINE text is being changed to lower case by the CC compiler (or the CLIST) !!!!

    Answer

    This behaviour is the result of several factors.

    The solution in your example is to provide the arguments in mixed case: def(MACH_TYPE=MVS_AUSSIM). When the C runtime gets the mixed case arguments, it knows that they were actually typed that way and leaves them alone.

    Question- Multiple Memory files

    I would like to know whether multiple C memory(hiperspace) files can be opened in one application. For instance, FILE *fp1 = fopen("file1", "w, type=memory(hiperspace)"); FILE *fp2 = fopen("file2", "w, type=memory(hiperspace)"); and so on. On the C/370 prog. guide manual (SC09-1384-00) it references to the following: Page 219, memory files in HS, the last sentence says: "More than one stream cannot be opened to a HS memory file" I do not really understand if I can or can not do the above.

    Answer

    The documentation is referring to multiple streams opened to the same hiperspace memory file. Multiple hiperspace files are allowed.

    Question- Porting a C program to the mainframe

    I am trying to port a C program written for the PC to the mainframe. I'm using the AD/Cycle C/370 compiler (5688-216) under MVS. I have several questions that have resulted from my efforts to accomplish this migration.

    1. Calling C from a COBOL program. Can this be done using VS/COBOL? Is it supported, or do we need to use a newer version of the COBOL compiler?

    2. I have used both '//' and '/*' to identify source code comments. I think that only '/*' is acceptable in C/370 and that I have to alter the original programs to use only '/*' to achieve portability-without-pain. Is this correct advice, or is there a way to use '//' in the C/370 world?

    3. I encountered problems with long names (labels, etc.) that were truncated when compiled with C/370. Do you have any recommendations about this?

    4. There is a general class of problem related to translation and use of special characters. Some of these were a result of the upload and translation approach they used. But I am still wrestling with a problem related to the use of square brackets not translating correctly. Is there a preferred tool/approach for uploading and translating C code (I used ISPF)? Is there an acceptable (and displayable) set of characters (or multi-character representations) for things like square brackets?

    Answer

    1. Calling C from COBOL can be done providing you relink the application with LE/370. There are some migration issues that you need to consider. See the COBOL manuals for details.

    2. // can be used together with /* if you specify the SSCOMM compiler option.

    3. You can use long names in mixed case up to 255 characters long when you specify the LONGNAME compiler option. In this case, you must also use the prelinker utility before you link application. You may also need to use the object library utility to maintain the objects that were created with the LONGNAME compiler option. This is described in the AD/Cycle C/370 programming Guide, pub# SC09-1356-01.

    4. There is a C/370 Code Point Mapping table in the book referenced in point 3. You should use this table to modify the translate table used in your upload routine. There are many ways to upload text files from PC to MVS, so we cannot be specific in terms of exact procedure needed to modify the translate table. If you use a correct translate table, you can compile the uploaded source code successfully on MVS. However, not all characters will be readily visible on the ISPF/PDF screen, as they are treated as non-display characters. Since non-display characters cannot be manipulated with ISPF/PDF, it will be difficult to maintain such source code. The remedy may be to use trigraphs instead of those characters that will not appear as display characters on MVS, or to use a PC- based emulator to dynamically change the code points of these characters for the duration of display, so they can be manipulated by ISPF/PDF. The trigraphs are described in the C Reference - Level 2 pub# SC09-1308-02 on page 19.

    Question- Performance Problems

    I am having performance problems with a new system I am now stress testing. BSAM appears to be used as the access method for many files. Our performance monitors show that we are waiting 11-17 percent of the time in BSAM's CHECK module.(IGG019BB) We would like to improve the performance on these files by buffering. Do you know why BSAM was chosen by C/370 as the access method?

    The customer coded fopen() and fread() (with a BUFFER_LEN).

    Answer

    Support for file repositioning is the reason for selecting BSAM as the access method. QSAM access method is preferable for performance critical applications, but it is not currently supported by C/370. However, we have an outstanding requirement to add the support for QSAM access method in a future release of C/370.

    Queston- Forcing an abend

    I want to find a good way to force an abend in a C/370 program that does DB/2 calls so that DB/2 will back out to the beginning (or an explicit commit). I tried the abort() library routine, but that didn't work-it apparently doesn't cause an actual abend. Is there a way to force an abend in a C/370 program if a certain condition is detected by the program?

    Answer

    An ABEND is something we generally try to avoid, but if you wish to force one, you can use the following. For the runtime options , select NOSTAE to stop the attempt to generate a diagnostic message and a CEEDUMP when the abend occurs. There will be no attempt to close files and terminate the environment. Selecting NOSPIE lets the program interrupts be interpreted as abends. A simple way to generate an abend is to issue a divide by zero. Do not select OPT(2), and issue the following:

                 a=0;
                 b=2;
                 c=b/a;
    
    The compiler should not detect the divide by zero at compile time.

    Question- CICS & C/370

    We are using the CICS translator for C/370 on multiple source files. The translator is creating EIB declarations in each file so we are getting duplicate reference warnings for these variables at link time. Is only one set of EIB declarations necessary for each load module? If so I can prevent the other copies from being compiled by defining a __dfheitab constant to the C compiler. If each compile unit needs its own EIB declarations they should be declared with static scope.

    Answer

    There is only one EIB per CICS transaction. It is not part of the program, but is created by CICS. Addressability to it is provided by CICS. The translator inserts definitions (DSECT) of the EIB in your program. This is not allocated storage, but definitions of external data.

    C/370's addressability to the EIB is not automatic as in other languages. It must be established by the program with an EXEC CICS ADDRESS command. This will return the address of the EIB which you use as a pointer.

    In your load module, each of the separately compiled modules must use the same pointer value. You must either pass this value or make it a global variable accessible to all of the modules.

    If the pointer name used in the separate modules is different, you must ensure that the VALUE is the same.


    Missed our Previous Editions?

    If you did not get a copy of any of our previous editions, just let us know and we will be more than happy to send them to you.


    A word from your editor

    If you haven't already sent for your free subscription to this newsletter, now is the time to mail it in. So far, we have been able to keep to our plan of 4 issues a year (even thought we may sometimes be a little late). Please keep those cards and letters coming in to us so that we can keep publishing. We really thank the many of you who have already sent your comments and subscriptions in. If you prefer, mail or fax your business card to the address/phone number on the Reader's Comment Form.

    For the many of you sending in the reply forms with your comments, we may need to call you to discuss your comments further. It's a great help if you include your phone number. Thanks!


    Coming Soon

    Well, that's all we can squeeze in for now. In future issues, we'll bring back some performance tips and answer some more of your questions. Thanks for reading; please let us know what you think of this newsletter.

    +--------------------------------------------------------------+
    

    This newsletter was produced by the C/370 Planning department of the IBM Software Solutions Toronto Laboratory. For further information on any of the products mentioned, please contact your local IBM office, or an authorized IBM Business Partner.

    Numerous product references in this publication are registered trademarks or trademarks of International Business Machines Corporation unless otherwise indicated. IBM Canada Ltd., a related company, is a licensee.

    This newsletter was created and marked for processing using IBM BookMaster(TM) (Program Number 5688-015) and IBM Document Composition Facility (DCF). (Program Number 5748-XX9).

    The final copy was printed on an IBM 3825 Page Printer, an Advanced Function Printer.

    This newsletter is © Copyright IBM Corporation 1994.

    In Canada - © Copyright IBM Canada Ltd. 1994. +--------------------------------------------------------------+


    1. Did you find this newsletter useful?

    2. Is there any way you think we could improve this newsletter?

    3. Is there any C/370 compiler-related subject you would like to see addressed in this newsletter?

    Please note:

    Thank you for your cooperation and help. You can either mail this form to us, or hand it into an IBM office for forwarding.

    You can also fax the form to us. Our fax number is 416-448-6057. Please mark your fax for the attention of Gord Sinclair. Thanks.




    Footnotes:

    ( ) Products marked (TM) or ® are trademarks or registered trademarks of the International Business Machines Corporation, unless otherwise indicated.

    ( ) Unix is a trademark of UNIX System Laboratories, Inc. POSIX and IEEE are trademarks of the Institute of Electrical and Electronic Engineers.

    (1) These characters are not in the C character set.