Newer
Older
TIASShot / TIASshot / HwTest / HwTestOptions.cs
#if HWTEST
using System;

namespace TIASshot {

    /// <summary>実機テストで使うカメラの機種(HWTEST 限定)</summary>
    internal enum HwTestCameraKind {
        /// <summary>Lumenera(Lucam)</summary>
        Lucam,
        /// <summary>ImagingSource(IScam)</summary>
        IScam,
    }

    /// <summary>
    /// 実機テスト(--hwtest)の引数(HWTEST 限定.SDK・UI に依存しない純粋な解析).
    /// <code>TIASshot.exe --hwtest --camera &lt;lucam|iscam&gt; [--hwtest-out &lt;path&gt;] [--with-chart] [--hwtest-keep]</code>
    /// </summary>
    internal sealed class HwTestOptions {

        public const string FlagHwTest = "--hwtest";
        public const string FlagCamera = "--camera";
        public const string FlagOut = "--hwtest-out";
        public const string FlagWithChart = "--with-chart";
        public const string FlagKeep = "--hwtest-keep";

        /// <summary>検査するカメラの機種</summary>
        public HwTestCameraKind Camera { get; private set; }

        /// <summary>結果ファイルの出力先(省略時は null.呼び出し側が既定のパスを決める)</summary>
        public string OutPath { get; private set; }

        /// <summary>チャートが必要な検査(calibrate・shot・close-saving・close-calibrating.PLAN_06 フェーズ 2)を行うか.指定するとチャート不要の検査は行わない(connect・cleanup は共通)</summary>
        public bool WithChart { get; private set; }

        /// <summary>合格時も作業フォルダ(一時設定・保存物)を削除しないか</summary>
        public bool Keep { get; private set; }

        /// <summary>実機テストが要求されているか(--hwtest があるか)</summary>
        public static bool IsRequested(string[] args) {
            if (args == null) return false;
            foreach (var a in args) {
                if (Is(a, FlagHwTest)) return true;
            }
            return false;
        }

        /// <summary>
        /// 引数を解析する.先頭要素が実行ファイルのパス(Environment.GetCommandLineArgs の形)でもよい.
        /// 知らないフラグ("--" 始まり)・値の欠落・--camera の指定漏れや不正値は誤りとする(打ち間違いで別の検査が走らないため).
        /// </summary>
        /// <param name="args">コマンドライン引数</param>
        /// <param name="error">誤りがあればその理由(日本語),無ければ null</param>
        /// <returns>解析結果.誤りがあれば null</returns>
        public static HwTestOptions Parse(string[] args, out string error) {
            error = null;
            if (args == null) {
                error = "引数がありません";
                return null;
            }
            var options = new HwTestOptions();
            string camera = null;
            for (var i = 0; i < args.Length; i++) {
                var a = args[i];
                if (a == null || !a.StartsWith("--", StringComparison.Ordinal)) {
                    // 実行ファイルのパス(先頭)以外の値は,直前のフラグの値として読み終えているはず
                    if (i == 0) continue;
                    error = $"不明な引数です: {a}";
                    return null;
                }
                if (Is(a, FlagHwTest)) continue;
                if (Is(a, FlagWithChart)) { options.WithChart = true; continue; }
                if (Is(a, FlagKeep)) { options.Keep = true; continue; }
                if (Is(a, FlagCamera) || Is(a, FlagOut)) {
                    var value = i + 1 < args.Length ? args[i + 1] : null;
                    if (string.IsNullOrWhiteSpace(value) || value.StartsWith("--", StringComparison.Ordinal)) {
                        error = $"{a} の値がありません";
                        return null;
                    }
                    i++;
                    if (Is(a, FlagCamera)) {
                        if (camera != null) {
                            error = $"{FlagCamera} が複数回指定されています";
                            return null;
                        }
                        camera = value;
                    } else {
                        if (options.OutPath != null) {
                            error = $"{FlagOut} が複数回指定されています";
                            return null;
                        }
                        options.OutPath = value;
                    }
                    continue;
                }
                error = $"不明なフラグです: {a}";
                return null;
            }

            if (camera == null) {
                error = $"{FlagCamera} lucam または {FlagCamera} iscam を指定してください";
                return null;
            }
            HwTestCameraKind kind;
            if (!TryParseCamera(camera, out kind)) {
                error = $"{FlagCamera} の値が不正です: {camera}(lucam または iscam)";
                return null;
            }
            options.Camera = kind;
            return options;
        }

        /// <summary>機種名(lucam / iscam.大文字小文字は区別しない)を解析する</summary>
        public static bool TryParseCamera(string value, out HwTestCameraKind kind) {
            if (string.Equals(value, "lucam", StringComparison.OrdinalIgnoreCase)) {
                kind = HwTestCameraKind.Lucam;
                return true;
            }
            if (string.Equals(value, "iscam", StringComparison.OrdinalIgnoreCase)) {
                kind = HwTestCameraKind.IScam;
                return true;
            }
            kind = HwTestCameraKind.Lucam;
            return false;
        }

        private static bool Is(string arg, string flag) {
            return string.Equals(arg, flag, StringComparison.OrdinalIgnoreCase);
        }
    }
}
#endif