Config 言語仕様
1999 年 10 月 18 日
Michael Elizabeth Chastain, <mailto:mec@shout.net>

    日本語訳：JF プロジェクト
      翻訳者：川崎貴彦 <takahiko@hakubi.co.jp>



=== はじめに

Config 言語は 'bash' ではありません。

このドキュメントは、Linux カーネル設定言語である Config 言語について
記述したものです。config.in ファイルと Config.in ファイルは、この言語で
書かれています。

Config 言語は 'sh' 言語のサブセットのように見え、通常はそのように動作
しますが、制限された構文と異なるセマンティックスを持っています。

ここに Config 言語プログラミングの基本指針を示します。それは、現存する
Config.in ファイル内に存在するプログラミング・イディオムのみを使用する
こと、です。シェルプログラマにとって合理的に思えるイディオムを作り上げ
ようとして、シェルプログラミング経験を利用してしまう人が結構いますが、
Config 言語内では、それらは何も言わずに失敗してしまいます。

Config 言語は 'bash' ではないのです。



=== インタプリタ

4 つの異なる設定プログラムが Config 言語を解釈します:

    scripts/Configure   make config, make oldconfig
    scripts/Menuconfig  make menuconfig
    scripts/tkparse     make xconfig
    mconfig             ftp.kernel.org/pub/linux/kernel/people/hch/mconfig/

'Configure' は、source することによって Config.in ファイルを解釈する bash
スクリプトです。幾つかの Config 言語コマンドは、ネイティブな bash コマンド
です。残りのコマンドは、シンプルな bash 関数で実装されています。

'Menuconfig' は、もう一つの bash スクリプトです。Menuconfig は、小さな awk
スクリプトで入力ファイルをスキャンし、各メニュー用にシェル関数を作り、その
作ったシェル関数を source し、それから、ユーザが起動した順番でシェル関数を
実行します。Menuconfig は、実際のスクリーン出力を行うために、 'lxdialog'
というバックエンド・ユーティリティプログラムを使用します。'lxdialog' は、
curses を使用する C プログラムです。

'scripts/tkparse' は、Config 言語スクリプトを大きな Tcl/Tk プログラムに
変換する特別なパーサを持つ C プログラムです。'make xconfig' は、この
Tcl/Tk プログラムを 'wish' に渡し、wish がそれを実行します。

'mconfig' は、次世代の Config 言語インタプリタです。mconfig は、Config 言語
スクリプトを内部構文木に変換し、その構文木をユーザインターフェース・フロント
エンドのどれか一つに渡す bison パーサを持つ C プログラムです。



=== 文

Config 言語スクリプトは、文のリストでできています。22 のシンプルな文、
'if' 文、メニューブロック、'source' 文、があります。

行末の '\' は、行が続くことを示します。

'#' には通常、コメントが続きます。行末までがコメントになります。しかし、
'# ... is not set' という形式の行は、コメントとはなりません。それらは、
セマンティックス的に有意であり、4 つ全ての config インタプリタが、この
意味付けを実装しています。

改行は重要です。改行のかわりにセミコロンを使うことはできません。'if' 文には、
一箇所だけセミコロンを受けつける場所があります。その場所では、かわりに改行を
使うことができます。

ここに、基本的な文法要素を挙げます。

    /プロンプト/ は、シングルクォートまたはダブルクォートされている文字列です。
    ダブルクォートされている場合は、$ 置換を含んでいてはいけません。

    /ワード/ は、クォートされていない単一の語、シングルクォートされている文字列、
    またはダブルクォートされている文字列です。ワードがクォートされていない場合、
    もしくはダブルクォートされている場合は、そのワードに対して $ 置換が実行され
    ます。

    /シンボル/ は、クォートされていない単一の語です。シンボルは、CONFIG_* という
    形式の名前を持っていなければなりません。scripts/mkdep.c は、個々の CONFIG_*
    シンボルの依存関係を生成するため、 include/linux/autoconf.h に一つの巨大な
    依存関係を作成するかわりに、この名前付けの慣習を当てにしています。

    /依存/ は、依存関係です。構文的には、/ワード/ です。実行時には、/依存/ は
    "y", "m", "n", もしくは "", と評価されなければなりません。

    /式/ は、演算子 '=', '!=', '-a', '-o', '!' を使用する bash ライクな式です。


