VMS Argument Converter

VMS Argument Converter


Version 2.2

VMSARG is a tool to modify a program written to parse Unix style command lines so that it can parse VMS DCL style qualifiers. The tool involves minimal or no change to the original source code. Inputs are a .CLD file defining the VMS style qualifiers, and a mapping file that lists the corresponding Unix commands.


2023-04-23 The information in this document is subject to change without notice and should not be construed as a commitment by anyone.

The software described in this document is provided as is. No guarantee is made to the suitability, reliability, security, usefulness, performance or good taste of this software.

Availability This product may be freely used, distributed or incorporated into any program, commercial or otherwise. It may be enhanced or ported to other platforms.

Copyright ©2006 Tom Wade

Contents


Chapter 1
Introduction

1.1 Function of VMSARG

The aim of this program is to provide a tool by which programs that have been written to accept Unix style command arguments, can be easily enhanced to support VMS standard command line arguments. Often such programs are ported to VMS, without any change to the command style, leaving the target users with an interface that is alien, unfriendly and downright cryptic.

1.2 Objects of the tool

The tool has the following properties:

1.3 Requirements

A C compiler is required, as you will need to compile the output of the GEN-MAPPING utility.

1.4 Who is it aimed at ?

The product is aimed at two distinct groups. Firstly, people who are porting a package from Unix to VMS. This software is made freely available for inclusion in such products, whether they are freeware, public domain or commercial. No licensing is required. As far as I am concerned, I just want to help lessen the numbers of `half-ported' programs that require hieroglyphics like


 foobar -j -h -L=stop flurgl.txt 
The second group is people who have been landed with the task of supporting such `half-ported' software on their machine. This allows you to integrate such a package into the general VMS environment.

1.5 How it works

Basically, you have to do the following: The idea is that the Parse_VMS_Args routine translates the VMS style command line arguments into the Unix style equivalents that the target program is expecting. Thus the only change required to the target source is the call to Parse_VMS_Args -- the rest of the program operates on the command set it has been written to handle.

1.5.1 The CLD file

The CLD file is a standard VMS Command Definition Utility file, which defines the various parameters and qualifiers you wish to support, along with any range of valid values and defaults. It is assumed that the implementor is familiar with this utility. If not, consult the Command Definition Utility manual in the VMS documentation set.

1.5.2 The MAP file

This file is a text file containing the mapping between VMS qualifiers and Unix qualifiers. It also allows you to specify: The format of the MAP file is described in the Map File chapter. This is then converted by the GEN-MAPPING utility into a C file, which is then compiled by the C compiler (it is done this way to ensure that no extra I/O is incurred by the program at run time because of the argument translation).

1.5.3 Change to main program

An extra line is added to the main program. This line is actually


   Parse_VMS_Args (&argc, &argv); 
You may also include a type definition (required by the DEC C compiler):


   int Parse_VMS_Args (); 
This routine parses the user's (VMS style) input and using the mapping provided, builds an argv vector corresponding to equivalent Unix arguments, and sets argc to the number of resultant arguments. The routine then replaces the program's argc & argv by the ones it has just generated. The main program then procedes with the Unix style arguments that it has been written for.

1.6 Program without sources

In the case of a program whose sources are not available, there will be the penalty of an extra image activation in the argument translation. Firstly, a dummy program (provided with the utility) is activated. It parses the user's VMS style input qualifiers, and activates the real program with the translated arguments. This program is called NULLMAIN.C, and is linked with the PARSE-VMS.OBJ file and the output of the .CLD and .MAP file.

1.7 Allowing both VMS and Unix styles

An optional qualifier in the map file tells the Parse_VMS_Args routine to leave the command line unchanged if it detects any qualifiers starting with the `-' character.

1.8 Supported Compilers and Platforms

The VMSARG utility is written for the DEC C compiler, and can be compiled using either this or the VAX C compiler. VMSARG is provided for OpenVMS VAX, OpenVMS Alpha, OpenVMS IA64 and OpenVMS X86.


Chapter 2
Defining a Map file

The Map file specifies how VMS qualifiers and/or parameters are mapped into Unix command line arguments. This file is a text file which you will normally create using an editor. The Map file consists of a single ACTION command and a number of MAP commands (one for each VMS qualifier or parameter). Any line with a `!' character in the first position is regarded as a comment, and ignored. Blank lines are also ignored, and lines may be continued onto another line by appending a dash `-' character at the end.

2.1 Action Command

The MAP file must also contain one (and only one) ACTION command. This is normally at the top of the file, but need not be so. This command tells the parser what it is to do with the translated qualifiers when it has generated them. The format of this command is


 ACTION <action-type>  [/qualifiers] 

