gtool5 Fortran 90/95 Library 1.0.0-rc5
日本語
Loading...
Searching...
No Matches
dc_args.f90
Go to the documentation of this file.
1!-----------------------------------------------------------------------
2! Copyright (c) 2000-2026 Gtool Development Group. All rights reserved.
3!-----------------------------------------------------------------------
4!>
5!> @author Youhei SASAKI, Yasuhiro MORIKAWA
6!> @copyright Copyright (C) GFD Dennou Club, 2005-2026. All rights reserved. <br/>
7!> License is BSD-2-Clause. see [COPYRIGHT](@ref COPYRIGHT) in detail
8!> @en
9!> @brief Command line arguments parser
10!> @details
11!> This module parses command line arguments.
12!>
13!> In addition, convenient subroutines for displaying help messages
14!> are provided.
15!>
16!> @section args_tutorial Tutorial
17!>
18!> - gtool5 Official Tutorial:
19!> @ref tutorial_dc_args "Command Line Arguments Parsing"
20!>
21!> @section args_procedures Procedures list
22!>
23!> | Procedure | Description |
24!> |----------------|----------------------------------------------------------|
25!> | DCArgsOpen | Initialize ARGS derived type variable |
26!> | DCArgsClose | Finalize ARGS derived type variable |
27!> | DCArgsGet | Get command line arguments |
28!> | DCArgsNumber | Return number of command line arguments |
29!> | DCArgsOption | Configure for getting command line option |
30!> | DCArgsDebug | Auto-configure debug option |
31!> | DCArgsHelp | Auto-configure help option |
32!> | DCArgsHelpMsg | Configure help message |
33!> | DCArgsStrict | Configure to show warning when invalid option is given |
34!> | DCArgsPutLine | Print contents of ARGS derived type variable |
35!>
36!> @enden
37!>
38!> @ja
39!> @brief コマンドライン引数の解析
40!> @details
41!> コマンドライン引数の解析を行います.
42!>
43!> 加えて, ヘルプメッセージの表示に関して便利なサブルーチンも
44!> 用意しています.
45!>
46!> @section args_tutorial_ja チュートリアル
47!>
48!> - gtool5 オフィシャルチュートリアル:
49!> @ref tutorial_dc_args "コマンドライン引数の解析"
50!>
51!> @section args_procedures_ja 手続一覧
52!>
53!> | 手続名 | 説明 |
54!> |----------------|----------------------------------------------------------|
55!> | DCArgsOpen | 構造型 ARGS 変数の初期化 |
56!> | DCArgsClose | 構造型 ARGS 変数の終了処理 |
57!> | DCArgsGet | コマンドライン引数の取得 |
58!> | DCArgsNumber | コマンドライン引数の数を返す |
59!> | DCArgsOption | コマンドライン引数オプションを取得するための設定 |
60!> | DCArgsDebug | デバッグオプションの自動設定 |
61!> | DCArgsHelp | ヘルプオプションの自動設定 |
62!> | DCArgsHelpMsg | ヘルプメッセージの設定 |
63!> | DCArgsStrict | 無効なオプションが指定された時に警告を表示するよう設定 |
64!> | DCArgsPutLine | 構造型 ARGS 変数の内容を印字 |
65!>
66!> @section args_usage_ja 使用方法
67!>
68!> 構造型 ARGS の変数を定義し, Open, Get を利用することで
69!> コマンドライン引数を取得することができます.
70!>
71!> @code{.f90}
72!> program dc_args_sample1
73!> use dc_types
74!> use dc_string, only: StoA
75!> use dc_args
76!> implicit none
77!> type(ARGS) :: arg
78!> character(STRING), pointer :: argv(:) => null()
79!> integer :: i
80!>
81!> call DCArgsOpen( arg = arg ) ! (out)
82!> call DCArgsDebug( arg = arg ) ! (inout)
83!> call DCArgsHelp( arg = arg ) ! (inout)
84!> call DCArgsStrict( arg = arg ) ! (inout)
85!> call DCArgsGet( arg = arg, argv = argv )
86!> do i = 1, size( argv )
87!> write(*,*) argv(i)
88!> end do
89!> deallocate( argv )
90!> call DCArgsClose( arg = arg ) ! (inout)
91!> end program dc_args_sample1
92!> @endcode
93!>
94!> 引数にオプションを指定したい場合には, DCArgsOption サブルーチンを
95!> 利用してください. オプションの書式に関しては DCArgsOption の
96!> 「オプションの書式」を参照してください.
97!>
98!> @code{.f90}
99!> program dc_args_sample2
100!> use dc_types
101!> use dc_string, only: StoA
102!> use dc_args
103!> implicit none
104!> type(ARGS) :: arg
105!> logical :: OPT_size
106!> logical :: OPT_namelist
107!> character(STRING) :: VAL_namelist
108!>
109!> call DCArgsOpen( arg = arg )
110!> call DCArgsOption( arg = arg, options = StoA('-s', '--size'), &
111!> & flag = OPT_size, help = "Return number of arguments")
112!> call DCArgsOption( arg = arg, options = StoA('-N', '--namelist'), &
113!> & flag = OPT_namelist, value = VAL_namelist, help = "Namelist filename")
114!>
115!> call DCArgsDebug( arg = arg )
116!> call DCArgsHelp( arg = arg )
117!> call DCArgsStrict( arg = arg )
118!>
119!> if (OPT_size) then
120!> write(*,*) 'number of arguments :: ', DCArgsNumber(arg)
121!> end if
122!> if (OPT_namelist) then
123!> write(*,*) '--namelist=', trim(VAL_namelist)
124!> else
125!> write(*,*) '--namelist is not found'
126!> end if
127!> call DCArgsClose( arg = arg )
128!> end program dc_args_sample2
129!> @endcode
130!>
131!> コマンドライン引数に '-h', '-H', '--help' のいづれかのオプションを
132!> 指定することで, オプションの一覧が標準出力に表示されます.
133!>
134!> ヘルプメッセージの内容を充実させたい場合には DCArgsHelpMsg を
135!> 参照してください.
136!>
137!> @note 後方互換
138!>
139!> バージョン 20071009 以前に利用可能だった以下の手続きは,
140!> 後方互換のため, しばらくは利用可能です.
141!>
142!> - Open, Close, Option, PutLine, Debug, Help, HelpMsg, Strict, Get, Number
143!>
144!> @endja
145!>
146!> @note dc_args モジュールを作成した理由について
147!>
148!> Fortran コンパイラのほとんどには IARGC, GETARG といった
149!> コマンドライン引数取得のための副プログラムが用意されている.
150!> これらの副プログラムの利用によって, コマンドラインの引数を
151!> 単に取得することは簡単である.
152!>
153!> しかしこの IARGC, GETARG の使用に際し, 2 つほど面倒な点がある.
154!>
155!> 1 つはコンパイラ依存による IARGC, GETARG の仕様の違いである.
156!> これらの副プログラムは Fortran 規格に含まれないサービスルーチン
157!> であるため, たいていのコンパイラにはこの副プログラムは
158!> 存在するものの, 仕様が微妙に異なる場合がある. (大抵のコンパイラは
159!> GETARG の第一引数を 1 にすると一つ目の引数を取得するが,
160!> 古い HITACHI のコンパイラは第一引数を 2 にしないと一つ目の
161!> 引数を取得できない, など). そこで gtool5 ライブラリでは
162!> これらのコンパイラ依存性を吸収する設計を行っている.
163!> dc_args モジュールを使用する際には, これらのコンパイラ依存は
164!> 気にしなくてよい. (なお, コンパイラ依存性を実際に
165!> 吸収しているのは sysdep モジュールである).
166!>
167!> 2 つ目は, コマンドライン引数におけるオプション引数
168!> (-h や --version など) の取り扱いの不便さである.
169!> IARGC や GETARG は単に引数を取得するための副プログラムであり,
170!> Perl や Ruby などのインタプリタ言語のように,
171!> コマンドライン引数にオプション引数を処理するための
172!> ライブラリ (Getopt や OptionParser など) が用意されていない.
173!> dc_args モジュールは, Fortran プログラムでもオプション引数を
174!> 手軽に扱えるよう, オプション引数処理の
175!> ためのコーディングをできるだけ簡素にするべく整備したプログラムである.
176!>
177!> 設計思想は, Ruby の OptionParser を真似ており,
178!> OptionParser クラスのオブジェクトを構造型 ARGS に,
179!> new (initialize) メソッドを DCArgsOpen サブルーチンに,
180!> on メソッドを DCArgsOption サブルーチンに, parse メソッドを DCArgsGet
181!> サブルーチンに見立てている. 言語仕様の違いにより実装や仕様は
182!> それなりに異なるが, 構造型 ARGS の変数をオブジェクトに見立て,
183!> この変数に対してサブルーチンを作用させることによって
184!> オブジェクトへの操作やオブジェクトからの引数情報の取得を行うという点では
185!> OptionParser と同様である.
186!>
187!> おまけ的機能であるが, dc_trace モジュールとの連携も図られており,
188!> Debug サブルーチンを使用することにより (使用法は上記参照), 再コン
189!> パイルすることなく, プログラムの実行の際に "-D" オプションをつける
190!> ことでデバッグメッセージを表示するモードに変更することもできる.
191!>
192
194 use dc_types, only : string
195 use dc_hash, only: hash
196 implicit none
197 private
198
199 public:: args
203 public:: dcargsnumber
204
205 !-----------------------------------------------
206 ! 後方互換用
207 ! For backward compatibility
208 public:: Open, Close, option, putline, debug, help, helpmsg, strict, get
209 public:: number
210
211 !> @en
212 !> @brief Derived type for command line argument parsing
213 !> @details
214 !> Use DCArgsOpen for initialization and DCArgsClose for finalization.
215 !> Stores arguments given in command line and information given by
216 !> DCArgsOption and DCArgsHelpMsg subroutines within the program.
217 !>
218 !> See dc_args Usage for detailed usage.
219 !> @enden
220 !>
221 !> @ja
222 !> @brief コマンドライン引数解析用の構造型
223 !> @details
224 !> 初期化には DCArgsOpen を, 終了処理には DCArgsClose を用います.
225 !> コマンドライン引数に与えられる引数や, プログラム内で
226 !> DCArgsOption, DCArgsHelpMsg サブルーチンによって与えられた情報を
227 !> 格納します.
228 !>
229 !> 詳しい使い方は dc_args の Usage を参照ください.
230 !> @endja
231 type args
232 private
233 type(OPT_ENTRY), pointer :: opt_table(:) => null()
234 !< @en List of options specified by DCArgsOption subroutine @enden
235 !< @ja DCArgsOption サブルーチンで指定されるオプションのリスト @endja
236 logical :: initialized = .false.
237 !< @en Initialization flag @enden
238 !< @ja 初期化フラグ @endja
239 type(cmd_opts_internal), pointer :: cmd_opts_list(:) => null()
240 !< @en List of items identified as options among command line arguments @enden
241 !< @ja コマンドライン引数のうち, オプションとして識別されるもののリスト @endja
242 type(hash) :: helpmsg
243 !< @en Help message hash @enden
244 !< @ja ヘルプメッセージハッシュ @endja
245 end type args
246
247 !> @en
248 !> @brief Internal type for option entry
249 !> @enden
250 !> @ja
251 !> @brief オプションエントリ用内部型
252 !> @endja
253 type opt_entry
254 character(STRING), pointer:: options(:) => null()
255 !< @en List of option names @enden
256 !< @ja オプション名リスト @endja
257 character(STRING) :: help_message
258 !< @en Help message @enden
259 !< @ja ヘルプメッセージ @endja
260 logical :: optvalue_flag
261 !< @en Flag for presence of option value @enden
262 !< @ja オプションの値の有無 @endja
263 end type opt_entry
264
265 !> @en
266 !> @brief Internal type for command line options
267 !> @enden
268 !> @ja
269 !> @brief コマンドラインオプション用内部型
270 !> @endja
271 type cmd_opts_internal
272 character(STRING) :: name
273 !< @en Option name @enden
274 !< @ja オプション名 @endja
275 character(STRING) :: value
276 !< @en Option value @enden
277 !< @ja 値 @endja
278 logical:: flag_called = .false.
279 !< @en Flag to determine if this option name was called by DCArgsOption @enden
280 !< @ja このオプション名が DCArgsOption で呼ばれたものかどうかを判別するフラグ @endja
281 end type cmd_opts_internal
282
283 interface dcargsopen
284 module procedure dcargsopen0
285 end interface
286
287 interface dcargsclose
288 module procedure dcargsclose0
289 end interface
290
291 interface dcargsoption
292 module procedure dcargsoption0
293 end interface
294
296 module procedure dcargsputline0
297 end interface
298
299 interface dcargsdebug
300 module procedure dcargsdebug0
301 end interface
302
303 interface dcargshelp
304 module procedure dcargshelp0
305 end interface
306
308 module procedure dcargshelpmsg0
309 end interface
310
311 interface dcargsstrict
312 module procedure dcargsstrict0
313 end interface
314
315 interface dcargsget
316 module procedure dcargsget0
317 end interface
318
319 interface dcargsnumber
320 module procedure dcargsnumber0
321 end interface
322
323 !-----------------------------------------------
324 ! 後方互換用
325 ! For backward compatibility
326 interface open
327 module procedure dcargsopen0
328 end interface
329
330 interface close
331 module procedure dcargsclose0
332 end interface
333
334 interface option
335 module procedure dcargsoption0
336 end interface
337
338 interface putline
339 module procedure dcargsputline0
340 end interface
341
342 interface debug
343 module procedure dcargsdebug0
344 end interface
345
346 interface help
347 module procedure dcargshelp0
348 end interface
349
350 interface helpmsg
351 module procedure dcargshelpmsg0
352 end interface
353
354 interface strict
355 module procedure dcargsstrict0
356 end interface
357
358 interface get
359 module procedure dcargsget0
360 end interface
361
362 interface number
363 module procedure dcargsnumber0
364 end interface
365
366
367 !-------------------------------------
368 !> @en Variables set by BuildArgTable @enden
369 !> @ja BuildArgTable で設定される変数 @endja
370
371 character(STRING), allocatable, save:: argstr_table(:)
372 !< @en Contents of all arguments (no distinction whether option or not).
373 !< Set by BuildArgTable. @enden
374 !< @ja 全引数の内容 (オプションかどうかなどの判別は行っていない).
375 !< BuildArgTable で設定される. @endja
376
377 integer, save:: argind_count = -1
378 !< @en Number of all arguments. Set by BuildArgTable. @enden
379 !< @ja 全引数の数. BuildArgTable で設定される. @endja
380
381 !-------------------------------------
382 !> @en Variables set by SortArgTable @enden
383 !> @ja SortArgTable で設定される変数 @endja
384
385 type(CMD_OPTS_INTERNAL), allocatable, save :: cmd_opts_list(:)
386 !< @en List of items identified as options among command line arguments.
387 !< Set by SortArgTable. @enden
388 !< @ja コマンドライン引数のうち, オプションとして識別されるもののリスト.
389 !< SortArgTable で設定される. @endja
390
391 character(STRING), allocatable, save:: cmd_argv_list(:)
392 !< @en List of non-option arguments among command line arguments.
393 !< Set by SortArgTable. @enden
394 !< @ja コマンドライン引数のうち, オプションではない引数のリスト.
395 !< SortArgTable で設定される. @endja
396
397contains
398
399 !> @en
400 !> @brief Initialize ARGS derived type variable
401 !> @details
402 !> Initializes ARGS derived type variable.
403 !>
404 !> When using ARGS derived type variable, please perform initialization
405 !> first with this subroutine.
406 !>
407 !> This subroutine stores command line argument information obtained
408 !> using IARGC and GETARG in lower-level subroutines into argument `arg`.
409 !>
410 !> @param[out] arg ARGS derived type variable to initialize
411 !> @enden
412 !>
413 !> @ja
414 !> @brief 構造型 ARGS 変数の初期化
415 !> @details
416 !> ARGS 型の変数を初期設定します.
417 !>
418 !> ARGS 型の変数を利用する際にはまずこのサブルーチンによって
419 !> 初期設定を行ってください.
420 !>
421 !> このサブルーチンは, より下層のサブルーチン内で IARGC や GETARG
422 !> を用いて得られたコマンドライン引数の情報を引数 `arg`
423 !> へと格納します.
424 !>
425 !> @param[out] arg 初期化する ARGS 型変数
426 !> @endja
427 subroutine dcargsopen0(arg)
428 use dc_message, only: messagenotify
429 implicit none
430 type(args), intent(out) :: arg
431 integer:: cmd_opts_max
432 character(len = *), parameter :: subname = 'DCArgsOpen'
433 continue
434 if (arg % initialized) then
435 call messagenotify('W', subname, 'This argument (type ARGS) is already opend.')
436 return
437 end if
438 call buildargtable
439 call sortargtable
440 cmd_opts_max = size(cmd_opts_list)
441 allocate(arg % cmd_opts_list(cmd_opts_max))
442 arg % cmd_opts_list = cmd_opts_list
443 nullify( arg % opt_table )
444 arg % initialized = .true.
445 end subroutine dcargsopen0
446
447 !> @en
448 !> @brief Finalize ARGS derived type variable
449 !> @details
450 !> Performs finalization of ARGS derived type variable.
451 !>
452 !> @param[in,out] arg ARGS derived type variable to finalize
453 !> @enden
454 !>
455 !> @ja
456 !> @brief 構造型 ARGS 変数の終了処理
457 !> @details
458 !> ARGS 型の変数の終了処理を行います.
459 !>
460 !> @param[in,out] arg 終了処理する ARGS 型変数
461 !> @endja
462 subroutine dcargsclose0(arg)
463 use dc_hash, only: dchashdelete
464 implicit none
465 type(args), intent(inout) :: arg
466 integer :: i
467 continue
468 if (arg % initialized) then
469 if ( associated( arg % opt_table ) ) then
470 do i = 1, size(arg % opt_table)
471 deallocate(arg % opt_table(i) % options)
472 end do
473
474 deallocate(arg % opt_table)
475 end if
476
477 deallocate(arg % cmd_opts_list)
478 deallocate(argstr_table)
479 deallocate(cmd_argv_list)
480 deallocate(cmd_opts_list)
481
482 call dchashdelete(arg % helpmsg)
483 end if
484 end subroutine dcargsclose0
485
486 !> @en
487 !> @brief Configure for getting command line option
488 !> @details
489 !> Registers and retrieves option information.
490 !>
491 !> Among command line arguments, retrieves information about options
492 !> given in `options` to `flag` and `value`. If `options` is given
493 !> in command line arguments, `.true.` is returned to `flag`, otherwise
494 !> `.false.` is returned. If the option has a value specified,
495 !> that value is returned to `value`. If the option itself is not given,
496 !> an empty string is returned to `value`.
497 !>
498 !> `help` registers a help message about `options` in `arg`.
499 !> This message is output when using subroutine DCArgsHelp.
500 !> The message changes depending on whether `value` is given.
501 !>
502 !> @section option_format Option Format
503 !>
504 !> Among command line arguments, the following are judged as options:
505 !>
506 !> - When the first character is '-'. In this case it becomes a short option,
507 !> and only one character after '-' is valid as the option.
508 !>
509 !> - When the first two characters are '--' (two hyphens).
510 !> In this case it becomes a long option,
511 !> and the string after '--' is valid as the option.
512 !>
513 !> The option value is the string after "=".
514 !>
515 !> @param[in,out] arg ARGS derived type variable
516 !> @param[in] options Array of option names (e.g., '-s', '--size')
517 !> @param[out] flag Returns .true. if option is found
518 !> @param[out] value Returns option value if specified (optional)
519 !> @param[in] help Help message for this option (optional)
520 !> @enden
521 !>
522 !> @ja
523 !> @brief コマンドライン引数オプションを取得するための設定
524 !> @details
525 !> オプション情報の登録と取得を行います.
526 !>
527 !> コマンドライン引数のうち, `options` に与えるオプションに関する情
528 !> 報を `flag` と `value` に取得します. `options` がコマンドライン
529 !> 引数に与えられていれば `flag` に `.true.` が, そうでない場合は
530 !> `.false.` が返ります. オプションに値が指定される場合は `value` に
531 !> その値が返ります. オプション自体が与えられていない場合には
532 !> `value` には空文字が返ります.
533 !>
534 !> `help` には `options` に関するヘルプメッセージを `arg` に
535 !> 登録します. サブルーチン DCArgsHelp を
536 !> 用いた際に, このメッセージが出力されます.
537 !> `value` を与えているかどうでこのメッセージは変化します.
538 !>
539 !> @section option_format_ja オプションの書式
540 !>
541 !> コマンドライン引数のうち, オプションと判定されるのは以下の場合です.
542 !>
543 !> - 1 文字目が '-' の場合. この場合は短いオプションとなり, '-'
544 !> の次の一文字のみがオプションとして有効になります.
545 !>
546 !> - 1-2文字目が '--' (ハイフン 2 文字) の場合.
547 !> この場合は長いオプションとなり,
548 !> '--' 以降の文字列がオプションとして有効になります.
549 !>
550 !> オプションの値は, "=" よりも後ろの文字列になります.
551 !>
552 !> @param[in,out] arg ARGS 型変数
553 !> @param[in] options オプション名の配列 (例: '-s', '--size')
554 !> @param[out] flag オプションが見つかった場合に .true. を返す
555 !> @param[out] value オプション値が指定されている場合にその値を返す (省略可能)
556 !> @param[in] help このオプションのヘルプメッセージ (省略可能)
557 !> @endja
558 subroutine dcargsoption0(arg, options, flag, value, help)
559 use dc_message, only: messagenotify
560 implicit none
561 type(args), intent(inout) :: arg
562 character(len = *), intent(in) :: options(:)
563 logical, intent(out) :: flag
564 character(len = *), intent(out), optional :: value
565 character(len = *), intent(in), optional :: help
566 integer :: i, j, options_size, table_size
567 type(opt_entry), allocatable :: local_tables(:)
568 character(len = STRING) :: opt_name, opt_value, opt_full
569 character(len = *), parameter :: subname = 'DCArgsOption'
570 continue
571 flag = .false.
572 if (present(value)) value = ''
573 if (.not. arg % initialized) then
574 call messagenotify('W', subname, 'Call Open before Option in dc_args.')
575 call dcargsopen(arg)
576 end if
577 options_size = size(options)
578 if (options_size < 1) then
579 return
580 end if
581
582 !-----------------------------------
583 ! 構造体 ARGS へのヘルプメッセージ用の情報登録
584 ! * まずはテーブル arg % opt_table を一つ広げる.
585 !-----------------------------------
586 if ( .not. associated( arg % opt_table ) ) then
587 ! 1 つめのオプション指定
588 !
589 table_size = 0
590 allocate(arg % opt_table(table_size + 1))
591 else
592 ! 2 つめ以降のオプション指定
593 !
594 table_size = size(arg % opt_table)
595 allocate(local_tables(table_size))
596 local_tables(1:table_size) = arg % opt_table(1:table_size)
597 deallocate(arg % opt_table)
598 allocate(arg % opt_table(table_size + 1))
599 arg % opt_table(1:table_size) = local_tables(1:table_size)
600 deallocate(local_tables)
601 end if
602
603 !----- 値の代入 -----
604 allocate(arg % opt_table(table_size + 1) % options(options_size))
605 arg % opt_table(table_size + 1) % options = options
606 arg % opt_table(table_size + 1) % help_message = ''
607 if (present(help)) then
608 arg % opt_table(table_size + 1) % help_message = help
609 end if
610 arg % opt_table(table_size + 1) % optvalue_flag = present(value)
611
612
613 !----- options の正規化 -----
614 do i = 1, options_size
615 opt_full = arg % opt_table(table_size + 1) % options(i)
616 if (dcoptionformc(opt_full, opt_name, opt_value)) then
617 arg % opt_table(table_size + 1) % options(i) = opt_name
618 else
619 if (len(trim(adjustl(opt_full))) < 2) then
620 arg % opt_table(table_size + 1) % options(i) = &
621 & '-' // trim(adjustl(opt_full))
622 else
623 arg % opt_table(table_size + 1) % options(i) = &
624 & '--' // trim(adjustl(opt_full))
625 end if
626 end if
627 end do
628
629 ! arg % cmd_opts_list 内の探査と flag, value への代入
630 ! 呼ばれたものに関しては arg % cmd_opts_list % flag_called を
631 ! .true. に
632 do i = 1, options_size
633 do j = 1, size(arg % cmd_opts_list)
634 if (trim(arg % opt_table(table_size + 1) % options(i)) &
635 & == trim(arg % cmd_opts_list(j) % name)) then
636 flag = .true.
637 if (present(value)) then
638 value = arg % cmd_opts_list(j) % value
639 end if
640 arg % cmd_opts_list(j) % flag_called = .true.
641 end if
642 end do
643 end do
644 end subroutine dcargsoption0
645
646 !> @en
647 !> @brief Auto-configure debug option
648 !> @details
649 !> Performs automatic configuration of the debug option.
650 !>
651 !> When -D or --debug is specified, automatically calls
652 !> dc_trace#SetDebug to configure `arg`.
653 !>
654 !> @param[in,out] arg ARGS derived type variable
655 !> @enden
656 !>
657 !> @ja
658 !> @brief デバッグオプションの自動設定
659 !> @details
660 !> デバッグオプションの自動設定を行います.
661 !>
662 !> -D もしくは --debug が指定された際, 自動的に
663 !> dc_trace#SetDebug を呼び出すよう `arg` を設定します.
664 !>
665 !> @param[in,out] arg ARGS 型変数
666 !> @endja
667 subroutine dcargsdebug0(arg)
668 use dc_types, only: string
669 use dc_string, only: stoa, stoi
670 use dc_trace, only: setdebug
671 use dc_message, only: messagenotify
672 implicit none
673 type(args), intent(inout) :: arg
674 logical :: OPT_debug
675 character(STRING) :: VAL_debug
676 character(len = *), parameter :: subname = 'DCArgsDebug'
677 continue
678 if (.not. arg % initialized) then
679 call messagenotify('W', subname, 'Call Open before Debug in dc_args.')
680 call dcargsopen(arg)
681 end if
682 call option(arg, stoa('-D', '--debug'), opt_debug, val_debug, &
683 & help="call dc_trace#SetDebug (display a lot of messages for debug). " // &
684 & "VAL is unit number (default is standard output)")
685 if (opt_debug) then
686 if (trim(val_debug) == '') then
687 call setdebug
688 else
689 call setdebug(stoi(val_debug))
690 end if
691 end if
692 return
693 end subroutine dcargsdebug0
694
695
696 !> @en
697 !> @brief Auto-configure help option
698 !> @details
699 !> Performs automatic configuration of the help option.
700 !>
701 !> When any of -h, -H, --help is specified, automatically displays
702 !> information configured in `arg` as a help message and then
703 !> terminates the program.
704 !> As a rule, please call DCArgsOption and DCArgsDebug subroutines
705 !> before this subroutine.
706 !>
707 !> If `.true.` is specified for `force`, the help message is displayed
708 !> and the program is terminated even if -H, --help option is not given.
709 !>
710 !> Information displayed in the help message can be added using
711 !> DCArgsOption and DCArgsHelpMsg subroutines.
712 !>
713 !> @param[in,out] arg ARGS derived type variable
714 !> @param[in] force If .true., display help even without option (optional)
715 !> @enden
716 !>
717 !> @ja
718 !> @brief ヘルプオプションの自動設定
719 !> @details
720 !> ヘルプオプションの自動設定を行います.
721 !>
722 !> -h, -H, --help のいづれかが指定された際, 自動的に `arg` 内に設定された
723 !> 情報をヘルプメッセージとして表示した後, プログラムを終了させます.
724 !> 原則的に, このサブルーチンよりも前に DCArgsOption, DCArgsDebug
725 !> のサブルーチンを呼んで下さい.
726 !>
727 !> `force` に `.true.` が指定される場合, -H, --help オプションが与え
728 !> られない場合でもヘルプメッセージを表示した後, プログラムを終了さ
729 !> せます.
730 !>
731 !> ヘルプメッセージに表示される情報は, DCArgsOption, DCArgsHelpMsg
732 !> サブルーチンによって付加することが可能です.
733 !>
734 !> @param[in,out] arg ARGS 型変数
735 !> @param[in] force .true. の場合, オプション無しでもヘルプを表示 (省略可能)
736 !> @endja
737 subroutine dcargshelp0(arg, force)
738 use dc_types, only: string, stdout
741 use dc_message, only: messagenotify
743 implicit none
744 type(args), intent(inout) :: arg
745 logical, intent(in), optional :: force
746 logical :: OPT_help, found, end
747 character(STRING) :: VAL_help, options_msg, help_msg, category
748 character(STRING), pointer :: localopts(:) => null()
749 integer :: unit, i
750 character(len = *), parameter :: subname = 'DCArgsHelp'
751 continue
752 if (.not. arg % initialized) then
753 call messagenotify('W', subname, 'Call Open before Help in dc_args.')
754 call dcargsopen(arg)
755 end if
756 call dcargsoption(arg, stoa('-h', '-H', '--help'), opt_help, val_help, &
757 & help="display this help and exit. " // &
758 & "VAL is unit number (default is standard output)")
759 if (.not. opt_help .and. .not. present_and_true(force)) then
760 return
761 end if
762 if (trim(val_help) == '') then
763 unit = stdout
764 else
765 unit = stoi(val_help)
766 end if
767
768 call printf(unit, '')
769
770 call dchashget(arg % helpmsg, 'TITLE', help_msg, found)
771 if (found) then
772 call printf(unit, '%c', c1=trim(help_msg))
773 call printf(unit, '')
774 call dchashdelete(arg % helpmsg, 'TITLE')
775 end if
776
777 call dchashget(arg % helpmsg, 'OVERVIEW', help_msg, found)
778 if (found) then
779 call printf(unit, 'Overview::')
780 call printautolinefeed(unit, help_msg, indent=' ')
781 call printf(unit, '')
782 call dchashdelete(arg % helpmsg, 'OVERVIEW')
783 end if
784
785 call dchashget(arg % helpmsg, 'USAGE', help_msg, found)
786 if (found) then
787 call printf(unit, 'Usage::')
788 call printautolinefeed(unit, help_msg, indent=' ')
789 call printf(unit, '')
790 call dchashdelete(arg % helpmsg, 'USAGE')
791 end if
792
793 call printf(unit, 'Options::')
794 if ( associated(arg % opt_table) ) then
795 do i = 1, size(arg % opt_table)
796 options_msg = ' '
797 if (arg % opt_table(i) % optvalue_flag) then
798 call concat(arg % opt_table(i) % options, '=VAL', localopts)
799 else
800 allocate(localopts(size(arg % opt_table(i) % options)))
801 localopts = arg % opt_table(i) % options
802 end if
803 options_msg = trim(options_msg) // trim(joinchar(localopts))
804 deallocate(localopts)
805 call printf(unit, ' %c', c1=trim(options_msg))
806 call printautolinefeed(unit, &
807 & arg % opt_table(i) % help_message, indent=' ')
808 call printf(unit, '')
809 end do
810 end if
811
812 call dchashrewind(arg % helpmsg)
813 do
814 call dchashnext(arg % helpmsg, category, help_msg, end)
815 if (end) exit
816
817 call printf(unit, '%c%c::', &
818 & c1=trim(uchar(category(1:1))), c2=trim(lchar(category(2:))))
819 call printautolinefeed(unit, help_msg, indent=' ')
820 call printf(unit, '')
821
822 enddo
823
824 call dcargsclose(arg)
825
826 stop
827 end subroutine dcargshelp0
828
829 !> @en
830 !> @brief Add help message
831 !> @details
832 !> Adds a message to be displayed when using subroutine DCArgsHelp.
833 !> Messages with `category` set to "Title", "Overview", or "Usage"
834 !> are displayed above "Options", while others are displayed below.
835 !> Give the message to `msg`.
836 !>
837 !> @section helpmsg_example Example
838 !>
839 !> @code{.f90}
840 !> program dc_args_sample3
841 !> use dc_types
842 !> use dc_string, only: StoA
843 !> use dc_args
844 !> implicit none
845 !> type(ARGS) :: arg
846 !> logical :: OPT_namelist
847 !> character(STRING) :: VAL_namelist
848 !> character(STRING), pointer :: argv(:) => null()
849 !> integer :: i
850 !>
851 !> call DCArgsOpen( arg = arg )
852 !> call DCArgsHelpMsg( arg = arg, category = 'Title', &
853 !> & msg = 'dcargs :: Test program of dc_args' )
854 !> call DCArgsHelpMsg( arg = arg, category = 'Usage', &
855 !> & msg = 'dcargs [Options] arg1, arg2, ...')
856 !> call DCArgsOption( arg = arg, options = StoA('-N', '--namelist'), &
857 !> & flag = OPT_namelist, value = VAL_namelist, help = "Namelist filename")
858 !> call DCArgsHelpMsg( arg = arg, category = 'DESCRIPTION', &
859 !> & msg = '(1) Define type "HASH". (2) Open the variable. ...')
860 !> call DCArgsHelpMsg( arg = arg, category = 'Copyright', &
861 !> & msg = 'Copyright (C) GFD Dennou Club, 2008. All rights reserved.')
862 !> call DCArgsDebug( arg = arg )
863 !> call DCArgsHelp( arg = arg )
864 !> call DCArgsStrict( arg = arg )
865 !> call DCArgsGet( arg = arg, argv = argv )
866 !> write(*,*) '--namelist=', trim( VAL_namelist )
867 !> do i = 1, size(argv)
868 !> write(*,*) argv(i)
869 !> end do
870 !> deallocate( argv )
871 !> call DCArgsClose( arg = arg )
872 !> end program dc_args_sample3
873 !> @endcode
874 !>
875 !> By specifying any of '-h', '-H', '--help' options in command line
876 !> arguments, the message given by HelpMsg and the list of options
877 !> are displayed to standard output.
878 !>
879 !> @param[in,out] arg ARGS derived type variable
880 !> @param[in] category Category name ("Title", "Overview", "Usage", etc.)
881 !> @param[in] msg Help message to add
882 !> @enden
883 !>
884 !> @ja
885 !> @brief ヘルプメッセージを追加
886 !> @details
887 !> サブルーチン DCArgsHelp を使用した際に出力されるメッセージを
888 !> 付加します. `category` に "Title", "Overview", "Usage" が
889 !> 指定されたものは "Options" よりも上部に,
890 !> それ以外のものは下部に表示されます.
891 !> `msg` にはメッセージを与えてください.
892 !>
893 !> @section helpmsg_example_ja 例
894 !>
895 !> @code{.f90}
896 !> program dc_args_sample3
897 !> use dc_types
898 !> use dc_string, only: StoA
899 !> use dc_args
900 !> implicit none
901 !> type(ARGS) :: arg
902 !> logical :: OPT_namelist
903 !> character(STRING) :: VAL_namelist
904 !> character(STRING), pointer :: argv(:) => null()
905 !> integer :: i
906 !>
907 !> call DCArgsOpen( arg = arg )
908 !> call DCArgsHelpMsg( arg = arg, category = 'Title', &
909 !> & msg = 'dcargs :: Test program of dc_args' )
910 !> call DCArgsHelpMsg( arg = arg, category = 'Usage', &
911 !> & msg = 'dcargs [Options] arg1, arg2, ...')
912 !> call DCArgsOption( arg = arg, options = StoA('-N', '--namelist'), &
913 !> & flag = OPT_namelist, value = VAL_namelist, help = "Namelist filename")
914 !> call DCArgsHelpMsg( arg = arg, category = 'DESCRIPTION', &
915 !> & msg = '(1) Define type "HASH". (2) Open the variable. ...')
916 !> call DCArgsHelpMsg( arg = arg, category = 'Copyright', &
917 !> & msg = 'Copyright (C) GFD Dennou Club, 2008. All rights reserved.')
918 !> call DCArgsDebug( arg = arg )
919 !> call DCArgsHelp( arg = arg )
920 !> call DCArgsStrict( arg = arg )
921 !> call DCArgsGet( arg = arg, argv = argv )
922 !> write(*,*) '--namelist=', trim( VAL_namelist )
923 !> do i = 1, size(argv)
924 !> write(*,*) argv(i)
925 !> end do
926 !> deallocate( argv )
927 !> call DCArgsClose( arg = arg )
928 !> end program dc_args_sample3
929 !> @endcode
930 !>
931 !> コマンドライン引数に '-h', '-H', '--help' のいづれかのオプション
932 !> を指定することで, HelpMsg で与えたメッセージと, オプションの一覧
933 !> が標準出力に表示されます.
934 !>
935 !> @param[in,out] arg ARGS 型変数
936 !> @param[in] category カテゴリ名 ("Title", "Overview", "Usage" など)
937 !> @param[in] msg 追加するヘルプメッセージ
938 !> @endja
939 subroutine dcargshelpmsg0(arg, category, msg)
940 use dc_hash, only: dchashput
941 use dc_string, only: uchar
942 use dc_message, only: messagenotify
943 implicit none
944 type(args), intent(inout) :: arg
945 character(*), intent(in) :: category
946 character(*), intent(in) :: msg
947 character(len = *), parameter :: subname = 'DCArgsHelpMsg'
948 continue
949 if (.not. arg % initialized) then
950 call messagenotify('W', subname, 'Call Open before Help in dc_args.')
951 call dcargsopen(arg)
952 end if
953 call dchashput(arg % helpmsg, key=uchar(category), value=msg)
954 end subroutine dcargshelpmsg0
955
956
957 !> @en
958 !> @brief Perform option check
959 !> @details
960 !> Performs option validation.
961 !>
962 !> Among command line argument options, if any option that is not
963 !> configured by DCArgsOption subroutine exists, a warning is returned.
964 !> If `.true.` is specified for `severe`, an error is returned and
965 !> the program terminates.
966 !> Before calling this subroutine, please call DCArgsOption, DCArgsDebug,
967 !> and DCArgsHelp subroutines.
968 !>
969 !> By applying this subroutine to an ARGS derived type variable,
970 !> you can check whether the options given as command line arguments
971 !> are correctly recognized by the program.
972 !>
973 !> @param[in,out] arg ARGS derived type variable
974 !> @param[in] severe If .true., return error and terminate (optional)
975 !> @enden
976 !>
977 !> @ja
978 !> @brief オプションチェックを行う
979 !> @details
980 !> オプションチェックを行います.
981 !>
982 !> コマンドライン引数のオプションとして指定されたものの内,
983 !> DCArgsOption サブルーチンで設定されていないものが存在する
984 !> 場合には警告を返します. `severe` に `.true.` を指定すると
985 !> エラーを返して終了します.
986 !> このサブルーチンを呼ぶ前に, DCArgsOption, DCArgsDebug,
987 !> DCArgsHelp サブルーチンを呼んでください.
988 !>
989 !> 構造型 ARGS の変数に対してこのサブルーチンを適用しておく
990 !> ことで, コマンドライン引数として与えたオプションが正しく
991 !> プログラムが認識しているかどうかをチェックすることができます.
992 !>
993 !> @param[in,out] arg ARGS 型変数
994 !> @param[in] severe .true. の場合, エラーを返して終了 (省略可能)
995 !> @endja
996 subroutine dcargsstrict0(arg, severe)
997 use dc_types, only: string
999 use dc_message, only: messagenotify
1000 implicit none
1001 type(args), intent(inout) :: arg
1002 logical, intent(in), optional :: severe
1003 character(STRING) :: err_mess
1004 integer :: i
1005 character(len = *), parameter :: subname = 'DCArgsStrict'
1006 continue
1007 if (.not. arg % initialized) then
1008 call messagenotify('W', subname, 'Call Open before Help in dc_args.')
1009 call dcargsopen(arg)
1010 end if
1011 do i = 1, size(arg % cmd_opts_list)
1012 err_mess = trim(arg % cmd_opts_list(i) % name) // ' is invalid option.'
1013 if (.not. arg % cmd_opts_list(i) % flag_called) then
1014 if (present_and_true(severe)) then
1015 call messagenotify('E', subname, err_mess)
1016 else
1017 call messagenotify('W', subname, err_mess)
1018 end if
1019 end if
1020 end do
1021 end subroutine dcargsstrict0
1022
1023
1024 !> @en
1025 !> @brief Get non-option command line arguments
1026 !> @details
1027 !> Returns command line arguments that are not options to `argv`.
1028 !>
1029 !> `argv` is a pointer to a character array.
1030 !> When giving it as an argument, be sure to give it in an empty state.
1031 !>
1032 !> @param[in,out] arg ARGS derived type variable
1033 !> @param[out] argv Pointer to character array to receive non-option arguments
1034 !> @enden
1035 !>
1036 !> @ja
1037 !> @brief オプションでないコマンドライン引数を取得
1038 !> @details
1039 !> コマンドライン引数のうち, オプションではないものを
1040 !> `argv` に返します.
1041 !>
1042 !> `argv` は文字型配列のポインタです.
1043 !> 引数として与える場合には必ず空状態にして与えてください.
1044 !>
1045 !> @param[in,out] arg ARGS 型変数
1046 !> @param[out] argv オプションでない引数を受け取る文字型配列のポインタ
1047 !> @endja
1048 subroutine dcargsget0(arg, argv)
1049 use dc_string, only: stoa, stoi, printf, concat, joinchar
1050 use dc_present, only: present_and_true
1051 use dc_message, only: messagenotify
1052 implicit none
1053 type(args), intent(inout) :: arg
1054 character(*), pointer :: argv(:) !(out)
1055 integer :: i, cmd_argv_max
1056 character(len = *), parameter :: subname = 'DCArgsGet'
1057 continue
1058 if (.not. arg % initialized) then
1059 call messagenotify('W', subname, 'Call Open before Help in dc_args.')
1060 call dcargsopen(arg)
1061 end if
1062 cmd_argv_max = size(cmd_argv_list)
1063 allocate(argv(cmd_argv_max))
1064 do i = 1, cmd_argv_max
1065 argv(i) = cmd_argv_list(i)
1066 end do
1067 end subroutine dcargsget0
1068
1069 !> @en
1070 !> @brief Return number of command line arguments
1071 !> @details
1072 !> Returns the number of non-option arguments given as command line arguments.
1073 !>
1074 !> @param[in,out] arg ARGS derived type variable
1075 !> @return Number of command line arguments (excluding options)
1076 !> @enden
1077 !>
1078 !> @ja
1079 !> @brief コマンドライン引数の数を返す
1080 !> @details
1081 !> コマンドライン引数として与えられた引数の数を返します.
1082 !>
1083 !> @param[in,out] arg ARGS 型変数
1084 !> @return コマンドライン引数の数 (オプションを除く)
1085 !> @endja
1086 function dcargsnumber0(arg) result(result)
1087 use dc_message, only: messagenotify
1088 implicit none
1089 type(args), intent(inout) :: arg
1090 integer :: result
1091 character(len = *), parameter :: subname = 'DCArgsNumber'
1092 continue
1093 if (.not. arg % initialized) then
1094 call messagenotify('W', subname, 'Call Open before Help in dc_args.')
1095 call dcargsopen(arg)
1096 end if
1097 result = size(cmd_argv_list)
1098 end function dcargsnumber0
1099
1100 !> @en
1101 !> @brief Print information about ARGS variable
1102 !> @details
1103 !> Displays information about `arg` to standard output.
1104 !> This is mainly for debugging purposes.
1105 !>
1106 !> @param[in] arg ARGS derived type variable
1107 !> @enden
1108 !>
1109 !> @ja
1110 !> @brief ARGS 変数の情報を表示
1111 !> @details
1112 !> `arg` に関する情報を標準出力に表示します.
1113 !> 主にデバッグ用途に使用します.
1114 !>
1115 !> @param[in] arg ARGS 型変数
1116 !> @endja
1117 subroutine dcargsputline0(arg)
1118 use dc_types, only: stdout
1119 use dc_string, only: printf, joinchar
1120 implicit none
1121 type(args), intent(in) :: arg
1122 integer :: i
1123 continue
1124 if (.not. arg % initialized) then
1125 call printf(stdout, '#<ARGS:: @initialized=%y>', l=(/arg % initialized/))
1126 return
1127 end if
1128 call printf(stdout, '#<ARGS:: @initialized=%y,', l=(/arg % initialized/))
1129 call printf(stdout, ' @opt_table(:)=')
1130 if ( associated(arg % opt_table) ) then
1131 do i = 1, size(arg % opt_table)
1132 call printf(stdout, ' #<OPT_ENTRY:: ')
1133 call printf(stdout, ' @options=%c, @help_message=%c, @optvalue_flag=%y', &
1134 & c1=trim(joinchar(arg % opt_table(i) % options)), &
1135 & c2=trim(arg % opt_table(i) % help_message), &
1136 & l=(/arg % opt_table(i) % optvalue_flag/))
1137 call printf(stdout, ' >')
1138 end do
1139 end if
1140 call printf(stdout, ' ,')
1141 call printf(stdout, ' @cmd_opts_list(:)=')
1142 do i = 1, size(arg % cmd_opts_list)
1143 call printf(stdout, ' #<CMD_OPTS_INTERNAL:: ')
1144 call printf(stdout, ' @name=%c, @value=%c, @flag_called=%y', &
1145 & c1=trim(arg % cmd_opts_list(i) % name), &
1146 & c2=trim(arg % cmd_opts_list(i) % value), &
1147 & l=(/arg % cmd_opts_list(i) % flag_called/))
1148 call printf(stdout, ' >')
1149 end do
1150 call printf(stdout, ' ,')
1151 call printf(stdout, ' @cmd_argv_list(:)=%c', &
1152 & c1=trim(joinchar(cmd_argv_list)))
1153 call printf(stdout, '>')
1154
1155 end subroutine dcargsputline0
1156
1157 !> @en
1158 !> @brief Print string with automatic line feed
1159 !> @details
1160 !> Outputs a string with automatic line wrapping.
1161 !> This is a subroutine for internal use within this module.
1162 !>
1163 !> The text given to `fmt` is wrapped to within `length` characters
1164 !> (default is 70 if not specified) and output. When `indent` is
1165 !> specified, that string is inserted at the beginning of each line.
1166 !> The default output destination is standard output. You can change
1167 !> the output destination by setting the unit number to `unit`.
1168 !>
1169 !> @param[in] unit Output unit number (optional)
1170 !> @param[in] fmt Format string to output
1171 !> @param[in] length Line length (default 70) (optional)
1172 !> @param[in] indent Indentation string (optional)
1173 !> @enden
1174 !>
1175 !> @ja
1176 !> @brief 文字列を自動改行して出力
1177 !> @details
1178 !> 文字列を自動改行して出力します.
1179 !> このモジュール内部で用いるためのサブルーチンです.
1180 !>
1181 !> `fmt` に与えられた文章を文字数 `length` (指定されない場合 70)
1182 !> 以内に改行し, 出力します. 出力の際, `indent` が指定されていると
1183 !> その文字列を行頭に挿入して出力を行います.
1184 !> 出力先はデフォルトは標準出力となります. `unit` に出力装置番号
1185 !> を設定することで出力先を変更できます.
1186 !>
1187 !> @param[in] unit 出力装置番号 (省略可能)
1188 !> @param[in] fmt 出力するフォーマット文字列
1189 !> @param[in] length 行の長さ (デフォルト 70) (省略可能)
1190 !> @param[in] indent 字下げ文字列 (省略可能)
1191 !> @endja
1192 subroutine printautolinefeed(unit, fmt, length, indent)
1193 use dc_types, only: string, stdout
1194 use dc_string, only: split
1195 implicit none
1196 character(*), intent(in) :: fmt
1197 integer, intent(in), optional :: length ! 一行の長さ
1198 character(*), intent(in), optional :: indent ! 字下げ文字列
1199 integer, intent(in), optional :: unit ! 出力装置
1200 character(STRING), pointer :: carray_tmp(:) => null()
1201 character(STRING) :: store_str
1202 integer, parameter :: default_len = 70
1203 integer :: i, split_len, indent_len, unit_num
1204 logical :: new_line_flag
1205 continue
1206 if (present(unit)) then
1207 unit_num = unit
1208 else
1209 unit_num = stdout
1210 end if
1211
1212 if (present(indent)) then
1213 indent_len = len(indent)
1214 else
1215 indent_len = 0
1216 end if
1217
1218 if (present(length)) then
1219 split_len = length - indent_len
1220 else
1221 split_len = default_len - indent_len
1222 end if
1223
1224
1225 nullify(carray_tmp)
1226 call split(fmt, carray_tmp, '')
1227 store_str = ''
1228 new_line_flag = .true.
1229 i = 1
1230 do
1231 if (i > size(carray_tmp)) then
1232 write(unit_num, '(A)') trim(store_str)
1233 exit
1234 end if
1235
1236 if (len(trim(store_str)) + len(trim(carray_tmp(i))) > split_len) then
1237 if (new_line_flag) then
1238 write(unit_num, '(A)') trim(carray_tmp(i))
1239 i = i + 1
1240 else
1241 write(unit_num, '(A)') trim(store_str)
1242 store_str = ''
1243 new_line_flag = .true.
1244 end if
1245 cycle
1246 end if
1247
1248 if (new_line_flag .and. present(indent)) then
1249 store_str = indent // trim(carray_tmp(i))
1250 else
1251 store_str = trim(store_str) // ' ' // trim(carray_tmp(i))
1252 end if
1253 new_line_flag = .false.
1254 i = i + 1
1255 end do
1256
1257 end subroutine printautolinefeed
1258
1259 !> @en
1260 !> @brief Sort argument table (internal use)
1261 !> @details
1262 !> This is an internal subroutine for sorting arguments.
1263 !>
1264 !> Uses argind_count and argstr_table set by BuildArgTable to
1265 !> configure cmd_argv_list and cmd_opts_list.
1266 !>
1267 !> If this subroutine has already been called, it returns without doing anything.
1268 !> @enden
1269 !>
1270 !> @ja
1271 !> @brief 引数テーブルの振り分け (内部使用)
1272 !> @details
1273 !> 内部向けの引数振り分けのためのサブルーチンです.
1274 !>
1275 !> BuildArgTable で設定された argind_count, argstr_table を
1276 !> 用い, cmd_argv_list, cmd_opts_list を設定します.
1277 !>
1278 !> 既に一度でも呼ばれている場合, 何もせずに終了します.
1279 !> @endja
1280 subroutine sortargtable
1281 use dc_types, only: string
1282 implicit none
1283 character(STRING):: raw_arg, name, value
1284 integer:: i, cmd_argv_count, cmd_opts_count, cmd_argv_max, cmd_opts_max
1285 continue
1286 if (allocated(cmd_opts_list)) return
1287 cmd_argv_count = 0
1288 cmd_opts_count = 0
1289 check_count: do, i = 1, argind_count
1290 raw_arg = argstr_table(i)
1291 if (dcoptionformc(raw_arg, name, value)) then
1292 cmd_opts_count = cmd_opts_count + 1
1293 else
1294 cmd_argv_count = cmd_argv_count + 1
1295 end if
1296 end do check_count
1297
1298 cmd_argv_max = cmd_argv_count
1299 cmd_opts_max = cmd_opts_count
1300
1301 allocate(cmd_argv_list(cmd_argv_max))
1302 allocate(cmd_opts_list(cmd_opts_max))
1303
1304 cmd_argv_count = 0
1305 cmd_opts_count = 0
1306 arg_get : do, i = 1, argind_count
1307 raw_arg = argstr_table(i)
1308 if (dcoptionformc(raw_arg, name, value)) then
1309 cmd_opts_count = cmd_opts_count + 1
1310 cmd_opts_list(cmd_opts_count) % name = name
1311 cmd_opts_list(cmd_opts_count) % value = value
1312 cmd_opts_list(cmd_opts_count) % flag_called = .false.
1313 else
1314 cmd_argv_count = cmd_argv_count + 1
1315 cmd_argv_list(cmd_argv_count) = raw_arg
1316 end if
1317 end do arg_get
1318 end subroutine sortargtable
1319
1320 !> @en
1321 !> @brief Build argument table (internal use)
1322 !> @details
1323 !> This is an internal subroutine for command line argument processing.
1324 !>
1325 !> Calls sysdep#SysdepArgCount and sysdep#SysdepArgGet from the sysdep
1326 !> module, and stores their contents in argind_count and argstr_table.
1327 !>
1328 !> If this subroutine has already been called, it returns without doing anything.
1329 !> @enden
1330 !>
1331 !> @ja
1332 !> @brief 引数テーブルの構築 (内部使用)
1333 !> @details
1334 !> 内部向けコマンドライン引数処理のサブルーチンです.
1335 !>
1336 !> モジュール sysdep の sysdep#SysdepArgCount, sysdep#SysdepArgGet
1337 !> を呼び出し, その内容を argind_count と argstr_table に格納します.
1338 !>
1339 !> 既に一度でも呼ばれている場合, 何もせずに終了します.
1340 !> @endja
1341 subroutine buildargtable
1343 use dc_types, only: string
1344 implicit none
1345 integer:: i, narg, nargmax
1346 character(len = STRING):: value
1347 character(len = STRING), allocatable:: localtab(:)
1348 continue
1349 if (argind_count >= 0) return
1350 nargmax = sysdepargcount()
1351 allocate(localtab(nargmax))
1352 narg = 0
1353 do, i = 1, nargmax
1354 call sysdepargget(i, value)
1355 narg = narg + 1
1356 localtab(narg) = value
1357 enddo
1358 argind_count = narg
1359 allocate(argstr_table(narg))
1360 argstr_table(1: narg) = localtab(1: narg)
1361 deallocate(localtab)
1362 end subroutine buildargtable
1363
1364 !> @en
1365 !> @brief Check if argument is an option (internal use)
1366 !> @details
1367 !> By passing a string obtained as an argument to `argument`,
1368 !> determines whether it is an option or not. If determined to be
1369 !> an option, returns `.true.` as the return value, and returns
1370 !> the option name to `name` and its value to `value`.
1371 !> If no value is attached to the option, an empty string is returned to `value`.
1372 !>
1373 !> If it is not an option, returns `.false.` as the return value,
1374 !> and returns empty strings to `name` and `value`.
1375 !>
1376 !> The following cases are determined as options:
1377 !>
1378 !> - If the first character is '-'. In this case it becomes a short option,
1379 !> and only one character after '-' is valid as the option.
1380 !>
1381 !> - If characters 1-2 are '--'. In this case it becomes a long option,
1382 !> and the string after '--' is valid as the option.
1383 !>
1384 !> The option value is the string after "=".
1385 !>
1386 !> @section optionformc_example Example
1387 !>
1388 !> | argument | name | value | result |
1389 !> |---------------|------------|--------|---------|
1390 !> | arg | (empty) | (empty)| .false. |
1391 !> | -O | -O | (empty)| .true. |
1392 !> | -debug | -d | (empty)| .true. |
1393 !> | --debug | --debug | (empty)| .true. |
1394 !> | -I=/usr | -I | /usr | .true. |
1395 !> | --include=/usr| --include | /usr | .true. |
1396 !>
1397 !> @param[in] argument Argument string to check
1398 !> @param[out] name Option name (empty if not an option)
1399 !> @param[out] value Option value (empty if not specified)
1400 !> @return .true. if argument is an option, .false. otherwise
1401 !> @enden
1402 !>
1403 !> @ja
1404 !> @brief 引数がオプションかどうか判定 (内部使用)
1405 !> @details
1406 !> 引数として得られた文字列を `argument` に渡すことで,
1407 !> それがオプションなのかそうでないのかを判別し, もしも
1408 !> オプションと判別した場合には戻り値に `.true.` を返し,
1409 !> `name` にオプション名, `value` にその値を返す.
1410 !> オプションに値が付加されない場合は `value` には空白を返す.
1411 !>
1412 !> オプションではない場合は戻り値に `.false.` を返し,
1413 !> `name`, `value` には空白を返す.
1414 !>
1415 !> オプションと判定されるのは以下の場合です.
1416 !>
1417 !> - 一文字目が '-' の場合. この場合は短いオプションとなり, '-'
1418 !> の次の一文字のみがオプションとして有効になります.
1419 !>
1420 !> - 1-2文字目が '--' の場合. この場合は長いオプションとなり,
1421 !> '--' 以降の文字列がオプションとして有効になります.
1422 !>
1423 !> オプションの値は, "=" よりも後ろの文字列になります.
1424 !>
1425 !> @section optionformc_example_ja 例
1426 !>
1427 !> | argument | name | value | 返り値 |
1428 !> |---------------|------------|--------|---------|
1429 !> | arg | 空白 | 空白 | .false. |
1430 !> | -O | -O | 空白 | .true. |
1431 !> | -debug | -d | 空白 | .true. |
1432 !> | --debug | --debug | 空白 | .true. |
1433 !> | -I=/usr | -I | /usr | .true. |
1434 !> | --include=/usr| --include | /usr | .true. |
1435 !>
1436 !> @param[in] argument チェックする引数文字列
1437 !> @param[out] name オプション名 (オプションでない場合は空白)
1438 !> @param[out] value オプション値 (指定されていない場合は空白)
1439 !> @return 引数がオプションの場合 .true., そうでなければ .false.
1440 !> @endja
1441 function dcoptionformc(argument, name, value) result(result)
1442 implicit none
1443 character(len = *), intent(in):: argument
1444 character(len = *), intent(out):: name, value
1445 logical :: result
1446 integer:: equal
1447 continue
1448 equal = index(argument, '=')
1449 if (argument(1:1) == '-' .and. argument(2:2) /= '-') then
1450 ! Short Option
1451 if (equal == 0) then
1452 name = argument(1:2)
1453 value = ""
1454 else
1455 name = argument(1:2)
1456 value = argument(equal+1: )
1457 endif
1458 result = .true.
1459 elseif (argument(1:2) == '--') then
1460 ! Long Option
1461 if (equal == 0) then
1462 name = argument
1463 value = ""
1464 else
1465 name = argument(1:equal-1)
1466 value = argument(equal+1: )
1467 endif
1468 result = .true.
1469! elseif (equal == 0 .and. &
1470! & verify(argument(1:equal-1), WORDCHARS) == 0) then
1471! ! ???
1472! name = argument(1:equal-1)
1473! value = argument(equal+1: )
1474! result = .true.
1475 else
1476 ! No Option (normal arguments)
1477 name = ""
1478 value = ""
1479 result = .false.
1480 endif
1481 end function dcoptionformc
1482
1483
1484
1485end module dc_args
Command line arguments parser.
Definition dc_args.f90:193
Hash (associative array) module.
Definition dc_hash.f90:143
Message output module.
Judge optional control parameters.
logical function, public present_and_true(arg)
Handling character types.
Definition dc_string.f90:83
character(string) function, public joinchar(carray, expr)
Debug tracing module.
Definition dc_trace.f90:150
subroutine, public setdebug(debug)
Definition dc_trace.f90:336
Provides kind type parameter values.
Definition dc_types.f90:55
integer, parameter, public string
Character length for string
Definition dc_types.f90:137
integer, parameter, public stdout
Unit number for Standard OUTPUT
Definition dc_types.f90:117
Provides interface for system dependent procedures.
Definition sysdep.f90:54
subroutine, public sysdepargget(index, val)
Get command line argument.
Definition sysdep.f90:138
integer function, public sysdepargcount()
Get number of command line arguments.
Definition sysdep.f90:114