ここに全ての文を挙げます:

    テキスト文:

        mainmenu_name   /プロンプト/
        comment         /プロンプト/
        text            /プロンプト/

    質問文:

        bool            /プロンプト/ /シンボル/
        hex             /プロンプト/ /シンボル/ /ワード/
        int             /プロンプト/ /シンボル/ /ワード/
        string          /プロンプト/ /シンボル/ /ワード/
        tristate        /プロンプト/ /シンボル/

    定義文:

        define_bool     /シンボル/ /ワード/
        define_hex      /シンボル/ /ワード/
        define_int      /シンボル/ /ワード/
        define_string   /シンボル/ /ワード/
        define_tristate /シンボル/ /ワード/

    依存文:

        dep_bool        /プロンプト/ /シンボル/ /依存/ ...
        dep_mbool       /プロンプト/ /シンボル/ /依存/ ...
        dep_hex         /プロンプト/ /シンボル/ /ワード/ /依存/ ...
        dep_int         /プロンプト/ /シンボル/ /ワード/ /依存/ ...
        dep_string      /プロンプト/ /シンボル/ /ワード/ /依存/ ...
        dep_tristate    /プロンプト/ /シンボル/ /依存/ ...

    定義解除文:

        unset /シンボル/ ...

    選択文:

        choice          /プロンプト/ /ワード/ /ワード/
        nchoice         /プロンプト/ /シンボル/ /プロンプト/ /シンボル/ ...

    If 文:

        if [ /式/ ] ; then
	  /文/
	  ...
        fi

        if [ /式/ ] ; then
	  /文/
	  ...
        else
	  /文/
	  ...
        fi

    メニューブロック:

        mainmenu_option next_comment
        comment /プロンプト/
          /文/
	  ...
        endmenu

    Source 文:

        source /ワード/



=== mainmenu_name /プロンプト/

この動詞は、見た目よりははるかに重要度は低いです。mainmenu_name は、この
Config 言語ファイルのトップレベル名を指定します。

Configure:  この行を無視します
Menuconfig: この行を無視します
Xconfig:    ラベルウィンドウ用に /プロンプト/ を使用します。
mconfig:    この行を無視します (mconfig はこれが無くても、より良い仕事をします)

例:

    # arch/sparc/config.in
    mainmenu_name "Linux/SPARC Kernel Configuration"



=== comment /プロンプト/

この動詞は、設定プロセス中にユーザに対してプロンプトを表示し、また、出力中は
出力ファイルにプロンプトを書き出します。全てのプロンプトと同様、プロンプトは
ドル置換の無いクォートされた文字列であることに注意してください。

動詞 'comment' は、Config 言語のコメントではありません。comment は、ユーザ
インターフェースにテキストを表示させるようにし、また、出力ファイルに書出しが
行われるようにもします。

Configure:  実装されている
Menuconfig: 実装されている
Xconfig:    実装されている
mconfig:    実装されている

例:

    # drivers/net/Config.in
    comment 'CCP compressors for PPP are only built as modules.'



=== text /プロンプト/

この動詞は、ユーザに対して、一切の修飾無しでプロンプトを表示します。
出力ファイルにはプロンプトを書き出しません。mconfig は、ヘルプ機能用に
この動詞を内部で使用しています。

Configure:  実装されていない
Menuconfig: 実装されていない
Xconfig:    実装されていない
mconfig:    実装されている

例:

    # mconfig internal help text
    text 'Here are all the mconfig command line options.'



=== bool /プロンプト/ /シンボル/

この動詞は、ユーザに /プロンプト/ を表示し、ユーザから値を受け取り、
その値を /シンボル/ に設定します。有効な入力値は、"n" と "y" です。

動詞 bool がデフォルト値を持っていないことに注意してください。 bool に対する
デフォルト値を与えて Config 言語スクリプトを書こうと、みなさん試みられますが、
現存する全ての言語インタプリタは追加の値を捨ててしまいます。拡張としてこれを
実装したいとお考えでしたら、マルチインタプリタ・パッチを遠慮せず linux-kbuild
まで送ってください。

