次: , 前: Group options, 上: Top


6 コンフィグレーションファイル

コマンドラインオプションを直接コンフィグレーションファイルで指定すると 便利なときも多いので,オプションの値はコマンドラインオプションが与えら れていない場合,このファイルから読みこまれるようにします.コマンドライ ンオプション--conf-parserがgengetoptで与えられている場合,標準的 なコマンドラインオプションの構文解析器以外に,以下の追加の構文解析器が 生成されます(名前は<commandline_parser>_configfileです).

     int
     <cmd_parser_name>_configfile (char * const filename,
                                   struct gengetopt_args_info *args_info,
                                   int override,
                                   int initialize,
                                   int check_required);

パラメータoverrideは,コンフィグレーションファイルから読み込まれ た値を,コマンドラインで指定されたものに優先させる必要があるかどうかを 伝えます.initializeは,args_info構造体を初期化する必要があるか どうかを伝えます.

重要:コンフィグレーションファイルの構文解析器を,標準のコマンドライン オプション構文解析器の前に呼び出す場合,明示的にinitializeを真に 設定する必要があり(例えば,0ではないもの),そうしなければ予想できない結 果が表示される可能性があります.

check_requiredは,必須のオプションを調査する必要があるかどうかを 伝えます.

コンフィグレーションファイルの構文解析器を標準のコマンドラインオプショ ンの構文解析器の前に呼び出す場合で,標準のコマンドラインの構文解析器を 呼び出したい場合,以下の二番目のバージョンを使用する必要があり,コンフィ グレーションファイルで収集した値を失わないように,初期化で0を渡す必要が あります.

     int
     <cmd_parser_name>2 (int argc,
                         char * const *argv,
                         struct gengetopt_args_info *args_info,
                         int override,
                         int initialize,
                         int check_required);

注意:このバージョンを用いると,コマンドラインで渡すオプションをコンフィ グレーションファイルから読み込んだものに優先させる必要があるかどうかを 指定することも可能です.overrideを0に設定し,コンフィグレーショ ンファイルから既に読み込まれているものに対し,コマンドラインオプション が与えられた場合,エラーが発生します.さらに,足りない必須オプションの 調査をする必要があるかどうかを指定する必要があります.これは,必須グルー プのオプションにも関係します(Group options).

必須オプションの調査を要求しないことに決めた場合,コマンドラインの構文 解析が,以下のように生成された関数を使用して戻った後で,手動で調査する ことが可能です.

     int
     <cmd_parser_name>_required (struct gengetopt_args_info *args_info,
                                 const char *program_name);

ここで,program_nameは実行形式の名前です(通常,引数として argv[0]で渡します).関数が0以外の値を返す場合,必須オプションに 足りないものがあります.エラーはこの関数で既に出力されています.これは, 必須グループのオプションにも関係します(Group options).

