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



CEEDOD is what you need to use to get the length of VARSIZE fields and it requires Operational Descriptors.

However, it is important to remember that the Operational Descriptors of one procedure are not automatically passed to a call to another procedure.

Say a Service Program has two procedures, Procedure 1 and Procedure 2. Both have Operational Descriptors OPDESC and an in/out field defined as Char(##) Options(*Varsize). The ## would be the "max" size of the field.
If your program calls Procedure 1, which then calls Procedure 2, then Procedure 2 does not get the Operational Descriptor from your Program.



Program1:

Ctl-Opt Main(Program1);
Dcl-Proc Program1;
DCL-S LOCVAR CHAR(15);
If Procedure1( Locvar );
// It is true
Endif;
End-Proc;


Service Program Procedures:

Ctl-Opt nomain;
Dcl-Proc Procedure1 Export;
Dcl-Pi Procedure1 Ind Opdesc;
Input Char(20) Options(*Varsize);
End-Pi;
Return Procedure2( Input);
End-Proc;

Dcl-Proc Procedure2 Export;
Dcl-Pi Procedure2 Ind Opdesc;
Input Char(20) Options(*Varsize);
Size Int(10) Const Options(*Nopass);
End-Pi;
Dcl-S Dsctyp Int(10);
Dcl-S Dtatyp Int(10);
Dcl-S Dscinf1 Int(10);
Dcl-S Dscinf2 Int(10);
Dcl-S Arglen Int(10);
CEEDOD(%Parmnum(Input) :DscTyp :DtaTyp :DscInf1 :DscInf2 : Arglen:*OMIT);
If Arglen = 0;
Return *Off;
Endif;
%Subst( Input : 1 : Arglen) = 'PARTYTIME';
Return *ON;
End-Proc;


In this case Procedure2 will receive a varsize of 20, not 15.

When I came across this issue the only way I could see to resolve it was to add the Size parm to Procedure 2.
Then Procedure 1 passes the size of its input.
However, when Procedure 2 is used directly it gets the correct operational descriptor.


Ctl-Opt nomain;

Dcl-Pr Ceedod;
Pr_Argnum Int(10) CONST;
Pr_Dsctyp Int(10);
Pr_Dtatyp Int(10);
Pr_Dscinf1 Int(10);
Pr_Dscinf2 Int(10);
Pr_Arglen Int(10);
Pr_Fbcod Char(12) OPTIONS(*OMIT);
End-Pr;

Dcl-Proc Procedure1 Export;
Dcl-Pi Procedure1 Ind Opdesc;
Input Char(20) Options(*Varsize);
End-Pi;
Dcl-S Dsctyp Int(10);
Dcl-S Dtatyp Int(10);
Dcl-S Dscinf1 Int(10);
Dcl-S Dscinf2 Int(10);
Dcl-S Arglen Int(10);
CEEDOD(%Parmnum(Input) :DscTyp :DtaTyp :DscInf1 :DscInf2 : Arglen:*OMIT);
Return Procedure2( Input : Arglen);
End-Proc;

Dcl-Proc Procedure1 Export;
Dcl-Pi Procedure1 Ind Opdesc;
Input Char(20) Options(*Varsize);
Size Int(10) Const Options(*Nopass);
End-Pi;
Dcl-S Dsctyp Int(10);
Dcl-S Dtatyp Int(10);
Dcl-S Dscinf1 Int(10);
Dcl-S Dscinf2 Int(10);
Dcl-S Arglen Int(10);
CEEDOD(%Parmnum(Input) :DscTyp :DtaTyp :DscInf1 :DscInf2 : Arglen:*OMIT);
If Size > Arglen;
Arglen = Size;
Endif;

If Arglen = 0;
Return *Off;
Endif;
%Subst( Input : 1 : Arglen) = 'PARTYTIME';
Return *ON;
End-Proc;

Chris Hiebert
Senior Programmer/Analyst
Disclaimer: Any views or opinions presented are solely those of the author and do not necessarily represent those of the company.


-----Original Message-----
From: RPG400-L [mailto:rpg400-l-bounces@xxxxxxxxxxxx] On Behalf Of Dan
Sent: Tuesday, May 16, 2017 5:41 PM
To: RPG400-L@xxxxxxxxxxxx
Subject: 2 calls to same program using different parameter lengths

I am at my wit's end. I thought I knew this stuff, but maybe I've just been lucky before with scenarios that didn't cause problems.

I created a utility program that masks account numbers, changing all but the last 4 digits to asterisks. It has two parameters, both 20 byte characters, the first is input, the second is output. The program that will call this utility program has a choice of passing either two 20-character fields or two 17-character fields. The call using the 20-character fields as parameters works fine. The call using the 17-character fields as parameters does not. I've tried several D-spec keywords, VARYING, OPTIONS(*VARSIZE), maybe others, to no avail. VARYING doesn't work, I think, because the fields in the calling program that I want to pass as parameters are not also VARYING; the compile issued RNF7535 (The type and attributes of parameter 1 do not match those of the prototype). I've created a short calling program that mimics what is happening in the larger program that I want to use the new utility program
in:

d CA9802R pr ExtPgm( 'CA9802R' )
d 20 Options( *VarSize )
d 20 Options( *VarSize )

d AC_ACCT s 20 Inz
d zz_ACCT s 20 Inz
d XX_OACHACT s 17 Inz
d zz_OACHACT s 17 Inz

ac_Acct = '12345678901234567890';
Callp CA9802R( ac_Acct : zz_Acct );
returns '****************7890'

XX_OACHACT = 'Just11Chars';
Callp CA9802R( xx_OACHACT : zz_OACHACT );
returns '**************** '

*inLR = *on;
DUMP(A);

Program CA9802R:
h DftActGrp( *No )
d CA9802R pi
d p_Account# 20a Options( *VarSize )
d p_MaskedAcct# 20a Options( *VarSize )

d MaskAccount# pr 20a
d AccountNbr 20a Const Options( *Trim )

p_MaskedAcct# = MaskAccount#( p_Account# );
*inLR = *on;
Return;

p MaskAccount# b
d MaskAccount# pi 20a
d AccountNbr 20a Const Options( *Trim )

d wAccountNbr s 20a
d Length s 3 0
d #ofAsterisks s 3 0
d i s 3 0

wAccountNbr = AccountNbr;
Length = %len( %trimr( wAccountNbr ));
If Length > 1;
If Length >= 8;
#ofAsterisks = Length - 4; // Mask all but last 4 digits
Else;
#ofAsterisks = Length / 2; // Mask half of the digits
Endif;
For i = 1 to #ofAsterisks;
%subst( wAccountNbr : i : 1 ) = '*';
Endfor;
Endif;
Return wAccountNbr;
p MaskAccount# e

When I debugged CA9802R, the p_Account# field for the second call had a junk character in position 18. I understand it's because the parameter passed from the calling program is 17 bytes, but I thought one of the "vary*" keywords would allow me to do this without having to pass a length parameter.

What am I missing here?

- Dan
--
This is the RPG programming on the IBM i (AS/400 and iSeries) (RPG400-L) mailing list To post a message email: RPG400-L@xxxxxxxxxxxx To subscribe, unsubscribe, or change list options,
visit: http://lists.midrange.com/mailman/listinfo/rpg400-l
or email: RPG400-L-request@xxxxxxxxxxxx
Before posting, please take a moment to review the archives at http://archive.midrange.com/rpg400-l.

Please contact support@xxxxxxxxxxxx for any subscription related questions.

Help support midrange.com by shopping at amazon.com with our affiliate link: http://amzn.to/2dEadiD

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.