diff --git a/qse/include/qse/xli/SkvEnv.hpp b/qse/include/qse/xli/SkvEnv.hpp index ce898e9c..fd325467 100644 --- a/qse/include/qse/xli/SkvEnv.hpp +++ b/qse/include/qse/xli/SkvEnv.hpp @@ -50,16 +50,16 @@ public: { qse_char_t sctn[MAX_SCTN_LEN + 1]; qse_char_t key [MAX_KEY_LEN + 1]; - qse_char_t name[MAX_NAME_LEN + 1]; + qse_char_t name[MAX_NAME_LEN + 1]; // sctn*key qse_char_t dval[MAX_DVAL_LEN + 1]; // default value ProbeProc probe; }; typedef QSE::LinkedList ItemList; SkvEnv (Mmgr* mmgr = QSE_NULL); - ~SkvEnv (); + virtual ~SkvEnv (); - int addItem (const qse_char_t* name, const qse_char_t* dval, ProbeProc probe); + int addItem (const qse_char_t* name, const qse_char_t* dval, ProbeProc probe = QSE_NULL); int removeItem (const qse_char_t* name); const qse_char_t* getValue (const qse_char_t* name) const; @@ -74,6 +74,18 @@ protected: int split_name (const qse_char_t* name, qse_char_t** sctn, qse_size_t* sctn_len, qse_char_t** key, qse_size_t* key_len); int set_value_with_item (Item& item, const qse_char_t* value); + + virtual int probe_item_value (const Item& item, const qse_char_t* value) + { + if (item.probe && (this->*item.probe)(value) <= -1) return -1; + return 0; + } + + int call_probe_item_value (const Item& item, const qse_char_t* value) + { + try { return this->probe_item_value(item, value); } + catch (...) { return -1; } + } }; QSE_END_NAMESPACE(QSE) diff --git a/qse/lib/xli/Makefile.am b/qse/lib/xli/Makefile.am index e8050aee..b28c13ce 100644 --- a/qse/lib/xli/Makefile.am +++ b/qse/lib/xli/Makefile.am @@ -5,7 +5,7 @@ AM_CPPFLAGS = \ -I$(top_srcdir)/include lib_LTLIBRARIES = libqsexli.la -libqsexli_la_SOURCES = xli.h xli.c err.c \ +libqsexli_la_SOURCES = xli-prv.h xli.c err.c \ read.c read-ini.c read-json.c \ write.c write-ini.c write-json.c \ std.c diff --git a/qse/lib/xli/Makefile.in b/qse/lib/xli/Makefile.in index 907c0656..eb44cecc 100644 --- a/qse/lib/xli/Makefile.in +++ b/qse/lib/xli/Makefile.in @@ -402,7 +402,7 @@ AM_CPPFLAGS = \ -I$(top_srcdir)/include lib_LTLIBRARIES = libqsexli.la $(am__append_1) -libqsexli_la_SOURCES = xli.h xli.c err.c \ +libqsexli_la_SOURCES = xli-prv.h xli.c err.c \ read.c read-ini.c read-json.c \ write.c write-ini.c write-json.c \ std.c diff --git a/qse/lib/xli/SkvEnv.cpp b/qse/lib/xli/SkvEnv.cpp index 9f6bea7b..dc8a7dee 100644 --- a/qse/lib/xli/SkvEnv.cpp +++ b/qse/lib/xli/SkvEnv.cpp @@ -28,8 +28,10 @@ #include #include + #include #include "../cmn/mem-prv.h" +#include "xli-prv.h" #define SCTN_KEY_SPLITTER QSE_T('*') @@ -90,7 +92,7 @@ int SkvEnv::removeItem (const qse_char_t* name) if (this->split_name (name, &sctn, &sctn_len, &key, &key_len) == -1) return -1; - for (ItemList::Node* np = item_list.getHeadNode(); np; np = np->getNextNode()) + for (ItemList::Node* np = this->item_list.getHeadNode(); np; np = np->getNextNode()) { Item& item = np->value; if (qse_strxcmp(sctn, sctn_len, item.sctn) == 0 && @@ -113,7 +115,7 @@ const qse_char_t* SkvEnv::getValue (const qse_char_t* name) const QSE_ASSERT (pair->val != QSE_NULL); QSE_ASSERT (pair->val->type == QSE_XLI_STR); - + return (((qse_xli_str_t*)pair->val))->ptr; } @@ -172,7 +174,8 @@ int SkvEnv::split_name (const qse_char_t* name, qse_char_t** sctn, qse_size_t* s int SkvEnv::set_value_with_item (Item& item, const qse_char_t* value) { - if (item.probe && (this->*item.probe)(value) <= -1) return -1; +#if 0 + if (this->probe_item_value(item, value) <= -1) return -1; qse_cstr_t v = { (qse_char_t*)value, qse_strlen(value) }; @@ -195,7 +198,70 @@ int SkvEnv::set_value_with_item (Item& item, const qse_char_t* value) if (!qse_xli_insertpairwithstr(this->xli, (qse_xli_list_t*)pair->val, QSE_NULL, item.key, QSE_NULL, QSE_NULL, &v, QSE_NULL)) return -1; } + this->accept_item_value (item, value); return 0; +#else + + // this function adds/updates the pair with the given value + // before it verifies the value. as long as verification is + // ok, the value is guaranteed to be set. + + qse_cstr_t v = { (qse_char_t*)value, qse_strlen(value) }; + qse_xli_pair_t* sctn_pair = QSE_NULL, * kv_pair = QSE_NULL; + + sctn_pair = qse_xli_findpair(this->xli, QSE_NULL, item.sctn); + if (sctn_pair) + { + // section exists. + QSE_ASSERT (sctn_pair->val && sctn_pair->val->type == QSE_XLI_LIST); + kv_pair = qse_xli_findpair(this->xli, (qse_xli_list_t*)sctn_pair->val, item.key); + if (kv_pair) + { + // key also exists + qse_xli_pair_t* existing_kv_pair = kv_pair; + + kv_pair = QSE_NULL; + sctn_pair = QSE_NULL; + + qse_xli_str_t* newstrv = qse_xli_makestrval(this->xli, &v, QSE_NULL); + if (!newstrv) goto rollback; + + if (this->call_probe_item_value(item, value) <= -1) + { + qse_xli_freeval (this->xli, (qse_xli_val_t*)newstrv); + goto rollback; + } + + qse_xli_freeval (this->xli, existing_kv_pair->val); + existing_kv_pair->val = (qse_xli_val_t*)newstrv; + } + else + { + kv_pair = qse_xli_insertpairwithstr(this->xli, (qse_xli_list_t*)sctn_pair->val, QSE_NULL, item.key, QSE_NULL, QSE_NULL, &v, QSE_NULL); + sctn_pair = QSE_NULL; + if (!kv_pair) goto rollback; + + if (this->call_probe_item_value(item, value) <= -1) goto rollback; + } + } + else + { + sctn_pair = qse_xli_insertpairwithemptylist(this->xli, QSE_NULL, QSE_NULL, item.sctn, QSE_NULL, QSE_NULL); + if (!sctn_pair) return -1; + + kv_pair = qse_xli_insertpairwithstr(this->xli, (qse_xli_list_t*)sctn_pair->val, QSE_NULL, item.key, QSE_NULL, QSE_NULL, &v, QSE_NULL); + if (!kv_pair) goto rollback; + + if (this->call_probe_item_value(item, value) <= -1) goto rollback; + } + + return 0; + +rollback: + if (kv_pair) qse_xli_deletepair (this->xli, kv_pair); + if (sctn_pair) qse_xli_deletepair (this->xli, sctn_pair); + return -1; +#endif } int SkvEnv::load (const qse_char_t* path) @@ -205,7 +271,7 @@ int SkvEnv::load (const qse_char_t* path) if (!this->xli) { // this means that no items have been registered with - // this->addItem(). + // this->addItem(). so loading is meaningless. return -1; } @@ -239,6 +305,7 @@ int SkvEnv::load (const qse_char_t* path) } } +// TODO: check if there are any unknown names. flag it via callbacks??? qse_xli_close(xli); return 0; } diff --git a/qse/lib/xli/err.c b/qse/lib/xli/err.c index e36d4636..a718c65a 100644 --- a/qse/lib/xli/err.c +++ b/qse/lib/xli/err.c @@ -24,7 +24,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "xli.h" +#include "xli-prv.h" #include "../cmn/mem-prv.h" const qse_char_t* qse_xli_dflerrstr (const qse_xli_t* xli, qse_xli_errnum_t errnum) diff --git a/qse/lib/xli/read-ini.c b/qse/lib/xli/read-ini.c index deedb2a5..581502c1 100644 --- a/qse/lib/xli/read-ini.c +++ b/qse/lib/xli/read-ini.c @@ -24,7 +24,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "xli.h" +#include "xli-prv.h" #include /* diff --git a/qse/lib/xli/read-json.c b/qse/lib/xli/read-json.c index be409230..656f2755 100644 --- a/qse/lib/xli/read-json.c +++ b/qse/lib/xli/read-json.c @@ -24,7 +24,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "xli.h" +#include "xli-prv.h" #include /* diff --git a/qse/lib/xli/read.c b/qse/lib/xli/read.c index 51e83261..07e05638 100644 --- a/qse/lib/xli/read.c +++ b/qse/lib/xli/read.c @@ -24,7 +24,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "xli.h" +#include "xli-prv.h" #include static int get_token (qse_xli_t* xli); diff --git a/qse/lib/xli/std.c b/qse/lib/xli/std.c index 81f0d5d7..170bb1e9 100644 --- a/qse/lib/xli/std.c +++ b/qse/lib/xli/std.c @@ -24,7 +24,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "xli.h" +#include "xli-prv.h" #include #include #include "../cmn/mem-prv.h" diff --git a/qse/lib/xli/write-ini.c b/qse/lib/xli/write-ini.c index e59b3219..dc7e6b92 100644 --- a/qse/lib/xli/write-ini.c +++ b/qse/lib/xli/write-ini.c @@ -24,7 +24,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "xli.h" +#include "xli-prv.h" static int write_to_current_stream (qse_xli_t* xli, const qse_char_t* ptr, qse_size_t len) { diff --git a/qse/lib/xli/write-json.c b/qse/lib/xli/write-json.c index 595255e5..07dab50b 100644 --- a/qse/lib/xli/write-json.c +++ b/qse/lib/xli/write-json.c @@ -24,7 +24,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "xli.h" +#include "xli-prv.h" #include typedef struct arg_data_t arg_data_t; diff --git a/qse/lib/xli/write.c b/qse/lib/xli/write.c index e06c563f..295a8913 100644 --- a/qse/lib/xli/write.c +++ b/qse/lib/xli/write.c @@ -24,7 +24,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "xli.h" +#include "xli-prv.h" #include typedef struct arg_data_t arg_data_t; diff --git a/qse/lib/xli/xli.h b/qse/lib/xli/xli-prv.h similarity index 100% rename from qse/lib/xli/xli.h rename to qse/lib/xli/xli-prv.h diff --git a/qse/lib/xli/xli.c b/qse/lib/xli/xli.c index cf664993..b2425e0a 100644 --- a/qse/lib/xli/xli.c +++ b/qse/lib/xli/xli.c @@ -24,7 +24,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "xli.h" +#include "xli-prv.h" #include static qse_xli_root_list_t* make_root (qse_xli_t* xli); diff --git a/qse/samples/xli/skvenv01.cpp b/qse/samples/xli/skvenv01.cpp index bae1042d..77ef714c 100644 --- a/qse/samples/xli/skvenv01.cpp +++ b/qse/samples/xli/skvenv01.cpp @@ -29,6 +29,7 @@ #include #include #include +#include #include #if defined(_WIN32) @@ -37,24 +38,32 @@ class MyEnv: public QSE::SkvEnv { - +public: + int probe_agent_name (const qse_char_t* name) + { +qse_printf (QSE_T("probing agent_name %s\n"), name); + return 0; + } }; MyEnv myenv; static int env_main (int argc, qse_char_t* argv[]) { - myenv.addItem (QSE_T("main*target"), QSE_T("file"), QSE_NULL); - myenv.addItem (QSE_T("main*targetq"), QSE_T("file"), QSE_NULL); + myenv.addItem (QSE_T("main*target"), QSE_T("file")); + myenv.addItem (QSE_T("main*targetq"), QSE_T("file")); + myenv.addItem (QSE_T("agent*name"), QSE_T("my-agent"), (MyEnv::ProbeProc)&MyEnv::probe_agent_name); + myenv.load (QSE_T("myenv.conf")); -//myenv.setValue(QSE_T("main*target"), QSE_T("qqqqqq")); -//myenv.setValue(QSE_T("main*target"), QSE_T("abcdefg")); -//myenv.setValue(QSE_T("main*targetq"), QSE_T("zozo")); + QSE::String x (myenv.getValue(QSE_T("main*target"))); + x.append (QSE_T("-jj")); + myenv.setValue(QSE_T("main*target"), x); + const qse_char_t* v = myenv.getValue(QSE_T("main*target")); qse_printf (QSE_T("%s\n"), (v? v: QSE_T(""))); -myenv.store (QSE_T("myenv.conf")); + myenv.store (QSE_T("myenv.conf")); return 0; }