# 機能設計書 72-parseopt

## 概要

本ドキュメントは、Nim標準ライブラリのparseoptモジュールの機能設計について記載する。本モジュールはコマンドラインオプション解析機能を提供し、CLIアプリケーション開発における引数処理を支援する。

### 本機能の処理概要

parseoptモジュールは、コマンドライン引数を解析し、オプション（短形式・長形式）と引数を識別する機能を提供する。3つのパーサーモード（NimMode、LaxMode、GnuMode）をサポートし、様々なコマンドライン規約に対応可能である。

**業務上の目的・背景**：CLIアプリケーションやスクリプト、ビルドツールなどでは、ユーザーからのコマンドライン入力を適切に解析する必要がある。本モジュールは、短形式オプション（-a）、長形式オプション（--option）、位置引数を統一的に処理し、アプリケーション開発の生産性を向上させる。POSIXやGNUスタイルの引数規約にも対応している。

**機能の利用シーン**：
- CLIアプリケーションの引数解析
- ビルドスクリプトのオプション処理
- システム管理ツールの開発
- テストランナーのパラメータ処理
- NimScriptでの引数処理

**主要な処理内容**：
1. コマンドライン文字列のトークン化
2. 短形式オプション（-a, -abc, -a:value）の解析
3. 長形式オプション（--option, --option=value）の解析
4. 位置引数（ファイル名等）の識別
5. `--`による引数終端の処理

**関連システム・外部連携**：osモジュール（paramCount、paramStr経由でのシステム引数取得）と連携する。

**権限による制御**：特になし。純粋な文字列解析機能のため、権限管理は不要。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 本モジュールはGUI/画面を持たないライブラリ機能 |

## 機能種別

パーサー処理 / 文字列解析

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| cmdline | string / seq[string] | No | コマンドライン引数（空の場合はOS引数を使用） | - |
| shortNoVal | set[char] | No | 値を取らない短形式オプションの集合 | - |
| longNoVal | seq[string] | No | 値を取らない長形式オプションのリスト | - |
| mode | CliMode | No | パーサーモード（デフォルト: NimMode） | NimMode/LaxMode/GnuMode |

### 入力データソース

- 文字列リテラル
- seq[string]（引数リスト）
- osモジュール経由のシステム引数

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| kind | CmdLineKind | トークン種別（cmdEnd/cmdArgument/cmdLongOption/cmdShortOption） |
| key | string | オプション名または引数値 |
| val | string | オプションの値（値がない場合は空文字列） |

### 出力先

- OptParserオブジェクトのフィールド（kind, key, val）
- イテレータからのタプル出力

## 処理フロー

### 処理シーケンス

```
1. OptParser初期化（initOptParser）
   └─ コマンドライン取得、パーサールール設定
2. トークン解析ループ（next）
   └─ 空白スキップ、トークン種別判定
3. オプション/引数識別
   ├─ "-"で始まる: 短形式オプションまたは長形式オプション
   ├─ "--"で始まる: 長形式オプション
   └─ それ以外: 引数
4. 値の取得
   ├─ 区切り文字（:, =）の後ろの値
   ├─ 隣接する値（-j4形式）
   └─ 次の引数（-c value形式、モードによる）
5. 解析終了（cmdEnd）
```

### フローチャート

