added QSE_XLI_KEEPTEXT and QSE_XLI_KEEPFILE and implemented these options

This commit is contained in:
hyung-hwan 2013-06-23 14:44:29 +00:00
parent a218958f51
commit e7b5352046
6 changed files with 148 additions and 26 deletions

View File

@ -128,9 +128,11 @@ static void print_usage (QSE_FILE* out, int argc, qse_char_t* argv[])
qse_fprintf (out, QSE_T("options as follows:\n"));
qse_fprintf (out, QSE_T(" -h/--help show this message\n"));
qse_fprintf (out, QSE_T(" --version show version\n"));
qse_fprintf (out, QSE_T(" -f file specify an input file\n"));
qse_fprintf (out, QSE_T(" -i file specify an input file\n"));
qse_fprintf (out, QSE_T(" -o file specify an output file\n"));
qse_fprintf (out, QSE_T(" -n allow a key name\n"));
qse_fprintf (out, QSE_T(" -f keep file inclusion info\n"));
qse_fprintf (out, QSE_T(" -t keep comment text\n"));
qse_fprintf (out, QSE_T(" -m number specify the maximum amount of memory to use in bytes\n"));
#if defined(QSE_BUILD_DEBUG)
qse_fprintf (out, QSE_T(" -X number fail the number'th memory allocation\n"));
@ -157,9 +159,9 @@ static int handle_args (int argc, qse_char_t* argv[])
static qse_opt_t opt =
{
#if defined(QSE_BUILD_DEBUG)
QSE_T("hf:o:nm:X:"),
QSE_T("hi:o:nftm:X:"),
#else
QSE_T("hf:o:nm:"),
QSE_T("hi:o:nftm:"),
#endif
lng
};
@ -193,7 +195,7 @@ static int handle_args (int argc, qse_char_t* argv[])
print_usage (QSE_STDOUT, argc, argv);
goto done;
case QSE_T('f'):
case QSE_T('i'):
g_input_file = opt.arg;
break;
@ -205,6 +207,14 @@ static int handle_args (int argc, qse_char_t* argv[])
g_trait |= QSE_XLI_KEYNAME;
break;
case QSE_T('f'):
g_trait |= QSE_XLI_KEEPFILE;
break;
case QSE_T('t'):
g_trait |= QSE_XLI_KEEPTEXT;
break;
case QSE_T('m'):
g_memlimit = qse_strtoulong (opt.arg);
break;

View File

