1 (* GetOpt.mod allows users to manage long options to getopt.
3 Copyright (C) 2017-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 GetOpt
; (*!m2pim+gm2*)
29 FROM DynamicStrings
IMPORT string
, InitStringCharStar
;
30 FROM Storage
IMPORT ALLOCATE
, REALLOCATE
, DEALLOCATE
;
31 FROM MemUtils
IMPORT MemCopy
;
37 Crecord
= RECORD (* see man 3 getopt. *)
44 ptrToCrecord
= POINTER TO Crecord
;
46 LongOptions
= POINTER TO RECORD
54 GetOpt - call C getopt and fill in the parameters:
55 optarg, optind, opterr and optop.
58 PROCEDURE GetOpt (argc
: INTEGER; argv
: ADDRESS
; optstring
: String
;
60 VAR optind
, opterr
, optopt
: INTEGER) : CHAR ;
64 r
:= cgetopt.
getopt (argc
, argv
, string (optstring
)) ;
65 optarg
:= InitStringCharStar (cgetopt.optarg
) ;
66 opterr
:= cgetopt.opterr
;
67 optopt
:= cgetopt.optopt
;
73 InitLongOptions - creates and returns a LongOptions empty array.
76 PROCEDURE InitLongOptions () : LongOptions
;
91 AddLongOption - appends long option {name, has_arg, flag, val} to the
92 array of options and new long options array is returned.
93 The old array, lo, should no longer be used.
96 The meanings of the different fields are:
98 name is the name of the long option.
101 is: no_argument (or 0) if the option does not take an argument; required_argument
102 (or 1) if the option requires an argument; or optional_argument (or 2) if the
103 option takes an optional argument.
105 flag specifies how results are returned for a long option. If flag is NULL, then
106 getopt_long() returns val. (For example, the calling program may set val to the
107 equivalent short option character.) Otherwise, getopt_long() returns 0, and flag
108 points to a variable which is set to val if the option is found, but left unchanged
109 if the option is not found.
111 val is the value to return, or to load into the variable pointed to by flag.
113 The last element of the array has to be filled with zeros.
116 PROCEDURE AddLongOption (lo
: LongOptions
;
117 name
: String
; has_arg
: INTEGER;
118 flag
: PtrToInteger
; val
: INTEGER) : LongOptions
;
121 entry
: ptrToCrecord
;
127 lo^.size
:= SIZE (Crecord
) ;
132 lo^.size
:= lo^.len
* SIZE (Crecord
) ;
133 REALLOCATE (lo^.cptr
, lo^.size
) ;
140 INC (entry
, SIZE (Crecord
) * lo^.len
-1)
142 MemCopy (old
, lo^.len
-1, lo^.cptr
) ;
144 INC (entry
, SIZE (Crecord
) * lo^.len
-1)
147 fillIn (entry
, name
, has_arg
, flag
, val
) ;
156 PROCEDURE fillIn (entry
: ptrToCrecord
;
157 name
: String
; has_arg
: INTEGER; flag
: PtrToInteger
; val
: INTEGER) ;
161 entry^.name
:= name
;
162 entry^.has_arg
:= has_arg
;
163 entry^.flag
:= flag
;
170 KillLongOptions - returns NIL and also frees up memory associated with, lo.
173 PROCEDURE KillLongOptions (lo
: LongOptions
) : LongOptions
;
175 DEALLOCATE (lo^.cptr
, lo^.size
) ;
178 END KillLongOptions
;
182 GetOptLong - works like GetOpt but will accept long options (using two dashes).
183 If the program only accepts long options then optstring should be
184 an empty string, not NIL.
187 PROCEDURE GetOptLong (argc
: INTEGER; argv
: ADDRESS
; optstring
: String
;
188 longopts
: LongOptions
; VAR longindex
: INTEGER) : INTEGER ;
192 r
:= cgetopt.
getopt_long (argc
, argv
, string (optstring
), longopts^.cptr
, longindex
) ;
198 GetOptLongOnly - works like GetOptLong except that a single dash can be used
202 PROCEDURE GetOptLongOnly (argc
: INTEGER; argv
: ADDRESS
; optstring
: String
;
203 longopts
: LongOptions
; VAR longindex
: INTEGER) : INTEGER ;
207 r
:= cgetopt.
getopt_long_only (argc
, argv
, string (optstring
),
208 longopts^.cptr
, longindex
) ;