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