libSUFR
a LIBrary of Some Useful Fortran Routines
All Classes Namespaces Files Functions Variables Pages
getopt.f90
Go to the documentation of this file.
1!> \file getopt.f90 Procedures for a getopt and getopt_long implementation to parse command-line parameters in Fortran
2!!
3!! \example getopt_example.f90
4!! \example getopt_long_example.f90
5
6
7! Copyright (c) 2002-2025 Marc van der Sluys - Nikhef/Utrecht University - marc.vandersluys.nl
8!
9! This file is part of the libSUFR package,
10! see: http://libsufr.sourceforge.net/
11!
12! This is free software: you can redistribute it and/or modify it under the terms of the European Union
13! Public Licence 1.2 (EUPL 1.2). This software is distributed in the hope that it will be useful, but
14! WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15! PURPOSE. See the EU Public Licence for more details. You should have received a copy of the European
16! Union Public Licence along with this code. If not, see <https://www.eupl.eu/1.2/en/>.
17
18
19
20
21
22!***********************************************************************************************************************************
23!> \brief Procedures for a getopt and getopt_long implementation to parse command-line parameters in Fortran
24!!
25!! Getopt implementation in Fortran, similar but not identical to the GlibC implementation. Two possibilities are available:
26!! - function getopt(): parses short options only
27!! - function getopt_long(): parses short and long options
28!!
29!! Both functions return the letter of the option (e.g. 'a' for -a) and set the variable optArg which contains the argument if
30!! required and present. In addition, getopt_long() sets the variable longOption which contains the full option found (e.g.
31!! "-a" or "--all"). Both functions and variables can be accessed through the SUFR_getopt module.
32!!
33!! In addition, a quick help output can be generated (e.g. when no option, a help option or a non-existing option is given) using:
34!! - subroutine getopt_help(): prints a help list of all short options and their required arguments
35!! - subroutine getopt_long_help(): prints a help list of all short/long options, their required arguments and their descriptions
36!!
37!!
38!! \remarks
39!! This implementation of getopt was inspired by:
40!! - [1] GlibC getopt: man 3 getopt or https://www.gnu.org/software/libc/manual/html_node/Getopt.html
41!! - [2] The getopt_long_module by Joe Krahn: http://fortranwiki.org/fortran/show/getopt_long_module
42!! - [3] The getoptions module by Dominik Epple: http://www.dominik-epple.de/getoptions/
43!!
44!! The general idea comes from [1] and [2], while I followed [3] for the return values indication an issue (>!.). Unlike [3],
45!! I wanted both short and long options, allow the argument to be glued to the option (e.g. -ffile.txt) and get a warning if
46!! a required argument is missing. Unlike [2] I thought a non-OOP solution might be simpler. In addition, I wanted to allow
47!! an equal sign in e.g. --file=file.txt, and to provide a short description for each option, in order to simplify the
48!! generation of an explanatory list of options, which is provided through getopt_help() and getopt_long_help().
49
51 implicit none
52
53 integer, parameter, private :: longOptLen = 99 !< \brief Maximum length of a long option (without '--')
54
55 character :: commandline*(9999) !< \brief The full command line as a single string
56 integer :: numberofarguments = -1 !< \brief The number of *arguments* on the command line, *excluding* the command (= argc-1 in C)
57
58 character :: curarg*(999) !< \brief The current argument or option (word)
59 character :: optarg*(999) !< \brief The option's argument, if required and present
60 character :: longoption*(longoptlen+2) !< \brief The short or long option found, including leading dash(es)
61 integer, save :: optcount = 0 !< \brief The current option count
62
63 character :: getopthelpheader*(999) = '' !< \brief The header line for the message printed by getopt(_long)_help()
64 character :: getopthelpsyntax*(999) = '' !< \brief The syntax line for the message printed by getopt(_long)_help()
65 character :: getopthelpfooter*(999) = '' !< \brief The footer line for the message printed by getopt(_long)_help()
66
67 !> \brief Struct to define short and long options for getopt_long()
69 character :: short = '' !< \brief The short option (single character, without the leading dash)
70 character :: long*(longoptlen) = '' !< \brief The long option (without the leading dashes, max 99 characters long)
71 integer :: reqarg = 0 !< \brief Argument required? 0-no, 1-yes
72 character :: descr*(999) = '' !< \brief A (short) description (recommended: <1 screen width; max 999 characters)
73 end type getopt_t
74
75contains
76
77 !*********************************************************************************************************************************
78 !> \brief Parse a command-line parameter and return short options and their arguments. A warning is printed to stderr if an
79 !! argument is required but not present.
80 !!
81 !! \param optStr String defining the allowed short options. Characters followed by a colon have a required argument.
82 !! Example: 'ab:c' for -a, -b <arg> and -c.
83 !!
84 !! \retval getopt Either:
85 !! - a '>' if no further command-line parameters were found
86 !! - a '!' if an unidentified option was found
87 !! - a '.' if a non-option argument was found
88 !! - a single character identifying the short version of the option identified (without the leading dash)
89 !!
90 !! The following 'global' variables are set (accessible through the module SUFR_getopt):
91 !! - commandLine: the full command line as a single string
92 !! - curArg: the current argument or option
93 !! - optArg: the argument, if required and present
94
95 function getopt(optStr)
96 implicit none
97 character, intent(in) :: optstr*(*)
98 integer :: narg, optstri
99 character :: getopt, option
100 logical :: found
101
102
103 ! If this is the first call, get the command-line arguments, split compound short options, and save them as an array:
104 if(optcount.eq.0) then
105 call getopt_get_command()
106 end if
107
108
110
111 ! Default values:
112 getopt = ''
113 optarg = ''
114 curarg = ''
115
117
118 if(optcount.gt.narg) then
119 getopt = '>'
120 return
121 end if
122
123 call getopt_get_command_argument(optcount, curarg) ! Fetch the current argument or option
124
125 if(curarg(1:1).eq.'-') then ! Found a short option
126
127 option = curarg(2:2) ! The short-option character
128 found = .false.
129
130 do optstri=1,len(optstr) ! Loop over all defined options for a match
131 if(optstr(optstri:optstri).eq.option) then ! Current option matches character in option string
132 found = .true.
133
134 if(optstr(optstri+1:optstri+1).eq.':') then ! Option requires an argument
135 if(len_trim(curarg).gt.2) then ! Argument is glued to option (no space)
136 optarg = trim(curarg(3:))
137
138 else ! Next parameter should be an argument
139
142 if(optcount.gt.narg .or. optarg.eq.'') write(0,'(A)') 'WARNING: option -'//option//' requires an argument'
143 end if
144
145 end if ! Argument required
146
147 exit
148 end if ! Match
149 end do ! optStrI
150
151
152 if(found) then
153 getopt = option
154 else
155 getopt = '!'
156 optarg = curarg
157 end if
158
159 else ! no '-'
160
161 getopt = '.'
162 optarg = curarg
163 end if
164
165 end function getopt
166 !*********************************************************************************************************************************
167
168
169
170 !*********************************************************************************************************************************
171 !> \brief Parse a command-line parameter and return short and/or long options and their arguments. A warning is printed to
172 !! stderr if an argument is required but not present or vice versa.
173 !!
174 !! \param longopts Long-options used for getopt_long(). This is an array of getopt_t structs, each of which contains:
175 !! - short: the short option (single character, without the leading dash)
176 !! - long: the long option (without the leading dashes, max 99 characters long)
177 !! - reqArg: argument required? 0-no, 1-yes
178 !! - descr: a (short) description (recommended: <1 screen width; max 999 characters)
179 !! An example entry would be getopt_t('f','file',1,'Input file name').
180 !!
181 !! \retval getopt_long Either:
182 !! - a '>' if no further command-line parameters were found
183 !! - a '!' if an unidentified option was found
184 !! - a '.' if a non-option argument was found
185 !! - a single character identifying the short version of the option identified (without the leading dash)
186 !!
187 !! The following 'global' variables are set (accessible through the module SUFR_getopt):
188 !! - commandLine: the full command line as a single string
189 !! - curArg: the current argument or option
190 !! - longOption: the short or long option found, including leading dash(es)
191 !! - optArg: the option's argument, if required and found
192 !!
193
194 function getopt_long(longopts)
195 implicit none
196 type(getopt_t), intent(in) :: longopts(:)
197 integer :: narg, opti, pos, debug=0 ! 0-1
198 character :: getopt_long, option, longopt*(longoptlen)
199 logical :: found, haseql
200
201
202 ! If this is the first call, get the command-line arguments, split compound short options, and save them as an array:
203 if(optcount.eq.0) then
204 call getopt_get_command()
205 end if
206
207
209
210 ! Default values:
211 getopt_long = ''
212 optarg = ''
213 curarg = ''
214 longoption = ''
215
216 ! Get the current command-line parameter:
218 if(optcount.gt.narg) then
219 getopt_long = '>'
220 return
221 end if
222
223 call getopt_get_command_argument(optcount, curarg) ! Fetch the current argument or option
224 if(debug.ge.1) write(*,'(A,I0,A)') 'getopt_long(): option ', optcount, ': '//trim(curarg)
225
226
227 ! Check for long options, short options and arguments:
228 if(curarg(1:2).eq.'--') then ! Found a long option
229 longopt = trim(curarg(3:))
230
231 ! Allow for an argument connected through an equal sign, e.g. --file=file.txt
232 haseql = .false.
233 pos = scan(trim(longopt), '=')
234 if(pos.gt.0) then ! Separate option and argument
235 optarg = trim(longopt(pos+1:))
236 longopt = longopt(1:pos-1)
237 haseql = .true.
238 end if
239
240 found = .false.
241 do opti=1,size(longopts)
242 if(longopts(opti)%long.eq.longopt) then ! Current option matches character in option string
243 found = .true.
244 longoption = '--'//trim(longopt)
245 if(longopts(opti)%reqArg.gt.0 .and. .not.haseql) then ! Option requires an argument, not glued using =
246
248 call getopt_get_command_argument(optcount, optarg) ! Fetch the current argument or option
249
250 if(optcount.gt.narg .or. optarg.eq.'') write(0,'(A)') 'WARNING: option --'//option//' requires an argument'
251
252 else if(longopts(opti)%reqArg.eq.0 .and. haseql) then
253 write(0,'(A)') 'WARNING: option --'//option//' does not require an argument'
254 end if
255
256 exit
257 end if
258 end do
259
260 if(found) then
261 getopt_long = longopts(opti)%short
262 else
263 getopt_long = '!'
264 optarg = curarg
265 end if
266
267
268 else if(curarg(1:1).eq.'-') then ! Short option
269 option = curarg(2:2)
270
271 found = .false.
272 do opti=1,size(longopts)
273 if(longopts(opti)%short.eq.option) then ! Current option matches character in option string
274 found = .true.
275 longoption = '-'//option
276 if(longopts(opti)%reqArg.gt.0) then ! Option requires an argument
277 if(len_trim(curarg).gt.2) then ! Argument is glued to option (no space)
278 optarg = trim(curarg(3:))
279
280 else ! Next parameter should be argument
281
283 call getopt_get_command_argument(optcount, optarg) ! Fetch the current argument or option
284
285 if(optcount.gt.narg .or. optarg.eq.'') write(0,'(A)') 'WARNING: option -'//option//' requires an argument'
286
287 end if
288 end if ! Argument
289
290 exit
291 end if
292 end do
293
294 if(found) then
295 getopt_long = option
296 else
297 getopt_long = '!'
298 optarg = curarg
299 end if
300
301 else ! no '-'
302
303 getopt_long = '.'
304 optarg = curarg
305 end if
306
307 if(debug.ge.1) write(*,'(2(A,I0))') 'optCount: ',optcount, ' -> ', optcount+1
308
309 end function getopt_long
310 !*********************************************************************************************************************************
311
312
313
314 !*********************************************************************************************************************************
315 !> \brief Get the full command line in a string, split compound short options (e.g. "-abc" -> "-a -b -c") and set numberOfArguments.
316
318 use sufr_text, only: count_substring
319
320 implicit none
321
322 call get_command(commandline) ! Fetch the complete command line as a single string
323 call getopt_split_short_options(commandline) ! Split compound short options into separate ones (e.g. " -abc" -> " -a -b -c")
324
325 numberofarguments = count_substring(trim(commandline), ' ') ! Number of internal spaces = number of arguments, excluding the command
326
327 end subroutine getopt_get_command
328 !*********************************************************************************************************************************
329
330
331 !*********************************************************************************************************************************
332 !> \brief Return the number of arguments on the command line (excluding the command).
333 !!
334 !! \retval getopt_command_argument_count Number of *arguments* excluding the command
335
337 implicit none
339
340 if(numberofarguments.lt.0) call getopt_get_command() ! If still at initialised -1, read the command line now
341 getopt_command_argument_count = numberofarguments ! Note: number of *arguments* excluding the command, like Fortran's command_argument_count()
342
344 !*********************************************************************************************************************************
345
346
347 !*********************************************************************************************************************************
348 !> \brief Returns the argNr-th command-line argument or option.
349 !!
350 !! \param argNr Number of the desired argument
351 !!
352 !! \param arg Content of the desired argument (a word/string)
353
354 subroutine getopt_get_command_argument(argNr, arg)
356 use sufr_text, only: int2str
357
358 implicit none
359 integer, intent(in) :: argNr
360 character, intent(out) :: arg*(99)
361 integer :: iArg, in,din
362
363 if(numberofarguments.lt.0) call getopt_get_command() ! If still at initialised -1, read the command line now
364
365 if(argnr.gt.numberofarguments) call quit_program_error('getopt_get_command_argument(): the argument number ('//int2str(argnr)// &
366 ') must be smaller than or equal to the total number of arguments ('//int2str(numberofarguments)//').', 1)
367
368 in = 1
369 do iarg=0,argnr ! Starting with the command (iArg=0), loop up to the desired argument
370 din = index(commandline(in:), ' ') ! Find the iArg+1-th space, which precedes the iArg+1-th argument
371 arg = trim(commandline(in:in+din-2)) ! Save the current argument as the return value. If the loop finishes, this becomes the return value
372 in = in + din ! In the next iteration, start with the next space
373 end do
374
375 end subroutine getopt_get_command_argument
376 !*********************************************************************************************************************************
377
378
379 !*********************************************************************************************************************************
380 !> \brief Extract and return an integer value from the argument optArg. On error, report and abort.
381 !!
382 !! \param minValue Minimum acceptable value for this argument (optional).
383 !! \param maxValue Maximum acceptable value for this argument (optional).
384 !!
385 !! \retval getopt_optarg_to_int The integer value of the argument
386
387 function getopt_optarg_to_int(minValue, maxValue)
389 use sufr_text, only: int2str
390
391 implicit none
392 integer :: getopt_optarg_to_int, status
393 integer, intent(in), optional :: minvalue,maxvalue
394
395 ! Read the value from the string, and monitor the output status:
396 read(optarg,*, iostat=status) getopt_optarg_to_int
397
398 ! In case of probem, report the error and abort the program:
399 if(status.ne.0) call quit_program_error('Error: '//trim(optarg)//' is an invalid integer value as the argument of option '//trim(longoption)//', aborting.', 1)
400
401 ! Check value boundaries if desired:
402 if(present(minvalue)) then
403 if(getopt_optarg_to_int.lt.minvalue) call quit_program_error('Error: the argument of option '//trim(longoption)//' is '//trim(optarg)// &
404 ', but should not be lower than '//int2str(minvalue)//', aborting.', 1)
405 end if
406
407 if(present(maxvalue)) then
408 if(getopt_optarg_to_int.gt.maxvalue) call quit_program_error('Error: the argument of option '//trim(longoption)//' is '//trim(optarg)// &
409 ', but should not be higher than '//int2str(maxvalue)//', aborting.', 1)
410 end if
411
412 end function getopt_optarg_to_int
413 !*********************************************************************************************************************************
414
415
416 !*********************************************************************************************************************************
417 !> \brief Extract and return a real value from the argument optArg. On error, report and abort.
418 !!
419 !! \param minValue Minimum acceptable value for this argument (optional).
420 !! \param maxValue Maximum acceptable value for this argument (optional).
421 !!
422 !! \retval getopt_optarg_to_real The real value of the argument
423
424 function getopt_optarg_to_real(minValue, maxValue)
426 use sufr_text, only: real2str
427
428 implicit none
430 real, intent(in), optional :: minvalue,maxvalue
431 integer :: status
432
433 ! Read the value from the string, and monitor the output status:
434 read(optarg,*, iostat=status) getopt_optarg_to_real
435
436 ! In case of probem, report the error and abort the program:
437 if(status.ne.0) call quit_program_error('Error: '//trim(optarg)//' is an invalid value as the argument of option '//trim(longoption)//', aborting.', 1)
438
439 ! Check value boundaries if desired:
440 if(present(minvalue)) then
441 if(getopt_optarg_to_real.lt.minvalue) call quit_program_error('Error: the argument of option '//trim(longoption)//' is '//trim(optarg)// &
442 ', but should not be lower than '//real2str(minvalue, len_trim(optarg))//', aborting.', 1)
443 end if
444
445 if(present(maxvalue)) then
446 if(getopt_optarg_to_real.gt.maxvalue) call quit_program_error('Error: the argument of option '//trim(longoption)//' is '//trim(optarg)// &
447 ', but should not be higher than '//real2str(maxvalue, len_trim(optarg))//', aborting.', 1)
448 end if
449
450 end function getopt_optarg_to_real
451 !*********************************************************************************************************************************
452
453
454 !*********************************************************************************************************************************
455 !> \brief Extract and return a double value from the argument optArg. On error, report and abort.
456 !!
457 !! \param minValue Minimum acceptable value for this argument (optional).
458 !! \param maxValue Maximum acceptable value for this argument (optional).
459 !!
460 !! \retval getopt_optarg_to_dbl The integer value of the argument
461
462 function getopt_optarg_to_dbl(minValue, maxValue)
463 use sufr_kinds, only: double
465 use sufr_text, only: dbl2str
466
467 implicit none
469 real(double), intent(in), optional :: minvalue,maxvalue
470 integer :: status
471
472 ! Read the value from the string, and monitor the output status:
473 read(optarg,*, iostat=status) getopt_optarg_to_dbl
474
475 ! In case of probem, report the error and abort the program:
476 if(status.ne.0) call quit_program_error('Error: '//trim(optarg)//' is an invalid value as the argument of option '//trim(longoption)//', aborting.', 1)
477
478 ! Check value boundaries if desired:
479 if(present(minvalue)) then
480 if(getopt_optarg_to_dbl.lt.minvalue) call quit_program_error('Error: the argument of option '//trim(longoption)//' is '//trim(optarg)// &
481 ', but should not be lower than '//dbl2str(minvalue, len_trim(optarg))//', aborting.', 1)
482 end if
483
484 if(present(maxvalue)) then
485 if(getopt_optarg_to_dbl.gt.maxvalue) call quit_program_error('Error: the argument of option '//trim(longoption)//' is '//trim(optarg)// &
486 ', but should not be higher than '//dbl2str(maxvalue, len_trim(optarg))//', aborting.', 1)
487 end if
488
489 end function getopt_optarg_to_dbl
490 !*********************************************************************************************************************************
491
492
493 !*********************************************************************************************************************************
494 !> \brief Split combined short command-line options into several individual ones, e.g. "... -abc ..." -> "... -a -b -c ..."
495 !!
496 !! \param CLoptStr String containing (all) command-line options (I/O).
497
498 subroutine getopt_split_short_options(CLoptStr)
499 use sufr_dummy, only: dumdbl
500
501 implicit none
502 character, intent(inout) :: CLoptStr*(*)
503 integer :: iArg, in1,din, status, iChar,nChar, lverbose
504 character :: subStr*(99),newSubStr*(99)
505
506 iarg = 0
507 in1 = 1
508 din = 1
509 lverbose = 0
510
511 do while(din.ge.0)
512 din = index(trim(cloptstr(in1:)), ' ') - 1 ! Issue, since trim is used, a final compound of short options will never be found ("... -abc")
513
514 if(lverbose.gt.0) then
515 print*
516 write(*,'(A,3I5, A50)') 'iArg: ',iarg,in1,din,'###'//trim(cloptstr(in1:))//'###'
517 print*,len_trim(cloptstr),in1,din,len_trim(cloptstr(in1:)), in1+len_trim(cloptstr(in1:))-1
518 end if
519
520 if(din.lt.0 .and. in1+len_trim(cloptstr(in1:))-1.eq.len_trim(cloptstr)) din = len_trim(cloptstr(in1:)) ! Last argument on command line
521
522 if(din.ge.0) then
523 substr = cloptstr(in1:in1+din) ! Isolate a single argument
524
525 ! Verify whether this argument is a compound short option (>2 characters long, starting with a single dash, and not a negative number):
526 if(len_trim(substr).gt.2) then ! Argument contains >2 characters
527 if(substr(1:1) .eq. '-') then ! Argument is an option (starts with dash)
528 if(.not.substr(1:2) .eq. '--') then ! Argument is a LONG option (starts with --)
529 read(substr,*, iostat=status) dumdbl
530 if(status.ne.0) then ! Argument is not a negative number
531
532 ! When arrived here, the current argument is an option with >2 characters, not a long option and and not a negative number, hence must be (?) a compound short option
533 if(lverbose.gt.0) write(*,'(A,4I5,2A25)') ' New group: ', iarg,in1,din,status, '###'//cloptstr(in1:in1+din-1)//'###', '###'//substr(1:din)//'###'
534
535
536 nchar = len_trim(substr)
537 newsubstr = ''
538 do ichar=2,nchar
539 newsubstr = trim(newsubstr)//' -'//substr(ichar:ichar)
540 end do
541 if(lverbose.gt.0) print*,'New substring: ###'//trim(newsubstr)//'###'
542
543 cloptstr = cloptstr(1:in1-2)//trim(newsubstr)//trim(cloptstr(in1+din:)) ! -2: remove dash and first character. CLoptStr(in1+din) contains space.
544 in1 = in1-2 + len_trim(newsubstr) - din ! - din, since this will be added below
545 end if
546 end if
547 end if
548 end if
549
550
551 ! Prepare for the next iteration:
552 iarg = iarg+1
553 in1 = in1+din+1 ! Until after the current space
554 end if
555 end do
556
557 end subroutine getopt_split_short_options
558 !*********************************************************************************************************************************
559
560
561 !*********************************************************************************************************************************
562 !> \brief Print a help list of all short options and their required arguments
563 !!
564 !! \param optStr Short-options string used for getopt()
565 !! \param lineBef Number of lines to print before option list (default: 0)
566 !! \param lineAft Number of lines to print after option list (default: 0)
567 !!
568 !! \note If the string variables getoptHelpHeader, getoptHelpSyntax or getoptHelpFooter are set, a header,
569 !! syntax or footer line is printed in addition to the options. By default, the strings are empty and the
570 !! lines are not printed.
571
572
573 subroutine getopt_help(optStr, lineBef,lineAft)
575 implicit none
576 character, intent(in) :: optStr*(*)
577 integer, intent(in), optional :: lineBef, lineAft
578 character :: curChar
579 integer :: iLine,iChar
580
581 ! Print empty lines:
582 if(present(linebef)) then
583 if(linebef.gt.0) then
584 do iline=1,linebef
585 write(*,*)
586 end do
587 end if
588 end if
589
590 ! Print header:
591 if(getopthelpheader.ne.'') then
592 write(*,'(A)') trim(program_name)//': '//trim(getopthelpheader)
593 end if
594
595 ! Print syntax:
596 if(getopthelpsyntax.ne.'') then
597 write(*,'(A)') 'Syntax: '//trim(program_name)//' '//trim(getopthelpsyntax)
598 end if
599
600 write(*,'(A)', advance='no') 'Available options: '
601 do ichar=1,len_trim(optstr)
602 curchar = optstr(ichar:ichar)
603
604 if(curchar.eq.':') then
605 write(*,'(A)', advance='no') ' <arg>'
606 else
607 if(ichar.gt.1) write(*,'(A)', advance='no') ','
608 write(*,'(A)', advance='no') ' -'//curchar
609 end if
610 end do
611 write(*,'(A)') '.'
612
613 ! Print footer:
614 if(getopthelpfooter.ne.'') then
615 write(*,'(A)') trim(getopthelpfooter)
616 end if
617
618 ! Print empty lines:
619 if(present(lineaft)) then
620 if(lineaft.gt.0) then
621 do iline=1,lineaft
622 write(*,*)
623 end do
624 end if
625 end if
626
627 end subroutine getopt_help
628 !*********************************************************************************************************************************
629
630
631 !*********************************************************************************************************************************
632 !> \brief Print a help list of all short/long options, their required arguments and their descriptions
633 !!
634 !! \param longopts Long-options struct used for getopt_long()
635 !! \param lineBef Number of lines to print before option list (default: 0)
636 !! \param lineAft Number of lines to print after option list (default: 0)
637 !!
638 !! \note If the string variables getoptHelpHeader, getoptHelpSyntax or getoptHelpFooter are set, a header,
639 !! syntax or footer line is printed in addition to the options. By default, the strings are empty and the
640 !! lines are not printed.
641
642 subroutine getopt_long_help(longopts, lineBef, lineAft)
644 implicit none
645 type(getopt_t), intent(in) :: longopts(:)
646 integer, intent(in), optional :: lineBef, lineAft
647 type(getopt_t) :: curOpt
648 integer :: iLine, iOpt, nChar, iSpc
649
650 ! Print empty lines:
651 if(present(linebef)) then
652 if(linebef.gt.0) then
653 do iline=1,linebef
654 write(*,*)
655 end do
656 end if
657 end if
658
659 ! Print header:
660 if(getopthelpheader.ne.'') then
661 write(*,'(A)') trim(program_name)//': '//trim(getopthelpheader)
662 write(*,*)
663 end if
664
665 ! Print syntax:
666 if(getopthelpsyntax.ne.'') then
667 write(*,'(A)') 'Syntax: '//trim(program_name)//' '//trim(getopthelpsyntax)
668 write(*,*)
669 end if
670
671 write(*,'(A)') 'Available options:'
672 do iopt=1,size(longopts)
673 curopt = longopts(iopt)
674
675 nchar = 0
676 ! Print short option if defined:
677 if(trim(curopt%short).ne.'') then
678 write(*,'(A4)', advance='no') ' -'//curopt%short
679 nchar = nchar + 4
680 end if
681
682 ! Print long option if defined:
683 if(trim(curopt%long).ne.'') then
684 write(*,'(A)', advance='no') ' --'//trim(curopt%long)
685 nchar = nchar + len_trim(curopt%long) + 3 ! max: 99+3 = 102
686 end if
687
688 ! Print argument if required:
689 if(curopt%reqArg.gt.0) then
690 write(*,'(A7)', advance='no') ' <arg>'
691 nchar = nchar + 7
692 end if
693
694 ! Justify description using spaces:
695 do ispc=1,30-nchar
696 write(*,'(1x)', advance='no')
697 end do
698
699 ! Print description:
700 write(*,'(5x,A)') trim(curopt%descr)
701 end do
702
703 ! Print footer:
704 if(getopthelpfooter.ne.'') then
705 write(*,*)
706 write(*,'(A)') trim(getopthelpfooter)
707 end if
708
709 ! Print empty lines:
710 if(present(lineaft)) then
711 if(lineaft.gt.0) then
712 do iline=1,lineaft
713 write(*,*)
714 end do
715 end if
716 end if
717
718 end subroutine getopt_long_help
719 !*********************************************************************************************************************************
720
721
722end module sufr_getopt
723!***********************************************************************************************************************************
Provides all constants in the library, and routines to define them.
Definition constants.f90:23
character, dimension(199), public program_name
Name of the currently running program, without the path.
Module containing dummy variables for all kinds.
real(double) dumdbl
Dummy double.
Procedures for a getopt and getopt_long implementation to parse command-line parameters in Fortran.
Definition getopt.f90:50
subroutine getopt_get_command_argument(argnr, arg)
Returns the argNr-th command-line argument or option.
Definition getopt.f90:355
real function getopt_optarg_to_real(minvalue, maxvalue)
Extract and return a real value from the argument optArg. On error, report and abort.
Definition getopt.f90:425
character, dimension(999) optarg
The option's argument, if required and present.
Definition getopt.f90:59
character, dimension(999) getopthelpheader
The header line for the message printed by getopt(_long)_help()
Definition getopt.f90:63
integer, save optcount
The current option count.
Definition getopt.f90:61
integer numberofarguments
The number of arguments on the command line, excluding the command (= argc-1 in C)
Definition getopt.f90:56
character, dimension(longoptlen+2) longoption
The short or long option found, including leading dash(es)
Definition getopt.f90:60
character, dimension(999) getopthelpfooter
The footer line for the message printed by getopt(_long)_help()
Definition getopt.f90:65
subroutine getopt_long_help(longopts, linebef, lineaft)
Print a help list of all short/long options, their required arguments and their descriptions.
Definition getopt.f90:643
integer function getopt_optarg_to_int(minvalue, maxvalue)
Extract and return an integer value from the argument optArg. On error, report and abort.
Definition getopt.f90:388
subroutine getopt_split_short_options(cloptstr)
Split combined short command-line options into several individual ones, e.g. "... -abc ....
Definition getopt.f90:499
character function getopt(optstr)
Parse a command-line parameter and return short options and their arguments. A warning is printed to ...
Definition getopt.f90:96
character function getopt_long(longopts)
Parse a command-line parameter and return short and/or long options and their arguments....
Definition getopt.f90:195
real(double) function getopt_optarg_to_dbl(minvalue, maxvalue)
Extract and return a double value from the argument optArg. On error, report and abort.
Definition getopt.f90:463
subroutine getopt_get_command()
Get the full command line in a string, split compound short options (e.g. "-abc" -> "-a -b -c") and s...
Definition getopt.f90:318
subroutine getopt_help(optstr, linebef, lineaft)
Print a help list of all short options and their required arguments.
Definition getopt.f90:574
character, dimension(999) curarg
The current argument or option (word)
Definition getopt.f90:58
character, dimension(999) getopthelpsyntax
The syntax line for the message printed by getopt(_long)_help()
Definition getopt.f90:64
integer function getopt_command_argument_count()
Return the number of arguments on the command line (excluding the command).
Definition getopt.f90:337
character, dimension(9999) commandline
The full command line as a single string.
Definition getopt.f90:55
Provides kinds and related constants/routines.
Definition kinds.f90:26
integer, parameter double
Double-precision float. Precision = 15, range = 307.
Definition kinds.f90:35
System-related procedures.
Definition system.f90:23
subroutine quit_program_error(message, status)
Print an error message to StdErr and stop the execution of the current program.
Definition system.f90:78
Procedures to manipulate text/strings.
Definition text.f90:21
integer function count_substring(string, substr)
Count how many times a substring is present in a string.
Definition text.f90:271
pure character function, dimension(sign(1, floor(number)) -1) real2str(number, decim, mark)
Convert a single-precision real to a nice character string. Single-precision wrapper for dbl2str.
Definition text.f90:573
pure character function, dimension(sign(1_long, floor(number, long)) -1) dbl2str(number, decim, mark)
Convert a double-precision real to a nice character string. Difference with the F0 format descriptor:...
Definition text.f90:455
pure character function, dimension(sign(1, number) -1) int2str(number)
Convert an integer to a character string of the proper length.
Definition text.f90:435
Struct to define short and long options for getopt_long()
Definition getopt.f90:68