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("options as follows:\n"));
qse_fprintf (out, QSE_T(" -h/--help show this message\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(" --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(" -o file specify an output file\n"));
qse_fprintf (out, QSE_T(" -n allow a key name\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")); 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)
qse_fprintf (out, QSE_T(" -X number fail the number'th memory allocation\n")); 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 = static qse_opt_t opt =
{ {
#if defined(QSE_BUILD_DEBUG) #if defined(QSE_BUILD_DEBUG)
QSE_T("hf:o:nm:X:"), QSE_T("hi:o:nftm:X:"),
#else #else
QSE_T("hf:o:nm:"), QSE_T("hi:o:nftm:"),
#endif #endif
lng lng
}; };
@ -193,7 +195,7 @@ static int handle_args (int argc, qse_char_t* argv[])
print_usage (QSE_STDOUT, argc, argv); print_usage (QSE_STDOUT, argc, argv);
goto done; goto done;
case QSE_T('f'): case QSE_T('i'):
g_input_file = opt.arg; g_input_file = opt.arg;
break; break;
@ -205,6 +207,14 @@ static int handle_args (int argc, qse_char_t* argv[])
g_trait |= QSE_XLI_KEYNAME; g_trait |= QSE_XLI_KEYNAME;
break; 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'): case QSE_T('m'):
g_memlimit = qse_strtoulong (opt.arg); g_memlimit = qse_strtoulong (opt.arg);
break; break;

View File

