× The internal search function is temporarily non-functional. The current search engine is no longer viable and we are researching alternatives.
As a stop gap measure, we are using Google's custom search engine service.
If you know of an easy to use, open source, search engine ... please contact support@midrange.com.


  • Subject: An introduction to MI by example II (part B)...
  • From: "Phil Hall" <hallp@xxxxxxxx>
  • Date: Mon, 15 Nov 1999 21:18:05 -0600

For those of you who actually read my 'Introducing MI...II', you may be
wondering how Tim managed to turn twelve lines of code (in Leif's
dynamic memory allocation version of GETOWNLIB) into one line of code.

Well Tim 'cheated' - sort of !

Let's look at Tim's code first, and then see where the 'cheat' is...

    DCL DD INVINFO CHAR(16) BDRY(16);
        DCL SYSPTR INVPGM DEF(INVINFO) POS(1);
    DCL SPCPTR P#INVINF INIT(INVINFO);

    /* The attribute info selects the program pointer.
    DCL DD ATTINFO CHAR(144) BDRY(16);
        DCL DD NUMATT BIN(4) DEF(ATTINFO) POS(1) INIT(1);
        DCL DD ATTID BIN(4) DEF(ATTINFO) POS(17) INIT(6);
        DCL DD ATTLGH BIN(4) DEF(ATTINFO) POS(29) INIT(16);
    DCL SPCPTR P#ATTINF INIT(ATTINFO);

    /* The selection criteria controls the invocation level.
    DCL DD SELECT CHAR(48) BDRY(16);
    DCL DD SRCINV BIN(4) DEF(SELECT) POS(1) INIT(-1);

    /* Materialize the INVOCATION stack - current-1
    MATINVAT P#INVINF,SELECT,P#ATTINF;

Nothing too difficult in this code, just a lot of variable declaring,
then the one line of code - the call to 'MATINVAT'. What did Tim do
differently ? He called MATINVAT, instead of MATINVS. MATINVAT
(MATerialize INVocation ATtributes) materializes a single entry in the
call stack, where as if you remember MATINVS materializes the whole
stack. If you take a look at the MATINVAT instruction in the MI
Reference, you'll find that the way to call the instruction is to pass
it a selection template - or in MI speak a attribute selection template.
This is similar to when you call some of the OS/400 list API's such as
QUSROBJD (list object description) in RPG. You can shorted the list
returned from QUSROBJD by passing in a selection parameter to, say, just
list the *JOBD objects. In this case, Tim is using the selection
template 'ATTINFO', setting the values of the template as follows;

    DCL DD ATTINFO CHAR(144) BDRY(16);

The template 'ATTINFO' is declared as character, 144 in length, aligned
on a 16-byte boundary (the alignment is needed to keep the pointer that
will be returned 'usable')

        DCL DD NUMATT BIN(4) DEF(ATTINFO) POS(1) INIT(1);

We're only after one type of attribute to be returned, hence 'NUMATT' is
initialized to the value of 1.

        DCL DD ATTID BIN(4) DEF(ATTINFO) POS(17) INIT(6);

We want a pointer to the calling program, so 'ATTID' is set to 6 (see
the MI ref. for other attribute types you can request)

        DCL DD ATTLGH BIN(4) DEF(ATTINFO) POS(29) INIT(16);

'ATTLGH' is set to the length of a system pointer, 16 bytes.

We also see the variable 'SELECT' being declared as follows;

    DCL DD SELECT CHAR(48) BDRY(16);
    DCL DD SRCINV BIN(4) DEF(SELECT) POS(1) INIT(-1);

Here, we want the stack entry previous to the current one (the current
one will be an entry for the GETOWNLIB itself), so we see 'SRCINV' being
set to -1.

Finally, when the line of code;

    MATINVAT P#INVINF,SELECT,P#ATTINF;

Is executed, MATINVAT uses 'SELECT' to determine which entry in the call
stack to materialize, then uses 'P#ATTINF' (really, the data P#ATTINF
points to) to determine what data to actually materialize for the
selected stack entry. You might want to re-read that a couple of times
until it makes sense.

OK, what's the cheat ? Well a few things are missing...

1) The definition of the incoming parameter from the calling
program.
2) The 'conversion' of the system pointer 'P#INVINF' from it's
pointer representation to a more readable form. If you look back at
Leif's code, this was achieved by using the MI instruction 'MATPTR'
3) Copying the name of the library of the calling program into the
passed in parameter.

So although Tim reduced the code to one line, as the program stands (how
he wrote it) it doesn't produce the same results as GETOWNLIB (in fact
it won't compile).

So what needs to be done to make it 'functionally equivalent' to Leif's
GETOWNLIB program ? Well, this would be a good chance to test how much
MI you've managed to learn from these 'Introducing MI.." emails. You
have all the information you need from Leif's program, plus the
'one-liner' from Tim to create the source. Go on, give it a try ! If you
get stuck, I've included what the source should resemble a few pages
down...

Finally, even when we 'fix' Tim's 'one-liner' to work, it's still only
three lines of code !

--phil
























keep trying before you look !!




























OK, here's the source I cobbled together from Leif & Tim's code hence
the two different variable naming conventions...

/*** Declare incoming parameters ***/
DCL DD PARM1 CHAR(10) BAS(.PARM1);
    DCL DD PARM-LIB-NAME CHAR(10) DEF(PARM1) POS(1);
