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. ------