elder@WPAFB-INFO2.ARPA ("INFOCEN - Greg Elder") (11/17/86)
The following files are submitted as a contribution to INFO-MODULA-2.
I've written a module to use with the Logitech Modula-2/86 compiler and MS-DOS
for reading the command line arguments and looking up the values of environment
variables. This module simulates the argc/argv features of C. Also,
a procedure called GetEnv is provided which will search the environment for
a given string and return the string's value if found. The following files
are provided:
CMDENV.DEF - Definition module for CmdEnv.
CMDENV.MOD - Implementation module for CmdEnv.
CMDTEST.MOD - A program to test the ArgC/ArgV variables provided by
CmdEnv.
ENVTEST.MOD - A program to test the GetEnv procedure provided by
CmdEnv.
Use an editor to extract the various files from this message.
To use, compile CMDENV.DEF and COMDENV.MOD. Next, compile and link CMDTEST.MOD
and ENVTEST.MOD. Use the Logitech program LOD2EXE to convert the resulting LOD
files to EXE files (CMDTEST.EXE and ENVTEST.EXE).
CMDTEST will list the arguments found on the command line. For example,
typing
A>cmdtest hello world
will produce
ArgV[ 1]= hello
ArgV[ 2]= world
When you run ENVTEST, you will be asked for an environment variable. After
typing in one, the value of the varianble will be displayed (if the variable
is found). For example,
A>envtest
Enter environment variable: COMSPEC
COMSPEC= A:\COMMAND.COM
Type CONTROL-C to abort envtest.
I hope this module will be of benefit to some people. I still consider myself
a novice Modula-2 programmer. Any suggestions to improve my code are welcome.
Greg Elder
================ CUT HERE =====================================================
(*
* Title: Command Line/Environment Information (CmdEnv)
* Author: Gregory Elder
* Last Update: September 25, 1986
* Compiler: Logitech Modula-2/86
* Description:
* This module provides argc and argv features similar to C and a procedure
* for getting the values of environment variables. ArgC is the count of the
* number of parameters on the command line. ArgV is an array of pointers
* to strings containing the various command line parameters. GetEnv is
* a procedure which, when given an enviroment variable, will return the
* value the variable is set to.
*
*)
DEFINITION MODULE CmdEnv;
EXPORT QUALIFIED
MaxArgs, ArgC, ArgV, GetEnv;
CONST
MaxArgs = 10; (* Max arguments on the command line *)
ArraySize = 200;
TYPE
StringPTR = POINTER TO ARRAY[0..ArraySize] OF CHAR;
Args = ARRAY[0..MaxArgs] OF StringPTR;
VAR
ArgC : CARDINAL;
ArgV : Args;
PROCEDURE GetEnv(EnvVar : ARRAY OF CHAR; VAR Strg : ARRAY OF CHAR);
END CmdEnv.
============ CUT HERE ========================================================
(*
* Title: Command Line/Environment Information
* Author: Gregory Elder
* Last Update: September 25, 1986
* Compiler: Logitech Modula-2/86
* Description:
* This module provides argc and argv features similar to C and a procedure
* for getting the values of environment variables. ArgC is the count of the
* number of parameters on the command line. ArgV is an array of pointers
* to strings containing the various command line parameters. GetEnv is
* a procedure which, when given an enviroment variable, will return the
* value the variable is set to.
*
*)
IMPLEMENTATION MODULE CmdEnv;
FROM SYSTEM IMPORT
AX, BX, CX, GETREG, SETREG, SWI, RTSVECTOR, ADDRESS;
FROM Storage IMPORT
ALLOCATE;
FROM ASCII IMPORT
nul;
FROM Strings IMPORT
Length, CompareStr;
CONST
CmdTailAdr = 80H;
EnvOffSet = 2CH;
TYPE
CardPTR = POINTER TO CARDINAL;
VAR
PSP, AnAddress : ADDRESS;
EnvPTR : StringPTR;
EnvAdrSegment : CardPTR;
PROCEDURE ParseCmdLine;
VAR
CmdLength, i, j, start : CARDINAL;
CmdLine, Sptr : StringPTR;
CmdAdr : ADDRESS;
BEGIN
CmdAdr := PSP;
INC(CmdAdr, CmdTailAdr); (* Get command tail *)
CmdLine := CmdAdr;
i := 0;
CmdLength := ORD(CmdLine^[i]) - 1;
INC(i);
WHILE (i <= CmdLength) AND (CmdLine^[i] = ' ') DO
INC(i);
END;
WHILE (i <= CmdLength) AND (CmdLine^[i] # ' ') DO
INC(i);
END;
ArgV[0] := NIL;
ArgC := 0;
WHILE i <= CmdLength DO
WHILE (CmdLine^[i] = ' ') AND (i <= CmdLength) DO
INC(i);
END;
IF i <= CmdLength THEN
start := i;
WHILE (CmdLine^[i] # ' ') AND (i <= CmdLength) DO
INC(i);
END;
ALLOCATE(Sptr, i - start + 2);
j := 0;
WHILE start <= i DO
Sptr^[j] := CmdLine^[start];
INC(start);
INC(j);
END;
Sptr^[j] := nul;
IF ArgC < MaxArgs THEN
INC(ArgC);
ArgV[ArgC] := Sptr;
END;
END;
END;
i := ArgC + 1;
LOOP
IF i > MaxArgs THEN EXIT END;
ArgV[i] := NIL;
INC(i);
END;
END ParseCmdLine;
PROCEDURE GetEnv(EnvVar : ARRAY OF CHAR; VAR Strg : ARRAY OF CHAR);
CONST
StringSize = 40;
VAR
i, j, len : CARDINAL;
Str1, Str2 : ARRAY[0..StringSize-1] OF CHAR;
BEGIN
len := Length(EnvVar);
FOR i := 0 TO (len - 1) DO
IF (EnvVar[i] >= 'a') AND (EnvVar[i] <= 'z') THEN
Str1[i] := CHR(ORD(EnvVar[i]) - ORD('a') + ORD('A'));
ELSE
Str1[i] := EnvVar[i];
END;
END;
Str1[i + 1] := nul;
i := 0;
LOOP
j := 0;
WHILE (EnvPTR^[i] # '=') AND (EnvPTR^[i] # nul) DO
Str2[j] := EnvPTR^[i];
INC(i);
INC(j);
END;
Str2[j] := nul;
INC(i);
IF CompareStr(Str1, Str2) = 0 THEN
j := 0;
WHILE EnvPTR^[i] # nul DO
Strg[j] := EnvPTR^[i];
INC(i);
INC(j);
END;
Strg[j] := nul;
EXIT;
ELSE
WHILE EnvPTR^[i] # nul DO
INC(i);
END;
END;
INC(i);
IF EnvPTR^[i] = nul THEN
Strg[0] := nul;
EXIT;
END;
END;
END GetEnv;
BEGIN
(* Get PSP *)
SETREG(AX, 026H);
SWI(RTSVECTOR);
GETREG(BX, PSP.OFFSET);
GETREG(CX, PSP.SEGMENT);
ParseCmdLine;
(* Set up environment pointer *)
AnAddress := PSP;
INC(AnAddress, EnvOffSet);
EnvAdrSegment := AnAddress;
AnAddress.SEGMENT := EnvAdrSegment^;
AnAddress.OFFSET := 0;
EnvPTR := AnAddress;
END CmdEnv.
==================== CUT HERE =================================================
(*
* Title: Command Line Test (CmdTest)
* Author: Gregory Elder
* Last Update: November 16, 1986
* Compiler: Logitech Modula-2/86 Version 2
* Description: This program provides a test for the CmdEnv module. It
* simply displays the arguments entered on the command line. To use it
* type the following at the DOS prompt:
*
* A>cmdtest [arg1 ... arg10]
*
* The information in brackets is optional. Up to 10 arguments may be
* typed on the command line. The program responds by listing the
* arguments on separate lines. For example, if you enter
*
* A>cmdtest hello world
*
* The program responds with
*
* ArgV[1]= hello
* ArgV[2]= world
*
*)
MODULE CmdTest;
FROM CmdEnv IMPORT
ArgC, ArgV;
FROM InOut IMPORT
WriteString, WriteLn, WriteCard;
VAR
i : CARDINAL;
BEGIN
IF ArgC = 0 THEN
WriteString("No Arguments on Command Line");
WriteLn;
ELSE
FOR i := 1 TO ArgC DO
WriteString("ArgV[");
WriteCard(i, 2);
WriteString("]= ");
WriteString(ArgV[i]^);
WriteLn;
END;
END;
END CmdTest.
================ CUT HERE ====================================================
(*
* Title: Environment Test (EnvTest)
* Author: Gregory Elder
* Last Update: November 16, 1986
* Compiler: Logitech Modula-2/86 Version 2
* Description: Provides a test of the GetEnv procedure from the CmdEnv
* module. Prompts user for an environment variable then calls GetEnv
* to search the environment for that variable. If the variable is found,
* its value is displayed to the user. Type CONTROL-C to abort the program.
* Test the program with the variables COMSPEC and PATH.
*
*)
MODULE EnvTest;
FROM CmdEnv IMPORT
GetEnv;
FROM InOut IMPORT
WriteString, WriteLn, ReadString;
VAR
str1, str2 : ARRAY[0..79] OF CHAR;
BEGIN
str1[0] := 'A';
WHILE str1[0] # 0C DO
WriteString("Enter environment variable: ");
ReadString(str1);
WriteLn;
IF str1[0] # 0C THEN
GetEnv(str1, str2);
WriteString(str1);
IF str2[0] # 0C THEN
WriteString("= ");
WriteString(str2);
ELSE
WriteString(" Not Found.");
END;
WriteLn;
END;
END;
END EnvTest.
------