# 通知設計書 23-terminfo不正行警告

## 概要

本ドキュメントは、Juliaのterminfo定数データ生成処理において、ncursesの定義ファイルを解析中に不正な行やサポートされていない型が検出された場合に出力される警告通知の設計を記述する。

### 本通知の処理概要

本通知は、`base/terminfo_data.jl` のビルド時コード生成スクリプト内で、ncursesのCapabilitiesファイル（`Caps`, `Caps-ncurses`）を解析する際に、不正なフォーマットの行や認識できないケイパビリティ型・データ型が検出された場合に警告を出力するものである。

**業務上の目的・背景**：Juliaのターミナル機能（色出力、カーソル制御など）は、terminfoデータベースに基づいて端末のケイパビリティを判定する。このデータはncursesの定義ファイルから自動生成される。解析中に不正な行が見つかった場合、データ生成の品質を保証するために開発者に警告する必要がある。

**通知の送信タイミング**：`terminfo_data.jl` のコード生成部分（`#=run ... =#` ブロック内のスクリプト）が実行される際に、以下の4つのケースで発生する。
1. 標準ケイパビリティファイルの行が不正なフォーマットの場合（59行目）
2. 標準ケイパビリティファイルの型が認識できない場合（67行目）
3. ユーザーケイパビリティファイルの行が不正なフォーマットの場合（80行目）
4. ユーザーケイパビリティファイルのデータ型が認識できない場合（90行目）

**通知の受信者**：Julia開発者（terminfo_data.jl の再生成を行う開発者）。

**通知内容の概要**：不正な行の内容、または認識できない型名を表示する。

**期待されるアクション**：開発者は、ncursesの定義ファイルフォーマットが変更されていないか確認し、必要に応じてパーサーを更新する。

## 通知種別

ログ（Warn） -- Julia標準ロギングフレームワーク（`@warn` マクロ）によるコンソール出力

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 同期（スクリプト実行時に即時出力） |
| 優先度 | 中（ログレベル Warn） |
| リトライ | 無し（ログ出力であるため） |

### 送信先決定ロジック

Julia の標準ロギングフレームワークに従い、`stderr` に出力される。

## 通知テンプレート

### メール通知の場合

該当なし（コンソールログ出力）

### 本文テンプレート

以下の4パターンがある。

**パターン1: 標準ケイパビリティ不正行**
```
┌ Warning: Malformed line: "..."
└ @ Main base/terminfo_data.jl:59
```

**パターン2: 標準ケイパビリティ不明型**
```
┌ Warning: Unrecognised capability type: {type}
└ @ Main base/terminfo_data.jl:67
```

**パターン3: ユーザーケイパビリティ不正行**
```
┌ Warning: Malformed line: "..."
└ @ Main base/terminfo_data.jl:80
```

**パターン4: ユーザーケイパビリティ不明データ型**
```
┌ Warning: Unrecognised data type: {type}
└ @ Main base/terminfo_data.jl:90
```

### 添付ファイル

該当なし

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| line | 不正な行の内容 | パースループ内の現在行（パターン1,3） | Yes |
| type | 認識できない型名文字列 | `split(line, '\t')` の結果から抽出（パターン2,4） | Yes |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| データ解析 | 標準Capsファイルの行解析 | `length(components) not in 8:9` | タブ区切りのコンポーネント数が8-9でない場合 |
| データ解析 | 標準Capsファイルの型判定 | `type not in ["bool", "num", "str"]` | ケイパビリティ型がbool/num/strのいずれでもない場合 |
| データ解析 | ユーザーCapsファイルの行解析 | `length(components) not in 4:5` | タブ区切りのコンポーネント数が4-5でない場合 |
| データ解析 | ユーザーCapsファイルのデータ型判定 | `dtype === nothing` | Bool/Int/Stringのいずれにもマッピングできない場合 |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| コメント行 | `startswith(line, '#')` の場合はスキップ |
| 非userdef行 | ユーザーCaps処理で `!startswith(line, "userdef")` の場合はスキップ |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[ncurses Capsファイル読み込み] --> B[行ごとにイテレーション]
    B --> C{コメント行?}
    C -->|Yes| B
    C -->|No| D[タブ区切りで分割]
    D --> E{コンポーネント数チェック}
    E -->|不正| F["@warn Malformed line"]
    F --> B
    E -->|正常| G{型チェック}
    G -->|不明| H["@warn Unrecognised type"]
    H --> B
    G -->|正常| I[ケイパビリティ登録]
    I --> B
