全部の普通に使われているコマンドライン設定を解析するクロスプラットフォームC++のライブラリです。プログラムはASCII、MBCS(Shift-JISなど)かUnicode(UTF-8)でも可能です。全部のプラットフォームで使えるように作って、WindowsでもLinuxでもテストしました。クロスプラットフォームのglob()も含んで、コマンドラインのワイルドカード文字を検索します。MITライセンスでオーペンソースとしてリリースしました。

ドキュメンテーション

インタフェースのドキュメンテーションはオンラインか別のファイルダウンロードです。

ダウンロード

現在のSimpleOptバージョンが 3.0 (最新更新: 8日11月2007年)

ダウンロード simpleopt-3.0.zip (約55Kb)
ダウンロード Doxygen ドキュメンテーション (英語版のみ) (約65Kb)

ソースリポジトリ

全部のソースコード、デモとテストプログラムがダウンロードに入っています。プロジェクトのホームページがここだけど、ソースリポジトリがGoogle Codeで保存しています。

機能

  • MIT ライセンスだから全部のプロジェクトで使える (GPL、会社専用)
  • クロスプラットフォーム (Windows 95/98/ME/NT/2K/XP, Linux, Unix)
  • 全部のコマンドライン設定のオプションに対応:
    -オプション文字のみ (例: stdinの入力)
    -o短いオプション (1文字)
    -long長いオプション (数文字, 1フラグ文字)
    --longer長いオプション (数文字, 数フラグ文字)
    word特別の言葉がオプション、フラグ文字無し
  • 全部のコマンドラインオプションの引数に対応:
    --option(短・長) フラグだけ、引数なし
    --option ARG(短・長) 別の必要な引数
    --option=ARG(短・長) 複合の必要な引数
    --option[=ARG](短・長) 複合の選択的の引数
    -oARG(短のみ) 別の必要な引数
    -o[ARG](短のみ) 複合の選択的の引数
  • 複数か不定数の引数に対応:
    --multi ARG1 ARG2複数の引数
    --multi N ARG-1 ARG-2 ... ARG-N不定数の引数
  • 大小文字区別せずオプション一致に対応
  • 複数の短いオプションがつないでいる文字列に対応:
    foo.exe -defgcFILE==foo.exe -d -e -f -g -cFILE
  • Windowsで自動的にスラッシュ文字がハイフン(オプション文字)と同じく使う
    foo.exe /f FILE==foo.exe -f FILE
  • ファイルの引数はコマンドラインにどこでも入れても大丈夫:
    foo.exe FILE1 -a arg FILE2 --flag FILE3 FILE4
  • ファイルの引数(と不明な引数)がコマンドラインの同じ順番で返す:
    FILE1 FILE2 FILE3 FILE4
  • 短絡オプション一致: "--man" が "--mandate" と一致する (「短絡オプション一致」のセクションを参照して)
  • 無効なオプションがコマンドライン処理のうちにハンドリング可能
  • 一つのC++ヘッダーファイルだけ
  • Cランタイムライブラリ、OS関数を使わない (参照: SO_ARG_MAX)
  • char も wchar_t もWindows TCHAR が同時に使える
  • テストプログラムと自動的なテストハーネス含んでいる
  • エラー、警告なしのコンパイル: warning level 4 (Windows/VC.NET 2003), warning level 3 (Windows/VC6) and -Wall (Linux/gcc)

SimpleOpt 使い方

