Difference between revisions of "Create Menu Message FIle (UTMNUMSGF)"
DaveLClarkI (talk | contribs) (→Summary) |
DaveLClarkI (talk | contribs) (→Sample Application) |
||
Line 7: | Line 7: | ||
== Sample Application == | == Sample Application == | ||
− | + | This command uses a REXX/400 command-processing program. Thus, an environment variable is required in order to always insure that the command can find the REXX source member in the library list. See the technical notes included in the comment headers of the associated source members below. | |
=== Command Definition === | === Command Definition === |
Revision as of 16:36, 31 January 2019
Contents
Summary
The following are the complete definitions and instructions needed for using the Create Menu Message FIle (UTMNUMSGF) command. This command creates a menu message file from the associated QQ member in lieu of the IBM STRSDA application. Note that STRSDA supports a menu selection command length of 115 characters while this command supports the full 132 characters that the message file supports for first-level message text.
By Dave Clark
Sample Application
This command uses a REXX/400 command-processing program. Thus, an environment variable is required in order to always insure that the command can find the REXX source member in the library list. See the technical notes included in the comment headers of the associated source members below.
Command Definition
Place the following in a QCMDSRC member named UTMNUMSGF and compile it.
/******************************************************************************/ /* Program Name: UTMNUMSGF */ /* Programmer: Dave L Clark I */ /* Date: September 25, 2012 */ /* Project/Request #: PetProj - Create Menu Message File */ /* Purpose: This command accepts either a menu message file name */ /* or(and) a menu command source member to (re)create a */ /* menu message file using the content of the specified */ /* or derived menu command source member. The menu */ /* command source member must have a QQ suffix if this */ /* command is to derive the name of the menu command */ /* source member. The format of the menu command source */ /* member must be the same format as used by the IBM SDA */ /* utility. Indeed, the QQ suffix is based on IBM SDA. */ /* */ /******************************************************************************/ /* Technical Notes: */ /* ---------------------------------------------------------------------------*/ /* */ /* This member requires a compile-time override because it uses REXX: */ /* */ /* PGM(*REXX) */ /* */ /* The following system setting must be in place in order for the operating */ /* system to be able to find REXX source members at command processing time: */ /* */ /* ADDENVVAR ENVVAR(QIBM_REX_FIND_SRCMBR) */ /* VALUE('*BYMBRNAME') */ /* LEVEL(*SYS) REPLACE(*YES) */ /* */ /******************************************************************************/ /* Modification Log: */ /* ---------------------------------------------------------------------------*/ /* */ /* Mod# Date User Description */ /* ---- ---------- ---------- ----------------------------------------------- */ /* M000 */ /******************************************************************************/ UTMNUMSGF: CMD PROMPT('Create Menu Message File') TEXT(*CMDPMT) + MAXPOS(1) HLPID(*CMD) HLPPNLGRP(UTMNUMSGF) PARM KWD(MSGF) TYPE(MSGF) MIN(1) PROMPT('Menu message + file') PARM KWD(TEXT) TYPE(*CHAR) LEN(50) DFT(*CMDMBRTXT) + SPCVAL((*CMDMBRTXT) (*BLANK)) CASE(*MIXED) + PROMPT('Text ''description''') PARM KWD(CMDMBR) TYPE(*NAME) LEN(10) DFT(*MSGF) + SPCVAL((*MSGF)) PROMPT('Menu command member') PARM KWD(SRCFILE) TYPE(SRCFILE) PROMPT('Source file') MSGF: QUAL TYPE(*NAME) LEN(10) SPCVAL((*CMDMBR)) QUAL TYPE(*NAME) LEN(10) DFT(*CURLIB) SPCVAL((*CURLIB)) + PROMPT('Library') SRCFILE: QUAL TYPE(*NAME) LEN(10) DFT(QMNUSRC) QUAL TYPE(*NAME) LEN(10) DFT(*LIBL) SPCVAL((*LIBL) + (*CURLIB)) PROMPT('Library')
REXX/400 Program
Place the following in a QREXSRC member named UTMNUMSGF and save it. Note that REXX is interpreted and therefore there is no associated compile command.
/* ************************************************************************** */ /* Program Name: UTMNUMSGF */ /* Programmer: Dave L Clark I */ /* Date: September 25, 2012 */ /* Project/Request #: PetProj - Create Menu Message File */ /* Purpose: This is the REXX program for the UTMNUMSGF command. */ /* It accepts either a menu message file name or(and) a */ /* menu command source member to (re)create a menu message*/ /* file using the content of the specified or derived menu*/ /* command source member. The menu command source member */ /* must have a QQ suffix if this command is to derive the */ /* name of the menu command source member. The format of */ /* the menu command source member must be the same format */ /* as used by the IBM SDA utility. Indeed, the QQ suffix */ /* is based on IBM SDA. */ /* */ /* ************************************************************************** */ /* Technical Notes: */ /* -------------------------------------------------------------------------- */ /* */ /* The following system setting must be in place in order for teh operating */ /* system to be able to find REXX source members at command processing time: */ /* */ /* ADDENVVAR ENVVAR(QIBM_REX_FIND_SRCMBR) */ /* VALUE('*BYMBRNAME') */ /* LEVEL(*SYS) REPLACE(*YES) */ /* */ /* ************************************************************************** */ /* Modification Log: */ /* -------------------------------------------------------------------------- */ /* */ /* Mod# Date User Description */ /* ---- ---------- ---------- ----------------------------------------------- */ /* M000 */ /* ************************************************************************** */ Parse Source _sys _env _pgm _file _lib .; /* get source attributes */ interact = ''; /* initialize receiver variable */ "RTVJOBA TYPE(&INTERACT)"; /* get batch vs. interactive flag */ If interact <> '1' Then Do /* if batch, send stdout to spool */ "OVRPRTF FILE(STDOUT) TOFILE(QSYS/QSYSPRT) USRDTA('"_pgm"')"; If rc <> 0 Then Do Call RelaySystemError; /* relay system errors to line 24 */ End End "OVRMSGF MSGF(WSMSGF) TOMSGF(SHR460/WSMSGF)" /* override message file */ If rc <> 0 Then Do Call RelaySystemError; /* relay system errors to line 24 */ End Parse Arg "MSGF(" MsgfLib "/" MsgfName ")", "TEXT(" MsgfText ")", "CMDMBR(" CmdMbr ")", "SRCFILE(" SrcLib "/" SrcFile ")"; /* get command arguments */ /* ------------------------------------------------------------------------ */ /* edit command arguments... */ /* ------------------------------------------------------------------------ */ If MsgfName = '*CMDMBR', & CmdMbr = '*MSGF', Then Do /* circular reference not allowed */ Call CancelPgm 'UTM0001', ''; /* send escape message */ End Select When MsgfName = '*CMDMBR' Then /* if msgf name based on member name */ Do If Right(CmdMbr,2) = 'QQ' Then Do /* if member name ends in QQ */ MsgfName = SubStr(CmdMbr,1,Length(CmdMbr)-2); /* strip off for msgf */ End Else Do /* else */ MsgfName = CmdMbr; /* msgf name will match member name */ End End When CmdMbr = '*MSGF' Then /* if member name based on msgf name */ Do CmdMbr = MsgfName || 'QQ'; /* add the same QQ suffix SDA uses */ End Otherwise End /* ------------------------------------------------------------------------ */ /* call the IBM API instead of using the RTVMBRD CL command because the */ /* CL command only searches in file name priority while the API optionally */ /* searches in member name priority -- which is necessary when dealing with */ /* source file members which can be promoted to different source files in */ /* the same library list. */ /* ------------------------------------------------------------------------ */ parm1 = Copies(' ',140); /* return data area */ parm2 = D2C(Length(parm1),4); /* available return length */ parm3 = 'MBRD0100'; /* format to return */ parm4 = Left(SrcFile,10,' ')||Left(SrcLib,10,' '); /* qualified file */ parm5 = Left(CmdMbr,10,' '); /* desired member */ parm6 = '0 force to char'; /* process file overrides? */ parm7 = Copies(' ',16+100); /* build error data structure */ parm7 = Overlay(D2C(0,4),parm7,1); /* set bytes available to zero */ parm7 = Overlay(D2C(0,4),parm7,5); /* set bytes returned to zero */ parm8 = '1 force to char'; /* member search algorithm */ "CALL PGM(QUSRMBRD) PARM(&PARM1 &PARM2 &PARM3 &PARM4", "&PARM5 &PARM6 &PARM7 &PARM8)"; If rc <> 0 Then Do Call RelaySystemError; /* relay system errors to line 24 */ End Parse Var parm1 19 MbrLib . 29 ., 39 FileAtr ., 49 MbrType . 59 ., 85 MbrTxt, 135 FileType 136 .; /* extract values from return data */ FileAtr = '*'FileAtr; /* match RTVMBRD-type output */ If FileType = '1' Then FileType = '*SRC '; /* match RTVMBRD-type output */ Else FileType = '*DATA'; /* match RTVMBRD-type output */ /* ------------------------------------------------------------------------ */ If FileAtr <> '*PF', | FileType <> '*SRC', Then Do /* source file not source file type? */ Call CancelPgm 'UTM0002', FileAtr||FileType; /* send escape message */ End If MbrType <> 'MNUCMD' Then Do /* src member not menu command type? */ Call CancelPgm 'UTM0003', MbrType; /* send escape message */ If rc <> 0 Then Do Call RelaySystemError; /* relay system errors to line 24 */ End End Select /* edit message file text parameter */ When MsgfText = '*CMDMBRTXT' Then Do MsgfText = MbrTxt; /* use command member text */ End When MsgfText = '*BLANK' Then Do MsgfText = ' '; /* use blank text */ End Otherwise Interpret("MsgfText =" MsgfText); /* get rid of enclosing quotes */ End "OVRDBF FILE(STDIN)", "TOFILE("||Strip(MbrLib)||"/"||Strip(SrcFile)||")", "MBR("||Strip(CmdMbr)||")"; /* point to source for final check */ If rc <> 0 Then Do Call RelaySystemError; /* relay system errors to line 24 */ End Parse Pull 13 mbrchk ',' mnuopt .; /* parse first line of command member */ If mbrchk <> Strip(CmdMbr), | (mnuopt <> '0' & mnuopt <> '1'), Then Do /* source line 1 not correct format? */ Call CancelPgm 'UTM0004', Left(mbrchk,10,' ')||mnuopt; /* escape message */ End /* ------------------------------------------------------------------------ */ /* begin processing... */ /* ------------------------------------------------------------------------ */ "DLTMSGF MSGF(&MSGFLIB/&MSGFNAME)"; /* delete any existing message file */ If rc <> 0, & rc <> 'CPF2105', Then Do Call RelaySystemError; /* relay system errors to line 24 */ End "CRTMSGF MSGF(&MSGFLIB/&MSGFNAME) TEXT(&MSGFTEXT)"; /* recreate msg file */ If rc <> 0 Then Do Call RelaySystemError; /* relay system errors to line 24 */ End ErrMsgDta = ''; /* initialize receiver variables */ ErrMsgId = ''; "RCVMSG MSGTYPE(*LAST) RMV(*NO) MSGDTA(&ERRMSGDTA) MSGID(&ERRMSGID)"; If ErrMsgId = 'CPC9801' Then Do /* completion message? */ MsgfLib = Strip(SubStr(ErrMsgDta,11,10)); /* get lib from message */ End linecnt = 1; /* initialize a line counter */ Do Until Length(cmdline) = 0 /* loop on cmd member content */ Parse Pull cmdline; /* retrieve commands file msg file */ linecnt = linecnt + 1; /* increment line counter */ If Length(cmdline) > 0 Then Do /* if a record was read */ Parse Var cmdline 13 seq cmd; /* parse out record components */ If Pos('+',Left(seq,5)) > 0 Then Do /* continued command? -- M002 */ Parse Var cmdline 13 seq '+' cmd; /* split at plus sign -- M002 */ Parse Pull cmdline2; /* get command extension -- M002 */ linecnt = linecnt + 1; /* increment line counter -- M002 */ Parse Var cmdline2 13 cmdext; /* omit leading time stamp -- M002 */ cmd = cmd||cmdext; /* merge command extension -- M002 */ End /* M002 */ cmd = Strip(cmd); /* remove leading/trailing blanks */ If Length(cmd) > 132 Then Do cmd = SubStr(cmd,1,132); /* msgf limit of 132 chars */ End If Datatype(seq,'W'), & Length(cmd) > 0, Then Do /* expected parm format? */ "ADDMSGD MSGID(USR"||Right(seq,4,'0')||")", "MSGF(&MSGFLIB/&MSGFNAME)", "MSG('"||DoubleApost(cmd)||"')"; /* add cmd as a message */ If rc <> 0 Then Do Call RelaySystemError; /* relay system errors to line 24 */ End End Else Do /* else report bad format */ /* Call Diagnostic 'UTM0005', Left(linecnt,4,' ')||seq cmd; M001 */ Call CancelPgm 'UTM0005', Left(linecnt,4,' ')||seq cmd; /* M001 */ End End End /* loop on cmd member content */ /* ------------------------------------------------------------------------ */ /* send completion message and return to system */ /* ------------------------------------------------------------------------ */ Call Completion 'UTM0000', Left(MsgfLib,10,' ') || Left(MsgfName,10,' '); Return; /* ------------------------------------------------------------------------ */ /* internal procedures follow */ /* ------------------------------------------------------------------------ */ BatchMsg: Procedure; Parse Arg mid, data; /* get arguments -- M001 */ Msg = Copies(' ',256); /* get message text with subs. data */ "RTVMSG MSGID("mid") MSGF(WSMSGF)", /* M001 */ "MSGDTA('"||DoubleApost(data)||"')", /* M001 */ "MSG(&MSG)"; If rc <> 0 Then Do Call RelaySystemError; /* relay system errors to line 24 */ End Say mid||':' Msg; /* put msg in spool file */ Return; CancelPgm: Procedure Expose interact; Parse Arg mid, data; /* get arguments -- M001 */ If interact <> '1' Then Do /* batch execution? */ Call BatchMsg mid, data; /* put escape message in a spool file */ End "SNDPGMMSG MSGID("mid") MSGF(WSMSGF)", /* M001 */ "MSGDTA('"||DoubleApost(data)||"')", /* M001 */ "MSGTYPE(*ESCAPE)"; If rc <> 0 Then Do Call RelaySystemError; /* relay system errors to line 24 */ End Return; Diagnostic: Procedure Expose interact; Parse Arg mid, data; /* get arguments -- M001 */ If interact <> '1' Then Do /* batch execution? */ Call BatchMsg mid, data; /* put escape message in a spool file */ End "SNDPGMMSG MSGID("mid") MSGF(WSMSGF)", /* M001 */ "MSGDTA('"||DoubleApost(data)||"')", /* M001 */ "MSGTYPE(*DIAG)"; If rc <> 0 Then Do Call RelaySystemError; /* relay system errors to line 24 */ End Return; Completion: Procedure Expose interact; Parse Arg mid, data; /* get arguments -- M001 */ If interact <> '1' Then Do /* batch execution? */ Call BatchMsg mid, data; /* put comp message in a spool file */ End "SNDPGMMSG MSGID("mid") MSGF(WSMSGF)", /* M001 */ "MSGDTA('"||DoubleApost(data)||"')", /* M001 */ "MSGTYPE(*COMP)"; If rc <> 0 Then Do Call RelaySystemError; /* relay system errors to line 24 */ End Return; DoubleApost: Procedure; /* double any apostrophes found */ Parse Arg haystack; /* get the argument string */ p = Pos("'",haystack); /* find first apostrophe */ Do While p > 0 /* loop if apostrophe found */ haystack = Insert("'",haystack,p);/* insert another apostrophe */ p = Pos("'",haystack,p+2); /* any more after new apostrophe? */ End /* loop if another apostrophe found */ Return haystack; /* return the new string */ /* -------------------- relay system errors to line 24 -------------------- */ RelaySystemError: Procedure Expose interact; ErrMsg = Copies(' ',256); /* initialize receiver variables */ ErrMsgDta = Copies(' ',256); ErrMsgId = Copies(' ',7); ErrMsgF = Copies(' ',10); ErrMsgfLib = Copies(' ',10); "RCVMSG MSGTYPE(*LAST) RMV(*YES) MSG(&ERRMSG) MSGDTA(&ERRMSGDTA)", "MSGID(&ERRMSGID) MSGF(&ERRMSGF) MSGFLIB(&ERRMSGFLIB)"; If interact <> '1' Then Do /* batch execution? */ Say Strip(ErrMsgId)||':' ErrMsg; /* put escape msg in a spool file */ End "SNDPGMMSG MSGID("||Strip(ErrMsgId)||")", "MSGF("||Strip(ErrMsgfLib)||"/"||Strip(ErrMsgF)||")", "MSGDTA(&ERRMSGDTA)", "MSGTYPE(*ESCAPE)"; Return;
HELP Panel Group
Place the following in a QPNLSRC member named UTMNUMSGF and compile it.
.******************************************************************************* .* Program Name: UTMNUMSGF * .* Programmer: Dave L Clark I * .* Date: September 25, 2012 * .* Project/Request #: PetProj - Create Menu Message File * .* Purpose: This is the F1 help associated with the command of the * .* of the same name. * .* * .******************************************************************************* .* Technical Notes: * .* --------------------------------------------------------------------------- * .* * .* NONE * .* * .******************************************************************************* .* Modification Log: * .* --------------------------------------------------------------------------- * .* * .* Mod# Date User Description * .* ---- ---------- ---------- ------------------------------------------------ * .* M001 * .******************************************************************************* :pnlgrp. .************************************************************************** .* Help for command UTMNUMSGF .************************************************************************** :help name='UTMNUMSGF'. Create Menu Message File - Help :p.The Create Menu Message File (UTMNUMSGF) command provides the ability to (re)create the message file associated with a menu. Such a message file contains the commands behind the selections on the menu. These commands are listed in a special source member which is normally maintained via IBM SDA that normally also takes care of creating the associated message file as needed. However, when switching from green-screen development to a GUI IDE, such as the IBM Rational Developer for POWER Systems (RDP), this ancillary (but, useful) function is lost. :p.That is where this command comes in. The RDP developer must now maintain the menu's command list as a separate source member. IBM SDA created and maintained this source member using the menu name with a "QQ" suffix as the convention for naming that member. The RDP developer, then, is advised to continue this convention as this command will expect the same "QQ" suffix by default. The discussions of the command parameters, below, will bring out how this suffix comes into play. :p.Simply put, then, this command may be used as the standard "compile" command for either the menu message file or the menu command member. Giving just one of the names of these two objects is sufficient for this command to derive the name of the other object using the "QQ" suffix as a convention. Alternatively, both the menu message file name and the menu command member name may be supplied where the "QQ" suffix convention is not followed. :ehelp. .******************************************* .* Help for parameter MSGF .******************************************* :help name='UTMNUMSGF/MSGF'. Menu message file (MSGF) - Help :xh3.Menu message file (MSGF) :p.Specifies the desired object name for a message file to create in association with a menu definition. By convention, the message file name matches the name of the menu definition. This is not a strict requirement, though, as long as the actual message file name is specified as an override at the time the menu definition is created. :p.This is a required parameter. :p.:hp2.Qualifier 1: Menu message file:ehp2. :parml. :pt.:pk.*CMDMBR:epk. :pd. This special value indicates that the actual name of a menu command member is specified as a command parameter and the name of the message file is to be derived from that name. This is accomplished by stripping the expected "QQ" suffix from the name of the specified menu command member. :pt.:pv.message-file-name:epv. :pd. Specify the name of the desired message file which will be associated with a menu definition. This name must conform to the conventions for naming IBM objects. The resulting message file definition will replace any existing message file of the same name in the target library. :eparml. :p.:hp2.Qualifier 2: Library:ehp2. :parml. :pt.:pk def.*CURLIB:epk. :pd. This special value indicates that the signed-on user's "current" library should be used as the target library for the resulting message file definition. If there is no "current" library defined, then the QGPL library is used as the target library. :pt.:pv.library-name:epv. :pd. Specify the name of the library to serve as the target for the resulting message file definition. :eparml. :ehelp. .******************************************* .* Help for parameter TEXT .******************************************* :help name='UTMNUMSGF/TEXT'. Text 'description' (TEXT) - Help :xh3.Text 'description' (TEXT) :p.Specifies up to 50 characters of text that briefly describes the resulting menu message file object. :parml. :pt.:pk def.*CMDMBRTXT:epk. :pd. This special value indicates that the textual description from the menu command member is to be used as the description for the resulting menu message file object. :pt.:pk.*BLANK:epk. :pd. This special value indicates that the resulting menu message file object should have no textual description at all. :eparml. :ehelp. .******************************************* .* Help for parameter CMDMBR .******************************************* :help name='UTMNUMSGF/CMDMBR'. Menu command member (CMDMBR) - Help :xh3.Menu command member (CMDMBR) :p.Specifies the name of the source member which contains the command list to use when creating the associated menu message file definition. By convention, this member name should end with a "QQ" suffix but this is not a strict requirement unless the name of the menu message file is to be derived from this source member's name. :note.The format of this source member is expected to be the same as that which was previously used by IBM SDA for this same purpose. However, this format is not documented anywhere. Basically, it has a first line which is the name of the "QQ" member, itself, followed by a comma and the number 0 or 1 (though not documented what those numbers mean). Each subsequent line is made up of a 4-digit menu selection number (with leading zeroes), a blank, then up to 75 characters for a command and its parameters. A continuation is supported by placing a plus-sign in column 5 instead of a blank. Then the total command length can be 115 characters for IBM SDA or 132 characters for this command. :ent. :parml. :pt.:pk def.*MSGF:epk. :pd. This special value indicates that the actual name of a menu message file is specified as a command parameter and the name of the command member is to be derived from that name. This is accomplished by appending the requisite "QQ" suffix to the name of the specified menu message file. :pt.:pv.member-name:epv. :pd. Specify the name of the source member that contains the command list associated with a menu definition. This name must conform to the conventions for naming IBM objects and, for backward compatibility with IBM SDA, should end with a "QQ" suffix. :eparml. :ehelp. .******************************************* .* Help for parameter SRCFILE .******************************************* :help name='UTMNUMSGF/SRCFILE'. Source file (SRCFILE) - Help :xh3.Source file (SRCFILE) :p.Specifies the name of the source file that contains the menu command list member. :p.:hp2.Qualifier 1: Source file:ehp2. :parml.:pt.:pk def.QMNUSRC:epk. :pd. The default source file, QMNUSRC, contains the command member to use as input to this process. :pt.:pv.source-file-name:epv. :pd. Enter the source file name that contains the command member to use as input to this process. :eparml. :p.:hp2.Qualifier 2: Library:ehp2. :parml. :pt.:pk def.*LIBL:epk. :pd. The system searches the library list to find the library where the source file is located. :pt.:pk.*CURLIB:epk. :pd. The current library will be used. If you have not specified a current library, then QGPL will be used. :pt.:pv.library-name:epv. :pd. Enter the name of the library where the source file is located. :eparml. :ehelp. .************************************************** .* Examples for UTMNUMSGF .************************************************** :help name='UTMNUMSGF/COMMAND/EXAMPLES'. Examples for UTMNUMSGF - Help :xh3.Examples for UTMNUMSGF :p.:hp2.Example 1: Simple Command Example:ehp2. :xmp. UTMNUMSGF MSGF(MYMENU) :exmp. :p.This command creates a menu message file by the name of MYMENU.MSGF in the user's "current" library (or in QGPL.LIB if no "current" library defined) and adopting an object description taken from the description of the MYMENUQQ.MBR entry in the QMNUSRC.FILE found by searching the user's library list. The MYMENUQQ.MBR name was derived from the message file name by appending "QQ" as a suffix. Then, message descriptions are added to that message file based on the content of the command list member. :p.:hp2.Example 2: More Complex Command Example:ehp2. :xmp. UTMNUMSGF MSGF(MYLIB/*CMDMBR) TEXT('My Menu') CMDMBR(MYMENUQQ) SRCFILE(MYLIB/MYMNUSRC) :exmp. :p.This command creates a menu message file by the name of MYMENU.MSGF in MYLIB.LIB with the specified object description. The MYMENU.MSGF name was derived from the specified command member name by stripping off the "QQ" suffix. Then, message descriptions are added to that message file based on the content of MYMENUQQ.MBR as found in MYMNUSRC.FILE in MYLIB.LIB regardless of the user's library list. :ehelp. :epnlgrp.
References
- RPG/ILE version of API Error Code Structure (ApiErrC)
- RPG/ILE version of Retrieve Member Description (QUSRMBRD) API