```

## データベース参照・更新仕様

### 参照テーブル一覧

該当なし（外部ncursesファイルを入力として使用）

### 更新テーブル一覧

| データ構造 | 更新内容 | 更新条件 |
|----------|---------|---------|
| `TERM_FLAGS` | (name, shortcode, description) 追加 | `type == "bool"` |
| `TERM_NUMBERS` | (name, shortcode, description) 追加 | `type == "num"` |
| `TERM_STRINGS` | (name, shortcode, description) 追加 | `type == "str"` |
| `TERM_USER` | (dtype, code, description) 追加 | ユーザーケイパビリティとして正常解析された場合 |

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| 不正行 | コンポーネント数が期待と異なる | 警告を出力して該当行をスキップし、処理を継続 |
| 不明型 | 型文字列が既知の型にマッチしない | 警告を出力して該当行をスキップし、処理を継続 |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | 0（リトライなし） |
| リトライ間隔 | 該当なし |
| リトライ対象エラー | 該当なし |

## 配信設定

### レート制限

| 項目 | 内容 |
|-----|------|
| 1分あたり上限 | 制限なし（ビルド時の1回実行で全行を処理） |
| 1日あたり上限 | 制限なし |

### 配信時間帯

制限なし（ビルドスクリプト実行時）

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

外部のncursesソースから取得したデータの内容がログに含まれるが、これはオープンソースのターミナルケイパビリティ定義であり、機密情報ではない。

## 備考

- このコードは `#=run ... =#` ブロック内にあり、通常のJulia実行時には動作しない。`terminfo_data.jl` の再生成時のみ実行されるビルドスクリプトである
- ncursesのCapsファイルはGitHubの `ThomasDickey/ncurses-snapshots` リポジトリからダウンロードされる
- 警告が出力されても処理は `continue` で継続され、不正行はスキップされる

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | terminfo_data.jl | `base/terminfo_data.jl` | 13-33行目: `TermCapability` 構造体の定義 |
| 1-2 | terminfo_data.jl | `base/terminfo_data.jl` | 48-51行目: `TERM_FLAGS`, `TERM_NUMBERS`, `TERM_STRINGS`, `TERM_USER` の定義 |

**読解のコツ**: これらのデータ構造はビルドスクリプト内の `NTuple{3, String}[]` として定義される。最終的に `TermCapability` 型に変換されてJuliaのソースコードに埋め込まれる。

#### Step 2: エントリーポイントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | terminfo_data.jl | `base/terminfo_data.jl` | 35-46行目: `#=run ... =#` ブロック。ビルドスクリプトの開始。ncursesファイルのダウンロード |
| 2-2 | terminfo_data.jl | `base/terminfo_data.jl` | 8-11行目: シェルからの自動実行メカニズム |

#### Step 3: 通知発生箇所を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | terminfo_data.jl | `base/terminfo_data.jl` | 55-72行目: 標準ケイパビリティ解析ループ。59行目と67行目に `@warn` |
| 3-2 | terminfo_data.jl | `base/terminfo_data.jl` | 74-94行目: ユーザーケイパビリティ解析ループ。80行目と90行目に `@warn` |

**主要処理フロー**:
- **55行目**: `eachline(seekstart(standard_caps))` で標準Capsファイルを行ごとに読み込み
- **56行目**: コメント行（`#` 始まり）をスキップ
- **57行目**: タブ区切りで分割
- **58-59行目**: コンポーネント数が8-9でなければ `@warn "Malformed line..."` を出力して `continue`
- **63-69行目**: 型が `bool`/`num`/`str` でなければ `@warn "Unrecognised capability type..."` を出力して `continue`
- **74行目**: `eachline(seekstart(user_caps))` でユーザーCapsファイルを行ごとに読み込み
- **79-80行目**: コンポーネント数が4-5でなければ `@warn "Malformed line..."` を出力して `continue`
- **89-90行目**: データ型がマッピングできなければ `@warn "Unrecognised data type..."` を出力して `continue`

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

```
terminfo_data.jl ビルドスクリプト (#=run...=#)
    │
    ├─ Downloads.download(VERSION_URL, version_info) [44行目]
    ├─ Downloads.download(STANDARD_CAPS_URL, standard_caps) [45行目]
    ├─ Downloads.download(USER_CAPS_URL, user_caps) [46行目]
    │
    ├─ 標準ケイパビリティ解析ループ [55-72行目]
    │      ├─ @warn "Malformed line: ..." [59行目]
    │      └─ @warn "Unrecognised capability type: ..." [67行目]
    │
    ├─ ユーザーケイパビリティ解析ループ [74-94行目]
    │      ├─ @warn "Malformed line: ..." [80行目]
    │      └─ @warn "Unrecognised data type: ..." [90行目]
    │
    └─ コード生成出力 [99行目以降]
```

### データフロー図

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

ncurses Caps ファイル ────────▶ 行解析ループ ─────────────────▶ TERM_FLAGS
  (Downloads.download)         │                               TERM_NUMBERS
                               ├─ コンポーネント数チェック ──▶  TERM_STRINGS
                               │     └─ 不正 ──▶ @warn ──▶ stderr
ncurses Caps-ncurses ────────▶ │
  (Downloads.download)         ├─ 型チェック ────────────────▶ TERM_USER
                               │     └─ 不明 ──▶ @warn ──▶ stderr
                               │
                               └─ コード生成 ───────────────▶ terminfo.jl 定数
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| terminfo_data.jl | `base/terminfo_data.jl` | ソース | 通知の発生元。terminfoデータ生成スクリプト |
| terminfo.jl | `base/terminfo.jl` | ソース | 生成された定数を使用するterminfo実装 |
| logging.jl | `base/logging/logging.jl` | ソース | `@warn` マクロの実装 |
