On 2017-11-15 09:58, John McKown wrote:
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.



That's an interesting approach, John, offloading the annoyances to the LE runtime library. And using the LE entry and exit macros is certainly simpler than using CEEPIPI to access the runtime.

Having said that, I've found that the most convenient way to call the LE runtime routines is from a language designed to use them. Your code above is much simpler than the code required to do all the work in HLASM, but it's also more complex than writing the program in C.

I'm reminded of Dave Cole's post "The Pointlessness of handwriting "efficient" code (was One Byte MVC Versus IC/STC)" from 2017-10-16 12:23. These days, IMHO it's best to use HLASM when it's necessary for some reason, as opposed to automatically using it for everything. It's pretty simple to call a LE-compliant HLASM routine from a C program to accomplish something unique.

Now, having blathered on for a bit, ISTR that you don't have access to a C compiler. So for you, the choices would be a little different!

--

Regards, Gord Tomlin
Action Software International
(a division of Mazda Computer Corporation)
Tel: (905) 470-7113, Fax: (905) 470-6507
Support: https://actionsoftware.com/support/

Reply via email to