1 /* Helper routines for parsing XML using Expat. 2 3 Copyright (C) 2006-2013 Free Software Foundation, Inc. 4 5 This file is part of GDB. 6 7 This program is free software; you can redistribute it and/or modify 8 it under the terms of the GNU General Public License as published by 9 the Free Software Foundation; either version 3 of the License, or 10 (at your option) any later version. 11 12 This program is distributed in the hope that it will be useful, 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 GNU General Public License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 19 20 #include "defs.h" 21 #include "gdbcmd.h" 22 #include "exceptions.h" 23 #include "xml-support.h" 24 25 #include "gdb_string.h" 26 #include "safe-ctype.h" 27 28 /* Debugging flag. */ 29 static int debug_xml; 30 31 /* The contents of this file are only useful if XML support is 32 available. */ 33 #ifdef HAVE_LIBEXPAT 34 35 #include "gdb_expat.h" 36 37 /* The maximum depth of <xi:include> nesting. No need to be miserly, 38 we just want to avoid running out of stack on loops. */ 39 #define MAX_XINCLUDE_DEPTH 30 40 41 /* Simplified XML parser infrastructure. */ 42 43 /* A parsing level -- used to keep track of the current element 44 nesting. */ 45 struct scope_level 46 { 47 /* Elements we allow at this level. */ 48 const struct gdb_xml_element *elements; 49 50 /* The element which we are within. */ 51 const struct gdb_xml_element *element; 52 53 /* Mask of which elements we've seen at this level (used for 54 optional and repeatable checking). */ 55 unsigned int seen; 56 57 /* Body text accumulation. */ 58 struct obstack *body; 59 }; 60 typedef struct scope_level scope_level_s; 61 DEF_VEC_O(scope_level_s); 62 63 /* The parser itself, and our additional state. */ 64 struct gdb_xml_parser 65 { 66 XML_Parser expat_parser; /* The underlying expat parser. */ 67 68 const char *name; /* Name of this parser. */ 69 void *user_data; /* The user's callback data, for handlers. */ 70 71 VEC(scope_level_s) *scopes; /* Scoping stack. */ 72 73 struct gdb_exception error; /* A thrown error, if any. */ 74 int last_line; /* The line of the thrown error, or 0. */ 75 76 const char *dtd_name; /* The name of the expected / default DTD, 77 if specified. */ 78 int is_xinclude; /* Are we the special <xi:include> parser? */ 79 }; 80 81 /* Process some body text. We accumulate the text for later use; it's 82 wrong to do anything with it immediately, because a single block of 83 text might be broken up into multiple calls to this function. */ 84 85 static void 86 gdb_xml_body_text (void *data, const XML_Char *text, int length) 87 { 88 struct gdb_xml_parser *parser = data; 89 struct scope_level *scope = VEC_last (scope_level_s, parser->scopes); 90 91 if (parser->error.reason < 0) 92 return; 93 94 if (scope->body == NULL) 95 { 96 scope->body = XZALLOC (struct obstack); 97 obstack_init (scope->body); 98 } 99 100 obstack_grow (scope->body, text, length); 101 } 102 103 /* Issue a debugging message from one of PARSER's handlers. */ 104 105 void 106 gdb_xml_debug (struct gdb_xml_parser *parser, const char *format, ...) 107 { 108 int line = XML_GetCurrentLineNumber (parser->expat_parser); 109 va_list ap; 110 char *message; 111 112 if (!debug_xml) 113 return; 114 115 va_start (ap, format); 116 message = xstrvprintf (format, ap); 117 if (line) 118 fprintf_unfiltered (gdb_stderr, "%s (line %d): %s\n", 119 parser->name, line, message); 120 else 121 fprintf_unfiltered (gdb_stderr, "%s: %s\n", 122 parser->name, message); 123 xfree (message); 124 } 125 126 /* Issue an error message from one of PARSER's handlers, and stop 127 parsing. */ 128 129 void 130 gdb_xml_error (struct gdb_xml_parser *parser, const char *format, ...) 131 { 132 int line = XML_GetCurrentLineNumber (parser->expat_parser); 133 va_list ap; 134 135 parser->last_line = line; 136 va_start (ap, format); 137 throw_verror (XML_PARSE_ERROR, format, ap); 138 } 139 140 /* Find the attribute named NAME in the set of parsed attributes 141 ATTRIBUTES. Returns NULL if not found. */ 142 143 struct gdb_xml_value * 144 xml_find_attribute (VEC(gdb_xml_value_s) *attributes, const char *name) 145 { 146 struct gdb_xml_value *value; 147 int ix; 148 149 for (ix = 0; VEC_iterate (gdb_xml_value_s, attributes, ix, value); ix++) 150 if (strcmp (value->name, name) == 0) 151 return value; 152 153 return NULL; 154 } 155 156 /* Clean up a vector of parsed attribute values. */ 157 158 static void 159 gdb_xml_values_cleanup (void *data) 160 { 161 VEC(gdb_xml_value_s) **values = data; 162 struct gdb_xml_value *value; 163 int ix; 164 165 for (ix = 0; VEC_iterate (gdb_xml_value_s, *values, ix, value); ix++) 166 xfree (value->value); 167 VEC_free (gdb_xml_value_s, *values); 168 } 169 170 /* Handle the start of an element. DATA is our local XML parser, NAME 171 is the element, and ATTRS are the names and values of this 172 element's attributes. */ 173 174 static void 175 gdb_xml_start_element (void *data, const XML_Char *name, 176 const XML_Char **attrs) 177 { 178 struct gdb_xml_parser *parser = data; 179 struct scope_level *scope; 180 struct scope_level new_scope; 181 const struct gdb_xml_element *element; 182 const struct gdb_xml_attribute *attribute; 183 VEC(gdb_xml_value_s) *attributes = NULL; 184 unsigned int seen; 185 struct cleanup *back_to; 186 187 /* Push an error scope. If we return or throw an exception before 188 filling this in, it will tell us to ignore children of this 189 element. */ 190 VEC_reserve (scope_level_s, parser->scopes, 1); 191 scope = VEC_last (scope_level_s, parser->scopes); 192 memset (&new_scope, 0, sizeof (new_scope)); 193 VEC_quick_push (scope_level_s, parser->scopes, &new_scope); 194 195 gdb_xml_debug (parser, _("Entering element <%s>"), name); 196 197 /* Find this element in the list of the current scope's allowed 198 children. Record that we've seen it. */ 199 200 seen = 1; 201 for (element = scope->elements; element && element->name; 202 element++, seen <<= 1) 203 if (strcmp (element->name, name) == 0) 204 break; 205 206 if (element == NULL || element->name == NULL) 207 { 208 /* If we're working on XInclude, <xi:include> can be the child 209 of absolutely anything. Copy the previous scope's element 210 list into the new scope even if there was no match. */ 211 if (parser->is_xinclude) 212 { 213 struct scope_level *unknown_scope; 214 215 XML_DefaultCurrent (parser->expat_parser); 216 217 unknown_scope = VEC_last (scope_level_s, parser->scopes); 218 unknown_scope->elements = scope->elements; 219 return; 220 } 221 222 gdb_xml_debug (parser, _("Element <%s> unknown"), name); 223 return; 224 } 225 226 if (!(element->flags & GDB_XML_EF_REPEATABLE) && (seen & scope->seen)) 227 gdb_xml_error (parser, _("Element <%s> only expected once"), name); 228 229 scope->seen |= seen; 230 231 back_to = make_cleanup (gdb_xml_values_cleanup, &attributes); 232 233 for (attribute = element->attributes; 234 attribute != NULL && attribute->name != NULL; 235 attribute++) 236 { 237 const char *val = NULL; 238 const XML_Char **p; 239 void *parsed_value; 240 struct gdb_xml_value new_value; 241 242 for (p = attrs; *p != NULL; p += 2) 243 if (!strcmp (attribute->name, p[0])) 244 { 245 val = p[1]; 246 break; 247 } 248 249 if (*p != NULL && val == NULL) 250 { 251 gdb_xml_debug (parser, _("Attribute \"%s\" missing a value"), 252 attribute->name); 253 continue; 254 } 255 256 if (*p == NULL && !(attribute->flags & GDB_XML_AF_OPTIONAL)) 257 { 258 gdb_xml_error (parser, _("Required attribute \"%s\" of " 259 "<%s> not specified"), 260 attribute->name, element->name); 261 continue; 262 } 263 264 if (*p == NULL) 265 continue; 266 267 gdb_xml_debug (parser, _("Parsing attribute %s=\"%s\""), 268 attribute->name, val); 269 270 if (attribute->handler) 271 parsed_value = attribute->handler (parser, attribute, val); 272 else 273 parsed_value = xstrdup (val); 274 275 new_value.name = attribute->name; 276 new_value.value = parsed_value; 277 VEC_safe_push (gdb_xml_value_s, attributes, &new_value); 278 } 279 280 /* Check for unrecognized attributes. */ 281 if (debug_xml) 282 { 283 const XML_Char **p; 284 285 for (p = attrs; *p != NULL; p += 2) 286 { 287 for (attribute = element->attributes; 288 attribute != NULL && attribute->name != NULL; 289 attribute++) 290 if (strcmp (attribute->name, *p) == 0) 291 break; 292 293 if (attribute == NULL || attribute->name == NULL) 294 gdb_xml_debug (parser, _("Ignoring unknown attribute %s"), *p); 295 } 296 } 297 298 /* Call the element handler if there is one. */ 299 if (element->start_handler) 300 element->start_handler (parser, element, parser->user_data, attributes); 301 302 /* Fill in a new scope level. */ 303 scope = VEC_last (scope_level_s, parser->scopes); 304 scope->element = element; 305 scope->elements = element->children; 306 307 do_cleanups (back_to); 308 } 309 310 /* Wrapper for gdb_xml_start_element, to prevent throwing exceptions 311 through expat. */ 312 313 static void 314 gdb_xml_start_element_wrapper (void *data, const XML_Char *name, 315 const XML_Char **attrs) 316 { 317 struct gdb_xml_parser *parser = data; 318 volatile struct gdb_exception ex; 319 320 if (parser->error.reason < 0) 321 return; 322 323 TRY_CATCH (ex, RETURN_MASK_ALL) 324 { 325 gdb_xml_start_element (data, name, attrs); 326 } 327 if (ex.reason < 0) 328 { 329 parser->error = ex; 330 #ifdef HAVE_XML_STOPPARSER 331 XML_StopParser (parser->expat_parser, XML_FALSE); 332 #endif 333 } 334 } 335 336 /* Handle the end of an element. DATA is our local XML parser, and 337 NAME is the current element. */ 338 339 static void 340 gdb_xml_end_element (void *data, const XML_Char *name) 341 { 342 struct gdb_xml_parser *parser = data; 343 struct scope_level *scope = VEC_last (scope_level_s, parser->scopes); 344 const struct gdb_xml_element *element; 345 unsigned int seen; 346 347 gdb_xml_debug (parser, _("Leaving element <%s>"), name); 348 349 for (element = scope->elements, seen = 1; 350 element != NULL && element->name != NULL; 351 element++, seen <<= 1) 352 if ((scope->seen & seen) == 0 353 && (element->flags & GDB_XML_EF_OPTIONAL) == 0) 354 gdb_xml_error (parser, _("Required element <%s> is missing"), 355 element->name); 356 357 /* Call the element processor. */ 358 if (scope->element != NULL && scope->element->end_handler) 359 { 360 char *body; 361 362 if (scope->body == NULL) 363 body = ""; 364 else 365 { 366 int length; 367 368 length = obstack_object_size (scope->body); 369 obstack_1grow (scope->body, '\0'); 370 body = obstack_finish (scope->body); 371 372 /* Strip leading and trailing whitespace. */ 373 while (length > 0 && ISSPACE (body[length-1])) 374 body[--length] = '\0'; 375 while (*body && ISSPACE (*body)) 376 body++; 377 } 378 379 scope->element->end_handler (parser, scope->element, parser->user_data, 380 body); 381 } 382 else if (scope->element == NULL) 383 XML_DefaultCurrent (parser->expat_parser); 384 385 /* Pop the scope level. */ 386 if (scope->body) 387 { 388 obstack_free (scope->body, NULL); 389 xfree (scope->body); 390 } 391 VEC_pop (scope_level_s, parser->scopes); 392 } 393 394 /* Wrapper for gdb_xml_end_element, to prevent throwing exceptions 395 through expat. */ 396 397 static void 398 gdb_xml_end_element_wrapper (void *data, const XML_Char *name) 399 { 400 struct gdb_xml_parser *parser = data; 401 volatile struct gdb_exception ex; 402 403 if (parser->error.reason < 0) 404 return; 405 406 TRY_CATCH (ex, RETURN_MASK_ALL) 407 { 408 gdb_xml_end_element (data, name); 409 } 410 if (ex.reason < 0) 411 { 412 parser->error = ex; 413 #ifdef HAVE_XML_STOPPARSER 414 XML_StopParser (parser->expat_parser, XML_FALSE); 415 #endif 416 } 417 } 418 419 /* Free a parser and all its associated state. */ 420 421 static void 422 gdb_xml_cleanup (void *arg) 423 { 424 struct gdb_xml_parser *parser = arg; 425 struct scope_level *scope; 426 int ix; 427 428 XML_ParserFree (parser->expat_parser); 429 430 /* Clean up the scopes. */ 431 for (ix = 0; VEC_iterate (scope_level_s, parser->scopes, ix, scope); ix++) 432 if (scope->body) 433 { 434 obstack_free (scope->body, NULL); 435 xfree (scope->body); 436 } 437 VEC_free (scope_level_s, parser->scopes); 438 439 xfree (parser); 440 } 441 442 /* Initialize and return a parser. Register a cleanup to destroy the 443 parser. */ 444 445 static struct gdb_xml_parser * 446 gdb_xml_create_parser_and_cleanup_1 (const char *name, 447 const struct gdb_xml_element *elements, 448 void *user_data, struct cleanup **old_chain) 449 { 450 struct gdb_xml_parser *parser; 451 struct scope_level start_scope; 452 struct cleanup *dummy; 453 454 /* Initialize the parser. */ 455 parser = XZALLOC (struct gdb_xml_parser); 456 parser->expat_parser = XML_ParserCreateNS (NULL, '!'); 457 if (parser->expat_parser == NULL) 458 { 459 xfree (parser); 460 malloc_failure (0); 461 } 462 463 parser->name = name; 464 465 parser->user_data = user_data; 466 XML_SetUserData (parser->expat_parser, parser); 467 468 /* Set the callbacks. */ 469 XML_SetElementHandler (parser->expat_parser, gdb_xml_start_element_wrapper, 470 gdb_xml_end_element_wrapper); 471 XML_SetCharacterDataHandler (parser->expat_parser, gdb_xml_body_text); 472 473 /* Initialize the outer scope. */ 474 memset (&start_scope, 0, sizeof (start_scope)); 475 start_scope.elements = elements; 476 VEC_safe_push (scope_level_s, parser->scopes, &start_scope); 477 478 if (old_chain == NULL) 479 old_chain = &dummy; 480 481 *old_chain = make_cleanup (gdb_xml_cleanup, parser); 482 return parser; 483 } 484 485 /* Initialize and return a parser. Register a cleanup to destroy the 486 parser. */ 487 488 struct gdb_xml_parser * 489 gdb_xml_create_parser_and_cleanup (const char *name, 490 const struct gdb_xml_element *elements, 491 void *user_data) 492 { 493 struct cleanup *old_chain; 494 495 return gdb_xml_create_parser_and_cleanup_1 (name, elements, user_data, 496 &old_chain); 497 } 498 499 /* External entity handler. The only external entities we support 500 are those compiled into GDB (we do not fetch entities from the 501 target). */ 502 503 static int XMLCALL 504 gdb_xml_fetch_external_entity (XML_Parser expat_parser, 505 const XML_Char *context, 506 const XML_Char *base, 507 const XML_Char *systemId, 508 const XML_Char *publicId) 509 { 510 struct gdb_xml_parser *parser = XML_GetUserData (expat_parser); 511 XML_Parser entity_parser; 512 const char *text; 513 enum XML_Status status; 514 515 if (systemId == NULL) 516 { 517 text = fetch_xml_builtin (parser->dtd_name); 518 if (text == NULL) 519 internal_error (__FILE__, __LINE__, 520 _("could not locate built-in DTD %s"), 521 parser->dtd_name); 522 } 523 else 524 { 525 text = fetch_xml_builtin (systemId); 526 if (text == NULL) 527 return XML_STATUS_ERROR; 528 } 529 530 entity_parser = XML_ExternalEntityParserCreate (expat_parser, context, NULL); 531 532 /* Don't use our handlers for the contents of the DTD. Just let expat 533 process it. */ 534 XML_SetElementHandler (entity_parser, NULL, NULL); 535 XML_SetDoctypeDeclHandler (entity_parser, NULL, NULL); 536 XML_SetXmlDeclHandler (entity_parser, NULL); 537 XML_SetDefaultHandler (entity_parser, NULL); 538 XML_SetUserData (entity_parser, NULL); 539 540 status = XML_Parse (entity_parser, text, strlen (text), 1); 541 542 XML_ParserFree (entity_parser); 543 return status; 544 } 545 546 /* Associate DTD_NAME, which must be the name of a compiled-in DTD, 547 with PARSER. */ 548 549 void 550 gdb_xml_use_dtd (struct gdb_xml_parser *parser, const char *dtd_name) 551 { 552 enum XML_Error err; 553 554 parser->dtd_name = dtd_name; 555 556 XML_SetParamEntityParsing (parser->expat_parser, 557 XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE); 558 XML_SetExternalEntityRefHandler (parser->expat_parser, 559 gdb_xml_fetch_external_entity); 560 561 /* Even if no DTD is provided, use the built-in DTD anyway. */ 562 err = XML_UseForeignDTD (parser->expat_parser, XML_TRUE); 563 if (err != XML_ERROR_NONE) 564 internal_error (__FILE__, __LINE__, 565 _("XML_UseForeignDTD failed: %s"), 566 XML_ErrorString (err)); 567 } 568 569 /* Invoke PARSER on BUFFER. BUFFER is the data to parse, which 570 should be NUL-terminated. 571 572 The return value is 0 for success or -1 for error. It may throw, 573 but only if something unexpected goes wrong during parsing; parse 574 errors will be caught, warned about, and reported as failure. */ 575 576 int 577 gdb_xml_parse (struct gdb_xml_parser *parser, const char *buffer) 578 { 579 enum XML_Status status; 580 const char *error_string; 581 582 gdb_xml_debug (parser, _("Starting:\n%s"), buffer); 583 584 status = XML_Parse (parser->expat_parser, buffer, strlen (buffer), 1); 585 586 if (status == XML_STATUS_OK && parser->error.reason == 0) 587 return 0; 588 589 if (parser->error.reason == RETURN_ERROR 590 && parser->error.error == XML_PARSE_ERROR) 591 { 592 gdb_assert (parser->error.message != NULL); 593 error_string = parser->error.message; 594 } 595 else if (status == XML_STATUS_ERROR) 596 { 597 enum XML_Error err = XML_GetErrorCode (parser->expat_parser); 598 599 error_string = XML_ErrorString (err); 600 } 601 else 602 { 603 gdb_assert (parser->error.reason < 0); 604 throw_exception (parser->error); 605 } 606 607 if (parser->last_line != 0) 608 warning (_("while parsing %s (at line %d): %s"), parser->name, 609 parser->last_line, error_string); 610 else 611 warning (_("while parsing %s: %s"), parser->name, error_string); 612 613 return -1; 614 } 615 616 int 617 gdb_xml_parse_quick (const char *name, const char *dtd_name, 618 const struct gdb_xml_element *elements, 619 const char *document, void *user_data) 620 { 621 struct gdb_xml_parser *parser; 622 struct cleanup *back_to; 623 int result; 624 625 parser = gdb_xml_create_parser_and_cleanup_1 (name, elements, 626 user_data, &back_to); 627 if (dtd_name != NULL) 628 gdb_xml_use_dtd (parser, dtd_name); 629 result = gdb_xml_parse (parser, document); 630 631 do_cleanups (back_to); 632 633 return result; 634 } 635 636 /* Parse a field VALSTR that we expect to contain an integer value. 637 The integer is returned in *VALP. The string is parsed with an 638 equivalent to strtoul. 639 640 Returns 0 for success, -1 for error. */ 641 642 static int 643 xml_parse_unsigned_integer (const char *valstr, ULONGEST *valp) 644 { 645 const char *endptr; 646 ULONGEST result; 647 648 if (*valstr == '\0') 649 return -1; 650 651 result = strtoulst (valstr, &endptr, 0); 652 if (*endptr != '\0') 653 return -1; 654 655 *valp = result; 656 return 0; 657 } 658 659 /* Parse an integer string into a ULONGEST and return it, or call 660 gdb_xml_error if it could not be parsed. */ 661 662 ULONGEST 663 gdb_xml_parse_ulongest (struct gdb_xml_parser *parser, const char *value) 664 { 665 ULONGEST result; 666 667 if (xml_parse_unsigned_integer (value, &result) != 0) 668 gdb_xml_error (parser, _("Can't convert \"%s\" to an integer"), value); 669 670 return result; 671 } 672 673 /* Parse an integer attribute into a ULONGEST. */ 674 675 void * 676 gdb_xml_parse_attr_ulongest (struct gdb_xml_parser *parser, 677 const struct gdb_xml_attribute *attribute, 678 const char *value) 679 { 680 ULONGEST result; 681 void *ret; 682 683 if (xml_parse_unsigned_integer (value, &result) != 0) 684 gdb_xml_error (parser, _("Can't convert %s=\"%s\" to an integer"), 685 attribute->name, value); 686 687 ret = xmalloc (sizeof (result)); 688 memcpy (ret, &result, sizeof (result)); 689 return ret; 690 } 691 692 /* A handler_data for yes/no boolean values. */ 693 694 const struct gdb_xml_enum gdb_xml_enums_boolean[] = { 695 { "yes", 1 }, 696 { "no", 0 }, 697 { NULL, 0 } 698 }; 699 700 /* Map NAME to VALUE. A struct gdb_xml_enum * should be saved as the 701 value of handler_data when using gdb_xml_parse_attr_enum to parse a 702 fixed list of possible strings. The list is terminated by an entry 703 with NAME == NULL. */ 704 705 void * 706 gdb_xml_parse_attr_enum (struct gdb_xml_parser *parser, 707 const struct gdb_xml_attribute *attribute, 708 const char *value) 709 { 710 const struct gdb_xml_enum *enums = attribute->handler_data; 711 void *ret; 712 713 for (enums = attribute->handler_data; enums->name != NULL; enums++) 714 if (strcasecmp (enums->name, value) == 0) 715 break; 716 717 if (enums->name == NULL) 718 gdb_xml_error (parser, _("Unknown attribute value %s=\"%s\""), 719 attribute->name, value); 720 721 ret = xmalloc (sizeof (enums->value)); 722 memcpy (ret, &enums->value, sizeof (enums->value)); 723 return ret; 724 } 725 726 727 /* XInclude processing. This is done as a separate step from actually 728 parsing the document, so that we can produce a single combined XML 729 document - e.g. to hand to a front end or to simplify comparing two 730 documents. We make extensive use of XML_DefaultCurrent, to pass 731 input text directly into the output without reformatting or 732 requoting it. 733 734 We output the DOCTYPE declaration for the first document unchanged, 735 if present, and discard DOCTYPEs from included documents. Only the 736 one we pass through here is used when we feed the result back to 737 expat. The XInclude standard explicitly does not discuss 738 validation of the result; we choose to apply the same DTD applied 739 to the outermost document. 740 741 We can not simply include the external DTD subset in the document 742 as an internal subset, because <!IGNORE> and <!INCLUDE> are valid 743 only in external subsets. But if we do not pass the DTD into the 744 output at all, default values will not be filled in. 745 746 We don't pass through any <?xml> declaration because we generate 747 UTF-8, not whatever the input encoding was. */ 748 749 struct xinclude_parsing_data 750 { 751 /* The obstack to build the output in. */ 752 struct obstack obstack; 753 754 /* A count indicating whether we are in an element whose 755 children should not be copied to the output, and if so, 756 how deep we are nested. This is used for anything inside 757 an xi:include, and for the DTD. */ 758 int skip_depth; 759 760 /* The number of <xi:include> elements currently being processed, 761 to detect loops. */ 762 int include_depth; 763 764 /* A function to call to obtain additional features, and its 765 baton. */ 766 xml_fetch_another fetcher; 767 void *fetcher_baton; 768 }; 769 770 static void 771 xinclude_start_include (struct gdb_xml_parser *parser, 772 const struct gdb_xml_element *element, 773 void *user_data, VEC(gdb_xml_value_s) *attributes) 774 { 775 struct xinclude_parsing_data *data = user_data; 776 char *href = xml_find_attribute (attributes, "href")->value; 777 struct cleanup *back_to; 778 char *text, *output; 779 780 gdb_xml_debug (parser, _("Processing XInclude of \"%s\""), href); 781 782 if (data->include_depth > MAX_XINCLUDE_DEPTH) 783 gdb_xml_error (parser, _("Maximum XInclude depth (%d) exceeded"), 784 MAX_XINCLUDE_DEPTH); 785 786 text = data->fetcher (href, data->fetcher_baton); 787 if (text == NULL) 788 gdb_xml_error (parser, _("Could not load XML document \"%s\""), href); 789 back_to = make_cleanup (xfree, text); 790 791 output = xml_process_xincludes (parser->name, text, data->fetcher, 792 data->fetcher_baton, 793 data->include_depth + 1); 794 if (output == NULL) 795 gdb_xml_error (parser, _("Parsing \"%s\" failed"), href); 796 797 obstack_grow (&data->obstack, output, strlen (output)); 798 xfree (output); 799 800 do_cleanups (back_to); 801 802 data->skip_depth++; 803 } 804 805 static void 806 xinclude_end_include (struct gdb_xml_parser *parser, 807 const struct gdb_xml_element *element, 808 void *user_data, const char *body_text) 809 { 810 struct xinclude_parsing_data *data = user_data; 811 812 data->skip_depth--; 813 } 814 815 static void XMLCALL 816 xml_xinclude_default (void *data_, const XML_Char *s, int len) 817 { 818 struct gdb_xml_parser *parser = data_; 819 struct xinclude_parsing_data *data = parser->user_data; 820 821 /* If we are inside of e.g. xi:include or the DTD, don't save this 822 string. */ 823 if (data->skip_depth) 824 return; 825 826 /* Otherwise just add it to the end of the document we're building 827 up. */ 828 obstack_grow (&data->obstack, s, len); 829 } 830 831 static void XMLCALL 832 xml_xinclude_start_doctype (void *data_, const XML_Char *doctypeName, 833 const XML_Char *sysid, const XML_Char *pubid, 834 int has_internal_subset) 835 { 836 struct gdb_xml_parser *parser = data_; 837 struct xinclude_parsing_data *data = parser->user_data; 838 839 /* Don't print out the doctype, or the contents of the DTD internal 840 subset, if any. */ 841 data->skip_depth++; 842 } 843 844 static void XMLCALL 845 xml_xinclude_end_doctype (void *data_) 846 { 847 struct gdb_xml_parser *parser = data_; 848 struct xinclude_parsing_data *data = parser->user_data; 849 850 data->skip_depth--; 851 } 852 853 static void XMLCALL 854 xml_xinclude_xml_decl (void *data_, const XML_Char *version, 855 const XML_Char *encoding, int standalone) 856 { 857 /* Do nothing - this function prevents the default handler from 858 being called, thus suppressing the XML declaration from the 859 output. */ 860 } 861 862 static void 863 xml_xinclude_cleanup (void *data_) 864 { 865 struct xinclude_parsing_data *data = data_; 866 867 obstack_free (&data->obstack, NULL); 868 xfree (data); 869 } 870 871 const struct gdb_xml_attribute xinclude_attributes[] = { 872 { "href", GDB_XML_AF_NONE, NULL, NULL }, 873 { NULL, GDB_XML_AF_NONE, NULL, NULL } 874 }; 875 876 const struct gdb_xml_element xinclude_elements[] = { 877 { "http://www.w3.org/2001/XInclude!include", xinclude_attributes, NULL, 878 GDB_XML_EF_OPTIONAL | GDB_XML_EF_REPEATABLE, 879 xinclude_start_include, xinclude_end_include }, 880 { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL } 881 }; 882 883 /* The main entry point for <xi:include> processing. */ 884 885 char * 886 xml_process_xincludes (const char *name, const char *text, 887 xml_fetch_another fetcher, void *fetcher_baton, 888 int depth) 889 { 890 struct gdb_xml_parser *parser; 891 struct xinclude_parsing_data *data; 892 struct cleanup *back_to; 893 char *result = NULL; 894 895 data = XZALLOC (struct xinclude_parsing_data); 896 obstack_init (&data->obstack); 897 back_to = make_cleanup (xml_xinclude_cleanup, data); 898 899 parser = gdb_xml_create_parser_and_cleanup (name, xinclude_elements, data); 900 parser->is_xinclude = 1; 901 902 data->include_depth = depth; 903 data->fetcher = fetcher; 904 data->fetcher_baton = fetcher_baton; 905 906 XML_SetCharacterDataHandler (parser->expat_parser, NULL); 907 XML_SetDefaultHandler (parser->expat_parser, xml_xinclude_default); 908 909 /* Always discard the XML version declarations; the only important 910 thing this provides is encoding, and our result will have been 911 converted to UTF-8. */ 912 XML_SetXmlDeclHandler (parser->expat_parser, xml_xinclude_xml_decl); 913 914 if (depth > 0) 915 /* Discard the doctype for included documents. */ 916 XML_SetDoctypeDeclHandler (parser->expat_parser, 917 xml_xinclude_start_doctype, 918 xml_xinclude_end_doctype); 919 920 gdb_xml_use_dtd (parser, "xinclude.dtd"); 921 922 if (gdb_xml_parse (parser, text) == 0) 923 { 924 obstack_1grow (&data->obstack, '\0'); 925 result = xstrdup (obstack_finish (&data->obstack)); 926 927 if (depth == 0) 928 gdb_xml_debug (parser, _("XInclude processing succeeded.")); 929 } 930 else 931 result = NULL; 932 933 do_cleanups (back_to); 934 return result; 935 } 936 #endif /* HAVE_LIBEXPAT */ 937 938 939 /* Return an XML document which was compiled into GDB, from 940 the given FILENAME, or NULL if the file was not compiled in. */ 941 942 const char * 943 fetch_xml_builtin (const char *filename) 944 { 945 const char *(*p)[2]; 946 947 for (p = xml_builtin; (*p)[0]; p++) 948 if (strcmp ((*p)[0], filename) == 0) 949 return (*p)[1]; 950 951 return NULL; 952 } 953 954 /* A to_xfer_partial helper function which reads XML files which were 955 compiled into GDB. The target may call this function from its own 956 to_xfer_partial handler, after converting object and annex to the 957 appropriate filename. */ 958 959 LONGEST 960 xml_builtin_xfer_partial (const char *filename, 961 gdb_byte *readbuf, const gdb_byte *writebuf, 962 ULONGEST offset, LONGEST len) 963 { 964 const char *buf; 965 LONGEST len_avail; 966 967 gdb_assert (readbuf != NULL && writebuf == NULL); 968 gdb_assert (filename != NULL); 969 970 buf = fetch_xml_builtin (filename); 971 if (buf == NULL) 972 return -1; 973 974 len_avail = strlen (buf); 975 if (offset >= len_avail) 976 return 0; 977 978 if (len > len_avail - offset) 979 len = len_avail - offset; 980 memcpy (readbuf, buf + offset, len); 981 return len; 982 } 983 984 985 static void 986 show_debug_xml (struct ui_file *file, int from_tty, 987 struct cmd_list_element *c, const char *value) 988 { 989 fprintf_filtered (file, _("XML debugging is %s.\n"), value); 990 } 991 992 void 993 obstack_xml_printf (struct obstack *obstack, const char *format, ...) 994 { 995 va_list ap; 996 const char *f; 997 const char *prev; 998 int percent = 0; 999 1000 va_start (ap, format); 1001 1002 prev = format; 1003 for (f = format; *f; f++) 1004 { 1005 if (percent) 1006 { 1007 switch (*f) 1008 { 1009 case 's': 1010 { 1011 char *p; 1012 char *a = va_arg (ap, char *); 1013 1014 obstack_grow (obstack, prev, f - prev - 1); 1015 p = xml_escape_text (a); 1016 obstack_grow_str (obstack, p); 1017 xfree (p); 1018 prev = f + 1; 1019 } 1020 break; 1021 } 1022 percent = 0; 1023 } 1024 else if (*f == '%') 1025 percent = 1; 1026 } 1027 1028 obstack_grow_str (obstack, prev); 1029 va_end (ap); 1030 } 1031 1032 char * 1033 xml_fetch_content_from_file (const char *filename, void *baton) 1034 { 1035 const char *dirname = baton; 1036 FILE *file; 1037 struct cleanup *back_to; 1038 char *text; 1039 size_t len, offset; 1040 1041 if (dirname && *dirname) 1042 { 1043 char *fullname = concat (dirname, "/", filename, (char *) NULL); 1044 1045 if (fullname == NULL) 1046 malloc_failure (0); 1047 file = fopen (fullname, FOPEN_RT); 1048 xfree (fullname); 1049 } 1050 else 1051 file = fopen (filename, FOPEN_RT); 1052 1053 if (file == NULL) 1054 return NULL; 1055 1056 back_to = make_cleanup_fclose (file); 1057 1058 /* Read in the whole file, one chunk at a time. */ 1059 len = 4096; 1060 offset = 0; 1061 text = xmalloc (len); 1062 make_cleanup (free_current_contents, &text); 1063 while (1) 1064 { 1065 size_t bytes_read; 1066 1067 /* Continue reading where the last read left off. Leave at least 1068 one byte so that we can NUL-terminate the result. */ 1069 bytes_read = fread (text + offset, 1, len - offset - 1, file); 1070 if (ferror (file)) 1071 { 1072 warning (_("Read error from \"%s\""), filename); 1073 do_cleanups (back_to); 1074 return NULL; 1075 } 1076 1077 offset += bytes_read; 1078 1079 if (feof (file)) 1080 break; 1081 1082 len = len * 2; 1083 text = xrealloc (text, len); 1084 } 1085 1086 fclose (file); 1087 discard_cleanups (back_to); 1088 1089 text[offset] = '\0'; 1090 return text; 1091 } 1092 1093 void _initialize_xml_support (void); 1094 1095 void 1096 _initialize_xml_support (void) 1097 { 1098 add_setshow_boolean_cmd ("xml", class_maintenance, &debug_xml, 1099 _("Set XML parser debugging."), 1100 _("Show XML parser debugging."), 1101 _("When set, debugging messages for XML parsers " 1102 "are displayed."), 1103 NULL, show_debug_xml, 1104 &setdebuglist, &showdebuglist); 1105 } 1106