| (* CmdArgs.mod provides procedures to retrieve arguments from strings. |
| |
| Copyright (C) 2001-2025 Free Software Foundation, Inc. |
| Contributed by Gaius Mulley <gaius.mulley@southwales.ac.uk>. |
| |
| This file is part of GNU Modula-2. |
| |
| GNU Modula-2 is free software; you can redistribute it and/or modify |
| it under the terms of the GNU General Public License as published by |
| the Free Software Foundation; either version 3, or (at your option) |
| any later version. |
| |
| GNU Modula-2 is distributed in the hope that it will be useful, but |
| WITHOUT ANY WARRANTY; without even the implied warranty of |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| General Public License for more details. |
| |
| Under Section 7 of GPL version 3, you are granted additional |
| permissions described in the GCC Runtime Library Exception, version |
| 3.1, as published by the Free Software Foundation. |
| |
| You should have received a copy of the GNU General Public License and |
| a copy of the GCC Runtime Library Exception along with this program; |
| see the files COPYING3 and COPYING.RUNTIME respectively. If not, see |
| <http://www.gnu.org/licenses/>. *) |
| |
| IMPLEMENTATION MODULE CmdArgs ; |
| |
| FROM ASCII IMPORT cr, nul ; |
| FROM StrLib IMPORT StrLen ; |
| |
| CONST |
| esc = '\' ; |
| space = ' ' ; |
| squote = "'" ; |
| dquote = '"' ; |
| tab = ' ' ; |
| |
| |
| (* |
| GetArg - takes a command line and attempts to extract argument, n, |
| from CmdLine. The resulting argument is placed into, a. |
| The result of the operation is returned. |
| *) |
| |
| PROCEDURE GetArg (CmdLine: ARRAY OF CHAR ; |
| n: CARDINAL; VAR Argi: ARRAY OF CHAR) : BOOLEAN ; |
| VAR |
| Index, |
| i : CARDINAL ; |
| Another: BOOLEAN ; |
| BEGIN |
| Index := 0 ; |
| (* Continually retrieve an argument until we get the n th argument. *) |
| i := 0 ; |
| REPEAT |
| Another := GetNextArg(CmdLine, Index, Argi) ; |
| INC(i) ; |
| UNTIL (i>n) OR (NOT Another) ; |
| RETURN( i>n ) |
| END GetArg ; |
| |
| |
| (* |
| GetNextArg - Returns true if another argument may be found. |
| The argument is taken from CmdLine at position Index, |
| Arg is filled with the found argument. |
| *) |
| |
| PROCEDURE GetNextArg (CmdLine: ARRAY OF CHAR; VAR CmdIndex: CARDINAL; |
| VAR Arg: ARRAY OF CHAR) : BOOLEAN ; |
| VAR |
| ArgIndex: CARDINAL ; (* Index into Arg *) |
| HighA, |
| HighC: CARDINAL ; |
| BEGIN |
| HighA := HIGH(Arg) ; |
| HighC := StrLen(CmdLine) ; |
| ArgIndex := 0 ; |
| (* Skip spaces *) |
| WHILE (CmdIndex<HighC) AND Space(CmdLine[CmdIndex]) DO |
| INC(CmdIndex) |
| END ; |
| IF CmdIndex<HighC |
| THEN |
| IF SingleQuote(CmdLine[CmdIndex]) |
| THEN |
| (* Skip over the single quote *) |
| INC(CmdIndex) ; |
| CopyUntil(CmdLine, CmdIndex, HighC, Arg, ArgIndex, HighA, squote) ; |
| INC(CmdIndex) |
| ELSIF DoubleQuote(CmdLine[CmdIndex]) |
| THEN |
| (* Skip over the double quote *) |
| INC(CmdIndex) ; |
| CopyUntil(CmdLine, CmdIndex, HighC, Arg, ArgIndex, HighA, dquote) ; |
| INC(CmdIndex) |
| ELSE |
| CopyUntilSpace(CmdLine, CmdIndex, HighC, Arg, ArgIndex, HighA) |
| END |
| END ; |
| (* Skip spaces *) |
| WHILE (CmdIndex<HighC) AND Space(CmdLine[CmdIndex]) DO |
| INC(CmdIndex) |
| END ; |
| IF ArgIndex<HighA |
| THEN |
| Arg[ArgIndex] := nul |
| END ; |
| RETURN( (CmdIndex<HighC) ) |
| END GetNextArg ; |
| |
| |
| (* |
| CopyUntilSpace - copies characters until a Space character is found. |
| *) |
| |
| PROCEDURE CopyUntilSpace (From: ARRAY OF CHAR; |
| VAR FromIndex: CARDINAL; FromHigh: CARDINAL; |
| VAR To: ARRAY OF CHAR; |
| VAR ToIndex: CARDINAL; ToHigh: CARDINAL) ; |
| BEGIN |
| WHILE (FromIndex<FromHigh) AND (ToIndex<ToHigh) AND |
| (NOT Space(From[FromIndex])) DO |
| CopyChar(From, FromIndex, FromHigh, To, ToIndex, ToHigh) |
| END |
| END CopyUntilSpace ; |
| |
| |
| (* |
| CopyUntil - copies characters until the UntilChar is found. |
| *) |
| |
| PROCEDURE CopyUntil (From: ARRAY OF CHAR; |
| VAR FromIndex: CARDINAL; FromHigh: CARDINAL; |
| VAR To: ARRAY OF CHAR; |
| VAR ToIndex: CARDINAL; ToHigh: CARDINAL; |
| UntilChar: CHAR) ; |
| BEGIN |
| WHILE (FromIndex<FromHigh) AND (ToIndex<ToHigh) AND |
| (From[FromIndex]#UntilChar) DO |
| CopyChar(From, FromIndex, FromHigh, To, ToIndex, ToHigh) |
| END |
| END CopyUntil ; |
| |
| |
| (* |
| CopyChar - copies a character from string From to string To and |
| takes into consideration escape characters. ie \x |
| Where x is any character. |
| *) |
| |
| PROCEDURE CopyChar (From: ARRAY OF CHAR; |
| VAR FromIndex: CARDINAL; FromHigh: CARDINAL; |
| VAR To: ARRAY OF CHAR; |
| VAR ToIndex: CARDINAL; ToHigh: CARDINAL) ; |
| BEGIN |
| IF (FromIndex<FromHigh) AND (ToIndex<ToHigh) |
| THEN |
| IF Escape(From[FromIndex]) |
| THEN |
| (* Skip over Escape Character *) |
| INC(FromIndex) |
| END ; |
| IF FromIndex<FromHigh |
| THEN |
| (* Copy Normal Character *) |
| To[ToIndex] := From[FromIndex] ; |
| INC(ToIndex) ; |
| INC(FromIndex) |
| END |
| END |
| END CopyChar ; |
| |
| |
| (* |
| Narg - returns the number of arguments available from |
| command line, CmdLine. |
| *) |
| |
| PROCEDURE Narg (CmdLine: ARRAY OF CHAR) : CARDINAL ; |
| VAR |
| a : ARRAY [0..1000] OF CHAR ; |
| ArgNo: CARDINAL ; |
| BEGIN |
| ArgNo := 0 ; |
| WHILE GetArg(CmdLine, ArgNo, a) DO |
| INC( ArgNo ) |
| END ; |
| (* |
| IF ArgNo>0 |
| THEN |
| DEC(ArgNo) |
| END ; |
| *) |
| RETURN( ArgNo ) |
| END Narg ; |
| |
| |
| PROCEDURE Escape (ch: CHAR) : BOOLEAN ; |
| BEGIN |
| RETURN( ch=esc ) |
| END Escape ; |
| |
| |
| PROCEDURE Space (ch: CHAR) : BOOLEAN ; |
| BEGIN |
| RETURN( (ch=space) OR (ch=tab) ) |
| END Space ; |
| |
| |
| PROCEDURE DoubleQuote (ch: CHAR) : BOOLEAN ; |
| BEGIN |
| RETURN( ch=dquote ) |
| END DoubleQuote ; |
| |
| |
| PROCEDURE SingleQuote (ch: CHAR) : BOOLEAN ; |
| BEGIN |
| RETURN( ch=squote ) |
| END SingleQuote ; |
| |
| |
| END CmdArgs. |