David FOXWELL wrote:
I just came across a program that has started trimming off the end of the character strings it was supposed to produce.
I found this :
writeText ( gTxt1 + gTxt2 + gTxt3 );
gTxt1, gTxt2, and gTxt3 are all 80 characters. The procedure expects a 132 character parameter.
If the gTxt fields are fixed length, then only 52 characters of gTxt2
and none of gTxt3 would be visible to writeText. If the gTxt fields are
varying length, then characters will be cut off if (%len(gTxt1) +
%len(gTxt2) + %len(gTxt3)) > 132.
I believe we have discussed before some kind of automatic conversion of parameters with prototypes that sometimes takes place.
You are basically doing the same thing as
eval shortString = longString;
where longString is 240 characters (80*3) and shortString is 132 characters.
To make it easier to demonstrate, suppose that the gTxt fields above are
5 long instead of 80, and that writeText expects a 7 character parameter
(call it wTxt).
/free
gTxt1 = 'ab';
gTxt2 = 'cde';
gTxt3 = 'fg';
writeText(gTxt1 + gTxt2 + gTxt3);
/end-free
So the question is, how does wTxt get it's value? The first thing that
happens is that RPG creates (or reuses) a temporary variable to hold the
result of the expression 'gTxt1 + gTxt2 + gTxt3'. So somewhere in
memory, we have
....5...10...15
temp = |ab cde fg '
Now writeText() is called, and it gets a pointer to temp*, which so that
(in essence) wTxt overlays temp. Since wTxt only 7 characters long, it
looks like 'ab cd', and so the output is cut off.
How should this problem be avoided?
Don't pass too much data to writeText().
How can I fix it? There are loads of callers to the same procedure, often using the same manner of sticking fields together.
No matter what, you're going to have to rebind (if writeText is in it's
own module or service program) or recompile (if writeText is /copy'ed or
<shudder> duplicated in each member) all the programs.
You could change all the callers so they stop passing too much data.
You could change writeText() so that it takes one varying character,
with options(*VARSIZE) and a long length. If my guess is right, and
writeText() is outputting to a printer file or database file with
lines/fields 132 long, then writeText() would have to take the long
string and chop it up into 132 character chunks.
Have fun!
Adam
* I'm ignoring for the moment passing by reference vs. passing by value,
because the end result is the same.
As an Amazon Associate we earn from qualifying purchases.