[トップ][編集][ノート][編集履歴][一覧][最近の更新][->English]

設定管理モジュール,プログラムの設定を管理したり,ファイルに書き出したり読み込んだり

用語について

エリア

他の設定に影響を及ぼさない大きな区分(SQLのテーブルに相当)

セクション

設定内の区分

扱える設定ファイルの書式

# 一行コメント(行末コメントには非対応)
セクション名 {
    キー1: 値
    キー2: 値
    キー3: 値
}

サンプル

/* 2015/8/16
 * サンプルスクリプト
 */

#include "sioc.hsp"

#define CONFIG "config.cfg"

// 初期化
sioc_init MODE_NORMAL

sioc_createArea "SampleConfig"

        // セクションを決める
        sioc_setSection "General"

        // 値を設定する
        sioc_setValue "Config1", "test1"
        sioc_setValue "Config2", "test2"
        sioc_setValue "Config3", "test3"
        
        
// 設定ファイルに出力
sioc_exportToFile CONFIG

// リセットする
sioc_resetArea

// 設定ファイルを読み込む
sioc_importFromFile CONFIG

        sioc_setSection "General"

        // 値を読み込む
        mes "Config1="+sioc_getValue("Config1")
        mes "Config2="+sioc_getValue("Config2")
        mes "Config3="+sioc_getValue("Config3")
        
sioc_end

sioc.hsp

/* 2015/09/07
 * sioc.hsp v1.4
 * 設定管理モジュール。
 * 必須: sqlele.hsp sqlite3.dll
 */
#include "sqlele.hsp"

#ifndef __CTL_SIO__
#define global __CTL_SIO__

#const global MODE_NORMAL 0
#const global MODE_DEBUG        1

#module "sioc"

#define global sioc_init(%1=0) _sioc_init %1
#deffunc _sioc_init int debug //MODE_DEBUGでデバッグ。データベースファイルが残る。
        if (initialized == 1) :return
                
        sdim nowTableID
        sdim nowSect
        nowSect = "global"
        initialized = 1

                
        if (debug) { ;on
                sql_open "debug.db"
        } else { ;off
                sql_open ":memory:"
        }

return
 
#deffunc sioc_end
        sql_close
return

                
#defcfunc sioc_newArea
        /* sioc_newArea
         * 返り値 : エリアID
         * 新しいエリア(テーブル)を作成する。
         */
                        
        nowTableID = sioc_uniqStr()
                
                
        sql =   strf("CREATE TABLE \"%s\"", nowTableID)
        sql += "("
        sql += "id INTEGER PRIMARY KEY,"
        sql += "section VARCHAR(256),"
        sql += "key VARCHAR(256) NOT NULL,"
        sql += "value VARCHAR(512)"
        sql += ")"
        sql_q sql
return nowTableID

#deffunc sioc_setFocus str ID
        /* sioc_setFocus
         * 引数 : "エリアID"
         * 対象となるエリアのIDを変更する。
         * 必ず指定するように。
         */
                        
        if (ID != "") {
                nowTableID = ID
        } else {
                return -1
        }
return

#defcfunc sioc_getFocus
        /* sioc_getFocus
         * 返り値 : エリアID
         * 現在のエリアIDを返す.
         */
        return nowTableID
        
#defcfunc sioc_uniqStr
        /* sioc_uniqStr
         * 返り値 : "ユニークな文字列"
         * 重複のない文字列を作成する。
         */
                
        result = ""
                                
        result = strf("%02d%02d%02d%02d", getTime(4), getTime(5), getTime(6), getTime(7))
return result

#deffunc sioc_createArea str id
        /* sioc_createArea
         * 引数 : "エリアID"
         * エリアIDを指定して作成する。
         */
                        
        sql = ""
        nowTableID = id
                
                
        sql =   strf("CREATE TABLE IF NOT EXISTS \"%s\"", id)
        sql += "("
        sql += "id INTEGER PRIMARY KEY,"
        sql += "section VARCHAR(256),"
        sql += "key VARCHAR(256) NOT NULL,"
        sql += "value VARCHAR(512)"
        sql += ")"
        sql_q sql
