× The internal search function is temporarily non-functional. The current search engine is no longer viable and we are researching alternatives.
As a stop gap measure, we are using Google's custom search engine service.
If you know of an easy to use, open source, search engine ... please contact support@midrange.com.



pcrtXMLDoc        B                   Export
d crtXMLDoc       PI             1N
d  FlrPth                      256    const
d                                     varying
d  DocNam                       40    const
d                                     varying
d  ErrId                              like(ref.msgid)

Why would you want to pass the folder and document name in separate parameters? That only makes it more complicated to call.


I thought that by declaring the parameters (FlrPth & DocNam) as varying
I could cater for the various lengths that these strings might be passed
with.

Yes and no.. by passing them as 40A VARYING and 256A VARYING you're limiting your caller to always have a folder thats 256 or shorter, and a document name that's 40 or shorter. Not sure why you'd want to impose those limits, but I guess if you're happy with them, who am I to complain?


d docID           s            256A
C                   EVAL      docID=  %trim(FlrPth) + %trim(DocNam) + x'00'

YUCK. Not only are the folder and document limited to 256 and 40 (respectively), but the total length of both of them is now limited to 255. (Though, your code doesn't check those limits, so if the caller exceeds 255, you'll just get garbage in the filename).

also, please notice that your prototype has options(*string) on it. What that does is automatically add a x'00' to the end for you -- makes me wonder why you're adding it manually?

Worse, you didn't put a directory separator in between them, so the caller has to stick an extra '/' in the filename to make it legal, and that makes this subprocedure inconsistent with everything else that uses the IFS.


C                   EVAL      FilDes = open(%addr(DOCID)
C                                      :  O_CREAT+O_TRUNC+O_WRONLY
C                                      : (6*64)+(6*8)+(6))

You should NOT use %addr() when you use options string. However because you didn't use the VARYING field for DocID, you'll have to use %trimr().

Also, that 3rd parameter is very hard to read -- consider using named constants to make it clearer for the next guy.

If you want to keep the separate Folder and Doc parameters, I'd code it like this:

 D RW              C                   CONST(6)
 D OWNER           C                   CONST(64)
 D GROUP           C                   CONST(16)
 D PUBLIC          C                   CONST(1)

   FilDes = open( FlrPth + '/' + DocNam
                : O_CREAT+O_TRUNC+O_WRONLY
                : RW*OWNER + RW*GROUP + RW )

However, if you want to use only one variable for filename (and I highly recommend that) then do this:

  d crtXMLDoc       PI             1N
  d  FlrPth                         *   value options(*string)
  d  ErrId                              like(ref.msgid)

and then open it like this:

   FilDes = open( FlrPth
                : O_CREAT+O_TRUNC+O_WRONLY
                : RW*OWNER + RW*GROUP + RW )

That way, the caller can pass any variable (either varying or fixed) of any length to the subprocedure, and there's no limitations. The disadvantage, however, is that the caller has to remember to trim the blanks off, which seems to be confusing for a lot of people. So as an alternative, you could do it this way:

  d crtXMLDoc       PI             1N
  d  FlrPth                     1024A   varying const
  d  ErrId                              like(ref.msgid)

Although that still limits them to 1024 chars, it's probably enough for just about anything. Then open it this way:

   FilDes = open( %trimr(FlrPth)
                : O_CREAT+O_TRUNC+O_WRONLY
                : RW*OWNER + RW*GROUP + RW )

That way, you don't have to worry about the caller forgetting to trim the blanks, since you've done it for him. If the caller does have the folder and object name in separate variables he can easily combine them when he calls your proc like this:

    RC = crtXMLDoc( %trimr(Folder) + '/' + Object
                  : ErrId )

That's fairly easy for the caller to do -- much easier than trying to split the object and folder name if he should happen to have them combined in one variable (which is the most common)

I thought that by using %addr(DOCID) I would match the prototype
requiring a pointer, and appending the x'00' would make it a null
terminated string.

That would be true if you didn't have options(*string) on the prototype. However, with options(*string) RPG will automatically convert a variable or expression by copying it to temporary memory and adding the x'00' to the end automatically.

When you pass %ADDR(), RPG ignores the options(*string) and doesn't do the extra work for you.

When you pass the variable name, it copies it to temp storage and automatically adds the x'00' for you.

I'm not sure why you thought you hadd to pass %ADDR(), since you cited my e-book, and my e-book NEVER uses %ADDR()!!


As an Amazon Associate we earn from qualifying purchases.

This thread ...

Replies:

Follow On AppleNews
Return to Archive home page | Return to MIDRANGE.COM home page

This mailing list archive is Copyright 1997-2024 by midrange.com and David Gibbs as a compilation work. Use of the archive is restricted to research of a business or technical nature. Any other uses are prohibited. Full details are available on our policy page. If you have questions about this, please contact [javascript protected email address].

Operating expenses for this site are earned using the Amazon Associate program and Google Adsense.