コンフィグレーションファイルは,以下のような単純な構文になっています. `#'で始まる行はコメントと考慮されます.

     <option_name> = {<option_val>}

または,(オプションが引数を取らない場合)単純に以下のようになっています.

     <option_name>

これは,option_nameが与えられていて,引数をうけいれる場合が値が option_valになっていることを意味します.=は必須ではありま せん.

例えば,この機能を使用している以下のプログラムを考えます(これはテストの test_conf_parserです).

     /* test_conf_parser.c test */
     
     /* test all kinds of options and the conf file parser */
     
     #include <stdlib.h>
     #include <stdio.h>
     
     #include "test_conf_parser_cmd.h"
     
     static struct my_args_info args_info;
     
     int
     main (int argc, char **argv)
     {
       int i;
       int result = 0;
     
       if (test_conf_parser_cmd_parser (argc, argv, &args_info) != 0) {
         result = 1;
         goto stop;
       }
     
       /* override cmd options, but do not initialize args_info, check for required options */
       if (test_conf_parser_cmd_parser_configfile
           (args_info.conf_file_arg, &args_info, 1, 0, 1) != 0)
         {
           result = 1;
           goto stop;
         }
     
       printf ("value of required: %s\n", args_info.required_arg);
       printf ("value of string: %s\n", args_info.string_arg);
       printf ("value of no-short_given: %d\n", args_info.no_short_given);
       printf ("value of int: %d\n", args_info.int_arg);
       printf ("value of float: %f\n", args_info.float_arg);
     
       printf ("value of multi-string_given: %d\n", args_info.multi_string_given);
       for (i = 0; i < args_info.multi_string_given; ++i)
         printf ("  value of multi-string: %s\n", args_info.multi_string_arg [i]);
     
       printf ("value of multi-string-def_given: %d\n",
               args_info.multi_string_def_given);
       for (i = 0; i < args_info.multi_string_def_given; ++i)
         printf ("  value of multi-string-def: %s\n",
                 args_info.multi_string_def_arg [i]);
       if (!args_info.multi_string_def_given && args_info.multi_string_def_arg [0])
         printf ("default value of multi-string-def: %s\n",
                 args_info.multi_string_def_arg [0]);
     
       printf ("value of opta: %s\n", args_info.opta_arg);
     
       printf ("noarg given %d times\n", args_info.noarg_given);
       printf ("noarg_noshort given %d times\n", args_info.noarg_noshort_given);
     
       printf ("opt-arg given: %d\n", args_info.opt_arg_given);
       printf ("opt-arg value: %s\n", (args_info.opt_arg_arg ? args_info.opt_arg_arg : "not given"));
     
       if (args_info.file_save_given) {
         if (test_conf_parser_cmd_parser_file_save (args_info.file_save_arg, &args_info) == EXIT_FAILURE)
           result = 1;
         else
           printf ("saved configuration file %s\n", args_info.file_save_arg);
       }
     
      stop:
       test_conf_parser_cmd_parser_free (&args_info);
     
       return result;
     }
     

そして,以下のコンフィグレーションファイルを使用している状況を考えます.

     # required option
     required "this is a test"
     float 3.14
     no-short
     string another

そして,test_conf_parserを以下のように実行します.

     ./test_conf_parser -r bar -i 100 --float 2.14 --conf-file test_conf.conf
     value of required: this is a test
     value of string: another
     value of no-short: 1
     value of int: 100
     value of float: 3.140000

代わりに,引数に優先させるためtest_conf_parser_cmd_parser_configfileを0として呼び出す場合,以下のような結果になります.

     value of required: bar
     value of string: another
     value of no-short: 1
     value of int: 100
     value of float: 2.140000

この二番目の例では,二番目のバージョンのコマンドライン構文解析器を使用 しています.最初にコンフィグレーションファイル構文解析器を呼び出し,そ れからコマンドライン構文解析器を呼び出します(コマンドラインオプションは, コンフィグレーションファイルのオプションに優先します).

     /* test_conf_parser_ov2.c test */
     
     /* test all kinds of options and the conf file parser */
     /* differently from test_conf_parser_ov.c, first scan the conf file and
        then the command line */
     
     #include <stdlib.h>
     #include <stdio.h>
     
     #include "test_conf_parser_cmd.h"
     
     static struct my_args_info args_info;
     
     int
     main (int argc, char **argv)
     {
       /* do not override command line options, initialize args_info */
       if (test_conf_parser_cmd_parser_configfile
           ("./test_conf2.conf", &args_info, 0, 1, 0) != 0)
         exit(1);
     
       if (test_conf_parser_cmd_parser2 (argc, argv, &args_info, 1, 0, 1) != 0)
         exit(1) ;
     
       printf ("value of required: %s\n", args_info.required_arg);
       printf ("value of string: %s\n", args_info.string_arg);
       printf ("value of no-short_given: %d\n", args_info.no_short_given);
       printf ("value of int: %d\n", args_info.int_arg);
       printf ("value of float: %f\n", args_info.float_arg);
     
       test_conf_parser_cmd_parser_free (&args_info);
     
       return 0;
     }
     

以下のように呼び出したときの結果です.

     ./test_conf_parser_ov2 -r "bar" --float 2.14 -i 100
     value of required: bar
     value of string: another
     value of no-short: 1
     value of int: 100
     value of float: 2.140000

6.1 コンフィグレーションファイルの構文解析器の詳細

生成されるコンフィグレーションファイルの構文解析関数は,コンフィグレー ションファイルのそれぞれの行を読み込むとき,定数 CONFIG_FILE_LINE_SIZEを使用しています.この定数のデフォルトは 2048に設定されていて,ほとんどのアプリケーションで十分でしょう. アプリケーションで,それ以上の長さの行があるコンフィグレーションファイ ルを使用している場合,gcc-Dコマンドラインオプションを用 いて,この定数の値を明示的に指定して,Cファイルのコンパイルをすることが 可能です.