User Spaces and List APIs

Now for the Calc specs. It's possible the user space already exists, so we start by calling the Ptr2UsrSpc API to try to get a pointer to it. By checking the BytesUsed field in the error feedback data structure, we can determine if we get an error. We'll make the bold assumption that any error is because the user space doesn't exist and call the CrtUsrSpc API to create it, followed by Ptr2UsrSpc again. By now, we should have a value in the pHeaderInfo pointer field that the HeaderInfo data structure is based on. It's now safe to use that data structure.


C                 CallP     Ptr2UsrSpc ('SRVPGMINFOQTEMP' :
C                              pHeaderInfo : ErrorInfo )

C                 If        BytesUsed > 0

C                 CallP     CrtUsrSpc ('SRVPGMINFOQTEMP' :
C                              'DTA' : 10000 : '*' : '*ALL' :
C                              'Srv Pgm Info': '*YES' : ErrorInfo)

C                 CallP     Ptr2UsrSpc('SRVPGMINFOQTEMP' :
C                               pHeaderInfo : ErrorInfo )
C                 EndIf

Next we call the ListPgmInf API passing the required parameters, including the list of programs we want information for, which in our example is *ALL programs in the library whose name was passed to the program as a parameter.

C                 CallP     ListPgmInf('SRVPGMINFOQTEMP': 'PGML0200'
C                              : AllPrograms + Library: ErrorInfo)

Once the API completes its processing, we have the required information in the user space and can begin processing it. We know that the first list item begins ListOffSet bytes from the beginning of the user space. So we can now set the basing pointer for our SrvPgmInf DS, which represents the list details, by adding the ListOffSet value to the pHeaderInfo pointer. We can now reference the data in the SrvPgmInf data structure.

C                 Eval      pSrvPgmInf = pHeaderInfo + ListOffset

From here, the logic is mostly "ordinary" RPG logic, with the exception of the pointer manipulation to move through the list. (Note: We know how many entries to process (NbrEntries) and the length of each entry (EntryLen) from the HeaderInfo data structure.) As we loop through the list, we update any program that references our target service program. Then we move to the next list item by taking the pointer to the current item and adding the entry length.

C                 For       I = 1 to NbrEntries

C                 If        BndSrvPgm = SrvPgmInput
C                 Eval      Command = 'UPDPGM ' + %Trim(PgmLib) +
C                               '/' + %Trim(Pgm)
C                 CallP     UpdPgm (Command : %Len(Command))
C                 EndIf

C                 Eval      pSrvPgmInf = pSrvPgmInf + EntryLen
C                 EndFor

Pretty simple, isn't it? User spaces, pointers and list APIs are really not difficult to use once you know the basics. Clearly, this program could be made more robust and functional than we've illustrated here. We kept the program as simple as possible to accomplish the task. We'll leave it up to you to use this as an example to write your own.


Jon Paris is a technical editor with IBM Systems Magazine and co-owner of Partner400.

Susan Gantner is a technical editor with IBM Systems Magazine and co-owner of Partner400.

comments powered by Disqus



2019 Solutions Edition

A Comprehensive Online Buyer's Guide to Solutions, Services and Education.

Are You Multilingual?

Rational enables development in multiplatform environments

IBM Systems Magazine Subscribe Box Read Now Link Subscribe Now Link iPad App Google Play Store
IBMi News Sign Up Today! Past News Letters