Building a SAS® Front-end using the Command Definition Utility

Hallett German

GTE Laboratories, Inc.


Copyright (c) 1991 All Rights Reserved

Return to Home Page Publications


1. Introduction

Unlike MVS, the SAS® system does not provide a front-end that VMS users can easily customize. The result has been many VMS sites writing lengthy command procedures using DCL (Digital Command Language.) These are far from intuitive and are difficult to support. A more powerful alternative is using the Command Definition Utility (CDU) to create your own DCL SAS verb.

[SAS's version of this can be found in SAS$ROOT:[SAS606.IMAGE]SAS606.CLD]

However, the documentation to do this is in several DEC manuals and examples (especially with C) are sparse. This paper attempts to demystify this process by creating a simplified annotated DCL verb. References for further information are provided. Once you understand the framework and have an example to work from, you can then build your own DCL front-end.

The following are steps to create a Command Language definition file:

  1. Creating a Command Language Definition file (.CLD).
    This is the "skeleton and skin" of a DCL verb. CLD files define the command-to-be by specifying all valid qualifiers, parameters, default values, and the like.

  2. Create and Compile a C program. This is the"muscle and nerves" of the DCL verb by specifying the sequences enacted when a certain qualifier or parameter is specified. An object file is produced.

  3. Link the C Program. The C object file is linked resulting in an executable. Other object files may be linked as well.

  4. Add the DCL verb to the process command table. (the default). Placing it in your LOGIN.COM> means the DCL verb will be available to you each time that you log on. If you wish to share a command with other users, then ask your VMS system administrators to add it to the permanent system command table.

  5. Run the new DCL command. The command should be now successfully created and available to you. Enter the command name and the specified processing should be performed. If not, repeat steps 1-5 again (and as many times as necessary.)

    Figure 2 shows a general command procedure (.COM file ) that allows you to run steps 1-5 by just entering one command. Just enter RUNIT program at the DCL ($) prompt. (With program the name of your C program and command.) This results in program being assigned to the P1 symbol. (I use the /LIST and /SHOW qualifiers to assist in the inevitable debugging of the C program. These produce a program listing of program.lis that contains intermediate macro expansions.)

    Figure 1 shows the overall process:

    Figure 1 : Process to create a DCL command.





    Figure 2: Example of a generalized batch file to create DCL verbs

    RUNIT.COM

    $ cc 'P1'.c/list/show=(intermediate)
    $ link 'P1
    $ set command 'P1'.cld
    $ 'P1

    The remainder of the paper discusses in greater detail the components used to create a new DCL verb.

    2. The .CLD file

    The .CLD is a text file that sets the boundaries of a verb. The basic syntax is fairly simple. Figure 3 lists the skeleton of a valid .CLD file:

    Figure 3 Skeleton of a .CLD file

    DEFINE VERB verb_name
    IMAGE directory:file
    PARAMETER p1, PROMPT="prompt text",
    LABEL=label,
    VALUE(REQUIRED,LIST)
    PARAMETER p2,PROMPT="prompt text",
    LABEL=label,
    VALUE(DEFAULT="value")
    QUALIFIER value VALUE(REQUIRED)
    SYNONYM "synonym"

    Elements of .CLD file

  6. DEFINE Specifies verb to be defined.

  7. IMAGE Specifies the executable to invoke to process the DCL verb.

  8. PARAMETER Defines the positional parameter (P1-P8) associated with the parameter. (Parameters are not entered with a /). You can also specify for the parameter the following: a prompt, a label, if the parameter is required or has a default value.

  9. QUALIFIER Specifies a qualifier is to be used. (Qualifiers are specified. You can also specify for the parameter the following: a prompt,a label , if the parameter is required or has a default value.)

  10. SYNONYM Creates an alias(es) for a VERB.
  11. To help clarify this, a simple example is provided.

    Let us create a new DCL verb called NAME that will use all of the above. (This example will be used to discuss the other CDU elements as well.)

    Figure 4 lists the .CLD file used to create this verb:

    Figure 4 NAME.CLD

    VERB name
    IMAGE disk1:[hhg1.c]name.exe
    PARAMETER p1, Prompt = "Your First Name",
    LABEL=first,
    VALUE(REQUIRED)
    PARAMETER p2, Prompt = "Your Last Name",
    LABEL=last,
    VALUE(Default="Smith")
    QUALIFIER middle,value

    What is going on here is quite simple:

    Thus the following are possible sessions using the NAME verb:
    NAME
    _Your First Name: PROC
    _Your Last Name: REPORT
    F: PROC L :REPORT

    NAME
    _Your First Name: PROC
    _Your Last Name:
    F: PROC L:SMITH

    NAME /MIDDLE=THE MACK KNIFE
    _Your First Name: MACK
    _Your Last Name: KNIFE
    F: MACK M: THE L:KNIFE

    Space does not permit a discussion of other components of the .CLD file such as DEFINE SYNTAX (Use to modify an already defined verb), and DEFINE TYPE (Define values for syntax, values, labels, etc).

    Keep the following in mind when creating a .CLD to be used as a SAS front-end:

    1. 1. Use DEFINE TYPE to build a category of related keywords. Then you can place a type= statement in a value adjective:

      define type names
      keyword....
      (later on)
      qualifier name value=(type=names,required)

    2. Use the built variables to define values:
      • $DATETIME (allows date and time values)
      • $FILE(checks if a valid file name),
      • $NUMBER(checks if is a valid number)
      • $QUOTEDSTRING (checks if string is in quotes [and retains quotes.])
      • PARAMETER p2, VALUE(TYPE=$NUMBER)

    3. Use the DISALLOW clause to specify combinations of parameters or qualifiers not allowed. Disallow P1 and Q1.

    4. Give the user more flexibility by use the NEGETABLE adjective as part of the qualifier or parameter. This allows users to enter a "NO" prefix to a qualifier name. For example:

      qualifier mess negatable

    3. The fun part -- the C program.

    Even if you are knowledgeable in C, creating a C program to process the result from a .CLD file can be a frightening experience. Two components particularly can cause this anxiety -- 1) use of string descriptors, and 2) CLI run time procedures. Each will be briefly discussed.

    String Descriptors

    Strings in VAX C are represented by string descriptors which are really data structures containing the address type, length, and class of the string. The problem is that VMS C has no direct way to pass by descriptor. Instead, you have to face the ugly and unnerving task of building your own string descriptors. The clearest explanation on this topic can be found in the May 1990 Issue of DEC Professional (pages 132-140)

    CLI Run Time Procedures

    There are 4 major CLI (Command Language Interface) routines. We will only be discussing two of them:

    CLI$PRESENT(qualifier). Returns if a qualifier is present. This will always be true if the qualifier is the default. (Unless a negatable version of a qualifier is used such as /NONUKES.) Results are placed in the variables CLI$PRESENT or CLI$NEGATED.

    CLI$GETVALUE(input string, output string,length of string). This values processes a string and returns an output string. Results are placed in the SS$NORMAL variable.

    We are now ready to look at the NAME.C program.


    #include descrip
    #include stdio
    #include ssdef /*The header of descriptors and types*/
    main()
    {
    register status; /*Status is heavily used so place in a /*register*/
    char fname[25],lname[35],mname[10]; /* arrays are used to hold names*/
    short ret_length=0; /*initialize length variable*/
    $DESCRIPTOR(fn_in, "first");
    $DESCRIPTOR(fn_out, fname);
    $DESCRIPTOR(ln_in, "last");
    $DESCRIPTOR(ln_out, lname);
    $DESCRIPTOR(mn_in, "middle");
    $DESCRIPTOR(mn_out, mname);/*Declare a descriptor for each input and output string*/
    first:
    status=cli$GET_VALUE(&fn_in,&fn_out,&ret_length); /*Read first name*/

    fname[ret_length]=0;
    if (!status) lib$stop(status);/*Exit if failed*/
    last:
    status=cli$GET_VALUE(&ln_in,&ln_out,&ret_length); /*Read last name*/
    lname[ret_length]=0;
    if (!status) lib$stop(status);
    /*Exit if failed*/
    middle:
    status=cli$GET_VALUE(&mn_in,&mn_out,&ret_length); /*Read first name*/
    mname[ret_length]=0;
    if (status == SS$_NORMAL); /*If everything worked then...*/
    printf("F:%s M:%s L:%s", fname, mname, lname);
    } /*End of C program*/

    Keep the following in mind when building a C program to serve as a SAS-front end:

    1. Some people have built their own function calls that perform a lot of the above front-end work. An example is available from the author above request.

    2. Take the time to print the DESCRIP header file to better understand the components of string descriptors.

    3. Enhance your program by using the error messages to provide smoother error handling and easy to understand error messages. This is compiled by entering MESSAGE errorlibrary.

    4. Create a help document (.hlb) and use the LIBRARIAN command to add to the help library. Help documents are in a text file in a special format.

    4. SET COMMAND

    We've already mentioned about SET command used to create the DCL verb. This section just mentions the qualifiers that you can use with this command.

    /DELETE Deletes a verb

    /LISTING Give an output listing

    /OUTPUT Specifies the command table file.

    /REPLACE Replace a verb.

    /TABLE Specifies command table to use.

    5. Conclusions

    This can only be a brief introduction on the major issues in creating a front-end using the Command Definition Utility (CDU). By using the simplified framework, one can have the courage to look at the various DEC manuals (see below) and start building your own DCL verbs.

    Getting in touch with me/Trademarks

    Hallett German
    GTE Laboratories Inc
    40 Sylvan Road
    Waltham, Ma 02254
    617-466-2290
    Mail to me

    SAS ® and all other SAS products mentioned is a registered trademark of the SAS Institute

    VAX, VMS, DCL, and DEC are trademarks of the Digital Equipment Corporation.

    References [Annotated]

    [Since the information on building a DCL Verb in C is not in one place, I have described what each reference contains.]

    Digital Equipment Corporation VMS Command Definition Utility Manual 1988 (Volume 2B
    [Describes the .CLD file components and SET Command.]

    Digital Equipment Corporation VMS Librarian Utility Manual 1988 (Volume 2B)
    [Describes the LIBRARIAN command and HELP libraries.]

    Digital Equipment Corporation VMS Message Utility Manual 1988 (Volume 2B)
    [Describes the MESSAGE command and the message source file components.]

    Gibes, Kernon "A VAX/VMS Command for SAS/Batch Jobs" SUGI 14 Proceedings 1989 pp. 1497-1501
    [Kernon does a good job describing building your own SAS DCL verb and covers some of the above. His program was written in FORTRAN and has provided source in the past. Also describes building your own foreign DCL interface which is not described in this paper.]

    Jaeschke, Rex "String Descriptors"Digital Review May 1990. pp. 132-140
    [I found the DEC manual on this topic less than friendly. I suggest look at the DESCRIP file and reading this article. Rex has a regular column on C, C++, and VMS that I recommend reading]