@ -73,9 +73,11 @@ typedef enum qse_xli_opt_t qse_xli_opt_t;
enum qse_xli_trait_t enum qse_xli_trait_t
{ {
QSE_XLI_KEYNODUP = (1 << 0), QSE_XLI_KEYNODUP = (1 << 1),
QSE_XLI_KEYNAME = (1 << 1), QSE_XLI_KEYNAME = (1 << 2),
QSE_XLI_NOTEXT = (1 << 10)
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; 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_pair_t qse_xli_pair_t;
typedef struct qse_xli_text_t qse_xli_text_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_file_t qse_xli_file_t;
typedef struct qse_xli_eof_t qse_xli_eof_t;
enum qse_xli_val_type_t enum qse_xli_val_type_t
{ {
@ -102,6 +105,7 @@ enum qse_xli_atom_type_t
QSE_XLI_PAIR, QSE_XLI_PAIR,
QSE_XLI_TEXT, QSE_XLI_TEXT,
QSE_XLI_FILE, QSE_XLI_FILE,
QSE_XLI_EOF
}; };
typedef enum qse_xli_atom_type_t qse_xli_atom_type_t; 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; 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 * The qse_xli_ecb_close_t type defines the callback function
* called when an xli object is cloxli. * 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 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_EXPORT qse_xli_list_t* qse_xli_getroot (
qse_xli_t* xli 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); GET_CHAR_TO (xli, c);
if (c == QSE_T('\n') || c == QSE_CHAR_EOF) break; if (c == QSE_T('\n') || c == QSE_CHAR_EOF) break;
#if 0
ADD_TOKEN_CHAR (xli, tok, c); if (xli->opt.trait & QSE_XLI_KEEPTEXT) ADD_TOKEN_CHAR (xli, tok, c);
#endif
} }
while (1); while (1);
#if 0 if ((xli->opt.trait & QSE_XLI_KEEPTEXT) &&
if (qse_xli_inserttext (xli, list, QSE_NULL, QSE_STR_PTR(tok->name)) <= -1) return -1; qse_xli_inserttext (xli, xli->parlink->list, QSE_NULL, QSE_STR_PTR(tok->name)) == QSE_NULL) return -1;
#endif
GET_CHAR (xli); /* eat the new line letter */ GET_CHAR (xli); /* eat the new line letter */
return 1; /* comment by # */ 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; return 0;
} }
static int end_include (qse_xli_t* xli) static int end_include (qse_xli_t* xli, int noeof)
{ {
int x; int x;
qse_xli_io_arg_t* cur; qse_xli_io_arg_t* cur;
if (xli->sio.inp == &xli->sio.arg) return 0; /* no include */ if (xli->sio.inp == &xli->sio.arg) return 0; /* no include */
/* if it is an included file, close it and /* if it is an included file, close it and
* retry to read a character from an outer file */ * 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); QSE_MMGR_FREE (xli->mmgr, cur);
/* xli->parse.depth.incl--; */ /* 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) if (x != 0)
{ {
/* the failure mentioned above is returned here */ /* the failure mentioned above is returned here */
@ -349,12 +351,19 @@ static int begin_include (qse_xli_t* xli)
* from this file. */ * from this file. */
if (get_char (xli) <= -1 || get_token (xli) <= -1) 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 /* i don't jump to oops since i've called
* end_include() where xli->sio.inp/arg is freed. */ * end_include() where xli->sio.inp/arg is freed. */
return -1; 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; return 0;
oops: oops:
@ -389,7 +398,7 @@ retry:
if (c == QSE_CHAR_EOF) if (c == QSE_CHAR_EOF)
{ {
n = end_include (xli); n = end_include (xli, 0);
if (n <= -1) return -1; if (n <= -1) return -1;
if (n >= 1) if (n >= 1)
{ {
@ -526,18 +535,21 @@ static int get_token (qse_xli_t* xli)
return get_token_into (xli, &xli->tok); 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* key = QSE_NULL;
qse_char_t* name = QSE_NULL; qse_char_t* name = QSE_NULL;
qse_xli_pair_t* pair; qse_xli_pair_t* pair;
qse_xli_list_t* parlist;
parlist = xli->parlink->list;
if (xli->opt.trait & QSE_XLI_KEYNODUP) if (xli->opt.trait & QSE_XLI_KEYNODUP)
{ {
qse_xli_atom_t* atom; qse_xli_atom_t* atom;
/* find any key conflicts in the current scope */ /* find any key conflicts in the current scope */
atom = list->tail; atom = parlist->tail;
while (atom) while (atom)
{ {
if (atom->type == QSE_XLI_PAIR && 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; qse_xli_atom_t* atom;
atom = list->tail; atom = parlist->tail;
while (atom) while (atom)
{ {
if (atom->type == QSE_XLI_PAIR && 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 ( 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; if (pair == QSE_NULL) goto oops;
/* semicolon is mandatory for a string */ /* 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; if (get_token (xli) <= -1) goto oops;
/* insert a pair with an empty list */ /* 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 (pair == QSE_NULL) goto oops;
if (read_list (xli, (qse_xli_list_t*)pair->val) <= -1) 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)) else if (MATCH (xli, TOK_SEMICOLON))
{ {
/* no value has been specified for the pair */ /* 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; if (pair == QSE_NULL) goto oops;
/* skip the semicolon */ /* skip the semicolon */
@ -698,8 +710,17 @@ oops:
return -1; 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) while (1)
{ {
if (MATCH (xli, TOK_XINCLUDE)) 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)) 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)) 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; return 0;
oops: oops:
if (link)
{
QSE_ASSERT (link == xli->parlink);
xli->parlink = link->next;
qse_xli_freemem (xli, link);
}
return -1; 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 (get_char (xli) <= -1 || get_token (xli) <= -1) goto oops;
if (read_list (xli, &xli->root) <= -1) goto oops; if (read_list (xli, &xli->root) <= -1) goto oops;
QSE_ASSERT (xli->parlink == QSE_NULL);
if (!MATCH (xli, TOK_EOF)) if (!MATCH (xli, TOK_EOF))
{ {
qse_xli_seterror (xli, QSE_XLI_ESYNTAX, QSE_NULL, &xli->tok.loc); qse_xli_seterror (xli, QSE_XLI_ESYNTAX, QSE_NULL, &xli->tok.loc);

View File

@ -84,10 +84,13 @@ static int write_list (qse_xli_t* xli, qse_xli_list_t* list, int depth)
case QSE_XLI_FILE: case QSE_XLI_FILE:
/* TODO filename escaping.... */ /* TODO filename escaping.... */
qse_printf (QSE_T("@include \"%s\";\n"),(( qse_xli_file_t*)curatom)->path); qse_printf (QSE_T("@include \"%s\";\n"),((qse_xli_file_t*)curatom)->path);
/* TODO: open a new stream */ /* TODO: open a new stream */
break; 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->type = QSE_XLI_TEXT;
text->ptr = (const qse_char_t*)(text + 1); 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); insert_atom (xli, parent, peer, (qse_xli_atom_t*)text);
return 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); 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; 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 struct qse_xli_t
{ {
qse_mmgr_t* mmgr; qse_mmgr_t* mmgr;
@ -50,8 +58,9 @@ struct qse_xli_t
qse_xli_ecb_t* ecb; qse_xli_ecb_t* ecb;
qse_xli_list_t root;
qse_xli_nil_t xnil; qse_xli_nil_t xnil;
qse_xli_list_t root;
qse_xli_list_link_t* parlink;
qse_str_t* tmp[1]; qse_str_t* tmp[1];
qse_xli_tok_t tok; qse_xli_tok_t tok;