| /* do not edit automatically generated by mc from CmdArgs. */ |
| /* 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/>. */ |
| |
| #include "config.h" |
| #include "system.h" |
| #include <stdbool.h> |
| # if !defined (PROC_D) |
| # define PROC_D |
| typedef void (*PROC_t) (void); |
| typedef struct { PROC_t proc; } PROC; |
| # endif |
| |
| #define _CmdArgs_C |
| |
| #include "GCmdArgs.h" |
| # include "GASCII.h" |
| # include "GStrLib.h" |
| |
| # define esc '\\' |
| # define space ' ' |
| # define squote '\'' |
| # define dquote '"' |
| # define 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. |
| */ |
| |
| extern "C" bool CmdArgs_GetArg (const char *CmdLine_, unsigned int _CmdLine_high, unsigned int n, char *Argi, unsigned int _Argi_high); |
| |
| /* |
| Narg - returns the number of arguments available from |
| command line, CmdLine. |
| */ |
| |
| extern "C" unsigned int CmdArgs_Narg (const char *CmdLine_, unsigned int _CmdLine_high); |
| |
| /* |
| 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. |
| */ |
| |
| static bool GetNextArg (const char *CmdLine_, unsigned int _CmdLine_high, unsigned int *CmdIndex, char *Arg, unsigned int _Arg_high); |
| |
| /* |
| CopyUntilSpace - copies characters until a Space character is found. |
| */ |
| |
| static void CopyUntilSpace (const char *From_, unsigned int _From_high, unsigned int *FromIndex, unsigned int FromHigh, char *To, unsigned int _To_high, unsigned int *ToIndex, unsigned int ToHigh); |
| |
| /* |
| CopyUntil - copies characters until the UntilChar is found. |
| */ |
| |
| static void CopyUntil (const char *From_, unsigned int _From_high, unsigned int *FromIndex, unsigned int FromHigh, char *To, unsigned int _To_high, unsigned int *ToIndex, unsigned int ToHigh, char UntilChar); |
| |
| /* |
| CopyChar - copies a character from string From to string To and |
| takes into consideration escape characters. ie \x |
| Where x is any character. |
| */ |
| |
| static void CopyChar (const char *From_, unsigned int _From_high, unsigned int *FromIndex, unsigned int FromHigh, char *To, unsigned int _To_high, unsigned int *ToIndex, unsigned int ToHigh); |
| static bool Escape (char ch); |
| static bool Space (char ch); |
| static bool DoubleQuote (char ch); |
| static bool SingleQuote (char ch); |
| |
| |
| /* |
| 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. |
| */ |
| |
| static bool GetNextArg (const char *CmdLine_, unsigned int _CmdLine_high, unsigned int *CmdIndex, char *Arg, unsigned int _Arg_high) |
| { |
| unsigned int ArgIndex; |
| unsigned int HighA; |
| unsigned int HighC; |
| char CmdLine[_CmdLine_high+1]; |
| |
| /* make a local copy of each unbounded array. */ |
| memcpy (CmdLine, CmdLine_, _CmdLine_high+1); |
| |
| HighA = _Arg_high; /* Index into Arg */ |
| HighC = StrLib_StrLen ((const char *) CmdLine, _CmdLine_high); |
| ArgIndex = 0; |
| /* Skip spaces */ |
| while (((*CmdIndex) < HighC) && (Space (CmdLine[(*CmdIndex)]))) |
| { |
| (*CmdIndex) += 1; |
| } |
| if ((*CmdIndex) < HighC) |
| { |
| /* avoid gcc warning by using compound statement even if not strictly necessary. */ |
| if (SingleQuote (CmdLine[(*CmdIndex)])) |
| { |
| /* Skip over the single quote */ |
| (*CmdIndex) += 1; |
| CopyUntil ((const char *) CmdLine, _CmdLine_high, CmdIndex, HighC, (char *) Arg, _Arg_high, &ArgIndex, HighA, squote); |
| (*CmdIndex) += 1; |
| } |
| else if (DoubleQuote (CmdLine[(*CmdIndex)])) |
| { |
| /* avoid dangling else. */ |
| /* Skip over the double quote */ |
| (*CmdIndex) += 1; |
| CopyUntil ((const char *) CmdLine, _CmdLine_high, CmdIndex, HighC, (char *) Arg, _Arg_high, &ArgIndex, HighA, dquote); |
| (*CmdIndex) += 1; |
| } |
| else |
| { |
| /* avoid dangling else. */ |
| CopyUntilSpace ((const char *) CmdLine, _CmdLine_high, CmdIndex, HighC, (char *) Arg, _Arg_high, &ArgIndex, HighA); |
| } |
| } |
| /* Skip spaces */ |
| while (((*CmdIndex) < HighC) && (Space (CmdLine[(*CmdIndex)]))) |
| { |
| (*CmdIndex) += 1; |
| } |
| if (ArgIndex < HighA) |
| { |
| const_cast<char *>(Arg)[ArgIndex] = ASCII_nul; |
| } |
| return (*CmdIndex) < HighC; |
| /* static analysis guarentees a RETURN statement will be used before here. */ |
| __builtin_unreachable (); |
| } |
| |
| |
| /* |
| CopyUntilSpace - copies characters until a Space character is found. |
| */ |
| |
| static void CopyUntilSpace (const char *From_, unsigned int _From_high, unsigned int *FromIndex, unsigned int FromHigh, char *To, unsigned int _To_high, unsigned int *ToIndex, unsigned int ToHigh) |
| { |
| char From[_From_high+1]; |
| |
| /* make a local copy of each unbounded array. */ |
| memcpy (From, From_, _From_high+1); |
| |
| while ((((*FromIndex) < FromHigh) && ((*ToIndex) < ToHigh)) && (! (Space (From[(*FromIndex)])))) |
| { |
| CopyChar ((const char *) From, _From_high, FromIndex, FromHigh, (char *) To, _To_high, ToIndex, ToHigh); |
| } |
| } |
| |
| |
| /* |
| CopyUntil - copies characters until the UntilChar is found. |
| */ |
| |
| static void CopyUntil (const char *From_, unsigned int _From_high, unsigned int *FromIndex, unsigned int FromHigh, char *To, unsigned int _To_high, unsigned int *ToIndex, unsigned int ToHigh, char UntilChar) |
| { |
| char From[_From_high+1]; |
| |
| /* make a local copy of each unbounded array. */ |
| memcpy (From, From_, _From_high+1); |
| |
| while ((((*FromIndex) < FromHigh) && ((*ToIndex) < ToHigh)) && (From[(*FromIndex)] != UntilChar)) |
| { |
| CopyChar ((const char *) From, _From_high, FromIndex, FromHigh, (char *) To, _To_high, ToIndex, ToHigh); |
| } |
| } |
| |
| |
| /* |
| CopyChar - copies a character from string From to string To and |
| takes into consideration escape characters. ie \x |
| Where x is any character. |
| */ |
| |
| static void CopyChar (const char *From_, unsigned int _From_high, unsigned int *FromIndex, unsigned int FromHigh, char *To, unsigned int _To_high, unsigned int *ToIndex, unsigned int ToHigh) |
| { |
| char From[_From_high+1]; |
| |
| /* make a local copy of each unbounded array. */ |
| memcpy (From, From_, _From_high+1); |
| |
| if (((*FromIndex) < FromHigh) && ((*ToIndex) < ToHigh)) |
| { |
| if (Escape (From[(*FromIndex)])) |
| { |
| /* Skip over Escape Character */ |
| (*FromIndex) += 1; |
| } |
| if ((*FromIndex) < FromHigh) |
| { |
| /* Copy Normal Character */ |
| const_cast<char *>(To)[(*ToIndex)] = From[(*FromIndex)]; |
| (*ToIndex) += 1; |
| (*FromIndex) += 1; |
| } |
| } |
| } |
| |
| static bool Escape (char ch) |
| { |
| return ch == esc; |
| /* static analysis guarentees a RETURN statement will be used before here. */ |
| __builtin_unreachable (); |
| } |
| |
| static bool Space (char ch) |
| { |
| return (ch == space) || (ch == tab); |
| /* static analysis guarentees a RETURN statement will be used before here. */ |
| __builtin_unreachable (); |
| } |
| |
| static bool DoubleQuote (char ch) |
| { |
| return ch == dquote; |
| /* static analysis guarentees a RETURN statement will be used before here. */ |
| __builtin_unreachable (); |
| } |
| |
| static bool SingleQuote (char ch) |
| { |
| return ch == squote; |
| /* static analysis guarentees a RETURN statement will be used before here. */ |
| __builtin_unreachable (); |
| } |
| |
| |
| /* |
| 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. |
| */ |
| |
| extern "C" bool CmdArgs_GetArg (const char *CmdLine_, unsigned int _CmdLine_high, unsigned int n, char *Argi, unsigned int _Argi_high) |
| { |
| unsigned int Index; |
| unsigned int i; |
| bool Another; |
| char CmdLine[_CmdLine_high+1]; |
| |
| /* make a local copy of each unbounded array. */ |
| memcpy (CmdLine, CmdLine_, _CmdLine_high+1); |
| |
| Index = 0; |
| /* Continually retrieve an argument until we get the n th argument. */ |
| i = 0; |
| do { |
| Another = GetNextArg ((const char *) CmdLine, _CmdLine_high, &Index, (char *) Argi, _Argi_high); |
| i += 1; |
| } while (! ((i > n) || ! Another)); |
| return i > n; |
| /* static analysis guarentees a RETURN statement will be used before here. */ |
| __builtin_unreachable (); |
| } |
| |
| |
| /* |
| Narg - returns the number of arguments available from |
| command line, CmdLine. |
| */ |
| |
| extern "C" unsigned int CmdArgs_Narg (const char *CmdLine_, unsigned int _CmdLine_high) |
| { |
| typedef struct Narg__T1_a Narg__T1; |
| |
| struct Narg__T1_a { char array[1000+1]; }; |
| Narg__T1 a; |
| unsigned int ArgNo; |
| char CmdLine[_CmdLine_high+1]; |
| |
| /* make a local copy of each unbounded array. */ |
| memcpy (CmdLine, CmdLine_, _CmdLine_high+1); |
| |
| ArgNo = 0; |
| while (CmdArgs_GetArg ((const char *) CmdLine, _CmdLine_high, ArgNo, (char *) &a.array[0], 1000)) |
| { |
| ArgNo += 1; |
| } |
| /* |
| IF ArgNo>0 |
| THEN |
| DEC(ArgNo) |
| END ; |
| */ |
| return ArgNo; |
| /* static analysis guarentees a RETURN statement will be used before here. */ |
| __builtin_unreachable (); |
| } |
| |
| extern "C" void _M2_CmdArgs_init (__attribute__((unused)) int argc, __attribute__((unused)) char *argv[], __attribute__((unused)) char *envp[]) |
| { |
| } |
| |
| extern "C" void _M2_CmdArgs_fini (__attribute__((unused)) int argc, __attribute__((unused)) char *argv[], __attribute__((unused)) char *envp[]) |
| { |
| } |