24#include "gdbsupport/filestuff.h"
25#include "gdbsupport/gdb-safe-ctype.h"
40#define MAX_XINCLUDE_DEPTH 30
49 : elements (elements_),
71 gdb_xml_parser (
const char *
name,
78 void use_dtd (
const char *dtd_name);
81 const char *dtd_name ()
82 {
return m_dtd_name; }
90 int parse (
const char *buffer);
93 void vdebug (
const char *format, va_list ap)
97 void verror (
const char *format, va_list ap)
100 void body_text (
const XML_Char *text,
int length);
101 void start_element (
const XML_Char *
name,
const XML_Char **attrs);
102 void end_element (
const XML_Char *
name);
110 {
return m_user_data; };
113 void set_is_xinclude (
bool is_xinclude)
114 { m_is_xinclude = is_xinclude; }
117 void set_error (gdb_exception &&error)
119 m_error = std::move (error);
120#ifdef HAVE_XML_STOPPARSER
121 XML_StopParser (m_expat_parser, XML_FALSE);
126 XML_Parser expat_parser ()
127 {
return m_expat_parser; }
131 XML_Parser m_expat_parser;
140 std::vector<scope_level> m_scopes;
143 struct gdb_exception m_error;
149 const char *m_dtd_name;
160gdb_xml_parser::body_text (
const XML_Char *text,
int length)
162 if (m_error.reason < 0)
165 scope_level &scope = m_scopes.back ();
166 scope.body.append (text, length);
170gdb_xml_body_text (
void *data,
const XML_Char *text,
int length)
172 struct gdb_xml_parser *parser = (
struct gdb_xml_parser *) data;
174 parser->body_text (text, length);
180gdb_xml_parser::vdebug (
const char *format, va_list ap)
182 int line = XML_GetCurrentLineNumber (m_expat_parser);
184 std::string message = string_vprintf (format, ap);
187 m_name, line, message.c_str ());
190 m_name, message.c_str ());
194gdb_xml_debug (
struct gdb_xml_parser *parser,
const char *format, ...)
200 va_start (ap, format);
201 parser->vdebug (format, ap);
209gdb_xml_parser::verror (
const char *format, va_list ap)
211 int line = XML_GetCurrentLineNumber (m_expat_parser);
214 throw_verror (XML_PARSE_ERROR, format, ap);
218gdb_xml_error (
struct gdb_xml_parser *parser,
const char *format, ...)
221 va_start (ap, format);
222 parser->verror (format, ap);
244gdb_xml_parser::start_element (
const XML_Char *
name,
245 const XML_Char **attrs)
247 if (m_error.reason < 0)
262 m_scopes.emplace_back ();
265 scope_level &scope = m_scopes[m_scopes.size () - 2];
273 for (element = scope.elements; element && element->
name;
274 element++, seen <<= 1)
275 if (strcmp (element->
name,
name) == 0)
278 if (element == NULL || element->
name == NULL)
285 XML_DefaultCurrent (m_expat_parser);
287 scope_level &unknown_scope = m_scopes.back ();
288 unknown_scope.elements = scope.elements;
307 const char *val = NULL;
311 for (p = attrs; *p != NULL; p += 2)
318 if (*p != NULL && val == NULL)
328 "<%s> not specified"),
342 parsed_value = xstrdup (val);
352 for (p = attrs; *p != NULL; p += 2)
361 gdb_xml_debug (
this, _(
"Ignoring unknown attribute %s"), *p);
373 scope_level &new_scope = m_scopes.back ();
374 new_scope.element = element;
375 new_scope.elements = element->
children;
382gdb_xml_start_element_wrapper (
void *data,
const XML_Char *
name,
383 const XML_Char **attrs)
385 struct gdb_xml_parser *parser = (
struct gdb_xml_parser *) data;
389 parser->start_element (
name, attrs);
391 catch (gdb_exception &ex)
393 parser->set_error (std::move (ex));
400gdb_xml_parser::end_element (
const XML_Char *
name)
402 if (m_error.reason < 0)
405 struct scope_level *scope = &m_scopes.back ();
411 for (element = scope->elements, seen = 1;
412 element != NULL && element->
name != NULL;
413 element++, seen <<= 1)
414 if ((scope->seen & seen) == 0
420 if (scope->element != NULL && scope->element->end_handler)
424 if (scope->body.empty ())
430 length = scope->body.size ();
431 body = scope->body.c_str ();
434 while (length > 0 && ISSPACE (body[length - 1]))
436 scope->body.erase (length);
437 while (*body && ISSPACE (*body))
441 scope->element->end_handler (
this, scope->element,
444 else if (scope->element == NULL)
445 XML_DefaultCurrent (m_expat_parser);
448 m_scopes.pop_back ();
455gdb_xml_end_element_wrapper (
void *data,
const XML_Char *
name)
457 struct gdb_xml_parser *parser = (
struct gdb_xml_parser *) data;
461 parser->end_element (
name);
463 catch (gdb_exception &ex)
465 parser->set_error (std::move (ex));
471gdb_xml_parser::~gdb_xml_parser ()
473 XML_ParserFree (m_expat_parser);
478gdb_xml_parser::gdb_xml_parser (
const char *
name,
482 m_user_data (user_data),
485 m_is_xinclude (false)
487 m_expat_parser = XML_ParserCreateNS (NULL,
'!');
488 if (m_expat_parser == NULL)
491 XML_SetUserData (m_expat_parser,
this);
494 XML_SetElementHandler (m_expat_parser, gdb_xml_start_element_wrapper,
495 gdb_xml_end_element_wrapper);
496 XML_SetCharacterDataHandler (m_expat_parser, gdb_xml_body_text);
499 m_scopes.emplace_back (elements);
507gdb_xml_fetch_external_entity (XML_Parser expat_parser,
508 const XML_Char *context,
509 const XML_Char *base,
510 const XML_Char *systemId,
511 const XML_Char *publicId)
513 XML_Parser entity_parser;
517 if (systemId == NULL)
519 gdb_xml_parser *parser
520 = (gdb_xml_parser *) XML_GetUserData (expat_parser);
524 internal_error (_(
"could not locate built-in DTD %s"),
525 parser->dtd_name ());
534 entity_parser = XML_ExternalEntityParserCreate (expat_parser,
539 XML_SetElementHandler (entity_parser, NULL, NULL);
540 XML_SetDoctypeDeclHandler (entity_parser, NULL, NULL);
541 XML_SetXmlDeclHandler (entity_parser, NULL);
542 XML_SetDefaultHandler (entity_parser, NULL);
543 XML_SetUserData (entity_parser, NULL);
545 status = XML_Parse (entity_parser, text, strlen (text), 1);
547 XML_ParserFree (entity_parser);
552gdb_xml_parser::use_dtd (
const char *dtd_name)
556 m_dtd_name = dtd_name;
558 XML_SetParamEntityParsing (m_expat_parser,
559 XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE);
560 XML_SetExternalEntityRefHandler (m_expat_parser,
561 gdb_xml_fetch_external_entity);
564 err = XML_UseForeignDTD (m_expat_parser, XML_TRUE);
565 if (
err != XML_ERROR_NONE)
566 internal_error (_(
"XML_UseForeignDTD failed: %s"),
567 XML_ErrorString (
err));
578gdb_xml_parser::parse (
const char *buffer)
581 const char *error_string;
585 status = XML_Parse (m_expat_parser, buffer, strlen (buffer), 1);
590 if (m_error.reason == RETURN_ERROR
591 && m_error.error == XML_PARSE_ERROR)
593 gdb_assert (m_error.message != NULL);
594 error_string = m_error.what ();
598 enum XML_Error
err = XML_GetErrorCode (m_expat_parser);
600 error_string = XML_ErrorString (
err);
604 gdb_assert (m_error.reason < 0);
605 throw_exception (std::move (m_error));
608 if (m_last_line != 0)
609 warning (_(
"while parsing %s (at line %d): %s"), m_name,
610 m_last_line, error_string);
612 warning (_(
"while parsing %s: %s"), m_name, error_string);
620 const char *document,
void *user_data)
622 gdb_xml_parser parser (
name, elements, user_data);
623 if (dtd_name != NULL)
624 parser.use_dtd (dtd_name);
625 return parser.parse (document);
635xml_parse_unsigned_integer (
const char *valstr, ULONGEST *valp)
643 result = strtoulst (valstr, &endptr, 0);
659 if (xml_parse_unsigned_integer (
value, &result) != 0)
675 if (xml_parse_unsigned_integer (
value, &result) != 0)
676 gdb_xml_error (parser, _(
"Can't convert %s=\"%s\" to an integer"),
679 ret = XNEW (ULONGEST);
680 memcpy (ret, &result,
sizeof (result));
707 enums->name != NULL; enums++)
708 if (strcasecmp (enums->name,
value) == 0)
711 if (enums->name == NULL)
712 gdb_xml_error (parser, _(
"Unknown attribute value %s=\"%s\""),
715 ret =
xmalloc (
sizeof (enums->value));
716 memcpy (ret, &enums->value, sizeof (enums->value));
743struct xinclude_parsing_data
745 xinclude_parsing_data (std::string &output_,
750 include_depth (include_depth_),
773xinclude_start_include (
struct gdb_xml_parser *parser,
778 struct xinclude_parsing_data *
data
779 = (
struct xinclude_parsing_data *) user_data;
782 gdb_xml_debug (parser, _(
"Processing XInclude of \"%s\""), href);
784 if (
data->include_depth > MAX_XINCLUDE_DEPTH)
785 gdb_xml_error (parser, _(
"Maximum XInclude depth (%d) exceeded"),
788 gdb::optional<gdb::char_vector> text =
data->fetcher (href);
790 gdb_xml_error (parser, _(
"Could not load XML document \"%s\""), href);
793 text->data (),
data->fetcher,
794 data->include_depth + 1))
801xinclude_end_include (
struct gdb_xml_parser *parser,
803 void *user_data,
const char *body_text)
805 struct xinclude_parsing_data *
data
806 = (
struct xinclude_parsing_data *) user_data;
812xml_xinclude_default (
void *data_,
const XML_Char *s,
int len)
814 struct gdb_xml_parser *parser = (
struct gdb_xml_parser *) data_;
815 xinclude_parsing_data *
data = (xinclude_parsing_data *) parser->user_data ();
819 if (
data->skip_depth)
824 data->output.append (s, len);
828xml_xinclude_start_doctype (
void *data_,
const XML_Char *doctypeName,
829 const XML_Char *sysid,
const XML_Char *pubid,
830 int has_internal_subset)
832 struct gdb_xml_parser *parser = (
struct gdb_xml_parser *) data_;
833 xinclude_parsing_data *
data = (xinclude_parsing_data *) parser->user_data ();
841xml_xinclude_end_doctype (
void *data_)
843 struct gdb_xml_parser *parser = (
struct gdb_xml_parser *) data_;
844 xinclude_parsing_data *
data = (xinclude_parsing_data *) parser->user_data ();
850xml_xinclude_xml_decl (
void *data_,
const XML_Char *
version,
851 const XML_Char *encoding,
int standalone)
864 {
"http://www.w3.org/2001/XInclude!include", xinclude_attributes, NULL,
866 xinclude_start_include, xinclude_end_include },
874 const char *
name,
const char *text,
877 xinclude_parsing_data
data (result, fetcher, depth);
879 gdb_xml_parser parser (
name, xinclude_elements, &data);
880 parser.set_is_xinclude (
true);
882 XML_SetCharacterDataHandler (parser.expat_parser (), NULL);
883 XML_SetDefaultHandler (parser.expat_parser (), xml_xinclude_default);
888 XML_SetXmlDeclHandler (parser.expat_parser (), xml_xinclude_xml_decl);
892 XML_SetDoctypeDeclHandler (parser.expat_parser (),
893 xml_xinclude_start_doctype,
894 xml_xinclude_end_doctype);
896 parser.use_dtd (
"xinclude.dtd");
898 if (parser.parse (text) == 0)
901 gdb_xml_debug (&parser, _(
"XInclude processing succeeded."));
916 const char *
const (*p)[2];
919 if (strcmp ((*p)[0], filename) == 0)
932 gdb_byte *readbuf,
const gdb_byte *writebuf,
933 ULONGEST offset, LONGEST len)
938 gdb_assert (readbuf != NULL && writebuf == NULL);
939 gdb_assert (filename != NULL);
945 len_avail = strlen (buf);
946 if (offset >= len_avail)
949 if (len > len_avail - offset)
950 len = len_avail - offset;
951 memcpy (readbuf, buf + offset, len);
963gdb::optional<gdb::char_vector>
968 if (dirname !=
nullptr && *dirname !=
'\0')
970 gdb::unique_xmalloc_ptr<char> fullname
971 (concat (dirname,
"/", filename, (
char *) NULL));
973 file = gdb_fopen_cloexec (fullname.get (), FOPEN_RB);
976 file = gdb_fopen_cloexec (filename, FOPEN_RB);
985 if (fseek (file.get (), 0, SEEK_END) == -1)
986 perror_with_name (_(
"seek to end of file"));
987 len = ftell (file.get ());
988 rewind (file.get ());
990 gdb::char_vector text (len + 1);
992 if (fread (text.data (), 1, len, file.get ()) != len
993 || ferror (file.get ()))
995 warning (_(
"Read error from \"%s\""), filename);
1009 _(
"Set XML parser debugging."),
1010 _(
"Show XML parser debugging."),
1011 _(
"When set, debugging messages for XML parsers "
static struct @5 attributes[]
struct cmd_list_element * showdebuglist
struct cmd_list_element * setdebuglist
set_show_commands add_setshow_boolean_cmd(const char *name, enum command_class theclass, bool *var, const char *set_doc, const char *show_doc, const char *help_doc, cmd_func_ftype *set_func, show_value_ftype *show_func, struct cmd_list_element **set_list, struct cmd_list_element **show_list)
static void ATTRIBUTE_PRINTF(1, 0)
mach_port_t mach_port_t name mach_port_t mach_port_t name kern_return_t err
mach_port_t mach_port_t name mach_port_t mach_port_t name kern_return_t int status
__extension__ enum dwarf_attribute name
const struct gdb_xml_attribute * attributes
gdb_xml_element_start_handler * start_handler
const struct gdb_xml_element * children
gdb::unique_xmalloc_ptr< void > value
void malloc_failure(long size)
void verror(const char *string, va_list args)
void gdb_printf(struct ui_file *stream, const char *format,...)
const char *const xml_builtin[][2]
const char * fetch_xml_builtin(const char *filename)
void _initialize_xml_support()
gdb::optional< gdb::char_vector > xml_fetch_content_from_file(const char *filename, const char *dirname)
static void show_debug_xml(struct ui_file *file, int from_tty, struct cmd_list_element *c, const char *value)
LONGEST xml_builtin_xfer_partial(const char *filename, gdb_byte *readbuf, const gdb_byte *writebuf, ULONGEST offset, LONGEST len)
void void gdb_xml_error(struct gdb_xml_parser *parser, const char *format,...) ATTRIBUTE_NORETURN ATTRIBUTE_PRINTF(2
void void struct gdb_xml_value * xml_find_attribute(std::vector< gdb_xml_value > &attributes, const char *name)
int gdb_xml_parse_quick(const char *name, const char *dtd_name, const struct gdb_xml_element *elements, const char *document, void *user_data)
const struct gdb_xml_enum gdb_xml_enums_boolean[]
gdb_xml_attribute_handler gdb_xml_parse_attr_ulongest
gdb::function_view< gdb::optional< gdb::char_vector >(const char *)> xml_fetch_another
void gdb_xml_debug(struct gdb_xml_parser *parser, const char *format,...) ATTRIBUTE_PRINTF(2
ULONGEST gdb_xml_parse_ulongest(struct gdb_xml_parser *parser, const char *value)
gdb_xml_attribute_handler gdb_xml_parse_attr_enum
bool xml_process_xincludes(std::string &result, const char *name, const char *text, xml_fetch_another fetcher, int depth)