return

#deffunc sioc_importFromFile str path
        /* sioc_importFromFile
         * 引数 : "パス"
         * 現在選択されているエリアに設定ファイルを読み込む。
         * このとき初期化されるので注意。
         */
                 
        nowScope                                = "global"
        scopeStrIndex    = -1
        keyDelimitIndex = -1
        scopeEndIndex    = -1
        lineTemp                                = ""
        keyTemp                          = ""
        valueTemp                        = ""
        fileBuf                          = ""
                
                
        exist path
        if (strsize <= 0) :return -1
        sioc_resetArea
        notesel fileBuf
        noteload path
        repeat notemax
                noteget lineTemp, cnt
                lineTemp = sioc_trimWhiteSpace(lineTemp)
                        
                scopeStrIndex    = instr(lineTemp, 0, "{")
                keyDelimitIndex = instr(lineTemp, 0, ":")
                scopeEndIndex    = instr(lineTemp, 0, "}")
                        
                if (strmid(lineTemp, 0, 1) == "#") :continue
                        
                if (scopeStrIndex != -1) {
                        nowScope = strmid(lineTemp, 0, scopeStrIndex)
                }
                        
                if (scopeEndIndex != -1) {
                        nowScope = "global"
                }
                        
                if (keyDelimitIndex != -1) {
                        keyTemp  = strmid(lineTemp, 0,  keyDelimitIndex)
                        valueTemp = strmid(lineTemp, -1, strlen(lineTemp) -keyDelimitIndex -1)
                        sql =   strf("INSERT INTO \"%s\"", nowTableID)
                        sql += "("
                        sql += "section, key, value"
                        sql += ") VALUES ("
                        sql += strf("\"%s\", \"%s\", \"%s\"", nowScope, keyTemp, valueTemp)
                        sql += ")"
                        sql_q sql
                }
        loop
return
 
#deffunc sioc_exportToFile str file
        /* sioc_exportToFile
         * 引数 : "パス"
         * 現在選択されているエリアを設定ファイルに書き込む。
         */
                
        sql                              = ""
        nowScope                = "global"
        fileBuf          = ""
        keyTemp          = ""
        scopeTemp        = ""
        valueTemp        = ""
        indentLevel = 0
        
        sql = strf("SELECT * FROM \"%s\" ORDER BY \"section\" ASC, \"key\" ASC", nowTableID)
        sql_q sql
 
        len = stat
                
        notesel fileBuf
                 
        repeat len
                scopeTemp = sql_v("section")
                keyTemp  = sql_v("key")
                valueTemp = sql_v("value")
                 
                if (nowScope != scopeTemp) {
                        if (nowScope != "global") {
                                indentLevel--
                                noteadd strf("%"+(indentLevel*2)+"s}", "")
                        }
                                 
                        noteadd strf("%"+(indentLevel*2)+"s%s {", "", scopeTemp)
                        nowScope = scopeTemp
                        indentLevel++
                }
        
                noteadd strf("%"+(indentLevel*2)+"s%s: %s", "", keyTemp, valueTemp)
 
                sql_next
        loop
 
        if (nowScope != "global") {
                indentLevel--
                noteadd strf("%"+(indentLevel*2)+"s}", "")
        }
        
        notesave file
 
return

#defcfunc sioc_trimWhiteSpace str data
        /* sioc_trimWhiteSpace
         * 引数   : "元データ"
         * 返り値: "トリム後データ"
         * 空白文字を削除する。
         */
                                
        result = data
                
        result = strtrim(result, 3, ' ')
        result = strtrim(result, 3, '\t')
        result = strtrim(result, 3, ' ')
return result

