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
As an Amazon Associate we earn from qualifying purchases.