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
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:
- Minimal change to the source file of the ported package (in
practice, addition of two lines).
- The conversion can be performed by somebody with no knowledge of C
programming.
- Provision must be made for cases where the source code is not
available at all.
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:
- Create a CLD file to define the VMS command arguments.
- Create a MAP file to define how these map to the Unix qualifiers
that the program expects.
- Run the MAP file through a generator program which produces a C
routine.
- Run this C routine through a C compiler.
- Add a call to the Parse_VMS routine immediately before the first
executable statement of the main program of the ported package. This
routine modifies the argc and argv variables to be the Unix style
equivalents of a VMS style command line.
- Recompile the file containing the main program.
- Relink the application, including the supplied object library.
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:
- Specify negative equivalents, i.e. absence of a given VMS
qualifier implies a certain Unix qualifier.
- Specify lists of keyword values to a VMS qualifier, and their
equivalent Unix keywords.
- Specify separator characters for multiple values.
- Define conversion rules for date specifications.
- Activate an interactive HELP session.
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):
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.
- Activate target image immediately (via Lib$Do_Command).
- Pass translated line as a DCL symbol.
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'):
- The program translates the VMS qualifiers to Unix style.
- The program defines the local DCL symbol FOO to be "$SYS$ETC:FOO".
- 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)
- Define the symbol FOO to activate a DCL command procedure.
- This procedure runs the dummy program which returns the Unix
command line in a symbol.
- 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:
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.
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
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
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:
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:
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.