ibmi-brunch-learn

Announcement

Collapse
No announcement yet.

Input/output parameter changes.

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Input/output parameter changes.

    Good day.
    I need help, I have a task to modify an old RPG program.
    The modification means , that I need to adapt this to the call programm with other input parameters.
    I have a problem.
    In the first case, the program is called with 1 parameter in the form of a DS with 10 fields.
    In the second case, the program is called with 10 other parameters, in the form of 10 variables.
    Code:
    DCPLYCPUFR2             PI
    D pDsInp_Output                               Options(*Omit:*NoPass)
    D                                                                likeds(DsInp_Output)
    D inName_From                                 Options (*NoPass) like(CMDFRM)
    D inName_To                                       Options(*NoPass) like(CMDTO)
    D inDate                                                 Options(*NoPass) like(CMDDTE)
    D inSQN                                                 Options(*NoPass) like(CMDSQN)
    D inCommand_Code                        Options(*NoPass) like(CMDCOD)
    D ioAnswer                                1A      Options(*NoPass)
    D ioResult                                   1A      Options(*NoPass)
    D ioError                                                Options(*NoPass) like(CMDERR)
    D ioChild_FROM                      3A      Options(*NoPass)
    D ioChild_Date                         7S 0   Options(*NoPass)
    D ioChild_SQN                       10P 0   Options(*NoPass)
    When I call a program with DS, the parameters are passed correctly.
    When the call is made with 10 parameters, the program does not work correctly.
    Attached Files

  • #2
    Can you post your CALL Command?

    Comment


    • #3
      I can't change the call to the program. This call is used for calling another programmes

      Comment


      • #4
        My guess would be that you are not putting *OMIT for the first parameter (which is the data structure) when you're trying to call the program with the individual parameters. You still have to account for it even though it's not being passed:

        Callp(e) CPLYCPUFR2(*OMIT:CMDFRM:CMDTO: and so on...)

        Comment


        • #5
          Originally posted by Brian Rusch View Post
          My guess would be that you are not putting *OMIT for the first parameter (which is the data structure) when you're trying to call the program with the individual parameters. You still have to account for it even though it's not being passed:

          Callp(e) CPLYCPUFR2(*OMIT:CMDFRM:CMDTO: and so on...)
          I created a test call program:
          Code:
          CallP(E) CPLYCPUFR2 ( *Omit
          : inName_From
          : inName_To
          : inDate
          : inSQN
          : inCommand_Code
          : ioAnswer
          : ioResult
          : ioError
          : ioChild_FROM
          : ioChild_Date
          : ioChild_SQN
          );
          transmitted trash ....

          Comment


          • #6
            Maybe I described the problem incorrectly.
            The program (CPLYCPUFR2 ) is called from another program with 11 parameters ( inName_From : inName_To : inDate: inSQN and so on.....)
            I'm upgrading the program to be called from another program that can only transmit to the DS.
            Call I can't upgrade.
            Nothing works when using Options(*Omit:*NoPass) .... transmit trash

            Comment


            • #7
              The work that the computer has to do for these two calls is very different. The actual machine instructions to be executed... in the case where the first parameter is a data structure, it has to access one memory location and read X bytes from that location (i.e. the length of the data structure in bytes.) In the second, it has to read shorter lengths from 12 different memory locations.

              You seem to assume that if you code both of them on one prototype, it'll just magically pick one or the other and fill it in properly for you. That's not how it works. Programmers tell the computer waht to do -- they don't expect the computer to figure it out for them.

              If the code is written properly (remember, we haven't seen the code) and you use *OMIT for the first parameter, then pass the remaining parameters, it will work properly. You are saying that you are "getting trash". That means the code wasn't written properly.

              You also show calls to it where you don't pass *OMIT, but still pass separate parameters. That isn't how this prototype was written to work. You say you can't change the call -- well, then why did you write the prototype this way?

              If you want the procedure to somehow determine whether it does/doesn't contain a data structure in the first parameter, then you need to write code to make that happen. It's not going to happen automatically.

              Comment


              • #8
                Simple rule of thumb:
                If a program is called from various other programs, and you have to change the parameter list for the called program, you'll have to include the other programs in your project in order to adjust the parameter list for each to still work against the called program.

                Exceptions to this rule:
                Yes, you can manipulate the code to avoid the change in parameters, but in doing so you'll have to ask yourself the following questions:
                • Is this still a structured change?
                • Would my colleagues or successor approve?

                Happy coding!
                -----------------
                Paul
                Sweden

                Comment


                • #9
                  Just to be clear.
                  I assume the old program is called with 10 individual parameter fields and you want to reduce this to 1 parameter that is a data structure
                  but still want to keep the possibility to call it with 10 individual parameter fields that means the new program can be called with 11 parameters.

                  Why not keep the old program as it is with the 10 individual fields and make a new program with 1 parameter that is the data structure.
                  This new program could move data to and from the data structure to/from the individual fields.

                  An alternative is this:
                  You take a copy of the old program to a new program and modify the new program to use the data structure instead.
                  Then you clear all code in the old program but don't change the 10 parameters. Instead you use them to call the new program via the data
                  structure. Thus you don't have to make any changes to the way the existing programs calls the program.

                  Something like this
                  • oldPGM called with 10 parameters
                  • move the parameters to the data structure
                  • call newPGM with 1 parameter ( the data structure )
                  • move the data from the data structure to the parameter fields
                  • return
                  New programs can be coded to call the newPGM using the data structure as parameter.

                  Comment


                  • #10
                    Originally posted by Vinori_Vlad View Post
                    Good day.
                    I need help, I have a task to modify an old RPG program.
                    The modification means , that I need to adapt this to the call programm with other input parameters.
                    I have a problem.
                    In the first case, the program is called with 1 parameter in the form of a DS with 10 fields.
                    In the second case, the program is called with 10 other parameters, in the form of 10 variables.
                    Code:
                    DCPLYCPUFR2 PI
                    D pDsInp_Output Options(*Omit:*NoPass)
                    D likeds(DsInp_Output)
                    D inName_From Options (*NoPass) like(CMDFRM)
                    D inName_To Options(*NoPass) like(CMDTO)
                    D inDate Options(*NoPass) like(CMDDTE)
                    D inSQN Options(*NoPass) like(CMDSQN)
                    D inCommand_Code Options(*NoPass) like(CMDCOD)
                    D ioAnswer 1A Options(*NoPass)
                    D ioResult 1A Options(*NoPass)
                    D ioError Options(*NoPass) like(CMDERR)
                    D ioChild_FROM 3A Options(*NoPass)
                    D ioChild_Date 7S 0 Options(*NoPass)
                    D ioChild_SQN 10P 0 Options(*NoPass)
                    When I call a program with DS, the parameters are passed correctly.
                    When the call is made with 10 parameters, the program does not work correctly.
                    It is not enough to describe the parameter as *omit in the prototype. It is also necessary to check in the procedure itself - whether *omit was passed there or a real parameter.

                    By default, passing a parameter to a procedure in RPG occurs by reference (in other words, not the value, but the address of the parameter is pushed onto the stack of the called procedure). When we pass *omit there, *null is pushed onto the stack instead of the address.

                    Thus, if we describe a parameter as *omit , then before using it in a procedure, we must check

                    Code:
                    if %addr(pDsInp_Output) <> *null;
                    and only if this condition is met, we can use this parameter.

                    Are you sure that your procedure really has such a check?

                    Comment

                    Working...
                    X