Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update ilePGM() and ileSRV() to count parameters backwards so they don't leave off subsequent parameters after an omitted parameter #64

Closed
wants to merge 5 commits into from

Conversation

brandonp42
Copy link

@brandonp42 brandonp42 commented Nov 9, 2022

Closes #63

The current logic starting at lines https://github.com/IBM/xmlservice/blob/master/src/plugile.rpgle#L4342 and https://github.com/IBM/xmlservice/blob/master/src/plugile.rpgle#L4985 doesn't work correctly because it assumes once you hit a parameter with a null pointer there are no other valid parameters following that. Unfortunately if you have a parameter that allows *OMIT and then specify a later parameter then it won't pass that later parameter.

My changes walk backwards through the parameter pointer array instead, finding the last valid parameter. I also put code in place to ensure it doesn't evaluate memory that's not technically in use (using sArgvSz) although in theory those unused pointers are already initialized to null.

@brandonp42 brandonp42 changed the title Update ilePGM() and ileSRV() to fix issue 63 Update ilePGM() and ileSRV() to fix issue #63 Nov 9, 2022
@brandonp42 brandonp42 changed the title Update ilePGM() and ileSRV() to fix issue #63 Update ilePGM() and ileSRV() to count parameters backwards so they don't leave off subsequent parameters after an omitted parameter Nov 9, 2022
@brandonp42
Copy link
Author

Tagging @amagid and @GajenderI

@brandonp42 brandonp42 marked this pull request as ready for review November 9, 2022 22:16
Signed-off-by: Brandon Peterson <117427172+brandonp42@users.noreply.github.com>
@GajenderI
Copy link

@brandonp42 Thank you very much for this.

…y space

Signed-off-by: Brandon Peterson <117427172+brandonp42@users.noreply.github.com>
Copy link
Member

@kadler kadler left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was trying to understand this code and the changes you've made.

I am trying to understand why this code even needs to calculate how many args there are being passed. The argument array is being pointed to a global variable sArgvBegP, which gets set elsewhere. There's also another global variable sArgvSz, couldn't that just be used to calculate the count? I really hate global variables since it makes it hard to reason about the program flow and who sets what where, but it seems to me that whoever is setting up this array should know how many elements are in it already and it should be responsible for keeping the count (maybe we need a new global to track? 🤮).

Comment on lines 4352 to 4353
dow 1 = 1;
if argc = 0;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Couldn't this be replaced to something like dow argc > 0?

@brandonp42
Copy link
Author

I am trying to understand why this code even needs to calculate how many args there are being passed.

In the ilePGM() function (invoked for mode="opm") it needs to know argc so it can pass that directly to _CALLPGMV.

While ileSRV() (again invoked for mode="opm") doesn't use _CALLPGMV, it still needs to know how argc to decide which generic prototype to use based on how many parameters it should pass on. Basically this function used for mode="opm" gets around the _ILECALL (lack of) operational descriptor issue by using generic prototypes that allows RPG to build the operational descriptor that subsequent RPG functions need for %PARMS(). I did consider changing it to use a single generic prototype with all the parameters set for OPTIONS(*NOPASS) but started to get more uncomfortable with that due to the testing situation so ultimately decided to just leave that be for now.

The argument array is being pointed to a global variable sArgvBegP, which gets set elsewhere. There's also another global variable sArgvSz, couldn't that just be used to calculate the count? I really hate global variables since it makes it hard to reason about the program flow and who sets what where, but it seems to me that whoever is setting up this array should know how many elements are in it already and it should be responsible for keeping the count (maybe we need a new global to track? 🤮).

I agree we really ought to add a new global argument count variable. Going back to automated testing though I was trying to make strategic localized changes instead of bigger picture stuff that would be worrisome without a good way to prove it all works right.

So FWIW I'd be fine if you want to leave this PR open until better testing is in place. Also I could change it back to a draft until then, however you'd like to approach it is totally fine with me.

Signed-off-by: Brandon Peterson <117427172+brandonp42@users.noreply.github.com>
Signed-off-by: Brandon Peterson <117427172+brandonp42@users.noreply.github.com>
Signed-off-by: Brandon Peterson <117427172+brandonp42@users.noreply.github.com>
@brandonp42 brandonp42 closed this Jan 30, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Calls to programs or service program functions with mode="opm" do not handle *OMIT parameters properly
3 participants