# 帳票設計書 7-デバッガ ソースリスト出力

## 概要

mrubyデバッガ(mrdb)のlistコマンドによるソースコードの行番号付き表示に関する帳票設計書である。.rbファイルの指定範囲を標準出力に表示する。

### 本帳票の処理概要

本帳票は、mrubyデバッガ(mrdb)のlistコマンドで、デバッグ中のRubyソースファイル(.rb)の指定行範囲を行番号付きで標準出力に表示する機能である。`mrb_debug_list`関数により実装され、ソースファイルの検索パス解決も行う。

**業務上の目的・背景**：デバッグセッション中に、現在の実行位置周辺のソースコードを確認するために必要な機能である。ブレークポイント設定や変数値の確認と合わせて使用することで、効率的なデバッグが可能になる。

**帳票の利用シーン**：mrdbデバッガのプロンプトでlistコマンドを実行した際に出力される。例: `(mrdb) list 10 20`（10行目から20行目を表示）。

**主要な出力内容**：
1. 行番号（8桁左詰め）
2. ソースコードの各行テキスト

**帳票の出力タイミング**：デバッガプロンプトでlistコマンドを入力した際に即時出力される。

**帳票の利用者**：mrubyアプリケーション開発者（デバッグ時）。

## 帳票種別

テキスト出力（stdoutへのソースコード行番号付き表示）

## 利用画面

| 画面No | 画面名 | URL/ルーティング | 出力操作 |
|--------|--------|-----------------|---------|
| - | mrdbデバッガ | `(mrdb) list [line_min] [line_max]` | listコマンド実行 |

## 出力形式

### 基本仕様

| 項目 | 内容 |
|-----|------|
| ファイル形式 | テキスト（stdout） |
| 用紙サイズ | N/A |
| 向き | N/A |
| ファイル名 | N/A（標準出力） |
| 出力方法 | printf / fgets（stdout） |
| 文字コード | UTF-8 / ASCII |

### PDF固有設定

N/A

### Excel固有設定

N/A

## 帳票レイアウト

### レイアウト概要

```
10      puts "hello"
11      x = 1 + 2
12      puts x
```

### ヘッダー部

N/A

### 明細部

| No | 項目名 | 説明 | データ取得元 | 表示形式 | 列幅 |
|----|-------|------|-------------|---------|-----|
| 1 | 行番号 | ソースファイルの行番号 | `file->lineno` | `%-8d` (8桁左詰め) | 8 |
| 2 | ソースコード | 該当行のテキスト | `fgets(buf, ...)` | テキスト | 可変 |

### フッター部

N/A

## 出力条件

### 抽出条件

| 条件名 | 説明 | 必須 |
|-------|------|-----|
| ソースファイル | .rb拡張子のRubyソースファイル | Yes |
| 開始行番号 | 表示開始行 (line_min) | Yes |
| 終了行番号 | 表示終了行 (line_max >= line_min) | Yes |

### ソート順

| 優先度 | 項目 | 昇順/降順 |
|-------|------|---------|
| 1 | 行番号 | 昇順 |

### 改ページ条件

N/A

## データベース参照仕様

### 参照テーブル一覧

| テーブル名 | 用途 | 結合条件 |
|-----------|------|---------|
| source_file (構造体) | ソースファイル情報 | ファイルパスからオープン |

### テーブル別参照項目詳細

#### source_file

| 参照項目（フィールド名） | 帳票項目との対応 | 取得条件 | 備考 |
|-------------------|----------------|---------|------|
| path | ファイルパス | 常時 | mrdb_strdupで複製 |
| lineno | 現在読み込み行番号 | 常時 | uint16_t, 1から開始 |
| fp | ファイルポインタ | 常時 | fopenで取得 |

## 計算仕様

### 計算項目一覧

| 項目名 | 計算式 | 端数処理 | 備考 |
|-------|-------|---------|------|
| ソースファイルパス | srcpath/dirname/カレントの順で検索 | なし | build_path関数 |

## 処理フロー

### 出力フロー