2.1.1 Return translated qualifiers

If the action type is RETURN then the parser will return to the calling program with a modified argc & argv argument variables. This mode is used when you are modifying the source code of the application. You add the following line as the first executable statement in the program:


   Parse_VMS_Args (&argc, &argv); 
Note that if you are using the DECC compiler, you should also declare the routine:


   main (int argc, char **argv) 
   { 
   .... (declarations) 
   int Parse_VMS_Args (); 
 
   Parse_VMS_Args (&argc, &argv); 
   ... (rest of code) 

The Parse_VMS_Args routine will return a new argv vector and a modified argc count, which reflect the corresponding set of Unix qualifiers and values to the VMS style ones entered.

2.1.2 Activating a secondary image

If the action type is EXIT then the parser will cause the program to exit after translating the command line. You normally use this approach when you do not have (or do not wish to modify) the sources for the application. You use a dummy program (supplied) which translates the command line into a Unix style one, and then passes this modified command line to the real application image. You can pass this information to the application in a number of ways. This has the advantage of not requiring any modification to the source, at the cost of an extra image activation.

2.1.3 Direct Activation

This is the normal method of providing DCL command functionality to a program where the sources are not available. If the /COMMAND=command-name qualifier is present, the parser will cause the program to execute a LIB$DO_COMMAND) passing the command-name followed by the translated command line (separated by a space). This will cause the dummy program to exit, and immediately activate the application program. The /IMAGE qualifier is normally used in conjunction with the /COMMAND qualifier to specify the image to be actuivated. For example, the following line:


 ACTION EXIT /COMMAND=FOO /IMAGE=SYS$ETC:FOO 
will do the following (assume the user entered an argument *.* /EXCLUDE=*.OBJ) which translated to `*.* -x *.OBJ'):

  1. The program translates the VMS qualifiers to Unix style.
  2. The program defines the local DCL symbol FOO to be "$SYS$ETC:FOO".
  3. The program exits and causes DCL to execute FOO "-x" *.OBJ.

Note the presence of quote characters protecting the lowercase qualifier. This are normally required because DCL will uppercase all the command line by default. Append the /NOQUOTE qualifier to the ACTION command if this is not required.

2.1.4 Defining a DCL symbol

If you need to perform any additional processing to the translated arguments, you can embed the program calls within an enclosing DCL command procedure. The first program accepts the VMS qualifiers, translates them into Unix syntax, and returns them to the command procedure in a DCL symbol. The /SYMBOL=symbol-name qualifier defines the DCL symbol to be defined. The command procedure can then peform any additional processing of this symbol before passing it to the original program. This approach would normally involve the following (for example, our application is called FOO and the real image is SYS$ETC:FOO.EXE)
  1. Define the symbol FOO to activate a DCL command procedure.
  2. This procedure runs the dummy program which returns the Unix command line in a symbol.
  3. The procedure then defines a foreign command to activate FOO.EXE and pass it the translated string.
See the Chapter on using VMSArg when sources are not available for details.

2.1.5 Allowing Unix Syntax

Append the /ALLOW_UNIX qualifier to the ACTION command if you want the program to continue to accept Unix style input. If this qualifier is present, the parse routines will check all the command line elements to see if any starts with a dash character ('-'). If any does, then the line is returned unchanged to the main program (for the RETURN action) or passed to the external image.

2.2 MAP command

The general format of a MAP command is:


 MAP [vms-keyword]  [unix-keyword]  [optional-qualifiers] 
In its simplest form, it simply maps a VMS qualifier directly onto a Unix keyword. For example:


 MAP INCLUDE "-i" 
will map a command like "/INCLUDE=FILE.TXT" onto "-i FILE.TXT". Note that lowercase Unix keywords must be enclosed within double quotes. The optional qualifiers can be used to modify the mapping as described below.

2.2.1 Mapping absence of a qualifier

You can also define a mapping which maps the absence of a VMS qualifier to the presence of a Unix keyword. For example, if the /LOG qualifier is not present, you might want the Unix keyword `-q' to be present. Note that by defining the /LOG qualifier as on by default in the CLD file, you could ensure that the user must enter /NOLOG to get the -q qualifier. This is achieved by using a /NEGATIVE qualifier on the MAP command.


 MAP LOG /negative="-q" 
Note that in this case the affirmative Unix keyword is omitted, meaning that if /LOG is present, no equivalent Unix keyword is generated. You can provide both negative and affirmative keywords, in which case the presence or absence of the VMS qualifier will determine which keyword is used.

