BRK string1;
The BOM table has the 2 formats depending on the BOM table flags (matpg?bom-flag). If the flag indicates to use new BOM table format, then the first bit of the MI instruction number is not a flag, so numbers up to 64k-1 can be used. The 2 BOM formats are defined as bom-entry0-t, and bom-entry1-t in mip-h.emi like the following:
dcl spc bom-entry0-t bas(*) ; /* bit 0. Format flag. 0 = HLL statement number is in character format 1 = HLL statement number is in numeric format */ dcl dd bome0?mi-inst bin(2) unsgnd dir ; dcl dd bome0?hll-stmt-str char(10) dir ; dcl dd bome0?hll-stmt-num bin(2) def(bome0?hll-stmt-str) ; dcl spc bom-entry1-t bas(*) ; dcl dd bome1?mi-inst bin(2) unsgnd dir ; /* bit 0. Format flag. 0 = HLL statement number is in character format 1 = HLL statement number is in numeric format */ dcl dd bome1?fmt char(1) dir ; dcl dd bome1?hll-stmt-str char(10) dir ; dcl dd bome1?hll-stmt-num bin(2) def(bome1?hll-stmt-str) ;
The following is an example MI program (tmip03.emi) that parses the BOM table component of OPM RPG program t143rpg.rpg.
/* @file tmip03.emi Parse the BOM of an OPM MI program template. */ entry *(pl-main) ext ; dcl spcptr .pgm-name parm ; dcl spcptr .pgm-type parm ; dcl ol pl-main( .pgm-name, .pgm-type ) parm ext ; dcl dd pgm-name char(10) bas(.pgm-name) ; dcl dd pgm-type char(2) bas(.pgm-type) ; dcl dd rt char(34) auto ; dcl sysptr pgm auto ; cpybrep rt, x'00' ; cpybla rt(1:2), pgm-type ; cpyblap rt(3:30), pgm-name, ' ' ; rslvsp pgm, rt, *, * ; brk '1' ; dcl spcptr p auto ; dcl dd len bin(4) auto ; modasa p, 8 ; cpynv p->matpg?bytes-in, 8 ; matpg p, pgm ; cpynv len, p->matpg?bytes-out ; modasa p, -8 ; modasa p, len ; cpynv p->matpg?bytes-in, len ; matpg p, pgm ; brk '2' ; /* does tmpl-extension exists? */ tstbts(b) p->matpg?pgm-attr, 10 / zer(see-you) ; /* determine BOM format */ dcl dd new-bom-fmt char(1) auto ; tstbts(i) p->matpg?bom-flag, 0 / nzer(new-bom-fmt) ; /* determin length of a BOM entry */ dcl dd bome-len bin(2) auto ; cmpbla(b) new-bom-fmt, '1' / eq(=+3) ; addn(s) bome-len, 2 ; b =+2 ; : addn(s) bome-len, 3 ; : addn(s) bome-len, p->matpg?bome-len ; /* locate the BOM component */ dcl spcptr pos auto ; addspp pos, p, p->matpg?bom-off ; dcl dd n bin(4) auto ; cpynv n, 0 ; bom-loop: /* determine breakpoint format */ dcl dd char-fmt char(1) auto ; cmpbla(b) new-bom-fmt, '1' / eq(=+3) ; tstbts(i) pos->bome0?mi-inst, 0 / eq(char-fmt) ; /* old BOM format */ b =+2 ; : tstbts(i) pos->bome1?fmt, 0 / eq(char-fmt) ; : /* print a BOM entry */ calli print-bom-entry, *, print-bom-entry-ptr ; addn(s) n, bome-len ; cmpnv(b) n, p->matpg?bom-len / nlo(end-bom-loop) ; addspp pos, pos, bome-len ; b bom-loop ; end-bom-loop: see-you: neg(s) len ; modasa p, len ; rtx * ; dcl dd msg char(64) auto ; dcl dd msg-inst znd(6) def(msg) pos(1) ; dcl dd msg-bkp char(10) def(msg) pos(26) ; /* print-bom-entry @pre char-fmt, pos, p->matpg?bome-len */ dcl insptr print-bom-entry-ptr auto ; entry print-bom-entry int ; dcl spcptr hll-stmt-ptr auto ; dcl dd hll-stmt-num char(2) bas(hll-stmt-ptr) ; dcl spcptr msg-bkp-ptr auto ; cpybrep msg, " " ; cmpbla(b) new-bom-fmt, '1' / eq(=+5) ; setspp hll-stmt-ptr, pos->bome0?hll-stmt-str ; clrbts pos->bome0?mi-inst, 0 ; cpynv msg-inst, pos->bome0?mi-inst ; b =+3 ; : setspp hll-stmt-ptr, pos->bome1?hll-stmt-str ; cpynv msg-inst, pos->bome1?mi-inst ; : /* breakpoint name or number */ cmpbla(b) char-fmt, '1' / neq(numeric-bkp) ; setspp msg-bkp-ptr, msg-bkp ; %memcpy(msg-bkp-ptr, hll-stmt-ptr, p->matpg?bome-len) ; b end-bkp ; numeric-bkp: cvthc msg-bkp, hll-stmt-num ; end-bkp: %sendmsg(msg, 64) ; b print-bom-entry-ptr ; /include mip-h.emi ; pend ;
Call TMIP03 like the following:
CALL TMIP03 ('T143RPG' X'0201')
The output of TMIP03 is the following:
000001 .ENTRY 000003 .STOP 000005 PROG DS 000005 .DUMP 000022 *GETIN 000030 .ERX 000037 *TOTC 000038 *TOTL 000039 *OFL 000041 *DETC 000042 200 000043 300 000044 400 000045 500 000046 600 000047 700 000056 800 000069 900 000082 1000 000084 *DETL 000089 .SORT 000089 S.ARR 000103 *INIT 000134 .SENDMSG 000138 *CANCL 000146 *TERM 000150 .FILERR 000151 .ERR 000178 .END0002 000182 .END0001 000185 .DEACTPG 000192 .EXCPTON