```mermaid
flowchart TD
    A[開始: initOptParser] --> B[next呼び出し]
    B --> C{インデックス >= 引数数?}
    C -->|Yes| D[cmdEnd]
    C -->|No| E{先頭文字判定}
    E -->|"-"| F{2文字目が"-"?}
    E -->|その他| G[cmdArgument]
    F -->|Yes| H[cmdLongOption]
    F -->|No| I[cmdShortOption]
    H --> J[オプション名解析]
    I --> K[handleShortOption]
    J --> L{区切り文字あり?}
    L -->|Yes| M[値取得]
    L -->|No| N{次引数から値取得?}
    N -->|Yes| O[次引数を値として取得]
    N -->|No| P[値なし]
    K --> Q{バンドル継続?}
    Q -->|Yes| B
    Q -->|No| R[完了]
    G --> R
    M --> R
    O --> R
    P --> R
    D --> S[終了]
    R --> B
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-72-01 | 短形式バンドル | -abcは-a, -b, -cとして解析 | shortNoVal指定時 |
| BR-72-02 | 区切り文字 | `:` と `=` をサポート（GnuModeは`=`のみ） | 常時 |
| BR-72-03 | 空オプション | `--`は名前が空の長形式オプション | 常時 |
| BR-72-04 | 隣接値 | -j4は-jオプションの値4として解析 | shortNoVal指定時 |

### 計算ロジック

パーサールール（toRules関数）によるモード別動作:

**NimMode** (デフォルト):
- Common + Laxルールセット
- 区切り文字: `:` と `=`
- 次引数値取得: 長形式のみ

**LaxMode**:
- Common + Lax + ShortPosixルールセット
- 最も寛容なモード
- 短形式でも次引数値取得可能

**GnuMode**:
- Common + ShortPosixルールセット
- 区切り文字: `=`のみ
- GNU getopt互換を目指す

## データベース操作仕様

### 操作別データベース影響一覧

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| - | - | - | 本モジュールはデータベース操作を行わない |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| AssertionError | 実行時アサーション | 空コマンドラインかつOS引数取得不可 | 明示的なコマンドライン指定 |

### リトライ仕様

コマンドライン解析は通常1回のみ実行。エラー時は引数を修正して再実行。

## トランザクション仕様

本モジュールはパーサーのみであり、トランザクション管理は行わない。

## パフォーマンス要件

- 軽量なパーサー実装
- 文字列の部分参照（substr）による効率的な処理
- イテレータベースのメモリ効率的な処理

## セキュリティ考慮事項

- ユーザー入力のサニタイズは呼び出し側の責任
- クォート処理によるシェルインジェクション対策
- 値の検証は呼び出し側で実装が必要

## 備考

- LaxMode、GnuModeは実験的機能であり、将来変更の可能性あり
- カスタムルールセットはサポート外
- NimScriptでも利用可能

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

まず、パーサーの状態を管理するデータ構造を理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | parseopt.nim | `lib/pure/parseopt.nim` | CmdLineKind列挙型（369-373行目）: トークン種別の定義 |
| 1-2 | parseopt.nim | `lib/pure/parseopt.nim` | OptParser型（374-392行目）: パーサー状態の管理構造 |
| 1-3 | parseopt.nim | `lib/pure/parseopt.nim` | CliMode列挙型（346-351行目）: パーサーモードの定義 |
| 1-4 | parseopt.nim | `lib/pure/parseopt.nim` | ParserRules列挙型（354-366行目）: 個別パーサールール |

**読解のコツ**: OptParser型のフィールドが解析状態を表す。`kind`, `key`, `val`が公開フィールドで、`pos`, `idx`, `inShortState`等が内部状態。

#### Step 2: 初期化処理を理解する

パーサーの初期化とモード設定の流れを把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | parseopt.nim | `lib/pure/parseopt.nim` | toRules関数（396-419行目）: モードからルールセットへの変換 |
| 2-2 | parseopt.nim | `lib/pure/parseopt.nim` | initOptParser（437-473行目）: 内部初期化関数 |
| 2-3 | parseopt.nim | `lib/pure/parseopt.nim` | initOptParser公開版（475-549行目）: ユーザー向けAPI |

**主要処理フロー**:
1. **396-419行目**: toRulesでCliModeをParserRulesのセットに変換
2. **451-452行目**: 区切り文字（`:`, `=`）の設定
3. **453-473行目**: 空コマンドライン時のOS引数取得

#### Step 3: トークン解析を理解する

next関数によるトークン取得の流れを把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | parseopt.nim | `lib/pure/parseopt.nim` | next関数（625-710行目）: メイン解析ループ |
| 3-2 | parseopt.nim | `lib/pure/parseopt.nim` | handleShortOption（569-623行目）: 短形式オプション処理 |
| 3-3 | parseopt.nim | `lib/pure/parseopt.nim` | parseWord関数（421-435行目）: 単語解析 |

**主要処理フロー**:
- **641-643行目**: インデックス終端チェック → cmdEnd
- **671-706行目**: "-"で始まる場合のオプション解析
- **673-703行目**: "--"で始まる場合の長形式オプション解析
- **704-706行目**: "-"のみの場合の短形式オプション解析
- **707-710行目**: それ以外は引数として処理

#### Step 4: イテレータを理解する

getoptイテレータによる便利な使用方法を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | parseopt.nim | `lib/pure/parseopt.nim` | getopt（OptParser版）（744-780行目）: パーサーイテレータ |
| 4-2 | parseopt.nim | `lib/pure/parseopt.nim` | getopt（seq版）（782-836行目）: 便利イテレータ |

**主要処理フロー**:
- **775-780行目**: パーサーをリセットしてnextを繰り返し呼び出し
- **830-836行目**: initOptParserを内部で呼び出してイテレート

### プログラム呼び出し階層図

```
getopt(cmdline: seq[string], ...)
    │
    ├─ initOptParser(cmdline, shortNoVal, longNoVal, rules)
    │      │
    │      └─ toRules(mode) -> set[ParserRules]
    │
    └─ [ループ] next(OptParser)
           │
           ├─ handleShortOption(OptParser, cmd)
           │      └─ 短形式オプションの解析
           │
           ├─ parseWord(s, i, w, delim)
           │      └─ 単語の切り出し
           │
           └─ yield (kind, key, val)
```

### データフロー図

```
[入力]                    [処理]                         [出力]

コマンドライン    ───▶  initOptParser
文字列/seq              (初期化)
                           │
                           ▼
                      OptParser
                      (状態管理)
                           │
                           ▼
                      next()呼び出し
                      (トークン解析)
                           │
                           ▼
                      ┌─────────────┐
                      │ CmdLineKind │
                      │ key: string │  ───▶  アプリケーション
                      │ val: string │        ロジック
                      └─────────────┘
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| parseopt.nim | `lib/pure/parseopt.nim` | ソース | コマンドラインパーサーの実装 |
| os.nim | `lib/pure/os.nim` | ソース | システム引数取得（paramCount, paramStr） |
| strutils.nim | `lib/pure/strutils.nim` | ソース | 文字列ユーティリティ（toLowerAscii等） |
| inclrtl.nim | `lib/system/inclrtl.nim` | ソース | RTL（ランタイムライブラリ）インクルード |