2.2.2 Appending values to keywords

By default, the value or values of VMS qualifiers are placed in successive argv cells to the Unix keyword, as if the values were separated from the keyword by spaces. For example, with the mapping for INCLUDE above, a command line of:


 /INCLUDE=(FILE1.TXT,FILE2.TXT) 
would be translated as


 -i FILE1.TXT FILE2.TXT 
In some cases, you might want to attach the value to the keyword differently. For example, to specify a block size to a tape command, you might wish to have a syntax of


 -b=20 
for a block size of 20. In such a case, you would use the following mapping:


 Map BLOCK_SIZE "-b=" /append 
This causes the BLOCK_SIZE qualifier to be replaced by `-b=' and the value appended directly to it.

2.2.3 Separators between values

By default, multiple values are separated from each other by spaces. You can specify an alternate separator if you wish. For example, in the earlier example for /INCLUDE, you might want multiple files to be separated by semicolons. Thus the mapping


 Map INCLUDE "-i" /separator=";" 
would produce the following output for the previous /INCLUDE qualifier:


 -i FILE1.TXT;FILE2.TXT 

2.2.4 Keyword Lists

Keyword Lists allow you to specify a valid set of values which are expected for a given VMS qualifier, and an equivalent list of Unix style keywords. The parser will replace the value of the VMS qualifier with the corresponding value in the Unix list. For example, if you wish to use the VMS qualifier /MODE with two keywords RESTART and CONTINUE, and have this correspond to the Unix qualifier `-m' with keywords `r' and `c', then you would define:


 Map MODE  "-m" /VLIST=(RESTART,CONTINUE) /ULIST=("r", "i") 
If the user entered /MODE=RESTART, it would be translated as `-m r'. If the user enters a value that is not in the list, then it is left unchanged (note that you can restrict the user to only those values you define, by the use of a DEFINE TYPE command within the CLD definitions).

You can combine lists with null keywords to enhance the flexibility of the substitution. For example, if you want the following correspondences:


 /COMPRESSION=GOOD            ->  -9 
 /COMPRESSION=FAST            ->  -1 
use the following mapping:


 Map COMPRESS /VLIST=(FAST,GOOD) /ULIST=("-9", "-1") 
You must ensure that the number of arguments in both lists are the same. The parser will accept unambiguous abbreviations of the VMS keywords (but will always produce the full Unix keywords).

2.2.5 Date and Time fields

Programs written for Unix systems often expect a date/time specification as one of the arguments, and will almost certainly want it in a different format than the one you are accustomed to in VMS. By using the /DATE qualifier, you instruct the parser to accept a VMS style or ISO 8601 date/time specification for this argument, and translate it into the format expected by the application. You specify the pattern as the value of the /DATE qualifier. For example, the application expects a date specification in the form mmddyy. Use the following mapping:


 Map SINCE "-t" /DATE="$N$D$y" 
The parser will accept a VMS style date/time for the /SINCE qualifier, and translate it into the required form. For example, if the user enters /SINCE=28-Mar-2019, it will translate to `-t 032819'.

The full list of transformation characters is as follows:
Symbol Meaning
Y Year in 4 digit form.
y Year in 2 digit form.
M Month name 3 characters.
N Month number 2 digits with leading zero if needed.
n Month number 1 or 2 digits.
D Date 2 digits with leading zero if needed.
d Date 1 or 2 digits.
H Hour field 2 digits with leading zero if needed.
h Hour field 1 or 2 digits.
m Minutes 2 digits with leading zero if needed.
S Seconds 2 digits with leading zero if needed.
The input format can be any of the following types:


/SINCE=25-APR-2023 
/SINCE=YESTERDAY 
/SINCE="-01:00:00" 
/SINCE="+05:00:00" 
/SINCE="YESTERDAY+05:00" 
/SINCE="2024-01-15 15:13"  (ISO 8601 date format). 

Note

If you wish to accept ISO 8601 format dates, make sure you omit the "TYPE=$DATETIME" clause in the CLD file, as this will cause the DCL parser to reject the date before VMSARG can process it.

2.2.6 Help Library

You can cause a qualifier to activate an interactive help session by specifing the /HELP qualifier on the MAP command. For example:


 Map HELP /HELP=ZIP 
Using the HELP command will cause an interactive HELP session using the keyword ZIP as a starting point. By default, the system help library (SYS$HELP:HELPLIB.OLB) is used, but you can override this by adding a /LIBRARY qualifier to the MAP definition as well. You must prepare a Help Library file (.HLB) file---consult the VMS Help Utility manual for details. After exiting from Help, the program will exit.


Next Contents