@ -73,9 +73,11 @@ typedef enum qse_xli_opt_t qse_xli_opt_t;
enum qse_xli_trait_t
{
QSE_XLI_KEYNODUP = (1 << 0),
QSE_XLI_KEYNAME = (1 << 1),
QSE_XLI_NOTEXT = (1 << 10)
QSE_XLI_KEYNODUP = (1 << 1),
QSE_XLI_KEYNAME = (1 << 2),
QSE_XLI_KEEPTEXT = (1 << 3), /**< keep comment text */
QSE_XLI_KEEPFILE = (1 << 4), /**< keep inclusion file info */
};
typedef enum qse_xli_trait_t qse_xli_trait_t;
@ -88,6 +90,7 @@ typedef struct qse_xli_atom_t qse_xli_atom_t;
typedef struct qse_xli_pair_t qse_xli_pair_t;
typedef struct qse_xli_text_t qse_xli_text_t;
typedef struct qse_xli_file_t qse_xli_file_t;
typedef struct qse_xli_eof_t qse_xli_eof_t;
enum qse_xli_val_type_t
{
@ -102,6 +105,7 @@ enum qse_xli_atom_type_t
QSE_XLI_PAIR,
QSE_XLI_TEXT,
QSE_XLI_FILE,
QSE_XLI_EOF
};
typedef enum qse_xli_atom_type_t qse_xli_atom_type_t;
@ -163,6 +167,12 @@ struct qse_xli_file_t
const qse_char_t* path;
};
struct qse_xli_eof_t
{
QSE_XLI_ATOM_HDR;
};
/**
* The qse_xli_ecb_close_t type defines the callback function
* called when an xli object is cloxli.
@ -487,6 +497,26 @@ QSE_EXPORT qse_xli_pair_t* qse_xli_insertpairwithstr (
const qse_cstr_t* value
);
QSE_EXPORT qse_xli_text_t* qse_xli_inserttext (
qse_xli_t* xli,
qse_xli_list_t* parent,
qse_xli_atom_t* peer,
const qse_char_t* str
);
QSE_EXPORT qse_xli_file_t* qse_xli_insertfile (
qse_xli_t* xli,
qse_xli_list_t* parent,
qse_xli_atom_t* peer,
const qse_char_t* path
);
QSE_EXPORT qse_xli_eof_t* qse_xli_inserteof (
qse_xli_t* xli,
qse_xli_list_t* parent,
qse_xli_atom_t* peer
);
QSE_EXPORT qse_xli_list_t* qse_xli_getroot (
qse_xli_t* xli
);

View File

@ -174,15 +174,13 @@ static int skip_comment (qse_xli_t* xli, qse_xli_tok_t* tok)
{
GET_CHAR_TO (xli, c);
if (c == QSE_T('\n') || c == QSE_CHAR_EOF) break;
#if 0
ADD_TOKEN_CHAR (xli, tok, c);
#endif
if (xli->opt.trait & QSE_XLI_KEEPTEXT) ADD_TOKEN_CHAR (xli, tok, c);
}
while (1);
#if 0
if (qse_xli_inserttext (xli, list, QSE_NULL, QSE_STR_PTR(tok->name)) <= -1) return -1;
#endif
if ((xli->opt.trait & QSE_XLI_KEEPTEXT) &&
qse_xli_inserttext (xli, xli->parlink->list, QSE_NULL, QSE_STR_PTR(tok->name)) == QSE_NULL) return -1;
GET_CHAR (xli); /* eat the new line letter */
return 1; /* comment by # */
@ -271,13 +269,14 @@ static int get_symbols (qse_xli_t* xli, qse_cint_t c, qse_xli_tok_t* tok)
return 0;
}
static int end_include (qse_xli_t* xli)
static int end_include (qse_xli_t* xli, int noeof)
{
int x;
qse_xli_io_arg_t* cur;
if (xli->sio.inp == &xli->sio.arg) return 0; /* no include */
/* if it is an included file, close it and
* retry to read a character from an outer file */
@ -298,6 +297,9 @@ static int end_include (qse_xli_t* xli)
QSE_MMGR_FREE (xli->mmgr, cur);
/* xli->parse.depth.incl--; */
if ((xli->opt.trait & QSE_XLI_KEEPFILE) && !noeof &&
qse_xli_inserteof (xli, xli->parlink->list, QSE_NULL) == QSE_NULL) return -1;
if (x != 0)
{
/* the failure mentioned above is returned here */
@ -349,12 +351,19 @@ static int begin_include (qse_xli_t* xli)
* from this file. */
if (get_char (xli) <= -1 || get_token (xli) <= -1)
{
end_include (xli);
end_include (xli, 1);
/* i don't jump to oops since i've called
* end_include() where xli->sio.inp/arg is freed. */
return -1;
}
if ((xli->opt.trait & QSE_XLI_KEEPFILE) &&
qse_xli_insertfile (xli, xli->parlink->list, QSE_NULL, arg->name) == QSE_NULL)
{
end_include (xli, 1);
return -1;
}
return 0;
oops:
@ -389,7 +398,7 @@ retry:
if (c == QSE_CHAR_EOF)
{
n = end_include (xli);
n = end_include (xli, 0);
if (n <= -1) return -1;
if (n >= 1)
{
@ -526,18 +535,21 @@ static int get_token (qse_xli_t* xli)
return get_token_into (xli, &xli->tok);
}
static int read_pair (qse_xli_t* xli, qse_xli_list_t* list)
static int read_pair (qse_xli_t* xli)
{
qse_char_t* key = QSE_NULL;
qse_char_t* name = QSE_NULL;
qse_xli_pair_t* pair;
qse_xli_list_t* parlist;
parlist = xli->parlink->list;
if (xli->opt.trait & QSE_XLI_KEYNODUP)
{
qse_xli_atom_t* atom;
/* find any key conflicts in the current scope */
atom = list->tail;
atom = parlist->tail;
while (atom)
{
if (atom->type == QSE_XLI_PAIR &&
@ -567,7 +579,7 @@ static int read_pair (qse_xli_t* xli, qse_xli_list_t* list)
{
qse_xli_atom_t* atom;
atom = list->tail;
atom = parlist->tail;
while (atom)
{
if (atom->type == QSE_XLI_PAIR &&
@ -630,7 +642,7 @@ static int read_pair (qse_xli_t* xli, qse_xli_list_t* list)
}
pair = qse_xli_insertpairwithstr (
xli, list, QSE_NULL, key, name, QSE_STR_CSTR(xli->tmp[0]));
xli, parlist, QSE_NULL, key, name, QSE_STR_CSTR(xli->tmp[0]));
if (pair == QSE_NULL) goto oops;
/* semicolon is mandatory for a string */
@ -653,7 +665,7 @@ static int read_pair (qse_xli_t* xli, qse_xli_list_t* list)
if (get_token (xli) <= -1) goto oops;
/* insert a pair with an empty list */
pair = qse_xli_insertpairwithemptylist (xli, list, QSE_NULL, key, name);
pair = qse_xli_insertpairwithemptylist (xli, parlist, QSE_NULL, key, name);
if (pair == QSE_NULL) goto oops;
if (read_list (xli, (qse_xli_list_t*)pair->val) <= -1) goto oops;
@ -676,7 +688,7 @@ static int read_pair (qse_xli_t* xli, qse_xli_list_t* list)
else if (MATCH (xli, TOK_SEMICOLON))
{
/* no value has been specified for the pair */
pair = qse_xli_insertpair (xli, list, QSE_NULL, key, name, &xli->xnil);
pair = qse_xli_insertpair (xli, parlist, QSE_NULL, key, name, &xli->xnil);
if (pair == QSE_NULL) goto oops;
/* skip the semicolon */
@ -698,8 +710,17 @@ oops:
return -1;
}
static int read_list (qse_xli_t* xli, qse_xli_list_t* list)
static int read_list (qse_xli_t* xli, qse_xli_list_t* parlist)
{
qse_xli_list_link_t* link = QSE_NULL;
link = (qse_xli_list_link_t*) qse_xli_callocmem (xli, QSE_SIZEOF(*link));
if (link == QSE_NULL) goto oops;
link->list = parlist;
link->next = xli->parlink;
xli->parlink = link;
while (1)
{
if (MATCH (xli, TOK_XINCLUDE))
@ -716,7 +737,7 @@ static int read_list (qse_xli_t* xli, qse_xli_list_t* list)
}
else if (MATCH (xli, TOK_IDENT))
{
if (read_pair (xli, list) <= -1) goto oops;
if (read_pair (xli) <= -1) goto oops;
}
else if (MATCH (xli, TOK_TEXT))
{
@ -728,9 +749,19 @@ static int read_list (qse_xli_t* xli, qse_xli_list_t* list)
}
}
QSE_ASSERT (link == xli->parlink);
xli->parlink = link->next;
qse_xli_freemem (xli, link);
return 0;
oops:
if (link)
{
QSE_ASSERT (link == xli->parlink);
xli->parlink = link->next;
qse_xli_freemem (xli, link);
}
return -1;
}
@ -774,6 +805,8 @@ int qse_xli_read (qse_xli_t* xli, qse_xli_io_impl_t io)
if (get_char (xli) <= -1 || get_token (xli) <= -1) goto oops;
if (read_list (xli, &xli->root) <= -1) goto oops;
QSE_ASSERT (xli->parlink == QSE_NULL);
if (!MATCH (xli, TOK_EOF))
{
qse_xli_seterror (xli, QSE_XLI_ESYNTAX, QSE_NULL, &xli->tok.loc);

View File

@ -88,6 +88,9 @@ static int write_list (qse_xli_t* xli, qse_xli_list_t* list, int depth)
/* TODO: open a new stream */
break;
case QSE_XLI_EOF:
break;
}
}

View File

@ -300,11 +300,48 @@ qse_xli_text_t* qse_xli_inserttext (
text->type = QSE_XLI_TEXT;
text->ptr = (const qse_char_t*)(text + 1);
qse_strcpy ((qse_char_t*)(text + 1), str);
insert_atom (xli, parent, peer, (qse_xli_atom_t*)text);
return text;
}
qse_xli_file_t* qse_xli_insertfile (
qse_xli_t* xli, qse_xli_list_t* parent, qse_xli_atom_t* peer, const qse_char_t* path)
{
qse_xli_file_t* file;
qse_size_t plen;
plen = qse_strlen (path);
file = qse_xli_callocmem (xli, QSE_SIZEOF(*file) + ((plen + 1) * QSE_SIZEOF(*path)));
if (file == QSE_NULL) return QSE_NULL;
file->type = QSE_XLI_FILE;
file->path = (const qse_char_t*)(file + 1);
qse_strcpy ((qse_char_t*)(file + 1), path);
insert_atom (xli, parent, peer, (qse_xli_atom_t*)file);
return file;
}
qse_xli_eof_t* qse_xli_inserteof (
qse_xli_t* xli, qse_xli_list_t* parent, qse_xli_atom_t* peer)
{
qse_xli_eof_t* eof;
eof = qse_xli_callocmem (xli, QSE_SIZEOF(*eof));
if (eof == QSE_NULL) return QSE_NULL;
eof->type = QSE_XLI_EOF;
insert_atom (xli, parent, peer, (qse_xli_atom_t*)eof);
return eof;
}
/* ------------------------------------------------------ */
static void free_list (qse_xli_t* xli, qse_xli_list_t* list);

View File

@ -34,6 +34,14 @@ struct qse_xli_tok_t
qse_xli_loc_t loc;
};
typedef struct qse_xli_list_link_t qse_xli_list_link_t;
struct qse_xli_list_link_t
{
qse_xli_list_link_t* next;
qse_xli_list_t* list;
};
struct qse_xli_t
{
qse_mmgr_t* mmgr;
@ -50,8 +58,9 @@ struct qse_xli_t
qse_xli_ecb_t* ecb;
qse_xli_list_t root;
qse_xli_nil_t xnil;
qse_xli_list_t root;
qse_xli_list_link_t* parlink;
qse_str_t* tmp[1];
qse_xli_tok_t tok;