|
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 mailing list archive is Copyright 1997-2025 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.