Configure:  実装されている
Menuconfig: 実装されている
Xconfig:    実装されている
mconfig:    実装されている

例:

    # arch/i386/config.in
    bool 'Symmetric multi-processing support' CONFIG_SMP



=== hex /プロンプト/ /シンボル/ /ワード/

この動詞は、ユーザに /プロンプト/ を表示し、ユーザから値を受け取り、
その値を /シンボル/ に設定します。16 進数ならば、どのような値でも
有効な入力となります。/ワード/ はデフォルト値です。

動詞 hex は、範囲パラメータを受け付けません。

Configure:  実装されている
Menuconfig: 実装されている
Xconfig:    実装されている
mconfig:    実装されている

例:

    # drivers/sound/Config.in
    hex 'I/O base for SB Check from manual of the card' CONFIG_SB_BASE 220



=== int /プロンプト/ /シンボル/ /ワード/

この動詞は、ユーザに /プロンプト/ を表示し、ユーザから値を受け取り、
その値を /シンボル/ に設定します。/ワード/ はデフォルト値です。10
進数ならば、どのような値でも有効な入力となります。

動詞 int は、範囲パラメータを受け付けません。

Configure:  実装されている
Menuconfig: 実装されている
Xconfig:    実装されている
mconfig:    実装されている

例:

    # drivers/char/Config.in
    int 'Maximum number of Unix98 PTYs in use (0-2048)' \
        CONFIG_UNIX98_PTY_COUNT 256



=== string /プロンプト/ /シンボル/ /ワード/

この動詞は、ユーザに /プロンプト/ を表示し、ユーザから値を受け取り、
その値を /シンボル/ に設定します。/ワード/ はデフォルト値です。文字
'"' と '\\' を除き、どのような ASCII 文字列も有効な入力値となります。
Configure は、ヘルプを表示するため、入力文字列 "?" を捕捉します。

デフォルト値は必須です。

Configure:  実装されている
Menuconfig: 実装されている
Xconfig:    実装されている
mconfig:    実装されている

例:

    # drivers/sound/Config.in
    string '  Full pathname of DSPxxx.LD firmware file' \
        CONFIG_PSS_BOOT_FILE /etc/sound/dsp001.ld



=== tristate /プロンプト/ /シンボル/

この動詞は、ユーザに /プロンプト/ を表示し、ユーザから値を受け取り、
その値を /シンボル/ に設定します。有効な値は、"n", "m", または "y" です。

値 "m" は、"module" を意味し、/シンボル/ がカーネルモジュールとして
構築されるべきであることを示します。値 "m" は、その時点でシンボル
CONFIG_MODULES の値が "y" である場合のみ有効です。

動詞 tristate は、デフォルト値を持ちません。

Configure:  実装されている
Menuconfig: 実装されている
Xconfig:    実装されている
mconfig:    実装されている

例:

    # fs/Config.in
    tristate 'NFS filesystem support' CONFIG_NFS_FS



=== define_bool /シンボル/ /ワード/

この動詞は、/ワード/ の値を /シンボル/ に設定します。有効な値は、"n"
もしくは "y" です。

互換性上の理由により、値 "m" も有効です。というのも、define_tristate が
全ての個所で実装されるまでにしばらく時間がかかるからです。

Configure:  実装されている
Menuconfig: 実装されている
Xconfig:    実装されている
mconfig:    実装されている

例:

    # arch/alpha/config.in
    if [ "$CONFIG_ALPHA_GENERIC" = "y" ]
    then
            define_bool CONFIG_PCI y
            define_bool CONFIG_ALPHA_NEED_ROUNDING_EMULATION y
    fi



=== define_hex /シンボル/ /ワード/

この動詞は、/ワード/ の値を /シンボル/ に設定します。16 進数ならば、
どのような値でも有効です。

Configure:  実装されている
Menuconfig: 実装されている
Xconfig:    実装されている
mconfig:    実装されている

