allow configuration input (typically CYCLONEDDS_URI) to include XML fragments

The configuration handling already allowed specifying multiple files in CYCLONEDDS_URI to be read in-order, this extends the behaviour to also allow the contents of these files to be embedded. This makes it possible to set a configuration without requiring a file system, or to add some ad-hoc options.

Signed-off-by: Erik Boasson <eb@ilities.com>
This commit is contained in:
Erik Boasson 2019-03-23 13:06:37 +01:00
parent 15a3d7d3ad
commit a39701fc2e

View file

@ -2772,51 +2772,69 @@ struct cfgst * config_init (const char *configfile)
cfgst->error = 0; cfgst->error = 0;
/* configfile == NULL will get you the default configuration */ /* configfile == NULL will get you the default configuration */
if ( configfile ) { if (configfile) {
char *copy = ddsrt_strdup(configfile), *cursor = copy, *tok; char *copy = ddsrt_strdup(configfile), *cursor = copy;
while ( (tok = ddsrt_strsep(&cursor, ",")) != NULL ) { struct ut_xmlpCallbacks cb;
struct ut_xmlpCallbacks cb;
cb.attr = proc_attr;
cb.elem_close = proc_elem_close;
cb.elem_data = proc_elem_data;
cb.elem_open = proc_elem_open;
cb.error = proc_error;
while (ok && cursor && cursor[0]) {
struct ut_xmlpState *qx; struct ut_xmlpState *qx;
FILE *fp; FILE *fp;
char *tok;
DDSRT_WARNING_MSVC_OFF(4996); tok = cursor;
if ( (fp = fopen(tok, "r")) == NULL ) { if (tok[0] == '<') {
if ( strncmp(tok, "file://", 7) != 0 || (fp = fopen(tok + 7, "r")) == NULL ) { /* Read XML directly from input string */
DDS_ERROR("can't open configuration file %s\n", tok); qx = ut_xmlpNewString (tok, cfgst, &cb);
ddsrt_free(copy); ut_xmlpSetRequireEOF (qx, 0);
ddsrt_free(cfgst); fp = NULL;
return NULL; } else {
char *comma;
if ((comma = strchr (cursor, ',')) == NULL) {
cursor = NULL;
} else {
*comma = 0;
cursor = comma + 1;
} }
} DDSRT_WARNING_MSVC_OFF(4996);
DDSRT_WARNING_MSVC_ON(4996); if ((fp = fopen(tok, "r")) == NULL) {
if (strncmp(tok, "file://", 7) != 0 || (fp = fopen(tok + 7, "r")) == NULL) {
cb.attr = proc_attr; DDS_ERROR("can't open configuration file %s\n", tok);
cb.elem_close = proc_elem_close; ddsrt_free(copy);
cb.elem_data = proc_elem_data; ddsrt_free(cfgst);
cb.elem_open = proc_elem_open; return NULL;
cb.error = proc_error; }
}
if ( (qx = ut_xmlpNewFile(fp, cfgst, &cb)) == NULL ) { DDSRT_WARNING_MSVC_ON(4996);
fclose(fp); qx = ut_xmlpNewFile(fp, cfgst, &cb);
ddsrt_free(copy);
ddsrt_free(cfgst);
return NULL;
} }
cfgst_push(cfgst, 0, &root_cfgelem, &config); cfgst_push(cfgst, 0, &root_cfgelem, &config);
ok = (ut_xmlpParse(qx) >= 0) && !cfgst->error; ok = (ut_xmlpParse(qx) >= 0) && !cfgst->error;
/* Pop until stack empty: error handling is rather brutal */ /* Pop until stack empty: error handling is rather brutal */
assert(!ok || cfgst->path_depth == 1); assert(!ok || cfgst->path_depth == 1);
while ( cfgst->path_depth > 0 ) while (cfgst->path_depth > 0) {
cfgst_pop(cfgst); cfgst_pop(cfgst);
}
if (fp) {
fclose(fp);
} else if (ok) {
cursor = tok + ut_xmlpGetBufpos (qx);
}
ut_xmlpFree(qx); ut_xmlpFree(qx);
fclose(fp); while (cursor && cursor[0] == ',') {
cursor++;
}
} }
ddsrt_free(copy); ddsrt_free(copy);
} }
/* Set defaults for everything not set that we have a default value /* Set defaults for everything not set that we have a default value
for, signal errors for things unset but without a default. */ for, signal errors for things unset but without a default. */
{ {
int ok1 = set_defaults(cfgst, cfgst->cfg, 0, root_cfgelems, 0); int ok1 = set_defaults(cfgst, cfgst->cfg, 0, root_cfgelems, 0);
ok = ok && ok1; ok = ok && ok1;