1 (* OptLib.mod allows users to manipulate Argv/Argc.
3 Copyright (C) 2019-2023 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 ;
31 FROM DynamicStrings IMPORT String ;
33 IMPORT DynamicStrings ;
37 Option = POINTER TO RECORD
48 InitOption - constructor for Option.
51 PROCEDURE InitOption (argc: INTEGER; argv: ADDRESS) : Option ;
64 newOption - returns an option
67 PROCEDURE newOption () : Option ;
76 freeList := freeList^.next
83 KillOption - deconstructor for Option.
86 PROCEDURE KillOption (o: Option) : Option ;
95 Min - returns the lowest value of a and b.
98 PROCEDURE Min (a, b: INTEGER) : INTEGER ;
110 dupArgv - return an array which is a duplicate as defined
114 PROCEDURE dupArgv (argc: INTEGER; argv: ADDRESS) : ADDRESS ;
118 ALLOCATE (nargv, VAL (CARDINAL, argc) * SIZE (ADDRESS)) ;
119 nargv := memcpy (nargv, argv, VAL (CARDINAL, argc) * SIZE (ADDRESS)) ;
125 Dup - duplicate the option array inside, o.
126 Notice that this does not duplicate all the contents
128 Shallow copy of the top level indices.
131 PROCEDURE Dup (o: Option) : Option ;
137 n^.argv := dupArgv (o^.argc, o^.argv) ;
144 Slice - return a new option which has elements [low:high] from the
148 PROCEDURE Slice (o: Option; low, high: INTEGER) : Option ;
161 high := o^.argc + high
163 high := Min (o^.argc, high)
165 n^.argc := high-low+1 ;
167 INC (p, VAL (INTEGER, SIZE (ADDRESS)) * low) ;
168 ALLOCATE (a, VAL (INTEGER, SIZE (ADDRESS)) * n^.argc) ;
169 n^.argv := memcpy (a, p, VAL (INTEGER, SIZE (ADDRESS)) * n^.argc) ;
176 IndexStrCmp - returns the index in the argv array which matches
177 string, s. -1 is returned if the string is not found.
180 PROCEDURE IndexStrCmp (o: Option; s: String) : INTEGER ;
183 p : POINTER TO POINTER TO CHAR ;
189 optString := DynamicStrings.InitStringCharStar (p^) ;
190 IF DynamicStrings.Equal (s, optString)
192 optString := DynamicStrings.KillString (optString) ;
195 optString := DynamicStrings.KillString (optString) ;
196 INC (p, SIZE (ADDRESS)) ;
204 IndexStrNCmp - returns the index in the argv array where the first
205 characters are matched by string, s.
206 -1 is returned if the string is not found.
209 PROCEDURE IndexStrNCmp (o: Option; s: String) : INTEGER ;
213 p : POINTER TO POINTER TO CHAR ;
218 len := DynamicStrings.Length (s) ;
220 optString := DynamicStrings.InitStringCharStar (p^) ;
221 IF DynamicStrings.Length (optString) >= len
223 optString := DynamicStrings.Slice (DynamicStrings.Mark (optString), 0, len) ;
224 IF DynamicStrings.Equal (s, optString)
226 optString := DynamicStrings.KillString (optString) ;
230 optString := DynamicStrings.KillString (optString) ;
231 INC (p, SIZE (ADDRESS)) ;
239 ConCat - returns the concatenation of a and b.
242 PROCEDURE ConCat (a, b: Option) : Option ;
246 result := newOption () ;
247 result^.argc := a^.argc + b^.argc ;
248 ALLOCATE (result^.argv, result^.argc * VAL (INTEGER, SIZE (ADDRESS))) ;
249 result^.argv := memcpy (result^.argv, a^.argv, a^.argc * VAL (INTEGER, SIZE (ADDRESS))) ;
250 result^.argv := memcpy (result^.argv + VAL (ADDRESS, a^.argc * VAL (INTEGER, SIZE (ADDRESS))),
251 b^.argv, b^.argc * VAL (INTEGER, SIZE (ADDRESS))) ;
252 result^.next := NIL ;
258 GetArgv - return the argv component of option.
261 PROCEDURE GetArgv (o: Option) : ADDRESS ;
268 GetArgc - return the argc component of option.
271 PROCEDURE GetArgc (o: Option) : INTEGER ;