例:

    # Not from the corpus
    bool 'Specify custom serial port' CONFIG_SERIAL_PORT_CUSTOM
    if [ "$CONFIG_SERIAL_PORT_CUSTOM" = "y" ]; then
	hex 'Serial port number' CONFIG_SERIAL_PORT
    else
	define_hex CONFIG_SERIAL_PORT 0x3F8
    fi



=== define_int /シンボル/ /ワード/

この動詞は、/ワード/ の値を /シンボル/ に設定します。10 進数ならば
どのような値でも有効です。

Configure:  実装されている
Menuconfig: 実装されている
Xconfig:    実装されている
mconfig:    実装されている

例:

    # drivers/char/ftape/Config.in
    define_int CONFIG_FT_ALPHA_CLOCK 0



=== define_string /シンボル/ /ワード/

この動詞は、/ワード/ の値を /シンボル/ に設定します。文字 '"' と
'\\' を除き、どのような ASCII 文字列も有効な入力値となります。

Configure:  実装されている
Menuconfig: 実装されている
Xconfig:    実装されている
mconfig:    実装されている

例:

    # Not from the corpus
    define_string CONFIG_VERSION "2.2.0"



=== define_tristate /シンボル/ /ワード/

この動詞は、/ワード/ の値を /シンボル/ に設定します。有効な入力値は、
"n", "m", "y" です。

全てのインタプリタでこの動詞が実装されたら、できるだけ早い時期に、
三状態値を定義するときに define_bool のかわりに define_tristate を
使用するようにしてください。これは、静的な型チェックをおこなうことを
目標としています。

Configure:  実装されている
Menuconfig: 実装されている
Xconfig:    実装されている
mconfig:    実装されている

例:

    # drivers/video/Config.in
    if [ "$CONFIG_FB_AMIGA" = "y" ]; then
       define_tristate CONFIG_FBCON_AFB y
       define_tristate CONFIG_FBCON_ILBM y
    else
       if [ "$CONFIG_FB_AMIGA" = "m" ]; then
          define_tristate CONFIG_FBCON_AFB m
          define_tristate CONFIG_FBCON_ILBM m
       fi
    fi



=== dep_bool /プロンプト/ /シンボル/ /依存/ ...

この動詞は、依存関係リスト内の全ての依存関係を評価します。値 "y" を
持つどの依存関係も入力範囲を制限しません。値が空である依存関係は全て
無視されます。値 "n", またはその他の値 ("m" など) を持つ依存関係は全て、
入力範囲を "n" に制限します。依存関係をクォートすることは認められていま
せん。空の値を取り得るような依存関係を使用することは、推奨されません。
下記の dep_mbool も参照してください。

もしも入力範囲が一つの選択肢 "n" に制限されているならば、dep_bool は何も
言わずに "n" を /シンボル/ に設定します。入力範囲に二つ以上の選択肢がある
場合は、dep_bool は /プロンプト/ をユーザに表示し、ユーザから値を受け取り、
その値を /シンボル/ に設定します。

Configure:  実装されている
Menuconfig: 実装されている
XConfig:    実装されている
mconfig:    実装されている

例:

    # drivers/net/Config.in
    dep_bool 'Aironet 4500/4800 PCI support 'CONFIG_AIRONET4500_PCI $CONFIG_PCI

既知のバグ:
- コマンドが依存関係により無効にされている場合、Xconfig は "# foo is not set" を
  .config に書き込みません (同様に "#undef foo" を autoconf.h に書き込みません) 。



=== dep_mbool /プロンプト/ /シンボル/ /依存/ ...

この動詞は、依存関係リスト内の全ての依存関係を評価します。値 "y" または "m" を
持つどの依存関係も入力範囲を制限しません。値が空である依存関係は全て無視されます。
値 "n", またはその他の値を持つ依存関係は全て、入力範囲を "n" に制限します。依存
関係をクォートすることは認められていません。空の値を取り得るような依存関係を使用
することは、推奨されません。

もしも入力範囲が一つの選択肢 "n" に制限されているならば、dep_mbool は何も
言わずに "n" を /シンボル/ に設定します。入力範囲に二つ以上の選択肢がある
場合は、dep_mbool は /プロンプト/ をユーザに表示し、ユーザから値を受け取り、
その値を /シンボル/ に設定します。

