0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

teratermマクロ iniファイルの項目を全て配列に格納するサブルーチン

Posted at

teratermのマクロ苦し過ぎる
もう少し頭が良ければなと泣きながら勉強したのでアウトプット

  1. INI解析マクロ (ini_parser.ttl) - 3配列版
    ファイル名: ini_parser.ttl
; ===================================================
; INIファイルパーサー・ユーティリティ (ini_parser.ttl)
; 結果をセクション、キー、値の3配列に格納する
; ===================================================

; ---------------------------------------------------
; サブルーチン: ParseIniFile
; パス1で項目数をカウントし、パス2で3配列に格納する
;
; [入力]
;   INI_PATH (グローバル変数): 読み込むINIファイルのフルパス
;
; [出力(グローバル変数)]
;   ini_item_count : 読み込んだ設定項目の総数
;   ini_sections   : セクション名を格納する配列 (例: Server)
;   ini_keys       : キー名を格納する配列 (例: Host)
;   ini_values     : 値を格納する配列 (例: 192.168.1.1)
; ---------------------------------------------------
:ParseIniFile
    ; --- 出力変数の初期化 ---
    ini_item_count = 0
    current_section_name = ''

    ; ===================================================
    ; --- パス1: INIファイルの総項目数をカウント ---
    ; ===================================================
    fileopen fhandle INI_PATH 1
    if result=0 then
        messagebox '設定ファイルが開けません' INI_PATH
        return
    endif

    :count_loop
        filereadln fhandle line
        if result=0 goto count_end
        strtrim line ' ' 3
        strlen line
        if result=0 continue
        strcopy line 1 1 test_char
        if test_char=';' continue

        strscan line '['
        is_section_start = result
        strscan line ']'
        is_section_end = result
        if is_section_start=1 && is_section_end>1 then
            ; [修正] セクション名の両端の[]を除去して保持
            strcopy line 2 is_section_end-2 current_section_name
            continue
        endif

        strscan line '='
        if result > 1 && current_section_name != '' then
            ini_item_count = ini_item_count + 1 ; キー=値 の行
        endif
    goto count_loop

:count_end
    fileclose fhandle

    if ini_item_count = 0 then
        return
    endif

    ; --- カウントした項目数に基づき、3配列を初期化 ---
    for i 1 ini_item_count
        ini_sections[i] = ''
        ini_keys[i] = ''
        ini_values[i] = ''
    next

    ; ===================================================
    ; --- パス2: INIファイルの内容を3配列に格納 ---
    ; ===================================================
    fileopen fhandle INI_PATH 1
    if result=0 then
        messagebox '設定ファイルが開けません(パス2)' INI_PATH
        return
    endif

    current_section_name = ''
    current_index = 0

    :parse_loop
        filereadln fhandle line
        if result=0 goto parse_end
        strtrim line ' ' 3
        strlen line
        if result=0 continue
        strcopy line 1 1 test_char
        if test_char=';' continue

        strscan line '['
        is_section_start = result
        strscan line ']'
        is_section_end = result
        if is_section_start=1 && is_section_end>1 then
            ; [修正] セクション名の両端の[]を除去して保持
            strcopy line 2 is_section_end-2 current_section_name
            continue
        endif

        strscan line '='
        equal_pos = result
        if equal_pos > 1 && current_section_name != '' then
            current_index = current_index + 1

            ; --- キーを取得 ---
            key_len = equal_pos - 1
            strcopy line 1 key_len key
            strtrim key ' ' 3
            ; --- 値を取得 ---
            strlen line line_len
            val_start = equal_pos + 1
            val_len = line_len - equal_pos
            strcopy line val_start val_len value
            strtrim value ' ' 3

            ; --- 3配列に格納 ---
            ini_sections[current_index] = current_section_name
            ini_keys[current_index] = key
            ini_values[current_index] = value
        endif
    goto parse_loop

:parse_end
    fileclose fhandle
    return
  1. 呼び出し元マクロ (main.ttl)

ファイル名: main.ttl

; ===================================================
; メインマクロ (main.ttl)
; 3配列(セクション, キー, 値)を受け取り、指定形式で表示
; ===================================================
include 'ini_parser.ttl'

; --- INIファイルのパスを指定 ---
INI_FILE = 'settings.ini'
getdir MACRO_DIR
strconcat INI_PATH MACRO_DIR
strconcat INI_PATH '\'
strconcat INI_PATH INI_FILE

; --- INI解析処理を呼び出す ---
call ParseIniFile

;
; ▼▼▼ この時点で、以下の4つの変数が利用可能 ▼▼▼
;
;   ini_item_count : 項目数 (例: 3)
;   ini_sections   : セクション名の配列
;   ini_keys       : キーの配列
;   ini_values     : 値の配列
;
; ▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲
;

; --- 受け取った配列の中身を、ご要望の形式で表示 ---
sprintf2 title 'INIファイルから取得した全 %d 項目' ini_item_count

message = ''

; `ini_item_count` の回数だけループ
for i 1 ini_item_count
    
    ; ご要望の形式で1行の文字列を組み立てる
    sprintf2 line "SECTION=%s\nKEY=%s\nVALUE=%s\n" ini_sections[i] ini_keys[i] ini_values[i]
    
    ; 項目間に区切り線を入れる
    if i > 1 then
        strconcat message "--------------------\n"
    endif
    
    ; メッセージに連結
    strconcat message line
next

; 組み立てたメッセージをメッセージボックスで表示
messagebox message title
3. INIファイル (settings.ini)
変更不要です。

ファイル名: settings.ini

Ini, TOML

; テスト用設定
[Server]
Host=192.168.1.1
User=admin

[Options]
LogLevel=3
実行結果
main.ttl を実行すると、ini_parser.ttl が呼び出され、以下の内容のメッセージボックスが表示されます。

INIファイルから取得した全 3 項目
---------------------------
SECTION=Server
KEY=Host
VALUE=192.168.1.1
--------------------
SECTION=Server
KEY=User
VALUE=admin
--------------------
SECTION=Options
KEY=LogLevel
VALUE=3

(KEY= Host ではなく KEY=Host になっていますが、これは ini_parser.ttl 側でキーの前後の空白を strtrim で除去しているため。もし KEY= Host のようにキーの前の空白を残したい場合はini_parser.ttl 内の strtrim key ' ' 3 の行をコメントアウトしてください。)

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?