This is what we C/C++ programmers take for granted! Welcome to the wonderful 
world of the C library.

Charles

-----Original Message-----
From: IBM Mainframe Assembler List [mailto:[email protected]] On 
Behalf Of John McKown
Sent: Wednesday, November 15, 2017 6:58 AM
To: [email protected]
Subject: A modest proposal: LE enabled HLASM + C runtime

This idea came to me the other night. And may be explained by the slight fever 
induced by my flu vacination. As a bit of background, I like to write my HLASM 
code to be non-self-modifying (i.e. can be loaded and run successfully in R/O 
key zero memory, like LPA). I was always upset because IBM did not have any 
kind of standard setup macro to help me with this. In reading, I came across 
the CEEENTRY macro. This macro makes my start up and shutdown easier. Well, 
easier than coding up my own. So, especially for my UNIX programs, I started 
using the CEEENTRY macro and LE subroutines; that is the CEE* programs. Soon 
afterwards, it dawned upon me that since all the regular IBM compilers are LE, 
that I could use "C" routines (or PL/I or Fortran) in COBOL code. This was 
helpful because "C" has some useful routines for strings that I could use in 
COBOL.

So I started looking to see how C run-time routines might be helpful in HLASM. 
I don't need most of the C string routines, since it is easy to do that stuff 
in HLASM. The only C string routine that I've found helpful is the snprintf() 
routine. It is wonderful for easily formatting a nice human readable message. I 
use snprintf() to format the message into a buffer, then write the buffer out 
using QSAM.

First an aside, who else is disappointed that IBM has not really addressed the 
need to do QSAM/BSAM/BPAM code in RMODE(31)? This was an irritation to me the 
other day when I was writing some test code to learn about the IEFPRMLB macro.  
All the "crap" that I had to go through to write my normal RO code, which 
precludes just having a DCB in the module and OPEN'ing it. I've got either copy 
the DCB into RMODE(24) dynamic storage, or maybe do some "tricks" with the 
binder and RMODE(SPLIT). DCBs are a pain. So, in my fever, I thought "too bad I 
can't just use printf() to write my messages, rather than  snprintf() to format 
them, then QSAM to print the formatted string." Of course, this lead to the 
revelation: I can!

This has lead me into the world of the weird. Where possible, instead of using 
QSAM to do my printing to SYSPRINT, I can do a fopen() and
fprintf() with fclose() at the end. These routines free me from the necessity 
of having a DCB in my program. I can simply write code like:

         L     R15,FOPEN
         LA    R1,PLIST
         CALL  (15),(DD_SYSPRINT,WRITE),VL,MF=(E,(1))
         LTR   R15,R15
         JZ    BADOPEN
         ST    R15,FILEPTR SAVE FILE * VALUE FROM FOPEN()
...
*
* AT THIS POINT WE'VE DONE SOMETHING WHICH RESULTS IN A RETURN
* CODE IN R15 AND A REASON CODE IN R0. I WANT TO FORMAT THEM
* AND WRITE THEM OUT, IF R15 ISN'T ZERO.
         LTR   R15,R15
         JZ    GOOD
*
* CREATE CALL PARAMETER LIST FOR FPRINTF(FILE *,CHAR *FMT, ...)
         MVC   PLIST+0(4),FILEPTR  FILE * FOR SYSPRINT
         MVC   PLIST+4(4),=A(FMT1) ADDR OF FORMAT CONTROL
         ST    R15,PLIST+8  RETURN CODE
         ST    R0,PLIST+12  REASON CODE
         L     R15,FPRINTF  ADDRESS OF FPRINTF()
         LA    R1,PLIST     ADDRESS OF PARAMETER LIST
         BASR  R14,R15      CALL FPRINTF - NOTE VL=1 NOT NEEDED IN C
...
         MVC   PLIST+0(4),FILEPTR
         LA    R1,PLIST
         L     R15,FCLOSE
         BASR  R14,R15       CLOSE SYSPRINT FILE
...
FOPEN    DC    V(FOPEN)
FPRINTF  DC    V(FPRINTF)
FCLOSE   DC    V(FCLOSE)
FILEPTR  DS    A
PLIST    DC    20A(0) GENERAL PARM LIST AREA
DD_SYSPRINT DC C'//DD:SYSPRINT',X'00' X'00' IS C STRING TERMINATOR
WRITE    DC    C'W',X'00'
FMT1     DC    C'SOME ERROR MESSAGE. RC=%d, REASON=%d',X'15',X'00'
* NOTE X'15' IS END-OF-LINE FOR FPRINTF
*      X'00' IS END OF STRING DELIMITER FOR C

Ok, maybe the above is just a bit too weird for actual use. But I found it 
interesting to at least think about. If you want a full example of the above, 
which I used to do some test learning about the IEFPRMLB macro, the code is 
here:
https://gist.github.com/JohnArchieMckown/a08e0e4b6777cd36f57bbae78e28abcc

More about the use & abuse of IEFPRMLB later.


--
I have a theory that it's impossible to prove anything, but I can't prove it.

Maranatha! <><
John McKown

Reply via email to