× 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.



[SNIP]
>      D ToUpper         PR            10I 0
>      D  InString                  32766A   Const Varying
>      D  OutString                 32766A   OPTIONS(*VARSIZE)
>
> The second parameter now becomes the target of the
> conversion, and the OPTIONS(*VARSIZE) allows you to pass a
> parameter whose length is 1 to 32766 bytes. You simply use
> %LEN(InString) inside the subprocedure to determine how
> much data was actually passed to your subprocedure. Then,
> be sure to "touch" only that many characters in the
> OUTSTRING parameter.

That assumes that InString and OutString are always the same length, I
suppose.  It'll work as long as you're careful to stick with single-byte
character sets, and you trust the programmer to make sure the two
parameters match in size.

I'd also declare options(*varsize) on InString as well as OutString, since
it doesn't change your logic at all, and will improve performance.  You
see, CONST lets the compiler help you convert the data -- if you pass a
fixed-length field, the compiler will magically transform it into a
varying when your procedure is called, and it will give it the length of
the fixed-length field.  So, if the user passes a 10A, the compiler will
create a 32k temp field, copy in the 10A bytes, and set the temp field's
varying length to 10, then call your procedure.  I'd use options(*varsize)
so that the compiler wouldn't need to create a 32k temp var, but rather a
12 byte temp var.  In either case you're not going to exceed the 10 bytes,
so why require them?

> 1.  Wouldn't you need to use %len(%trimr(InString)) because
> if the input parm used in the calling program is NOT a
> variable length field or a literal it won't be correct.

In Bob's example, the input parm *WAS* defined as VARYING.  There's no
need for extra work of the %trimr().  If the user wants his string
trimmed, let him trim it himself.


> 2.  Couldn't you just use:
>      D ToUpper         PR            10I 0
>      D  String                    32766A   OPTIONS(*VARSIZE)
>
> And use the same parameter for input and output?  Wouldn't
> that cut down on the amount of storage that is allocated
> when the procedure is called?

These parameters are passed by reference.  The only storage that's
allocated when the procedure is called is a pointer...  16 bytes..  big
hairy deal :)

Though, I suppose that with the two-parm solution, the caller needs to
make two copies of his string, which does mean allocating extra memory.
Especially since Bob didn't use options(*varsize) on the input parameter,
so the compiler will go ahead and allocate a 32k buffer :)

Your solution would work.  However, the way you've coded it, there's no
way to tell how much data was passed to the procedure.   You'd need to
either add another parameter so that the user could pass the field length
or you'd have to use operational descriptors.  (I hate opdesc, but that's
me)

So, why would you want to use Bob's two-parm example instead?   Well, for
one thing it allows you to keep the old variable intact if you want it.
For another, it automagically calculates the length of the input field
without resorting to OPDESC.  It allows you to pass a literal value if you
want (though that's not very useful in a ToUpper() routine, it would be
useful in a  ToAscii() routine, or any number of other places)

> And would you really need or want to use *VARSIZE?  You
> could use %len(%trim(String)) or CHECKR to get the length
> of the field.

If you don't use *VARSIZE then the person who calls the procedure has to
declare his variable exactly the same as yours.   If I have a 10A field,
for example, that I want to convert to uppercase, I'd have to move it to a
32k field before calling your procedure.

By using *VARSIZE and passing a separate length, the same procedure can be
made to operate on ANY length field.

Using %trim() requires code to be run that reads through your string
character by character looking for the first & last non-blank characters.
That takes time, and it's totally unnecessary in this circumstance.  Why
would you ever use %trim() unless you absolutely had to?  Just because
%trim() was released two releases before VARYING, so you learned it
first?

> Or as I have seen in other exaples pass the length along
> (which you'd need to do in either place, where it happens
> in the program or in the procedure, I wouldn't think it
> would matter).

Yeah, either pass the length or use OPDESC.  I always opt for the former,
since it both gives the user more control (maybe he only wants to convert
part of teh string to uppercase), it performs better (no extra procedure
call), and it's easier to code.

Of course, it also gives the user an extra bit of rope to hang himself
with.

VARYING is much the same thing as passing the length separately, though
when using in conjunction with CONST you can achieve some really nice
effects that passing the length separately can't do.  (Which is what Bob
did in his example)

Okay, this message is too long.  I've said enough :)


As an Amazon Associate we earn from qualifying purchases.

This thread ...

Follow-Ups:
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.