Support multiple domains in configuration
Change the structure of the configuration file (in a backwards compatible manner) to allow specifying configurations for multiple domains in a file. (Listing multiple files in CYCLONEDDS_URI was already supported.) A configuration specifies an id, with a default of any, configurations for an incompatible id are ignored. If the application specifies an id other than DDS_DOMAIN_DEFAULT in the call to create_participant, then only configuration specifications for Domain elements with that id or with id "any" will be used. If the application does specify DDS_DOMAIN_DEFAULT, then the id will be taken from the first Domain element that specifies an id. If none do, the domain id defaults to 0. Each applicable domain specification is taken as a separate source and may override settings made previously. All settings moved from the top-level CycloneDDS element to the CycloneDDS/Domain element. The CycloneDDS/Domain/Id element moved to become the "id" attribute of CycloneDDS/Domain. The old locations still work, with appropriate deprecation warnings. Signed-off-by: Erik Boasson <eb@ilities.com>
This commit is contained in:
parent
70a342991f
commit
891fc2b12f
27 changed files with 1161 additions and 711 deletions
|
@ -109,11 +109,21 @@ typedef struct {
|
|||
} dds_log_data_t;
|
||||
|
||||
/** Function signature that log and trace callbacks must adhere too. */
|
||||
typedef void(*dds_log_write_fn_t)(void *, const dds_log_data_t *);
|
||||
typedef void (*dds_log_write_fn_t) (void *, const dds_log_data_t *);
|
||||
|
||||
/** Semi-opaque type for log/trace configuration. */
|
||||
struct ddsrt_log_cfg_common {
|
||||
/** Mask for testing whether the xLOG macro should forward to the
|
||||
function (and so incur the cost of constructing the parameters).
|
||||
Messages in DDS_LOG_MASK are rare, so the overhead of calling
|
||||
the function and then dropping the message is not an issue, unlike
|
||||
for messages in DDS_TRACE_MASK. */
|
||||
uint32_t mask;
|
||||
|
||||
/** The actual configured trace mask */
|
||||
uint32_t tracemask;
|
||||
|
||||
/** Domain id for reporting; UINT32_MAX = no domain */
|
||||
uint32_t domid;
|
||||
};
|
||||
|
||||
|
@ -225,7 +235,7 @@ dds_set_trace_sink(
|
|||
* other parameters.
|
||||
* @param[in] domid Numerical identifier in log/trace, UINT32_MAX is
|
||||
* reserved for global logging.
|
||||
* @param[in] mask Mask determining what to log/trace.
|
||||
* @param[in] tracemask Mask determining which traces should be written.
|
||||
* @param[in] log_fp File for default sink.
|
||||
* @param[in] trace_fp File for default sink.
|
||||
*/
|
||||
|
@ -233,7 +243,7 @@ DDS_EXPORT void
|
|||
dds_log_cfg_init(
|
||||
struct ddsrt_log_cfg *cfg,
|
||||
uint32_t domid,
|
||||
uint32_t mask,
|
||||
uint32_t tracemask,
|
||||
FILE *log_fp,
|
||||
FILE *trace_fp);
|
||||
|
||||
|
@ -244,7 +254,7 @@ dds_log_cfg_init(
|
|||
* Direct use of #dds_log is discouraged. Use #DDS_CINFO, #DDS_CWARNING,
|
||||
* #DDS_CERROR, #DDS_CTRACE or #DDS_CLOG instead.
|
||||
*/
|
||||
DDS_EXPORT int
|
||||
DDS_EXPORT void
|
||||
dds_log_cfg(
|
||||
const struct ddsrt_log_cfg *cfg,
|
||||
uint32_t prio,
|
||||
|
@ -264,7 +274,7 @@ dds_log_cfg(
|
|||
*
|
||||
* Direct use of #dds_log_id is discouraged. Use #DDS_ILOG instead.
|
||||
*/
|
||||
DDS_EXPORT int
|
||||
DDS_EXPORT void
|
||||
dds_log_id(
|
||||
uint32_t prio,
|
||||
uint32_t domid,
|
||||
|
@ -283,7 +293,7 @@ dds_log_id(
|
|||
* Direct use of #dds_log is discouraged. Use #DDS_INFO, #DDS_WARNING,
|
||||
* #DDS_ERROR, #DDS_FATAL or #DDS_LOG instead.
|
||||
*/
|
||||
DDS_EXPORT int
|
||||
DDS_EXPORT void
|
||||
dds_log(
|
||||
uint32_t prio,
|
||||
const char *file,
|
||||
|
|
|
@ -20,10 +20,10 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef int (*ddsrt_xmlp_proc_elem_open_t) (void *varg, uintptr_t parentinfo, uintptr_t *eleminfo, const char *name);
|
||||
typedef int (*ddsrt_xmlp_proc_attr_t) (void *varg, uintptr_t eleminfo, const char *name, const char *value);
|
||||
typedef int (*ddsrt_xmlp_proc_elem_data_t) (void *varg, uintptr_t eleminfo, const char *data);
|
||||
typedef int (*ddsrt_xmlp_proc_elem_close_t) (void *varg, uintptr_t eleminfo);
|
||||
typedef int (*ddsrt_xmlp_proc_elem_open_t) (void *varg, uintptr_t parentinfo, uintptr_t *eleminfo, const char *name, int line);
|
||||
typedef int (*ddsrt_xmlp_proc_attr_t) (void *varg, uintptr_t eleminfo, const char *name, const char *value, int line);
|
||||
typedef int (*ddsrt_xmlp_proc_elem_data_t) (void *varg, uintptr_t eleminfo, const char *data, int line);
|
||||
typedef int (*ddsrt_xmlp_proc_elem_close_t) (void *varg, uintptr_t eleminfo, int line);
|
||||
typedef void (*ddsrt_xmlp_error) (void *varg, const char *msg, int line);
|
||||
|
||||
struct ddsrt_xmlp_callbacks {
|
||||
|
@ -46,8 +46,6 @@ extern "C" {
|
|||
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_xmlUnescapeInsitu (char *buffer, size_t *n);
|
||||
|
||||
#if defined (__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -44,7 +44,7 @@ static char *expand_env (const char *name, char op, const char *alt, expand_fn e
|
|||
} else if (strcmp (name, "$") == 0 || strcmp (name, "CYCLONEDDS_PID") == 0) {
|
||||
snprintf (idstr, sizeof (idstr), "%"PRIdPID, ddsrt_getpid ());
|
||||
env = idstr;
|
||||
} else if (strcmp (name, "CYCLONEDDS_DOMAIN_ID") == 0) {
|
||||
} else if (strcmp (name, "CYCLONEDDS_DOMAIN_ID") == 0 && domid != UINT32_MAX) {
|
||||
snprintf (idstr, sizeof (idstr), "%"PRIu32, domid);
|
||||
env = idstr;
|
||||
}
|
||||
|
|
|
@ -33,7 +33,7 @@ typedef struct {
|
|||
} log_buffer_t;
|
||||
|
||||
typedef struct {
|
||||
dds_log_write_fn_t funcs[2];
|
||||
dds_log_write_fn_t func;
|
||||
void *ptr;
|
||||
FILE *out;
|
||||
} log_sink_t;
|
||||
|
@ -52,25 +52,20 @@ DDSRT_STATIC_ASSERT (sizeof (struct ddsrt_log_cfg_impl) <= sizeof (struct ddsrt_
|
|||
|
||||
static void default_sink (void *ptr, const dds_log_data_t *data)
|
||||
{
|
||||
fwrite (data->message - data->hdrsize, 1, data->hdrsize + data->size + 1, (FILE *) ptr);
|
||||
fflush ((FILE *) ptr);
|
||||
}
|
||||
|
||||
static void nop_sink (void *ptr, const dds_log_data_t *data)
|
||||
{
|
||||
(void) ptr;
|
||||
(void) data;
|
||||
return;
|
||||
if (ptr)
|
||||
{
|
||||
fwrite (data->message - data->hdrsize, 1, data->hdrsize + data->size + 1, (FILE *) ptr);
|
||||
fflush ((FILE *) ptr);
|
||||
}
|
||||
}
|
||||
|
||||
#define LOG (0)
|
||||
#define TRACE (1)
|
||||
#define USE (0)
|
||||
#define SET (1)
|
||||
|
||||
static struct ddsrt_log_cfg_impl logconfig = {
|
||||
.c = {
|
||||
.mask = DDS_LC_ERROR | DDS_LC_WARNING,
|
||||
.tracemask = 0,
|
||||
.domid = UINT32_MAX
|
||||
},
|
||||
.sink_fps = {
|
||||
|
@ -80,11 +75,11 @@ static struct ddsrt_log_cfg_impl logconfig = {
|
|||
};
|
||||
|
||||
static log_sink_t sinks[2] = {
|
||||
[LOG] = { .funcs = { [USE] = default_sink, [SET] = default_sink }, .ptr = NULL, .out = NULL },
|
||||
[TRACE] = { .funcs = { [USE] = default_sink, [SET] = default_sink }, .ptr = NULL, .out = NULL }
|
||||
[LOG] = { .func = default_sink, .ptr = NULL, .out = NULL },
|
||||
[TRACE] = { .func = default_sink, .ptr = NULL, .out = NULL }
|
||||
};
|
||||
|
||||
uint32_t *const dds_log_mask = &logconfig.c.mask;
|
||||
uint32_t * const dds_log_mask = &logconfig.c.mask;
|
||||
|
||||
static void init_lock (void)
|
||||
{
|
||||
|
@ -112,17 +107,6 @@ static void unlock_sink (void)
|
|||
ddsrt_rwlock_unlock (&lock);
|
||||
}
|
||||
|
||||
static void set_active_log_sinks (void)
|
||||
{
|
||||
sinks[LOG].funcs[USE] = sinks[LOG].funcs[SET];
|
||||
sinks[TRACE].funcs[USE] = sinks[TRACE].funcs[SET];
|
||||
if (sinks[LOG].funcs[USE] == sinks[TRACE].funcs[USE])
|
||||
{
|
||||
if (sinks[LOG].funcs[USE] != default_sink && sinks[LOG].ptr == sinks[TRACE].ptr)
|
||||
sinks[LOG].funcs[USE] = nop_sink;
|
||||
}
|
||||
}
|
||||
|
||||
static void set_log_sink (log_sink_t *sink, dds_log_write_fn_t func, void *ptr)
|
||||
{
|
||||
assert (sink != NULL);
|
||||
|
@ -132,9 +116,8 @@ static void set_log_sink (log_sink_t *sink, dds_log_write_fn_t func, void *ptr)
|
|||
responsible for that. Ensure this operation is deterministic and that on
|
||||
return, no thread in the DDS stack still uses the deprecated sink. */
|
||||
lock_sink (WRLOCK);
|
||||
sink->funcs[SET] = (func != 0) ? func : default_sink;
|
||||
sink->func = (func != 0) ? func : default_sink;
|
||||
sink->ptr = ptr;
|
||||
set_active_log_sinks ();
|
||||
unlock_sink ();
|
||||
}
|
||||
|
||||
|
@ -143,7 +126,6 @@ void dds_set_log_file (FILE *file)
|
|||
{
|
||||
lock_sink (WRLOCK);
|
||||
logconfig.sink_fps[LOG] = (file == NULL ? stderr : file);
|
||||
set_active_log_sinks ();
|
||||
unlock_sink ();
|
||||
}
|
||||
|
||||
|
@ -151,7 +133,6 @@ void dds_set_trace_file (FILE *file)
|
|||
{
|
||||
lock_sink (WRLOCK);
|
||||
logconfig.sink_fps[TRACE] = (file == NULL ? stderr : file);
|
||||
set_active_log_sinks ();
|
||||
unlock_sink ();
|
||||
}
|
||||
|
||||
|
@ -170,17 +151,18 @@ extern inline uint32_t dds_get_log_mask (void);
|
|||
void dds_set_log_mask (uint32_t cats)
|
||||
{
|
||||
lock_sink (WRLOCK);
|
||||
*dds_log_mask = (cats & (DDS_LOG_MASK | DDS_TRACE_MASK));
|
||||
set_active_log_sinks ();
|
||||
logconfig.c.tracemask = cats & DDS_TRACE_MASK;
|
||||
logconfig.c.mask = (cats & (DDS_LOG_MASK | DDS_TRACE_MASK)) | DDS_LC_FATAL;
|
||||
unlock_sink ();
|
||||
}
|
||||
|
||||
void dds_log_cfg_init (struct ddsrt_log_cfg *cfg, uint32_t domid, uint32_t mask, FILE *log_fp, FILE *trace_fp)
|
||||
void dds_log_cfg_init (struct ddsrt_log_cfg *cfg, uint32_t domid, uint32_t tracemask, FILE *log_fp, FILE *trace_fp)
|
||||
{
|
||||
struct ddsrt_log_cfg_impl *cfgimpl = (struct ddsrt_log_cfg_impl *) cfg;
|
||||
assert (domid != UINT32_MAX); /* because that's reserved for global use */
|
||||
memset (cfgimpl, 0, sizeof (*cfgimpl));
|
||||
cfgimpl->c.mask = mask;
|
||||
cfgimpl->c.mask = tracemask | DDS_LOG_MASK;
|
||||
cfgimpl->c.tracemask = tracemask;
|
||||
cfgimpl->c.domid = domid;
|
||||
cfgimpl->sink_fps[LOG] = log_fp;
|
||||
cfgimpl->sink_fps[TRACE] = trace_fp;
|
||||
|
@ -220,7 +202,7 @@ static size_t print_header (char *str, uint32_t id)
|
|||
return (size_t) cnt;
|
||||
}
|
||||
|
||||
static void vlog (const struct ddsrt_log_cfg_impl *cfg, uint32_t cat, uint32_t domid, const char *file, uint32_t line, const char *func, const char *fmt, va_list ap)
|
||||
static void vlog1 (const struct ddsrt_log_cfg_impl *cfg, uint32_t cat, uint32_t domid, const char *file, uint32_t line, const char *func, const char *fmt, va_list ap)
|
||||
{
|
||||
int n, trunc = 0;
|
||||
size_t nrem;
|
||||
|
@ -242,8 +224,8 @@ static void vlog (const struct ddsrt_log_cfg_impl *cfg, uint32_t cat, uint32_t d
|
|||
/* Thread-local buffer is always initialized with all zeroes. The pos
|
||||
member must always be greater or equal to BUF_OFFSET. */
|
||||
if (lb->pos < BUF_OFFSET) {
|
||||
lb->pos = BUF_OFFSET;
|
||||
lb->buf[lb->pos] = 0;
|
||||
lb->pos = BUF_OFFSET;
|
||||
lb->buf[lb->pos] = 0;
|
||||
}
|
||||
nrem = sizeof (lb->buf) - lb->pos;
|
||||
if (nrem > 0) {
|
||||
|
@ -263,7 +245,8 @@ static void vlog (const struct ddsrt_log_cfg_impl *cfg, uint32_t cat, uint32_t d
|
|||
}
|
||||
}
|
||||
|
||||
if (fmt[strlen (fmt) - 1] == '\n') {
|
||||
if (fmt[strlen (fmt) - 1] == '\n' && lb->pos > BUF_OFFSET + 1) {
|
||||
assert (lb->pos > BUF_OFFSET);
|
||||
size_t hdrsize = print_header (lb->buf, domid);
|
||||
|
||||
data.priority = cat;
|
||||
|
@ -271,32 +254,28 @@ static void vlog (const struct ddsrt_log_cfg_impl *cfg, uint32_t cat, uint32_t d
|
|||
data.function = func;
|
||||
data.line = line;
|
||||
data.message = lb->buf + BUF_OFFSET;
|
||||
data.size = strlen(data.message) - 1;
|
||||
data.size = lb->pos - BUF_OFFSET - 1;
|
||||
data.hdrsize = hdrsize;
|
||||
|
||||
dds_log_write_fn_t f = 0;
|
||||
void *f_arg = NULL;
|
||||
for (size_t i = (cat & DDS_LOG_MASK) ? LOG : TRACE;
|
||||
i < sizeof (sinks) / sizeof (sinks[0]);
|
||||
i++)
|
||||
if (cat & DDS_LOG_MASK)
|
||||
{
|
||||
if (sinks[i].funcs[USE] != default_sink) {
|
||||
if (sinks[i].funcs[USE] != f || sinks[i].ptr != f_arg) {
|
||||
assert (sinks[i].funcs[USE]);
|
||||
sinks[i].funcs[USE] (sinks[i].ptr, &data);
|
||||
f = sinks[i].funcs[USE]; f_arg = sinks[i].ptr;
|
||||
}
|
||||
} else if (cfg->sink_fps[i]) {
|
||||
if (default_sink != f || cfg->sink_fps[i] != f_arg) {
|
||||
default_sink (cfg->sink_fps[i], &data);
|
||||
f = default_sink; f_arg = cfg->sink_fps[i];
|
||||
}
|
||||
} else if (logconfig.sink_fps[i]) {
|
||||
if (default_sink != f || logconfig.sink_fps[i] != f_arg) {
|
||||
default_sink (logconfig.sink_fps[i], &data);
|
||||
f = default_sink; f_arg = logconfig.sink_fps[i];
|
||||
}
|
||||
}
|
||||
f = sinks[LOG].func;
|
||||
f_arg = (f == default_sink) ? cfg->sink_fps[LOG] : sinks[LOG].ptr;
|
||||
assert (f != 0);
|
||||
f (f_arg, &data);
|
||||
}
|
||||
/* if tracing is enabled, then print to trace if it matches the
|
||||
trace flags or if it got written to the log
|
||||
(mask == (tracemask | DDS_LOG_MASK)) */
|
||||
if (cfg->c.tracemask && (cat & cfg->c.mask))
|
||||
{
|
||||
dds_log_write_fn_t const g = sinks[TRACE].func;
|
||||
void * const g_arg = (g == default_sink) ? cfg->sink_fps[TRACE] : sinks[TRACE].ptr;
|
||||
assert (g != 0);
|
||||
if (g != f || g_arg != f_arg)
|
||||
g (g_arg, &data);
|
||||
}
|
||||
|
||||
lb->pos = BUF_OFFSET;
|
||||
|
@ -304,51 +283,45 @@ static void vlog (const struct ddsrt_log_cfg_impl *cfg, uint32_t cat, uint32_t d
|
|||
}
|
||||
}
|
||||
|
||||
int dds_log_cfg (const struct ddsrt_log_cfg *cfg, uint32_t cat, const char *file, uint32_t line, const char *func, const char *fmt, ...)
|
||||
static void vlog (const struct ddsrt_log_cfg_impl *cfg, uint32_t cat, uint32_t domid, const char *file, uint32_t line, const char *func, const char *fmt, va_list ap)
|
||||
{
|
||||
lock_sink (RDLOCK);
|
||||
vlog1 (cfg, cat, domid, file, line, func, fmt, ap);
|
||||
unlock_sink ();
|
||||
if (cat & DDS_LC_FATAL)
|
||||
abort();
|
||||
}
|
||||
|
||||
void dds_log_cfg (const struct ddsrt_log_cfg *cfg, uint32_t cat, const char *file, uint32_t line, const char *func, const char *fmt, ...)
|
||||
{
|
||||
const struct ddsrt_log_cfg_impl *cfgimpl = (const struct ddsrt_log_cfg_impl *) cfg;
|
||||
if ((cfgimpl->c.mask & cat) || (cat & DDS_LC_FATAL)) {
|
||||
/* cfgimpl->c.mask is too weak a test because it has all DDS_LOG_MASK bits set,
|
||||
rather than just the ones in dds_get_log_mask() (so as not to cache the latter
|
||||
and have to keep them synchronized */
|
||||
if ((cfgimpl->c.mask & cat) && ((dds_get_log_mask () | cfgimpl->c.tracemask) & cat)) {
|
||||
va_list ap;
|
||||
va_start (ap, fmt);
|
||||
lock_sink (RDLOCK);
|
||||
vlog (cfgimpl, cat, cfgimpl->c.domid, file, line, func, fmt, ap);
|
||||
unlock_sink ();
|
||||
va_end (ap);
|
||||
}
|
||||
if (cat & DDS_LC_FATAL) {
|
||||
abort();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dds_log_id (uint32_t cat, uint32_t id, const char *file, uint32_t line, const char *func, const char *fmt, ...)
|
||||
void dds_log_id (uint32_t cat, uint32_t id, const char *file, uint32_t line, const char *func, const char *fmt, ...)
|
||||
{
|
||||
if ((dds_get_log_mask () & cat) || (cat & DDS_LC_FATAL)) {
|
||||
if (dds_get_log_mask () & cat) {
|
||||
va_list ap;
|
||||
va_start (ap, fmt);
|
||||
lock_sink (RDLOCK);
|
||||
vlog (&logconfig, cat, id, file, line, func, fmt, ap);
|
||||
unlock_sink ();
|
||||
va_end (ap);
|
||||
}
|
||||
if (cat & DDS_LC_FATAL) {
|
||||
abort ();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dds_log (uint32_t cat, const char *file, uint32_t line, const char *func, const char *fmt, ...)
|
||||
void dds_log (uint32_t cat, const char *file, uint32_t line, const char *func, const char *fmt, ...)
|
||||
{
|
||||
if ((dds_get_log_mask () & cat) || (cat & DDS_LC_FATAL)) {
|
||||
if (dds_get_log_mask () & cat) {
|
||||
va_list ap;
|
||||
va_start (ap, fmt);
|
||||
lock_sink (RDLOCK);
|
||||
vlog (&logconfig, cat, UINT32_MAX, file, line, func, fmt, ap);
|
||||
unlock_sink ();
|
||||
va_end (ap);
|
||||
}
|
||||
if (cat & DDS_LC_FATAL) {
|
||||
abort ();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -54,36 +54,40 @@ struct ddsrt_xmlp_state {
|
|||
struct ddsrt_xmlp_callbacks cb; /* user-supplied callbacks (or stubs) */
|
||||
};
|
||||
|
||||
static int cb_null_elem_open (void *varg, uintptr_t parentinfo, uintptr_t *eleminfo, const char *name)
|
||||
static int cb_null_elem_open (void *varg, uintptr_t parentinfo, uintptr_t *eleminfo, const char *name, int line)
|
||||
{
|
||||
DDSRT_UNUSED_ARG (varg);
|
||||
DDSRT_UNUSED_ARG (parentinfo);
|
||||
DDSRT_UNUSED_ARG (eleminfo);
|
||||
DDSRT_UNUSED_ARG (name);
|
||||
DDSRT_UNUSED_ARG (line);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cb_null_attr (void *varg, uintptr_t eleminfo, const char *name, const char *value)
|
||||
static int cb_null_attr (void *varg, uintptr_t eleminfo, const char *name, const char *value, int line)
|
||||
{
|
||||
DDSRT_UNUSED_ARG (varg);
|
||||
DDSRT_UNUSED_ARG (eleminfo);
|
||||
DDSRT_UNUSED_ARG (name);
|
||||
DDSRT_UNUSED_ARG (value);
|
||||
DDSRT_UNUSED_ARG (line);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cb_null_elem_data (void *varg, uintptr_t eleminfo, const char *data)
|
||||
static int cb_null_elem_data (void *varg, uintptr_t eleminfo, const char *data, int line)
|
||||
{
|
||||
DDSRT_UNUSED_ARG (varg);
|
||||
DDSRT_UNUSED_ARG (eleminfo);
|
||||
DDSRT_UNUSED_ARG (data);
|
||||
DDSRT_UNUSED_ARG (line);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cb_null_elem_close (void *varg, uintptr_t eleminfo)
|
||||
static int cb_null_elem_close (void *varg, uintptr_t eleminfo, int line)
|
||||
{
|
||||
DDSRT_UNUSED_ARG (varg);
|
||||
DDSRT_UNUSED_ARG (eleminfo);
|
||||
DDSRT_UNUSED_ARG (line);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -606,7 +610,7 @@ static int parse_element (struct ddsrt_xmlp_state *st, uintptr_t parentinfo)
|
|||
PE_LOCAL_ERROR ("expecting '<'", 0);
|
||||
}
|
||||
|
||||
if ((ret = st->cb.elem_open (st->varg, parentinfo, &eleminfo, name)) < 0) {
|
||||
if ((ret = st->cb.elem_open (st->varg, parentinfo, &eleminfo, name, st->line)) < 0) {
|
||||
PE_ERROR ("failed in element open callback", name);
|
||||
}
|
||||
|
||||
|
@ -620,7 +624,7 @@ static int parse_element (struct ddsrt_xmlp_state *st, uintptr_t parentinfo)
|
|||
ddsrt_free (content);
|
||||
PE_LOCAL_ERROR ("expecting string value for attribute", aname);
|
||||
}
|
||||
ret = st->cb.attr (st->varg, eleminfo, aname, content);
|
||||
ret = st->cb.attr (st->varg, eleminfo, aname, content, st->line);
|
||||
ddsrt_free (content);
|
||||
if (ret < 0) {
|
||||
PE_ERROR2 ("failed in attribute callback", name, aname);
|
||||
|
@ -633,7 +637,7 @@ static int parse_element (struct ddsrt_xmlp_state *st, uintptr_t parentinfo)
|
|||
switch (tok)
|
||||
{
|
||||
case TOK_SHORTHAND_CLOSE_TAG:
|
||||
ret = st->cb.elem_close (st->varg, eleminfo);
|
||||
ret = st->cb.elem_close (st->varg, eleminfo, st->line);
|
||||
goto ok;
|
||||
case '>':
|
||||
st->nest++;
|
||||
|
@ -679,7 +683,7 @@ static int parse_element (struct ddsrt_xmlp_state *st, uintptr_t parentinfo)
|
|||
PE_ERROR ("invalid character sequence", 0);
|
||||
} else if (content != NULL) {
|
||||
if (*content != '\0') {
|
||||
ret = st->cb.elem_data (st->varg, eleminfo, content);
|
||||
ret = st->cb.elem_data (st->varg, eleminfo, content, st->line);
|
||||
ddsrt_free (content);
|
||||
if (ret < 0) {
|
||||
PE_ERROR ("failed in data callback", 0);
|
||||
|
@ -706,7 +710,7 @@ static int parse_element (struct ddsrt_xmlp_state *st, uintptr_t parentinfo)
|
|||
if (have_input_marker (st)) {
|
||||
discard_input_marker (st);
|
||||
}
|
||||
ret = st->cb.elem_close (st->varg, eleminfo);
|
||||
ret = st->cb.elem_close (st->varg, eleminfo, st->line);
|
||||
goto ok;
|
||||
default:
|
||||
PE_LOCAL_ERROR ("expecting '/>' or '>'", 0);
|
||||
|
@ -742,7 +746,3 @@ int ddsrt_xmlp_parse (struct ddsrt_xmlp_state *st)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
int ddsrt_xmlUnescapeInsitu (char *buffer, size_t *n) {
|
||||
return unescape_insitu (buffer, n);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue