1 (* OptLib.mod allows users to manipulate Argv/Argc.
3 Copyright (C) 2019-2024 Free Software Foundation, Inc.
4 Contributed by Gaius Mulley <gaius.mulley@southwales.ac.uk>.
6 This file is part of GNU Modula-2.
8 GNU Modula-2 is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3, or (at your option)
13 GNU Modula-2 is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
18 Under Section 7 of GPL version 3, you are granted additional
19 permissions described in the GCC Runtime Library Exception, version
20 3.1, as published by the Free Software Foundation.
22 You should have received a copy of the GNU General Public License and
23 a copy of the GCC Runtime Library Exception along with this program;
24 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
25 <http://www.gnu.org/licenses/>. *)
27 IMPLEMENTATION MODULE OptLib
;
29 FROM Storage
IMPORT ALLOCATE
, DEALLOCATE
;
30 FROM libc
IMPORT memcpy
;
32 IMPORT DynamicStrings
;
36 Option
= POINTER TO RECORD
47 InitOption - constructor for Option.
50 PROCEDURE InitOption (argc
: INTEGER; argv
: ADDRESS
) : Option
;
63 newOption - returns an option
66 PROCEDURE newOption () : Option
;
75 freeList
:= freeList^.next
82 KillOption - deconstructor for Option.
85 PROCEDURE KillOption (o
: Option
) : Option
;
94 Min - returns the lowest value of a and b.
97 PROCEDURE Min (a
, b
: INTEGER) : INTEGER ;
109 dupArgv - return an array which is a duplicate as defined
113 PROCEDURE dupArgv (argc
: INTEGER; argv
: ADDRESS
) : ADDRESS
;
117 ALLOCATE (nargv
, VAL (CARDINAL, argc
) * SIZE (ADDRESS
)) ;
118 nargv
:= memcpy (nargv
, argv
, VAL (CARDINAL, argc
) * SIZE (ADDRESS
)) ;
124 Dup - duplicate the option array inside, o.
125 Notice that this does not duplicate all the contents
127 Shallow copy of the top level indices.
130 PROCEDURE Dup (o
: Option
) : Option
;
136 n^.argv
:= dupArgv (o^.argc
, o^.argv
) ;
143 Slice - return a new option which has elements [low:high] from the
147 PROCEDURE Slice (o
: Option
; low
, high
: INTEGER) : Option
;
160 high
:= o^.argc
+ high
162 high
:= Min (o^.argc
, high
)
164 n^.argc
:= high
-low
+1 ;
166 INC (p
, VAL (INTEGER, SIZE (ADDRESS
)) * low
) ;
167 ALLOCATE (a
, VAL (INTEGER, SIZE (ADDRESS
)) * n^.argc
) ;
168 n^.argv
:= memcpy (a
, p
, VAL (INTEGER, SIZE (ADDRESS
)) * n^.argc
) ;
175 IndexStrCmp - returns the index in the argv array which matches
176 string, s. -1 is returned if the string is not found.
179 PROCEDURE IndexStrCmp (o
: Option
; s
: String
) : INTEGER ;
182 p
: POINTER TO POINTER TO CHAR ;
188 optString
:= DynamicStrings.
InitStringCharStar (p^
) ;
189 IF DynamicStrings.
Equal (s
, optString
)
191 optString
:= DynamicStrings.
KillString (optString
) ;
194 optString
:= DynamicStrings.
KillString (optString
) ;
195 INC (p
, SIZE (ADDRESS
)) ;
203 IndexStrNCmp - returns the index in the argv array where the first
204 characters are matched by string, s.
205 -1 is returned if the string is not found.
208 PROCEDURE IndexStrNCmp (o
: Option
; s
: String
) : INTEGER ;
212 p
: POINTER TO POINTER TO CHAR ;
217 len
:= DynamicStrings.
Length (s
) ;
219 optString
:= DynamicStrings.
InitStringCharStar (p^
) ;
220 IF DynamicStrings.
Length (optString
) >= len
222 optString
:= DynamicStrings.
Slice (DynamicStrings.
Mark (optString
), 0, len
) ;
223 IF DynamicStrings.
Equal (s
, optString
)
225 optString
:= DynamicStrings.
KillString (optString
) ;
229 optString
:= DynamicStrings.
KillString (optString
) ;
230 INC (p
, SIZE (ADDRESS
)) ;
238 ConCat - returns the concatenation of a and b.
241 PROCEDURE ConCat (a
, b
: Option
) : Option
;
245 result
:= newOption () ;
246 result^.argc
:= a^.argc
+ b^.argc
;
247 ALLOCATE (result^.argv
, result^.argc
* VAL (INTEGER, SIZE (ADDRESS
))) ;
248 result^.argv
:= memcpy (result^.argv
, a^.argv
, a^.argc
* VAL (INTEGER, SIZE (ADDRESS
))) ;
249 result^.argv
:= memcpy (result^.argv
+ VAL (ADDRESS
, a^.argc
* VAL (INTEGER, SIZE (ADDRESS
))),
250 b^.argv
, b^.argc
* VAL (INTEGER, SIZE (ADDRESS
))) ;
251 result^.next
:= NIL ;
257 GetArgv - return the argv component of option.
260 PROCEDURE GetArgv (o
: Option
) : ADDRESS
;
267 GetArgc - return the argc component of option.
270 PROCEDURE GetArgc (o
: Option
) : INTEGER ;