ibmi-brunch-learn

Announcement

Collapse
No announcement yet.

Calling a command in CL with a variable number of values for one parameter?

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

  • Calling a command in CL with a variable number of values for one parameter?

    Many commands have parameters that accept multiple values. For example, STRJRNPF:

    STRJRNPF FILE(FILE1 FILE2 FILE3) JRN(MYJRN)

    If I was to write a CL program that needed to call STRJRNPF, I would have to have a separate CL field for each filename in the FILE parameter:

    STRJRNPF FILE(&FILE1 &FILE2 &FILE3) JRN(MYJRN)

    If I was to write a CL program where the number of files I needed to start journalling on was not known (the CL program is passed a list of one or more filenames)? Is there a way to specify a variable length list of filenames for the FILE parameter?

    To clarify, I do not actually want to do this, and I know that for this example I could call it in a loop or use QCMDEXC with a command string. I just want to know if it is possible to specify a command in a normal CL source line with a variable length list of values for a parameter.

  • #2
    Short answer: No. Long answer: Nope. (unless there's been an enhancement that I'm not aware of) Each variable represents one element in a list, the command processor does not parse the contents of variables.

    Comment


    • #3
      The normal answer to this question is to use QCMDEXC, but the OP slready ruled that out. Why is that? Why rule this out?

      Comment


      • #4
        I was just curious if it was possible.

        On a sidenote - if I ran a command with QCMDEXC, would I be able to MONSMG for escape errors returned from the command in the same way?

        Comment


        • #5
          Yes you can. Here's a blog post about that very subject: http://www.rpgpgm.com/2013/10/captur...ror-codes.html

          Comment


          • #6
            It can be possible in fairly limited cases, though it can be unlikely for lists greater than, say, 10 elements or so. It becomes cumbersome as the list grows.

            First, you do indeed need a variable per element when you populate for compiled commands. However, the variables don't always actually have to contain "data". Consider a theoretical command named THECMD with a FILE() parm that allows from one to three values. In source, it could look this way:
            Code:
            THECMD FILE( &f1 &f2 &f3 )
            It's possible to precede that with something like:
            Code:
            chgvar  &f1  'MYFILE1'
            chgvar  &f2  'MYFILE2'
            chgvar  &f3  '*N'
            The would result in only two file names actually being passed into THECMD. The third effectively becomes a "null" value and is ignored. If all &fx variables are initialized to '*N', you can populate only the needed ones with actual names as long as all variables are coded for the parm.

            I've done that in a few limited cases, but I'd probably go a different way for your example.

            I'd probably pass a list into the CL in whatever way seemed appropriate. Perhaps by parm, perhaps by processing a list from an API, perhaps from whatever is generating the list of file names. Then I'd simply run STRJRNPF in a loop over the list, processing one file at a time. It's not clear why anything else needs to be considered.
            Tom

            There are only two hard things in Computer Science: cache invalidation, naming things and off-by-one errors.

            Why is it that all of the instruments seeking intelligent life in the universe are pointed away from Earth?

            Comment


            • #7
              Originally posted by tomliotta View Post
              First, you do indeed need a variable per element when you populate for compiled commands. However, the variables don't always actually have to contain "data". Consider a theoretical command named THECMD with a FILE() parm that allows from one to three values. In source, it could look this way:
              Code:
              THECMD FILE( &f1 &f2 &f3 )
              It's possible to precede that with something like:
              Code:
              chgvar &f1 'MYFILE1'
              chgvar &f2 'MYFILE2'
              chgvar &f3 '*N'
              That's a cool idea, but it didn't work for me when I tried it. I got a CPD0073 error saying "*N not valid as a list value for parameter P1."

              Maybe I need some additional keyword on the PARM in my CMD definition?

              Code:
                           CMD        PROMPT('Test')                               
                           PARM       KWD(P1) TYPE(*CHAR) LEN(10) MAX(2)           +
                                         PROMPT('Parm 1')
              Code:
              dcl &p1 type(*char) len(10) value('abc')  
              dcl &p2 type(*char) len(10) value('*N')   
              TEST_CMD P1(&P1 &P2)

              Comment


              • #8
                Ah, you're right... wrong kind of list. Should've tested the explicit case. It requires a 'mixed list', e.g., SBMJOB LOG( &a &b &c). Even then, elements require defaults.

                Odd, though... maybe it's a matter of how long ago I learned about "*N" in the first place: 1984, processing lists of devices to vary on/off. Maybe CPF wasn't as discerning or years have simply made it seem more useful than it actually is. When I saw your post, I searched through old code and only found examples that didn't fit. (Some were 'very old'.)

                It's probably why I've done such things in loops for so long.
                Last edited by tomliotta; April 19, 2017, 03:10 AM.
                Tom

                There are only two hard things in Computer Science: cache invalidation, naming things and off-by-one errors.

                Why is it that all of the instruments seeking intelligent life in the universe are pointed away from Earth?

                Comment

                Working...
                X