#deffunc sioc_resetArea
        /* sioc_resetArea
         * 引数、返り値なし。
         * 現在選択されているエリアをリセットする。
         */
                                
        tempID = nowTableID
                                
        sioc_deleteArea
        sioc_createArea tempID
return

#deffunc sioc_deleteArea
        /* sioc_deleteArea
         * 引数、返り値なし。
         * 現在選択されているエリアを削除する。
         */
                        
        sql = ""
                        
        sql     = strf("DROP TABLE \"%s\"", nowTableID)
        sql_q sql
        nowTableID = ""
return

#deffunc sioc_setSection str sectTemp
        /* sioc_setSection
         * 引数 : "セクション名"
         * 読み込むセクションを変更する。
         */
                
        if (sectTemp == "") :return -1
        nowSect = sectTemp
return
        
#defcfunc sioc_getSection
return nowSect
 
#deffunc sioc_getKeys array out
        /* sioc_getKeys
         * 引数: 出力先の配列
         * 現在選択されているエリア、セクションのキー一覧を取得する。
         */
        sql = strf("SELECT key FROM \"%s\" WHERE section=\"%s\"", nowTableID, nowSect)

        sql_q sql
        count = stat
        
        if (count <= 0) : return 0
        
        sdim out,, count
        repeat count
                out(cnt) = sql_v("key")
                sql_next
        loop
        
return count
        
#defcfunc sioc_getValue str key
        /* sioc_getValue
         * 引数 : "キー"
         * 現在選択されているエリア、セクションのキーに対応する値を取得する。
         */
                
        tmparr(0, 0) = ""
        sql = ""
                                
        sql = strf("SELECT value FROM \"%s\" WHERE key=\"%s\" AND section=\"%s\"", nowTableID, key, nowSect)
        sql_q sql
 
        if (stat < 1) : return ""
return tmparr(0, 0)
 
#deffunc sioc_setValue str key, str value
        /* sioc_setValue
         * 引数 : "キー", "値"
         * 現在選択されているエリア、セクションのキーに対応する値を設定する。
         */
                 
         if (sioc_existsValue(key)) {
                 sioc_updateValue key, value
         } else {
                 sioc_addValue key, value
         }
 
return
 
#defcfunc sioc_existsValue str key
        /* sioc_existsValue
         * 引数 : "キー"
         * 現在選択されているエリア、セクションにキーが存在するかを取得する。
         */
        
        sql = ""
        
        sql =   strf("SELECT \"id\" FROM \"%s\" WHERE key=\"%s\" AND section=\"%s\"", nowTableID, key, nowSect)
        sql_q sql
        
return (stat > 0)
        
#deffunc sioc_addValue str key, str value
        /* sioc_addValue
         * 引数 : "キー", "値"
         * 現在選択されているエリア、セクションにキーに対応する値を作成する。
         * 通常はsioc_setValueを使用してください。
         */
                                        
        sql = ""
                        
        sql =   strf("INSERT INTO \"%s\" (\"section\", \"key\", \"value\") VALUES (\"%s\", \"%s\", \"%s\")", nowTableID, nowSect, key, value)
        sql_q sql
return
        
#deffunc sioc_updateValue str key, str value
        /* sioc_updateValue
         * 引数 : "キー", "値"
         * 現在選択されているエリア、セクションにキーに対応する値を更新する。
         * 通常はsioc_setValueを使用してください。
         */
                
        sql = ""
                        
        sql =   strf("UPDATE \"%s\" SET value=\"%s\" WHERE key=\"%s\"", nowTableID, value, key)
        sql_q sql
return
        
#deffunc sioc_deleteValue str key
        /* sioc_deleteValue
         * 引数 : "キー"
         * 現在選択されているエリア、セクションにキーを削除する。
         */
                
        sql = ""
        sql =   strf("DELETE FROM \"%s\" WHERE key=\"%s\"", nowTableID, key)
        sql_q sql
return

#global
#endif