dep_bool と dep_mbool の唯一の違いは、値 "m" を依存関係として扱う方法に
あるということに注意してください。

Configure:  実装されている
Menuconfig: 実装されている
XConfig:    実装されている
mconfig:    実装されている

例:

    # Not from the corpus
    dep_mbool 'Packet socket: mmapped IO' CONFIG_PACKET_MMAP $CONFIG_PACKET

既知のバグ:
- コマンドが依存関係により無効にされている場合、Xconfig は "# foo is not set" を
  .config に書き込みません (同様に "#undef foo" を autoconf.h に書き込みません) 。



=== dep_hex /プロンプト/ /シンボル/ /ワード/ /依存/ ...
=== dep_int /プロンプト/ /シンボル/ /ワード/ /依存/ ...
=== dep_string /プロンプト/ /シンボル/ /ワード/ /依存/ ...

これらの動詞のセマンティックスについては、現在検討中です。

Configure:  実装されていない
Menuconfig: 実装されていない
XConfig:    実装されていない
mconfig:    実装されていない



=== dep_tristate /プロンプト/ /シンボル/ /依存/ ...

この動詞は、依存関係リスト内の全ての依存関係を評価します。値 "y" を
持つどの依存関係も入力範囲を制限しません。値 "m" を持つ依存関係は全て
入力範囲を "m" もしくは "n" に制限します。値が空である依存関係は全て
無視されます。値 "n", またはその他の値を持つ依存関係は全て入力範囲を
"n" に制限します。依存関係をクォートすることは認められていません。空の
値を取り得るような依存関係を使用することは、推奨されません。

もしも入力範囲が一つの選択肢 "n" に制限されているならば、dep_tristate は
何も言わずに "n" を /シンボル/ に設定します。入力範囲に二つ以上の選択肢が
ある場合は、dep_tristate は /プロンプト/ をユーザに表示し、ユーザから値を
受け取り、その値を /シンボル/ に設定します。

Configure:  実装されている
Menuconfig: 実装されている
Xconfig:    実装されている
mconfig:    実装されている

例:

    # drivers/char/Config.in
    dep_tristate 'Parallel printer support' CONFIG_PRINTER $CONFIG_PARPORT

既知のバグ:
- コマンドが依存関係により無効にされている場合、Xconfig は "# foo is not set" を
  .config に書き込みません (同様に "#undef foo" を autoconf.h に書き込みません) 。



=== unset /シンボル/ ...

この動詞は、値 "" を /シンボル/ に設定します。しかし、/シンボル/ を出力結果
には含めません。この動詞の存在は、探究する価値があります。これにより、変化
しうるセマンティックスがランダム実行言語に与えられ、より深い問題が扱われる
ようになります。

Configure:  実装されている
Menuconfig: 実装されている
Xconfig:    実装されている (バグあり)
mconfig:    実装されている

例:

    # arch/mips/config.in
    unset CONFIG_PCI
    unset CONFIG_MIPS_JAZZ
    unset CONFIG_VIDEO_G364



=== choice /プロンプト/ /ワード/ /ワード/

この動詞は、選択リスト、いわゆる "ラジオボタンリスト" 選択を実装します。
choice は、 /プロンプト/ を、そして同様に、対応するシンボルを持つサブ
プロンプトのグループを、ユーザに表示します。

ユーザが値を選択すると、動詞 choice は対応するシンボルを "y" にセットし、
その選択リスト内の他のシンボルを全て "n" にセットします。

二番目の引数は、サブプロンプトとシンボル名の組を列挙した、シングルクォート
またはダブルクォートされたワードです。インタプリタはこのワードをスペース
境界でサブワードのリストに分けます。一番目のサブワードは一番目のプロンプトに、
二番目のサブワードは一番目のシンボルになります。三番目のサブワードは二番目の
プロンプトに、四番目のサブワードは二番目のシンボルになります。全てのサブ
ワードに対して、以下同様です。

三番目のワードはリテラルです。その値は、どれか一つのプロンプトに対して
厳密に一対一対応する一意な省略形でなければなりません。このプロンプトに
対応するシンボルは、デフォルトでイネーブルにされるシンボルです。

動詞 choice の構文上の理由により、サブプロンプトにスペースを含めることが
できないということに注意してください。

