|
Here's another edition in the on going 'Introducing MI...' series, to try and help the non-MI programmers (or the beginners) on the list to understand MI 'code in action' ============================================= You can request copies (some of which have been updated) of all "Introducing MI..." postings by clicking on the following link; hallp@ssax.com?SUBJECT=Introducing_MI_Bundle_Request Or if your email client doesn't support the above link, by sending an email to; hallp@ssax.com with; Introducing MI Bundle Request in the SUBJECT line. ============================================== This time we'll take a look at the little program that is the 'driver' for the sorting program. After cutting out the sort program source, this code looked all kind of lost and lonely in the clipboard so I felt guilty about discarding it ! Anyhow, this is an interesting program, as it could form the basis for a program that could be written and used to perform dynamic program invocation, i.e. calling a program when you don't know the name of it at runtime. As usual, here's the complete original source; DCL DD RESOLVE-PG CHAR(34); DCL DD RESOLVE-TYPE CHAR( 2) DEF(RESOLVE-PG) POS( 1) INIT(X'0201'); DCL DD RESOLVE-NAME CHAR(30) DEF(RESOLVE-PG) POS( 3); DCL DD RESOLVE-AUTH CHAR( 2) DEF(RESOLVE-PG) POS(33) INIT(X'0000'); DCL SPCPTR .PARM1 INIT(PARM1); DCL DD PARM1 CHAR(5); DCL DD PARM-NBR-ELEMENTS PKD(7,0) DEF(PARM1) POS(1); DCL DD PARM-DIRECTION CHAR(1) DEF(PARM1) POS(5); DCL SPCPTR .PARM2 INIT(PARM2); DCL DD PARM2(500000) ZND(20,0); DCL SYSPTR .COMBSORT; DCL OL COMBSORT(.PARM1, .PARM2) ARG; DCL DD NBR BIN(4); DCL DD MAX BIN(4) INIT(500000); ENTRY * EXT; RESOLVE-PGMS: CPYNV NBR, 0; NEXT: ADDN(S) NBR, 1; SUBN PARM2(NBR), 1000000, NBR; CMPNV(B) NBR, MAX/LO(NEXT); CPYBLAP RESOLVE-NAME, "COMBSORT" , " "; RSLVSP .COMBSORT, RESOLVE-PG, *, *; CPYNV PARM-NBR-ELEMENTS, P'500000'; CPYBLA PARM-DIRECTION, "A"; CALLX .COMBSORT, COMBSORT, *; RTX *; PEND; OK, lets look at the variable declaration section; DCL DD RESOLVE-PG CHAR(34); DCL DD RESOLVE-TYPE CHAR( 2) DEF(RESOLVE-PG) POS( 1) INIT(X'0201'); DCL DD RESOLVE-NAME CHAR(30) DEF(RESOLVE-PG) POS( 3); DCL DD RESOLVE-AUTH CHAR( 2) DEF(RESOLVE-PG) POS(33) INIT(X'0000'); Nothing new here, just defining a structure called 'RESOLVE-PG', that has three character variables mapped contiguously across it; 'RESOLVE-TYPE' is set to hex '0201' which is the type/subtype of program objects on the AS/400, 'RESOLVE-NAME' and 'RESOLVE-AUTH'. This structure will be used when we get a pointer to a program later in the code. DCL SPCPTR .PARM1 INIT(PARM1); DCL DD PARM1 CHAR(5); DCL DD PARM-NBR-ELEMENTS PKD(7,0) DEF(PARM1) POS(1); DCL DD PARM-DIRECTION CHAR(1) DEF(PARM1) POS(5); The above section is laying out the structure for parameter one 'PARM1' - the number of elements in the array and the sort direction, which we know from the sort program can either 'A' or 'D'. In fact if you go back and look at the sort program, you'll find that if the value in 'PARM-DIRECTION' is anything other than 'D' then the sort direction will be ascending. NOTE: These parameters are not the incoming parameters to *this* program, they will be used as parameters when calling the COMBSORT program. Next, 'PARM2' is defined; DCL SPCPTR .PARM2 INIT(PARM2); DCL DD PARM2(500000) ZND(20,0); It's being declared as an array with 500000 elements, each being 20 digit zoned. Then we have the variable '.COMBSORT'; DCL SYSPTR .COMBSORT; This is being defined as a system pointer (SYSPTR). System pointers are 16 byte pointers to 'real' AS/400 objects, such as programs, files, data areas, etc. Next up is the definition of the parameter list 'COMBSORT' we will use to call the sort program, and the order; DCL OL COMBSORT(.PARM1, .PARM2) ARG; Following this we have some general variables being declared; DCL DD NBR BIN(4); DCL DD MAX BIN(4) INIT(500000); These variables will be used to fill the array with some test data to be sorted. OK, here's a standard entry point; ENTRY * EXT; We now know from previous code, that no parameters are passed to this program, and then we have a branch target called 'RESOLVE-PGMS:' being defined; RESOLVE-PGMS: CPYNV NBR, 0; And 0 being copied in to 'NBR'. The next section; NEXT: ADDN(S) NBR, 1; SUBN PARM2(NBR), 1000000, NBR; CMPNV(B) NBR, MAX/LO(NEXT); Is a little loop that fills from element 1 of PARM2 upwards while 'NBR' is lower (/LO) than 'MAX'. Then we get to the code that calls the COMBSORT program; CPYBLAP RESOLVE-NAME, "COMBSORT" , " "; RSLVSP .COMBSORT, RESOLVE-PG, *, *; CPYNV PARM-NBR-ELEMENTS, P'500000'; CPYBLA PARM-DIRECTION, "A"; CALLX .COMBSORT, COMBSORT, *; So, the first line copies 'COMBSORT' (the name of the sort program) in to the variable 'RESOLVE-NAME' padding any extra characters at the end with " ". Then the MI instruction RSLVSP. This MI instruction locates the object named in 'RESOLVE-NAME' of object type 'RESOLVE-TYPE' (we'll ignore the authority variable 'RESOLVE-AUTH' for now). Once the system locates the object, it returns a system pointer to the object in to our pointer variable '.COMBSORT'. Then we set the direction for the sort, "A" (ascending) and invoke the program COMBSORT via the pointer '.COMBSORT' passing the parameters listed in the 'COMBSORT' operand list. Finally the old return and program end code; RTX *; PEND; Remember when I said that this program could be used as the basis for dynamic program invocations ? Well one of the things we would do is remove the hard coded "COMBSORT" as the program name. We could then use a passed in variable, a look-up table, etc. to get the name of the program to call. Although in this instance making the program name a variable doesn't aid us in any way, there are times when writing other programs/applications where you may need the flexibility of dynamic calls in a generic driver program. And the above code is not that far removed from what it would look like... --phil +--- | 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 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.