(Originally posted 2013-03-12.)
I’m sharing this technique in case it’s useful to you. And, selfishly, in case you can think of refinements. 🙂 (I’m not the best assembler programmer in the world so could easily be missing a trick or two.)
We map SMF records using a set of assembler macros – to create what are called log tables. We summarise these log tables into summary tables, again defined using assembler macros.
While the assembly process does produce a readable listing it doesn’t do what I want:
- Produce an HTML report I can download and usefully share.
- Allow me to do useful things such as calculations. One area that’s particularly tedious is tracing the derivation of one of the computed columns. Another is figuring out if we have gaps (or overlaps) in mapping the SMF record.
These macros are supplied with the (long out of support but still working well) Service Level Reporter (SLR) product.
But here’s the (perhaps) novel thought:
Just because one normally assembles the macros with the SLR maclib doesn’t mean you have to. Hence the “alternate macro libraries” in the title of this post.
Suppose you were to write your own macro library: Then you could have it produce whatever you wanted. Assembling with an alternate maclib is just a matter of different JCL.
The challenge that immediately hits you is how to have HLASM produce text. There doesn’t appear to be a way to write a side file in HLASM. But there is another way:
The PUNCH instruction writes data to the object deck. You can write literal strings this way, with the full power of the macro assembler language.
For example, you could punch the string “</table>” to the output. You can see where this heading.
So long as you don’t try to link edit the resulting object deck everything’s fine. (If you do you’d better not do it into Production. I’m hoping the link edit failure wouldn’t delete the target load module – but I don’t really know.)
Obviously you wouldn’t want to mix table macros with regular code (or macros that expand to regular code).
To take the summary table as an example there are very few actual macros…
Two define the start and end of the table. Of these one takes parameters.
There are three that define columns in the table, all of which take parameters.
There is one that defines what are called total patterns, which also takes parameters.
These aren’t terribly difficult to code alternate macros for – at least not if you don’t do any parameter checking. However, I want to handle default values for parameters and consider parameter checking to be only moderately more difficult.
As a relative novice at the HLASM flavour of macros I’m looking at the original SLR macro definitions: it’s more learning than swiping the code. Indeed for some use cases there would be copyright implications – so a “clean room” approach might be appropriate. For me, as IBM owns the copyright (plus I’m not shipping in a product) this is not an issue. But coding AIF, AGO etc and handling macro parameters and SETC etc are things I’m having to learn the syntax for.
The SLR manuals tell me which parameters are required and what the defaults are. But it’s nice to see them in the macro definitions.
So, the data lends itself to an HTML table as output, perhaps with augmentations. And that’s what I’m building.
I have a basic version of SUMTAB (with a subset of the parameters it takes) and TABEND (which takes no parameters) working – producing <table> and </table> elements. So I know the technique works. It’s a bit of a jumble of AIF instructions – but then so is the original. 🙂
I can think of other cases where tables are assembled from macros. And that’s probably not restricted to z/OS macro decks.
I’m slightly disappointed that I can’t find a way to have a new version of a macro invoke the original while writing a side file. That means two assemblies and two sets of JCL – one using my new macros to create documentation, and the other the original.
To keep the documentation up to date automatically requires both assemblies in the same job – and the source code might have to be copied to a separate temporary data set if it’s in the same member as the JCL: I would prefer to have one member containing one copy of the source code and JCL parameterised to either produce the documentation or the load module.
Whatever the fiddliness of the JCL I think this technique works well for me – and could be readily extended to other use cases.
You could argue I got really bitten by the “Principle” Of Sufficient Disgust (POSD) with this. I wouldn’t dissent from that view. By the way I put the word ‘principle’ in quotes because it’s not really a principle at all: It’s just that part of the human condition where some people get so fed up with something they go and fix it. 🙂