Configure:  実装されている
Menuconfig: 実装されている
Xconfig:    実装されている
mconfig:    実装されている

例:

    # arch/i386/config.in
    choice '  PCI access mode' \
        "BIOS           CONFIG_PCI_GOBIOS       \
         Direct         CONFIG_PCI_GODIRECT     \
         Any            CONFIG_PCI_GOANY"       Any



=== nchoice /プロンプト/ /シンボル/ /プロンプト/ /シンボル/ ...

この動詞は、choice と同じセマンティックスを持ちますが、構文はしっかり
しています。

最初の /プロンプト/ は、全選択リスト用のマスタープロンプトです。

最初の /シンボル/ は、イネーブルにされるデフォルトのシンボルです
(これはシンボルであり、一意なプロンプトの省略形ではありません) 。

あとに続く /プロンプト/ と /シンボル/ の組は、選択リストのプロンプトと
シンボルです。

Configure:  実装されていない
Menuconfig: 実装されていない
XConfig:    実装されていない
mconfig:    実装されている



=== if [ /式/ ] ; then

これは条件文で、オプションとして 'else' 節を付けることができます。
お望みなら、セミコロンのかわりに改行を使ってもかまいません。

/式/ には、下記のアトムと演算子を含めることができます。シェルとは異なり、
全てのアトムはダブルクォートする必要があるということに注意してください。

    /アトム/:
        "..."                   リテラル
        "$..."                  変数

    /式/:
        /アトム/  = /アトム/    両方のアトムが同じ値を持っていれば、真
        /アトム/ != /アトム/    両方のアトムが異なる値を持っていれば、真

    /式/:
        /式/ -o /式/            どちらかの式が真ならば、真
        /式/ -a /式/            両方の式が真ならば、真
        ! /式/                  式が偽ならば、真

裸の /アトム/ は有効な /式/ ではないということに注意してください。
もしも次のように使おうとすると、

    # Do not do this.
    if [ "$CONFIG_EXPERIMENTAL" ]; then
	bool 'Bogus experimental feature' CONFIG_BOGUS
    fi

... 驚くことになります。というのは、CONFIG_EXPERIMENTAL は決して空文字列
という値を持つことはないからです！ 値は常に "y" もしくは "n" であり、 bash
ベースのインタプリタである Configure と Menuconfig では、これらは両方とも
真 (空ではない) として扱われてしまいます。

Configure:  実装されている
Menuconfig: 実装されている
XConfig:    実装されているが、バグがある
mconfig:    実装されている

Xconfig には既知のバグがあり、また、おそらく未知のバグも幾つかあります:

- 空の値 "" を持つリテラルは、適切に扱われません。



=== mainmenu_option next_comment

この動詞は、新しいメニューを開始します。次の文は、動詞 comment でなければ
なりません。動詞 comment の /プロンプト/ は、メニューのタイトルになります
(なぜ初めの設計者が動詞 'menu ...' を作らなかったのかは分かりません) 。

どのメニューの範囲からもはずれる文は、暗黙的に存在するトップメニューの中に
置かれます。トップメニューのタイトルの選ばれ方にはいろいろあり、それはインタ
プリタに依存します。

Configure:  実装されている
Menuconfig: 実装されている
Xconfig:    実装されている
mconfig:    実装されている



=== endmenu

この動詞は、メニューの範囲を閉じます。

Configure:  実装されている
Menuconfig: 実装されている
Xconfig:    実装されている
mconfig:    実装されている



=== source /ワード/

この動詞は、リテラル /ワード/ をファイル名として解釈し、そのファイルの
内容を挿入します。ワードは、クォートされていない単一リテラルでなければ
なりません。

この動詞を実行時に解釈するインタプリタもあれば、パース時に解釈する
インタプリタもあります。

挿入は、C プリプロセッサの #include ファシリティのように、記述されたとおりに
実行されます。source は、サブメニューや何らかのブロックネスティングを暗示する
ものではありません。

Configure:  実装されている (実行時)
Menuconfig: 実装されている (パース時)
Xconfig:    実装されている (パース時)
mconfig:    実装されている (パース時)
