Editor's note! This file has been converted from Word Perfect, and still needs some cleanup! (coming soon...) TUTORIAL A Beginner's Guide to UDCs and JCWs: How to Use Them to Your Benefit (MPE XL Edition) David L. Largent The N.G. Gilbert Corporation 700 South Council P.O. Box 1032 Muncie, Indiana 47308-1032 U.S.A. Telephone 317/284-4461 Facsimile 317/288-2125 Telex 361285 Copyright 1988, 1991, 1992 David L. Largent TUTORIAL A Beginner's Guide to UDCs and JCWs: How to Use Them to Your Benefit (MPE XL Edition) Table of Contents 1 Introduction -- "Is this for me?" . . . . . . . . 1 1.1 About this tutorial -- "So tell me, what's new?". 2 2 What are UDCs?. . . . . . . . . . . . . . . . . . 2 2.1 A brief comparison of UDCs and Command Files. . . 3 2.2 How can UDCs help me? . . . . . . . . . . . . . . 4 2.3 How do I create a UDC?. . . . . . . . . . . . . . 5 2.3.1 Defining the UDC. . . . . . . . . . . . . . 5 2.3.1.1 The header section.. . . . . . . . . . . 6 2.3.1.2 The execution options section. . . . . . 8 2.3.1.3 The body section.. . . . . . . . . . . . 11 2.3.1.4 The UDC separator section. . . . . . . . 14 2.3.2 Put your UDC definitions in a UDC file. . . 14 2.3.3 Account-level and system-level UDCs.. . . . 15 2.3.4 Telling the system about your UDC file(s).. 17 2.3.4.1 Cataloging your first UDC file(s). . . . 18 2.3.4.2 Appending UDC files to those already cataloged. 19 2.3.4.3 Disabling individual UDC files.. . . . . 20 2.3.4.4 A couple seldom-used SETCATALOG parameters. 21 2.3.4.5 SETCATALOG use by account or system managers. 21 2.4 How do I alter a UDC file after it has been cataloged? 23 2.5 What happens when I logon and have some UDCs enabled? 23 2.6 How do I find out what UDCs are available?. . . . 24 2.7 How about some examples?. . . . . . . . . . . . . 26 2.8 What are some problems I may have while using UDCs? 36 2.9 Are we done with UDCs yet!?!. . . . . . . . . . . 38 3 What are JCWs?. . . . . . . . . . . . . . . . . . 38 3.1 A brief comparison of JCWs and session-level variables. 38 3.2 How can JCWs help me? - or - Why would I want a program to talk to my commands?. . . . . . . . . . . . . . . . . . . . . . . . . 39 3.3 OK, I think I see how they could help me. So, how do I create and use a JCW? . . . . . . . . . . . . . . . . . . . . . . . . . . . 39 3.3.1 User-defined JCWs.. . . . . . . . . . . . . 39 3.3.2 System-defined JCWs.. . . . . . . . . . . . 40 3.3.3 System-reserved JCWs. . . . . . . . . . . . 40 3.3.4 JCW usage in jobs and/or sessions.. . . . . 41 3.3.4.1 The SHOWJCW command. . . . . . . . . . . 41 3.3.4.2 The SETJCW command.. . . . . . . . . . . 42 3.3.4.3 The DELETEVAR command. . . . . . . . . . 43 3.3.4.4 The JCW value mnemonics. . . . . . . . . 44 3.3.5 JCW usage in programs.. . . . . . . . . . . 45 3.3.5.1 The FINDJCW intrinsic. . . . . . . . . . 45 3.3.5.2 The PUTJCW intrinsic.. . . . . . . . . . 47 3.3.5.3 The HPCIDELETEVAR intrinsic. . . . . . . 48 3.3.5.4 Interprocess communication with JCWs.. . 50 3.3.5.5 The GETJCW and SETJCW intrinsics.. . . . 50 3.4 How about some examples?. . . . . . . . . . . . . 50 3.4.1 Batch job examples. . . . . . . . . . . . . 50 3.4.2 Programmatic examples.. . . . . . . . . . . 54 3.5 What are some problems I may have while using JCWs? 56 4 How can I use UDCs and JCWs together? . . . . . . 57 4.1 Examples of combining UDCs and JCWs.. . . . . . . 57 5 Closing thoughts -- "Is it worth the effort of learning something new?" 62 Acknowledgements . . . . . . . . . . . . . . . . . . . . . 63 Bibliography . . . . . . . . . . . . . . . . . . . . . . . 64 Index. . . . . . . . . . . . . . . . . . . . . . . . . . . 66 TUTORIAL A Beginner's Guide to UDCs and JCWs: How to Use Them to Your Benefit (MPE XL Edition) David L. Largent The N.G. Gilbert Corporation 700 South Council P.O. Box 1032 Muncie, Indiana 47308-1032 U.S.A. Telephone 317/284-4461 Facsimile 317/288-2125 Telex 361285 Copyright 1988, 1991, 1992 David L. Largent 1 Introduction -- "Is this for me?" How many times have you forgotten to issue a "FILE" command before running a program? How often have you typed a FILE command wrong? Do you ever get tired of typing "SPOOLF spoolid; DELETE"? Have you been looking for a way to make your jobstreams a little "smarter?" Would a way to automate some of your procedures be helpful? If you have any of these problems and have never considered using UDCs and/or JCWs, now is the time to do so. If you are like me, you have known UDCs and JCWs existed, but thought they were some difficult, mysterious, (impossible?) thing to master. This is not so! On the following pages will be found answers to questions relating to User Defined Commands (UDCs) and Job Control Words (JCWs) such as: What are they? How can they help me? How are they created? How are they used? What are some common problems that arise? Are they worth the effort of learning something new? To find the answers, we will first examine what UDCs are and how they are created and used. We will look at numerous UDC examples to reinforce your learning. Next, we will examine JCWs in detail. And lastly, we will look at how to use JCWs and UDCs together effectively to create a synergism of the two. This tutorial is directed at new users of an HP3000 MPE XL computer system who have not yet explored the world of UDCs and/or JCWs. However, any user may find some tidbits to put in his or her "tool box" that will prove useful either now or in the future. This tutorial assumes you have a general knowledge of the HP3000; specifically, the following are "prerequisites": Knowledge of the HP3000 accounting structure (i.e., File/Group/Account/User). Knowledge of how to use an ASCII text editor (e.g., EDIT/3000). Knowledge of many MPE XL system commands and how to use them. Knowledge of jobstreams and how to use them. 1.1 About this tutorial -- "So tell me, what's new?" This tutorial is based on my award-winning MPE V-based tutorial of the same name, and my award-winning MPE V-based paper JCWs: An Underutilized MPE Feature, both presented at past INTEREX conferences. This version reflects information as it pertains to the MPE XL operating system. The information provided here is correct and up-to-date (to the best of my knowledge) and reflects the way UDCs and JCWs are used and work as of the A.41.01 release of MPE XL (2.2). For better or worse, I am yet to make the jump to a more recent version of MPE XL (excuse me... MPE/iX). Also note that I will continue to refer to the operating system as XL rather than iX in this tutorial. I've barely gotten used to calling it XL and now they're changing it again! The MPE XL operating system does a wonderful job of pretending that it's good ol' MPE V. There are, however, a number of new commands, added functionality, and just plain different ways of getting things done which make MPE XL a much richer and more enjoyable operating system to work with. A few of the new items that relate to this tutorial's subject matter include: Another way to specify UDC parameters (PARM) A non-parsed parameter for UDCs (ANYPARM) Recursion for UDCs (OPTION RECURSION) Programmatic access to UDCs (OPTION PROGRAM and HPCICOMMAND) Deletion of JCWs (DELETEVAR and HPCIDELETEVAR) A looping structure (WHILE and ENDWHILE) New I/O commands (INPUT, ECHO and PRINT) Additional SETCATALOG parameters (APPEND, DELETE and RESET) Command Files Variables All of these items will be touched upon in this tutorial -- some in a great deal of detail; others just in passing. 2 What are UDCs? UDC is one of many acronyms used in the HP3000 world. This one comes from the phrase User Defined Command. A UDC is a command designed for the user's convenience. It is made up of MPE XL system commands, command file references, and/or other UDCs. A UDC can replace a single, long command or a long sequence of many commands. UDCs provide a short cut (a more precise way!?!) to accomplish some particular task. By entering the UDC name, the predefined commands are automatically executed. Think of them as just another MPE XL system command. 2.1 A brief comparison of UDCs and Command Files. Another MPE XL feature, the Command File, is very similar to UDCs in that Command Files can execute several commands in response to a single command. Most of the options available for UDCs are also available for Command Files. Some instances may dictate the use of a UDC. In many situations, however, a Command File may work as well, or better than a UDC. In general, Command Files are a bit easier to work with than UDCs. They do lack some of the added capabilities of UDCs, however. With time and experience you will come to learn the best tool to use for the task at hand. I encourage you to learn all you can about Command Files from other references -- they do have their place in the scheme of things. An in-depth study of Command Files will not be provided here. However, the following tables are offered for your information. Many of the items will make more sense after reading the following pages. The entries in the tables are not being presented as advantages or disadvantages, but rather as comparisons of UDCs and Command Files. Which is the better tool for a given situation is left for you to determine. Comparison of User Defined Commands (UDCs) and Command Files Execution Considerations User Defined Commands Command Files Invoked by typing the name provided Invoked by typing the command in the header section of the UDC. file's file name. Automatic execution at logon time Automatic execution at logon time is available. is not available. Executed before MPE XL system Executed after UDCs and MPE XL commands and command files. system commands (unless XEQ is May override CI commands. used). May not override CI commands. User-, account-, and system-level Only "user-level" definitions are definitions are available. available. (Easy access at any level could be established with the PATH command.) SHOWCATALOG lists currently Cannot easily list currently available UDC names. available command file names. UDC file is more secure. (More Command file is less secure. difficult to purge or alter a UDC (Easier to purge or alter command file.) file.) Best used for production or stable Best used for testing, command definitions. development, or frequently changing command definitions. Comparison of User Defined Commands (UDCs) and Command Files Content Considerations User Defined Commands Command Files Multiple command definitions are Only one command definition is allowed per file. allowed per file. Header section is required. Contains no header section. May have long, descriptive command Command name is limited to eight name. characters (the file name). Comparison of User Defined Commands (UDCs) and Command Files Maintenance Considerations User Defined Commands Command Files Cataloging of the UDC file(s) is Command files are not cataloged; required before use. available immediately after creation. Must un-catalog the UDC file before May make changes to, or purge the making changes to, or purging the command file directly. file. May provide better organization of Organization may not be as good commands (fewer files). (more files to keep track of). System resource use is heaviest at System resource use is heaviest logon time. at command file execution time. Less disk space is required. More disk space is required. 2.2 How can UDCs help me? A UDC can be used in almost any situation where an MPE XL system command is used, even within another UDC. They can be used in both sessions and jobstreams. Under some circumstances, they can be executed from within programs and subsystems, and when you are in BREAK. UDCs are perfect solutions for many "problem" situations. A long sequence of MPE XL system commands can be replaced by a single UDC name, thus decreasing the time it takes to accomplish the task (less typing), and also eliminating typing errors. A lengthy command like "SPOOLF spoolid; DELETE" can be replaced by a UDC name such as "RPUR". A complicated sequence of commands, such as a long list of "FILE" commands before running a program, can be reduced to one UDC name such as "PAY". Many of your boring, repetitive tasks can be automated by using UDCs. UDCs can also be used to protect your system from both the naive user and the too-knowledgeable user. They can also cause something to happen automatically at logon time. These all serve as examples of ways to make the HP3000 more "user-friendly." By this point in time, you probably have half a dozen UDC ideas in your head just waiting to get out. So... 2.3 How do I create a UDC? First of all, slow down! UDCs, as with most everything in life, are best created with PPP -- Proper Prior Planning. If thought is given to each UDC you create, a lot of changes can be avoided later and you will likely end up with a more functional set of UDCs that are easier to use and maintain. For some people, creating a good UDC is an art, rather than a science -- they may put as much thought and care into a UDC as they put into developing a program. Now that you have slowed down a bit (you have, haven't you?!), give some thought to what MPE XL system commands are used often on your system. Are there particular tasks that always require the same sequence of commands? Are there commands or tasks that may not be difficult for us programmers to master, but may be intimidating for the user? Now take your list (you did write them down, didn't you?) and evaluate each command or task. Some of them may be used so seldom that it is not worthwhile to create a UDC. (That can also be a reason to create a UDC for a task, so that the sequence of steps need not be remembered!) Some of the commands may be so short that creating a UDC for them would only save two or three key strokes. You must make a judgement call for each command or task as to whether the convenience of having the UDC available for use is worth the time and effort of creating it. You must also consider whether it would be more appropriate to use a command file rather than a UDC. For example, is the command definition likely to change often, or do you want the added security of UDCs? 2.3.1 Defining the UDC. Let us assume that you have chosen to create a UDC for the SHOWJOB command in its simplest form. You would like to be able to type the letter "J", and have the system behave as if you had typed "SHOWJOB". A UDC to do this could look like: J Header section OPTION LIST, HELP Execution options section SHOWJOB Body section ** UDC separator section As shown above, every UDC consists of four main sections: a header section, an optional execution options section, a body section, and a UDC separator section. The first line in this example is the header section, containing the actual command the user will type. The second line provides some execution options to the system. The third line makes up the body section, containing the actual command to be executed. The fourth line serves as a separator between UDC definitions in a UDC file. 2.3.1.1 The header section. The header section of a UDC consists of the command name, parameters, and their optional default values. A UDC header may extend over more than one physical line for up to a maximum of ten lines, and may not exceed 279 characters in total. Each line to be continued must have as its last non-blank character an ampersand (&). The command name is what the user will actually type (along with any needed parameter values) to cause the UDC to be executed. It is composed of a maximum of 16 alphabetic or numeric characters and must begin with an alphabetic character. Use common sense when naming your UDCs. Use a derivative of the actual MPE XL system command(s), or if naming a UDC for a particular task, give it a name that is descriptive of the task. It is a good idea to avoid single letter UDC names to reduce the chance of executing the command by mistake (at least for any that may be "destructive"). Parameters are variables for a UDC that are assigned either a default value or a value provided by the user when the UDC is executed. These variables are specified on the same line as the command name and may be used in the body of the UDC to make the UDC more flexible and less specific. Hewlett-Packard Company documentation claims you may have up to 255 parameters defined in one UDC. I have successfully defined 122 parameters. However, when I tried to define 123 or more parameters in one UDC, I got various error messages when I executed the UDC. Regardless of what the real answer is, you can still define more parameters than you will ever know what to do with!! Besides, who wants to type that many names? Each parameter must have a name. A parameter name must begin with an alphabetic character; the remainder may be alphabetic or numeric characters. The maximum length for a parameter name is seventy characters. However, the actual maximum may be less; a parameter name may not be split between physical lines. The same is true for default values for parameters. Further constraints on the length of the parameter name may apply depending on the position where the parameter is used in the body section. In addition to specifying parameters on the command name line, you may use the PARM statement to specify parameters. PARM statements must be placed immediately after the line containing the command name (or other PARM statements if any are specified), and must start with "PARM", followed by a space and one or more parameters defined in the same way as on the command name line. Either or both methods may be used in a given UDC definition. A special parameter type, ANYPARM, is also available. ANYPARM may be used in place of PARM, and causes all normal delimiters to be ignored. This implies that delimiters (actually everything) are now considered part of the parameter's value. For this reason, only one parameter in a UDC may have ANYPARM specified, and it must be the last parameter of the UDC, since the equal sign(=), comma, semicolon, quotation mark, etc. are all treated as data for the parameter's value. Without the use of ANYPARM in the UDC definition, the user is forced to enclose their parameter value in quotation marks if it contains characters that MPE XL interprets as delimiters. With the use of ANYPARM, a lot more flexibility can be built into UDCs. If a UDC parameter does not have a default value specified, it is considered a required parameter and a value must be provided by the user when the UDC is executed. If a value for a required parameter is not provided by the user, an appropriate error message is displayed and the UDC is not executed. Let us change the requirements for our "J" UDC. We now want it to do one of three things: SHOWJOB JOB=@ (show all jobs) SHOWJOB JOB=@S (show sessions only) SHOWJOB JOB=@J (show batch jobs only) This can be accomplished with one UDC if we use a parameter. The header section will now look like: J WHAT2SHOW = " " The command name is still J. The character string "WHAT2SHOW" is the parameter name. A default value of a space has been specified. This means that if a user just types "J", a list of all jobs will be displayed. Similarly, if the user types "J S" the list will show sessions only. As can be seen in the example above, a default value for a parameter is specified by placing an equal sign (=) after the parameter name, and then following that with the default value. If the default value contains any spaces or special characters, it must be enclosed in quotation marks ("). If no spaces or special characters are needed in the default value, the quotation marks are optional. When a default value is not provided for a parameter, the only thing that appears in the header section is the parameter name. If you choose to use the PARM statement, the above UDC header section would look like: J PARM WHAT2SHOW = " " If more than one parameter is used in a UDC, default values may be specified for all, some, or none of them. That is, some of the parameters can be required while others are optional. A comma is used to separate a parameter name from the previous parameter name (or default value if one is specified). From the user's point of view, there are two ways UDC parameters can be thought of: keyword and positional. When a user is executing a UDC, either approach may be used, but not both at the same time. A keyword parameter is one in which the parameter name is typed, followed by an equal sign, followed by the parameter value. In this way, values for parameters may be provided in any order. For example: J WHAT2SHOW=S is the way the user would execute the J UDC using a keyword parameter. A positional parameter is one in which the value is specified for each parameter in the order they were defined in the UDC. If a new value is not provided for an optional parameter, its position must still be "held" by a comma. The J UDC executed with a positional parameter would look like: J S The concept of keyword and positional parameters is the same as for the standard MPE XL system commands, except that only one approach may be used on a given execution of a UDC. When providing numeric values for parameters (either the default values or the user's actual values), both decimal and octal numbers may be used. Octal numbers are indicated by preceding them with a percent sign (%). As you would expect, if the user provides a value for a parameter that has a default value, the user's value is the one that will be used. If the parameter value a user provides contains spaces or special characters, that value must be enclosed in quotation marks. 2.3.1.2 The execution options section. The execution options section of a UDC consists of choices from each of six pairs of options. Each of these six pairs has a default and, therefore, if the defaults are what is desired, this entire section can be left out. These options control the operation and use of the UDC. If the execution options section is provided, it must appear immediately after the header section and will consist of one or more lines. Each line must start with the word OPTION. The rest of the line contains the option or options you have chosen with a comma between each, if you list more than one. You may chose to put any number of options on a given execution option line. The six option pairs, along with their defaults, are shown in the table below and discussed in the following paragraphs. There are two exceptions to the placement rule for the option statements. The RECURSION/NORECURSION and LIST/NOLIST options may be placed in the body section, as well as in the execution option section of the UDC. This permits additional control over these two aspects of UDC execution, as they can be "turned on and off" as they are required. The format of the line is the same for both the execution options and the body sections. All other options may only be specified in the execution options section. Execution Option Pairs and their Defaults Execution Option Pair Default Used if Not Specified List / NoList NoList Break / NoBreak Break LogOn / NoLogOn NoLogOn Help / NoHelp Help Recursion / NoRecursion NoRecursion Program / NoProgram Program LIST/NOLIST. The default is NOLIST. The LIST option will cause the text of the body section to be listed on the standard list device with the parameter values substituted as each line is executed. The NOLIST option will not list any of the text of the body section. It is a good idea to use the LIST option on UDCs that are replacements for MPE XL system commands. This way the actual command is before you and you will be less likely to forget what the MPE XL system command is when you need to use it on another system that doesn't have your UDC! The NOLIST option is generally a good choice for UDCs that are implementing user tasks. BREAK/NOBREAK. The default is BREAK. If the NOBREAK option is chosen, the commands that make up the body of the UDC will be nonBREAKable. That is, pressing the BREAK key will not cause the command or program to stop. If the BREAK option is chosen, the commands that make up the body of the UDC will be BREAKable (if they are normally BREAKable as MPE XL system commands). It is a good idea to use the NOBREAK option on any UDC that runs a VPlus application. This eliminates the problems that occur when BREAK is pressed while in block mode. The use of the NOBREAK option will prohibit certain users from using any MPE XL system commands and can serve as a way to discourage simple security breaches. If the BREAK key is pressed during the execution of a UDC using the BREAK option, the following happens: If it was executing a non-program command, the UDC terminates. If it was executing a program, and the RESUME command is entered, the UDC will also resume execution. An exception to this occurs if a SETCATALOG command is executed while in BREAK. In this case, the program is resumed but the remainder of the UDC will not be executed. For you programmers, the NOBREAK option overrides the CAUSEBREAK intrinsic. A program containing CAUSEBREAK will not BREAK if it is executed from a UDC that has the NOBREAK option specified. LOGON/NOLOGON. The default is NOLOGON. If the LOGON option is chosen, the commands specified in the body of the UDC will automatically be executed when the user logs on. Only one LOGON UDC at the user level will be executed. If more than one LOGON UDC exists for the user level, only the first one will execute. The LOGON option can be put to good use on user task UDCs. By using this option, the user can logon and automatically be put into a menu or application program. If the NOBREAK option is also used, you can keep a user from gaining direct access to MPE XL system commands. An example of this will be shown later. If you have one or more tasks you want done every time a user logs on, but the tasks seem to change often, consider setting up a LOGON UDC that references a command file. By doing this, you will be able to easily alter the command file, but still have the LOGON functionality of UDCs. HELP/NOHELP. The default is HELP. If the HELP option is chosen, you may type HELP followed by the UDC name and see the definition of the UDC. If the NOHELP option is chosen, this possibility does not exist. More will be said later about the use of the MPE XL HELP subsystem. It is good to choose the HELP option unless you have a security sensitive situation. If you specify both the NOLIST and NOHELP options and an error occurs during execution of the UDC, the error will be reported but the line containing the error will not be listed. A small security breach you should be aware of: Even if you specify the NOHELP option, the definition of that UDC will still list when it is cataloged if the SHOW parameter is used on the SETCATALOG command. RECURSION/NORECURSION. The default is NORECURSION. If the NORECURSION option is chosen, MPE XL will search for UDC definitions from the current command in the executing UDC to the end of the UDC directory. (This is the way MPE V works.) As a result, UDCs that are defined "before" the current command are not available for use following the current command in the UDC. If RECURSION is specified, MPE XL starts at the beginning of the UDC directory to satisfy UDC usage. This allows a UDC to reference any other UDC -- even if the referenced UDC is defined "before" the current one. Note that the RECURSION option is only in effect for the UDC(s) in which it is specified. Other UDCs in the file are not affected -- not even those referenced by a UDC with RECURSION in effect. To prevent endless loops when the RECURSION option is specified (since two UDCs could call each other, or a UDC could reference itself, for example), MPE XL places a limit of thirty on how many times any UDC can call any other UDC, including itself, in a "circular" fashion. When the limit is reached, the system interrupts the process, and displays the error message shown below. We will talk more about RECURSION/NORECURSION later. USER COMMAND NESTING DEPTH LEVEL HIT. (CIERR 2030) PROGRAM/NOPROGRAM. The default is PROGRAM. If the PROGRAM option is chosen, programmatic access to UDCs will be available, provided the program calls a new MPE XL system intrinsic, HPCICOMMAND. Programs or subsystems that use the COMMAND intrinsic will not have access to UDCs, even if the PROGRAM option is specified in a UDC. (More information is available on these intrinsics in the MPE XL Intrinsics Reference Manual.) If NOPROGRAM is chosen, programmatic access to UDCs is not available. 2.3.1.3 The body section. The body section of a UDC consists of one or more MPE XL system commands and/or UDCs that will be executed when the user types the UDC name. Other non-command text such as data for subsystems or application programs may not be included. A logical line of the body may extend over more than one physical line for up to a maximum of ten lines, and may not exceed 279 characters in total. Each line to be continued must have as its last non-blank character an ampersand (&). The body section follows the execution options section, if any options have been listed. If the execution options section is not present, the body section will follow the header section. There are a few restrictions to be aware of. The REDO and DO commands may not be used in a UDC. The HELLO command may be used, however, it will cause the current session to logoff and effectively terminate execution of the UDC. Let us go back to our last version of the J UDC. We wanted it to do one of three things: SHOWJOB JOB=@ SHOWJOB JOB=@S SHOWJOB JOB=@J We last defined the header section as: J WHAT2SHOW = " " The body section needed to satisfy our requirements will consist of a single MPE XL system command: SHOWJOB JOB=@!WHAT2SHOW In this example, all the characters preceding the exclamation point (!) will be left as shown. The character string "!WHAT2SHOW" will be replaced by either the default value of a space, or whatever the user types as a parameter value following "J". This revised command image is then what is sent to the MPE XL system command interpreter (CI) for execution. Thus, if the user types: J S the command image executed will be: SHOWJOB JOB=@S Alternatively, if the user just types: J and uses the default parameter value, the command image executed will be: SHOWJOB JOB=@ As shown above, placing an exclamation point (!) immediately before a parameter name in the body section of a UDC will cause MPE XL to substitute the value of that parameter into that position of the command. If an exclamation point does not precede a parameter name, no substitution will be attempted, and the parameter name will be left in the command. If anything resembling a parameter name, other than a parameter name, follows an exclamation point, an error will be reported to the user. Normally, an exclamation point signifies a parameter name. If you want to use the exclamation point immediately before a character string that MPE would normally interpret as a potential parameter, but not have MPE XL attempt parameter substitution, use an even number of exclamation points. An odd number of exclamation points will cause MPE XL to attempt a substitution. Each pair of exclamation points will be translated into a single exclamation point provided a character string immediately follows them that could be interpreted as a parameter name. For example, consider the following UDC: EXAMPLE PARM OPTION NOLIST ECHO !!PARM ECHO !!!!!PARM ECHO PARM = !PARM ECHO PARM = !PARM! ** If the user were to execute it by typing: EXAMPLE TEST the ECHO statements would cause the following to be displayed: !PARM !!TEST PARM = TEST PARM = TEST! Sometimes you will need to insert a parameter into the middle of a character string in the UDC body section. As an example: LINKI PROGNAME, XL="XL.PUB" OPTION LIST LINK ^!"PROGNAME"L,!"PROGNAME"X;XL=!XL ** In this UDC, two parameters are used: PROGNAME and XL. XL has a default value of XL.PUB. When the UDC is executed, it will LINK a file, using an indirect file as input. The parameter PROGNAME is enclosed in quotation marks in the body to separate it from the letters "L" and "X" that follow. Without the quotation marks, there would appear to be invalid parameter names following the exclamation points. This is only a concern if the character immediately following a parameter name is a letter or number. If the UDC was to be executed by typing: LINKI PAY the actual command image executed would be: LINK ^PAYL,PAYX;XL=XL.PUB The parameter value "PAY" corresponds to parameter PROGNAME because they are both the first item provided in the list. Since a second parameter value was not provided when the UDC was executed, the default value for XL was used. If an error is encountered as the commands of a UDC are executed, an error message will be displayed and the UDC will terminate. If the UDC is being executed in a jobstream, the jobstream will also terminate. Sometimes it is desirable for the UDC to continue with the next command regardless of whether the previous command results in an error. To accomplish this, a CONTINUE command must be inserted immediately preceding the command that may result in an error. Consider the following UDC: REPORTS OPTION LIST CONTINUE RUN PROG1X RUN PROG2X SHOWTIME ** In this example, two programs are run and then the time of day is displayed. If program PROG2X results in an error (i.e., it aborts) when it is run, the remainder of the UDC will not be executed. That is, if program PROG2X aborts, nothing else will be done. Program PROG2X will always be run regardless of whether program PROG1X results in an error. The CONTINUE command tells MPE XL to continue with the next command, even if the current command fails. This "override" capability applies only to the command immediately following the CONTINUE command. UDCs can perform tasks much more complex than those already covered by using sophisticated command sequences and/or referencing other UDCs from within the body section of the UDC. By using control characters and escape sequences, you can control the appearance and location of information as it is displayed by a UDC. The terminal's function keys can be "loaded" by a UDC, thus making your terminal a little more user- friendly. Examples of these will be provided later. As mentioned earlier, a UDC may reference or execute another UDC. This process is referred to as nesting. Unless the RECURSION option is used, there is a limitation, however: A UDC can only reference another UDC that is defined later in the UDC file. As long as the reference occurs before the definition, UDCs can be written in a structured way. If the RECURSION option is used, the order of the UDC definitions generally is not important. Consider the following UDCs: INFO OPTION LIST ME J T ** J OPTION LIST SHOWJOB ** ME OPTION LIST SHOWME ** T OPTION LIST SHOWTIME ** In this example, we have defined four UDCs: INFO, J, ME, and T. The INFO UDC will cause the J, ME, and T UDCs to be executed one after the other in the order listed in the INFO UDC. When the J UDC is executed, it will execute the SHOWJOB command; the ME UDC will execute the SHOWME command; and the T UDC will execute the SHOWTIME command. So, by simply typing "INFO", the user will be provided information from all three of the MPE XL system commands automatically. 2.3.1.4 The UDC separator section. The last section of a UDC definition is the UDC separator. This consists of a single line that must start with an asterisk (*) in column one. The rest of the line is yours to do with as you wish. The purpose of this section is to separate one UDC from the next in the UDC file and must be the last line of the UDC definition. So, there you have it in ten words or less (give or take a few thousand). You now know how to define a UDC. But once you have a number of UDCs defined, what do you do with them? The answer to that question is... 2.3.2 Put your UDC definitions in a UDC file. A UDC file is simply an ASCII text file that contains one or more UDC definitions. Any ASCII text editor may be used to create a UDC file. MPE XL is expecting eighty- character records. (According to HP documentation. My testing, however, seems to indicate that any record length will work -- at least on this release of MPE XL. Nonetheless, I recommend you use eighty-character records, or be prepared to make changes in the future if and when HP decides to follow their documentation.) A UDC file may contain any number of UDC definitions (restricted, of course, by MPE XL's maximum file size). The UDCs should be entered in some logical sequence to make maintenance easier -- my suggestion is alphabetically by the UDC name. An exception: Remember if you are using nested UDCs without the RECURSION option, the definition of a UDC must be after its reference(s). So, either name them appropriately or include them in the file out of sequence. If you are using the escape character in your UDCs, an easy way to key it in is to type in some otherwise unused character (e.g., the ^ character) in place of the escape character. Then when you are finished entering the UDC definitions, globally change all occurrences of that character to the escape character. The reverse sequence can be used if you need to modify an existing UDC file. Just remember to change them back before you keep the file. Once you have entered all of the UDC definitions using your text editor, save the file with some meaningful name. My preference is to use the letters "UDC" as the last three characters of the file name. Doing so makes it easy to locate UDC files with the LISTF command. You may keep your file with or without line numbers -- MPE XL does not care. You may create multiple UDC files; however, for performance reasons (to be discussed later), it is best to limit the number of UDC files that exist for one user. If you wish, a lockword may be assigned to the UDC file. Simply creating a UDC file with a text editor does not yet make the UDCs available for use. The next step is to tell MPE XL that you have a UDC file you wish to use. However, before we discuss that, let us take a look at account and system level UDCs. 2.3.3 Account-level and system-level UDCs. Up to this point, we have been discussing UDCs in general. There are actually three different levels of UDCs: user, account, and system. A UDC file may be set up by a user for his/her own use. An account manager may create a set of UDCs for use by all users of that account. The system manager may create a set of UDCs for use by all users on the system. So now you have one more item to consider when you are creating a UDC: Who should have access to it? When the MPE XL system command interpreter is given a command (an MPE XL system command, a UDC, a command file, or an implied RUN of a program), it follows a predefined hierarchy to decide what to do with the command in question. Shown below is that hierarchy. ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ First User-Level UDC File ³ ³ . ³ ³ . ³ ³ . ³ ³ N'th User-Level UDC File ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ³ ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³First Account-Level UDC File ³ ³ . ³ ³ . ³ ³ . ³ ³ N'th Account-Level UDC File ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ³ ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ First System-Level UDC File ³ ³ . ³ ³ . ³ ³ . ³ ³ N'th System-Level UDC File ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ³ ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ MPE XL System Commands ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ³ ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ File Names ³ ³ (Command Files & Programs) ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ This hierarchy is followed regardless of whether it is trying to locate a command provided at a colon (:) prompt or a command that is coming from a UDC. This is the reason that when using nested UDCs, the UDC definition must follow the reference(s) to that UDC (unless the RECURSION option is specified). There is an exception to this hierarchy: UDCs with LOGON listed as an option. When a user logs on, one logon UDC, at most, will be performed from each UDC level. The system-level logon UDC (if present) will execute first, then the account-level logon UDC (if present), and finally, the user-level logon UDC (if present) will be executed. If more than one logon UDC exists at a level, only the first logon UDC at that level will be executed but it will not affect the execution of other levels' logon UDCs. Another implication of this hierarchy is that when a UDC at one level has an identical name to a UDC or command at another level, the following rules apply: 1. A UDC in user-level UDC file 1 takes precedence over a UDC in user-level UDC file n. 2. A UDC in user-level UDC file n takes precedence over a UDC in account-level UDC file 1. 3. A UDC in account-level UDC file 1 takes precedence over a UDC in account-level UDC file n. 4. A UDC in account-level UDC file n takes precedence over a UDC in system-level UDC file 1. 5. A UDC in system-level UDC file 1 takes precedence over a UDC in system-level UDC file n. 6. A UDC in system-level UDC file n takes precedence over the MPE XL system commands. 7. An MPE XL system command takes precedence over command and program files. What all of this means is that you can set up a UDC with exactly the same name as an MPE XL system command (or UDC, command file, or program file) and effectively redefine that command. For instance, if you want to keep a user from using the PURGE command, the following UDC could be established: PURGE FILENAME = " ", TEMP = " " ECHO YOU HAVE NOT BEEN GIVEN ACCESS TO THIS COMMAND. ** Unless you are specifically taking advantage of this capability, it is best to give all of your UDCs unique names from anything else on the system. Here is another example of these rules and the hierarchy: If both a system-level and a user-level UDC have the same name and an account-level UDC (with the NORECURSION option) references a UDC by that name, then the system-level UDC will be executed rather than the user-level UDC because the system-level UDC is "after" the account-level UDC that referenced it, whereas the user-level UDC would be "before" that reference. If, on the other hand, the account-level UDC is defined with the RECURSION option, the user-level UDC will be executed rather than the system-level UDC because the RECURSION option causes the search to start at the beginning of the UDC directory, rather than starting where it currently is. (Anybody lost?!?) A user must have special capabilities to establish account- or system-level UDCs. To establish account-level UDCs, the user must have the AM capability; to establish system- level UDCs, the user must have the SM capability. Additionally, if system-level UDCs are established, the system-level UDC files must either have their access security released or have the access security such that all users will have READ and LOCK access to the UDC file(s). (For security reasons, the latter is preferred.) 2.3.4 Telling the system about your UDC file(s). If there is any one thing that makes people stop using UDCs in favor of command files, it is likely the fact that UDCs must be cataloged, and command files do not. It is because of this cataloging that UDCs are not good candidates for command definitions that change often. In my experience, however, the large majority of user commands are pretty stable and seldom change. Those that do change often should probably be defined as command files. The new SETCATALOG parameters, APPEND and DELETE, make the cataloging task a bit more palatable. To continue with the creation of your UDCs, we need to tell the system about them. 2.3.4.1 Cataloging your first UDC file(s). As stated earlier, simply creating a UDC file with a text editor does not yet make the UDCs available for use. The next step is to tell MPE XL that you have a UDC file you wish to use. The MPE XL system command to do this is SETCATALOG. The simplest syntax of the SETCATALOG command is: SETCATALOG udcfilename[/lockword] where udcfilename is your UDC file name and lockword is an optional lockword assigned to the UDC file. This version will enable a UDC file for the user level only. The user executing the SETCATALOG command must have READ and LOCK access to the UDC file. Unless you have account or system manager capabilities, you must logon as the user that you want to enable the UDC file for. The SETCATALOG command may be issued from a session, job, or in BREAK. It may not be issued from a program, nor is it BREAKable. When SETCATALOG is executed with a file name provided, three things occur. The command interpreter searches the UDC file for errors: Problems like specifying an option that is not a valid option are caught; problems like syntax errors in the body section of the UDC are not caught. If no errors are found in a UDC, then an entry is established in a directory that will eventually contain entries for all UDCs in the UDC file. The UDC file name and optional lockword is stored in a system catalog of all UDC users. This system catalog is file COMMAND.PUB.SYS. The directory is stored as an "object" in transient space. Since the lockword (if one is provided) is stored in COMMAND.PUB.SYS, a user does not need to know the lockword to logon or to access a UDC. In addition to the UDC file name (and lockword), the user name and account and the UDC level (user, account, system) are also stored in COMMAND.PUB.SYS. As you could probably guess, the file COMMAND.PUB.SYS must exist before any SETCATALOG is attempted. If the file does not exist, the system manager or supervisor must build it. The file should be built with a record size of 128 words. The number of records required for the file can be determined by calculating the sum of: 1 for each user.account that will have user-level UDCs; plus 1 for each user-level UDC file to be used; plus 1 for each account that will have account-level UDCs; plus 1 for each account-level UDC file to be used; plus 1 if system-level UDCs are to be used; plus 1 for each system-level UDC file to be used. So, the BUILD command used by the system manager might look like: BUILD COMMAND.PUB.SYS;REC=128;DISC=500 To secure this file so all users may utilize UDCs, but only the system manager may read or modify it (since there could be sensitive information stored there), the system manager should enter: ALTSEC COMMAND.PUB.SYS;(X:ANY;R,L,W,A:CR) Taking this last step will provide execute access to all users (which is all they need), and restrict all other access to the creator of the file (in this instance, the system manager). If you have more than one UDC file that you wish to enable at the user level, the syntax of the SETCATALOG command becomes: SETCATALOG udcfilename[/lockword],udcfilename[/lockword]... The UDC file names are listed (with the optional lockwords) with a comma inserted between each one. The position of a UDC in the directory determines which other UDCs it may reference (remember the hierarchy discussed a few paragraphs back?). The UDC files are opened and scanned in the order they appeared in the last SETCATALOG command for that UDC level. All user-level UDCs are entered into the directory first, followed by all account-level UDCs, and finally, all system-level UDCs. 2.3.4.2 Appending UDC files to those already cataloged. If you simply want to add another UDC file to what has previously been cataloged, an option in MPE XL is to use a new parameter on the SETCATALOG command: SETCATALOG udcfilename[/lockword]...;APPEND When the APPEND parameter is specified, the UDCs defined in udcfilename are added to the end of the UDC directory. If you are using nested UDCs, or for some other reason the order in which the UDC files are cataloged is important, you likely do not want to use the APPEND parameter. Suppose sometime previously you typed: SETCATALOG UDC1,UDC3 You therefore have the UDCs from two UDC files enabled (plus any account or system level UDCs!). For whatever reason, you want to add a third UDC file, UDC2, to the UDC directory. To add this file, and retain the other two, you could type: SETCATALOG UDC1,UDC2,UDC3 - or - SETCATALOG UDC2;APPEND Unless the APPEND or DELETE (you will hear about it in a moment) parameters are used when the SETCATALOG command is executed, it has the effect of removing all user-level UDCs for the user entering the command. Additionally, if a UDC file name(s) is provided, those UDCs are re-cataloged and available for use. If file UDC2 must be cataloged between files UDC1 and UDC3, the first example must be used. If the sequence of the files is unimportant, the APPEND parameter provides the better solution. 2.3.4.3 Disabling individual UDC files. So, now you know how to "turn on" or enable user-level UDCs. What if you want to disable or "turn off" user-level UDCs? To accomplish this, you again use the SETCATALOG command, except this time do not provide a UDC file name: SETCATALOG When a UDC file name is not provided with the SETCATALOG command, all entries and references to any user-level UDC files in the UDC directory and COMMAND.PUB.SYS that are currently enabled for the user issuing the command are eliminated. The UDC files themselves, however, are not purged. To re-enable your UDC files, you would simply type the SETCATALOG command, followed by your UDC file name(s) again. Alternatively, an option in MPE XL is to use a new parameter on the SETCATALOG command: SETCATALOG udcfilename;DELETE When the DELETE parameter is specified, the UDCs defined in udcfilename are removed from the UDC directory. The original order of the remaining cataloged UDC files is retained. Disabling user-level UDCs does not have an immediate affect on other jobs or sessions that are logged on with the same user name. They may continue to use the disabled UDCs until they logoff. Conversely, if you enable some UDCs, other users will not have access to them until they logon again. Now, suppose sometime previously you typed: SETCATALOG UDC1,UDC2,UDC3 You therefore have the UDCs from three UDC files enabled (plus any account- or system- level UDCs!). For whatever reason, you no longer need the UDCs in file UDC2. To eliminate them, but still keep the others, you could type: SETCATALOG UDC1,UDC3 - or - SETCATALOG UDC2;DELETE As we found before, the first example has the effect of removing all user-level UDCs for the user entering the command, and re-cataloging the listed UDC files, effectively eliminating the UDCs defined in file UDC2. The use of the DELETE parameter on the second SETCATALOG command is the simpler approach in this instance, and causes the UDCs found in the file UDC2 to be removed from the directory, while leaving all others intact. 2.3.4.4 A couple seldom-used SETCATALOG parameters. A parameter I have never found a need to use is RESET. (Just in case you find it interesting, I will tell you about it anyway.) SETCATALOG udcfilename[/lockword][,udcfilename[/lockword]]...;RESET This causes the UDC file(s) being cataloged to replace all files that are already cataloged. If that sounds familiar it is because it is exactly the same thing that occurs if you don't provide any parameters. In other words: Including RESET is the same as leaving off APPEND and DELETE. One last parameter that you may wish to know about: SETCATALOG udcfilename[/lockword][,udcfilename[/lockword]]...;SHOW This will list the UDC file names and definitions in the files as they are scanned. This is helpful for locating where an error is occurring when you use the SETCATALOG command. I don't suggest it for general use, however; It can take a while to list all of the UDC definitions in a large UDC file. Also, a small security breach you should be aware of: Even if you have specified the NOHELP option on a UDC, the definition of that UDC will still list if SHOW is used on the SETCATALOG command. 2.3.4.5 SETCATALOG use by account or system managers. You now know everything (well almost everything) I know about using the SETCATALOG command with user-level UDC files. But what about account- and system-level UDC files? How do they get enabled and disabled for use? The answer again is the SETCATALOG command! We add one more parameter to the previous syntax: SETCATALOG udcfilename[/lockword][,udcfilename[/lockword]]...;ACCOUNT SETCATALOG udcfilename[/lockword][,udcfilename[/lockword]]...;SYSTEM The ACCOUNT parameter specifies that the UDC file(s) being enabled should be available for all users in the account. This parameter requires the account manager capability. Reading between the lines, you have probably realized that you must logon to the account that the UDC file is to be enabled for. For example, if you want to enable UDC file ACCTUDC for account XYZ, first logon as the account manager of account XYZ, then enter: SETCATALOG ACCTUDC;ACCOUNT If you wish to disable the account-level UDC files, you would enter: SETCATALOG;ACCOUNT Again, you must have the account manager capability to use the ACCOUNT parameter. Taking this new information into account, all previous information pertaining to the SETCATALOG command and user-level UDC files also applies to account level UDC files. The SYSTEM parameter specifies that the UDC file(s) being enabled should be available for all users of the system. This parameter requires the system manager capability. For example, if you want to enable UDC file SYSUDC for all users of the system, just logon as the system manager, then enter: SETCATALOG SYSUDC;SYSTEM If you wish to disable the system-level UDC files, you would enter: SETCATALOG;SYSTEM Again, you must have the system manager capability to use the SYSTEM parameter. Taking this new information into account, all previous information pertaining to the SETCATALOG command and user-level UDC files also applies to system-level UDC files. If you have the account manager or system manager capability, you may use another parameter of the SETCATALOG command: SETCATALOG udcfilename[/lockword][,udcfilename[/lockword]]...;USER=user[.account] where user is a user name and account is an account name. This allows you to enable a UDC file for a user other than the one you are logged on as. Account managers can enable UDC files for any user in their account. The system manager may enable UDC files for any user on the system. They will not take effect, however, until the next time the user logs on. This parameter can also be used to disable UDC files for other users: SETCATALOG;USER=user[.account] The same restrictions and capabilities apply for account managers and the system manager, as were just discussed. 2.4 How do I alter a UDC file after it has been cataloged? At some point (probably very soon after you start using UDCs), you will need to modify or add to an existing UDC file. There is not much more involved than simply using a text editor to make the changes or additions; however, you do need to know about a "gotcha". Because of the way UDCs are enabled, whenever a user is logged on to the system, any UDC file(s) associated with that user (including account- and system-level UDC files) are considered "open". What this means is that you may not alter that UDC file in any way as long as the user is logged on and has the UDC file enabled. You may not PURGE, RENAME, or (in EDIT/3000) modify and KEEP that UDC file. Any attempt to alter the file will result in the error message "EXCLUSIVE VIOLATION". So, how do you ever make changes or additions?!? You have five options (take your pick -- they all work well under different situations): 1. Have all users (and jobs) that are using the UDC file logoff (except you, of course). You use the SETCATALOG command to disable the UDC file in question. Make your changes to the file, and keep it. Re-enable the UDC file by using the SETCATALOG command. Notify the users they may logon again. 2. Have all affected users (including yourself) disable the UDC file by using the SETCATALOG command. Make your changes to the file, and keep it. Have all users re-enable the UDC file by using the SETCATALOG command or you use the SETCATALOG command and have the other affected users logon again. Watch out for batch jobs when using this option. 3. Have all affected users (and jobs) logoff the system. You logon so you can modify and keep the UDC file, but as a user who does not have this UDC file enabled. Make your changes to the file, and keep it. Notify the users they may logon again. 4. Logon so that you can modify and keep the UDC file. Make your changes to the file and keep it under a new file name. Later, after all affected users and jobs have logged off, disable the UDC file, PURGE the old UDC file, RENAME the new file to the old file's name, and re-enable the UDC file with the SETCATALOG command. 5. Any combination or variation of the above four options that you can get to work. It is important to understand that all affected users must take some action (log off/on or SETCATALOG) because the SETCATALOG command takes effect only for the session or job that issues it and for future logons. It does not affect other jobs or sessions currently logged on. 2.5 What happens when I logon and have some UDCs enabled? At logon time, any user who has one or more UDC file(s) enabled for his/her use (user, account, or system!) will cause a fair amount of CPU and disc utilization to occur. As a result of previous SETCATALOG commands, the file COMMAND.PUB.SYS contains the UDC file names enabled for every user, as well as those enabled for each account and the system. At logon time, this file is searched to identify what UDC files are enabled for the user in question. As each one is identified, that UDC file is opened and the contents of it are read. As the UDC file is scanned, entries are created and placed in a directory of UDCs for the session or job. That directory is created as an "object" in transient space, according to Hewlett-Packard. (It sounds like a table to me!) When you enter an MPE XL system command or UDC name, the command interpreter searches the UDC directory for that which you typed in, starting at the beginning of the directory. Remember entries are placed in the UDC directory in user-level, account- level, system-level sequence. If the command is found in the UDC directory, the UDC body for that command is read one line at a time and parameters are substituted into the line where appropriate. The command interpreter is then re-entered at a special internal entry point to interpret the new expanded command string and goes through the same steps just mentioned, except that this time, the UDC directory scan begins with the directory entry that follows the UDC currently being executed. (Now do you understand why the definition of a UDC must be after its reference?) If the RECURSION option is in effect, the directory scan starts at the beginning of the UDC directory again. If the command interpreter fails to find a match for a command string in the UDC directory, it then checks to see if it is a valid MPE XL system command. This cycle is repeated until the end of the UDC definition that is being executed. By the way, if you have system manager (SM) capability, and want to logon but not have any UDCs set up for your use, simply add ";PARM=-1" to your HELLO command. In this way, the system manager can logon and gain immediate access to an MPE XL prompt, without any interference from logon UDCs. This option is only available to users with system manager capability. 2.6 How do I find out what UDCs are available? There is a handy MPE XL system command that will list all of the UDC names enabled for your session or job: SHOWCATALOG [listfile] where listfile is the name of the file (disc or printer) you wish the list to be sent to. Unless directed elsewhere with a prior FILE command, if you specify listfile, the listing is sent to device class LP. If listfile is not provided, the list of UDC names will be displayed on $STDLIST (your terminal for a session). This command may be issued from a session, job, program or in BREAK. The SHOWCATALOG command is BREAKable (it aborts execution of the command). The output from the SHOWCATALOG command lists the UDCs currently enabled for your use, the level at which they are defined (user, account, system), and the file name in which they reside. A sample execution follows: :SHOWCATALOG UDC1.GROUP.ACCT AA USER BB USER UDC2.GROUP.ACCT CC USER ACCTUDC.PUB.ACCT DD ACCOUNT SYSUDC.PUB.SYS EE SYSTEM FF SYSTEM GG SYSTEM This example shows seven UDCs enabled from four different UDC files: Three at the user level, one at the account level, and three more at the system level. The SHOWCATALOG command has another parameter that can be useful, especially for account and system managers: SHOWCATALOG [listfile];USER=user[.account] where user is the name of a user, and account is an account name. This parameter permits you to specify a user other than yourself for which you want the SHOWCATALOG done. The output when this parameter is used will consist of only enabled UDC file names and which level they were defined at. No UDC names will be listed. For example if you want to know what UDC file(s) are enabled for a user, you could type: SHOWCATALOG;USER=DAVE and the system would respond with: USER UDC CATALOG FILE NAMES: UDC1.GROUP.ACCT UDC2.GROUP.ACCT ACCOUNT UDC CATALOG FILE NAMES: ACCTUDC.PUB.ACCT SYSTEM UDC CATALOG FILE NAMES: SYSUDC.PUB.SYS There are a few limitations when using the USER= parameter: 1. A user with neither account nor system manager capabilities can specify only his/her own user name. This type of user may not obtain information for any other user. 2. A user with account manager capability can specify any user in his/her account. Additionally, if "@" is used for the user name, only the account-level UDC file name(s) will be displayed. 3. A user with system manager capability can specify any user on the system. Additionally, if "@" is used for the user name and an account name is specified, the account-level UDC file name(s) will be displayed. Also, if "@" is specified for both the user and account, only the system-level UDC file name(s) will be displayed. A way of getting more information about a particular UDC is to use the MPE XL HELP command. Unless the NOHELP execution option was specified when the UDC was created, if you type: HELP udcname where udcname is the name of a UDC, you will receive a listing of the UDC definition. For example, if you typed: HELP J (and the UDC we discussed sometime back was enabled), the system would respond with: USER DEFINED COMMAND: J WHAT2SHOW=" " OPTION LIST SHOWJOB JOB=@!WHAT2SHOW If the NOHELP execution option is specified when a UDC is created, and the HELP command is used for that UDC, the system will respond with: Can't find anything under this command or in table of contents. unless the UDC name is the same as an MPE XL system command, in which case you will receive information about the MPE XL system command. It should be noted that you may not enter the HELP subsystem itself and get information about your UDCs. Only by using the HELP command as described earlier will you receive this information. 2.7 How about some examples? Good idea! Before we start, a few words of explanation: Anytime you see the characters in this tutorial, read it as an escape character. That is, for purposes of this tutorial, I have used the characters in place of the escape character. However, if you were to type in the UDC, you would need to use the escape character instead. Similarly, the control character will be represented by the characters . Let us start with a look at some games -- I mean UDCs for a games user. I have a variation of the following UDC file set up on my system: StartGames Option LogOn Echo &dA*********************************************** Echo &dA WELCOME TO THE HP3000 GAME ROOM Echo &dA*********************************************** Echo Type LIST to get a listing of the available games. ** Games Echo ADVENT.... (Adventure) A game of exploration. Echo AMORT..... Creates amortization (loan) tables. ...continued for other games available... ** Advent Continue Run ADVENT List ** Amort Echo &dBIf you want the loan schedule printed on paper, Echo &dBwait for this phrase to appear... Echo &dB ENTER THE LISTING DEVICE (RETURN FOR $STDLIST)? Echo &dBthen press the BREAK key. You will get a colon prompt. Echo &dBType AMORTPRINT, and press the RETURN key. Echo &dBThe screen will now say... Echo &dB READ pending Echo &dBNow type LP, press the RETURN key, and go on to Echo &dBanswer the other questions. Echo &dBIf you just want the schedule to print on the screen, Echo &dBpress the RETURN key instead of doing all of the above. Continue Run AMORT Reset List List ** AmortPrint File LIST=AMORTRPT;Forms=8 1/2 by 11 INCH PAPER REQUIRED G. Resume ** ...continued for other games available... ** Stop Abort ** List Echo Available Games... ADVENT AMORT ANIMAL BJ Echo CHESS FIVEROW FOOTBALL GRIC Echo OTHELLO SAHARA STARTREC TREK2640 Echo If you would like a one line description of each of the games, type GAMES. ** Items of interest in the games UDC file: 1. The LOGON execution option is used so the welcome message appears automatically. 2. Escape sequences are used to control the appearance of text on the screen. In the case of STARTGAMES, it will blink, and in AMORT, the text will be shown in inverse video. 3. The CONTINUE command is used in all of the individual game UDCs to guarantee that the LIST UDC will always be executed, even if the program aborts. 4. The RESUME command is used in AMORTPRINT to put them back in the program automatically after they press the BREAK key. 5. Notice no options were provided in most UDCs. Since the default is NOLIST, the command(s) will not be displayed on the screen. The ECHO commands, however, will cause the messages to be displayed. 6. The LIST UDC must be at the end after all of the individual game UDCs because each one of them ends with a reference to LIST, and I did not want to specify the RECURSION option in each one. 7. The STOP UDC exists to provide the user a "graceful" way to end a game they do not wish to continue. The users know to press the BREAK key and type STOP if they find themselves in this situation. OK, we have had our fun with the games. Time to get back to some serious work. The next examples come from some of my application systems. These UDCs are generally user level UDCs. First, a few UDCs from the accounts payable system. In UDC file APINUDC, I have the following UDC: Payable Option LogOn,NoBreak Continue Payable Bye ** In UDC file APUDC, the following UDCs exist (among others): Payable Option NoBreak File TODAT=TODAT.GLXEQ;Shr File AP830WRK=VENNAMES;Rec=-80,16,F,ASCII;Save Run PAYABLEX ** VendorMaint Option NoBreak Echo Use this program with extreme care.G Run AP429X ** Items of interest in the accounts payable examples: 1. There are two classes of users for most application systems: A "data entry" user who only needs access to one main menu-driven program (for example, PAYABLEX) and a user who needs access to that same program, as well as other utility programs (for example, AP429X) for the application system. I have implemented this by creating two UDC files. The "data entry" user has both UDC files enabled in the order listed above. However, the other user has only the second UDC file enabled. In this way, the UDC to run the program PAYABLEX only needs to be entered in the second UDC file (in this example that UDC is relatively short; however, some others have numerous FILE commands), with a reference made to it in the first, rather than needing to define it twice. 2. Even though the "data entry" users have both UDC files enabled for them, they effectively have only one thing they can do: RUN the PAYABLEX program. This is because of the LOGON execution option which automatically starts up the program at logon time, and logs them off (because of the BYE command) when the program stops running. Two more items are required to guarantee that this will work, however. The NOBREAK execution option must be specified to keep the user from pressing the BREAK key and gaining access to MPE XL. The CONTINUE command is also needed, so that if the PAYABLEX program should abort for any reason (I know -- you write perfect programs that never abort -- I have problems sometimes though!), the next command (in this case, BYE) will still execute. Here is a neat idea for use with the SORT program (it works well with many others too!): EquipmentSort Purge EQPSORTD Run SORT.PUB.SYS;StdIn=SDEQPSRT;StdList=$NULL ** Almost any program can have its standard input and output files redirected (i.e., provided from, or sent to, some place other than normal). See the RUN command for more details on this. In this UDC, the interactive input is coming from a disc file named SDEQPSRT, and the interactive output is discarded. File SDEQPSRT contains the commands that would normally have been provided to the SORT program (i.e., the names of the input and output files, and the key information). Here are some examples from the financial system that show how to execute the same program, but provide for different input and/or output. They also provide examples of nesting UDCs. BalanceSheet BalShRun 11,";Forms=BLANK 8 1/2 by 11 INCH PAPER REQG." ** BalanceSheetGB BalShRun 2 ** BalShRun Copies,Forms=" " File BALSHLST;Dev=LP,,!Copies!Forms Run BALSHX ** ClientPL PrintPL 2,9 ** CorporatePL PrintPL C,12 ** DivisionPL PrintPL 1,13 ** PrintPL FileCode,Copies=1 File PLFLA=PLFL!FileCode,Old File PRPALLST=PRPL!"FileCode"LST;Dev=LP,9,!Copies;& Forms=BLANK 8 1/2 by 11 PAPER REQ G. Run PRPALX ** Here is what to look for in these examples: 1. There are seven UDCs, but only two actually RUN a program; the other five just reference those two. 2. In the case of the balance sheet program (BALSHX), we need to print the report on both blank paper and regular green bar paper. The program takes very little time to run, so we run it twice, once with each UDC, to create two different spool files with a different number of copies for each. In one case, the FORMS parameter and value is provided, and in the other case, the default value is used. 3. In the case of the profit and loss program (PRPALX), we need to print a different number of copies of each type of statement. Additionally, because of the way the program is set up, there is a different input file for each type of statement. There is actually only one character different in each file name, so the FILECODE parameter is used to provide that. 4. In UDC PRINTPL, notice the use of quotation marks (") around the FILECODE parameter. This is because it needs to be substituted in the middle of a "word". 5. In that same UDC, also notice the use of the ampersand character (&) to continue the logical line onto the next physical line of the UDC. Were all of that to have been typed on the same line, it would have gone beyond the 80-character limit for a line. 6. In this example, the UDC definitions have been provided after their references, so RECURSION does not need to be specified. If, however, they were not listed in this sequence, RECURSION would be required in each of the UDCs that does not have a RUN command. What if you have two different users that need to use the same program, but do not use the same "terminology?" Create two UDCs that RUN the same program. The invoicing/accounts receivable system provides a good example. There is one set of users who work with the invoicing part of the system and a second set who work with the accounts receivable part of the system. It is really all one application system, but the two user groups tend to think of them as (related, but) separate entities. So... Invoices InvRecRun ** ARec InvRecRun ** InvRecRun Option NoBreak File ENAME.PUB;Shr File TODAT=TODAT.GLXEQ;Shr Run INVRECX;Lib=G ** In this example, each user group has a UDC that makes sense to them but both end up at exactly the same place! Since most of you are probably programmers, let us look at a couple of UDCs you may find useful in your day-to-day existence. A list of two is by no means an exhaustive list, but rather some ideas to get you started: DBSchema SchemaFile Option List File DBSTEXT=!SchemaFile File DBSLIST;Dev=LP Run DBSCHEMA.PUB.SYS;Parm=3 Reset DBSTEXT Reset DBSLIST ** LinkI ProgName, XL="XL.Pub" Option List Link ^!"ProgName"L,!"ProgName"X;XL=!XL ** There is not a whole lot to explain here -- nothing fancy -- just examples of commands and tasks that you may do every day. The only item I will mention is the use of OPTION LIST which displays the command as it is executed. This helps remind me I am using a UDC and that some day, somewhere, I may need to type this longer command. Now for some UDCs the system operator would likely find useful: AfterChecks LDevNum Option List Spooler !LDevNum;Start ** BackUp Option List Stream BackUpJ.Oper.Sys Limit 1,1 ** BeforeChecks LDevNum Option List Continue Spooler LP;Start Spooler !LDevNum;Stop HeadOff !LDevNum ** JobF Priority = 0 Option List JobFence !Priority ** OutF Priority=1 Option List OutFence !Priority ** RCop FileNumber, Copies=1 Option List SpoolF !FileNumber;Alter;Copies=!Copies;Show ** RPri FileNumber, Priority=8 Option List SpoolF !FileNumber;Alter;Pri=!Priority;Show ** RPur FileNumber Option List SpoolF !FileNumber;Delete;Show ** SetOpKeys Option LogOn SFK 1 0 " Reply " " " 6 "Reply " SFK 2 0 " Redo " " " 4 "Redo" SFK 3 0 " Recall " " " 6 "Recall" SFK 4 0 " System " " Up " 5 "SysUp" SFK 5 0 " Show " "Reports " 16 "ListSpF @;Detail" SFK 6 0 " SpoolF " "(First) " 7 "SpoolF " SFK 7 0 " ... " "UnDefer " 8 ";UnDefer" SFK 8 0 " System " " Down " 7 "SysDown" UserKeys ** Just the same as the last examples, this is by no means an exhaustive list, but rather a starting point as you consider what makes sense for your system. Now a couple points of interest: 1. We print our checks "hot" to the printer. That is, we stop the spooler process for the printer itself. Two UDCs make life easier in this situation: BEFORECHECKS and AFTERCHECKS. Nothing fancy; just some steps that have to be done over and over -- and done CORRECTLY every time. 2. In the SETOPKEYS UDC, the SFK UDC is referenced. This will be discussed later. For the time being, just understand that the SETOPKEYS UDC will cause the terminal function keys to be loaded with this information. If you are getting tired of examples, feel free to go on to the next section. For those of you who want more examples, we will next look at some of the UDCs from my system- level UDC file, and then finish up with some unique "goodies" that may prove useful to some of you. AboJ JSNumber Option List AbortJob #!JSNumber ** AltJ JobNumber,InPriority=8 Option List AltJob #J!JobNumber;InPri=!InPriority ** Files Option LogOn, List File LP;Dev=LP File FastLP;Dev=FastLP File SlowLP;Dev=SlowLP File T;Dev=TAPE Comment The above file commands are in effect. ** L FileSet="@",Detail=2,ListFile=$STDLIST Option List ListF !FileSet,!Detail;!ListFile ** LEq Option List ListEq ** LT FileSet="@",Detail=2,ListFile=$STDLIST Option List ListFTemp !FileSet,!Detail;!ListFile ** LUDC Option List ShowCatalog ** Out Detail= " " Option List ListSpF @;!Detail ** Purges FL1,FL2=$NULL,FL3=$NULL,FL4=$NULL,FL5=$NULL,FL6=$NULL Option List Purge !FL1 Purge !FL2 Purge !FL3 Purge !FL4 Purge !FL5 Purge !FL6 ** Quad Command = " " Option List Run QUAD.PUB.CSL3000;Info="!Command" ** SetUDC AnyParm AllParms = $Null Option List SetCatalog !AllParms ** Sort Input,Output Option List File INPUT=!Input File OUTPUT=!Output Reset LIST Run SORT.PUB.SYS ** T Option List ShowTime ** Make note of the FILES UDC. Option LOGON has been specified so that the file commands are established for every session or job that logs onto the system. Also note the use of ANYPARM in SETUDC. This makes this UDC extremely flexible by permitting the user to specify any required files and/or parameters for a given situation. The remainder of the UDCs simply exist to make it easier to accomplish a particular task, generally by eliminating some of the keystrokes that would be required without the UDC. OK, now for those unique "goodies" I promised you. Have you been looking for a way to load information into your terminal's function keys automatically? If you have, keep reading. If you have not, perhaps you want to know why you would want to. Using the function keys to execute commands is a good alternative to UDCs because the overall system overhead is usually less. Function keys also provide a one or two keystroke execution of commands. Why am I telling you about an alternative to UDCs?!? Because the solution is accomplished with UDCs. My source for this information is the November 1987 issue of Interact magazine. In that issue, Michael J. Parker and Lynn Wilson of State Farm Insurance in Bloomington, Illinois, had a short piece in the "Users' Forum" section of the magazine. I have successfully used a modification of their ideas on all of the terminals I have (HP 2392A, HP 700/92, and HP Vectra PC using Reflections 1). I believe it will work on any "HP" "terminal" that has the capability of "labeling" the function keys on the screen. There are three parts to the solution: Two UDCs that need to be defined once -- probably as system- level UDCs, and one (or more) additional UDC(s) defined that uses the first two. The two system-level UDCs are defined as: SFK Key=1, Attr=0, Head1=" ", Head2=" ", Length=40,& Function=" " Echo &f!"Attr"a!"Key"k16d!"Length"L!Head1!Head2!FunctionMA ** UserKeys Echo &jBMA ** The SFK UDC accepts the information for one function key and "loads" that information by causing it to be displayed on the terminal with the ECHO command. Be careful when you type this one in: Upper and lowercase makes a difference in how it will execute! The KEY parameter signifies which function key (1 through 8). The ATTR parameter indicates what should happen when the function key is pressed: Values for the Attribute (ATTR) parameter of the SFK UDC Value Action to be Taken 0 NORMAL. The defined string is displayed. To execute it, the user must press the RETURN key. 1 LOCAL ONLY. The defined string is displayed; it may not be executed, however. 2 TRANSMIT. The defined string is displayed and immediately executed. The HEAD1 and HEAD2 parameters provide values to be placed in the labels on the screen. LENGTH indicates how many characters are in the function string. And finally, the FUNCTION parameter provides the actual character string to be "loaded" into the function key. The USERKEYS UDC simply causes the function key labels to be displayed on the terminal screen (if they are not already). The "MA" sequence in both UDCs effectively "erases" the lines from the screen as the UDC executes. If you would like them left on the screen, that sequence could be left off the end of the line. What might the UDCs that use these look like? Here is an example: SetMainKeys SFK 1,2," "," Query ",17,"Run QUERY.PUB.SYS" SFK 2,2,"DataBase","Utility ",18,"Run DBUTIL.PUB.SYS" SFK 3,2," Show "," Jobs ", 7,"ShowJob" SFK 4,2," ","FormSpec",20,"Run FORMSPEC.PUB.SYS" SFK 5,2," "," Quad ",20,"Run QUAD.PUB.CSL3000" SFK 6,2," List ","Reports ",16,"ListSpf @;Detail" SFK 7,0,"Link Prg","Indirect", 6,"LinkI " SFK 8,0," Change "," Group ", 8,"ChGroup " UserKeys ** It is important to note that two eight-character labels must be provided for each of the function key labels. Also, either the actual lengths of the commands must be provided, or the command string must supply forty characters (the default value in SFK). If this advice is not followed, the function key load will likely not work. If you want to take this a step further (although you do get back your saved UDC overhead), instead of RUNning each of the programs, execute a UDC to do so. In the UDC for each program, execute a UDC before and after the RUN command to load the keys for the program about to be run and then reset them afterwards. For example: Query SetQueryKeys Run QUERY.PUB.SYS SetMainKeys ** DBUtil SetDBUtilKeys Run DBUTIL.PUB.SYS SetMainKeys ** Do remember to place these in the UDC file prior to the SETMAINKEYS and each of the SETxKEYS UDCs, or use the RECURSION option. By using this nesting technique, you can set up a "menu" system with only UDCs and terminal function keys. Neat, huh?!? Now for "goodie" number two. Have you ever wanted to get rid of a set of files but did not really want to type PURGE over and over and did not have access to MPEX? Now you can (maybe)! This idea came from the March 1988 issue of The HP Chronicle. Victoria Shoemaker (of Taurus Software) in her :NEWUSER column, presented this novel solution to the problem: PurgeFS FileSet Option List Store !FileSet;$Null;Show;Purge ** This UDC STOREs the file set you specify to $NULL (which does nothing -- you do not even need to REPLY to a console request!) and then PURGEs the files afterwards. This format of the STORE command is normally used to archive information and then remove it from the system -- we just happen to be archiving to the "bit bucket". Any file set that the STORE program will accept (including the "-" option) can be provided to this UDC. Be careful with this one -- it can be very powerful. Make sure you have a good backup before you type PURGEFS "@.@.@"! "Goodie" number three. Do you need a way to provide different "welcome" and/or "news" messages for each user? If so, read on. This one comes from an article M.E. Kabay (of JINBU Corporation) wrote in the March 1988 issue of The HP Chronicle. Originally, his UDC utilized a program named LIST found in the TELESUP account. MPE XL's PRINT command now serves the same purpose. Here's a system-level UDC: SysMessage Option LogOn Print NEWS.PUB.SYS ** If an account needs a special message or "news" file, set up an account-level UDC for it: AcctMessage Option LogOn Print NEWS.PUB.ACCT ** Special needs for a user? Try this user-level UDC: UserMessage Option LogOn Print NEWS.GROUP.ACCT ** By having all of these separate files, you can easily provide different information to different users or accounts by including it in their own news file. To update a file, simply use your favorite text editor. One last "goodie". This one permits you to send a message or list the contents of an entire file on any terminal screen that is turned on but not logged on: Send LDev,Source File TERM;Dev=!LDev Continue FCopy From=!Source;To=*TERM Reset TERM ** This UDC, when executed, uses the FCOPY program to copy the specified file to the specified terminal. Again, the destination terminal must be turned on but logged off for the message to be displayed. If $STDIN is provided for the SOURCE parameter, then the user can type whatever he/she wishes at the time of the UDC execution. (This can be a little tricky though -- there is no prompt and you must type ":EOD" to end your message.) A situation where I find this UDC helpful is after a backup has completed, and I need to let users know they can logon. Consider the following: SendToAll Source Send 100,!Source Send 101,!Source Send 102,!Source Send 103,!Source Send 104,!Source Send 105,!Source Send 110,!Source Send 111,!Source Send 112,!Source Send 113,!Source Send 114,!Source Send 115,!Source Send 120,!Source Send 121,!Source Send 122,!Source Send 123,!Source Send 124,!Source Send 125,!Source ** If I type: SENDTOALL SYSTEMUP.OPER.SYS then it will attempt to transmit the contents of file SYSTEMUP.OPER.SYS to each terminal. If a particular terminal is not turned on, or is already logged on, that FCOPY will fail, but because of the CONTINUE command, the next one will still be attempted. 2.8 What are some problems I may have while using UDCs? Throughout the tutorial, I have provided a number of warnings and gotchas. Listed here (in somewhat random order) are a few worth repeating and a few not mentioned previously. If a system- and a user-level UDC have identical names and an account-level UDC (with NORECURSION in effect) references a UDC by this name, then the system- level UDC will be executed because of the UDC hierarchy. If RECURSION is in effect, the user-level UDC will be executed instead. If an error or warning occurs as a UDC executes, MPE XL will: 1. Print an appropriate error message. 2. Unless NOHELP is specified, print a caret (^) pointing to the error. 3. Unless NOHELP and NOLIST are specified, print the line in which the error occurred. Every time a user logs on, a UDC directory is created for that session or job. If an error occurs during this initialization, only the UDC level in which the error occurs will fail to be initialized. All others will still be enabled. If the SETCATALOG is executed as part of a UDC, it will be the last command executed in the UDC body. Additionally, if the SETCATALOG was part of a nested UDC, all levels of UDC execution are terminated after completion of the SETCATALOG command. If you execute a UDC that RUNs a program, you press BREAK, and then execute the SETCATALOG command while in BREAK, you may type RESUME, and continue with that program; however, any further execution of the UDC that issued the RUN command will be terminated. UDCs are not always as secure as you might think. Certain programs and subsystems enable users to enter MPE XL system commands, RUN programs, and execute UDCs and command files. So even if you have a UDC with LOGON and NOBREAK specified, the user may still gain access to MPE XL. When you run a program, you may no longer have access to your UDCs. The COMMAND intrinsic can be used only to execute MPE XL system commands. To have access to your UDCs, they must have been defined with OPTION PROGRAM, and the program must use the HPCICOMMAND intrinsic to execute a UDC. Consider using the CONTINUE command wherever possible. This will help prevent a program from aborting and terminating the UDC execution. Even though it may seem unlikely that a program will abort, it can be accomplished in many programs by typing :EOD when prompted for input. This causes an end of file condition on $STDIN and gives many programs problems. Even though you have disallowed certain commands to a user (by redefining them with a UDC), be careful. If the user has access to the COMMAND intrinsic (e.g., through EDIT/3000), the user can still execute most MPE XL system commands. If instead, the user's access is to the HPCICOMMAND intrinsic, the UDCs should still redefine the commands. When modifying a UDC file, make sure all users (sessions and jobs) accessing that file have either logged off or disabled UDCs with the SETCATALOG command. If you are working on a system-level UDC file, that means every session and job on the system is affected! If you get rid of a user (with the PURGEUSER command) who has UDCs enabled, the entries are NOT removed from COMMAND.PUB.SYS. Always execute a SETCATALOG command to disable UDCs for the user before purging the user. Here is a question you have not asked yet: Is there a maximum number of UDCs that may be enabled for a user? The answer is: Not really. Every UDC enabled for a job or session must have an entry placed in a UDC directory stored in transient space. When transient space is completely used, you have reached the maximum number of UDCs. In practical terms, however, you will likely experience poor system response (especially at logon time) before you ever create the maximum number of UDCs! UDCs bring with them system resource overhead at logon time, and they use up part of the system's transient space. The transient space is used to store the UDC directory for each job or session. To reduce overhead and improve system performance when UDCs are used, do whatever you can to reduce the number of UDC files. This will reduce the number of FOPEN calls. If you keep these potential problems and limitations in mind as you start your adventure into the wonderful world of UDCs, you should do well in avoiding most of the problems and pitfalls along the way. 2.9 Are we done with UDCs yet!?! Yes! At least for the time being. And now for something completely different... 3 What are JCWs? JCW is one of the many acronyms used in the HP3000 world. This one comes from the phrase Job Control Word. A JCW is MPE XL's way of permitting programs and commands to communicate with each other within a given job or session. JCWs are unsigned 16-bit integer variables used at the operating system level with values ranging from zero through 65,535. Each JCW has a name and can be set and/or interrogated either by the operating system, MPE XL system commands, or programs. 3.1 A brief comparison of JCWs and session-level variables. An extremely close relative (adopting parents?) of the JCW is the variable. JCWs are actually a subset of session-level variables, being restricted by values and naming conventions. The MPE V idea of providing users with operating system-level variables was expanded in MPE XL to include data types other than numeric. MPE XL session- level variables can retain data in boolean form, 32-bit numeric form, and string form. JCWs are able to retain information in 16-bit numeric form only. These new variable types have made it possible for MPE XL to provide a wealth of new information not readily available to the user previously. The information in the predefined variables range from the formatted time of day, and job count, to the interactive state and CPU time used. Other variables are able to control the user's environment, such as changing the MPE XL prompt and automatically logging the user off if there has been no activity within a given amount of time. A further discussion of variables is outside the scope of this tutorial. As we progress through the JCW material, however, there will be occasional references to variables. I strongly encourage you to learn all you can from other sources about variables. They will open up many doors you may not even know you want open! 3.2 How can JCWs help me? - or - Why would I want a program to talk to my commands? Good questions! Properly used JCWs will permit you to create "smarter" jobstreams. They can help to automate some of the decision making process in procedures. JCWs will permit a program to pass a numeric value to another program without the use of a file, or interprocess communication. They can even help you catch errors before they become a problem! All of this is to say: JCWs can help make the system more user friendly. By testing JCWs against specific values, the user can program conditional statements that take action(s) based on the results of the test. JCWs can be set to predetermined values to indicate completion of steps within a procedure. JCWs can be checked to determine if certain events (usually errors) have occurred within MPE XL. With some limitations, JCWs can be used to pass control totals between programs. 3.3 OK, I think I see how they could help me. So, how do I create and use a JCW? First, some background information. JCWs are stored, along with standard variables, in the session Variable Table managed by MPE XL. This table is shared by all processes in a given job or session. Three classes of JCWs exist: user-defined JCWs; system- defined JCWs; and system-reserved JCWs. In some ways, they are exactly the same -- in other ways, they are completely different. 3.3.1 User-defined JCWs. User-defined JCWs are named and assigned values solely by the user. MPE XL never changes the value of, or interrogates a user-defined JCW. The user creates and assigns a value to this class of JCWs with the SETJCW command or the PUTJCW intrinsic. The JCW name must begin with an alphabetic character and consists of a maximum of 255 alphabetic or numeric characters. The JCW name may not contain an underscore ( _ ) even though this is acceptable for standard variable names. You may not begin a JCW name with the mnemonic names OK, WARN, FATAL, or SYSTEM except under very specific conditions. (If you want to know what the conditions are, see the HP "Commands" manual.) The value assigned to a user-defined JCW must be in the range of zero to 65,535 inclusive. User-defined JCWs can be interrogated by the user with the SHOWJCW command and the FINDJCW intrinsic. These new commands and intrinsics will be discussed later, so please be patient. 3.3.2 System-defined JCWs. System-defined JCWs are named by the system and assigned values by the system and/or by the user. Both the system and the user may interrogate system-defined JCWs. Only two system-defined JCWs exist: JCW and CIERROR. Both are created and set to zero at the beginning of every job or session. They will remain zero unless an error occurs or the user changes their value. The JCW named JCW is set by MPE XL and some subsystems. It is checked before each step (process) in a session or job. Based on its value, MPE XL may abort the job or UDC execution. (See a discussion of the CONTINUE command elsewhere.) The JCW named JCW has two special values as identified in the table below. Special values for the JCW Named JCW Value of the JCW JCW Message Displayed / Meaning 49,152 (System 0) Program aborted per user request. A value greater than 49,152 Program terminated in an error state. The CIERROR JCW keeps track of command interpreter (CI) errors: When a CI error occurs, CIERROR is set to reflect the error number. Valid commands do not reset CIERROR to zero. Thus, it always contains the number of the last error that occurred, unless the user resets its value. Generally, it is best not to alter the values of the system- defined JCWs. If you need to control a JCW, it is best to use a user-defined JCW. 3.3.3 System-reserved JCWs. System-reserved JCWs are named and assigned values solely by the operating system. Users may not change the value of a system-reserved JCW. They can, however, interrogate it. There are six system-reserved JCWs: HPMINUTE, HPHOUR, HPDAY, HPDATE, HPMONTH, and HPYEAR. The following table briefly explains each system-reserved JCW. The Six System-Reserved JCWs JCW Name JCW Description Possible JCW Values HPMINUTE Minute of the hour 0 through 59 HPHOUR Hour of the day 0 through 23; Midnight = 0 HPDAY Day of the week 1 through 7; Sunday = 1 HPDATE Day of the month 1 through 31 HPMONTH Month of the year 1 through 12; January = 1 HPYEAR Year of the century 0 through 99 3.3.4 JCW usage in jobs and/or sessions. OK, so now you know what JCWs are. You even know about the three classes of JCWs and what who can do to what. But, how do you look at or set their values? How do you delete a JCW? For jobs or sessions, the answer is: With the SHOWJCW, SETJCW, and DELETEVAR commands. The first two correspond to the MPE XL system commands SETVAR and SHOWVAR used on standard variables. (Actually, these variable commands may be used to set and display existing JCWs. However, with the SHOWVAR command you will also get a list of all standard variables along with your JCWs.) MPE XL distinguishes between variables created by the SETJCW command and those created by the SETVAR command by way of an internal "flag". 3.3.4.1 The SHOWJCW command. The SHOWJCW command displays the current value of one or more JCWs. Its syntax is: SHOWJCW [jcwname] where jcwname is a valid JCW name (any class). If a name is provided, then only the value for that JCW will be displayed. If a name is not provided, then all system-defined and user-defined JCWs and their values are displayed -- system-reserved JCWs are not displayed. This command can be executed from a session, job, program, or in BREAK. It is BREAKable (it aborts execution of the command). If no user-defined JCWs have been created and the user types: SHOWJCW the system will respond with: CIERROR = 0 JCW = 0 unless some error has occurred prior to this command. If you wish to see the current value of a specific JCW, you might type: SHOWJCW HPDAY and the system would respond with: HPDAY = 3 SYSTEM RESERVED JCW Or, if you typed: SHOWJCW UPDATEERRORS and UPDATEERRORS was a valid user-defined JCW name, the system would respond with: UPDATEERRORS = 2 3.3.4.2 The SETJCW command. Big deal, so you can look at the value of a JCW. So what?!? OK, let me tell you how you can change or set the value of a JCW -- that is a little more productive. We need the SETJCW command to do this: [+ value] SETJCW jcwname = value [- value] where jcwname is the name of a new or existing user- or system-defined JCW and value represents one of the following: An octal number between zero and %177777, inclusive. A decimal number between zero and 65,535, inclusive. An MPE XL-defined JCW value mnemonic (OK, WARN, FATAL, or SYSTEM) The name of an existing JCW. All values must be in the range of zero to 65,535, inclusive. That is, if the "+" or "-" option is used, the result of the arithmetic must be in the range as well. (The equal sign following the jcwname may actually be one or more punctuation characters or spaces, except "%" and "-". If you prefer some other notation, feel free...) This command can be executed from a session, job, program, or in BREAK. It is not BREAKable. When the SETJCW command is executed, it causes the MPE XL session Variable Table for your job or session to be scanned for the name of the specified JCW. If the name is found, the JCW is set to the value provided. If the name is not found, it is added to the table and then set to the value provided. If "@" is used for jcwname, all user-changeable JCWs for your job or session will be set to the value provided. Once a JCW is created, it exists for the duration of that session or job, or until the DELETEVAR command or the HPCIDELETEVAR intrinsic is used to delete it. For example, to set a JCW called UPDATEERRORS to a value of 3, you would type: SETJCW UPDATEERRORS=3 To set all user-changeable JCWs to zero, you could type: SETJCW @=0 And finally, if you wanted to create a JCW that had a value representing 2 days from now, you could type: SETJCW TWODAYSFROMNOW=HPDAY+2 This will take the current value from the system-reserved JCW HPDAY and add two. Obviously you would need to follow the statement with an "IF" statement to handle the end of the week, but I think you probably get the idea. You can change the value of an existing JCW by using either the SETJCW or SETVAR commands or the PUTJCW or HPCIPUTVAR intrinsics. If you assign a value to a JCW with the variable command or intrinsic that is not valid for JCWs, but is valid for standard variables, then MPE XL reclassifies the JCW as a standard variable, sets it to the new value, and prohibits you from using it as a JCW. If, however, you later set it to a valid JCW value with the SETJCW command or PUTJCW intrinsic, it is again reclassified as a JCW. When MPE XL reclassifies a JCW or standard variable it provides one of the following messages, as appropriate: JCW VARIABLE RECLASSIFIED AS A STANDARD VARIABLE. (CIWARN 8126) STANDARD VARIABLE RECLASSIFIED AS A JCW VARIABLE. (CIWARN 8127) 3.3.4.3 The DELETEVAR command. There is no command designed specifically to delete JCWs. However, since JCWs are a subset of session-level variables, the DELETEVAR command may be used to delete JCWs. Its syntax is: DELETEVAR variablename [,variablename]... where variablename is the name of an existing user-defined JCW (or user-defined variable). Wildcard characters may be used to delete multiple JCWs (and variables) at one time. If "@" is used for variablename, all user-defined JCWs (and all user-defined variables!) for your job or session will be deleted. It should be noted that only user- defined JCWs (and user-defined variables) can be deleted. This command can be executed from a session, job, program, or in BREAK. It is not BREAKable. For example, to delete a JCW called UPDATEERRORS, you would type: DELETEVAR UPDATEERRORS To delete all user-defined JCWs (and all user-defined variables), you could type: DELETEVAR @ 3.3.4.4 The JCW value mnemonics. A word or two about the four JCW value mnemonics. They are shown in the table below. JCW Value Mnemonics Mnemonic Value OK Zero WARN 16,384 FATAL 32,768 SYSTEM 49,152 These are strictly mnemonics for specific values -- they cannot be used as JCW names. You may use a combination of a mnemonic and a number to indicate a value between two mnemonics. If you specify: FATAL32 for example, an implied addition takes place (32,768 + 32) and the value would be 32,800. The "+" and "-" option can also be used with mnemonics. For example: FATAL - 768 will result in a value of 32,000. If the SHOWJCW command is used to display current JCW values, and a value is greater than one of the mnemonics, then the value will be displayed as the mnemonic plus the amount over. For example, a value of 16,386 will be displayed as: WARN2 An exception to this is that any value less than 16,384 will be shown as the actual number. You are still not feeling very productive with JCWs yet, right!?! OK, here is the good stuff. JCWs are most often used to control the flow of batch jobs (they can also be used in UDCs and/or in sessions), taking various actions based on the results of previous steps. To do this, the IF/THEN, ELSE, ELSEIF, ENDIF, WHILE and ENDWHILE commands are used. For purposes of this tutorial, I am going to assume you either know how these MPE XL system commands work or can easily acquire the knowledge as we look at examples. (Some examples will come later that should clear up some of your questions.) 3.3.5 JCW usage in programs. Now, for you programmer-type people, we will look at how to interrogate, set, and delete JCWs from within a program. The intrinsics FINDJCW, PUTJCW, and HPCIDELETEVAR will be utilized. The first two correspond to the MPE XL system commands HPCIGETVAR and HPCIPUTVAR used on standard variables. (Actually, these variable intrinsics may be used to set and display existing JCWs. However, with the HPCIGETVAR intrinsic you will also have access to all standard variables along with your JCWs.) MPE XL distinguishes between variables created by the PUTJCW intrinsic and those created by the HPCIPUTVAR intrinsic by way of an internal "flag". My examples are based on COBOL II/XL usage; however, I will try to provide information in a general way. 3.3.5.1 The FINDJCW intrinsic. The programmatic equivalent to the SHOWJCW command is the FINDJCW intrinsic. Its syntax (in COBOL II/XL format) is: CALL INTRINSIC "FINDJCW" USING jcwname,jcwvalue,status where jcwname is an alphanumeric variable (character array) containing the name of the JCW to be found, jcwvalue is an unsigned 16-bit integer variable to which the JCW value is returned and status is a signed 16-bit integer variable to which a value denoting the execution status of the intrinsic is returned. The jcwname parameter may contain up to 255 alphanumeric characters, starting with a letter and ending with a non-alphanumeric character, such as a blank. If the requested JCW is found in the session Variable Table, its value is returned to the program in the jcwvalue parameter; if not found, no change is made to this parameter. The status parameter will be returned with one of four possible values shown in the following table. Status Parameter Values for the FINDJCW Intrinsic Status Value Result or Meaning 0 Successful execution: The JCW was found. 1 Error: jcwname is longer than 255 characters. 2 Error: The value of jcwname does not start with a letter. 3 Error: The JCW was not found in the session Variable Table. The FINDJCW intrinsic can be used to return the value of any of the three classes of JCWs. To accomplish the same task in RPG/XL, use the FNDJW operation. Specify the JCW to be found in the Factor 2 Field, either as an alphanumeric variable or literal. Enter the name of the variable to contain the JCW value in the Result Field. This field must be numeric with zero decimal positions. At least one indicator must be provided in the Resulting Indicators Field. The Factor 1 Field is left blank. When FNDJW is executed in an RPG/XL program, the FINDJCW system intrinsic is called. One of the Resulting Indicators is set on to indicate the outcome of the operation as shown in the following table. Resulting Indicator Settings for the FNDJW Operation Resulting Indicator Meaning if the Resulting Indi