My colleague Bob Stark asked me to float a problem he's currently
experiencing at a client site out to some of the listservers for MVS and
Assember to see if anyone can help us debug this problem.
If you post back, can you please also copy your response to Bob at
[EMAIL PROTECTED] as he's in an account site and off-list with web email.
Thanks so much!
Scott
Date: Fri, 07 Oct 2005 14:49:13 -0400
From: "Bob Stark" <[EMAIL PROTECTED]>
To: [EMAIL PROTECTED]
Subject: S/390 Assembler Macro problem
X-Mailer: IceWarp Web Mail 5.4.3
X-Originating-IP: 208.165.251.16
I wrote the set of macros below which generate a linked list for a control
block module a month back, and now I am adding more userids. I hit a limit
that I didn't realize:
xx DC C'THIS MUST BE 256 BYTES OR LESS'
My list is now over 256 bytes, so I have to split that up unto multiple DC
instructions, and my technique of generating the length will no longer be
correct. When I wrote these two macros, I scoured the Internet looking
for examples, but didn't find much pay dirt, and the High Level Assembler
Programmer's Guide and Language reference are short on examples that put
everything together.
So I am looking for:
1. A suggested approach, withe a few actual lines of macro code, that show
how to split these DC's up and loop through them.
2. A Source of really good example assembler macros that I could copy
techniques from.
Here is a sample invocation of both macros:
$GRP TEST,USERS='T045022 T046726 T047542 T056131 T056313 T057345 +
T093897 T094643 T095122 T095507 T095556 T096058 +
T096148 T096199 T096255 T096518 T097282 T097579 +
T097617 T097623 T098914 T099268 T099301 T100052 +
'
GRPTABLE $GRPTBL THIS ENTRY MUST FOLLOW ALL $GRP MEMBERS
Here is the $GRP macro, which keeps an array of group data:
MACRO
&MACNAME $GRP &NAME,&USERS=''
.*-------------------------------------------------------------------*
.* *
.* FUNCTION - BUILDS ASSEMBLER TABLE FOR LINKAGE INTO LNKLST LIB. *
.* *
.* EXAMPLE: $GRP LANDUSR,USERS='T12345 TZ99999' *
.* *
.*-------------------------------------------------------------------*
GBLC &GRPNAMES(500)
GBLC &GRPUSERS(500)
GBLA &GRPCNTR
AIF (T'&NAME NE 'O').GOTNAME
MNOTE 12,'****** NO GROUP NAME ENTERED'
MEXIT
.GOTNAME ANOP
.*
AIF (T'&USERS NE 'O').GOTUSER
MNOTE 12,'****** NO USER NAME(S) ENTERED'
MEXIT
.GOTUSER ANOP
.*
&GRPCNTR SETA &GRPCNTR+1
.* THE NEXT LINE PADS THE NAME TO 8 CHARACTERS, SO IT COMPARES OK
.*&GRPNAMES(&GRPCNTR) SETC '&NAME'.' '(K'&NAME,8)
&GRPNAMES(&GRPCNTR) SETC '&NAME'
&GRPUSERS(&GRPCNTR) SETC '&USERS'
.END MEND
Here is the $GRPTBL Macro, where my problem lies. It sorts the array into
order (that part works okay), then generates control blocks from the data.
See the very bottom for what I think I need to do.
MACRO
&MACNAME $GRPTBL &DSECT=NO
.*-------------------------------------------------------------------*
.* *
.* FUNCTION - BUILDS ASSEMBLER TABLE FOR LINKAGE INTO LNKLST LIB. *
.* *
.* EXAMPLE: $GRPTBL DSECT=YES *
.*-------------------------------------------------------------------*
GBLC &GRPNAMES(500)
GBLC &GRPUSERS(500)
GBLA &GRPCNTR
LCLA &I,&J
LCLA &NEXT
LCLB &SWAP
LCLC &SAVEC
AIF ('&DSECT' EQ 'YES').DGEN
.* MNOTE 0,'*** TABLE CONTAINS &GRPCNTR GROUPS'
.* TOP OF "I" LOOP
&I SETA 1
.SRTLOOPI ANOP
&SWAP SETB 0
.* TOP OF "J" LOOP
&J SETA 1
.SRTLOOPJ ANOP
&NEXT SETA &J+1
AIF ('&GRPNAMES(&J)'.' '(K'&GRPNAMES(&J),8) LE +
'&GRPNAMES(&NEXT)'.' '(K'&GRPNAMES(&NEXT),8)).NOS+
WAP
.* ENTRIES OUT OF ORDER, MUST SWAP THEM
&SWAP SETB 1
.* MNOTE 0,'*** SWAP &J &GRPNAMES(&J) W/ &NEXT &GRPNAMES(&NEXT)'
&SAVEC SETC '&GRPNAMES(&J)'
&GRPNAMES(&J) SETC '&GRPNAMES(&NEXT)'
&GRPNAMES(&NEXT) SETC '&SAVEC'
.*
&SAVEC SETC '&GRPUSERS(&J)'
&GRPUSERS(&J) SETC '&GRPUSERS(&NEXT)'
&GRPUSERS(&NEXT) SETC '&SAVEC'
.NOSWAP ANOP
.*
.* BOTTOM OF "J" LOOP
&J SETA &J+1
.* MNOTE 0,'*** BOTTOM OF J LOOP, J=&J'
AIF (&J LT &GRPCNTR).SRTLOOPJ
.*
.* BOTTOM OF "I" LOOP
.* MNOTE 0,'*** BOTTOM OF I LOOP, I=&I'
AIF (&SWAP EQ 0).SORTED
&I SETA &I+1
AIF (&I LT &GRPCNTR).SRTLOOPI
.* THE ARRAY IS SORTED
.SORTED ANOP
.*
&I SETA 1
&MACNAME DS 0F ALIGN CONTROL BLOCK TO FULLWORD
.GRPLOOPI ANOP
&NEXT SETA &I+1
AIF (&I EQ &GRPCNTR).LASTGRP
GRP&GRPNAMES(&I) DC A(GRP&GRPNAMES(&NEXT)) POINTER TO NEXT GROUP OR 0
AGO .DIDGRP
.LASTGRP ANOP
GRP&GRPNAMES(&I) DC A(0) POINTER TO NEXT GROUP IS 0
.DIDGRP ANOP
DC A(&GRPNAMES(&I)) POINTER TO AUTH ENTRY
DC CL8'&GRPNAMES(&I)' GROUP NAME
DC AL2(L'GRPUSR&I) LENGTH OF USER LIST
GRPUSR&I DC C&GRPUSERS(&I)
*
&I SETA &I+1
AIF (&I LE &GRPCNTR).GRPLOOPI
AGO .END
.*
.DGEN ANOP
GRPTBL DSECT
GRPNEXT DS A POINTER TO NEXT GROUP OR 0
GRPAUTH DS A POINTER TO JOBTRAC AUTH ENTRY
GRPNAME DS CL8 GROUP NAME
GRPUSRLN DS AL2 LENGTH OF USER LIST
GRPUSERS DS 0C BEGINNING OF USER LIST
.END MEND
The following two lines
DC AL2(L'GRPUSR&I) LENGTH OF USER LIST
GRPUSR&I DC C&GRPUSERS(&I)
need to be split into something like:
DC AL2(GRPEND&I-GRPUSR&I) LENGTH OF USER
LIST
GRPUSR&I EQU *
DC CL256'&GRPUSERS(&I)(1,256) First
part
DC CL256'&GRPUSERS(&I)(257,512) Second
part
DC C'&GRPUSERS(&I)(257,MAXLENGTH) Last
part
GRPEND&I EQU *
Notice that this is pseudo code because I can't figure out the technique
here; I need a loop which generated out the accumulated data and deals
with the leading and trailing quote on the original input data.
Many many thanks and Regards,
Bob S.
Scott McFall
ProTechTraining, a division of
ProTech Professional Technical Svcs, Inc.
800-373-9188x113 cell 412-445-8070
"Charting the Course...to Your Success!"
Over 100,000 successfully trained IT professionals since 1990!
Class schedules and course information online at:
http://www.protechtraining.com
Think BIG iron..."I think there is a world market for about five
computers." -- Thomas J. Watson, Chairman of IBM, 1943
----------------------------------------------------------------------
For IBM-MAIN subscribe / signoff / archive access instructions,
send email to [EMAIL PROTECTED] with the message: GET IBM-MAIN INFO
Search the archives at http://bama.ua.edu/archives/ibm-main.html