Allow closing config elems with </> if from envvar
The Cyclone DDS configuration is in principle an XML document, but it is possible to write configuration fragments directly in the CYCLONEDDS_URI environment variable. In that case, it is quite annoying to have to enter the full closing tags all the time, and so it now allows closing elements with a simple </> when not reading them from a file. While it would be trivial to also allow this when reading the configuration from a file, it seems that promulgating invalid XML would be bad form ... and besides, in that case editors can help keep everything in order. Signed-off-by: Erik Boasson <eb@ilities.com>
This commit is contained in:
parent
b8e4b2a49b
commit
5ca66f5bda
3 changed files with 21 additions and 12 deletions
|
@ -2685,7 +2685,7 @@ struct cfgst * config_init (const char *configfile)
|
||||||
if (tok[0] == '<') {
|
if (tok[0] == '<') {
|
||||||
/* Read XML directly from input string */
|
/* Read XML directly from input string */
|
||||||
qx = ddsrt_xmlp_new_string (tok, cfgst, &cb);
|
qx = ddsrt_xmlp_new_string (tok, cfgst, &cb);
|
||||||
ddsrt_xmlp_set_requireEOF (qx, 0);
|
ddsrt_xmlp_set_options (qx, DDSRT_XMLP_ANONYMOUS_CLOSE_TAG);
|
||||||
fp = NULL;
|
fp = NULL;
|
||||||
} else {
|
} else {
|
||||||
char *comma;
|
char *comma;
|
||||||
|
|
|
@ -36,9 +36,12 @@ extern "C" {
|
||||||
|
|
||||||
struct ddsrt_xmlp_state;
|
struct ddsrt_xmlp_state;
|
||||||
|
|
||||||
|
#define DDSRT_XMLP_REQUIRE_EOF 1u /* set by default; if not set, junk may follow top-level closing tag */
|
||||||
|
#define DDSRT_XMLP_ANONYMOUS_CLOSE_TAG 2u /* clear by default; if set allow closing an element with </> instead of </name> */
|
||||||
|
|
||||||
DDS_EXPORT struct ddsrt_xmlp_state *ddsrt_xmlp_new_file (FILE *fp, void *varg, const struct ddsrt_xmlp_callbacks *cb);
|
DDS_EXPORT struct ddsrt_xmlp_state *ddsrt_xmlp_new_file (FILE *fp, void *varg, const struct ddsrt_xmlp_callbacks *cb);
|
||||||
DDS_EXPORT struct ddsrt_xmlp_state *ddsrt_xmlp_new_string (const char *string, void *varg, const struct ddsrt_xmlp_callbacks *cb);
|
DDS_EXPORT struct ddsrt_xmlp_state *ddsrt_xmlp_new_string (const char *string, void *varg, const struct ddsrt_xmlp_callbacks *cb);
|
||||||
DDS_EXPORT void ddsrt_xmlp_set_requireEOF (struct ddsrt_xmlp_state *st, int require_eof);
|
DDS_EXPORT void ddsrt_xmlp_set_options (struct ddsrt_xmlp_state *st, unsigned options);
|
||||||
DDS_EXPORT size_t ddsrt_xmlp_get_bufpos (const struct ddsrt_xmlp_state *st);
|
DDS_EXPORT size_t ddsrt_xmlp_get_bufpos (const struct ddsrt_xmlp_state *st);
|
||||||
DDS_EXPORT void ddsrt_xmlp_free (struct ddsrt_xmlp_state *st);
|
DDS_EXPORT void ddsrt_xmlp_free (struct ddsrt_xmlp_state *st);
|
||||||
DDS_EXPORT int ddsrt_xmlp_parse (struct ddsrt_xmlp_state *st);
|
DDS_EXPORT int ddsrt_xmlp_parse (struct ddsrt_xmlp_state *st);
|
||||||
|
|
|
@ -49,7 +49,7 @@ struct ddsrt_xmlp_state {
|
||||||
size_t tpescp; /* still escape sequences in tpescp .. tpp */
|
size_t tpescp; /* still escape sequences in tpescp .. tpp */
|
||||||
int nest; /* current nesting level */
|
int nest; /* current nesting level */
|
||||||
void *varg; /* user argument to callback functions */
|
void *varg; /* user argument to callback functions */
|
||||||
int require_eof; /* if false, junk may follow top-level closing tag */
|
unsigned options;
|
||||||
struct ddsrt_xmlp_callbacks cb; /* user-supplied callbacks (or stubs) */
|
struct ddsrt_xmlp_callbacks cb; /* user-supplied callbacks (or stubs) */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -108,7 +108,7 @@ static void ddsrt_xmlp_new_common (struct ddsrt_xmlp_state *st)
|
||||||
st->peekpayload = NULL;
|
st->peekpayload = NULL;
|
||||||
st->nest = 0;
|
st->nest = 0;
|
||||||
st->error = 0;
|
st->error = 0;
|
||||||
st->require_eof = 1;
|
st->options = DDSRT_XMLP_REQUIRE_EOF;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ddsrt_xmlp_new_setCB (struct ddsrt_xmlp_state *st, void *varg, const struct ddsrt_xmlp_callbacks *cb)
|
static void ddsrt_xmlp_new_setCB (struct ddsrt_xmlp_state *st, void *varg, const struct ddsrt_xmlp_callbacks *cb)
|
||||||
|
@ -148,9 +148,9 @@ struct ddsrt_xmlp_state *ddsrt_xmlp_new_string (const char *string, void *varg,
|
||||||
return st;
|
return st;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ddsrt_xmlp_set_requireEOF (struct ddsrt_xmlp_state *st, int require_eof)
|
void ddsrt_xmlp_set_options (struct ddsrt_xmlp_state *st, unsigned options)
|
||||||
{
|
{
|
||||||
st->require_eof = require_eof;
|
st->options = options;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t ddsrt_xmlp_get_bufpos (const struct ddsrt_xmlp_state *st)
|
size_t ddsrt_xmlp_get_bufpos (const struct ddsrt_xmlp_state *st)
|
||||||
|
@ -451,12 +451,15 @@ static int next_token_tag_withoutclose (struct ddsrt_xmlp_state *st, char **payl
|
||||||
next_char (st);
|
next_char (st);
|
||||||
}
|
}
|
||||||
/* we only do tag names that are identifiers */
|
/* we only do tag names that are identifiers */
|
||||||
if (!qq_isidentfirst (peek_char (st))) {
|
if (peek_char (st) == '>' && (st->options & DDSRT_XMLP_ANONYMOUS_CLOSE_TAG)) {
|
||||||
|
return TOK_SHORTHAND_CLOSE_TAG;
|
||||||
|
} else if (!qq_isidentfirst (peek_char (st))) {
|
||||||
return TOK_ERROR;
|
return TOK_ERROR;
|
||||||
}
|
} else {
|
||||||
next_token_ident (st, payload);
|
next_token_ident (st, payload);
|
||||||
return tok;
|
return tok;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int next_token_string (struct ddsrt_xmlp_state *st, char **payload)
|
static int next_token_string (struct ddsrt_xmlp_state *st, char **payload)
|
||||||
|
@ -560,6 +563,9 @@ static int next_token (struct ddsrt_xmlp_state *st, char **payload)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (tok == TOK_ERROR) {
|
if (tok == TOK_ERROR) {
|
||||||
|
char msg[512];
|
||||||
|
(void) snprintf (msg, sizeof (msg), "invalid token encountered");
|
||||||
|
st->cb.error (st->varg, msg, st->line);
|
||||||
st->error = 1;
|
st->error = 1;
|
||||||
}
|
}
|
||||||
return tok;
|
return tok;
|
||||||
|
@ -674,10 +680,10 @@ static int parse_element (struct ddsrt_xmlp_state *st, uintptr_t parentinfo)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
st->nest--;
|
st->nest--;
|
||||||
if (next_token (st, &ename) != TOK_CLOSE_TAG || next_char (st) != '>') {
|
if (((tok = next_token (st, &ename)) != TOK_CLOSE_TAG && tok != TOK_SHORTHAND_CLOSE_TAG) || next_char (st) != '>') {
|
||||||
PE_LOCAL_ERROR ("expecting closing tag", name);
|
PE_LOCAL_ERROR ("expecting closing tag", name);
|
||||||
}
|
}
|
||||||
if (strcmp (name, ename) != 0) {
|
if (tok != TOK_SHORTHAND_CLOSE_TAG && strcmp (name, ename) != 0) {
|
||||||
PE_LOCAL_ERROR ("open/close tag mismatch", ename);
|
PE_LOCAL_ERROR ("open/close tag mismatch", ename);
|
||||||
}
|
}
|
||||||
ret = st->cb.elem_close (st->varg, eleminfo);
|
ret = st->cb.elem_close (st->varg, eleminfo);
|
||||||
|
@ -709,7 +715,7 @@ int ddsrt_xmlp_parse (struct ddsrt_xmlp_state *st)
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
int ret = parse_element (st, 0);
|
int ret = parse_element (st, 0);
|
||||||
if (ret < 0|| !st->require_eof || next_token (st, NULL) == TOK_EOF ) {
|
if (ret < 0|| !(st->options & DDSRT_XMLP_REQUIRE_EOF) || next_token (st, NULL) == TOK_EOF ) {
|
||||||
return ret;
|
return ret;
|
||||||
} else {
|
} else {
|
||||||
return -1;
|
return -1;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue