added QSE_XLI_ASSIGNWITHCOLON, QSE_XLI_TAGMARKER, QSE_XLI_ARRAYMARKE and added partial code for more extension work in progress
This commit is contained in:
parent
dccad56ca5
commit
03cb7dd9dc
@ -168,6 +168,7 @@ static void print_usage (qse_sio_t* out, int argc, qse_char_t* argv[])
|
|||||||
qse_fprintf (out, QSE_T(" -l disallow lists\n"));
|
qse_fprintf (out, QSE_T(" -l disallow lists\n"));
|
||||||
qse_fprintf (out, QSE_T(" -K allow key tags\n"));
|
qse_fprintf (out, QSE_T(" -K allow key tags\n"));
|
||||||
qse_fprintf (out, QSE_T(" -S allow string tags\n"));
|
qse_fprintf (out, QSE_T(" -S allow string tags\n"));
|
||||||
|
qse_fprintf (out, QSE_T(" -c use a colon for assignment\n"));
|
||||||
qse_fprintf (out, QSE_T(" -v perform validation\n"));
|
qse_fprintf (out, QSE_T(" -v perform validation\n"));
|
||||||
qse_fprintf (out, QSE_T(" -m number specify the maximum amount of memory to use in bytes\n"));
|
qse_fprintf (out, QSE_T(" -m number specify the maximum amount of memory to use in bytes\n"));
|
||||||
#if defined(QSE_BUILD_DEBUG)
|
#if defined(QSE_BUILD_DEBUG)
|
||||||
@ -195,9 +196,9 @@ static int handle_args (int argc, qse_char_t* argv[])
|
|||||||
static qse_opt_t opt =
|
static qse_opt_t opt =
|
||||||
{
|
{
|
||||||
#if defined(QSE_BUILD_DEBUG)
|
#if defined(QSE_BUILD_DEBUG)
|
||||||
QSE_T("hi:o:I:O:uaftsdnlKSvm:X:"),
|
QSE_T("hi:o:I:O:uaftsdnlKScvm:X:"),
|
||||||
#else
|
#else
|
||||||
QSE_T("hi:o:I:O:uaftsdnlKSvm:"),
|
QSE_T("hi:o:I:O:uaftsdnlKScvm:"),
|
||||||
#endif
|
#endif
|
||||||
lng
|
lng
|
||||||
};
|
};
|
||||||
@ -291,6 +292,10 @@ static int handle_args (int argc, qse_char_t* argv[])
|
|||||||
g_trait |= QSE_XLI_STRTAG;
|
g_trait |= QSE_XLI_STRTAG;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case QSE_T('c'):
|
||||||
|
g_trait |= QSE_XLI_ASSIGNWITHCOLON;
|
||||||
|
break;
|
||||||
|
|
||||||
case QSE_T('v'):
|
case QSE_T('v'):
|
||||||
g_trait |= QSE_XLI_VALIDATE;
|
g_trait |= QSE_XLI_VALIDATE;
|
||||||
break;
|
break;
|
||||||
|
@ -115,7 +115,20 @@ enum qse_xli_opt_t
|
|||||||
*/
|
*/
|
||||||
QSE_XLI_ROOTXTNSIZE,
|
QSE_XLI_ROOTXTNSIZE,
|
||||||
|
|
||||||
QSE_XLI_KEYSPLITTER
|
/**
|
||||||
|
* It is a character to put between a parent key and a nested key.
|
||||||
|
* By default, it's a period and used like 'a.b.c' that means c under b under a.
|
||||||
|
*/
|
||||||
|
QSE_XLI_KEYSPLITTER,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The first character is in the tag marker speicifies the tag opener
|
||||||
|
* and the second chracter specifies the tag closer. The are used when
|
||||||
|
* key tags and/or string tags are enabled. By default, it is "[]".
|
||||||
|
*/
|
||||||
|
QSE_XLI_TAGMARKER,
|
||||||
|
|
||||||
|
QSE_XLI_ARRAYMARKER
|
||||||
};
|
};
|
||||||
typedef enum qse_xli_opt_t qse_xli_opt_t;
|
typedef enum qse_xli_opt_t qse_xli_opt_t;
|
||||||
|
|
||||||
@ -145,14 +158,20 @@ enum qse_xli_trait_t
|
|||||||
* "tg" is stored into the tag field of qse_xli_str_t. */
|
* "tg" is stored into the tag field of qse_xli_str_t. */
|
||||||
QSE_XLI_STRTAG = (1 << 10),
|
QSE_XLI_STRTAG = (1 << 10),
|
||||||
|
|
||||||
|
/** use a colon as an assignment character intead of an equal sign.
|
||||||
|
* it doesn't apply when reading or writing in the ini format. */
|
||||||
|
QSE_XLI_ASSIGNWITHCOLON = (1 << 11),
|
||||||
|
|
||||||
/** enable pair validation against pair definitions while reading */
|
/** enable pair validation against pair definitions while reading */
|
||||||
QSE_XLI_VALIDATE = (1 << 11)
|
QSE_XLI_VALIDATE = (1 << 12)
|
||||||
};
|
};
|
||||||
typedef enum qse_xli_trait_t qse_xli_trait_t;
|
typedef enum qse_xli_trait_t qse_xli_trait_t;
|
||||||
|
|
||||||
typedef struct qse_xli_val_t qse_xli_val_t;
|
typedef struct qse_xli_val_t qse_xli_val_t;
|
||||||
typedef struct qse_xli_nil_t qse_xli_nil_t;
|
typedef struct qse_xli_nil_t qse_xli_nil_t;
|
||||||
typedef struct qse_xli_str_t qse_xli_str_t;
|
typedef struct qse_xli_str_t qse_xli_str_t;
|
||||||
|
typedef struct qse_xli_int_t qse_xli_int_t;
|
||||||
|
typedef struct qse_xli_array_t qse_xli_array_t;
|
||||||
typedef struct qse_xli_list_t qse_xli_list_t;
|
typedef struct qse_xli_list_t qse_xli_list_t;
|
||||||
|
|
||||||
typedef struct qse_xli_atom_t qse_xli_atom_t;
|
typedef struct qse_xli_atom_t qse_xli_atom_t;
|
||||||
@ -207,6 +226,26 @@ struct qse_xli_str_t
|
|||||||
qse_xli_str_t* next;
|
qse_xli_str_t* next;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct qse_xli_int_t
|
||||||
|
{
|
||||||
|
QSE_XLI_VAL_HDR;
|
||||||
|
const qse_char_t* tag;
|
||||||
|
const qse_char_t* ptr;
|
||||||
|
qse_size_t len;
|
||||||
|
/* TODO: include a numeric value here???
|
||||||
|
qse_intmax_t val;
|
||||||
|
*/
|
||||||
|
/* NEED TO SUPPORT MULTI NUBMER? */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct qse_xli_array_t
|
||||||
|
{
|
||||||
|
QSE_XLI_VAL_HDR;
|
||||||
|
const qse_char_t* tag;
|
||||||
|
qse_xli_val_t* ptr;
|
||||||
|
qse_size_t count;
|
||||||
|
};
|
||||||
|
|
||||||
#define QSE_XLI_ATOM_HDR \
|
#define QSE_XLI_ATOM_HDR \
|
||||||
qse_xli_atom_type_t type; \
|
qse_xli_atom_type_t type; \
|
||||||
qse_xli_atom_t* prev; \
|
qse_xli_atom_t* prev; \
|
||||||
@ -225,6 +264,8 @@ struct qse_xli_pair_t
|
|||||||
const qse_char_t* key;
|
const qse_char_t* key;
|
||||||
const qse_char_t* alias;
|
const qse_char_t* alias;
|
||||||
const qse_char_t* tag;
|
const qse_char_t* tag;
|
||||||
|
unsigned int _key_quoted: 2; /* used internally for output */
|
||||||
|
unsigned int _alias_quoted: 2; /* used internally for output - in fact, an alias is always quoted */
|
||||||
qse_xli_val_t* val;
|
qse_xli_val_t* val;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -48,7 +48,7 @@ const qse_char_t* qse_xli_dflerrstr (
|
|||||||
QSE_T("syntax error"),
|
QSE_T("syntax error"),
|
||||||
QSE_T("semicolon expected in place of '${0}'"),
|
QSE_T("semicolon expected in place of '${0}'"),
|
||||||
QSE_T("equal-sign expected in place of '${0}'"),
|
QSE_T("equal-sign expected in place of '${0}'"),
|
||||||
QSE_T("left-brace or equal-sign expected in place of '${0}'"),
|
QSE_T("left-brace or assignment token expected in place of '${0}'"),
|
||||||
QSE_T("right-brace expected in place of '${0}'"),
|
QSE_T("right-brace expected in place of '${0}'"),
|
||||||
QSE_T("pair value expected in place of '${0}'"),
|
QSE_T("pair value expected in place of '${0}'"),
|
||||||
QSE_T("string not closed"),
|
QSE_T("string not closed"),
|
||||||
|
@ -27,6 +27,18 @@
|
|||||||
#include "xli.h"
|
#include "xli.h"
|
||||||
#include <qse/cmn/chr.h>
|
#include <qse/cmn/chr.h>
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
"key1" {
|
||||||
|
# comment
|
||||||
|
[keytag]key11 "alias" = [strtag]"test machine;
|
||||||
|
key1122 {
|
||||||
|
key112233 = "hello";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
static int get_token (qse_xli_t* xli);
|
static int get_token (qse_xli_t* xli);
|
||||||
static int read_list (qse_xli_t* xli, qse_xli_list_t* list, const qse_xli_scm_t* override);
|
static int read_list (qse_xli_t* xli, qse_xli_list_t* list, const qse_xli_scm_t* override);
|
||||||
|
|
||||||
@ -300,10 +312,11 @@ static int get_symbols (qse_xli_t* xli, qse_cint_t c, qse_xli_tok_t* tok)
|
|||||||
{
|
{
|
||||||
{ QSE_T("="), 1, QSE_XLI_TOK_EQ },
|
{ QSE_T("="), 1, QSE_XLI_TOK_EQ },
|
||||||
{ QSE_T(","), 1, QSE_XLI_TOK_COMMA },
|
{ QSE_T(","), 1, QSE_XLI_TOK_COMMA },
|
||||||
|
{ QSE_T(":"), 1, QSE_XLI_TOK_COLON },
|
||||||
{ QSE_T(";"), 1, QSE_XLI_TOK_SEMICOLON },
|
{ QSE_T(";"), 1, QSE_XLI_TOK_SEMICOLON },
|
||||||
{ QSE_T("{"), 1, QSE_XLI_TOK_LBRACE },
|
{ QSE_T("{"), 1, QSE_XLI_TOK_LBRACE },
|
||||||
{ QSE_T("}"), 1, QSE_XLI_TOK_RBRACE },
|
{ QSE_T("}"), 1, QSE_XLI_TOK_RBRACE },
|
||||||
{ QSE_NULL, 0, 0, }
|
{ QSE_NULL, 0, 0, }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ops_t* p;
|
struct ops_t* p;
|
||||||
@ -511,6 +524,8 @@ retry:
|
|||||||
(xli->opt.trait & QSE_XLI_LEADDIGIT) &&
|
(xli->opt.trait & QSE_XLI_LEADDIGIT) &&
|
||||||
QSE_ISDIGIT(c)))
|
QSE_ISDIGIT(c)))
|
||||||
{
|
{
|
||||||
|
/* if you change the rules here, you need to update
|
||||||
|
* need_quoting() in write.c */
|
||||||
int lead_digit = QSE_ISDIGIT(c);
|
int lead_digit = QSE_ISDIGIT(c);
|
||||||
int all_digits = 1;
|
int all_digits = 1;
|
||||||
|
|
||||||
@ -522,8 +537,8 @@ retry:
|
|||||||
GET_CHAR_TO (xli, c);
|
GET_CHAR_TO (xli, c);
|
||||||
|
|
||||||
if (c == QSE_T('_') || c == QSE_T('-') ||
|
if (c == QSE_T('_') || c == QSE_T('-') ||
|
||||||
c == QSE_T(':') || c == QSE_T('*') ||
|
(!(xli->opt.trait & QSE_XLI_ASSIGNWITHCOLON) && c == QSE_T(':')) ||
|
||||||
c == QSE_T('/') || QSE_ISALPHA (c))
|
c == QSE_T('*') || c == QSE_T('/') || QSE_ISALPHA (c))
|
||||||
{
|
{
|
||||||
all_digits = 0;
|
all_digits = 0;
|
||||||
}
|
}
|
||||||
@ -536,7 +551,7 @@ retry:
|
|||||||
|
|
||||||
if (lead_digit && all_digits)
|
if (lead_digit && all_digits)
|
||||||
{
|
{
|
||||||
/* if an identifier begins with a digit, it must contain a non-digits character */
|
/* if an identifier begins with a digit, it must contain a non-digit character */
|
||||||
qse_xli_seterror (xli, QSE_XLI_EIDENT, QSE_STR_XSTR(tok->name), &tok->loc);
|
qse_xli_seterror (xli, QSE_XLI_EIDENT, QSE_STR_XSTR(tok->name), &tok->loc);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -621,13 +636,15 @@ retry:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ((xli->opt.trait & (QSE_XLI_KEYTAG | QSE_XLI_STRTAG)) && c == QSE_T('['))
|
else if ((xli->opt.trait & (QSE_XLI_KEYTAG | QSE_XLI_STRTAG)) && c == xli->opt.tag_marker[0]) /* [ */
|
||||||
{
|
{
|
||||||
/* a string tag is a bracketed word placed in front of a string value.
|
/* a string tag is a bracketed word placed in front of a string value.
|
||||||
* A = [tg] "abc";
|
* A = [tg] "abc";
|
||||||
* "tg" is stored into the tag field of qse_xli_str_t.
|
* "tg" is stored into the tag field of qse_xli_str_t.
|
||||||
|
*
|
||||||
|
* however, the tag opener and the closer are not hard-coded. you may
|
||||||
|
* use a different opener and closer depending on your requirement.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
SET_TOKEN_TYPE (xli, tok, QSE_XLI_TOK_TAG);
|
SET_TOKEN_TYPE (xli, tok, QSE_XLI_TOK_TAG);
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
@ -641,7 +658,7 @@ retry:
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (c == QSE_T(']'))
|
if (c == xli->opt.tag_marker[1]) /* ] */
|
||||||
{
|
{
|
||||||
/* terminating quote */
|
/* terminating quote */
|
||||||
GET_CHAR (xli);
|
GET_CHAR (xli);
|
||||||
@ -724,6 +741,7 @@ static int read_pair (qse_xli_t* xli, const qse_char_t* keytag, const qse_xli_sc
|
|||||||
|
|
||||||
const qse_xli_scm_t* scm = QSE_NULL;
|
const qse_xli_scm_t* scm = QSE_NULL;
|
||||||
int key_nodup = 0, key_alias = 0, val_iffy = 0;
|
int key_nodup = 0, key_alias = 0, val_iffy = 0;
|
||||||
|
/*int key_quoted = 0, alias_quoted = 0;*/
|
||||||
|
|
||||||
key.ptr = QSE_NULL;
|
key.ptr = QSE_NULL;
|
||||||
name = QSE_NULL;
|
name = QSE_NULL;
|
||||||
@ -735,9 +753,11 @@ static int read_pair (qse_xli_t* xli, const qse_char_t* keytag, const qse_xli_sc
|
|||||||
if (xli->opt.trait & QSE_XLI_KEYNODUP) key_nodup = 1;
|
if (xli->opt.trait & QSE_XLI_KEYNODUP) key_nodup = 1;
|
||||||
if (xli->opt.trait & QSE_XLI_KEYALIAS) key_alias = 1;
|
if (xli->opt.trait & QSE_XLI_KEYALIAS) key_alias = 1;
|
||||||
|
|
||||||
|
/*if (MATCH(xli, QSE_XLI_TOK_SQSTR)) key_quoted = 1;
|
||||||
|
else if (MATCH(xli, QSE_XLI_TOK_DQSTR)) key_quoted = 2;*/
|
||||||
kloc = xli->tok.loc;
|
kloc = xli->tok.loc;
|
||||||
key.len = QSE_STR_LEN(xli->tok.name);
|
key.len = QSE_STR_LEN(xli->tok.name);
|
||||||
key.ptr = qse_strdup (QSE_STR_PTR(xli->tok.name), xli->mmgr);
|
key.ptr = qse_strdup(QSE_STR_PTR(xli->tok.name), xli->mmgr);
|
||||||
if (key.ptr == QSE_NULL)
|
if (key.ptr == QSE_NULL)
|
||||||
{
|
{
|
||||||
qse_xli_seterrnum (xli, QSE_XLI_ENOMEM, QSE_NULL);
|
qse_xli_seterrnum (xli, QSE_XLI_ENOMEM, QSE_NULL);
|
||||||
@ -745,8 +765,8 @@ static int read_pair (qse_xli_t* xli, const qse_char_t* keytag, const qse_xli_sc
|
|||||||
}
|
}
|
||||||
|
|
||||||
dotted_curkey_len = QSE_STR_LEN (xli->dotted_curkey);
|
dotted_curkey_len = QSE_STR_LEN (xli->dotted_curkey);
|
||||||
if ((dotted_curkey_len > 0 && qse_str_cat (xli->dotted_curkey, QSE_T(".")) == (qse_size_t)-1) ||
|
if ((dotted_curkey_len > 0 && qse_str_cat(xli->dotted_curkey, QSE_T(".")) == (qse_size_t)-1) ||
|
||||||
qse_str_cat (xli->dotted_curkey, key.ptr) == (qse_size_t)-1)
|
qse_str_cat(xli->dotted_curkey, key.ptr) == (qse_size_t)-1)
|
||||||
{
|
{
|
||||||
qse_xli_seterrnum (xli, QSE_XLI_ENOMEM, QSE_NULL);
|
qse_xli_seterrnum (xli, QSE_XLI_ENOMEM, QSE_NULL);
|
||||||
goto oops;
|
goto oops;
|
||||||
@ -784,7 +804,7 @@ static int read_pair (qse_xli_t* xli, const qse_char_t* keytag, const qse_xli_sc
|
|||||||
while (atom)
|
while (atom)
|
||||||
{
|
{
|
||||||
if (atom->type == QSE_XLI_PAIR &&
|
if (atom->type == QSE_XLI_PAIR &&
|
||||||
qse_strcmp (((qse_xli_pair_t*)atom)->key, QSE_STR_PTR(xli->tok.name)) == 0)
|
qse_strcmp(((qse_xli_pair_t*)atom)->key, QSE_STR_PTR(xli->tok.name)) == 0)
|
||||||
{
|
{
|
||||||
qse_xli_seterror (xli, QSE_XLI_EEXIST, QSE_STR_XSTR(xli->tok.name), &xli->tok.loc);
|
qse_xli_seterror (xli, QSE_XLI_EEXIST, QSE_STR_XSTR(xli->tok.name), &xli->tok.loc);
|
||||||
goto oops;
|
goto oops;
|
||||||
@ -794,15 +814,15 @@ static int read_pair (qse_xli_t* xli, const qse_char_t* keytag, const qse_xli_sc
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* once the key name is read, enable the numeric string for a value */
|
/* once the key name is read, enable the numeric string for a key alias and a value */
|
||||||
xli->tok_status |= TOK_STATUS_ENABLE_NSTR;
|
xli->tok_status |= TOK_STATUS_ENABLE_NSTR;
|
||||||
|
|
||||||
if (get_token (xli) <= -1) goto oops;
|
if (get_token(xli) <= -1) goto oops;
|
||||||
|
|
||||||
if (key_alias)
|
if (key_alias)
|
||||||
{
|
{
|
||||||
/* the alias part must be unique for the same key(s) */
|
/* the alias part must be unique for the same key(s) */
|
||||||
if (MATCH (xli, QSE_XLI_TOK_IDENT) || MATCH (xli, QSE_XLI_TOK_DQSTR) || MATCH (xli, QSE_XLI_TOK_SQSTR) || MATCH(xli, QSE_XLI_TOK_NSTR))
|
if (MATCH(xli, QSE_XLI_TOK_IDENT) || MATCH(xli, QSE_XLI_TOK_SQSTR) || MATCH(xli, QSE_XLI_TOK_DQSTR) || MATCH(xli, QSE_XLI_TOK_NSTR))
|
||||||
{
|
{
|
||||||
qse_xli_atom_t* atom;
|
qse_xli_atom_t* atom;
|
||||||
|
|
||||||
@ -827,6 +847,9 @@ static int read_pair (qse_xli_t* xli, const qse_char_t* keytag, const qse_xli_sc
|
|||||||
goto oops;
|
goto oops;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*if (MATCH(xli, QSE_XLI_TOK_SQSTR)) alias_quoted = 1;
|
||||||
|
else if (MATCH(xli, QSE_XLI_TOK_DQSTR)) alias_quoted = 2;*/
|
||||||
|
|
||||||
if (get_token (xli) <= -1) goto oops;
|
if (get_token (xli) <= -1) goto oops;
|
||||||
}
|
}
|
||||||
else if (key_alias == 2)
|
else if (key_alias == 2)
|
||||||
@ -838,10 +861,12 @@ static int read_pair (qse_xli_t* xli, const qse_char_t* keytag, const qse_xli_sc
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (MATCH (xli, QSE_XLI_TOK_EQ))
|
if (MATCH(xli, xli->opt._assign_tok)) /* either QSE_XLI_TOK_EQ or QSE_XLI_TOK_COLON */
|
||||||
{
|
{
|
||||||
if (get_token (xli) <= -1) goto oops;
|
if (get_token (xli) <= -1) goto oops;
|
||||||
|
|
||||||
|
if (!(xli->opt.trait & QSE_XLI_NOLIST) && MATCH(xli, QSE_XLI_TOK_LBRACE)) goto handle_list;
|
||||||
|
|
||||||
if ((xli->opt.trait & QSE_XLI_STRTAG) && MATCH (xli, QSE_XLI_TOK_TAG))
|
if ((xli->opt.trait & QSE_XLI_STRTAG) && MATCH (xli, QSE_XLI_TOK_TAG))
|
||||||
{
|
{
|
||||||
strtag = qse_strxdup (QSE_STR_PTR(xli->tok.name), QSE_STR_LEN(xli->tok.name), xli->mmgr);
|
strtag = qse_strxdup (QSE_STR_PTR(xli->tok.name), QSE_STR_LEN(xli->tok.name), xli->mmgr);
|
||||||
@ -854,7 +879,7 @@ static int read_pair (qse_xli_t* xli, const qse_char_t* keytag, const qse_xli_sc
|
|||||||
if (get_token (xli) <= -1) goto oops;
|
if (get_token (xli) <= -1) goto oops;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (MATCH (xli, QSE_XLI_TOK_SQSTR) || MATCH (xli, QSE_XLI_TOK_DQSTR) || MATCH(xli, QSE_XLI_TOK_NSTR) || MATCH (xli, QSE_XLI_TOK_IDENT))
|
if (MATCH(xli, QSE_XLI_TOK_SQSTR) || MATCH(xli, QSE_XLI_TOK_DQSTR) || MATCH(xli, QSE_XLI_TOK_NSTR) || MATCH(xli, QSE_XLI_TOK_IDENT))
|
||||||
{
|
{
|
||||||
qse_xli_str_t* curstrseg;
|
qse_xli_str_t* curstrseg;
|
||||||
qse_size_t segcount = 0;
|
qse_size_t segcount = 0;
|
||||||
@ -870,6 +895,11 @@ static int read_pair (qse_xli_t* xli, const qse_char_t* keytag, const qse_xli_sc
|
|||||||
pair = qse_xli_insertpairwithstr (xli, parlist, QSE_NULL, key.ptr, name, keytag, QSE_STR_XSTR(xli->tok.name), strtag);
|
pair = qse_xli_insertpairwithstr (xli, parlist, QSE_NULL, key.ptr, name, keytag, QSE_STR_XSTR(xli->tok.name), strtag);
|
||||||
if (pair == QSE_NULL) goto oops;
|
if (pair == QSE_NULL) goto oops;
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
pair->_key_quoted = key_quoted; /* store this for easier output support */
|
||||||
|
pair->_alias_quoted = alias_quoted;
|
||||||
|
#endif
|
||||||
|
|
||||||
segcount++;
|
segcount++;
|
||||||
curstrseg = (qse_xli_str_t*)pair->val;
|
curstrseg = (qse_xli_str_t*)pair->val;
|
||||||
|
|
||||||
@ -939,12 +969,12 @@ static int read_pair (qse_xli_t* xli, const qse_char_t* keytag, const qse_xli_sc
|
|||||||
goto oops;
|
goto oops;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* TODO: check against schema */
|
/* TODO: check against schema */
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (!(xli->opt.trait & QSE_XLI_NOLIST) && MATCH (xli, QSE_XLI_TOK_LBRACE))
|
else if (!(xli->opt.trait & QSE_XLI_NOLIST) && MATCH (xli, QSE_XLI_TOK_LBRACE))
|
||||||
{
|
{
|
||||||
|
handle_list:
|
||||||
if (scm && !(scm->flags & QSE_XLI_SCM_VALLIST))
|
if (scm && !(scm->flags & QSE_XLI_SCM_VALLIST))
|
||||||
{
|
{
|
||||||
/* check the value type */
|
/* check the value type */
|
||||||
@ -1050,8 +1080,10 @@ void qse_xli_freelistlink (qse_xli_t* xli, qse_xli_list_link_t* link)
|
|||||||
qse_xli_freemem (xli, link);
|
qse_xli_freemem (xli, link);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __read_list (qse_xli_t* xli, const qse_xli_scm_t* override)
|
static int __read_list (qse_xli_t* xli, const qse_xli_scm_t* override, int opt_outer_brace)
|
||||||
{
|
{
|
||||||
|
qse_size_t pair_count = 0;
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
if (MATCH (xli, QSE_XLI_TOK_XINCLUDE))
|
if (MATCH (xli, QSE_XLI_TOK_XINCLUDE))
|
||||||
@ -1066,12 +1098,17 @@ static int __read_list (qse_xli_t* xli, const qse_xli_scm_t* override)
|
|||||||
|
|
||||||
if (begin_include (xli) <= -1) return -1;
|
if (begin_include (xli) <= -1) return -1;
|
||||||
}
|
}
|
||||||
else if ((xli->opt.trait & QSE_XLI_KEYTAG) && MATCH (xli, QSE_XLI_TOK_TAG))
|
else if (opt_outer_brace == 1 && pair_count == 0 && MATCH(xli, QSE_XLI_TOK_LBRACE))
|
||||||
|
{
|
||||||
|
opt_outer_brace++;
|
||||||
|
if (get_token(xli) <= -1) return -1;
|
||||||
|
}
|
||||||
|
else if ((xli->opt.trait & QSE_XLI_KEYTAG) && MATCH(xli, QSE_XLI_TOK_TAG))
|
||||||
{
|
{
|
||||||
qse_char_t* keytag;
|
qse_char_t* keytag;
|
||||||
int x;
|
int x;
|
||||||
|
|
||||||
keytag = qse_strxdup (QSE_STR_PTR(xli->tok.name), QSE_STR_LEN(xli->tok.name), xli->mmgr);
|
keytag = qse_strxdup(QSE_STR_PTR(xli->tok.name), QSE_STR_LEN(xli->tok.name), xli->mmgr);
|
||||||
if (keytag == QSE_NULL)
|
if (keytag == QSE_NULL)
|
||||||
{
|
{
|
||||||
qse_xli_seterrnum (xli, QSE_XLI_ENOMEM, QSE_NULL);
|
qse_xli_seterrnum (xli, QSE_XLI_ENOMEM, QSE_NULL);
|
||||||
@ -1084,22 +1121,24 @@ static int __read_list (qse_xli_t* xli, const qse_xli_scm_t* override)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!MATCH(xli,QSE_XLI_TOK_IDENT))
|
if (!MATCH(xli,QSE_XLI_TOK_IDENT) && !MATCH(xli,QSE_XLI_TOK_SQSTR) && !MATCH(xli,QSE_XLI_TOK_DQSTR))
|
||||||
{
|
{
|
||||||
QSE_MMGR_FREE (xli->mmgr, keytag);
|
QSE_MMGR_FREE (xli->mmgr, keytag);
|
||||||
qse_xli_seterror (xli, QSE_XLI_ENOKEY, QSE_NULL, &xli->tok.loc);
|
qse_xli_seterror (xli, QSE_XLI_ENOKEY, QSE_NULL, &xli->tok.loc);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
x = read_pair (xli, keytag, override);
|
x = read_pair(xli, keytag, override);
|
||||||
QSE_MMGR_FREE (xli->mmgr, keytag);
|
QSE_MMGR_FREE (xli->mmgr, keytag);
|
||||||
if (x <= -1) return -1;
|
if (x <= -1) return -1;
|
||||||
|
pair_count++;
|
||||||
}
|
}
|
||||||
else if (MATCH (xli, QSE_XLI_TOK_IDENT))
|
else if (MATCH(xli, QSE_XLI_TOK_IDENT) || MATCH(xli, QSE_XLI_TOK_SQSTR) || MATCH(xli, QSE_XLI_TOK_DQSTR))
|
||||||
{
|
{
|
||||||
if (read_pair (xli, QSE_NULL, override) <= -1) return -1;
|
if (read_pair(xli, QSE_NULL, override) <= -1) return -1;
|
||||||
|
pair_count++;
|
||||||
}
|
}
|
||||||
else if (MATCH (xli, QSE_XLI_TOK_TEXT))
|
else if (MATCH(xli, QSE_XLI_TOK_TEXT))
|
||||||
{
|
{
|
||||||
if (get_token(xli) <= -1) return -1;
|
if (get_token(xli) <= -1) return -1;
|
||||||
}
|
}
|
||||||
@ -1109,6 +1148,16 @@ static int __read_list (qse_xli_t* xli, const qse_xli_scm_t* override)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (opt_outer_brace >= 2)
|
||||||
|
{
|
||||||
|
if (!MATCH(xli, QSE_XLI_TOK_RBRACE))
|
||||||
|
{
|
||||||
|
qse_xli_seterror (xli, QSE_XLI_ERBRCE, QSE_STR_XSTR(xli->tok.name), &xli->tok.loc);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (get_token(xli) <= -1) return -1;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1116,20 +1165,20 @@ static int read_list (qse_xli_t* xli, qse_xli_list_t* parlist, const qse_xli_scm
|
|||||||
{
|
{
|
||||||
qse_xli_list_link_t* link;
|
qse_xli_list_link_t* link;
|
||||||
|
|
||||||
link = qse_xli_makelistlink (xli, parlist);
|
link = qse_xli_makelistlink(xli, parlist);
|
||||||
if (link == QSE_NULL) return -1;
|
if (link == QSE_NULL) return -1;
|
||||||
|
|
||||||
/* get_token() here is to read the token after the left brace.
|
/* get_token() here is to read the token after the left brace.
|
||||||
* it must be called after the xli->parlink has been updated
|
* it must be called after the xli->parlink has been updated
|
||||||
* in case there are comments at the beginning of the list */
|
* in case there are comments at the beginning of the list */
|
||||||
if (get_token (xli) <= -1 || __read_list (xli, override) <= -1)
|
if (get_token(xli) <= -1 || __read_list(xli, override, 0) <= -1)
|
||||||
{
|
{
|
||||||
qse_xli_freelistlink (xli, link);
|
qse_xli_freelistlink (xli, link);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
QSE_ASSERT (link == xli->parlink);
|
QSE_ASSERT (link == xli->parlink);
|
||||||
qse_xli_freelistlink (xli, link);
|
qse_xli_freelistlink(xli, link);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -1138,17 +1187,18 @@ static int read_root_list (qse_xli_t* xli)
|
|||||||
{
|
{
|
||||||
qse_xli_list_link_t* link;
|
qse_xli_list_link_t* link;
|
||||||
|
|
||||||
link = qse_xli_makelistlink (xli, &xli->root->list);
|
link = qse_xli_makelistlink(xli, &xli->root->list);
|
||||||
if (!link) return -1;
|
if (!link) return -1;
|
||||||
|
|
||||||
if (qse_xli_getchar (xli) <= -1 || get_token (xli) <= -1 || __read_list (xli, QSE_NULL) <= -1)
|
/* TODO: pass opt_outer_brace 1 to __read_list only if a certian option is enabled */
|
||||||
|
if (qse_xli_getchar(xli) <= -1 || get_token(xli) <= -1 || __read_list(xli, QSE_NULL, 1) <= -1)
|
||||||
{
|
{
|
||||||
qse_xli_freelistlink (xli, link);
|
qse_xli_freelistlink (xli, link);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
QSE_ASSERT (link == xli->parlink);
|
QSE_ASSERT (link == xli->parlink);
|
||||||
qse_xli_freelistlink (xli, link);
|
qse_xli_freelistlink(xli, link);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "xli.h"
|
#include "xli.h"
|
||||||
|
#include <qse/cmn/chr.h>
|
||||||
|
|
||||||
typedef struct arg_data_t arg_data_t;
|
typedef struct arg_data_t arg_data_t;
|
||||||
struct arg_data_t
|
struct arg_data_t
|
||||||
@ -138,7 +139,7 @@ int qse_xli_closeactivewstream (qse_xli_t* xli, int* org_depth)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int write_to_current_stream (qse_xli_t* xli, const qse_char_t* ptr, qse_size_t len, int escape)
|
static int write_to_current_stream(qse_xli_t* xli, const qse_char_t* ptr, qse_size_t len, int escape)
|
||||||
{
|
{
|
||||||
qse_xli_io_arg_t* arg;
|
qse_xli_io_arg_t* arg;
|
||||||
qse_size_t i;
|
qse_size_t i;
|
||||||
@ -174,22 +175,100 @@ static int write_indentation (qse_xli_t* xli, int depth)
|
|||||||
|
|
||||||
if (depth <= QSE_COUNTOF(tabs))
|
if (depth <= QSE_COUNTOF(tabs))
|
||||||
{
|
{
|
||||||
if (write_to_current_stream (xli, tabs, depth, 0) <= -1) return -1;
|
if (write_to_current_stream(xli, tabs, depth, 0) <= -1) return -1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
if (write_to_current_stream (xli, tabs, QSE_COUNTOF(tabs), 0) <= -1) return -1;
|
if (write_to_current_stream(xli, tabs, QSE_COUNTOF(tabs), 0) <= -1) return -1;
|
||||||
for (i = QSE_COUNTOF(tabs); i < depth; i++)
|
for (i = QSE_COUNTOF(tabs); i < depth; i++)
|
||||||
{
|
{
|
||||||
if (write_to_current_stream (xli, QSE_T("\t"), 1, 0) <= -1) return -1;
|
if (write_to_current_stream(xli, QSE_T("\t"), 1, 0) <= -1) return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int key_needs_quoting (qse_xli_t* xli, const qse_char_t* str, int nstr)
|
||||||
|
{
|
||||||
|
/* this determines if a key or an alias requires quoting for output.
|
||||||
|
* NSTR is not taken into account because it's only allowed as a value */
|
||||||
|
|
||||||
|
/* refer to the tokenization rule in get_token_into() in read.c */
|
||||||
|
qse_char_t c;
|
||||||
|
|
||||||
|
c = *str++;
|
||||||
|
if (c == QSE_T('\0')) return 1; /* an empty string requires a quoting */
|
||||||
|
|
||||||
|
if (c == QSE_T('_') || QSE_ISALPHA(c) || (!nstr && (xli->opt.trait & QSE_XLI_LEADDIGIT) && QSE_ISDIGIT(c)))
|
||||||
|
{
|
||||||
|
int lead_digit = QSE_ISDIGIT(c);
|
||||||
|
int all_digits = 1;
|
||||||
|
|
||||||
|
/* a normal identifier can be composed of wider varieties of
|
||||||
|
* characters than a keyword/directive */
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
c = *str++;
|
||||||
|
if (c == QSE_T('\0')) break;
|
||||||
|
|
||||||
|
if (c == QSE_T('_') || c == QSE_T('-') ||
|
||||||
|
(!(xli->opt.trait & QSE_XLI_ASSIGNWITHCOLON) && c == QSE_T(':')) ||
|
||||||
|
c == QSE_T('*') || c == QSE_T('/') || QSE_ISALPHA(c))
|
||||||
|
{
|
||||||
|
all_digits = 0;
|
||||||
|
}
|
||||||
|
else if (QSE_ISDIGIT(c))
|
||||||
|
{
|
||||||
|
/* nothing to do */
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* a disallowed character for an identifier */
|
||||||
|
return 1; /* quote it */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lead_digit && all_digits)
|
||||||
|
{
|
||||||
|
/* if an identifier begins with a digit, it must contain a non-digit character */
|
||||||
|
/* in fact, it is not a valid identifer. so quote it */
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* this must be a normal identifer */
|
||||||
|
return 0; /* no quoting needed */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (nstr && QSE_ISDIGIT(c))
|
||||||
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
c = *str++;
|
||||||
|
if (c == QSE_T('\0')) return 0; /* it's a numeric string */
|
||||||
|
}
|
||||||
|
while (QSE_ISDIGIT(c));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* quote all the rest */
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
static int write_list (qse_xli_t* xli, qse_xli_list_t* list, int depth)
|
static int write_list (qse_xli_t* xli, qse_xli_list_t* list, int depth)
|
||||||
{
|
{
|
||||||
|
static struct
|
||||||
|
{
|
||||||
|
qse_char_t* qptr;
|
||||||
|
qse_size_t qlen;
|
||||||
|
} quotes[] =
|
||||||
|
{
|
||||||
|
{ QSE_T(""), 0 },
|
||||||
|
{ QSE_T("\'"), 1 },
|
||||||
|
{ QSE_T("\""), 1 }
|
||||||
|
};
|
||||||
|
|
||||||
qse_xli_atom_t* curatom;
|
qse_xli_atom_t* curatom;
|
||||||
|
|
||||||
for (curatom = list->head; curatom; curatom = curatom->next)
|
for (curatom = list->head; curatom; curatom = curatom->next)
|
||||||
@ -198,64 +277,84 @@ static int write_list (qse_xli_t* xli, qse_xli_list_t* list, int depth)
|
|||||||
{
|
{
|
||||||
case QSE_XLI_PAIR:
|
case QSE_XLI_PAIR:
|
||||||
{
|
{
|
||||||
|
int qtype;
|
||||||
qse_xli_pair_t* pair = (qse_xli_pair_t*)curatom;
|
qse_xli_pair_t* pair = (qse_xli_pair_t*)curatom;
|
||||||
|
|
||||||
if (write_indentation (xli, depth) <= -1) return -1;
|
if (write_indentation(xli, depth) <= -1) return -1;
|
||||||
|
|
||||||
if (pair->tag)
|
if (pair->tag)
|
||||||
{
|
{
|
||||||
if (write_to_current_stream (xli, QSE_T("["), 1, 0) <= -1 ||
|
if (write_to_current_stream(xli, &xli->opt.tag_marker[0], 1, 0) <= -1 ||
|
||||||
write_to_current_stream (xli, pair->tag, qse_strlen(pair->tag), 0) <= -1 ||
|
write_to_current_stream(xli, pair->tag, qse_strlen(pair->tag), 0) <= -1 ||
|
||||||
write_to_current_stream (xli, QSE_T("]"), 1, 0) <= -1) return -1;
|
write_to_current_stream(xli, &xli->opt.tag_marker[1], 1, 0) <= -1) return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (write_to_current_stream (xli, pair->key, qse_strlen(pair->key), 0) <= -1) return -1;
|
QSE_ASSERT(pair->_key_quoted >= 0 && pair->_key_quoted < QSE_COUNTOF(quotes));
|
||||||
|
qtype = pair->_key_quoted;
|
||||||
|
if (qtype <= 0 && key_needs_quoting(xli, pair->key, 0)) qtype = 2; /* force double quoting */
|
||||||
|
|
||||||
|
if (write_to_current_stream(xli, quotes[qtype].qptr, quotes[qtype].qlen, 0) <= -1 ||
|
||||||
|
write_to_current_stream(xli, pair->key, qse_strlen(pair->key), (qtype >= 2)) <= -1 ||
|
||||||
|
write_to_current_stream(xli, quotes[qtype].qptr, quotes[qtype].qlen, 0) <= -1) return -1;
|
||||||
|
|
||||||
if (pair->alias)
|
if (pair->alias)
|
||||||
{
|
{
|
||||||
if (write_to_current_stream (xli, QSE_T(" \""), 2, 0) <= -1 ||
|
QSE_ASSERT(pair->_alias_quoted >= 0 && pair->_alias_quoted < QSE_COUNTOF(quotes));
|
||||||
write_to_current_stream (xli, pair->alias, qse_strlen(pair->alias), 1) <= -1 ||
|
qtype = pair->_alias_quoted;
|
||||||
write_to_current_stream (xli, QSE_T("\""), 1, 0) <= -1) return -1;
|
if (qtype <= 0 && key_needs_quoting(xli, pair->alias, 1)) qtype = 2;
|
||||||
|
|
||||||
|
if (write_to_current_stream(xli, QSE_T(" "), 1, 0) <= -1 ||
|
||||||
|
write_to_current_stream(xli, quotes[qtype].qptr, quotes[qtype].qlen, 0) <= -1 ||
|
||||||
|
write_to_current_stream(xli, pair->alias, qse_strlen(pair->alias), (qtype >= 2)) <= -1 ||
|
||||||
|
write_to_current_stream(xli, quotes[qtype].qptr, quotes[qtype].qlen, 0) <= -1) return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (pair->val->type)
|
switch (pair->val->type)
|
||||||
{
|
{
|
||||||
case QSE_XLI_NIL:
|
case QSE_XLI_NIL:
|
||||||
if (write_to_current_stream (xli, QSE_T(";\n"), 2, 0) <= -1) return -1;
|
if (write_to_current_stream(xli, QSE_T(";\n"), 2, 0) <= -1) return -1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case QSE_XLI_STR:
|
case QSE_XLI_STR:
|
||||||
{
|
{
|
||||||
qse_xli_str_t* str = (qse_xli_str_t*)pair->val;
|
qse_xli_str_t* str = (qse_xli_str_t*)pair->val;
|
||||||
|
|
||||||
if (write_to_current_stream (xli, QSE_T(" = "), 3, 0) <= -1) return -1;
|
if (xli->opt.trait & QSE_XLI_ASSIGNWITHCOLON)
|
||||||
|
{
|
||||||
|
if (write_to_current_stream(xli, QSE_T(": "), 2, 0) <= -1) return -1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (write_to_current_stream(xli, QSE_T(" = "), 3, 0) <= -1) return -1;
|
||||||
|
}
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
if (str->tag)
|
if (str->tag)
|
||||||
{
|
{
|
||||||
if (write_to_current_stream (xli, QSE_T("["), 1, 0) <= -1 ||
|
if (write_to_current_stream(xli, QSE_T("["), 1, 0) <= -1 ||
|
||||||
write_to_current_stream (xli, str->tag, qse_strlen(str->tag), 0) <= -1 ||
|
write_to_current_stream(xli, str->tag, qse_strlen(str->tag), 0) <= -1 ||
|
||||||
write_to_current_stream (xli, QSE_T("]"), 1, 0) <= -1) return -1;
|
write_to_current_stream(xli, QSE_T("]"), 1, 0) <= -1) return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (write_to_current_stream (xli, QSE_T("\""), 1, 0) <= -1 ||
|
if (write_to_current_stream(xli, QSE_T("\""), 1, 0) <= -1 ||
|
||||||
write_to_current_stream (xli, str->ptr, str->len, 1) <= -1 ||
|
write_to_current_stream(xli, str->ptr, str->len, 1) <= -1 ||
|
||||||
write_to_current_stream (xli, QSE_T("\""), 1, 0) <= -1) return -1;
|
write_to_current_stream(xli, QSE_T("\""), 1, 0) <= -1) return -1;
|
||||||
if (!str->next) break;
|
if (!str->next) break;
|
||||||
|
|
||||||
if (write_to_current_stream (xli, QSE_T(", "), 2, 0) <= -1) return -1;
|
if (write_to_current_stream(xli, QSE_T(", "), 2, 0) <= -1) return -1;
|
||||||
str = str->next;
|
str = str->next;
|
||||||
}
|
}
|
||||||
if (write_to_current_stream (xli, QSE_T(";\n"), 2, 0) <= -1) return -1;
|
if (write_to_current_stream(xli, QSE_T(";\n"), 2, 0) <= -1) return -1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case QSE_XLI_LIST:
|
case QSE_XLI_LIST:
|
||||||
{
|
{
|
||||||
if (write_to_current_stream (xli, QSE_T(" {\n"), 3, 0) <= -1 ||
|
if (write_to_current_stream(xli, QSE_T(" {\n"), 3, 0) <= -1 ||
|
||||||
write_list (xli, (qse_xli_list_t*)pair->val, depth + 1) <= -1 ||
|
write_list (xli, (qse_xli_list_t*)pair->val, depth + 1) <= -1 ||
|
||||||
write_indentation (xli, depth) <= -1 ||
|
write_indentation (xli, depth) <= -1 ||
|
||||||
write_to_current_stream (xli, QSE_T("}\n"), 2, 0) <= -1) return -1;
|
write_to_current_stream(xli, QSE_T("}\n"), 2, 0) <= -1) return -1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -269,12 +368,12 @@ static int write_list (qse_xli_t* xli, qse_xli_list_t* list, int depth)
|
|||||||
|
|
||||||
for (i = 0; i < depth; i++)
|
for (i = 0; i < depth; i++)
|
||||||
{
|
{
|
||||||
if (write_to_current_stream (xli, QSE_T("\t"), 1, 0) <= -1) return -1;
|
if (write_to_current_stream(xli, QSE_T("\t"), 1, 0) <= -1) return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (write_to_current_stream (xli, QSE_T("#"), 1, 0) <= -1 ||
|
if (write_to_current_stream(xli, QSE_T("#"), 1, 0) <= -1 ||
|
||||||
write_to_current_stream (xli, str, qse_strlen(str), 0) <= -1 ||
|
write_to_current_stream(xli, str, qse_strlen(str), 0) <= -1 ||
|
||||||
write_to_current_stream (xli, QSE_T("\n"), 1, 0) <= -1) return -1;
|
write_to_current_stream(xli, QSE_T("\n"), 1, 0) <= -1) return -1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -285,12 +384,12 @@ static int write_list (qse_xli_t* xli, qse_xli_list_t* list, int depth)
|
|||||||
|
|
||||||
for (i = 0; i < depth; i++)
|
for (i = 0; i < depth; i++)
|
||||||
{
|
{
|
||||||
if (write_to_current_stream (xli, QSE_T("\t"), 1, 0) <= -1) return -1;
|
if (write_to_current_stream(xli, QSE_T("\t"), 1, 0) <= -1) return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (write_to_current_stream (xli, QSE_T("@include \""), 10, 0) <= -1 ||
|
if (write_to_current_stream(xli, QSE_T("@include \""), 10, 0) <= -1 ||
|
||||||
write_to_current_stream (xli, path, qse_strlen(path), 1) <= -1 ||
|
write_to_current_stream(xli, path, qse_strlen(path), 1) <= -1 ||
|
||||||
write_to_current_stream (xli, QSE_T("\";\n"), 3, 0) <= -1) return -1;
|
write_to_current_stream(xli, QSE_T("\";\n"), 3, 0) <= -1) return -1;
|
||||||
|
|
||||||
if (qse_xli_openwstream (xli, ((qse_xli_file_t*)curatom)->path, depth) <= -1) return -1;
|
if (qse_xli_openwstream (xli, ((qse_xli_file_t*)curatom)->path, depth) <= -1) return -1;
|
||||||
depth = 0;
|
depth = 0;
|
||||||
|
@ -70,6 +70,11 @@ int qse_xli_init (qse_xli_t* xli, qse_mmgr_t* mmgr, qse_size_t rootxtnsize)
|
|||||||
xli->errstr = qse_xli_dflerrstr;
|
xli->errstr = qse_xli_dflerrstr;
|
||||||
xli->opt.root_xtnsize = rootxtnsize;
|
xli->opt.root_xtnsize = rootxtnsize;
|
||||||
xli->opt.key_splitter = QSE_T('.');
|
xli->opt.key_splitter = QSE_T('.');
|
||||||
|
xli->opt.tag_marker[0] = QSE_T('[');
|
||||||
|
xli->opt.tag_marker[1] = QSE_T(']');
|
||||||
|
xli->opt.array_marker[0] = QSE_T('(');
|
||||||
|
xli->opt.array_marker[1] = QSE_T(')');
|
||||||
|
xli->opt._assign_tok = QSE_XLI_TOK_EQ;
|
||||||
|
|
||||||
xli->dotted_curkey = qse_str_open (mmgr, 0, 128);
|
xli->dotted_curkey = qse_str_open (mmgr, 0, 128);
|
||||||
if (xli->dotted_curkey == QSE_NULL) goto oops;
|
if (xli->dotted_curkey == QSE_NULL) goto oops;
|
||||||
@ -121,6 +126,7 @@ int qse_xli_setopt (qse_xli_t* xli, qse_xli_opt_t id, const void* value)
|
|||||||
{
|
{
|
||||||
case QSE_XLI_TRAIT:
|
case QSE_XLI_TRAIT:
|
||||||
xli->opt.trait = *(const int*)value;
|
xli->opt.trait = *(const int*)value;
|
||||||
|
xli->opt._assign_tok = (xli->opt.trait & QSE_XLI_ASSIGNWITHCOLON)? QSE_XLI_TOK_COLON: QSE_XLI_TOK_EQ;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
case QSE_XLI_PAIRXTNSIZE:
|
case QSE_XLI_PAIRXTNSIZE:
|
||||||
@ -134,6 +140,16 @@ int qse_xli_setopt (qse_xli_t* xli, qse_xli_opt_t id, const void* value)
|
|||||||
case QSE_XLI_KEYSPLITTER:
|
case QSE_XLI_KEYSPLITTER:
|
||||||
xli->opt.key_splitter = *(const qse_char_t*)value;
|
xli->opt.key_splitter = *(const qse_char_t*)value;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
case QSE_XLI_TAGMARKER:
|
||||||
|
xli->opt.tag_marker[0] = ((const qse_char_t*)value)[0];
|
||||||
|
xli->opt.tag_marker[1] = ((const qse_char_t*)value)[1];
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case QSE_XLI_ARRAYMARKER:
|
||||||
|
xli->opt.array_marker[0] = ((const qse_char_t*)value)[0];
|
||||||
|
xli->opt.array_marker[1] = ((const qse_char_t*)value)[1];
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
qse_xli_seterrnum (xli, QSE_XLI_EINVAL, QSE_NULL);
|
qse_xli_seterrnum (xli, QSE_XLI_EINVAL, QSE_NULL);
|
||||||
@ -159,6 +175,14 @@ int qse_xli_getopt (qse_xli_t* xli, qse_xli_opt_t id, void* value)
|
|||||||
case QSE_XLI_KEYSPLITTER:
|
case QSE_XLI_KEYSPLITTER:
|
||||||
*(qse_char_t*)value = xli->opt.key_splitter;
|
*(qse_char_t*)value = xli->opt.key_splitter;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
case QSE_XLI_TAGMARKER:
|
||||||
|
((qse_char_t*)value)[0] = xli->opt.tag_marker[1];
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case QSE_XLI_ARRAYMARKER:
|
||||||
|
((qse_char_t*)value)[0] = xli->opt.array_marker[1];
|
||||||
|
return 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
qse_xli_seterrnum (xli, QSE_XLI_EINVAL, QSE_NULL);
|
qse_xli_seterrnum (xli, QSE_XLI_EINVAL, QSE_NULL);
|
||||||
@ -1024,7 +1048,7 @@ int qse_xli_undefinepair (qse_xli_t* xli, const qse_char_t* fqpn)
|
|||||||
if (qse_rbt_delete (xli->schema, fqpn, qse_strlen(fqpn)) <= -1)
|
if (qse_rbt_delete (xli->schema, fqpn, qse_strlen(fqpn)) <= -1)
|
||||||
{
|
{
|
||||||
qse_cstr_t ea;
|
qse_cstr_t ea;
|
||||||
ea.ptr = fqpn;
|
ea.ptr = (qse_char_t*)fqpn;
|
||||||
ea.len = qse_strlen (ea.ptr);
|
ea.len = qse_strlen (ea.ptr);
|
||||||
qse_xli_seterrnum (xli, QSE_XLI_ENOENT, &ea);
|
qse_xli_seterrnum (xli, QSE_XLI_ENOENT, &ea);
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -37,6 +37,7 @@ enum qse_xli_tok_type_t
|
|||||||
QSE_XLI_TOK_EOF,
|
QSE_XLI_TOK_EOF,
|
||||||
QSE_XLI_TOK_XINCLUDE,
|
QSE_XLI_TOK_XINCLUDE,
|
||||||
QSE_XLI_TOK_SEMICOLON,
|
QSE_XLI_TOK_SEMICOLON,
|
||||||
|
QSE_XLI_TOK_COLON,
|
||||||
QSE_XLI_TOK_LBRACE,
|
QSE_XLI_TOK_LBRACE,
|
||||||
QSE_XLI_TOK_RBRACE,
|
QSE_XLI_TOK_RBRACE,
|
||||||
QSE_XLI_TOK_EQ,
|
QSE_XLI_TOK_EQ,
|
||||||
@ -93,6 +94,10 @@ struct qse_xli_t
|
|||||||
qse_size_t pair_xtnsize;
|
qse_size_t pair_xtnsize;
|
||||||
qse_size_t root_xtnsize;
|
qse_size_t root_xtnsize;
|
||||||
qse_char_t key_splitter; /**< character to use to split a key in the fqpn format */
|
qse_char_t key_splitter; /**< character to use to split a key in the fqpn format */
|
||||||
|
qse_char_t tag_marker[2];
|
||||||
|
qse_char_t array_marker[2];
|
||||||
|
|
||||||
|
qse_xli_tok_type_t _assign_tok;
|
||||||
} opt;
|
} opt;
|
||||||
|
|
||||||
qse_xli_ecb_t* ecb;
|
qse_xli_ecb_t* ecb;
|
||||||
@ -133,7 +138,7 @@ int qse_xli_init (qse_xli_t* xli, qse_mmgr_t* mmgr, qse_size_t rootxtnsize);
|
|||||||
void qse_xli_fini (qse_xli_t* xli);
|
void qse_xli_fini (qse_xli_t* xli);
|
||||||
|
|
||||||
const qse_char_t* qse_xli_dflerrstr (
|
const qse_char_t* qse_xli_dflerrstr (
|
||||||
const qse_xli_t* xli, qse_xli_errnum_t errnum);
|
const qse_xli_t* xli, qse_xli_errnum_t errnum);
|
||||||
|
|
||||||
void qse_xli_clearrionames (qse_xli_t* xli);
|
void qse_xli_clearrionames (qse_xli_t* xli);
|
||||||
void qse_xli_clearwionames (qse_xli_t* xli);
|
void qse_xli_clearwionames (qse_xli_t* xli);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user