home *** CD-ROM | disk | FTP | other *** search
- (***************************************************************************
-
- $RCSfile: Args.mod $
- Description: C-style command-line argument parsing
-
- Created by: fjc (Frank Copeland)
- $Revision: 2.3 $
- $Author: fjc $
- $Date: 1994/08/08 16:10:27 $
-
- Copyright © 1994, Frank Copeland.
- This file is part of the Oberon-A Library.
- See Oberon-A.doc for conditions of use and distribution.
-
- ***************************************************************************)
-
- MODULE Args;
-
- (*
- ** $C- CaseChk $I- IndexChk $L- LongAdr $N- NilChk
- ** $P- PortableCode $R- RangeChk $S= StackChk $T- TypeChk
- ** $V- OvflChk $Z- ZeroVars
- *)
-
- IMPORT E := Exec, D := Dos, WB := Workbench, SYS := SYSTEM;
-
- TYPE
- ArgVPtr *= POINTER TO ARRAY OF E.STRPTR;
-
- VAR
-
- IsCLI * : BOOLEAN;
- (*
- * TRUE = program started from CLI, FALSE = program started from
- * Workbench
- *)
-
- argc * : LONGINT;
- (* Number of arguments passed by CLI *)
-
- argv * : ArgVPtr;
- (*
- * Array of argument strings passed by CLI.
- * argv [0] is always the name of the program.
- *)
-
- NumArgs * : LONGINT;
- (* Number of arguments passed by Workbench *)
-
- ArgList * : WB.WBArgumentsPtr;
- (* Array of WBArg structures passed by Workbench *)
-
- DosCmdLen * : LONGINT;
- (* Length of the command string passed by the CLI *)
-
- DosArgs * : E.STRPTR;
- (* The actual command string passed by the CLI; !! DO NOT CHANGE !! *)
-
- argCopy : E.STRPTR;
- (* Copy of the command string passed by the CLI *)
-
- startDir : D.FileLockPtr;
-
- (*------------------------------------*)
- PROCEDURE GetArgs ();
-
- VAR argLen : LONGINT; args : E.APTR;
-
- (*------------------------------------*)
- PROCEDURE CliArgs ();
-
- VAR index, index2 : LONGINT; nameLen : INTEGER;
- process : D.ProcessPtr; prCLI : D.CommandLineInterfacePtr;
-
- BEGIN (* CliArgs *)
- IsCLI := TRUE; NumArgs := 0; ArgList := NIL;
- argCopy := NIL; argc := 1; (* First arg is always program name *)
- DosCmdLen := argLen; DosArgs := args;
-
- IF DosCmdLen > 0 THEN
- (* Make a copy of the command string *)
- SYS.NEW (argCopy, SYS.STRLEN (DosArgs^) + 1);
- COPY (DosArgs^, argCopy^);
-
- (*
- * Scan the copy, planting a NUL at the end of each argument and
- * keeping a count of the arguments found;
- *)
- index := 0;
- LOOP
- IF index >= DosCmdLen THEN (* last argument found *) EXIT END;
- (* Kill any leading spaces *)
- WHILE argCopy [index] = " " DO
- argCopy [index] := 0X; INC (index)
- END;
- IF argCopy [index] = 22X THEN (* a quoted argument *)
- (* zap the quote *)
- argCopy [index] := 0X; INC (index);
- (* scan for the next quote *)
- WHILE argCopy [index] # 22X DO INC (index) END;
- (* zap it too *)
- argCopy [index] := 0X; INC (index);
- INC (argc)
- ELSIF argCopy [index] > " " THEN (* an unquoted argument *)
- (* scan for the end of the argument *)
- WHILE argCopy [index] > " " DO INC (index) END;
- (* mark it *)
- argCopy [index] := 0X; INC (index);
- INC (argc)
- ELSE
- (*
- * This is probably a dummy "\n" at the end of an empty command
- * line.
- *)
- argCopy [index] := 0X; INC (index)
- END; (* IF *)
- END; (* LOOP *)
-
- (* Allocate the argv array *)
- NEW (argv, argc + 1);
-
- IF argc > 0 THEN (* Fill argv with pointers to arguments *)
- index := 0; index2 := 1;
- WHILE index2 < argc DO
- WHILE argCopy [index] = 0X DO INC (index) END;
- argv [index2] := SYS.ADR (argCopy [index]);
- INC (index2);
- WHILE argCopy [index] # 0X DO INC (index) END
- END; (* WHILE *)
- END; (* IF *)
-
- (* Terminate it with a NIL *)
- argv [argc] := NIL
- ELSE
- (* Create a dummy entry for argv *)
- NEW (argv, 2);
- argv [1] := NIL
- END; (* ELSE *)
-
- (* Get the command name *)
- process := SYS.VAL (D.ProcessPtr, E.base.FindTask (NIL));
- nameLen := ORD (process.cli.commandName [0]);
- SYS.NEW (argv [0], nameLen + 1, {E.memClear});
- SYS.MOVE (SYS.ADR (process.cli.commandName [1]), argv [0], nameLen);
- (* argv [0, nameLen] := 0X; *)
-
- startDir := NIL
- END CliArgs;
-
- (*------------------------------------*)
- PROCEDURE WBArgs ();
-
- VAR wbMsg : WB.WBStartupPtr;
-
- BEGIN (* WBArgs *)
- IsCLI := FALSE; argc := 0; argv := NIL;
- DosCmdLen := 0; DosArgs := NIL; argCopy := NIL;
- wbMsg := args;
- NumArgs := wbMsg.numArgs; ArgList := wbMsg.argList;
- IF NumArgs = 1 THEN
- startDir := D.base.CurrentDir (ArgList [0].lock)
- ELSE
- startDir := D.base.CurrentDir (ArgList [1].lock)
- END
- END WBArgs;
-
- BEGIN (* GetArgs *)
- SYS.ARGLEN (argLen); SYS.ARGS (SYS.VAL (LONGINT, args));
- IF argLen >= 0 THEN CliArgs ()
- ELSE WBArgs ()
- END
- END GetArgs;
-
- (*------------------------------------*)
- PROCEDURE* Cleanup ();
-
- BEGIN (* Cleanup *)
- IF startDir # NIL THEN startDir := D.base.CurrentDir (startDir) END
- END Cleanup;
-
- BEGIN (* Args *)
- GetArgs ();
- SYS.SETCLEANUP (Cleanup)
- END Args.
-