added QSE_XLI_KEEPTEXT and QSE_XLI_KEEPFILE and implemented these options
This commit is contained in:
parent
a218958f51
commit
e7b5352046
@ -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;
|
||||
|
@ -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
|
||||
);
|
||||
|
@ -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);
|
||||
|
@ -84,10 +84,13 @@ static int write_list (qse_xli_t* xli, qse_xli_list_t* list, int depth)
|
||||
|
||||
case QSE_XLI_FILE:
|
||||
/* 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 */
|
||||
break;
|
||||
|
||||
case QSE_XLI_EOF:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user