From dc43385559509e44323e69dd5141f87446b11925 Mon Sep 17 00:00:00 2001 From: hyung-hwan Date: Wed, 2 Sep 2015 08:43:43 +0000 Subject: [PATCH] added qse_xli_setpairwithstr() and qse_xli_deletepair() --- qse/cmd/xli/xli.c | 95 ++++++++++++++++++++++-------------- qse/include/qse/macros.h | 2 +- qse/include/qse/xli/stdxli.h | 2 + qse/include/qse/xli/xli.h | 25 ++++++++-- qse/lib/awk/parse.c | 10 ++-- qse/lib/xli/read-ini.c | 13 +++-- qse/lib/xli/std.c | 8 +-- qse/lib/xli/write-ini.c | 4 +- qse/lib/xli/write.c | 4 +- qse/lib/xli/xli.c | 85 +++++++++++++++++++++++++++++++- 10 files changed, 187 insertions(+), 61 deletions(-) diff --git a/qse/cmd/xli/xli.c b/qse/cmd/xli/xli.c index 35b109b9..380b5e8b 100644 --- a/qse/cmd/xli/xli.c +++ b/qse/cmd/xli/xli.c @@ -63,6 +63,7 @@ static int g_io_flags = 0; static qse_char_t* g_input_file = QSE_NULL; static qse_char_t* g_output_file = QSE_NULL; static qse_char_t* g_lookup_key = QSE_NULL; +static qse_char_t* g_value = QSE_NULL; static qse_ulong_t g_memlimit = 0; static int g_trait = 0; @@ -148,7 +149,7 @@ static void print_usage (qse_sio_t* out, int argc, qse_char_t* argv[]) { const qse_char_t* b = qse_basename (argv[0]); - qse_fprintf (out, QSE_T("USAGE: %s [options] -i input-file [key]\n"), b); + qse_fprintf (out, QSE_T("USAGE: %s [options] -i input-file [key [value]]\n"), b); qse_fprintf (out, QSE_T("options as follows:\n")); qse_fprintf (out, QSE_T(" -h/--help show this message\n")); @@ -341,12 +342,19 @@ static int handle_args (int argc, qse_char_t* argv[]) goto oops; } - if (opt.ind < argc) g_lookup_key = argv[opt.ind++]; - - if (opt.ind < argc) + if (opt.ind < argc) { - print_usage (QSE_STDERR, argc, argv); - goto oops; + g_lookup_key = argv[opt.ind++]; + if (opt.ind < argc) + { + g_value = argv[opt.ind++]; + + if (opt.ind < argc) + { + print_usage (QSE_STDERR, argc, argv); + goto oops; + } + } } return 1; @@ -461,6 +469,7 @@ static int xli_main (int argc, qse_char_t* argv[]) goto oops; } +#if 0 { static const qse_cstr_t strs[] = { @@ -477,48 +486,62 @@ static int xli_main (int argc, qse_char_t* argv[]) ); } } +#endif if (g_lookup_key) { - qse_xli_pair_t* pair; - qse_size_t count; - - count = qse_xli_countpairs (xli, QSE_NULL, g_lookup_key); - qse_printf (QSE_T("COUNT: %lu\n"), (unsigned long)count); - - pair = qse_xli_findpair (xli, QSE_NULL, g_lookup_key); - if (pair == QSE_NULL) + if (g_value) { - qse_fprintf (QSE_STDERR, - QSE_T("ERROR: cannot find %s - %s \n"), - g_lookup_key, - qse_xli_geterrmsg(xli) - ); - goto oops; + qse_cstr_t v; + + v.ptr = g_value; + v.len = qse_strlen(g_value); + if (qse_xli_setpairwithstr (xli, QSE_NULL, g_lookup_key, &v, QSE_NULL) == QSE_NULL) + { + qse_fprintf (QSE_STDERR, + QSE_T("ERROR: cannot set a string pair - %s \n"), + qse_xli_geterrmsg(xli) + ); + } } else { - if (pair->val->type == QSE_XLI_STR) + qse_xli_pair_t* pair; + qse_size_t count; + + count = qse_xli_countpairs (xli, QSE_NULL, g_lookup_key); + qse_printf (QSE_T("COUNT: %lu\n"), (unsigned long)count); + + pair = qse_xli_findpair (xli, QSE_NULL, g_lookup_key); + if (pair == QSE_NULL) { - qse_xli_str_t* str = (qse_xli_str_t*)pair->val; - qse_printf (QSE_T("[%.*s]\n"), (int)str->len, str->ptr); - } - else if (pair->val->type == QSE_XLI_NIL) - { - qse_printf (QSE_T("#NIL\n")); + qse_fprintf (QSE_STDERR, + QSE_T("ERROR: cannot find %s - %s \n"), + g_lookup_key, + qse_xli_geterrmsg(xli) + ); + goto oops; } else { - qse_printf (QSE_T("#LIST\n")); + if (pair->val->type == QSE_XLI_STR) + { + qse_xli_str_t* str = (qse_xli_str_t*)pair->val; + qse_printf (QSE_T("[%.*s]\n"), (int)str->len, str->ptr); + } + else if (pair->val->type == QSE_XLI_NIL) + { + qse_printf (QSE_T("#NIL\n")); + } + else + { + out.type = QSE_XLI_IOSTD_FILE; + out.u.file.path = QSE_T("-"); + out.u.file.cmgr = g_outfile_cmgr; + qse_xli_writestd (xli, pair->val, &out); + } } } - - /* - if (g_value) - { - TODO: ... set value... - } - */ } @@ -526,7 +549,7 @@ static int xli_main (int argc, qse_char_t* argv[]) out.u.file.path = g_output_file? g_output_file: QSE_T("-"); out.u.file.cmgr = g_outfile_cmgr; - ret = (g_io_flags & IO_FLAG_INI_OUTPUT)? qse_xli_writeinistd(xli, &out): qse_xli_writestd(xli, &out); + ret = (g_io_flags & IO_FLAG_INI_OUTPUT)? qse_xli_writeinistd(xli, QSE_NULL, &out): qse_xli_writestd(xli, QSE_NULL, &out); oops: if (xli) qse_xli_close (xli); diff --git a/qse/include/qse/macros.h b/qse/include/qse/macros.h index 78da05d2..d202e98a 100644 --- a/qse/include/qse/macros.h +++ b/qse/include/qse/macros.h @@ -72,7 +72,7 @@ # undef QSE_HAVE_INLINE_NEVER #endif -#if defined(_WIN32) || defined(__WATCOMC__) +#if defined(_WIN32) || (defined(__WATCOMC__) && !defined(__WINDOWS_386__)) # define QSE_IMPORT __declspec(dllimport) # define QSE_EXPORT __declspec(dllexport) # define QSE_PRIVATE diff --git a/qse/include/qse/xli/stdxli.h b/qse/include/qse/xli/stdxli.h index aa387819..2340e914 100644 --- a/qse/include/qse/xli/stdxli.h +++ b/qse/include/qse/xli/stdxli.h @@ -136,11 +136,13 @@ QSE_EXPORT int qse_xli_readinistd ( QSE_EXPORT int qse_xli_writestd ( qse_xli_t* xli, + qse_xli_list_t* root_list, qse_xli_iostd_t* out ); QSE_EXPORT int qse_xli_writeinistd ( qse_xli_t* xli, + qse_xli_list_t* root_list, qse_xli_iostd_t* out ); diff --git a/qse/include/qse/xli/xli.h b/qse/include/qse/xli/xli.h index ebdddb73..a0bbe9da 100644 --- a/qse/include/qse/xli/xli.h +++ b/qse/include/qse/xli/xli.h @@ -587,6 +587,11 @@ QSE_EXPORT qse_xli_pair_t* qse_xli_insertpair ( qse_xli_val_t* val ); +QSE_EXPORT void qse_xli_deletepair ( + qse_xli_t* xli, + qse_xli_pair_t* pair +); + /** * The qse_xli_insertpairwithemptylist() function inserts a new pair * with an empty list as a value. You should call this function for adding @@ -651,14 +656,22 @@ QSE_EXPORT qse_xli_eof_t* qse_xli_inserteof ( QSE_EXPORT qse_xli_pair_t* qse_xli_findpair ( qse_xli_t* xli, - const qse_xli_list_t* list, - const qse_char_t* fqpn + const qse_xli_list_t* list, + const qse_char_t* fqpn +); + +QSE_EXPORT qse_xli_pair_t* qse_xli_setpairwithstr ( + qse_xli_t* xli, + const qse_xli_list_t* list, + const qse_char_t* fqpn, + const qse_cstr_t* value, + const qse_char_t* strtag ); QSE_EXPORT qse_size_t qse_xli_countpairs ( - qse_xli_t* xli, - const qse_xli_list_t* list, - const qse_char_t* fqpn + qse_xli_t* xli, + const qse_xli_list_t* list, + const qse_char_t* fqpn ); @@ -736,11 +749,13 @@ QSE_EXPORT int qse_xli_readini ( QSE_EXPORT int qse_xli_write ( qse_xli_t* xli, + qse_xli_list_t* root_list, qse_xli_io_impl_t io ); QSE_EXPORT int qse_xli_writeini ( qse_xli_t* xli, + qse_xli_list_t* root_list, qse_xli_io_impl_t io ); diff --git a/qse/lib/awk/parse.c b/qse/lib/awk/parse.c index cc57cbf8..18c97bc4 100644 --- a/qse/lib/awk/parse.c +++ b/qse/lib/awk/parse.c @@ -5764,7 +5764,7 @@ static int get_string ( static int get_rexstr (qse_awk_t* awk, qse_awk_tok_t* tok) { - if (awk->sio.last.c == QSE_T('/')) + if (awk->sio.last.c == QSE_T('/')) { /* handle an empty regular expression. * @@ -5778,17 +5778,17 @@ static int get_rexstr (qse_awk_t* awk, qse_awk_tok_t* tok) GET_CHAR (awk); return 0; } - else + else { qse_size_t preescaped = 0; - if (awk->sio.last.c == QSE_T('\\')) - { + if (awk->sio.last.c == QSE_T('\\')) + { /* for input like /\//, this condition is met. * the initial escape character is added when the * second charater is handled in get_string() */ preescaped = 1; } - else + else { /* add other initial characters here as get_string() * begins with reading the next character */ diff --git a/qse/lib/xli/read-ini.c b/qse/lib/xli/read-ini.c index 0662dc68..9d9e50bc 100644 --- a/qse/lib/xli/read-ini.c +++ b/qse/lib/xli/read-ini.c @@ -28,20 +28,25 @@ #include /* + * It reads key-value pairs under sections as shown below: + * * [SECTION1] * key1 = value1 * key2 = value2 * [SECTION2] * key1 = value1 - * -------------------------------- + * + * The above can get translated to the native XLI format shown below: * * SECTION1 { - * key1 = value1; - * key2 = value2; + * key1 = "value1"; + * key2 = "value2"; * } * SECTION2 { - * key1 = value1; + * key1 = "value1"; * } + * + * The ini-format reader doesn't support file inclusion via @include. */ enum diff --git a/qse/lib/xli/std.c b/qse/lib/xli/std.c index 12c56efe..507dfd91 100644 --- a/qse/lib/xli/std.c +++ b/qse/lib/xli/std.c @@ -633,7 +633,7 @@ int qse_xli_readinistd (qse_xli_t* xli, qse_xli_iostd_t* in) } -int qse_xli_writestd (qse_xli_t* xli, qse_xli_iostd_t* out) +int qse_xli_writestd (qse_xli_t* xli, qse_xli_list_t* root_list, qse_xli_iostd_t* out) { int n; xtn_t* xtn = (xtn_t*) QSE_XTN (xli); @@ -648,7 +648,7 @@ int qse_xli_writestd (qse_xli_t* xli, qse_xli_iostd_t* out) } xtn->s.out.x = out; - n = qse_xli_write (xli, sf_out); + n = qse_xli_write (xli, root_list, sf_out); if (out->type == QSE_XLI_IOSTD_STR) { @@ -663,7 +663,7 @@ int qse_xli_writestd (qse_xli_t* xli, qse_xli_iostd_t* out) return n; } -int qse_xli_writeinistd (qse_xli_t* xli, qse_xli_iostd_t* out) +int qse_xli_writeinistd (qse_xli_t* xli, qse_xli_list_t* root_list, qse_xli_iostd_t* out) { int n; xtn_t* xtn = (xtn_t*) QSE_XTN (xli); @@ -678,7 +678,7 @@ int qse_xli_writeinistd (qse_xli_t* xli, qse_xli_iostd_t* out) } xtn->s.out.x = out; - n = qse_xli_writeini (xli, sf_out); + n = qse_xli_writeini (xli, root_list, sf_out); if (out->type == QSE_XLI_IOSTD_STR) { diff --git a/qse/lib/xli/write-ini.c b/qse/lib/xli/write-ini.c index 9b494d34..dd48c79c 100644 --- a/qse/lib/xli/write-ini.c +++ b/qse/lib/xli/write-ini.c @@ -148,7 +148,7 @@ static int write_list (qse_xli_t* xli, qse_xli_list_t* list, int depth) return 0; } -int qse_xli_writeini (qse_xli_t* xli, qse_xli_io_impl_t io) +int qse_xli_writeini (qse_xli_t* xli, qse_xli_list_t* root_list, qse_xli_io_impl_t io) { int n; @@ -169,7 +169,7 @@ int qse_xli_writeini (qse_xli_t* xli, qse_xli_io_impl_t io) if (qse_xli_openwstream (xli, QSE_NULL, 0) <= -1) return -1; /* begin writing the root list */ - n = write_list (xli, &xli->root->list, 0); + n = write_list (xli, (root_list? root_list: &xli->root->list), 0); /* close all open streams. there should be only the * top-level stream here if there occurred no errors */ diff --git a/qse/lib/xli/write.c b/qse/lib/xli/write.c index f7da194d..b393b609 100644 --- a/qse/lib/xli/write.c +++ b/qse/lib/xli/write.c @@ -317,7 +317,7 @@ void qse_xli_clearwionames (qse_xli_t* xli) } } -int qse_xli_write (qse_xli_t* xli, qse_xli_io_impl_t io) +int qse_xli_write (qse_xli_t* xli, qse_xli_list_t* root_list, qse_xli_io_impl_t io) { int n; @@ -338,7 +338,7 @@ int qse_xli_write (qse_xli_t* xli, qse_xli_io_impl_t io) if (qse_xli_openwstream (xli, QSE_NULL, 0) <= -1) return -1; /* begin writing the root list */ - n = write_list (xli, &xli->root->list, 0); + n = write_list (xli, (root_list? root_list: &xli->root->list), 0); /* close all open streams. there should be only the * top-level stream here if there occurred no errors */ diff --git a/qse/lib/xli/xli.c b/qse/lib/xli/xli.c index 56e4a355..09fe618e 100644 --- a/qse/lib/xli/xli.c +++ b/qse/lib/xli/xli.c @@ -308,6 +308,37 @@ qse_xli_pair_t* qse_xli_insertpair ( return insert_pair (xli, parent, peer, &k, ap, tp, value); } +void qse_xli_deletepair (qse_xli_t* xli, qse_xli_pair_t* pair) +{ + qse_xli_list_t* list; + + list = pair->super; + + if (pair->prev) + { + pair->prev->next = pair->next; + } + else + { + QSE_ASSERT (list->head == pair); + list->head = pair->next; + } + + if (pair->next) + { + pair->next->prev = pair->prev; + } + else + { + QSE_ASSERT (list->tail == pair); + list->tail = pair->prev; + } + + free_val (xli->root, pair->val); + QSE_MMGR_FREE (xli->mmgr, pair); +} + +/* ------------------------------------------------------ */ qse_xli_pair_t* qse_xli_insertpairwithemptylist ( qse_xli_t* xli, qse_xli_list_t* parent, qse_xli_atom_t* peer, const qse_char_t* key, const qse_char_t* alias, const qse_char_t* keytag) @@ -351,7 +382,7 @@ qse_xli_pair_t* qse_xli_insertpairwithstr ( qse_strcpy ((qse_char_t*)val->tag, strtag); } - tmp = qse_xli_insertpair (xli, parent, peer, key, alias, keytag, (qse_xli_val_t*)val); + tmp = qse_xli_insertpair (xli, parent, peer, key, alias, keytag, (qse_xli_val_t*)val); if (!tmp) qse_xli_freemem (xli, val); return tmp; } @@ -788,6 +819,56 @@ noent: return QSE_NULL; } +qse_xli_pair_t* qse_xli_setpairwithstr (qse_xli_t* xli, const qse_xli_list_t* list, const qse_char_t* fqpn, const qse_cstr_t* value, const qse_char_t* strtag) +{ + qse_xli_pair_t* pair, * xpair; + + pair = qse_xli_findpair (xli, list, fqpn); + if (pair) + { + if (xli->opt.trait & QSE_XLI_VALIDATE) + { + qse_rbt_pair_t* scm_pair; + const qse_xli_scm_t* scm; + + scm_pair = qse_rbt_search (xli->schema, fqpn, qse_strlen(fqpn)); + if (!scm_pair) + { + qse_cstr_t key; + + key.ptr = (qse_char_t*)fqpn; + key.len = qse_strlen(fqpn); + + qse_xli_seterror (xli, QSE_XLI_EUDKEY, &key, QSE_NULL); + return QSE_NULL; + } + + scm = (qse_xli_scm_t*)QSE_RBT_VPTR(scm_pair); + + if (scm && !(scm->flags & QSE_XLI_SCM_VALSTR)) + { + /* check the value type */ + qse_cstr_t key; + + key.ptr = (qse_char_t*)fqpn; + key.len = qse_strlen(fqpn); + + qse_xli_seterror (xli, QSE_XLI_EILVAL, (const qse_cstr_t*)&key, QSE_NULL); + return QSE_NULL; + } + } + + xpair = qse_xli_insertpairwithstr (xli, pair->super, (qse_xli_atom_t*)pair, pair->key, pair->alias, pair->tag, value, strtag); + if (xpair) qse_xli_deletepair (xli, pair); + return xpair; + } + else + { + /* TODO: insert a new pair */ + return QSE_NULL; + } +} + qse_size_t qse_xli_countpairs (qse_xli_t* xli, const qse_xli_list_t* list, const qse_char_t* fqpn) { @@ -881,7 +962,7 @@ qse_xli_str_t* qse_xli_addsegtostr ( val->tag = val->ptr + val->len + 1; qse_strcpy ((qse_char_t*)val->tag, tag); } - + val->next = str->next; str->next = val; return str->next;