SimpleOpt はこの簡単段階で使えます:

  1. SimpleOpt.h ヘッダーファイルをインクルード。
    #include "SimpleOpt.h"
  2. 有効のオプションの配列を定義する。

    下記のスースで OPT_* が自分で定義した固有なオプションの識別名。テキストがオプションのテキスト。SO_* の値がオプションが引数のあるかどうかフラグ。OPT_HELP は2回使ったので、「-?」でも「--help」でも使える。

    enum { OPT_HELP, OPT_FOO, OPT_BAR, OPT_HOGE };
    CSimpleOpt::SOption g_rgOptions[] = {
        // ID       TEXT          TYPE
        { OPT_FOO,  _T("-a"),     SO_NONE    }, // "-a"
        { OPT_BAR,  _T("-b"),     SO_NONE    }, // "-b"
        { OPT_HOGE, _T("-f"),     SO_REQ_SEP }, // "-f ARG"
        { OPT_HELP, _T("-?"),     SO_NONE    }, // "-?"
        { OPT_HELP, _T("--help"), SO_NONE    }, // "--help"
        SO_END_OF_OPTIONS                       // END
    };

    Windowsでスラッシュを使えても全部のオプションがハイフンだけで始まる。コマンドラインのスラッシュがハイフンと一致するから。例えば、下記のラインがWindowsで両方の「-?」も「/?」に一致する。

        { OPT_HELP, _T("-?"),     SO_NONE    }, // "-?"
  3. CSimpleOptのオブジェクトのインスタンスを作成して、argc、argv とオプションテーブルを渡す
    CSimpleOpt args(argc, argv, g_rgOptions);
  4. falseを返すまで、Next()を呼ぶうえでオプションを処理する。毎回trueを返したら、まずエラーは発生したかどうかLastError()で確認して、エラーかオプションのことを処理する。
    while (args.Next()) {
        if (args.LastError() == SO_SUCCESS) {
            // オプション処理:
            // * OptionId() が識別名を返す (例:OPT_HOGE)
            // * OptionText() がオプションテキストを返す (例:「-f」)
            // * OptionArg() がオプション引数を返す (例:「/tmp/file.o」)
        }
        else {
            // エラー処理(ドキュメンテーションをみて: enum ESOError
        }
    }
  5. 全部のファイル(無効オプション)を File()、Files()、FileCount() で処理する
    ShowFiles(args.FileCount(), args.Files());

SimpleGlob 使い方

SimpleGlobはこの簡単段階で使えます:

  1. SimpleGlob.hヘッダーファイルをインクルード。
    #include "SimpleGlob.h"
  2. CSimpleGlobのオブジェクトのインスタンスを作成して、使いたいフラグを渡す(ドキュメンテーション参照)
    CSimpleGlob glob(SG_GLOB_NODOT|SG_GLOB_NOCHECK);
  3. Add()でファイルスペックを追加
    if (SG_SUCCESS != glob.Add(argc, argv)) {
        // エラー処理
    }
  4. FileCount() と Files() でファイル名を使う
    for (int n = 0; n < glob.FileCount(); ++n) {
        printf("file %d: '%s'\n", n, glob.File(n));
    }

例え

Basic usage of the SimpleOpt and SimpleGlob library is illustrated by the following code sample (included in the download as basicSample.cpp). This shows simple command line processing including the use of SimpleGlob to expand wildcard filenames passed on the command line.

#include "SimpleOpt.h"
#include "SimpleGlob.h"

// define the ID values to indentify the option
enum { OPT_HELP, OPT_FLAG, OPT_ARG };

// declare a table of CSimpleOpt::SOption structures. See the SimpleOpt.h header
// for details of each entry in this structure. In summary they are:
//  1. ID for this option. This will be returned from OptionId() during processing.
//     It may be anything >= 0 and may contain duplicates.

//  2. Option as it should be written on the command line
//  3. Type of the option. See the header file for details of all possible types.
//     The SO_REQ_SEP type means an argument is required and must be supplied
//     separately, e.g. "-f FILE"
//  4. The last entry must be SO_END_OF_OPTIONS.
//
CSimpleOpt::SOption g_rgOptions[] = {
    { OPT_FLAG, _T("-a"),     SO_NONE    }, // "-a"
    { OPT_FLAG, _T("-b"),     SO_NONE    }, // "-b"
    { OPT_ARG,  _T("-f"),     SO_REQ_SEP }, // "-f ARG"
    { OPT_HELP, _T("-?"),     SO_NONE    }, // "-?"
    { OPT_HELP, _T("--help"), SO_NONE    }, // "--help"
    SO_END_OF_OPTIONS                       // END
};

