Just to clarify, I'm on V7R3M0.
I'm trying to call the Submit Debug Command (QteSubmitDebugCommand) API but not getting back the results I expect or I don't correctly understand the results. I'm trying to follow the example for a BREAK statement (near the bottom of the page in the manual). I'm expecting similar results to what are shown but I'm not getting the same results.
My prototype is:
dcl-pr QteSubmitDebugCommand extproc(*dclcase);
rcvrDta char(128);
rcvrSiz int(10) const;
viewID int(10) const;
InputBuffer char(64) const;
InpBfrSiz int(10) const;
CompilerID char(20) const;
apiError like(apiErrDs);
end-pr;
The definitions of the variables are:
dcl-pi *n ;
pViewID int(10) const;
pDebugCommand varchar(64) const options(*trim); // This is BREAK 10 WHEN IDX > 2
pCompilerID char(20) const; // which is valid in the test harness program
end-pi;
dcl-s receiverVariable char(128);
dcl-s i uns(5);
dcl-ds apiErrDs likeDs(apiErrDsTmp) inz;
dcl-ds resultEntryTmp template qualified;
resultType uns(10);
count uns(10);
length uns(10);
end-ds;
dcl-s receiverPtr pointer;
dcl-ds receiverData qualified based(receiverPtr);
bytesReturned int(10);
bytesAvailable int(10);
entries int(10);
resultArray dim(4) likeds(resultEntryTmp);
stringSpace char(256);
end-ds;
And I call the API with:
QteSubmitDebugCommand(receiverVariable :%Len(receiverVariable) :pViewID
:pDebugCommand :%Len(pDebugCommand) :pCompilerID :apiErrDS);
receiverPtr = %addr(receiverVariable);
At this point I dump the program to check the results.
What I see in the dump is:
RECEIVERDATA DS
BYTESAVAILABLE INT(10) 57 '00000039'X
BYTESRETURNED INT(10) 57 '00000039'X
ENTRIES INT(10) 3 '00000003'X
RESULTARRAY DS DIM(4)
(1)
COUNT UNS(10) 3 '00000003'X
LENGTH UNS(10) 0 '00000000'X
RESULTTYPE UNS(10) 33554432 '02000000'X
(2)
COUNT UNS(10) 10 '0000000A'X
LENGTH UNS(10) 0 '00000000'X
RESULTTYPE UNS(10) 83886080 '05000000'X
(3)
COUNT UNS(10) 10 '0000000A'X
LENGTH UNS(10) 0 '00000000'X
RESULTTYPE UNS(10) 83886080 '05000000'X
(4)
COUNT UNS(10) 1849750016 '6E40F200'X
LENGTH UNS(10) 4210752 '00404040'X
RESULTTYPE UNS(10) 3385124672 'C9C4E740'X
STRINGSPACE is not shown but it does look correct
According to the manual is should be getting back:
Receiver Variable
Offset Field Value
0 Bytes returned 59
Bytes available 59
Entry count 3
12 Result type BreakR(2)
Break results count 3
Reserved
24 Result type BreakPositionR(5)
Line number 7 (in my case this = 10)
Reserved
36 Result type ExpressionTextR(7)
Expression text offset 48
Expression text length 10
48 String space result > 5
So it looks like the Header record (Offset 0) is correct.
The resultArray(1) looks correct as the Hex value of the RESULTTYPE is '02000000'X which I think is the BreakR. But I was expecting the value in the dump to be 2 not 33554432. Can someone tell me why this is? Am I doing something wrong or just misunderstanding how it's displayed.
The resultArray(2) looks correct as the Hex value of the RESULTTYPE is '05000000'X which I think is the BreakPositionR. Same question as to why I have to look at the Hex value.
The resultArray(3) looks incorrect as the Hex value of the RESULTTYPE is '05000000'X and the manual shows I should have been expecting a ExpressionTextR (7).
As for the String space I don't see anything resembling IDX > 2 which the manual shows I should be expecting.
Can anyone see what I'm doing wrong in my call or in the definition of the prototype.
Also, can someone explain why the resultarray.count looks like a normal int yet the resultarray.recordtype appears correct only in Hex. Should I be looking at the Hex value?
Any thoughts would be greatly appreciated.
Thanks,
Rob
Update: After Mark's reply I changed the procedure to follow Mark's suggestion and it worked correctly. Thanks, Mark.
Here is what I ended changing the code to...
dcl-s receiverPtr pointer;
dcl-ds receiverData qualified based(receiverPtr);
bytesReturned int(10);
bytesAvailable int(10);
entries int(10);
end-ds;
dcl-s resultEntryPtr pointer;
dcl-ds resultEntry qualified based(resultEntryPtr);
type uns(10) pos(1);
count uns(10) pos(5);
offset uns(10) pos(5);
length uns(10) pos(9);
end-ds;
dcl-s stringSpace char(256);
QteSubmitDebugCommand(receiverVariable :%Len(receiverVariable) :pViewID :pDebugCommand :%Len(pDebugCommand)
:pCompilerID :apiErrDS);
receiverPtr = %addr(receiverVariable);
resultEntryPtr = %addr(receiverVariable);
// We want to position the pointer to the last entry which contains
// the offset and the length of the character string.
resultEntryPtr += 12 * receiverData.entries;
stringSpace = %subst(receiverVariable: resultEntry.offset: resultEntry.length);
Not real sure about the format of the result array entries, but one thing about this API is that the result array is variable length, and the string entries immediately follow the returned result array. That means unless you get exactly 4 entries in the result array, you will not end up with the string space in the your string space variable. Notice that if you convert the hex codes in result array entry 4 x'C9C4E740 6E40F200 00404040'
you have a null terminated EBCDIC string that says IDX > 2
. This is right where it should be, immediately following the third result array entry (since the API told you that there were 3 entries returned). The API does not know the format of your RPG fields, you are really just providing a buffer which you must interpret.
I usually use a based variable to interpret things like variable length formats. So in this case I would define something like this:
dcl-ds resultEntry Qualified Based(pResultEntry);
type Uns(10) Pos(1);
count Uns(10) Pos(5);
offset Uns(10) Pos(5);
length Uns(10) Pos(9);
end-ds;
dcl-s pResultEntry Pointer;
Note resultEntry.count
and resultEntry.offset
overlay each other, but provide good names in the case that the entry is a type 3 entry with offset and length rather that a type 2 entry with just a count. You can define this differently, but the key is the Based
keyword on the data structure declaration line.
To process this you can do something like this:
pResultEntry = %addr(ReceiverData);
for ix = 1 to ReceiverData.entries;
pResultEntry += 12;
ProcessResultArrayEntry(resultEntry);
endfor;
But as I said before, I am not sure about what you are seeing in result array entry 3. It seems that it should be one of those 3 part entries with offset and length. You should be able to substring the text out of that using something like this:
string = %subst(ReceiverData: resultEntry.offset: resultEntry.length);