```mermaid
flowchart TD
    A[listコマンド入力] --> B[mrb_debug_list呼び出し]
    B --> C{引数検証}
    C -->|NULL引数| D[MRB_DEBUG_INVALID_ARGUMENT返却]
    C -->|OK| E{.rb拡張子?}
    E -->|No| F[.rbファイルのみサポートメッセージ]
    E -->|Yes| G{line_min <= line_max?}
    G -->|No| H[INVALID_ARGUMENT返却]
    G -->|Yes| I[source_file_new: ファイルオープン]
    I --> J{ファイルオープン成功?}
    J -->|No| K[Invalid source file メッセージ]
    J -->|Yes| L[show_lines: 行範囲表示]
    L --> M[source_file_free: クリーンアップ]
    M --> N[MRB_DEBUG_OK返却]
```

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 表示メッセージ | 対処方法 |
|----------|---------|--------------|---------|
| 引数不正 | mrb/dbg/filenameがNULL | - | 引数を確認 |
| 拡張子不正 | .rb以外のファイル | `List command only supports .rb file.` | .rbファイルを指定 |
| 行範囲不正 | line_min > line_max | - | 行範囲を修正 |
| ファイルオープン失敗 | ファイルが見つからない | `Invalid source file named %s.` | ファイルパスと検索パスを確認 |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定データ件数 | 1ファイルの指定行範囲（通常10-20行程度） |
| 目標出力時間 | ミリ秒単位 |
| 同時出力数上限 | 1 |

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

- ソースファイルの内容が標準出力に表示されるため、機密コードの露出に注意
- 検索パスの解決により、意図しないファイルが読み込まれる可能性がある

## 備考

- ソースファイル検索は3段階で行われる: (1)srcpath、(2)IRPEデバッグ情報のdirname、(3)カレントディレクトリ
- 改行コードはCR/LF/CRLFすべてに対応（remove_newlines関数）
- 行番号は8桁左詰め（`%-8d`）で表示される
- LINE_BUF_SIZEはMAX_COMMAND_LINEと同値

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | apilist.c | `mrbgems/mruby-bin-debugger/tools/mrdb/apilist.c` | `source_file`構造体（18-22行目）: path, lineno, fpフィールド |

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | apilist.c | `mrbgems/mruby-bin-debugger/tools/mrdb/apilist.c` | `mrb_debug_list`（209-238行目）: listコマンドのメイン処理 |

**主要処理フロー**:
1. **214-216行目**: NULL引数チェック
2. **218-223行目**: .rb拡張子チェック
3. **225-227行目**: 行範囲チェック（line_min <= line_max）
4. **229-233行目**: source_file_new→show_lines→source_file_free

#### Step 3: ソースファイル表示処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | apilist.c | `mrbgems/mruby-bin-debugger/tools/mrdb/apilist.c` | `show_lines`（136-167行目）: 行範囲のソースコード表示 |
| 3-2 | apilist.c | `mrbgems/mruby-bin-debugger/tools/mrdb/apilist.c` | `remove_newlines`（104-133行目）: 改行コード処理 |
| 3-3 | apilist.c | `mrbgems/mruby-bin-debugger/tools/mrdb/apilist.c` | `mrb_debug_get_source`（170-206行目）: ソースファイル検索 |

**主要処理フロー**:
- **145行目**: fgetsでバッファに1行読み込み
- **146行目**: remove_newlinesで改行を除去
- **148-151行目**: line_min以上の行で行番号を`%-8d`形式で出力
- **153行目**: ソースコード行テキストを出力

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

```
mrb_debug_list() [apilist.c:209]
    │
    ├─ source_file_new() [apilist.c:80]
    │      └─ fopen() ← ファイルオープン
    │
    ├─ show_lines() [apilist.c:136]
    │      ├─ fgets() ← 1行読み込み
    │      ├─ remove_newlines() [apilist.c:104]
    │      └─ printf("%-8d") ← 行番号付き出力
    │
    └─ source_file_free() [apilist.c:25]
           └─ fclose() ← ファイルクローズ

mrb_debug_get_source() [apilist.c:170]
    ├─ dirname() [apilist.c:64]
    └─ build_path() [apilist.c:40]
```

### データフロー図

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

ファイル名 + 行範囲 ──▶ mrb_debug_list() ───────▶ stdout
                          │                        │
                          ├─ ファイルオープン         │
                          ├─ fgets (行読み込み)      │
                          ├─ remove_newlines        │
                          └─ printf (行番号+テキスト) │
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| apilist.c | `mrbgems/mruby-bin-debugger/tools/mrdb/apilist.c` | ソース | listコマンド・ソースファイル表示のコア実装 |
| apilist.h | `mrbgems/mruby-bin-debugger/tools/mrdb/apilist.h` | ヘッダー | mrb_debug_list関数宣言 |
| mrdb.h | `mrbgems/mruby-bin-debugger/tools/mrdb/mrdb.h` | ヘッダー | mrdb_state, mrb_debug_context構造体定義 |
| apistring.h | `mrbgems/mruby-bin-debugger/tools/mrdb/apistring.h` | ヘッダー | mrdb_strdup, mrdb_strndup関数宣言 |
