source: trunk/LMDZ.PLUTO/libf/muphypluto/swift_argparse.F90 @ 3590

Last change on this file since 3590 was 3560, checked in by debatzbr, 5 weeks ago

Addition of the microphysics model in moments.

File size: 117.9 KB
Line 
1! Copyright (c) Jeremie Burgalat (2013-2022)
2! Contributor: Jeremie Burgalat (jeremie.burgalat@univ-reims.fr).
3!
4! This file is part of SWIFT
5!
6! Permission is hereby granted, free of charge, to any person obtaining a copy of
7! this software and associated documentation files (the "Software"), to deal in
8! the Software without restriction, including without limitation the rights to
9! use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
10! the Software, and to permit persons to whom the Software is furnished to do so,
11! subject to the following conditions:
12!
13! The above copyright notice and this permission notice shall be included in all
14! copies or substantial portions of the Software.
15!
16! THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17! IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
18! FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
19! COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
20! IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21! CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
23!! File:    swift_argparse.F90
24!! Summary: Command-line parser source file.
25!! Author:  J. Burgalat
26!! Date:    2013-2022
27
28#include "swift_defined.h"
29
30MODULE SWIFT_ARGPARSE
31  !> Command-line parsing module
32  !!
33  !! Here are described all the public members of argparse module.
34  !! For your own sanity, private methods that call Ancient Gods powers through
35  !! evil black magic rituals are not described here.
36  !!
37  !! If you only wish to have an overview of argparse usage, you'd better go
38  !! [here](|url|/page/swift/p01_argparse.html).
39
40  USE, INTRINSIC :: ISO_FORTRAN_ENV, ONLY : stdout=>OUTPUT_UNIT, stderr=>ERROR_UNIT
41  USE SWIFT_ERRORS
42  USE SWIFT_FSYSTEM, ONLY : fs_termsize
43  USE SWIFT_STRING_OP, getpar => format_paragraph, splitstr  => format_string
44  IMPLICIT NONE
45
46  PRIVATE
47
48  ! Public members and imported features
49  ! from errors: export everything (operator are exported latter)
50  PUBLIC :: noerror,error, error_to_string,aborting
51  ! from strings
52  PUBLIC :: st_slen, st_llen
53  PUBLIC :: stderr, stdout
54  ! argparse module
55  PUBLIC :: new_argparser,              &
56            argparser_clear,            &
57            argparser_add_option,       &
58            argparser_add_positionals,  &
59            argparser_throw_error,      &
60            argparser_parse,            &
61            argparser_help,             &
62            argparser_get_positional,   &
63            argparser_get_value,        &
64            argparser_reset_values,     &
65            argparser_found,            &
66            argparser_get_num_values,   &
67            argparser_found_positional, &
68            argparser_get_num_positional
69
70  PUBLIC :: OPERATOR(==), OPERATOR(/=), ASSIGNMENT(=)
71
72  ! ===========================
73  ! PARAMETERS (INTRISIC TYPES)
74  ! ===========================
75
76  INTEGER, PARAMETER, PUBLIC :: ap_string  = st_string
77    !! String value type identifier.
78  INTEGER, PARAMETER, PUBLIC :: ap_complex = st_complex
79    !! Complex value type identifier.
80  INTEGER, PARAMETER, PUBLIC :: ap_logical = st_logical
81    !! Logical value type identifier.
82  INTEGER, PARAMETER, PUBLIC :: ap_integer = st_integer
83    !! Integer value type identifier.
84  INTEGER, PARAMETER, PUBLIC :: ap_real = st_real
85    !! Real value type identifier.
86
87  !> List of all available actions
88
89  INTEGER, PARAMETER, PUBLIC :: ap_store   = 1
90    !! store action ID : Each time the option is seen, values are replaced.
91  INTEGER, PARAMETER, PUBLIC :: ap_append  = 2
92    !! append action ID : Each time the option is seen, values are appended.
93  INTEGER, PARAMETER, PUBLIC :: ap_count   = 3
94    !! count action ID : increase a counter each time the option is seen.
95  INTEGER, PARAMETER, PUBLIC :: ap_help    = 4
96    !! help action ID : help is requested !
97  INTEGER, PARAMETER, PUBLIC :: ap_version = 5
98    !! version action ID : version is requested !
99
100  !> List of all available actions
101  INTEGER, DIMENSION(5), PARAMETER, PRIVATE :: ap_actions = (/ap_store,  &
102                                                              ap_append, &
103                                                              ap_count,  &
104                                                              ap_help,   &
105                                                              ap_version/)
106  !> List of all recognized types by the parser
107  INTEGER, DIMENSION(5), PARAMETER, PRIVATE :: ap_types = (/ap_string,  &
108                                                            ap_logical, &
109                                                            ap_complex, &
110                                                            ap_integer, &
111                                                            ap_real/)
112  !> The unknown flag
113  !!
114  !! This flag is only intended to initialize flags. It is set by default during initialization
115  !! and quielty replaced by default flags, if user does not provide the relevant feature.
116  INTEGER, PARAMETER :: ap_undef = -1
117
118  !> Add an option to the parser
119  !!
120  !! ```
121  !! FUNCTION argparser_add_option(this,dest,sflag,lflag,type,action,default,nrec,help,meta) RESULT(err)
122  !!          argparser_add_option(this,dest,flag,type,action,default,nrec,help,meta) RESULT(err)
123  !! ```
124  !!
125  !! The function defines a new argument based on input parameters, checks it and finally sets it
126  !! in the parser.
127  !!
128  !! In its first version both short (`sflag`) and long (`lflag`) options flags are mandatory. In its second
129  !! form, a single flag (`flag`) is expected: the method will automatically deduce if it belongs to short or
130  !! a long option flag based on the number of hyphens given.
131  !!
132  !! `type` value should be one of the following module constants (which are aliases from [[string_op(module)]]):
133  !!
134  !! - `ap_string` ([[string_op(module):st_string(variable)]])
135  !! - `ap_complex` ([[string_op(module):st_complex(variable)]])
136  !! - `ap_logical` ([[string_op(module):st_logical(variable)]])
137  !! - `ap_integer` ([[string_op(module):st_integer(variable)]])
138  !! - `ap_real` ([[string_op(module):st_real(variable)]])
139  !!
140  !! `action` value should be one of the following module constants:
141  !!
142  !! - [[argparse(module):ap_store(variable)]]
143  !! - [[argparse(module):ap_append(variable)]]
144  !! - [[argparse(module):ap_count(variable)]]
145  !! - [[argparse(module):ap_help(variable)]]
146  !!
147  !! `nrec` string can take the following forms:
148  !!
149  !! tag   | description
150  !! :---: | : -------------
151  !!  "?"  | zero or one argument's value
152  !!  "*"  | any number of arguments
153  !!  "+"  | one or more argument's value(s)
154  !!  "X"  | Exactly X values. Where X is the string representation of an integer (0 is accepted).
155  !!
156  !! On success, `noerror` is returned. Otherwise -9 error code is returned. Errors are only
157  !! produced by misuse of the function arguments. In such case, the program should be
158  !! stopped: note that such error should not occur in _released_ programs.
159  INTERFACE argparser_add_option
160    MODULE PROCEDURE ap_add_option_1, ap_add_option_2
161  END INTERFACE
162
163  !> Get positional argument value(s)
164  INTERFACE argparser_get_positional
165    MODULE PROCEDURE ap_get_positional_sc, ap_get_positional_ve
166  END INTERFACE
167
168  !> Get optional argument value(s)
169  !!
170  !! ```
171  !! FUNCTION argparser_get_value(this,name,output) RESULT(err)
172  !! ```
173  !!
174  !! This is the generic method that can be used to retrieve any kind of argument value(s) from the parser for a given
175  !! argument name (as defined by the `dest` argument of [[argparse(module):argparser_add_option(interface)]].
176  !! All the methods have the same dummy arguments only `output` dummy argument differs in type and shape.
177  !!
178  !! @note
179  !! For string vector, `output` is expected to be an allocatable vector of **assumed length**
180  !! strings (thus string length is left to user responsability).
181  !! A good compromise for strings length is to use the [[string_op(module):st_slen(variable)]]
182  !! parameter.
183  INTERFACE argparser_get_value
184    MODULE PROCEDURE ap_get_dv_sc, ap_get_rv_sc, ap_get_iv_sc, ap_get_lv_sc, &
185                     ap_get_cv_sc, ap_get_sv_sc, ap_get_dv_ve, ap_get_rv_ve, &
186                     ap_get_iv_ve, ap_get_lv_ve, ap_get_cv_ve, ap_get_sv_ve
187  END INTERFACE
188
189  !> Interface to [[argparse(module):argc(type)]] getters
190  !!
191  !! All the functions have the same prototype, only kind and type of arguments changed
192  !! from a function to the other.
193  INTERFACE argc_get_value
194    MODULE PROCEDURE ac_get_dv_sc, ac_get_rv_sc, ac_get_iv_sc, ac_get_lv_sc, &
195                     ac_get_cv_sc, ac_get_sv_sc, ac_get_dv_ve, ac_get_rv_ve, &
196                     ac_get_iv_ve, ac_get_lv_ve, ac_get_cv_ve, ac_get_sv_ve
197  END INTERFACE
198
199  !> argc equality operator
200  INTERFACE OPERATOR(==)
201    MODULE PROCEDURE ac_equals_arg
202  END INTERFACE
203
204  !> argc inequality operator
205  INTERFACE OPERATOR(/=)
206    MODULE PROCEDURE ac_differs_arg
207  END INTERFACE
208
209  !> argc assignment statement
210  INTERFACE ASSIGNMENT(=)
211    MODULE PROCEDURE ac_affect_arg
212    MODULE PROCEDURE ap_affect_parser
213  END INTERFACE
214
215  !> argc *destructors* interface
216  INTERFACE clear_argc
217    MODULE PROCEDURE ac_clear_arg_sc, ac_clear_arg_ve
218  END INTERFACE
219
220
221  TYPE, PRIVATE :: argc
222    !! Defines a command-line argument.
223    !!
224    !! An [[argparse(module):argc(type)]] object stores all information about a command-line
225    !! argument, that is:
226    !!
227    !! - its name
228    !! - its optional flags
229    !! - its type
230    !! - its action
231    !! - and finally its values
232    PRIVATE
233    INTEGER          :: ptype = ap_logical
234      !! Type flag (an integer from enum argparse::ap_types)
235    INTEGER          :: paction = ap_store
236      !! Action flag (an integer from enum argparse::ap_actions)
237    INTEGER          :: nrec = 0
238      !! Number of values
239    LOGICAL          :: fnd = .false.
240      !! A boolean flag set to `.true.` if argument has been found in the command-line.
241    TYPE(words)      :: values
242      !! Values of the argument
243    CHARACTER(len=2) :: sflag = "  "
244      !! Short flag option
245    TYPE(words)      :: meta
246      !! Meta variable name(s) of the argument
247#if HAVE_FTNDTSTR
248    CHARACTER(len=:), ALLOCATABLE :: default
249      !! Default flag
250    CHARACTER(len=:), ALLOCATABLE :: name
251      !! Name of the argument (needed to check and retrieve its value(s))
252    CHARACTER(len=:), ALLOCATABLE :: lflag
253      !! Long flag option (st_short_len max chars !)
254    CHARACTER(len=:), ALLOCATABLE :: help
255      !! Help about the argument
256#else
257    CHARACTER(len=st_slen) :: default = ""
258      !! Default flag
259    CHARACTER(len=st_slen) :: name
260      !! Name of the argument (needed to check and retrieve its value(s))
261    CHARACTER(len=st_slen) :: lflag = ""
262      !! Long flag option (st_short_len max chars !)
263    CHARACTER(len = 200)   :: help = ""
264      !! Help about the argument
265#endif
266  END TYPE argc
267
268
269  TYPE, PUBLIC :: argparser
270    !! Command-line parser
271    !!
272    !! This is the main object of the module. It stores definitions of CLI arguments and
273    !! their value(s) once the command-line have been parsed.
274    TYPE(argc), PRIVATE, ALLOCATABLE, DIMENSION(:) :: args
275      !! List of defined arguments
276    INTEGER, PRIVATE :: nargs = 0
277      !! Size of args
278    INTEGER, PRIVATE :: parsed = -1
279      !! Parsing control flag
280      !!
281      !! The parsing flag determines if the command line have been parsed :
282      !!
283      !!   - -1 : not parsed yet
284      !!   - 0  : unsuccessfully parsed
285      !!   - 1  : successfully parsed
286    TYPE(argc), PRIVATE :: posals
287      !! Positionals arguments (defined as a single argc object)
288    LOGICAL, PRIVATE :: have_posal = .false.
289      !! Positional control flag
290#if HAVE_FTNDTSTR
291    CHARACTER(len=:), PRIVATE, ALLOCATABLE :: usg
292      !! Program command usage
293    CHARACTER(len=:), PRIVATE, ALLOCATABLE :: descr
294      !! Program help description
295    CHARACTER(len=:), PRIVATE, ALLOCATABLE :: eplg
296      !! Program help epilog
297    CHARACTER(len=:), PRIVATE, ALLOCATABLE :: vers
298      !! Application version string
299#else
300    CHARACTER(len=st_llen), PRIVATE :: usg
301      !! Program command usage
302    CHARACTER(len=st_llen), PRIVATE :: descr
303      !! Program help description
304    CHARACTER(len=st_llen), PRIVATE :: eplg
305      !! Program help epilog
306    CHARACTER(len=st_llen), PRIVATE :: vers
307      !! Application version string
308#endif
309    INTEGER, PRIVATE :: mxhlpos = 20
310      !! Position of the short help for options
311    INTEGER, PRIVATE :: width = 0
312      !! Maximum width of the help
313    LOGICAL, PRIVATE :: init = .false.
314      !! Initialization control flag
315#if HAVE_FTNPROC
316
317    CONTAINS
318    PROCEDURE, PRIVATE :: ap_add_option_1
319    PROCEDURE, PRIVATE :: ap_add_option_2
320    PROCEDURE, PRIVATE :: ap_get_positional_sc
321    PROCEDURE, PRIVATE :: ap_get_positional_ve
322    PROCEDURE, PRIVATE :: ap_get_dv_sc
323    PROCEDURE, PRIVATE :: ap_get_rv_sc
324    PROCEDURE, PRIVATE :: ap_get_iv_sc
325    PROCEDURE, PRIVATE :: ap_get_lv_sc
326    PROCEDURE, PRIVATE :: ap_get_cv_sc
327    PROCEDURE, PRIVATE :: ap_get_sv_sc
328    PROCEDURE, PRIVATE :: ap_get_dv_ve
329    PROCEDURE, PRIVATE :: ap_get_rv_ve
330    PROCEDURE, PRIVATE :: ap_get_iv_ve
331    PROCEDURE, PRIVATE :: ap_get_lv_ve
332    PROCEDURE, PRIVATE :: ap_get_cv_ve
333    PROCEDURE, PRIVATE :: ap_get_sv_ve
334    PROCEDURE, PRIVATE :: ap_check_state
335    PROCEDURE, PUBLIC  :: throw_error        => argparser_throw_error
336      !! Throw an error and exit the program
337    PROCEDURE, PUBLIC  :: parse              => argparser_parse
338      !! Parse the command-line (or the given input string).
339    PROCEDURE, PUBLIC  :: help               => argparser_help
340      !! Compute and print help
341    PROCEDURE, PUBLIC  :: version            => argparser_version
342      !! print version string
343    PROCEDURE, PUBLIC  :: found              => argparser_found
344      !! Check if an optional argument has been found on the command-line
345    PROCEDURE, PUBLIC  :: get_num_values     => argparser_get_num_values
346      !! Get the actual number of values stored in an argument.
347    PROCEDURE, PUBLIC  :: found_positional   => argparser_found_positional
348      !! Check if positional argument(s) has been found on the command-line
349    PROCEDURE, PUBLIC  :: get_num_positional => argparser_get_num_positional
350      !! Get the actual number of values stored as positionals.
351    PROCEDURE, PUBLIC  :: add_positionals    => argparser_add_positionals
352      !! Add positionals definitions in the parser.
353    !> Add optional argument definition in the parser.
354    GENERIC, PUBLIC    :: add_option         => ap_add_option_1, &
355                                                ap_add_option_2
356    !> Get the values of the positionals stored in the parser.
357    GENERIC, PUBLIC    :: get_positional     => ap_get_positional_sc, &
358                                                ap_get_positional_ve
359    !> Get the value(s) of the given argument stored in the parser.
360    GENERIC, PUBLIC    :: get_value          => ap_get_dv_sc, &
361                                                ap_get_rv_sc, &
362                                                ap_get_iv_sc, &
363                                                ap_get_lv_sc, &
364                                                ap_get_cv_sc, &
365                                                ap_get_sv_sc, &
366                                                ap_get_dv_ve, &
367                                                ap_get_rv_ve, &
368                                                ap_get_iv_ve, &
369                                                ap_get_lv_ve, &
370                                                ap_get_cv_ve, &
371                                                ap_get_sv_ve
372#endif
373  END TYPE argparser
374
375  CONTAINS
376
377  ! argparser main methods (public)
378  ! -------------------------------
379
380  FUNCTION new_argparser(usg, dsc, epg, add_help, add_version, version_string,width, max_help_pos) RESULT(this)
381    !! Initialize an argparser object.
382    !!
383    !! The method initializes (properly) an [[argparse(module):argparser(type)]] object.
384    !! Even if all the arguments are optional, it is mandatory to **call** the method
385    !! before using an argparser object.
386    CHARACTER(len=*), INTENT(in), OPTIONAL :: usg
387      !! An optional string with the command line usage of the program. If it is not given
388      !! command-line usage is automatically built from informations set in the parser.
389    CHARACTER(len=*), INTENT(in), OPTIONAL :: dsc
390      !! An optional string with the short description of the program.
391    CHARACTER(len=*), INTENT(in), OPTIONAL :: epg
392      !! An optional string with the epilog of the program's help
393    LOGICAL, INTENT(in), OPTIONAL          :: add_help
394      !! An optional boolean flag with `.true.` to automatically set an option for program's help.
395      !! Note that, the option flags `-h` and `--help` are no more available in that case.
396    LOGICAL, INTENT(in), OPTIONAL          :: add_version
397      !! An optional boolean flag with `.true.` to automatically set an option for program's help.
398      !! Note that, the option flags `-V` and `--version` are no more available in that case.
399    CHARACTER(len=*), INTENT(in), OPTIONAL :: version_string
400      !! An optional string with the text to display if the *version* option is found on the
401      !! command line. The text is displayed without any format.
402    INTEGER, INTENT(in), OPTIONAL          :: width
403      !! An optional integer with the maximum width the help text.
404    INTEGER, INTENT(in), OPTIONAL          :: max_help_pos
405      !! An optional integer with the maximum position of the help string for each option of
406      !! the program when help is requested. Note that this value is just an indicator. The
407      !! helper computes the minimum position between this value and the maximum length of the
408      !! options flags.
409    TYPE(argparser) :: this
410      !! An initialized argparse object.
411    INTEGER     :: zh
412    TYPE(error) :: err
413    ! We always clear the parser
414    CALL argparser_clear(this)
415    ! Set keywords
416    IF (PRESENT(usg)) THEN ; this%usg=usg   ; ELSE ; this%usg=''   ; ENDIF
417    IF (PRESENT(dsc)) THEN ; this%descr=dsc ; ELSE ; this%descr='' ; ENDIF
418    IF (PRESENT(epg)) THEN ; this%eplg=epg  ; ELSE ; this%eplg=''  ; ENDIF
419    CALL fs_termsize(zh,this%width)
420    IF (PRESENT(width)) this%width = MAX(width,50)
421    IF(PRESENT(max_help_pos)) this%mxhlpos = MAX(5,max_help_pos)
422    this%init = .true. ! before adding option !!!
423    IF (PRESENT(add_help)) THEN
424      IF (add_help) &
425        err = argparser_add_option(this,'help',sflag='-h',lflag='--help', &
426                    action=ap_help, help="Print this help and quit")
427    ENDIF
428    IF (PRESENT(add_version)) THEN
429      IF (add_version) &
430        err = argparser_add_option(this,'version',sflag='-V',lflag='--version', &
431                    action=ap_version, help="Print the application version and quit")
432      this%vers = ''
433      if (PRESENT(version_string)) this%vers = TRIM(version_string)
434    ENDIF
435    RETURN
436  END FUNCTION new_argparser
437
438  SUBROUTINE argparser_clear(this)
439    !! Clear the parser
440    !! The subroutine is used as finalization subroutine of argparser type.
441    !! Once the method is called, the object is no more usable until it is
442    !! (re)initialized by calling argparse::new_argparser.
443    !! @note If **fccp** has not been built with support for finalization subroutine,
444    !! it should be called whenever the argparser object is no more used.
445    TYPE(argparser), INTENT(inout) :: this
446      !! An argparser object
447    IF (ALLOCATED(this%args)) THEN
448      CALL clear_argc(this%args)
449      DEALLOCATE(this%args)
450    ENDIF
451    ! maybe we should should set this%posals as allocatable
452    CALL clear_argc(this%posals)
453    this%nargs      = 0
454    this%parsed     = -1
455    this%have_posal = .false.
456    this%usg        = ''
457    this%descr      = ''
458    this%eplg       = ''
459    this%mxhlpos    = 20
460    this%width      = 0
461    this%init       = .false.
462  END SUBROUTINE argparser_clear
463
464  SUBROUTINE argparser_reset_values(this)
465    !! Reset all arguments values in the parser
466    !! The method only deletes arguments value(s) currently stored in the parser.
467    OBJECT(argparser), INTENT(inout) :: this
468      !! An argparser object reference
469    ! Check if list is empty
470    IF (this%nargs == 0) RETURN
471    CALL words_clear(this%args(:)%values)
472    CALL words_clear(this%posals%values)
473  END SUBROUTINE argparser_reset_values
474
475  FUNCTION argparser_add_positionals(this,nargs,meta,help) RESULT(err)
476    !! Add positional arguments definition to the parser.
477    !!
478    !! The method initializes the entry for positional arguments in the parser.
479    !! Positional arguments are always seen by the parser as strings and the
480    !! default associated action is 'store'.
481    OBJECT(argparser), INTENT(inout)                     :: this
482      !! An argparser object reference
483    CHARACTER(len=*), INTENT(in)                         :: nargs
484      !! A string with the expected number of specified values for the option
485    CHARACTER(len=*), INTENT(in), DIMENSION(:), OPTIONAL :: meta
486      !! A vector of strings with the the displayed value name(s) of the positionals in the help command
487    CHARACTER(len=*), INTENT(in), OPTIONAL               :: help
488      !! An optional string with a short description of the positional argument(s)
489    TYPE(error) :: err
490      !! Error object with the first error encountered in the process.
491    INTEGER                       :: ty,ac
492    CHARACTER(len=:), ALLOCATABLE :: sf,lf,de
493    err = noerror
494    IF (.NOT.this%init) THEN
495      err = error("argparse: parser not initialized yet",-1)
496      RETURN
497    ENDIF
498    IF (this%have_posal) THEN
499      err = error('argparse: positionals arguments already defined',-8)
500      RETURN
501    ELSE
502      this%posals%name = 'positional'
503      sf = '  ' ; lf = '' ; ty = ap_string ; ac = ap_store ; de = ''
504      IF (PRESENT(help)) THEN
505        this%posals%help = TRIM(help)
506      ELSE
507        this%posals%help = ''
508      ENDIF
509      IF (PRESENT(meta)) THEN
510        err = ac_check_and_set(this%posals,sf,lf,ty,ac,de,nargs,meta,.false.)
511      ELSE
512        err = ac_check_and_set(this%posals,sf,lf,ty,ac,de,nargs,check_flag=.false.)
513      ENDIF
514      IF (err /= noerror) THEN
515        RETURN
516      ENDIF
517      this%have_posal = this%posals%nrec /= 0
518    ENDIF
519    RETURN
520  END FUNCTION argparser_add_positionals
521
522  FUNCTION argparser_parse(this,cmd_line,auto) RESULT(err)
523    !! Parse the command line
524    !! The method parses either the command-line or the string `cmd_line`
525    !! given as optional argument and fills the parser's arguments.
526    !! @note
527    !! If `cmd_line` is provided it should not contains the name of the program or
528    !! the parsing process will certainly failed: program name will be seen as the
529    !! first positional argument and all tokens of the string will then be seen as
530    !! positional.
531    OBJECT(argparser), INTENT(inout)       :: this
532      !! An argparser object reference
533    CHARACTER(len=*), INTENT(in), OPTIONAL :: cmd_line
534      !! An optional string to parse that substitute for the actual command-line.
535    LOGICAL, INTENT(in), OPTIONAL          :: auto
536      !! An optional boolean flag with `.true.` to instruct the parser wether to perform
537      !! automatic actions or not when error occur during parsing. If `auto` is enabled,
538      !! then the parser dumps program's usage and stops the program on error.
539    TYPE(error) :: err
540      !! Error object with the first error encountered in the process.
541    CHARACTER(len=:), ALLOCATABLE :: cline,z
542    LOGICAL                       :: zauto
543    LOGICAL                       :: rhelp
544    LOGICAL                       :: rvers
545    INTEGER                       :: l
546    TYPE(words)                   :: cmd_tokens
547    err = noerror
548    IF (.NOT.this%init)  THEN
549      err = error("parser not initialized yet",-1) ; RETURN
550    ENDIF
551    rhelp = .false. ; rvers = .false.
552    zauto = .false. ; IF (PRESENT(auto)) zauto = auto
553    IF (PRESENT(cmd_line)) THEN
554      ALLOCATE(cline,source=cmd_line)
555    ELSE
556      CALL GET_COMMAND(length=l)
557      ALLOCATE(CHARACTER(len=l) :: z) ; CALL GET_COMMAND(z)
558      CALL GET_COMMAND_ARGUMENT(0,length=l)
559      IF (l >= LEN_TRIM(z)) THEN ; cline='' ; ELSE ; cline=z(l+1:LEN(z)) ; ENDIF
560      DEALLOCATE(z)
561    ENDIF
562    ! reset parsing status
563    this%parsed = -1
564    CALL argparser_reset_values(this)
565    DO
566      ! Do we have to launch the turbine ?
567      IF (LEN_TRIM(cline) == 0) THEN
568        IF (this%have_posal) err=error("Wrong number of arguments",-16)
569        EXIT ! ... No :)
570      ELSE
571        err = ap_split_cmd(this,cline,cmd_tokens,rhelp)
572        ! we only stops processing if :
573        !   - the internal error (string length) is raised
574        !   - help flag found AND auto has been set
575        IF (err /= noerror .OR. (rhelp.AND.zauto)) EXIT
576      ENDIF
577      CALL words_reset(cmd_tokens) ! not mandatory... at least theoretically
578      ! Parses the options
579      err = ap_parse_options(this,cmd_tokens,rhelp,rvers)
580      IF (err /= noerror) EXIT
581      ! exit loop if help or version is requested. Parser is not completely filled but we
582      ! expect someone to use the help or version actions...
583      IF (rhelp.OR.rvers) EXIT
584      ! Parses positionals
585      err = ap_parse_positionals(this,cmd_tokens)
586      EXIT ! A one iterated loop :)
587    ENDDO
588    IF (err /= 0) THEN
589      CALL argparser_reset_values(this)
590    ELSE
591      this%parsed = 1
592    ENDIF
593    IF (zauto) THEN
594      IF (rhelp) CALL argparser_help(this)
595      IF (rvers) CALL argparser_version(this)
596      IF (err /= 0) CALL argparser_throw_error(this,err,2)
597    ENDIF
598    RETURN
599  END FUNCTION argparser_parse
600
601  SUBROUTINE argparser_version(this)
602    !! Print version string and exit program
603    OBJECT(argparser), INTENT(inout) :: this
604      !! An argparser object reference
605    WRITE(stdout,'(a)') TRIM(this%vers)
606    CALL argparser_clear(this)
607    CALL EXIT(0)
608  END SUBROUTINE argparser_version
609
610  SUBROUTINE argparser_help(this)
611    !! Print help and exit program
612    OBJECT(argparser), INTENT(inout) :: this
613      !! An argparser object reference
614    CHARACTER(len=:), ALLOCATABLE :: helpme
615    !!!! WARNING we set no indication here !!!
616    IF (.NOT.this%init) RETURN
617    helpme = ap_gen_help(this)
618
619    WRITE(stdout,'(a)') helpme
620
621    CALL argparser_clear(this)
622    ! Finally we exit the program
623    CALL EXIT(0)
624  END SUBROUTINE argparser_help
625
626  SUBROUTINE argparser_throw_error(this,err,exit_id)
627    !! Dump error on standard error and exit
628    !!
629    !! The method performs the following actions:
630    !!
631    !! - Print the usage command of the program
632    !! - Dump the provided @p error message
633    !! - Call parser's clean-up subroutine (if a *cleaner* callback has been given during the
634    !!   parser's initialization, see [[argparse(module):new_argparser(function)]] documentation
635    !! - Stop the program
636    !!
637    !! The error message is always printed in standard error output.
638    !! @note
639    !! If errors::error::id is 0 the method does nothing.
640    OBJECT(argparser), INTENT(inout) :: this
641      !! An argparser object reference
642    TYPE(error), INTENT(in)          :: err
643      !! An error object with the error to print
644    INTEGER, INTENT(in), OPTIONAL    :: exit_id
645      !! An optional integer with the exit code (default to 2)
646    CHARACTER(len=:), ALLOCATABLE    :: pgn
647    TYPE(error) :: zerr
648    IF (err == 0) RETURN
649    zerr = error(err%msg,2)
650    IF (PRESENT(exit_id)) zerr%id=exit_id
651    CALL ap_format_usage(this)
652    WRITE(stderr,'(a)') TRIM(this%usg)//NEW_LINE('A')
653    ! clean the parser
654    CALL argparser_clear(this)
655    pgn = get_progname()
656    WRITE(stderr,'(a)') pgn//": error: "//TRIM(err%msg)
657    CALL EXIT(err%id)
658  END SUBROUTINE argparser_throw_error
659
660  FUNCTION argparser_found(this,argname) RESULT(found)
661    !! Check wether an argument has been found in the command-line.
662    !! @note
663    !! Keep in mind that arguments in the parser always have a default
664    !! value. This method is not intended to check if an argument has a value but
665    !! only if it has been seen on the command-line !
666    OBJECT(argparser), INTENT(in) :: this
667      !! An argparser object reference
668    CHARACTER(len=*), INTENT(in)  :: argname
669      !! Name of the argument to check
670    LOGICAL :: found
671      !! `.true.` if the option has been parsed, `.false.` otherwise
672    INTEGER  :: idx
673    idx = ap_get_arg_index(this,argname)
674    IF (idx == -1) THEN
675      found = .false.
676    ELSE
677      found = ac_found(this%args(idx))
678    ENDIF
679  END FUNCTION argparser_found
680
681  FUNCTION argparser_get_num_values(this,argname) RESULT(num)
682    !! Get the actual number of values stored in an argument.
683    OBJECT(argparser), INTENT(in) :: this
684      !! An argparser object reference
685    CHARACTER(len=*), INTENT(in)  :: argname
686      !! Name of the argument to check.
687    INTEGER :: num
688      !! The number of actual values stored in the argument
689    INTEGER  :: idx
690    idx = ap_get_arg_index(this,argname)
691    IF (idx == -1) THEN
692      num = 0
693    ELSE
694      num = words_length(this%args(idx)%values)
695    ENDIF
696  END FUNCTION argparser_get_num_values
697
698  FUNCTION argparser_found_positional(this) RESULT(ret)
699    !! Check if positional(s) has been found in the command line.
700    OBJECT(argparser), INTENT(in) :: this
701      !! An argparser object reference
702    LOGICAL :: ret
703    !! `.true.` if found, `.false.` otherwise
704    TYPE(error) :: err
705    ret = .false.
706    IF (this%have_posal) THEN
707      ret = this%posals%fnd
708    ENDIF
709  END FUNCTION argparser_found_positional
710
711  FUNCTION argparser_get_num_positional(this) RESULT(ret)
712    !! Get the actual number of positional argument values stored in the parser .
713    OBJECT(argparser), INTENT(in) :: this
714      !! An argparser object reference
715    INTEGER :: ret
716      !! The number of actual positionals arguments
717    ret = 0
718    IF (this%have_posal) THEN
719      ret = words_length(this%posals%values)
720    ENDIF
721  END FUNCTION argparser_get_num_positional
722
723  ! argparser private methods
724  ! -------------------------
725
726  FUNCTION ap_check_state(this) RESULT(err)
727    !! Check current parser state
728    !! The method returns an error based on the current parser's state:
729    !! - Parser is ready (0)
730    !! - parsing not done yet (-19)
731    !! - parsing (already) failed (-20)
732    !! - parser is **NOT** initialized (-1)
733    OBJECT(argparser), INTENT(in) :: this
734      !! An argparser object reference
735    TYPE(error) :: err
736      !! Error object with the *status* of the parser
737    err = noerror
738    IF (this%parsed == -1) THEN
739      err = error("argparse: Command-line not parsed (yet)",-19)
740    ELSE IF (this%parsed == 0) THEN
741      err = error("argparse: command-line parsing failed",-20)
742    ELSE IF (.NOT.this%init) THEN
743      err = error("argparse: parser not initialized yet",-1)
744    ENDIF
745    RETURN
746  END FUNCTION ap_check_state
747
748  SUBROUTINE ap_append_arg(this,arg)
749    !! Append an argument to the list of arguments.
750    TYPE(argparser), INTENT(inout) :: this
751      !! An argparser object reference
752    TYPE(argc), INTENT(in)         :: arg
753      !! An [[argparse(module):argc(type)]] object with the argument to add
754    INTEGER                               :: i
755    TYPE(argc), ALLOCATABLE, DIMENSION(:) :: tmp
756    TYPE(error) :: err
757    IF (.NOT.this%init)  THEN
758      err = error("parser not initialized yet",-1) ; RETURN
759    ENDIF
760    ! Empty list : we create it
761    IF (this%nargs == 0) THEN
762      ALLOCATE(this%args(1))
763      this%args(1) = arg
764      this%nargs = 1
765      RETURN
766    ENDIF
767    ! Adds a new argument to the vector of arguments
768    ! we will make a test with move_alloc but i'm not sure it does everything
769    ! the way we want (keep in mind that there is some pointer in argc members
770    ! !!!)
771    ALLOCATE(tmp(this%nargs))
772    DO i=1,this%nargs ; tmp(i) = this%args(i) ; ENDDO
773    CALL clear_argc(this%args)
774    DEALLOCATE(this%args)
775    this%nargs = this%nargs+1 ; ALLOCATE(this%args(this%nargs))
776    DO i=1,this%nargs-1 ; this%args(i) = tmp(i) ; ENDDO
777    CALL clear_argc(tmp)
778    DEALLOCATE(tmp)
779    this%args(i) = arg
780    RETURN
781  END SUBROUTINE ap_append_arg
782
783  FUNCTION ap_get_arg_index(this, name, sflag, lflag)  RESULT(idx)
784    !! Get an argument by name or option flag in the parser.
785    TYPE(argparser), INTENT(in), TARGET    :: this
786      !! An argparser object reference
787    CHARACTER(len=*), INTENT(in), OPTIONAL :: name
788      !! An optional string with the name of the argument
789    CHARACTER(len=*), INTENT(in), OPTIONAL :: lflag
790      !! An optional string with the long option flag of the argument
791    CHARACTER(len=2), INTENT(in), OPTIONAL :: sflag
792      !! An optional string with the short option flag of the argument
793    INTEGER :: idx
794      !! Index of the argument in the internal vector of argument or -1 if no argument is found.
795    INTEGER                       :: i,nn,nl,ns
796    CHARACTER(LEN=:), ALLOCATABLE :: lna, llf
797    CHARACTER(LEN=2)              :: lsf
798    idx = -1
799    IF (.NOT.this%init) RETURN
800    lna="" ; IF(PRESENT(name)) lna = name   ; nn = LEN_TRIM(lna)
801    lsf="" ; IF(PRESENT(sflag)) lsf = sflag ; ns = LEN_TRIM(lsf)
802    llf="" ; IF(PRESENT(lflag)) llf = lflag ; nl = LEN_TRIM(llf)
803    IF (nn == 0 .AND. ns == 0 .AND. nl == 0) RETURN
804    ! empty parser
805    IF (this%nargs == 0) RETURN
806    DO i=1, this%nargs
807      IF ((nn /= 0 .AND. TRIM(this%args(i)%name)  == TRIM(lna)) .OR. &
808          (ns /= 0 .AND. TRIM(this%args(i)%sflag) == TRIM(lsf)) .OR. &
809          (nl /= 0 .AND. TRIM(this%args(i)%lflag) == TRIM(llf))) THEN
810          idx = i ; RETURN
811      ENDIF
812    ENDDO
813    RETURN
814  END FUNCTION ap_get_arg_index
815
816
817  FUNCTION ap_add_option_1(this,dest,sflag,lflag,type,action,default,nrec,help,meta) RESULT(err)
818    !! Add an argument to the parser (interface #1)
819    !!
820    !! The function defines a new argument based on input parameters, checks it and finally sets it
821    !! in the parser. Both **short and long options flags** are mandatory input arguments of the function.
822    !!
823    !!  `type` value should be one of the following module constants (which are aliases from [[string_op(module)]]):
824    !!  - ap_string ([[string_op(module):st_string(variable)]])
825    !!  - ap_complex ([[string_op(module):st_complex(variable)]])
826    !!  - ap_logical ([[string_op(module):st_logical(variable)]])
827    !!  - ap_integer ([[string_op(module):st_integer(variable)]])
828    !!  - ap_real ([[string_op(module):st_real(variable)]])
829    !!
830    !!  `action` value should be one of the following module constants:
831    !!  - [[argparse(module):ap_store(variable)]]
832    !!  - [[argparse(module):ap_append(variable)]]
833    !!  - [[argparse(module):ap_count(variable)]]
834    !!  - [[argparse(module):ap_help(variable)]]
835    !!
836    !!  `nrec` string can take the following forms:
837    !!  tag | description
838    !!  :-: | : -------------
839    !!   ?  | zero or one argument's value
840    !!   *  | any number of arguments
841    !!   +  | one or more argument's value(s)
842    !!   X  | Exactly X values. Where X is the string representation of an integer (0 is accepted).
843    !!
844    !! See also ap_add_option_2 documentation.
845    OBJECT(argparser), INTENT(inout)                     :: this
846      !! An argparser object reference
847    CHARACTER(len=*), INTENT(in)                         :: dest
848      !! A string with the name of the argument
849    CHARACTER(len=2), INTENT(in)                         :: sflag
850      !! A two characters string with the short option flag of the argument
851    CHARACTER(len=*), INTENT(in)                         :: lflag
852      !! A string (3 characters minimum) with the long option flag of the argument
853    INTEGER, INTENT(in), OPTIONAL                        :: type
854      !! An integer with the type of the argument
855    INTEGER, INTENT(in), OPTIONAL                        :: action
856      !! An integer with the action of the argument
857    CHARACTER(len=*), INTENT(in), OPTIONAL               :: default
858      !! A string with the default value of the argument if not provided in the CLI
859    CHARACTER(len=*), INTENT(in), OPTIONAL               :: nrec
860      !! A string with the expected number of specified values for the argument in the CLI.
861    CHARACTER(len=*), INTENT(in), OPTIONAL               :: help
862      !! A string with a short description of the argument
863    CHARACTER(len=*), DIMENSION(:), INTENT(in), OPTIONAL :: meta
864      !! A vector of strings with the displayed value's name(s) of the argument in the help command
865    TYPE(error) :: err
866      !! Error object with the first error encountered in the process.
867    CHARACTER(len=:), ALLOCATABLE :: de,na,he
868    INTEGER                       :: ty,ac
869    TYPE(argc)                    :: arg
870    err = noerror
871    he = ""       ; IF (PRESENT(help))    he = TRIM(help)
872    na = ""       ; IF (PRESENT(nrec))    na = TRIM(nrec)
873    ty = ap_undef ; IF (PRESENT(type))    ty = type
874    ac = ap_undef ; IF (PRESENT(action))  ac = action
875    de =''        ; IF (PRESENT(default)) de = TRIM(default)
876    IF (.NOT.this%init)  THEN
877      err = error("argparse: parser not initialized yet",-1)
878      RETURN
879    ENDIF
880    IF (LEN_TRIM(dest) == 0) THEN
881      err = error("argparse: Invalid argument (empty dest)",-2)
882      RETURN
883    ENDIF
884    arg%name = TRIM(dest) ; arg%help = TRIM(he)
885    IF (PRESENT(meta)) THEN
886      err = ac_check_and_set(arg,sflag,lflag,ty,ac,de,na,meta)
887    ELSE
888      err = ac_check_and_set(arg,sflag,lflag,ty,ac,de,na)
889    ENDIF
890    IF (err /= noerror) RETURN
891    err = ap_check_in_parser(this,arg)
892    IF (err /= noerror) RETURN
893    CALL ap_append_arg(this,arg)
894    CALL clear_argc(arg)
895  END FUNCTION ap_add_option_1
896
897  FUNCTION ap_add_option_2(this,dest,flag,type,action,default,nrec,help,meta) RESULT(err)
898    !! Add an argument to the parser (interface #2)
899    !!
900    !! The function is a wrapper to ap_add_option_1. In this version,
901    !! only one option flag is required. The method only checks for the (trimmed) length of **flag** in
902    !! order to choose wether it is a **short** or **long** option flag. Then the function simply calls
903    !! ap_add_option_1 to set the argument.
904    !!
905    !! Other dummy arguments have the same meaning as in ap_add_option_1.
906    OBJECT(argparser), INTENT(inout)                     :: this
907      !! An argparser object reference
908    CHARACTER(len=*), INTENT(in)                         :: dest
909      !! A string with the name of the argument
910    CHARACTER(len=*), INTENT(in)                         :: flag
911      !! A string with either the short or long option flag
912    INTEGER, INTENT(in), OPTIONAL                        :: type
913      !! A string with the type of the argument
914    INTEGER, INTENT(in), OPTIONAL                        :: action
915      !! A string with the action of the argument
916    CHARACTER(len=*), INTENT(in), OPTIONAL               :: default
917      !! A string with the default value of the argument if not provided in the CLI
918    CHARACTER(len=*), INTENT(in), OPTIONAL               :: nrec
919      !! A string with the expected number of specified values for the argument in the CLI.
920    CHARACTER(len=*), INTENT(in), OPTIONAL               :: help
921      !! A string with a short description of the argument
922    CHARACTER(len=*), DIMENSION(:), INTENT(in), OPTIONAL :: meta
923      !! A vector of strings with the displayed value's name(s) of the argument in the help command
924    TYPE(error) :: err
925      !! Error object with the first error encountered in the process.
926    CHARACTER(len=:), ALLOCATABLE :: sf,lf,de,na,he
927    INTEGER                       :: ty,ac
928    err = noerror
929    sf = '  ' ; lf = ''
930    IF (LEN_TRIM(flag) == 2) THEN
931      sf = TRIM(flag)
932    ELSE
933      lf = TRIM(flag)
934    ENDIF
935    he = ""       ; IF (PRESENT(help))    he = TRIM(help)
936    na = ""       ; IF (PRESENT(nrec))    na = TRIM(nrec)
937    ty = ap_undef ; IF (PRESENT(type))    ty = type
938    ac = ap_undef ; IF (PRESENT(action))  ac = action
939    de = ''       ; IF (PRESENT(default)) de = TRIM(default)
940    ! Calling "true" function
941    IF (PRESENT(meta)) THEN
942      err = ap_add_option_1(this,dest,sf,lf,ty,ac,de,na,he,meta)
943    ELSE
944      err = ap_add_option_1(this,dest,sf,lf,ty,ac,de,na,he)
945    ENDIF
946    RETURN
947  END FUNCTION ap_add_option_2
948
949  FUNCTION ap_check_in_parser(this,arg) RESULT(err)
950    !! Check if an argument is already set in the parser
951    !! An argument is assumed to be already set in the parser if either its name,
952    !! short or long option flag is already defined (in the parser).
953    OBJECT(argparser), INTENT(in) :: this
954      !! An argparser object reference
955    TYPE(argc), INTENT(in)        :: arg
956      !! An argc object to check
957    TYPE(error) :: err
958      !! Error object with -8 id if object is already set, no error otherwise.
959    INTEGER :: i
960    err = noerror
961    IF (this%nargs == 0 ) RETURN
962    DO i=1,this%nargs
963    ! note : we could have use the == operator  but we want to get an specific
964    ! error message)
965      IF (TRIM(this%args(i)%name) == TRIM(arg%name)) THEN
966        err = error("argparse: argument '"//TRIM(arg%name)//"' already defined",-8) ; RETURN
967      ENDIF
968      IF (LEN_TRIM(this%args(i)%sflag) > 0 .AND. &
969          TRIM(this%args(i)%sflag) == TRIM(arg%sflag)) THEN
970        err = error("argparse: flag '"//TRIM(arg%sflag)//"' already defined",-8) ; RETURN
971      ENDIF
972      IF (LEN_TRIM(this%args(i)%lflag) > 0 .AND. &
973          TRIM(this%args(i)%lflag) == TRIM(arg%lflag)) THEN
974        err = error("argparse: flag '"//TRIM(arg%lflag)//"' already defined",-8) ; RETURN
975      ENDIF
976    ENDDO
977    RETURN
978  END FUNCTION ap_check_in_parser
979
980  FUNCTION ap_parse_options(this,cmd,help_req,vers_req) RESULT(err)
981    !! Parse options of the internal command line
982    !! This (internal) function manages the parsing of the command line options.
983    OBJECT(argparser), INTENT(inout), TARGET :: this
984      !! An argparser object reference
985    TYPE(words), INTENT(inout)               :: cmd
986      !! A [[string_op(module):words(type)]] object with the command-line to parse
987    LOGICAL, INTENT(out)                     :: help_req
988      !! An output logical flag with `.true.` if help option has been found, `.false.` otherwise
989    LOGICAL, INTENT(out)                     :: vers_req
990      !! An output logical flag with `.true.` if version option has been found, `.false.` otherwise
991    TYPE(error) :: err
992      !! Error object with the first error encountered in the process
993    CHARACTER(len=1), PARAMETER   :: sq = CHAR(39)
994    CHARACTER(len=:), ALLOCATABLE :: elt
995    INTEGER                       :: arg_idx
996    INTEGER                       :: i,nv,ic
997    err = noerror ; arg_idx = -1
998    help_req = .false.
999    DO WHILE(words_valid(cmd))
1000      ! get current element
1001      elt = words_current(cmd)
1002      ! check element kind: is it an option flag (-1/0) or a value (1)?
1003      ic = ap_check_string(this,elt,arg_idx)
1004      IF (ic <= 0) THEN
1005        IF (arg_idx /= -1) THEN
1006          err = ap_fill_argument(this,cmd,this%args(arg_idx))
1007          IF (err == 0) THEN
1008            IF (this%args(arg_idx)%paction == ap_help) THEN
1009              this%parsed = 1
1010              err = argparser_get_value(this,'help',help_req)
1011              EXIT
1012            ELSE IF (this%args(arg_idx)%paction == ap_version) THEN
1013              this%parsed = 1
1014              err = argparser_get_value(this,'version',vers_req)
1015              EXIT
1016            ENDIF
1017          ENDIF
1018          IF (err /= 0) EXIT
1019        ELSE
1020          err = error("Unknown argument ('"//elt//"')",-9)
1021          EXIT
1022        ENDIF
1023      ELSE
1024        ! We are in the positionals   !!!
1025        IF (TRIM(elt) == '--') CALL words_next(cmd)
1026        EXIT
1027      ENDIF
1028      ! iterates to next value
1029      CALL words_next(cmd)
1030    ENDDO
1031
1032    ! Do we need to check for error here ?
1033    IF (err /= 0) THEN
1034      this%parsed = 0
1035      arg_idx = -1
1036      RETURN
1037    ELSE IF (help_req) THEN
1038      arg_idx = -1
1039      RETURN
1040    ENDIF
1041
1042    ! Must check here for argument with append action if they have the correct
1043    ! number of argument
1044    DO i=1,this%nargs
1045      nv = words_length(this%args(i)%values)
1046      IF (this%args(i)%fnd                  .AND. &
1047          this%args(i)%paction == ap_append .AND. &
1048          this%args(i)%nrec > 0             .AND. &
1049          nv /= this%args(i)%nrec) THEN
1050        IF (this%args(i)%nrec < nv) THEN
1051          err = ac_fmt_val_err(this%args(i),-18) ! extra values
1052        ELSE
1053          err = ac_fmt_val_err(this%args(i),-17) ! missing values
1054        ENDIF
1055      ENDIF
1056    ENDDO
1057    IF (err /= 0) this%parsed = 0
1058    RETURN
1059  END FUNCTION ap_parse_options
1060
1061  FUNCTION ap_parse_positionals(this,cmd) RESULT(err)
1062    !! Parse positional arguments of the internal command line
1063    !! This (internal) function manages the parsing of the command line positional arguments.
1064    OBJECT(argparser), INTENT(inout) :: this
1065      !! An argparser object reference
1066    TYPE(words), INTENT(inout)       :: cmd
1067      !! A [[string_op(module):words(type)]] object with the command-line to parse
1068    TYPE(error) :: err
1069      !! Error object with the first error encountered in the process
1070    INTEGER                       :: na
1071    CHARACTER(len=:), ALLOCATABLE :: elt
1072    err = noerror
1073    ! cmd iterator is located at the first positional argument
1074
1075    ! no positional required but current word is valid
1076    ! Either : no positional required but valid element is present
1077    !     Or : positional required but no valid element is present
1078    IF ((this%have_posal.AND..NOT.words_valid(cmd)) .OR. &
1079        (.NOT.this%have_posal.AND.words_valid(cmd))) THEN
1080      err = error("Wrong number of arguments",-16) ; RETURN
1081    ENDIF
1082    ! ugly patch : we must clear this%posals%values because of the automatic
1083    ! setting of default value
1084    CALL words_clear(this%posals%values)
1085    this%posals%fnd = .true.
1086    DO
1087      na = words_length(this%posals%values)
1088      IF (words_valid(cmd)) THEN
1089        ! Gets the element value
1090        elt = words_current(cmd)
1091        ! and add it
1092        CALL words_append(this%posals%values,elt)
1093      ELSE
1094        ! no more elements: check against the number of expected records
1095        ! 1 or + elements expected but nothing has been saved
1096        IF (this%posals%nrec == -3 .AND. na > 1) THEN
1097          err = error("Extra value(s) found (positionals arguments)",-18)
1098        ELSE IF (this%posals%nrec == -2 .AND. na == 0) THEN
1099          err = error("Missing values (positionals arguments)",-17)
1100        ELSE IF (this%posals%nrec > 0 .AND. na /= this%posals%nrec) THEN
1101          IF (na > this%posals%nrec) THEN
1102            err = error("Extra value(s) found (positionals arguments)",-18)
1103          ELSE
1104            err = error("Missing values (positionals arguments)",-17)
1105          ENDIF
1106        ENDIF
1107        EXIT
1108      ENDIF
1109      ! get to the next element
1110      CALL words_next(cmd)
1111    ENDDO
1112    IF (err /= noerror) THEN
1113      this%posals%fnd = .false.
1114      this%parsed = 0
1115    ENDIF
1116    RETURN
1117  END FUNCTION ap_parse_positionals
1118
1119  FUNCTION ap_fill_argument(this,cmd,arg) RESULT(err)
1120    !! Fill an argument with values
1121    !!
1122    !! The function parses remaining parts of the command line from the position of
1123    !! the given argument and attempts to retrieve its value(s) (if any).
1124    !! Several tests are performed and may raise errors. The function always stops
1125    !! at the first error encountered which can be one of the following :
1126    !! - Invalid value type (conversion check failed)
1127    !! - Missing values (can not get as much values as defined in the argument)
1128    !! - Extra values found (more values can be retrieved from the command line
1129    !!   than defined in the argument)
1130    OBJECT(argparser), INTENT(inout)  :: this
1131      !! An argparser object reference
1132    TYPE(words), INTENT(inout)        :: cmd
1133      !! The command line
1134    TYPE(argc), INTENT(inout), TARGET :: arg
1135      !! An argc object reference with the argument currently processed.
1136    TYPE(error) :: err
1137      !! Error object with the first error encountered in the process
1138    INTEGER                       :: ca, isopt, itmp
1139    LOGICAL                       :: ltmp
1140    CHARACTER(len=:), ALLOCATABLE :: elt
1141    err = noerror
1142    ! We always reset arguments value if we are in store mode.
1143    ! If one wants to set an option several times and keeps track of the
1144    ! previous values, she must use 'append'
1145    IF (arg%paction == ap_store) CALL words_clear(arg%values)
1146    ! Gets values as a function of the expected number of records
1147    IF (arg%nrec == 0) THEN
1148      ! argparser_parse (main parsing method) reset all values: for 0 nrec
1149      ! we should have at least one value saved which is the default.
1150      ! if it is not the case we set default as values of the argument
1151      IF (words_length(arg%values) == 0) CALL words_append(arg%values,arg%default)
1152      ! NOW HANDLING 0 records case:
1153      ! we do not have to consume any argument but :
1154      !  - trigger a boolean (set it to .not.default)
1155      !  - increase a counter (if action == 'count')
1156      IF (arg%paction == ap_count) THEN
1157        elt = words_pop(arg%values)
1158        READ(elt,*) itmp ; itmp = itmp + 1
1159        CALL words_append(arg%values,TO_STRING(itmp))
1160      ELSE IF (arg%ptype == ap_logical) THEN
1161        elt = words_pop(arg%values)
1162        READ(elt,*) ltmp
1163        CALL words_append(arg%values,TO_STRING(.NOT.ltmp))
1164      ENDIF
1165    ELSE
1166      ! For any other case, the algorithm is quite simple :
1167      ! We consume tokens of the command-line until either the end or
1168      ! the next option (or '--' separator)
1169      ! When the exit condition is met we perform some tests based on the
1170      ! expected argument and sets the returned error object...
1171      ca = 0 ; IF(arg%paction == ap_append) ca = words_length(arg%values)
1172      DO
1173        CALL words_next(cmd) ; elt = words_current(cmd) ; isopt = ap_check_string(this,elt)
1174        ! We have a "valid" value
1175        IF (((.NOT.words_valid(cmd)).EQV.(isopt<=0)).AND.TRIM(elt) /= '--') THEN
1176          ! we have a value that we should check for conversion !
1177          err = ac_check_value(arg,elt)
1178          IF (err /= 0) THEN
1179            err = ac_fmt_val_err(arg,-2)
1180          ELSE
1181            CALL words_append(arg%values,elt) ; ca = ca + 1
1182          ENDIF
1183        ELSE
1184          ! 3 cases are possible :
1185          !    1) we have consumed all argument of command line
1186          !    2) current argument is not a value !
1187          !    3) current argument the separator '--'
1188          IF (isopt <= 0 .OR. TRIM(elt)=='--') CALL words_previous(cmd)
1189          IF (arg%nrec == -2 .AND. words_length(arg%values) == 0) &
1190            err = ac_fmt_val_err(arg,-17)
1191          IF (arg%paction /= ap_append .AND. arg%nrec > 0 .AND. ca /= arg%nrec) &
1192          THEN
1193            IF (ca > arg%nrec) THEN
1194              err = ac_fmt_val_err(arg,-18)
1195            ELSE
1196              err = ac_fmt_val_err(arg,-17)
1197            ENDIF
1198          ENDIF
1199          EXIT
1200        ENDIF
1201        IF (err /= noerror) EXIT
1202        IF (arg%nrec == -3) EXIT
1203        IF (ca == arg%nrec) EXIT
1204      ENDDO
1205    ENDIF
1206    arg%fnd = (err == noerror)
1207    RETURN
1208  END FUNCTION ap_fill_argument
1209
1210  FUNCTION ap_split_cmd(this,string,new_cmd,rhelp) RESULT(err)
1211    !! Preprocess the command line
1212    !! The function reads and splits the given string so merged options/values
1213    !! are splitted and saves the resulting string elements in a list of words.
1214    !! @warning
1215    !! For compilers that does not support allocatable strings in derived types,
1216    !! computation are highly dependent of [[string_op(module):st_slen(variable):
1217    !! tokens length are limited by this parameter.
1218    IMPLICIT NONE
1219    OBJECT(argparser), INTENT(in) :: this
1220      !! An argparser object reference
1221    CHARACTER(len=*), INTENT(in)  :: string
1222      !! A string to process
1223    TYPE(words), INTENT(out)      :: new_cmd
1224      !! An output [[string_op(module):words(type)]] object with the processed command line
1225    LOGICAL, INTENT(out)          :: rhelp
1226      !! An output boolean flag with `.true.` if help is requested, `.false.` otherwise
1227    TYPE(error) :: err
1228      !! Error object with the first error encountered in the process
1229    INTEGER                       :: isopt,j,tl,res
1230    CHARACTER(len=:), ALLOCATABLE :: elt
1231    TYPE(words)                   :: splitted
1232    INTEGER                       :: arg_idx
1233    err = noerror ; rhelp = .false.
1234    IF (LEN_TRIM(string) == 0) THEN
1235      err = error('internal error (empty string)',-255)
1236      RETURN
1237    ENDIF
1238    ! split input command line in words !
1239    call words_extend(splitted,string," ",.true.)
1240    ! reset iterator
1241    CALL words_reset(splitted)
1242    DO WHILE(words_valid(splitted))
1243      elt = words_current(splitted) ; tl = LEN_TRIM(elt)
1244      isopt = ap_check_string(this,TRIM(elt),arg_idx)
1245      ! we have a short option : maybe we need to split it
1246      IF (isopt == -1 ) THEN
1247        DO j=2,tl
1248          res = ap_check_string(this,"-"//elt(j:j),arg_idx)
1249          ! great we have another short option flag
1250          IF (res == -1 .AND. arg_idx /= -1) THEN ! another short option !
1251            rhelp = (this%args(arg_idx)%paction == ap_help.OR.rhelp)
1252            ! we must not set some argument's values here  for help argument
1253            ! if auto is not set the parse method will disable the option
1254            ! during next! parsing process
1255            CALL words_append(new_cmd,"-"//elt(j:j))
1256          ELSE
1257            IF (j == 2) THEN ! no more option flag !
1258              CALL words_append(new_cmd,TRIM(elt(j-1:)))
1259            ELSE
1260              CALL words_append(new_cmd,TRIM(elt(j:)))
1261            ENDIF
1262            EXIT ! WE MUST EXIT !!!!!!!
1263          ENDIF
1264        ENDDO
1265      ELSE
1266        IF (isopt == 0.AND.arg_idx /= -1) &
1267        rhelp = (this%args(arg_idx)%paction == ap_help.OR.rhelp)
1268        ! we must not set some argument's values here for help argument
1269        ! if auto is not set the parse method will disable the option during
1270        ! next parsing process
1271        CALL words_append(new_cmd,TRIM(elt))
1272      ENDIF
1273      ! Iterates to next word
1274      CALL words_next(splitted)
1275    ENDDO
1276    CALL words_clear(splitted)
1277    RETURN
1278  END FUNCTION ap_split_cmd
1279
1280  FUNCTION ap_check_string(this,string,idx) RESULT(ret)
1281    !! Check if a string is an option flag
1282    !! The function checks if the given string is either a short, long option flag or a value.
1283    !! @warning
1284    !! An empty string is considered as a value !
1285    OBJECT(argparser), INTENT(in)              :: this
1286      !! An argparser object reference
1287    CHARACTER(len=*), INTENT(in)               :: string
1288      !! A string to check
1289    INTEGER, INTENT(out), OPTIONAL             :: idx
1290      !! An optional output intger with the index of the afferent argument in the parser (-1 if not found)
1291    INTEGER :: ret
1292      !! Return code with the following possible values:
1293      !! - -1 if the string is a SHORT option flag
1294      !! - 0 if the string is a LONG option flag
1295      !! - 1 if it considered as a value
1296    CHARACTER(len=52), PARAMETER :: alpha = "abcdefghijklmnopqrstuvwxyz&
1297                                            &ABCDEFGHIJKLMNOPQRSTUVWXYZ"
1298    ! return code can be either :
1299    !  -1 : it's a short option flag
1300    !   0 : it's a long option flag
1301    !   1 : it's a value
1302    ! The combination of the (optional) output index and the return code
1303    ! allows to check if an option is known or not
1304    ret = 1
1305    ! '--' is special : it is a separator that is seen as a value.
1306    IF (TRIM(string) == '--') RETURN
1307    IF (PRESENT(idx)) idx = -1
1308    ! First we will check the two first characters of the string
1309    IF (LEN_TRIM(string) >= 2) THEN
1310      IF (string(1:1) == ACHAR(45)) THEN
1311        ! It's a long option flag !
1312        IF (string(2:2) == ACHAR(45)) THEN
1313          ret = 0
1314          IF (PRESENT(idx)) idx = ap_get_arg_index(this,lflag=TRIM(string))
1315        ELSE
1316          ! It's a short option flag !
1317          IF (INDEX(alpha, string(2:2)) /= 0) THEN
1318            ret = -1
1319            IF (PRESENT(idx)) idx = ap_get_arg_index(this,sflag=string(1:2))
1320          ENDIF
1321        ENDIF
1322      ENDIF
1323    ENDIF
1324    RETURN
1325  END FUNCTION ap_check_string
1326
1327  FUNCTION ap_gen_help(this) RESULT(hlp)
1328    !! Generate the help string
1329    OBJECT(argparser), INTENT(inout) :: this
1330      !! An argparser object reference
1331    CHARACTER(len=:), ALLOCATABLE :: hlp
1332      !! The formatted help message
1333    CHARACTER(len=:), ALLOCATABLE :: copt,spc,opts,text
1334    INTEGER                       :: i,j,ia,optmw,i1,io,n,zw,zh
1335    IF (this%width == 0) CALL fs_termsize(zh,this%width)
1336    zw = this%width
1337    ! Sets usage
1338    CALL ap_format_usage(this,optmw)
1339    ! computes the help position
1340    optmw = optmw +2 + 2 ! +2 for indentation + 2 for spaces after option
1341    optmw = MIN(MAX(5,this%mxhlpos-1),optmw)
1342    hlp = TRIM(this%usg)//NEW_LINE('A')//NEW_LINE('A')
1343    ! Sets description
1344    IF (LEN_TRIM(this%descr) /= 0) &
1345      hlp=hlp//getpar(this%descr,zw,2)//NEW_LINE('A')//NEW_LINE('A')
1346    ! Sets positionals
1347    IF (this%have_posal) THEN
1348      IF (LEN_TRIM(this%posals%help) /= 0) THEN
1349        hlp=hlp//'positionals:'//NEW_LINE('A')
1350        copt = ac_get_opt_str(this%posals) ; n = LEN_TRIM(copt)
1351        hlp=hlp//getpar(copt,zw,idt1=2)
1352        ! we must put help on a new line : no need to extends opt with spaces
1353        IF (n > optmw-2) THEN
1354          hlp=hlp//NEW_LINE('A')//REPEAT(CHAR(32),optmw)
1355        ELSE
1356          hlp=hlp//REPEAT(CHAR(32),optmw-n-2)
1357        ENDIF
1358        spc = REPEAT(CHAR(32),optmw)
1359        text = getpar(this%posals%help,zw-optmw,0,0)
1360        j=1
1361        DO WHILE(j <= LEN(text))
1362          i = INDEX(text(j:),NEW_LINE('A'))
1363          IF (i /= 0) THEN
1364            hlp=hlp//text(j:j+i-1)//spc
1365            j=j+i
1366          ELSE
1367            hlp=hlp//text(j:) ; EXIT
1368          ENDIF
1369        ENDDO
1370        hlp=hlp//NEW_LINE('A')//NEW_LINE('A')
1371      ENDIF
1372    ENDIF
1373    ! Sets options
1374    IF (this%nargs > 0) THEN
1375      opts=''
1376      DO ia=1, this%nargs
1377        IF (LEN_TRIM(this%args(ia)%help) /= 0) THEN
1378          copt = ac_get_opt_str(this%args(ia)) ; n = LEN_TRIM(copt)
1379          opts=opts//getpar(copt,zw,idt1=2)
1380          ! we must put help on a new line : no need to extends opt with spaces
1381          IF (n > optmw-2) THEN
1382            opts=opts//NEW_LINE('A')//REPEAT(CHAR(32),optmw)
1383          ELSE
1384            opts=opts//REPEAT(CHAR(32),optmw-n-2)
1385          ENDIF
1386          spc = REPEAT(CHAR(32),optmw)
1387          text = getpar(this%args(ia)%help,zw-optmw,0,0)
1388          j=1
1389          DO WHILE(j <= LEN(text))
1390            i = INDEX(text(j:),NEW_LINE('A'))
1391            IF (i /= 0) THEN
1392              opts=opts//text(j:j+i-1)//spc
1393              j=j+i
1394            ELSE
1395              opts=opts//text(j:) ; EXIT
1396            ENDIF
1397          ENDDO
1398          opts=opts//NEW_LINE('A')
1399        ENDIF
1400      ENDDO
1401      IF (LEN_TRIM(opts) > 0) hlp=hlp//'options:'//NEW_LINE('A')//opts
1402    ENDIF
1403    IF (LEN_TRIM(this%eplg) /= 0) THEN
1404      hlp=hlp//NEW_LINE('A')//getpar(this%eplg,zw,2)//NEW_LINE('A')
1405    ENDIF
1406    RETURN
1407  END FUNCTION ap_gen_help
1408
1409  SUBROUTINE ap_format_usage(this,optmw)
1410    !! Format command line usage.
1411    !!
1412    !! The subroutine creates and formats the command line usage of the
1413    !! given argparser object. If [[argparser(type):usg(variable)]] is already set (i.e. not empty)
1414    !! then the method only computes the maximum width of the option part of the usage command
1415    !! (see `optmw` argument description) if needed. In the other case, the method builds the usage
1416    !! line based on the arguments stored in the parser.
1417    OBJECT(argparser), INTENT(inout) :: this
1418      !! An argparser object reference
1419    INTEGER, INTENT(out), OPTIONAL   :: optmw
1420      !! An optional integer with the maximum length of the option part of the usage command.
1421      !! This variable is intended to set a fancy indentation while printing option in the helper.
1422    CHARACTER(len=:), ALLOCATABLE :: usage, idts, copt,pgn
1423    INTEGER                       :: i,omw,idt,cl,wopt
1424    ! Get/Checks/Sets maximum width
1425    ! get program name
1426    pgn = get_progname()
1427    omw = 0
1428    IF (LEN_TRIM(this%usg) == 0) THEN
1429      idt = 8 + LEN_TRIM(pgn)
1430      ALLOCATE(CHARACTER(LEN=idt+1) :: idts)
1431      idts(1:1) = NEW_LINE('A') ; idts(2:idt+1) = CHAR(32)
1432      ! Builds the usage string
1433      usage = "usage: "//TRIM(pgn)//CHAR(32)
1434      ! Looping over arguments
1435      cl = idt
1436      DO i=1,this%nargs
1437        ! gets max length for help options
1438        copt = ac_get_opt_str(this%args(i)) ; wopt=LEN_TRIM(copt)
1439        IF (LEN_TRIM(this%args(i)%help) /= 0.AND. wopt > omw) omw = wopt
1440        !IF (LEN_TRIM(copt) > omw) omw = LEN_TRIM(copt) ; copt=""
1441        ! Retrieve current argument usage string
1442        copt = ac_get_usg_opt_str(this%args(i))
1443        ! Set a new line if it does not hold width
1444        IF (cl+LEN_TRIM(copt) > this%width) THEN
1445          cl = idt ; usage = usage(:)//idts(:)
1446        ENDIF
1447        ! Write the argument usage + a blank space !
1448        usage = usage(:)//TRIM(copt)//CHAR(32)
1449        cl = cl + LEN_TRIM(copt)+1
1450      ENDDO
1451      IF (PRESENT(optmw)) optmw = omw
1452      ! handling positional
1453      IF (this%have_posal) THEN
1454        copt = ac_get_usg_opt_str(this%posals)
1455        IF (LEN_TRIM(copt) > 0) THEN
1456          ! print newline if it cannot fit
1457          IF (cl+LEN_TRIM(copt) > this%width) usage = usage(:)//idts(:)
1458          usage = usage(:)//TRIM(copt)
1459        ENDIF
1460      ENDIF
1461      this%usg = usage
1462    ELSE
1463      IF (PRESENT(optmw)) THEN
1464        DO i=1,this%nargs
1465          copt = ac_get_opt_str(this%args(i)) ; wopt=LEN_TRIM(copt)
1466          IF (LEN_TRIM(this%args(i)%help) /= 0.AND.wopt > omw) omw = wopt
1467          copt = ""
1468        ENDDO
1469        optmw = omw
1470      ENDIF
1471    ENDIF
1472  END SUBROUTINE ap_format_usage
1473
1474  SUBROUTINE ap_affect_parser(this,other)
1475    !! Argparser assignment operator subroutine
1476    !! The subroutine assigns `other` to `this`
1477    TYPE(argparser), INTENT(out) :: this
1478      !! An argparser object to be assigned
1479    TYPE(argparser), INTENT(in)  :: other
1480      !! An argparser object to assign
1481    INTEGER :: i
1482    IF (other%nargs > 0) THEN
1483      this%nargs = other%nargs
1484      ALLOCATE(this%args(this%nargs))
1485      DO i=1,this%nargs ; this%args(i) = other%args(i) ; ENDDO
1486    ENDIF
1487    this%have_posal = other%have_posal
1488    this%posals     = other%posals
1489    this%parsed     = other%parsed
1490#if HAVE_FTNDTSTR
1491    IF (ALLOCATED(other%usg))   this%usg   = other%usg
1492    IF (ALLOCATED(other%descr)) this%descr = other%descr
1493    IF (ALLOCATED(other%eplg))  this%eplg  = other%eplg
1494    IF (ALLOCATED(other%vers))  this%vers  = other%vers
1495#else
1496    this%usg   = other%usg
1497    this%descr = other%descr
1498    this%eplg  = other%eplg
1499    this%vers  = other%vers
1500#endif
1501    this%mxhlpos = other%mxhlpos
1502    this%width   = other%width
1503    this%init    = other%init
1504  END SUBROUTINE ap_affect_parser
1505
1506  ! argc methods
1507  ! ------------
1508
1509  SUBROUTINE ac_affect_arg(this,other)
1510    !! Argc object assignment operator subroutine
1511    !! The subroutine assigns `other` to `this`
1512    TYPE(argc), INTENT(out) :: this
1513      !! An argc object to be assigned
1514    TYPE(argc), INTENT(in)  :: other
1515      !! An argc object to assign
1516    this%nrec   = other%nrec
1517    this%paction = other%paction
1518    this%ptype   = other%ptype
1519    this%fnd  = other%fnd
1520    this%sflag  = other%sflag
1521#if HAVE_FTNDTSTR
1522    IF (ALLOCATED(other%name))    this%name    = other%name
1523    IF (ALLOCATED(other%lflag))   this%lflag   = other%lflag
1524    IF (ALLOCATED(other%help))    this%help    = other%help
1525    IF (ALLOCATED(other%default)) this%default = other%default
1526#else
1527    this%name    = other%name
1528    this%lflag   = other%lflag
1529    this%default = other%default
1530    this%help    = other%help
1531#endif
1532    CALL words_clear(this%values)
1533    CALL words_clear(this%meta)
1534    this%values = other%values
1535    this%meta   = other%meta
1536    RETURN
1537  END SUBROUTINE ac_affect_arg
1538
1539  FUNCTION ac_equals_arg(this,other) RESULT(ret)
1540    !! Check if two arguments are identical
1541    !! The method checks if two arguments are equal based on their name, short option flag and long
1542    !! option flag.Two arguments are considered equals if at least one of these three members is equal
1543    !! and not empty.
1544    TYPE(argc), INTENT(in) :: this
1545      !! First argc object to compare
1546    TYPE(argc), INTENT(in) :: other
1547      !! Second argc object to compare
1548    LOGICAL :: ret
1549      !! `.true.` if the two objects are equal, `.false.` otherwise.
1550    CHARACTER(len=:), ALLOCATABLE :: tna,ona,tsf,osf,tlf,olf
1551    INTEGER                       :: tn,ts,tl,on,os,ol
1552    ret = .false.
1553    tsf = TRIM(this%sflag) ; osf = TRIM(this%sflag)
1554#if HAVE_FTNDTSTR
1555    tna="" ; IF (ALLOCATED(this%name))   tna=TRIM(this%name)
1556    ona="" ; IF (ALLOCATED(other%name))  ona=TRIM(other%name)
1557    tlf="" ; IF (ALLOCATED(this%lflag))  tlf=TRIM(this%lflag)
1558    olf="" ; IF (ALLOCATED(other%lflag)) olf=TRIM(other%lflag)
1559#else
1560    tna=TRIM(this%name)  ; ona=TRIM(other%name)
1561    tlf=TRIM(this%lflag) ; olf=TRIM(other%lflag)
1562#endif
1563    tn=LEN_TRIM(tna) ; on=LEN_TRIM(ona)
1564    tl=LEN_TRIM(tlf) ; ol=LEN_TRIM(olf)
1565    ts=LEN_TRIM(tsf) ; os=LEN_TRIM(osf)
1566    ! check on name :
1567    ! Returns True if at least of name, sflag and lflag is set to non-empty
1568    ! string and is indentical for the two argument !
1569    ret = ((tn/=0 .AND. on==tn) .AND. tna == ona) .OR. &
1570          ((tl/=0 .AND. ol==tl) .AND. tlf == olf) .OR. &
1571          ((ts/=0 .AND. os==ol) .AND. tsf == osf)
1572    DEALLOCATE(tna,ona,tsf,osf,tlf,olf)
1573  END FUNCTION ac_equals_arg
1574
1575  FUNCTION ac_differs_arg(this,other) RESULT(ret)
1576    !! Check if two arguments are different
1577    !! The method checks if two arguments are different based on their names, short option flag
1578    !! and long option flag.
1579    !! @note
1580    !! This function is the extact contrary of [[argparse(module):ac_equals_arg(function)]] !
1581    TYPE(argc), INTENT(in) :: this
1582      !! First argc object to compare
1583    TYPE(argc), INTENT(in) :: other
1584      !! Second argc object to compare
1585    LOGICAL :: ret
1586      !! `.true.` if the two objects are different, `.false.` otherwise.
1587    ret = .NOT. ac_equals_arg(this,other)
1588  END FUNCTION ac_differs_arg
1589
1590  SUBROUTINE ac_clear_arg_sc(arg)
1591    !! argc destructor (scalar)
1592    !! The subroutine frees all memory used by an argc object and resets its member to
1593    !! default values.
1594    TYPE(argc), INTENT(inout) :: arg
1595      !! An argc object to free
1596    CALL words_clear(arg%values)
1597    CALL words_clear(arg%meta)
1598    arg%ptype   = ap_logical
1599    arg%paction = ap_store
1600    arg%nrec    = 0
1601    arg%fnd     = .false.
1602    arg%sflag   = "  "
1603#if HAVE_FTNDTSTR
1604    IF (ALLOCATED(arg%default)) DEALLOCATE(arg%default)
1605    IF (ALLOCATED(arg%name))    DEALLOCATE(arg%name)
1606    IF (ALLOCATED(arg%lflag))   DEALLOCATE(arg%lflag)
1607    IF (ALLOCATED(arg%help))    DEALLOCATE(arg%help)
1608#else
1609    arg%default = ""
1610    arg%name    = ""
1611    arg%help    = ""
1612    arg%lflag   = ""
1613#endif
1614  END SUBROUTINE ac_clear_arg_sc
1615
1616  SUBROUTINE ac_clear_arg_ve(args)
1617    !! argc destructor (vector)
1618    TYPE(argc), INTENT(inout), DIMENSION(:), TARGET :: args
1619      !! A vector of argc objects to free
1620    INTEGER :: i
1621    CALL words_clear(args%values)
1622    CALL words_clear(args%meta)
1623    DO i=1, SIZE(args)
1624      args(i)%ptype   = ap_logical
1625      args(i)%paction = ap_store
1626      args(i)%nrec    = 0
1627      args(i)%fnd     = .false.
1628      args(i)%sflag    = "  "
1629#if HAVE_FTNDTSTR
1630      IF (ALLOCATED(args(i)%default)) DEALLOCATE(args(i)%default)
1631      IF (ALLOCATED(args(i)%name))    DEALLOCATE(args(i)%name)
1632      IF (ALLOCATED(args(i)%lflag))   DEALLOCATE(args(i)%lflag)
1633      IF (ALLOCATED(args(i)%help))    DEALLOCATE(args(i)%help)
1634#else
1635      args(i)%default = ""
1636      args(i)%name    = ""
1637      args(i)%help    = ""
1638      args(i)%lflag   = ""
1639#endif
1640    ENDDO
1641  END SUBROUTINE ac_clear_arg_ve
1642
1643  FUNCTION ac_found(this) RESULT(yes)
1644    !! Check if argument has been found in the command line
1645    TYPE(argc), INTENT(in) :: this
1646      !! An argc object
1647    LOGICAL :: yes
1648      !! `.true.` if the option has been parsed, `.false.` otherwise
1649    yes = this%fnd
1650  END FUNCTION ac_found
1651
1652  FUNCTION ac_get_num_values(this) RESULT(num)
1653    !! Get the actual number of values stored in the argument
1654    TYPE(argc), INTENT(in) :: this
1655      !! An argc object
1656    INTEGER :: num
1657      !! The number of values stored in the argument
1658    num = words_length(this%values)
1659  END FUNCTION ac_get_num_values
1660
1661  FUNCTION ac_get_usg_opt_str(arg) RESULT(line)
1662    !! Build and format the option string for the usage part of the help message
1663    !! The function is private part of the help builder. It creates the
1664    !! option string part of a given argument.
1665    TYPE(argc), INTENT(in), TARGET :: arg
1666      !! An argc object
1667    CHARACTER(len=:), ALLOCATABLE :: line,meta
1668      !! Allocated string with the option flags string
1669    line=""
1670    IF (LEN_TRIM(arg%sflag) > 0) THEN
1671      line="["//TRIM(arg%sflag)
1672    ELSE IF (LEN_TRIM(arg%lflag) > 0) THEN
1673      line="["//TRIM(arg%lflag)
1674    ENDIF
1675    meta = TRIM(words_get(arg%meta,1))
1676    SELECT CASE (arg%nrec)
1677      CASE (-3)
1678        line=line(:)//" ["//meta//"]"
1679      CASE (-2)
1680        line=line(:)//CHAR(32)//meta//" [...]"
1681      CASE (-1)
1682        line=line(:)//" ["//meta//" [...]]"
1683      CASE (0)
1684        ! DO NOTHING BUT MUST BE EXPLICITELY SET
1685      CASE DEFAULT
1686        meta = words_to_string(arg%meta," ")
1687        line = line(:)//CHAR(32)//meta
1688    END SELECT
1689    IF (line(1:1) == "[") line=line(:)//"]"
1690    RETURN
1691  END FUNCTION ac_get_usg_opt_str
1692
1693  FUNCTION ac_get_opt_str(arg) RESULT(line)
1694    !! Build and format the option flag string for the option part of the help message
1695    !! The function is private part of the help builder. It creates the
1696    !! option string part of a given argument for the options part of the help.
1697    TYPE(argc), INTENT(in), TARGET :: arg
1698      !! An argc object
1699    CHARACTER(len=:), ALLOCATABLE :: line
1700      !! Allocated string with the option flags string
1701    CHARACTER(len=:), ALLOCATABLE :: values,m
1702    ! creates values string
1703    m = TRIM(words_get(arg%meta,1))
1704    SELECT CASE (arg%nrec)
1705      CASE(-3)
1706        values="["//m//"]"
1707      CASE(-2)
1708        values=m//" [...]"
1709      CASE(-1)
1710        values="["//m//" [...]]"
1711      CASE (0)
1712        values=""
1713      CASE DEFAULT
1714        values = words_to_string(arg%meta," ")
1715     END SELECT
1716     ! build the final string
1717     ! -s values, --long values
1718     line=""
1719     IF (LEN_TRIM(arg%sflag) > 0) THEN
1720       line=TRIM(arg%sflag)//CHAR(32)//TRIM(values)
1721       IF (LEN_TRIM(arg%lflag) > 0) line = line(:)//", "
1722     ENDIF
1723     IF (LEN_TRIM(arg%lflag) > 0) THEN
1724         line = line(:)//TRIM(arg%lflag)//CHAR(32)//TRIM(values)
1725     ENDIF
1726     ! this line handles positionals :)
1727     IF (arg%name == 'positional') line = TRIM(values)
1728    RETURN
1729  END FUNCTION ac_get_opt_str
1730
1731  FUNCTION ac_fmt_val_err(arg,id) RESULT(ret)
1732    !! Format specific error for argc values
1733    !! The function formats argparse specific errors when extra (missing) values
1734    !! are (not) set or when given values are not consistent with argument's type.
1735    !! For each of these errors, the basic error is updated with a more precise
1736    !! message.
1737    TYPE(argc), INTENT(in) :: arg
1738      !! An argc object
1739    INTEGER, INTENT(in)    :: id
1740      !! Integer with the error id (-3, -15 or -16 in fact)
1741    TYPE(error) :: ret
1742      !! Error object with the updated error message.
1743    CHARACTER(len=:), ALLOCATABLE :: msg,nv
1744    IF (LEN_TRIM(arg%sflag) /= 0) THEN
1745      msg=' ('//arg%sflag
1746    ELSE ! note that normally if no sflag are present lflag should be set
1747      msg=' ('//TRIM(arg%lflag)
1748    ENDIF
1749    nv = to_string(arg%nrec) ; IF (arg%nrec < 0) nv='1'
1750    ! we only handle ids : -2 (invalid arg), -17 (missing values), -18 (extra values)
1751    SELECT CASE(id)
1752      CASE (-2)  ! invalid value: cannot cast ->
1753        msg = msg//" option expects '"//apt2str(arg%ptype)//"' values)"
1754      CASE (-17) ! missing values -> -17
1755        IF (arg%nrec == -2) THEN
1756          msg = msg//' takes at least '//nv//' value(s))'
1757        ELSE
1758          msg = msg//' takes exactly '//nv//' value(s))'
1759        ENDIF
1760      CASE (-18) ! extra values -> -18
1761        IF (arg%nrec == -3) THEN
1762          msg = msg//' takes at most '//nv//' value(s))'
1763        ELSE
1764          msg = msg//' takes exactly '//nv//' value(s))'
1765        ENDIF
1766      CASE DEFAULT
1767        msg=''
1768    END SELECT
1769    ret = error(msg,id)
1770  END FUNCTION ac_fmt_val_err
1771
1772  FUNCTION ac_check_and_set(this,sf,lf,ty,ac,de,na,meta,check_flag) RESULT(ret)
1773    !! Interface to all argc's member tests
1774    !! The function calls all the tests to perform on argc members. Some of these tests can
1775    !! alter argc's member values to fit argparser's requirements.
1776    !!
1777    !! On success, `noerror` is returned. Otherwise -9 error code is returned. Errors are only
1778    !! produced by misuse of the function arguments. In such case, the program should be
1779    !! stopped: note that such ezrror should not occur in _released_ programs.
1780    TYPE(argc), INTENT(inout)                            :: this
1781      !! An argc object
1782    CHARACTER(len=2), INTENT(in)                         :: sf
1783      !! A string (2 chars wide) with the short option flag
1784    CHARACTER(len=*), INTENT(in)                         :: lf
1785      !! A string with the long option flag
1786    INTEGER, INTENT(in)                                  :: ty
1787      !! An integer with the type of the argument
1788    INTEGER, INTENT(in)                                  :: ac
1789      !! An integer with the action of the argument
1790    CHARACTER(len=*), INTENT(in)                         :: de
1791      !! A string with the default value of the argument
1792    CHARACTER(len=*), INTENT(in)                         :: na
1793      !! A string pattern with the expected number of values for the argument
1794    CHARACTER(len=*), INTENT(in), DIMENSION(:), OPTIONAL :: meta
1795      !! An optional vector of strings with the Meta-name of the values
1796    LOGICAL, INTENT(in), OPTIONAL                        :: check_flag
1797      !! An optional boolean flag hat instructs the method wether to check for option flag
1798      !! or not. By default this test is enabled but it should be disabled if one wants to
1799      !! check for POSITIONAL arguments as they do not have option flags.
1800    TYPE(error) :: ret
1801      !! Error object with the first error encountered in the process
1802    LOGICAL :: zflag
1803    zflag = .true. ; IF (PRESENT(check_flag)) zflag = check_flag
1804    ! 1) CHECKING FLAG SYNTAX
1805    IF (zflag) THEN
1806      ret = ac_check_flags(this,sf,lf) ; IF (ret /= 0) RETURN
1807    ELSE
1808      this%sflag = sf ; this%lflag = lf
1809    ENDIF
1810    ! 2) CHECKING AND SETTING action, type, default value and number of record
1811    ret = ac_check_ac_ty_de_na(this,ac,ty,de,na) ; IF (ret /= 0) RETURN
1812    ! 3) Sets/updates meta name
1813    IF (PRESENT(meta)) THEN
1814      CALL ac_set_meta(this,meta)
1815    ELSE
1816      CALL ac_set_meta(this)
1817    ENDIF
1818    RETURN
1819  END FUNCTION ac_check_and_set
1820
1821  FUNCTION ac_check_ac_ty_de_na(this,ac,ty,de,na) RESULT(ret)
1822    !! Check and set argc's action, type and default value
1823    !! The method checks if input argument's options are valid and update the argc object
1824    !! consequently.
1825    !!
1826    !! On success, `noerror` is returned. Otherwise -9 error code is returned. Errors are only
1827    !! produced by misuse of the function arguments.
1828    TYPE(argc), INTENT(inout)  :: this
1829      !! An argc object to update
1830    INTEGER, INTENT(in)          :: ac
1831      !! An integer with the action to set and check
1832    INTEGER, INTENT(in)          :: ty
1833      !! An integer with the type to set and check
1834    CHARACTER(len=*), INTENT(in) :: de
1835      !! A string with the default value to set and check
1836    CHARACTER(len=*), INTENT(in) :: na
1837      !! A string with the expected number of value to set and check
1838    TYPE(error) :: ret
1839      !! Error object with the first error encountered in the process
1840    CHARACTER(len=:), ALLOCATABLE :: eprf,zna
1841    TYPE(error)                   :: uty,ina
1842    ret = noerror
1843    eprf = 'argparse: '//"Invalid argument `"//TRIM(this%name)//"'"
1844    uty = error(eprf//" (type)",-9)
1845    ina = error(eprf//" (inconsistent nargs)",-9)
1846    zna = TRIM(na)
1847    ! Checks action
1848    IF(ANY(ap_actions == ac).OR.ac == ap_undef) THEN
1849      this%paction = ac
1850    ELSE
1851      ret = error(eprf//" (action)",-9) ; RETURN
1852    ENDIF
1853    ! Checks and sets type and default as a function of the action
1854    SELECT CASE(this%paction)
1855      ! HELP: fixed in any case:
1856      CASE(ap_help)
1857        this%default = 'F'
1858        this%ptype = ap_logical
1859        this%nrec = 0
1860      ! VERSION: fixed in any case:
1861      CASE(ap_version)
1862        this%default = 'F'
1863        this%ptype = ap_logical
1864        this%nrec = 0
1865      ! COUNT:
1866      ! we always use "hard-coded" stuff and do not warn if dev has made mistakes...
1867      CASE(ap_count)
1868        ! default settings of the count action
1869        this%ptype = ap_integer ; this%default = '0' ; this%nrec = 0
1870        ! check and set default value
1871        ret = set_def_val()
1872      ! STORE, APPEND actions
1873      CASE (ap_store, ap_append)
1874        ! set type
1875        IF (ty == ap_undef) THEN
1876          this%ptype= ap_integer
1877        ELSEIF (ANY(ap_types == ty)) THEN
1878          this%ptype = ty
1879        ELSE
1880          ret = uty ; RETURN
1881        ENDIF
1882        ! check and set default value
1883        ret = set_def_val() ; IF (ret /= 0) RETURN
1884        ! check for nargs (if na is empty then we set "*")
1885        ret = set_nrec("*")
1886      ! UNDEFINED:
1887      !   -> 1) set to action to store
1888      !   ->
1889      ! try to define a logical trigger and modifies it with user-defined
1890      ! characteristics
1891      CASE (ap_undef)
1892        ! 1) always define store action
1893        this%paction = ap_store
1894        ! 2) set type and nrec:
1895        !    2.1) If type is undef:
1896        !         - to default value type if default is given
1897        !         - ap_logical otherwiset type
1898        !    2.2) set nrec
1899        !        - if final type is ap_logical set nrec to 0
1900        !        - otherwise to *
1901        If (ty == ap_undef) THEN
1902          ! no explicit type : define logical trigger first
1903          this%ptype = ap_logical ; this%nrec = 0
1904          ! icheck the default value given
1905          IF (LEN_TRIM(de) > 0) THEN
1906            this%ptype = ap_types(string_is(de)+1)
1907          ELSE
1908            this%ptype = ap_logical
1909          ENDIF
1910          IF (this%ptype == ap_logical) THEN
1911            ret = set_nrec("0")
1912          ELSE
1913            ret = set_nrec("1")
1914          ENDIF
1915          ret = set_def_val()
1916          IF (ret /= 0) RETURN
1917        ! type is given
1918        ELSE IF (ANY(ty == ap_types)) THEN
1919          ! known type given :
1920          !  check default value and nrec: -> if na not given set "*"
1921          this%ptype = ty
1922          ret = set_def_val() ; IF (ret /= 0) RETURN
1923          IF (this%ptype == ap_logical) THEN
1924            ret = set_nrec("0")
1925          ELSE
1926            ret = set_nrec("1")
1927          ENDIF
1928        ELSE
1929          ! unknown type => bad end !
1930          ret = uty ; RETURN
1931        ENDIF
1932    END SELECT
1933    ! set default value as first value if ret is noerror ....
1934    IF (ret == 0) CALL words_append(this%values,this%default)
1935    RETURN
1936
1937    CONTAINS
1938
1939      FUNCTION set_nrec(base) RESULT(terr)
1940        !! Check and set argument's expected number of records
1941        !! The method compares `na` value with the expected and known flags and decides
1942        !! wether to raise an error or defines nrec member of the argument object. If `na`
1943        !! is empty then `base` is used.
1944        CHARACTER(len=1),INTENT(in) :: base
1945          !! Base value of nrec
1946        TYPE(error) :: terr
1947          !! Error object with the return status of the function
1948        terr = noerror
1949        ! check for nargs:
1950        IF (LEN(zna) == 0) zna=base
1951        SELECT CASE(zna)
1952          CASE("*") ; this%nrec = -1
1953          CASE("+") ; this%nrec = -2
1954          CASE("?") ; this%nrec = -3
1955            IF (this%paction == ap_append) terr = ina
1956          CASE DEFAULT ; this%nrec = 0
1957            ! check numeric characters
1958            IF (VERIFY(zna,"0123456789")==0) READ(zna,*) this%nrec
1959            IF (this%nrec == 0) terr = ina
1960        END SELECT
1961      END FUNCTION set_nrec
1962
1963      FUNCTION set_def_val() RESULT(terr)
1964        !! Check and set argument's default value
1965        !! The method compares `de` value with the type already stored in the argument and
1966        !! decides wether to raise an error or to save `de` as argument's default value.
1967        !! If `de` is empty then it sets a default value according to argument's type.
1968        TYPE(error) :: terr
1969          !! Error object with the return status of the function
1970        INTEGER :: t
1971        terr = noerror
1972        IF (LEN_TRIM(de) /= 0) THEN
1973          this%default = de ; t = string_is(de)
1974          IF (t /= this%ptype) THEN
1975            terr = error(eprf//" (inconsistent default value: expected '"// &
1976                           TRIM(st_type_names(this%ptype))//"', found '"// &
1977                           TRIM(st_type_names(t))//"')",-9)
1978            RETURN
1979          ENDIF
1980        ELSE
1981          SELECT CASE (this%ptype)
1982            CASE(ap_string)  ; this%default = ''
1983            CASE(ap_logical) ; this%default = 'F'
1984            CASE(ap_complex) ; this%default = '(0d0,0d0)'
1985            CASE(ap_integer) ; this%default = '0'
1986            CASE(ap_real)    ; this%default = '0d0'
1987          END SELECT
1988        ENDIF
1989        RETURN
1990      END FUNCTION set_def_val
1991  END FUNCTION ac_check_ac_ty_de_na
1992
1993  FUNCTION ac_check_flags(this,sflag,lflag) RESULT(ret)
1994    !! Set and check if argument's option flags are valid
1995    !! The method first sets the given flags in the argc object and then checks if
1996    !! its option flags are valid :
1997    !!    - A valid short option flag (`sflag`) starts with `-' followed by the
1998    !!      regex pattern : @p [a-zA-Z]
1999    !!    - A valid long option flag (`lflag`) starts with `--' followed by the
2000    !!      regex pattern : @p [-a-zA-Z_0-9]+
2001    !! @note
2002    !! Although the two arguments are mandatory one can be an empty string
2003    TYPE(argc), INTENT(inout)    :: this
2004      !! An argc object
2005    CHARACTER(len=2), INTENT(in) :: sflag
2006      !! A 2-characters wide string with the short option flag
2007    CHARACTER(len=*), INTENT(in) :: lflag
2008      !! A string (at least 3 characters wide) with the long option flag
2009    TYPE(error) :: ret
2010      !! Error object with the first error encountered in the process
2011    INTEGER :: ic
2012    ret = noerror
2013    this%sflag = sflag ; this%lflag = lflag
2014    ! 1) Check null strings !
2015    IF (LEN_TRIM(this%sflag) == 0 .AND. LEN_TRIM(this%lflag) == 0) THEN
2016      ret = error("argparse: Invalid argument (empty option flags)",-2) ; RETURN
2017    ENDIF
2018    ! 2) Check short option flag:
2019    IF (LEN_TRIM(this%sflag) > 0) THEN
2020      IF (this%sflag(1:1) /= achar(45)) THEN
2021        ret = error("argparse: Invalid argument (short option)",-2) ; RETURN
2022      ELSE
2023        SELECT CASE(iachar(this%sflag(2:2)))
2024          CASE(97:122,65:90) ; ret = noerror
2025          CASE DEFAULT
2026            ret = error("argparse: Invalid argument (short option)",-2) ; RETURN
2027        END SELECT
2028      ENDIF
2029    ENDIF
2030    ! 3) Check long option flag
2031    IF (LEN_TRIM(this%lflag) > 0) THEN
2032      ! We must have at least 3 chars !
2033      IF (LEN_TRIM(this%lflag) < 3) THEN
2034        ret = error("argparse: Invalid argument (long option)",-2) ; RETURN
2035      ELSE IF (this%lflag(1:2) /= achar(45)//achar(45)) THEN
2036        ret = error("argparse: Invalid argument (long option)",-2) ; RETURN
2037      ELSE
2038        DO ic=3,LEN_TRIM(this%lflag)
2039          SELECT CASE(iachar(this%lflag(ic:ic)))
2040            !  corresponds to [-a-zA-Z0-9_]
2041            CASE(45,48:57,65:90,95,97:122) ; ret = noerror
2042            CASE DEFAULT
2043              ret = error("argparse: Invalid argument (long option)",-2) ; RETURN
2044              EXIT
2045          END SELECT
2046        ENDDO
2047      ENDIF
2048    ENDIF
2049    RETURN
2050  END FUNCTION ac_check_flags
2051
2052  SUBROUTINE ac_set_meta(this, meta)
2053    !! Set meta-variable of the given argc object
2054    !! The method set meta-variable in the argc object. If no `meta` are given, the method
2055    !! uses argument's name to set the values.
2056    !! @warning
2057    !! To be effective, this subroutine must be called after argparse::chk_opt_nargs
2058    TYPE(argc), INTENT(inout)                            :: this
2059      !! An argc object reference
2060    CHARACTER(len=*), INTENT(in), DIMENSION(:), OPTIONAL :: meta
2061      !! An optional vector of strings with the meta-variable(s) to set
2062    INTEGER                       :: i,j,ms,blk
2063    CHARACTER(len=:), ALLOCATABLE :: zmeta
2064    ! clear meta values (not needed normally)
2065    CALL words_clear(this%meta)
2066    IF (PRESENT(meta)) THEN
2067      SELECT CASE(this%nrec)
2068        CASE(-3,-2,-1)
2069          zmeta = to_upper(meta(1))
2070          blk = INDEX(TRIM(zmeta),CHAR(32)) - 1
2071          IF (blk <= 0) blk=LEN_TRIM(zmeta)
2072          CALL words_append(this%meta,zmeta(1:blk))
2073        CASE(0)
2074          CALL words_append(this%meta,"")
2075        CASE DEFAULT
2076          ms = SIZE(meta) ; j = 0
2077          DO i=1,this%nrec
2078            j=j+1 ; IF (j>ms) j=1
2079            zmeta = to_upper(meta(j))
2080            blk=INDEX(TRIM(zmeta),CHAR(32))-1
2081            IF (blk <= 0) blk=LEN_TRIM(zmeta)
2082            CALL words_append(this%meta,zmeta(1:blk))
2083          ENDDO
2084      END SELECT
2085    ELSE
2086      zmeta = to_upper(TRIM(this%name))
2087      SELECT CASE(this%nrec)
2088        CASE(-3,-2,-1)
2089          CALL words_append(this%meta,zmeta)
2090        CASE DEFAULT
2091          DO i=1,this%nrec
2092            CALL words_append(this%meta,zmeta)
2093          ENDDO
2094      END SELECT
2095    ENDIF
2096    RETURN
2097  END SUBROUTINE ac_set_meta
2098
2099  FUNCTION ac_check_value(this,str) RESULT(err)
2100    !! Check if given string is a valid value for the argument
2101    TYPE(argc), INTENT(in)       :: this
2102      !! An argc object reference
2103    CHARACTER(len=*), INTENT(in) :: str
2104      !! A string with the value to check
2105    TYPE(error) :: err
2106      !! Error object with the first error encountered in the process
2107    INTEGER :: ty
2108    err = noerror
2109    ! Special conditions for strings: any kind of value is ok if we asked for
2110    ! strings
2111    IF (this%ptype == ap_string) RETURN
2112    ty = string_is(str)
2113    ! special handling for integer: they can be seen as real
2114    IF (this%ptype == ap_real) THEN
2115      IF (ty < 3)  err = error("Cannot cast value",-10)
2116    ELSE
2117      IF (ty /= this%ptype) err = error("Cannot cast value",-10)
2118    ENDIF
2119    RETURN
2120  END FUNCTION ac_check_value
2121
2122  !===========
2123  !  GETTERS
2124  !===========
2125
2126  ! argparser getters
2127  ! -----------------
2128
2129  FUNCTION ap_get_positional_sc(this,idx,value) RESULT(ret)
2130    !! Get positional arguments value at given index
2131    !! @warning
2132    !! On error, the status of `value` is undefined.
2133    OBJECT(argparser), INTENT(in)              :: this
2134      !! An argparser object reference
2135    INTEGER, INTENT(in)                        :: idx
2136      !! Subscript of the positional argument value to get
2137    CHARACTER(len=:), INTENT(out), ALLOCATABLE :: value
2138      !! Output raw value of the positional. If `idx` is out of range, `value` is set to an
2139      !! empty string.
2140    TYPE(error) :: ret
2141      !! Error object with the first error encountered in the process
2142    IF (.NOT.this%have_posal) THEN
2143      ret = error("argparse: No positional argument(s) defined",-7)
2144    ELSE IF (idx <= 0 .OR. idx > words_length(this%posals%values)) THEN
2145      ret = error("argparse: index out of range", -3)
2146    ELSE
2147      value = words_get(this%posals%values,idx)
2148      ret = noerror
2149    ENDIF
2150    RETURN
2151  END FUNCTION ap_get_positional_sc
2152
2153  FUNCTION ap_get_positional_ve(this,values) RESULT(ret)
2154    !! Get all positional arguments value
2155    !! @warning
2156    !! On error, the status of `values` is undefined.
2157    OBJECT(argparser), INTENT(in)                                  :: this
2158      !! An argparser object reference
2159    CHARACTER(len=st_slen), INTENT(out), ALLOCATABLE, DIMENSION(:) :: values
2160      !! An allocatable vector of **assumed length** strings with the value(s) of all
2161      !! positionals arguments found.
2162    TYPE(error) :: ret
2163      !! Error object with the first error encountered in the process
2164    LOGICAL :: ok
2165    ret = noerror
2166    IF (.NOT.this%have_posal) THEN
2167      ret = error("argparse: No positional argument(s) defined",-7)
2168    ELSE IF (words_length(this%posals%values) == 0) THEN
2169      ret = error("argparse: No positional argument(s) values found",-6)
2170    ELSE
2171      ok = words_to_vector(this%posals%values,values)
2172    ENDIF
2173    RETURN
2174  END FUNCTION ap_get_positional_ve
2175
2176  FUNCTION ap_get_dv_sc(this, name, output) RESULT(ret)
2177    !! Get a scalar `REAL(kind=8)` value from given argument
2178    !! The error returned by the method can be either:
2179    !! -  0  : No error
2180    !! - -1  : parser has not been initialized
2181    !! - -7  : argument not found (i.e. does not set in the parser)
2182    !! - -19 : parsing not done yet
2183    !! - -20 : (previous) parsing failed
2184    !! - -21 : inconsistent destination type
2185    !! @note
2186    !! If no error occured, the function always set a value which is the default value
2187    !! if the argument has not been parsed. Otherwise, `output` value is undefined.
2188    OBJECT(argparser), INTENT(in) :: this
2189      !! An argparser object reference
2190    CHARACTER(len=*), INTENT(in)  :: name
2191      !! Name of the argument
2192    REAL(kind=8), INTENT(out)     :: output
2193      !! A scalar with the first value of the argument
2194    TYPE(error) :: ret
2195      !! Error object with the first error encountered in the process
2196    INTEGER :: idx
2197    ret = ap_check_state(this)
2198    IF (ret == 0) THEN
2199      idx = ap_get_arg_index(this,name)
2200      IF (idx == -1) THEN
2201        ret = error("argparse: Argument not found ("//TRIM(name)//")",-7)
2202      ELSE
2203        ret = argc_get_value(this%args(idx),output)
2204      ENDIF
2205    ENDIF
2206    RETURN
2207  END FUNCTION ap_get_dv_sc
2208
2209  FUNCTION ap_get_rv_sc(this, name, output) RESULT(ret)
2210    !! Get a scalar `REAL(kind=4)` value from given argument
2211    !! The error returned by the method can be either:
2212    !! -  0  : No error
2213    !! - -1  : parser has not been initialized
2214    !! - -7  : argument not found (i.e. does not set in the parser)
2215    !! - -19 : parsing not done yet
2216    !! - -20 : (previous) parsing failed
2217    !! - -21 : inconsistent destination type
2218    !! @note
2219    !! If no error occured, the function always set a value which is the default value
2220    !! if the argument has not been parsed. Otherwise, `output` value is undefined.
2221    OBJECT(argparser), INTENT(in) :: this
2222      !! An argparser object reference
2223    CHARACTER(len=*), INTENT(in)  :: name
2224      !! Name of the argument
2225    REAL(kind=4), INTENT(out)     :: output
2226      !! A scalar with the first value of the argument
2227    TYPE(error) :: ret
2228      !! Error object with the first error encountered in the process
2229    INTEGER :: idx
2230    ret = ap_check_state(this)
2231    IF (ret == 0) THEN
2232      idx = ap_get_arg_index(this,name)
2233      IF (idx == -1) THEN
2234        ret = error("argparse: Argument not found ("//TRIM(name)//")",-7)
2235      ELSE
2236        ret = argc_get_value(this%args(idx),output)
2237      ENDIF
2238    ENDIF
2239    RETURN
2240  END FUNCTION ap_get_rv_sc
2241
2242  FUNCTION ap_get_iv_sc(this, name, output) RESULT(ret)
2243    !! Get a scalar `INTEGER` value from given argument
2244    !! The error returned by the method can be either:
2245    !! -  0  : No error
2246    !! - -1  : parser has not been initialized
2247    !! - -7  : argument not found (i.e. does not set in the parser)
2248    !! - -19 : parsing not done yet
2249    !! - -20 : (previous) parsing failed
2250    !! - -21 : inconsistent destination type
2251    !! @note
2252    !! If no error occured, the function always set a value which is the default value
2253    !! if the argument has not been parsed. Otherwise, `output` value is undefined.
2254    OBJECT(argparser), INTENT(in) :: this
2255      !! An argparser object reference
2256    CHARACTER(len=*), INTENT(in)  :: name
2257      !! Name of the argument
2258    INTEGER, INTENT(out)          :: output
2259      !! A scalar with the first value of the argument
2260    TYPE(error) :: ret
2261      !! Error object with the first error encountered in the process
2262    INTEGER :: idx
2263    ret = ap_check_state(this)
2264    IF (ret == 0) THEN
2265      idx = ap_get_arg_index(this,name)
2266      IF (idx == -1) THEN
2267        ret = error("argparse: Argument not found ("//TRIM(name)//")",-7)
2268      ELSE
2269        ret = argc_get_value(this%args(idx),output)
2270      ENDIF
2271    ENDIF
2272    RETURN
2273  END FUNCTION ap_get_iv_sc
2274
2275  FUNCTION ap_get_lv_sc(this, name, output) RESULT(ret)
2276    !! Get a scalar `LOGICAL` value from given argument
2277    !! The error returned by the method can be either:
2278    !! -  0  : No error
2279    !! - -1  : parser has not been initialized
2280    !! - -7  : argument not found (i.e. does not set in the parser)
2281    !! - -19 : parsing not done yet
2282    !! - -20 : (previous) parsing failed
2283    !! - -21 : inconsistent destination type
2284    !! @note
2285    !! If no error occured, the function always set a value which is the default value
2286    !! if the argument has not been parsed. Otherwise, `output` value is undefined.
2287    OBJECT(argparser), INTENT(in) :: this
2288      !! An argparser object reference
2289    CHARACTER(len=*), INTENT(in)  :: name
2290      !! Name of the argument
2291    LOGICAL, INTENT(out)          :: output
2292      !! A scalar with the first value of the argument
2293    TYPE(error) :: ret
2294      !! Error object with the first error encountered in the process
2295    INTEGER :: idx
2296    ret = ap_check_state(this)
2297    IF (ret == 0) THEN
2298      idx = ap_get_arg_index(this,name)
2299      IF (idx == -1) THEN
2300        ret = error("argparse: Argument not found ("//TRIM(name)//")",-7)
2301      ELSE
2302        ret = argc_get_value(this%args(idx),output)
2303      ENDIF
2304    ENDIF
2305    RETURN
2306  END FUNCTION ap_get_lv_sc
2307
2308  FUNCTION ap_get_cv_sc(this, name, output) RESULT(ret)
2309    !! Get a scalar `COMPLEX` value from given argument
2310    !! The error returned by the method can be either:
2311    !! -  0  : No error
2312    !! - -1  : parser has not been initialized
2313    !! - -7  : argument not found (i.e. does not set in the parser)
2314    !! - -19 : parsing not done yet
2315    !! - -20 : parsing failed
2316    !! - -21 : inconsistent destination type
2317    !! @note
2318    !! If no error occured, the function always set a value which is the default value
2319    !! if the argument has not been parsed. Otherwise, `output` value is undefined.
2320    OBJECT(argparser), INTENT(in) :: this
2321      !! An argparser object reference
2322    CHARACTER(len=*), INTENT(in)  :: name
2323      !! Name of the argument
2324    COMPLEX, INTENT(out)          :: output
2325      !! A scalar with the first value of the argument
2326    TYPE(error) :: ret
2327      !! Error object with the first error encountered in the process
2328    INTEGER :: idx
2329    ret = ap_check_state(this)
2330    IF (ret == 0) THEN
2331      idx = ap_get_arg_index(this,name)
2332      IF (idx == -1) THEN
2333        ret = error("argparse: Argument not found ("//TRIM(name)//")",-7)
2334      ELSE
2335        ret = argc_get_value(this%args(idx),output)
2336      ENDIF
2337    ENDIF
2338    RETURN
2339  END FUNCTION ap_get_cv_sc
2340
2341  FUNCTION ap_get_sv_sc(this, name, output) RESULT(ret)
2342    !! Get a scalar `STRING` value from given argument
2343    !! The error returned by the method can be either:
2344    !! -  0  : No error
2345    !! - -1  : parser has not been initialized
2346    !! - -7  : argument not found (i.e. does not set in the parser)
2347    !! - -19 : parsing not done yet
2348    !! - -20 : (previous) parsing failed
2349    !! - -21 : inconsistent destination type
2350    !! @note
2351    !! If no error occured, the function always set a value which is the default value
2352    !! if the argument has not been parsed. Otherwise, `output` status is undefined.
2353    OBJECT(argparser), INTENT(in)              :: this
2354      !! An argparser object reference
2355    CHARACTER(len=*), INTENT(in)               :: name
2356      !! Name of the argument
2357    CHARACTER(len=:), INTENT(out), ALLOCATABLE :: output
2358      !! An allocatable string with the first value of the argument
2359    TYPE(error) :: ret
2360      !! Error object with the first error encountered in the process
2361    INTEGER :: idx
2362    ret = ap_check_state(this)
2363    IF (ret == 0) THEN
2364      idx = ap_get_arg_index(this,name)
2365      IF (idx == -1) THEN
2366        ret = error("argparse: Argument not found ("//TRIM(name)//")",-7)
2367      ELSE
2368        ret = argc_get_value(this%args(idx),output)
2369      ENDIF
2370    ENDIF
2371    RETURN
2372  END FUNCTION ap_get_sv_sc
2373
2374  FUNCTION ap_get_dv_ve(this, name, output) RESULT(ret)
2375    !! Get a vector of `REAL(kind=8)` values from given argument
2376    !! The error returned by the method can be either:
2377    !! -  0  : No error
2378    !! - -1  : parser has not been initialized
2379    !! - -7  : argument not found (i.e. does not set in the parser)
2380    !! - -19 : parsing not done yet
2381    !! - -20 : (previous) parsing failed
2382    !! - -21 : inconsistent destination type
2383    !! @note
2384    !! If no error occured, the function always set a value which is the default value
2385    !! if the argument has not been parsed. Otherwise, `output` status is undefined.
2386    OBJECT(argparser), INTENT(in)                        :: this
2387      !! An argparser object reference
2388    CHARACTER(len=*), INTENT(in)                         :: name
2389      !! Name of the argument
2390    REAL(kind=8), INTENT(out), ALLOCATABLE, DIMENSION(:) :: output
2391      !! An allocatable vector with the values of the argument
2392    TYPE(error) :: ret
2393      !! Error object with the first error encountered in the process
2394    INTEGER :: idx
2395    ret = ap_check_state(this)
2396    IF (ret == 0) THEN
2397      idx = ap_get_arg_index(this,name)
2398      IF (idx == -1) THEN
2399        ret = error("argparse: Argument not found ("//TRIM(name)//")",-7)
2400      ELSE
2401        ret = argc_get_value(this%args(idx),output)
2402      ENDIF
2403    ENDIF
2404  END FUNCTION ap_get_dv_ve
2405
2406  FUNCTION ap_get_rv_ve(this, name, output) RESULT(ret)
2407    !! Get a vector of `REAL(kind=4)` values from given argument
2408    !! The error returned by the method can be either:
2409    !! -  0  : No error
2410    !! - -1  : parser has not been initialized
2411    !! - -7  : argument not found (i.e. does not set in the parser)
2412    !! - -19 : parsing not done yet
2413    !! - -20 : (previous) parsing failed
2414    !! - -21 : inconsistent destination type
2415    !! @note
2416    !! If no error occured, the function always set a value which is the default value
2417    !! if the argument has not been parsed. Otherwise, `output` status is undefined.
2418    OBJECT(argparser), INTENT(in)                        :: this
2419      !! An argparser object reference
2420    CHARACTER(len=*), INTENT(in)                         :: name
2421      !! Name of the argument
2422    REAL(kind=4), INTENT(out), ALLOCATABLE, DIMENSION(:) :: output
2423      !! An allocatable vector with the values of the argument
2424    TYPE(error) :: ret
2425      !! Error object with the first error encountered in the process
2426    INTEGER :: idx
2427    ret = ap_check_state(this)
2428    IF (ret == 0) THEN
2429      idx = ap_get_arg_index(this,name)
2430      IF (idx == -1) THEN
2431        ret = error("argparse: Argument not found ("//TRIM(name)//")",-7)
2432      ELSE
2433        ret = argc_get_value(this%args(idx),output)
2434      ENDIF
2435    ENDIF
2436  END FUNCTION ap_get_rv_ve
2437
2438  FUNCTION ap_get_iv_ve(this, name, output) RESULT(ret)
2439    !! Get a vector of `INTEGER` values from given argument
2440    !! The error returned by the method can be either:
2441    !! -  0  : No error
2442    !! - -1  : parser has not been initialized
2443    !! - -7  : argument not found (i.e. does not set in the parser)
2444    !! - -19 : parsing not done yet
2445    !! - -20 : (previous) parsing failed
2446    !! - -21 : inconsistent destination type
2447    !! @note
2448    !! If no error occured, the function always set a value which is the default value
2449    !! if the argument has not been parsed. Otherwise, `output` status is undefined.
2450    OBJECT(argparser), INTENT(in)                   :: this
2451      !! An argparser object reference
2452    CHARACTER(len=*), INTENT(in)                    :: name
2453      !! Name of the argument
2454    INTEGER, INTENT(out), ALLOCATABLE, DIMENSION(:) :: output
2455      !! An allocatable vector with the values of the argument
2456    TYPE(error) :: ret
2457      !! Error object with the first error encountered in the process
2458    INTEGER :: idx
2459    ret = ap_check_state(this)
2460    IF (ret == 0) THEN
2461      idx = ap_get_arg_index(this,name)
2462      IF (idx == -1) THEN
2463        ret = error("argparse: Argument not found ("//TRIM(name)//")",-7)
2464      ELSE
2465        ret = argc_get_value(this%args(idx),output)
2466      ENDIF
2467    ENDIF
2468  END FUNCTION ap_get_iv_ve
2469
2470  FUNCTION ap_get_lv_ve(this, name, output) RESULT(ret)
2471    !! Get a vector of `LOGICAL` values from given argument
2472    !! The error returned by the method can be either:
2473    !! -  0  : No error
2474    !! - -1  : parser has not been initialized
2475    !! - -7  : argument not found (i.e. does not set in the parser)
2476    !! - -19 : parsing not done yet
2477    !! - -20 : (previous) parsing failed
2478    !! - -21 : inconsistent destination type
2479    !! @note
2480    !! If no error occured, the function always set a value which is the default value
2481    !! if the argument has not been parsed. Otherwise, `output` status is undefined.
2482    OBJECT(argparser), INTENT(in)                   :: this
2483      !! An argparser object reference
2484    CHARACTER(len=*), INTENT(in)                    :: name
2485      !! Name of the argument
2486    LOGICAL, INTENT(out), ALLOCATABLE, DIMENSION(:) :: output
2487      !! An allocatable vector with the values of the argument
2488    TYPE(error) :: ret
2489      !! Error object with the first error encountered in the process
2490    INTEGER :: idx
2491    ret = ap_check_state(this)
2492    IF (ret == 0) THEN
2493      idx = ap_get_arg_index(this,name)
2494      IF (idx == -1) THEN
2495        ret = error("argparse: Argument not found ("//TRIM(name)//")",-7)
2496      ELSE
2497        ret = argc_get_value(this%args(idx),output)
2498      ENDIF
2499    ENDIF
2500  END FUNCTION ap_get_lv_ve
2501
2502  FUNCTION ap_get_cv_ve(this, name, output) RESULT(ret)
2503    !! Get a vector of `COMPLEX` values from given argument
2504    !! The error returned by the method can be either:
2505    !! -  0  : No error
2506    !! - -1  : parser has not been initialized
2507    !! - -7  : argument not found (i.e. does not set in the parser)
2508    !! - -19 : parsing not done yet
2509    !! - -20 : (previous) parsing failed
2510    !! - -21 : inconsistent destination type
2511    !! @note
2512    !! If no error occured, the function always set a value which is the default value
2513    !! if the argument has not been parsed. Otherwise, `output` status is undefined.
2514    OBJECT(argparser), INTENT(in)                   :: this
2515      !! An argparser object reference
2516    CHARACTER(len=*), INTENT(in)                    :: name
2517      !! Name of the argument
2518    COMPLEX, INTENT(out), ALLOCATABLE, DIMENSION(:) :: output
2519      !! An allocatable vector with the values of the argument
2520    TYPE(error) :: ret
2521      !! Error object with the first error encountered in the process
2522    INTEGER :: idx
2523    ret = ap_check_state(this)
2524    IF (ret == 0) THEN
2525      idx = ap_get_arg_index(this,name)
2526      IF (idx == -1) THEN
2527        ret = error("argparse: Argument not found ("//TRIM(name)//")",-7)
2528      ELSE
2529        ret = argc_get_value(this%args(idx),output)
2530      ENDIF
2531    ENDIF
2532  END FUNCTION ap_get_cv_ve
2533
2534  FUNCTION ap_get_sv_ve(this, name, output) RESULT(ret)
2535    !! Get a vector of `STRING` values from given argument
2536    !! The error returned by the method can be either:
2537    !! -  0  : No error
2538    !! - -1  : parser has not been initialized
2539    !! - -7  : argument not found (i.e. does not set in the parser)
2540    !! - -19 : parsing not done yet
2541    !! - -20 : (previous) parsing failed
2542    !! - -21 : inconsistent destination type
2543    !! @note
2544    !! If no error occured, the function always set a value which is the default value
2545    !! if the argument has not been parsed. Otherwise, `output` status is undefined.
2546    OBJECT(argparser), INTENT(in)                            :: this
2547      !! An argparser object reference
2548    CHARACTER(len=*), INTENT(in)                             :: name
2549      !! Name of the argument
2550    CHARACTER(len=*), INTENT(out), ALLOCATABLE, DIMENSION(:) :: output
2551      !! An allocatable vector of **assumed length** strings with the values of the argument
2552    TYPE(error) :: ret
2553      !! Error object with the first error encountered in the process
2554    INTEGER :: idx
2555    ret = ap_check_state(this)
2556    IF (ret == 0) THEN
2557      idx = ap_get_arg_index(this,name)
2558      IF (idx == -1) THEN
2559        ret = error("argparse: Argument not found ("//TRIM(name)//")",-7)
2560      ELSE
2561        ret = argc_get_value(this%args(idx),output)
2562      ENDIF
2563    ENDIF
2564  END FUNCTION ap_get_sv_ve
2565
2566  ! argc getters
2567  ! ------------
2568
2569  !> Gets a scalar @p REAL(kind=8) value from given argument
2570  !! @param[in,out] this An argc object
2571  !! @param[out] output A scalar with the first value of the argument
2572  !! @return An errors::error object with -21 if the destination variable's type
2573  !! is inconsistent, 0 otherwise.
2574  FUNCTION ac_get_dv_sc(this, output) RESULT(ret)
2575    !! Get a scalar `REAL(kind=8)` value from given argument
2576    !! If no error occured, the function always returns at least a value (whatever the parser's
2577    !! state is) which is the default value if no specific values are set in the argument.
2578    !! Otherwise, `output` value is undefined.
2579    TYPE(argc), INTENT(in)  :: this
2580      !! An argc object
2581    REAL(kind=8), INTENT(out) :: output
2582      !! Output value
2583    TYPE(error) :: ret
2584      !! Error object with the -21 if the destination variable's type is inconsistent, 0 otherwise
2585    ret = noerror
2586    IF (this%ptype /= ap_real) THEN
2587      ret = error("argparse: invalid type for output (expected `"// &
2588                  apt2str(this%ptype)//"' got REAL(kind=8))",-21)
2589    ELSEIF (words_length(this%values) == 0) THEN
2590      IF (.NOT.from_string(this%default,output)) &
2591        ret = error("Cannot cast value",-10)
2592    ELSE
2593      IF (.NOT.from_string(words_get(this%values,1), output)) &
2594        ret = error("Cannot cast value",-10)
2595    ENDIF
2596    RETURN
2597  END FUNCTION ac_get_dv_sc
2598
2599  FUNCTION ac_get_rv_sc(this, output) RESULT(ret)
2600    !! Get a scalar `REAL(kind=4)` value from given argument
2601    !! If no error occured, the function always returns at least a value (whatever the parser's
2602    !! state is) which is the default value if no specific values are set in the argument.
2603    !! Otherwise, `output` value is undefined.
2604    TYPE(argc), INTENT(in)    :: this
2605      !! An argc object
2606    REAL(kind=4), INTENT(out) :: output
2607      !! Output value
2608    TYPE(error) :: ret
2609      !! Error object with the first error encountered in the process
2610    ret = noerror
2611    IF (this%ptype /= ap_real) THEN
2612      ret = error("argparse: invalid type for output (expected `"// &
2613                  apt2str(this%ptype)//"' got REAL(kind=4))",-21)
2614    ELSEIF (words_length(this%values) == 0) THEN
2615      IF (.NOT.from_string(this%default,output)) &
2616        ret = error("Cannot cast value",-10)
2617    ELSE
2618      IF (.NOT.from_string(words_get(this%values,1), output)) &
2619        ret = error("Cannot cast value",-10)
2620    ENDIF
2621    RETURN
2622  END FUNCTION ac_get_rv_sc
2623
2624  FUNCTION ac_get_iv_sc(this, output) RESULT(ret)
2625    !! Get a scalar `INTEGER` value from given argument
2626    !! If no error occured, the function always returns at least a value (whatever the parser's
2627    !! state is) which is the default value if no specific values are set in the argument.
2628    !! Otherwise, `output` value is undefined.
2629    TYPE(argc), INTENT(in) :: this
2630      !! An argc object
2631    INTEGER, INTENT(out)   :: output
2632      !! Output value
2633    TYPE(error) :: ret
2634      !! Error object with the first error encountered in the process
2635    ret = noerror
2636    IF (this%ptype /= ap_integer) THEN
2637      ret = error("argparse: invalid type for output (expected `"// &
2638                  apt2str(this%ptype)//"' got INTEGER)",-21)
2639    ELSEIF (words_length(this%values) == 0) THEN
2640      IF (.NOT.from_string(this%default,output)) &
2641        ret = error("Cannot cast value",-10)
2642    ELSE
2643      IF (.NOT.from_string(words_get(this%values,1), output)) &
2644        ret = error("Cannot cast value",-10)
2645    ENDIF
2646    RETURN
2647  END FUNCTION ac_get_iv_sc
2648
2649  FUNCTION ac_get_lv_sc(this, output) RESULT(ret)
2650    !! Get a scalar `INTEGER` value from given argument
2651    !! If no error occured, the function always returns at least a value (whatever the parser's
2652    !! state is) which is the default value if no specific values are set in the argument.
2653    !! Otherwise, `output` value is undefined.
2654    TYPE(argc), INTENT(in) :: this
2655      !! An argc object
2656    LOGICAL, INTENT(out)   :: output
2657      !! Output value
2658    TYPE(error) :: ret
2659      !! Error object with the first error encountered in the process
2660    ret = noerror
2661    IF (this%ptype /= ap_logical) THEN
2662      ret = error("argparse: invalid type for output (expected `"// &
2663                  apt2str(this%ptype)//"' got LOGICAL)",-21)
2664    ELSEIF (words_length(this%values) == 0) THEN
2665      IF (.NOT.from_string(this%default,output)) &
2666        ret = error("Cannot cast value",-10)
2667    ELSE
2668      IF (.NOT.from_string(words_get(this%values,1), output)) &
2669        ret = error("Cannot cast value",-10)
2670    ENDIF
2671    RETURN
2672  END FUNCTION ac_get_lv_sc
2673
2674  FUNCTION ac_get_cv_sc(this, output) RESULT(ret)
2675    !! Get a scalar `COMPLEX` value from given argument
2676    !! If no error occured, the function always returns at least a value (whatever the parser's
2677    !! state is) which is the default value if no specific values are set in the argument.
2678    !! Otherwise, `output` value is undefined.
2679    TYPE(argc), INTENT(in) :: this
2680      !! An argc object
2681    COMPLEX, INTENT(out)   :: output
2682      !! Ouput value
2683    TYPE(error) :: ret
2684      !! Error object with the first error encountered in the process
2685    ret = noerror
2686    IF (this%ptype /= ap_complex) THEN
2687      ret = error("argparse: invalid type for output (expected `"// &
2688                  apt2str(this%ptype)//"' got COMPLEX)",-21)
2689    ELSEIF (words_length(this%values) == 0) THEN
2690      IF (.NOT.from_string(this%default,output)) &
2691        ret = error("Cannot cast value",-10)
2692    ELSE
2693      IF (.NOT.from_string(words_get(this%values,1), output)) &
2694        ret = error("Cannot cast value",-10)
2695    ENDIF
2696    RETURN
2697  END FUNCTION ac_get_cv_sc
2698
2699  FUNCTION ac_get_sv_sc(this, output) RESULT(ret)
2700    !! Get a scalar `STRING` value from given argument
2701    !! If no error occured, the function always returns at least a value (whatever the parser's
2702    !! state is) which is the default value if no specific values are set in the argument.
2703    !! Otherwise, `output` status is undefined.
2704    TYPE(argc), INTENT(in)                     :: this
2705      !! An argc object
2706    CHARACTER(len=:), INTENT(out), ALLOCATABLE :: output
2707      !! Output value
2708    TYPE(error) :: ret
2709      !! Error object with the first error encountered in the process
2710    ret = noerror
2711    IF (this%ptype /= ap_string) THEN
2712      ret = error("argparse: invalid type for output (expected `"// &
2713                  apt2str(this%ptype)//"' got STRING)",-21)
2714    ELSEIF (words_length(this%values) == 0) THEN
2715      output = this%default
2716    ELSE
2717      output = words_get(this%values,1)
2718    ENDIF
2719  END FUNCTION ac_get_sv_sc
2720
2721  FUNCTION ac_get_dv_ve(this, output) RESULT(ret)
2722    !! Get a vector of `REAL(kind=8)` values from given argument
2723    !! If no error occured, the function always returns at least a value (whatever the parser's
2724    !! state is) which is the default value if no specific values are set in the argument.
2725    !! Otherwise, `output` status is undefined.
2726    TYPE(argc), INTENT(in)                               :: this
2727      !! Argc object
2728    REAL(kind=8), INTENT(out), ALLOCATABLE, DIMENSION(:) :: output
2729      !! Output values
2730    TYPE(error) :: ret
2731      !! Error object with the first error encountered in the process
2732    CHARACTER(len=st_slen), ALLOCATABLE, DIMENSION(:) :: tmp
2733    LOGICAL                                           :: ok
2734    ret = noerror
2735    IF (this%ptype /= ap_real) THEN
2736      ret = error("argparse: invalid type for output (expected `"// &
2737                  apt2str(this%ptype)//"' got REAL(kind=8))",-21)
2738    ELSEIF (words_length(this%values) == 0) THEN
2739      ALLOCATE(output(MAX(this%nrec,1)))
2740      ok = from_string(this%default,output(1))
2741      output(1:SIZE(output)) = output(1)
2742    ELSE
2743      IF (ALLOCATED(output)) DEALLOCATE(output)
2744      ALLOCATE(output(words_length(this%values)))
2745      ok = words_to_vector(this%values,tmp)
2746      ok = from_string(tmp, output)
2747    ENDIF
2748  END FUNCTION ac_get_dv_ve
2749
2750  FUNCTION ac_get_rv_ve(this, output) RESULT(ret)
2751    !! Get a vector of `REAL(kind=4)` values from given argument
2752    !! If no error occured, the function always returns at least a value (whatever the parser's
2753    !! state is) which is the default value if no specific values are set in the argument.
2754    !! Otherwise, `output` status is undefined.
2755    TYPE(argc), INTENT(in)                               :: this
2756      !! Argc object
2757    REAL(kind=4), INTENT(out), ALLOCATABLE, DIMENSION(:) :: output
2758      !! Output values
2759    TYPE(error) :: ret
2760      !! Error object with the first error encountered in the process
2761    CHARACTER(len=st_slen), ALLOCATABLE, DIMENSION(:) :: tmp
2762    LOGICAL                                           :: ok
2763    ret = noerror
2764    IF (this%ptype /= ap_real) THEN
2765      ret = error("argparse: invalid type for output (expected `"// &
2766                  apt2str(this%ptype)//"' got REAL(kind=4))",-21)
2767    ELSEIF (words_length(this%values) == 0) THEN
2768      ALLOCATE(output(MAX(this%nrec,1)))
2769      ok = from_string(this%default,output(1))
2770      output(1:SIZE(output)) = output(1)
2771    ELSE
2772      IF (ALLOCATED(output)) DEALLOCATE(output)
2773      ALLOCATE(output(words_length(this%values)))
2774      ok = words_to_vector(this%values,tmp)
2775      ok = from_string(tmp, output)
2776    ENDIF
2777  END FUNCTION ac_get_rv_ve
2778
2779  FUNCTION ac_get_iv_ve(this, output) RESULT(ret)
2780    !! Get a vector of `INTEGER` values from given argument
2781    !! If no error occured, the function always returns at least a value (whatever the parser's
2782    !! state is) which is the default value if no specific values are set in the argument.
2783    !! Otherwise, `output` status is undefined.
2784    TYPE(argc), INTENT(in)                          :: this
2785      !! Argc object
2786    INTEGER, INTENT(out), ALLOCATABLE, DIMENSION(:) :: output
2787      !! Output values
2788    TYPE(error) :: ret
2789      !! Error object with the first error encountered in the process
2790    CHARACTER(len=st_slen), ALLOCATABLE, DIMENSION(:) :: tmp
2791    LOGICAL                                           :: ok
2792    ret = noerror
2793    IF (this%ptype /= ap_integer) THEN
2794      ret = error("argparse: invalid type for output (expected `"// &
2795                  apt2str(this%ptype)//"' got INTEGER)",-21)
2796    ELSEIF (words_length(this%values) == 0) THEN
2797      ALLOCATE(output(MAX(this%nrec,1)))
2798      ok = from_string(this%default,output(1))
2799      output(1:SIZE(output)) = output(1)
2800    ELSE
2801      IF (ALLOCATED(output)) DEALLOCATE(output)
2802      ALLOCATE(output(words_length(this%values)))
2803      ok = words_to_vector(this%values,tmp)
2804      ok = from_string(tmp, output)
2805    ENDIF
2806  END FUNCTION ac_get_iv_ve
2807
2808  FUNCTION ac_get_lv_ve(this, output) RESULT(ret)
2809    !! Get a vector of `LOGICAL` values from given argument
2810    !! If no error occured, the function always returns at least a value (whatever the parser's
2811    !! state is) which is the default value if no specific values are set in the argument.
2812    !! Otherwise, `output` status is undefined.
2813    TYPE(argc), INTENT(in)                          :: this
2814      !! Argc object
2815    LOGICAL, INTENT(out), ALLOCATABLE, DIMENSION(:) :: output
2816      !! Output values
2817    TYPE(error) :: ret
2818      !! Error object with the first error encountered in the process
2819    CHARACTER(len=st_slen), ALLOCATABLE, DIMENSION(:) :: tmp
2820    LOGICAL                                           :: ok
2821    ret = noerror
2822    IF (this%ptype /= ap_logical) THEN
2823      ret = error("argparse: invalid type for output (expected `"// &
2824                  apt2str(this%ptype)//"' got LOGICAL)",-21)
2825    ELSEIF (words_length(this%values) == 0) THEN
2826      ALLOCATE(output(MAX(this%nrec,1)))
2827      ok = from_string(this%default,output(1))
2828      output(1:SIZE(output)) = output(1)
2829    ELSE
2830      IF (ALLOCATED(output)) DEALLOCATE(output)
2831      ALLOCATE(output(words_length(this%values)))
2832      ok = words_to_vector(this%values,tmp)
2833      ok = from_string(tmp, output)
2834    ENDIF
2835  END FUNCTION ac_get_lv_ve
2836
2837  FUNCTION ac_get_cv_ve(this, output) RESULT(ret)
2838    !! Get a vector of `COMPLEX` values from given argument
2839    !! If no error occured, the function always returns at least a value (whatever the parser's
2840    !! state is) which is the default value if no specific values are set in the argument.
2841    !! Otherwise, `output` status is undefined.
2842    TYPE(argc), INTENT(in)                          :: this
2843      !! Argc object
2844    COMPLEX, INTENT(out), ALLOCATABLE, DIMENSION(:) :: output
2845      !! Output values
2846    TYPE(error) :: ret
2847      !! Error object with the first error encountered in the process
2848    CHARACTER(len=st_slen), ALLOCATABLE, DIMENSION(:) :: tmp
2849    LOGICAL                                           :: ok
2850    ret = noerror
2851    IF (this%ptype /= ap_complex) THEN
2852      ret = error("argparse: invalid type for output (expected `"// &
2853                  apt2str(this%ptype)//"' got COMPLEX)",-21)
2854    ELSEIF (words_length(this%values) == 0) THEN
2855      ALLOCATE(output(MAX(this%nrec,1)))
2856      ok = from_string(this%default,output(1))
2857      output(1:SIZE(output)) = output(1)
2858    ELSE
2859      IF (ALLOCATED(output)) DEALLOCATE(output)
2860      ALLOCATE(output(words_length(this%values)))
2861      ok = words_to_vector(this%values,tmp)
2862      ok = from_string(tmp, output)
2863    ENDIF
2864  END FUNCTION ac_get_cv_ve
2865
2866  FUNCTION ac_get_sv_ve(this, output) RESULT(ret)
2867    !! Get a vector of `STRING` values from given argument
2868    !! If no error occured, the function always returns at least a value (whatever the parser's
2869    !! state is) which is the default value if no specific values are set in the argument.
2870    !! Otherwise, `output` status is undefined.
2871    TYPE(argc), INTENT(in)                                         :: this
2872      !! Argc object
2873    CHARACTER(len=st_slen), INTENT(out), ALLOCATABLE, DIMENSION(:) :: output
2874      !! Output values
2875    TYPE(error) :: ret
2876      !! Error object with the first error encountered in the process
2877    ret = noerror
2878    IF (this%ptype /= ap_string) THEN
2879      ret = error("argparse: invalid type for output (expected `"// &
2880                  apt2str(this%ptype)//"' got STRING)",-21)
2881    ELSEIF (words_length(this%values) == 0) THEN
2882      ALLOCATE(output(MAX(this%nrec,1)))
2883      output(1:SIZE(output)) = TRIM(this%default)
2884    ELSE
2885      IF (.NOT.words_to_vector(this%values,output)) DEALLOCATE(output)
2886    ENDIF
2887  END FUNCTION ac_get_sv_ve
2888
2889  ! miscellaneous methods
2890  ! ---------------------
2891
2892  FUNCTION apt2str(ap_t) RESULT(str)
2893    !! Get the string representation of argparse types constants
2894    INTEGER, INTENT(in) :: ap_t
2895      !! One of ap_logical, ap_integer, ap_real, ap_complex or ap_string module constants.
2896    CHARACTER(len=:), ALLOCATABLE :: str
2897      !! String representation of the type.
2898    SELECT CASE(ap_t)
2899      CASE(ap_logical) ; str = 'logical'
2900      CASE(ap_integer) ; str = 'integer'
2901      CASE(ap_real)    ; str = 'real'
2902      CASE(ap_complex) ; str = 'complex'
2903      CASE(ap_string)  ; str = 'string'
2904      CASE DEFAULT     ; str = 'unknown'
2905    END SELECT
2906    RETURN
2907  END FUNCTION apt2str
2908
2909  FUNCTION apa2str(ap_a) RESULT(str)
2910    !! Get the string representation of argparse actions constants
2911    INTEGER, INTENT(in) :: ap_a
2912     !! One of ap_store, ap_append,cap_count or ap_help module constants
2913    CHARACTER(len=:), ALLOCATABLE :: str
2914      !! String representation of the action.
2915    SELECT CASE(ap_a)
2916      CASE(ap_store)  ; str = 'store'
2917      CASE(ap_append) ; str = 'append'
2918      CASE(ap_count)  ; str = 'count'
2919      CASE(ap_help)   ; str = 'help'
2920      CASE(ap_version); str = 'version'
2921      CASE DEFAULT    ; str = 'unknown'
2922    END SELECT
2923    RETURN
2924  END FUNCTION apa2str
2925
2926  FUNCTION get_progname() RESULT(name)
2927    !> Get the name of the program
2928    CHARACTER(len=:), ALLOCATABLE :: name !! The name of the program
2929    INTEGER :: c
2930    CALL GET_COMMAND_ARGUMENT(0,length=c)
2931    ALLOCATE(CHARACTER(len=c) :: name)
2932    CALL GET_COMMAND_ARGUMENT(0,value=name)
2933    c = INDEX(name, "/", back=.true.)
2934    IF (c /= 0.AND.c /= LEN_TRIM(name)) name = TRIM(name(c+1:))
2935  END FUNCTION get_progname
2936
2937END MODULE SWIFT_ARGPARSE
2938
Note: See TracBrowser for help on using the repository browser.