DCL SPCPTR .PARM1 PARM;
DCL OL PARMS(.PARM1) EXT PARM MIN(1);

/*** Declare variable for MATPTR ***/
DCL SPCPTR .PROGRAM INIT(PROGRAM);
DCL DD      PROGRAM CHAR(77) BDRY(16);
    DCL DD  PGM-BYTES-PRV      BIN(4) DEF(PROGRAM) POS( 1) INIT(77);
    DCL DD  PGM-LIB-NAME     CHAR(30) DEF(PROGRAM) POS(12);

/*** Declare invocation entry variable ***/
DCL DD INVINFO CHAR(16) BDRY(16);
    DCL SYSPTR INVPGM DEF(INVINFO) POS(1);
DCL SPCPTR .INVINF INIT(INVINFO);

/*** The attribute info selects the program pointer ***/
DCL DD ATTINFO CHAR(144) BDRY(16);
    DCL DD NUMATT BIN(4) DEF(ATTINFO)  POS(1)  INIT(1);
    DCL DD ATTID  BIN(4) DEF(ATTINFO) POS(17)  INIT(6);
    DCL DD ATTLGH BIN(4) DEF(ATTINFO) POS(29) INIT(16);
DCL SPCPTR .ATTINF INIT(ATTINFO);

/*** The selection criteria controls the invocation level ***/
DCL DD SELECT CHAR(48) BDRY(16);
    DCL DD SRCINV BIN(4) DEF(SELECT) POS(1) INIT(-1);

/*** program entry point ***/
ENTRY * (PARMS) EXT;
    /*** Materialize the INVOCATION stack entry current-1 ***/
    MATINVAT  .INVINF, SELECT, .ATTINF;
    MATPTR    .PROGRAM, INVPGM;
    CPYBLA     PARM-LIB-NAME, PGM-LIB-NAME;
RTX *;
PEND;




+---
| This is the MI Programmers Mailing List!
| To submit a new message, send your mail to MI400@midrange.com.
| To subscribe to this list send email to MI400-SUB@midrange.com.
| To unsubscribe from this list send email to MI400-UNSUB@midrange.com.
| Questions should be directed to the list owner/operator: dr2@cssas400.com
+---


As an Amazon Associate we earn from qualifying purchases.

This thread ...

Follow-Ups:

Follow On AppleNews
Return to Archive home page | Return to MIDRANGE.COM home page

This mailing list archive is Copyright 1997-2024 by midrange.com and David Gibbs as a compilation work. Use of the archive is restricted to research of a business or technical nature. Any other uses are prohibited. Full details are available on our policy page. If you have questions about this, please contact [javascript protected email address].

Operating expenses for this site are earned using the Amazon Associate program and Google Adsense.