// show the usage of this program
void ShowUsage() {
    _tprintf(_T("Usage: basicSample [-a] [-b] [-f FILE] [-?] [--help] FILES\n"));
}

int _tmain(int argc, TCHAR * argv[]) {
    // declare our options parser, pass in the arguments from main
    // as well as our array of valid options.
    CSimpleOpt args(argc, argv, g_rgOptions);

    // while there are arguments left to process
    while (args.Next()) {
        if (args.LastError() == SO_SUCCESS) {
            if (args.OptionId() == OPT_HELP) {
                ShowUsage();
                return 0;
            }
            _tprintf(_T("Option, ID: %d, Text: '%s', Argument: '%s'\n"),
                args.OptionId(), args.OptionText(),
                args.OptionArg() ? args.OptionArg() : "");
        }
        else {
            _tprintf(_T("Invalid argument: %s\n"), args.OptionText());
            return 1;
        }
    }

    // process any files that were passed to us on the command line.
    // send them to the globber so that all wildcards are expanded
    // into valid filenames (e.g. *.cpp -> a.cpp, b.cpp, c.cpp, etc)
    // See the SimpleGlob.h header file for details of the flags.
    CSimpleGlob glob(SG_GLOB_NODOT|SG_GLOB_NOCHECK);
    if (SG_SUCCESS != glob.Add(args.FileCount(), args.Files())) {
        _tprintf(_T("Error while globbing files\n"));
        return 1;
    }

    // dump all of the details, the script that was passed on the
    // command line and the expanded file names
    for (int n = 0; n < glob.FileCount(); ++n) {
        _tprintf(_T("file %d: '%s'\n"), n, glob.File(n));
    }

    return 0;
}

Another included example 'fullSample.cpp' implements the following command line. This demonstrates all of the different types of arguments which can be parsed by SimpleOpt.

Usage: fullSample [OPTIONS] [FILES]

--exact     Disallow partial matching of option names
--noslash   Disallow use of slash as an option marker on Windows
--shortarg  Permit arguments on single letter options with no equals sign
--clump     Permit single char options to be clumped as long string
--noerr     Do not generate any errors for invalid options
--pedantic  Generate an error for petty things

-d  -e  -f  -g  -flag  --flag               Flag (no arg)
-s ARG   -sep ARG  --sep ARG                Separate required arg
-cARG    -c=ARG    -com=ARG    --com=ARG    Combined required arg
-o[ARG]  -o[=ARG]  -opt[=ARG]  --opt[=ARG]  Combined optional arg
-man     -mandy    -mandate                 Shortcut matching tests
--man    --mandy   --mandate                Shortcut matching tests
--multi0 --multi1 ARG --multi2 ARG1 ARG2    Multiple argument tests
--multi N ARG-1 ARG-2 ... ARG-N             Multiple argument tests
open read write close zip unzip             Special words

-?  -h  -help  --help                       Output this help.

If a FILE is `-', read standard input.

A third included example 'globSample.cpp' implements the a test program to test all of the flags supported by SimpleGlob.

短絡オプション一致 (SimpleOpt)

The short-circuit matching of the long option names is enabled by default. It can be disabled by passing SO_O_EXACT as one of the flags to Init(). When disabled, only exact matches are accepted for options. When enabled, matches are calculated in the following manner.

  1. an exact match takes precedence over a partial match
  2. equal partial matches returns an "SO_OPT_MULTIPLE" error
  3. a better partial match will return the matched option

For example, if the command line has the following valid options:

  • --main
  • --mainline
  • --mainlamp

The following matches would occur:

CommandlineResultWhy
--maiSO_OPT_MULTIPLEmultiple patial matches
--main--mainexact match
--mainlSO_OPT_MULTIPLEmultiple patial matches
--mainli--mainlinesingle partial match
--mainline--mainlineexact match
Stats
Powered by Website Baker