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



On Tue, 24 Feb 2004, Wim wrote:
> Yes, I either declare it as type *X or as *char Len(1). Am I right in
> assuming that the definition in the command is merely for the compiler to do
> some preliminary type checking?

When you use TYPE(*X) it's also required that you pass VARY(*YES) and
PASSATR(*YES), I believe.  If you overwrote the special bytes that go at
the start of a string when you use PASSATR(*YES) or VARY(*YES), it could
certainly cause the error that you're describing.

Likewise, if you define it as TYPE(*CHAR) with VARY(*YES) and overwrite
the first two bytes with incorrect data, you'll get an error.

You also have to be very careful not to exceed the space that has been
allocated to the variable.   For example, if the variable is
TYPE(*CHAR) LEN(10), and your RPG does a myKeyVal = *blanks you'll write
blanks not only to the 10 bytes of of passed variable, but also to the
2038 bytes after it, so you have to do something like:

     %subst(myKeyVal: 1: myKeyValLen) = *blanks

To make sure that you don't write blanks into areas of memory that you
weren't supposed to access (and therefore causing random errors to occur)

In an effort to better understand your predicament, I wrote some test
programs, which worked in my environment.   One that used type(*X) and one
that used type(*CHAR).   As I said, these work for me -- though I didn't
test them very thoroughly.  Perhaps looking at them will help you get on
the right track.

First example:  Using type(*X) -- note that a separate length does NOT
need to be passed because the length is already sent as part of the
parameter, compliments of VARY(*YES)

CL program that runs RTVQ:

PGM
     DCL VAR(&TYPE) TYPE(*CHAR) LEN(100) VALUE('TEST')

     RTVQ FILE('/DOESNT/REALLY/MATTER.TXT') KEY('TYPE') +
          KEYVAL(&TYPE)

     SNDPGMMSG MSGID(CPF9897) MSGF(QCPFMSG) MSGDTA(&TYPE) +
                 MSGTYPE(*COMP)
ENDPGM


Command source:
             CMD        PROMPT(TEST)
             PARM       KWD(FILE) TYPE(*PNAME) LEN(2048) MIN(1) +
                          PROMPT('File')
             PARM       KWD(KEY) TYPE(*CHAR) LEN(10) MIN(1) +
                          PROMPT('Key')
             PARM       KWD(KEYVAL) TYPE(*X) LEN(1) RTNVAL(*YES) +
                          MIN(1) VARY(*YES *INT2) PASSATR(*YES) +
                          PROMPT('CL var for returned key value')


CPP for RTVQ, written in ILE RPG (I used /FREE, though you could do the
same thing in fixed-format):

     H DFTACTGRP(*NO) OPTION(*SRCSTMT: *NODEBUGIO: *NOSHOWCPY)

     D TypeX           DS                  qualified based(prototype_only)
     D   Attr                         1A
     D   Len                          5I 0
     D   Data                      2048A

     D QMHSNDPM        PR                  ExtPgm('QMHSNDPM')
     D   MessageID                    7A   Const
     D   QualMsgF                    20A   Const
     D   MsgData                  32767A   const options(*varsize)
     D   MsgDtaLen                   10I 0 Const
     D   MsgType                     10A   Const
     D   CallStkEnt                  10A   Const
     D   CallStkCnt                  10I 0 Const
     D   MessageKey                   4A
     D   ErrorCode                32767A   options(*varsize)

     D dsEC            DS                  qualified
     D   BytesPrv                    10I 0 inz(0)
     D   BytesAvl                    10I 0 inz(0)

     D Msg             s            100A   varying
     D MsgKey          s              4A

     D RTVQR4          PR                  ExtPgm('RTVQR4')
     D   peFile                    2048A   const
     D   peKey                       10A   const
     D   peKeyVal                          likeds(TypeX) options(*varsize)

     D RTVQR4          PI
     D   peFile                    2048A   const
     D   peKey                       10A   const
     D   peKeyVal                          likeds(TypeX) options(*varsize)

      /free

          if (peKeyVal.attr <> x'04');
             Msg = 'You must pass a *CHAR variable for KEYVAL';
             QMHSNDPM( 'CPF9897'
                     : 'QCPFMSG   *LIBL'
                     : Msg
                     : %len(Msg)
                     : '*ESCAPE'
                     : '*'
                     : 2
                     : MsgKey
                     : dsEC);
          endif;

          %subst(peKeyVal.data: 1: peKeyVal.Len) = *blanks;

          select;
          when  peKey = 'TYPE';
              %subst(peKeyVal.data: 1: peKeyVal.Len) = *all'T';
          when  peKey = 'NOTTYPE';
              %subst(peKeyVal.data: 1: peKeyVal.Len) = *all'N';
          other;
              %subst(peKeyVal.data: 1: peKeyVal.Len) = *all'O';
          endsl;

          *inlr = *on;
      /end-free


Here's the example that uses TYPE(*CHAR).  For this one, I tried to do
exactly what you described in your message, and used LEN(1) with
VARY(*NO).  (Since VARY would most likely not work when I specify LEN(1),
anyway...)  and that means that I need a separate KEYVALLEN parameter:

PGM
     DCL VAR(&TYPE) TYPE(*CHAR) LEN(100) VALUE('TEST')

     RTVQ2 FILE('/DOESNT/REALLY/MATTER.TXT') KEY('TYPE') +
          KEYVAL(&TYPE) KEYVALLEN(100)

     SNDPGMMSG MSGID(CPF9897) MSGF(QCPFMSG) MSGDTA(&TYPE) +
                 MSGTYPE(*COMP)
ENDPGM

             CMD        PROMPT(TEST)
             PARM       KWD(FILE) TYPE(*PNAME) LEN(2048) MIN(1) +
                          PROMPT('File')
             PARM       KWD(KEY) TYPE(*CHAR) LEN(10) MIN(1) +
                          PROMPT('Key')
             PARM       KWD(KEYVAL) TYPE(*CHAR) LEN(1) RTNVAL(*YES) +
                          MIN(1) PROMPT('CL var for returned key +
                          value')
             PARM       KWD(KEYVALLEN) TYPE(*DEC) LEN(4 0) MIN(1) +
                          PROMPT('Length of KEYVAL')

     H DFTACTGRP(*NO) OPTION(*SRCSTMT: *NODEBUGIO: *NOSHOWCPY)

     D RTVQR4          PR                  ExtPgm('RTVQR4')
     D   peFile                    2048A   const
     D   peKey                       10A   const
     D   peKeyVal                  2048A   options(*varsize)
     D   peKeyValLen                  4P 0 const

     D RTVQR4          PI
     D   peFile                    2048A   const
     D   peKey                       10A   const
     D   peKeyVal                  2048A   options(*varsize)
     D   peKeyValLen                  4P 0 const

      /free

          %subst(peKeyVal: 1: peKeyValLen) = *blanks;

          select;
          when  peKey = 'TYPE';
              %subst(peKeyVal: 1: peKeyValLen) = *all'T';
          when  peKey = 'NOTTYPE';
              %subst(peKeyVal: 1: peKeyValLen) = *all'N';
          other;
              %subst(peKeyVal: 1: peKeyValLen) = *all'O';
          endsl;

          *inlr = *on;
      /end-free

Hope that answers your question...

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.