Switch the license of all .c files to GPLv3.
[external/binutils.git] / gdb / xml-support.c
1 /* Helper routines for parsing XML using Expat.
2
3    Copyright (C) 2006, 2007 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 /* Clean up a vector of parsed attribute values.  */
141
142 static void
143 gdb_xml_values_cleanup (void *data)
144 {
145   VEC(gdb_xml_value_s) **values = data;
146   struct gdb_xml_value *value;
147   int ix;
148
149   for (ix = 0; VEC_iterate (gdb_xml_value_s, *values, ix, value); ix++)
150     xfree (value->value);
151   VEC_free (gdb_xml_value_s, *values);
152 }
153
154 /* Handle the start of an element.  DATA is our local XML parser, NAME
155    is the element, and ATTRS are the names and values of this
156    element's attributes.  */
157
158 static void
159 gdb_xml_start_element (void *data, const XML_Char *name,
160                        const XML_Char **attrs)
161 {
162   struct gdb_xml_parser *parser = data;
163   struct scope_level *scope;
164   struct scope_level new_scope;
165   const struct gdb_xml_element *element;
166   const struct gdb_xml_attribute *attribute;
167   VEC(gdb_xml_value_s) *attributes = NULL;
168   unsigned int seen;
169   struct cleanup *back_to;
170
171   /* Push an error scope.  If we return or throw an exception before
172      filling this in, it will tell us to ignore children of this
173      element.  */
174   VEC_reserve (scope_level_s, parser->scopes, 1);
175   scope = VEC_last (scope_level_s, parser->scopes);
176   memset (&new_scope, 0, sizeof (new_scope));
177   VEC_quick_push (scope_level_s, parser->scopes, &new_scope);
178
179   gdb_xml_debug (parser, _("Entering element <%s>"), name);
180
181   /* Find this element in the list of the current scope's allowed
182      children.  Record that we've seen it.  */
183
184   seen = 1;
185   for (element = scope->elements; element && element->name;
186        element++, seen <<= 1)
187     if (strcmp (element->name, name) == 0)
188       break;
189
190   if (element == NULL || element->name == NULL)
191     {
192       /* If we're working on XInclude, <xi:include> can be the child
193          of absolutely anything.  Copy the previous scope's element
194          list into the new scope even if there was no match.  */
195       if (parser->is_xinclude)
196         {
197           struct scope_level *unknown_scope;
198
199           XML_DefaultCurrent (parser->expat_parser);
200
201           unknown_scope = VEC_last (scope_level_s, parser->scopes);
202           unknown_scope->elements = scope->elements;
203           return;
204         }
205
206       gdb_xml_debug (parser, _("Element <%s> unknown"), name);
207       return;
208     }
209
210   if (!(element->flags & GDB_XML_EF_REPEATABLE) && (seen & scope->seen))
211     gdb_xml_error (parser, _("Element <%s> only expected once"), name);
212
213   scope->seen |= seen;
214
215   back_to = make_cleanup (gdb_xml_values_cleanup, &attributes);
216
217   for (attribute = element->attributes;
218        attribute != NULL && attribute->name != NULL;
219        attribute++)
220     {
221       const char *val = NULL;
222       const XML_Char **p;
223       void *parsed_value;
224       struct gdb_xml_value new_value;
225
226       for (p = attrs; *p != NULL; p += 2)
227         if (!strcmp (attribute->name, p[0]))
228           {
229             val = p[1];
230             break;
231           }
232
233       if (*p != NULL && val == NULL)
234         {
235           gdb_xml_debug (parser, _("Attribute \"%s\" missing a value"),
236                          attribute->name);
237           continue;
238         }
239
240       if (*p == NULL && !(attribute->flags & GDB_XML_AF_OPTIONAL))
241         {
242           gdb_xml_error (parser, _("Required attribute \"%s\" of "
243                                    "<%s> not specified"),
244                          attribute->name, element->name);
245           continue;
246         }
247
248       if (*p == NULL)
249         continue;
250
251       gdb_xml_debug (parser, _("Parsing attribute %s=\"%s\""),
252                      attribute->name, val);
253
254       if (attribute->handler)
255         parsed_value = attribute->handler (parser, attribute, val);
256       else
257         parsed_value = xstrdup (val);
258
259       new_value.name = attribute->name;
260       new_value.value = parsed_value;
261       VEC_safe_push (gdb_xml_value_s, attributes, &new_value);
262     }
263
264   /* Check for unrecognized attributes.  */
265   if (debug_xml)
266     {
267       const XML_Char **p;
268
269       for (p = attrs; *p != NULL; p += 2)
270         {
271           for (attribute = element->attributes;
272                attribute != NULL && attribute->name != NULL;
273                attribute++)
274             if (strcmp (attribute->name, *p) == 0)
275               break;
276
277           if (attribute == NULL || attribute->name == NULL)
278             gdb_xml_debug (parser, _("Ignoring unknown attribute %s"), *p);
279         }
280     }
281
282   /* Call the element handler if there is one.  */
283   if (element->start_handler)
284     element->start_handler (parser, element, parser->user_data, attributes);
285
286   /* Fill in a new scope level.  */
287   scope = VEC_last (scope_level_s, parser->scopes);
288   scope->element = element;
289   scope->elements = element->children;
290
291   do_cleanups (back_to);
292 }
293
294 /* Wrapper for gdb_xml_start_element, to prevent throwing exceptions
295    through expat.  */
296
297 static void
298 gdb_xml_start_element_wrapper (void *data, const XML_Char *name,
299                                const XML_Char **attrs)
300 {
301   struct gdb_xml_parser *parser = data;
302   volatile struct gdb_exception ex;
303
304   if (parser->error.reason < 0)
305     return;
306
307   TRY_CATCH (ex, RETURN_MASK_ALL)
308     {
309       gdb_xml_start_element (data, name, attrs);
310     }
311   if (ex.reason < 0)
312     {
313       parser->error = ex;
314 #ifdef HAVE_XML_STOPPARSER
315       XML_StopParser (parser->expat_parser, XML_FALSE);
316 #endif
317     }
318 }
319
320 /* Handle the end of an element.  DATA is our local XML parser, and
321    NAME is the current element.  */
322
323 static void
324 gdb_xml_end_element (void *data, const XML_Char *name)
325 {
326   struct gdb_xml_parser *parser = data;
327   struct scope_level *scope = VEC_last (scope_level_s, parser->scopes);
328   const struct gdb_xml_element *element;
329   unsigned int seen;
330
331   gdb_xml_debug (parser, _("Leaving element <%s>"), name);
332
333   for (element = scope->elements, seen = 1;
334        element != NULL && element->name != NULL;
335        element++, seen <<= 1)
336     if ((scope->seen & seen) == 0
337         && (element->flags & GDB_XML_EF_OPTIONAL) == 0)
338       gdb_xml_error (parser, _("Required element <%s> is missing"),
339                      element->name);
340
341   /* Call the element processor. */
342   if (scope->element != NULL && scope->element->end_handler)
343     {
344       char *body;
345
346       if (scope->body == NULL)
347         body = "";
348       else
349         {
350           int length;
351
352           length = obstack_object_size (scope->body);
353           obstack_1grow (scope->body, '\0');
354           body = obstack_finish (scope->body);
355
356           /* Strip leading and trailing whitespace.  */
357           while (length > 0 && ISSPACE (body[length-1]))
358             body[--length] = '\0';
359           while (*body && ISSPACE (*body))
360             body++;
361         }
362
363       scope->element->end_handler (parser, scope->element, parser->user_data,
364                                    body);
365     }
366   else if (scope->element == NULL)
367     XML_DefaultCurrent (parser->expat_parser);
368
369   /* Pop the scope level.  */
370   if (scope->body)
371     {
372       obstack_free (scope->body, NULL);
373       xfree (scope->body);
374     }
375   VEC_pop (scope_level_s, parser->scopes);
376 }
377
378 /* Wrapper for gdb_xml_end_element, to prevent throwing exceptions
379    through expat.  */
380
381 static void
382 gdb_xml_end_element_wrapper (void *data, const XML_Char *name)
383 {
384   struct gdb_xml_parser *parser = data;
385   volatile struct gdb_exception ex;
386
387   if (parser->error.reason < 0)
388     return;
389
390   TRY_CATCH (ex, RETURN_MASK_ALL)
391     {
392       gdb_xml_end_element (data, name);
393     }
394   if (ex.reason < 0)
395     {
396       parser->error = ex;
397 #ifdef HAVE_XML_STOPPARSER
398       XML_StopParser (parser->expat_parser, XML_FALSE);
399 #endif
400     }
401 }
402
403 /* Free a parser and all its associated state.  */
404
405 static void
406 gdb_xml_cleanup (void *arg)
407 {
408   struct gdb_xml_parser *parser = arg;
409   struct scope_level *scope;
410   int ix;
411
412   XML_ParserFree (parser->expat_parser);
413
414   /* Clean up the scopes.  */
415   for (ix = 0; VEC_iterate (scope_level_s, parser->scopes, ix, scope); ix++)
416     if (scope->body)
417       {
418         obstack_free (scope->body, NULL);
419         xfree (scope->body);
420       }
421   VEC_free (scope_level_s, parser->scopes);
422
423   xfree (parser);
424 }
425
426 /* Initialize and return a parser.  Register a cleanup to destroy the
427    parser.  */
428
429 struct gdb_xml_parser *
430 gdb_xml_create_parser_and_cleanup (const char *name,
431                                    const struct gdb_xml_element *elements,
432                                    void *user_data)
433 {
434   struct gdb_xml_parser *parser;
435   struct scope_level start_scope;
436
437   /* Initialize the parser.  */
438   parser = XZALLOC (struct gdb_xml_parser);
439   parser->expat_parser = XML_ParserCreateNS (NULL, '!');
440   if (parser->expat_parser == NULL)
441     {
442       xfree (parser);
443       nomem (0);
444     }
445
446   parser->name = name;
447
448   parser->user_data = user_data;
449   XML_SetUserData (parser->expat_parser, parser);
450
451   /* Set the callbacks.  */
452   XML_SetElementHandler (parser->expat_parser, gdb_xml_start_element_wrapper,
453                          gdb_xml_end_element_wrapper);
454   XML_SetCharacterDataHandler (parser->expat_parser, gdb_xml_body_text);
455
456   /* Initialize the outer scope.  */
457   memset (&start_scope, 0, sizeof (start_scope));
458   start_scope.elements = elements;
459   VEC_safe_push (scope_level_s, parser->scopes, &start_scope);
460
461   make_cleanup (gdb_xml_cleanup, parser);
462
463   return parser;
464 }
465
466 /* External entity handler.  The only external entities we support
467    are those compiled into GDB (we do not fetch entities from the
468    target).  */
469
470 static int XMLCALL
471 gdb_xml_fetch_external_entity (XML_Parser expat_parser,
472                                const XML_Char *context,
473                                const XML_Char *base,
474                                const XML_Char *systemId,
475                                const XML_Char *publicId)
476 {
477   struct gdb_xml_parser *parser = XML_GetUserData (expat_parser);
478   XML_Parser entity_parser;
479   const char *text;
480   enum XML_Status status;
481
482   if (systemId == NULL)
483     {
484       text = fetch_xml_builtin (parser->dtd_name);
485       if (text == NULL)
486         internal_error (__FILE__, __LINE__, "could not locate built-in DTD %s",
487                         parser->dtd_name);
488     }
489   else
490     {
491       text = fetch_xml_builtin (systemId);
492       if (text == NULL)
493         return XML_STATUS_ERROR;
494     }
495
496   entity_parser = XML_ExternalEntityParserCreate (expat_parser, context, NULL);
497
498   /* Don't use our handlers for the contents of the DTD.  Just let expat
499      process it.  */
500   XML_SetElementHandler (entity_parser, NULL, NULL);
501   XML_SetDoctypeDeclHandler (entity_parser, NULL, NULL);
502   XML_SetXmlDeclHandler (entity_parser, NULL);
503   XML_SetDefaultHandler (entity_parser, NULL);
504   XML_SetUserData (entity_parser, NULL);
505
506   status = XML_Parse (entity_parser, text, strlen (text), 1);
507
508   XML_ParserFree (entity_parser);
509   return status;
510 }
511
512 /* Associate DTD_NAME, which must be the name of a compiled-in DTD,
513    with PARSER.  */
514
515 void
516 gdb_xml_use_dtd (struct gdb_xml_parser *parser, const char *dtd_name)
517 {
518   enum XML_Error err;
519
520   parser->dtd_name = dtd_name;
521
522   XML_SetParamEntityParsing (parser->expat_parser,
523                              XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE);
524   XML_SetExternalEntityRefHandler (parser->expat_parser,
525                                    gdb_xml_fetch_external_entity);
526
527   /* Even if no DTD is provided, use the built-in DTD anyway.  */
528   err = XML_UseForeignDTD (parser->expat_parser, XML_TRUE);
529   if (err != XML_ERROR_NONE)
530     internal_error (__FILE__, __LINE__,
531                     "XML_UseForeignDTD failed: %s", XML_ErrorString (err));
532 }
533
534 /* Invoke PARSER on BUFFER.  BUFFER is the data to parse, which
535    should be NUL-terminated.
536
537    The return value is 0 for success or -1 for error.  It may throw,
538    but only if something unexpected goes wrong during parsing; parse
539    errors will be caught, warned about, and reported as failure.  */
540
541 int
542 gdb_xml_parse (struct gdb_xml_parser *parser, const char *buffer)
543 {
544   enum XML_Status status;
545   const char *error_string;
546
547   status = XML_Parse (parser->expat_parser, buffer, strlen (buffer), 1);
548
549   if (status == XML_STATUS_OK && parser->error.reason == 0)
550     return 0;
551
552   if (parser->error.reason == RETURN_ERROR
553       && parser->error.error == XML_PARSE_ERROR)
554     {
555       gdb_assert (parser->error.message != NULL);
556       error_string = parser->error.message;
557     }
558   else if (status == XML_STATUS_ERROR)
559     {
560       enum XML_Error err = XML_GetErrorCode (parser->expat_parser);
561       error_string = XML_ErrorString (err);
562     }
563   else
564     {
565       gdb_assert (parser->error.reason < 0);
566       throw_exception (parser->error);
567     }
568
569   if (parser->last_line != 0)
570     warning (_("while parsing %s (at line %d): %s"), parser->name,
571              parser->last_line, error_string);
572   else
573     warning (_("while parsing %s: %s"), parser->name, error_string);
574
575   return -1;
576 }
577
578 /* Parse a field VALSTR that we expect to contain an integer value.
579    The integer is returned in *VALP.  The string is parsed with an
580    equivalent to strtoul.
581
582    Returns 0 for success, -1 for error.  */
583
584 static int
585 xml_parse_unsigned_integer (const char *valstr, ULONGEST *valp)
586 {
587   const char *endptr;
588   ULONGEST result;
589
590   if (*valstr == '\0')
591     return -1;
592
593   result = strtoulst (valstr, &endptr, 0);
594   if (*endptr != '\0')
595     return -1;
596
597   *valp = result;
598   return 0;
599 }
600
601 /* Parse an integer string into a ULONGEST and return it, or call
602    gdb_xml_error if it could not be parsed.  */
603
604 ULONGEST
605 gdb_xml_parse_ulongest (struct gdb_xml_parser *parser, const char *value)
606 {
607   ULONGEST result;
608
609   if (xml_parse_unsigned_integer (value, &result) != 0)
610     gdb_xml_error (parser, _("Can't convert \"%s\" to an integer"), value);
611
612   return result;
613 }
614
615 /* Parse an integer attribute into a ULONGEST.  */
616
617 void *
618 gdb_xml_parse_attr_ulongest (struct gdb_xml_parser *parser,
619                              const struct gdb_xml_attribute *attribute,
620                              const char *value)
621 {
622   ULONGEST result;
623   void *ret;
624
625   if (xml_parse_unsigned_integer (value, &result) != 0)
626     gdb_xml_error (parser, _("Can't convert %s=\"%s\" to an integer"),
627                    attribute->name, value);
628
629   ret = xmalloc (sizeof (result));
630   memcpy (ret, &result, sizeof (result));
631   return ret;
632 }
633
634 /* A handler_data for yes/no boolean values.  */
635
636 const struct gdb_xml_enum gdb_xml_enums_boolean[] = {
637   { "yes", 1 },
638   { "no", 0 },
639   { NULL, 0 }
640 };
641
642 /* Map NAME to VALUE.  A struct gdb_xml_enum * should be saved as the
643    value of handler_data when using gdb_xml_parse_attr_enum to parse a
644    fixed list of possible strings.  The list is terminated by an entry
645    with NAME == NULL.  */
646
647 void *
648 gdb_xml_parse_attr_enum (struct gdb_xml_parser *parser,
649                          const struct gdb_xml_attribute *attribute,
650                          const char *value)
651 {
652   const struct gdb_xml_enum *enums = attribute->handler_data;
653   void *ret;
654
655   for (enums = attribute->handler_data; enums->name != NULL; enums++)
656     if (strcasecmp (enums->name, value) == 0)
657       break;
658
659   if (enums->name == NULL)
660     gdb_xml_error (parser, _("Unknown attribute value %s=\"%s\""),
661                  attribute->name, value);
662
663   ret = xmalloc (sizeof (enums->value));
664   memcpy (ret, &enums->value, sizeof (enums->value));
665   return ret;
666 }
667 \f
668
669 /* XInclude processing.  This is done as a separate step from actually
670    parsing the document, so that we can produce a single combined XML
671    document - e.g. to hand to a front end or to simplify comparing two
672    documents.  We make extensive use of XML_DefaultCurrent, to pass
673    input text directly into the output without reformatting or
674    requoting it.
675
676    We output the DOCTYPE declaration for the first document unchanged,
677    if present, and discard DOCTYPEs from included documents.  Only the
678    one we pass through here is used when we feed the result back to
679    expat.  The XInclude standard explicitly does not discuss
680    validation of the result; we choose to apply the same DTD applied
681    to the outermost document.
682
683    We can not simply include the external DTD subset in the document
684    as an internal subset, because <!IGNORE> and <!INCLUDE> are valid
685    only in external subsets.  But if we do not pass the DTD into the
686    output at all, default values will not be filled in.
687
688    We don't pass through any <?xml> declaration because we generate
689    UTF-8, not whatever the input encoding was.  */
690
691 struct xinclude_parsing_data
692 {
693   /* The obstack to build the output in.  */
694   struct obstack obstack;
695
696   /* A count indicating whether we are in an element whose
697      children should not be copied to the output, and if so,
698      how deep we are nested.  This is used for anything inside
699      an xi:include, and for the DTD.  */
700   int skip_depth;
701
702   /* The number of <xi:include> elements currently being processed,
703      to detect loops.  */
704   int include_depth;
705
706   /* A function to call to obtain additional features, and its
707      baton.  */
708   xml_fetch_another fetcher;
709   void *fetcher_baton;
710 };
711
712 static void
713 xinclude_start_include (struct gdb_xml_parser *parser,
714                         const struct gdb_xml_element *element,
715                         void *user_data, VEC(gdb_xml_value_s) *attributes)
716 {
717   struct xinclude_parsing_data *data = user_data;
718   char *href = VEC_index (gdb_xml_value_s, attributes, 0)->value;
719   struct cleanup *back_to;
720   char *text, *output;
721   int ret;
722
723   gdb_xml_debug (parser, _("Processing XInclude of \"%s\""), href);
724
725   if (data->include_depth > MAX_XINCLUDE_DEPTH)
726     gdb_xml_error (parser, _("Maximum XInclude depth (%d) exceeded"),
727                    MAX_XINCLUDE_DEPTH);
728
729   text = data->fetcher (href, data->fetcher_baton);
730   if (text == NULL)
731     gdb_xml_error (parser, _("Could not load XML document \"%s\""), href);
732   back_to = make_cleanup (xfree, text);
733
734   output = xml_process_xincludes (parser->name, text, data->fetcher,
735                                   data->fetcher_baton,
736                                   data->include_depth + 1);
737   if (output == NULL)
738     gdb_xml_error (parser, _("Parsing \"%s\" failed"), href);
739
740   obstack_grow (&data->obstack, output, strlen (output));
741   xfree (output);
742
743   do_cleanups (back_to);
744
745   data->skip_depth++;
746 }
747
748 static void
749 xinclude_end_include (struct gdb_xml_parser *parser,
750                       const struct gdb_xml_element *element,
751                       void *user_data, const char *body_text)
752 {
753   struct xinclude_parsing_data *data = user_data;
754
755   data->skip_depth--;
756 }
757
758 static void XMLCALL
759 xml_xinclude_default (void *data_, const XML_Char *s, int len)
760 {
761   struct gdb_xml_parser *parser = data_;
762   struct xinclude_parsing_data *data = parser->user_data;
763
764   /* If we are inside of e.g. xi:include or the DTD, don't save this
765      string.  */
766   if (data->skip_depth)
767     return;
768
769   /* Otherwise just add it to the end of the document we're building
770      up.  */
771   obstack_grow (&data->obstack, s, len);
772 }
773
774 static void XMLCALL
775 xml_xinclude_start_doctype (void *data_, const XML_Char *doctypeName,
776                             const XML_Char *sysid, const XML_Char *pubid,
777                             int has_internal_subset)
778 {
779   struct gdb_xml_parser *parser = data_;
780   struct xinclude_parsing_data *data = parser->user_data;
781
782   /* Don't print out the doctype, or the contents of the DTD internal
783      subset, if any.  */
784   data->skip_depth++;
785 }
786
787 static void XMLCALL
788 xml_xinclude_end_doctype (void *data_)
789 {
790   struct gdb_xml_parser *parser = data_;
791   struct xinclude_parsing_data *data = parser->user_data;
792
793   data->skip_depth--;
794 }
795
796 static void XMLCALL
797 xml_xinclude_xml_decl (void *data_, const XML_Char *version,
798                        const XML_Char *encoding, int standalone)
799 {
800   /* Do nothing - this function prevents the default handler from
801      being called, thus suppressing the XML declaration from the
802      output.  */
803 }
804
805 static void
806 xml_xinclude_cleanup (void *data_)
807 {
808   struct xinclude_parsing_data *data = data_;
809
810   obstack_free (&data->obstack, NULL);
811   xfree (data);
812 }
813
814 const struct gdb_xml_attribute xinclude_attributes[] = {
815   { "href", GDB_XML_AF_NONE, NULL, NULL },
816   { NULL, GDB_XML_AF_NONE, NULL, NULL }
817 };
818
819 const struct gdb_xml_element xinclude_elements[] = {
820   { "http://www.w3.org/2001/XInclude!include", xinclude_attributes, NULL,
821     GDB_XML_EF_OPTIONAL | GDB_XML_EF_REPEATABLE,
822     xinclude_start_include, xinclude_end_include },
823   { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
824 };
825
826 /* The main entry point for <xi:include> processing.  */
827
828 char *
829 xml_process_xincludes (const char *name, const char *text,
830                        xml_fetch_another fetcher, void *fetcher_baton,
831                        int depth)
832 {
833   enum XML_Error err;
834   struct gdb_xml_parser *parser;
835   struct xinclude_parsing_data *data;
836   struct cleanup *back_to;
837   char *result = NULL;
838
839   data = XZALLOC (struct xinclude_parsing_data);
840   obstack_init (&data->obstack);
841   back_to = make_cleanup (xml_xinclude_cleanup, data);
842
843   parser = gdb_xml_create_parser_and_cleanup (name, xinclude_elements, data);
844   parser->is_xinclude = 1;
845
846   data->include_depth = depth;
847   data->fetcher = fetcher;
848   data->fetcher_baton = fetcher_baton;
849
850   XML_SetCharacterDataHandler (parser->expat_parser, NULL);
851   XML_SetDefaultHandler (parser->expat_parser, xml_xinclude_default);
852
853   /* Always discard the XML version declarations; the only important
854      thing this provides is encoding, and our result will have been
855      converted to UTF-8.  */
856   XML_SetXmlDeclHandler (parser->expat_parser, xml_xinclude_xml_decl);
857
858   if (depth > 0)
859     /* Discard the doctype for included documents.  */
860     XML_SetDoctypeDeclHandler (parser->expat_parser,
861                                xml_xinclude_start_doctype,
862                                xml_xinclude_end_doctype);
863
864   gdb_xml_use_dtd (parser, "xinclude.dtd");
865
866   if (gdb_xml_parse (parser, text) == 0)
867     {
868       obstack_1grow (&data->obstack, '\0');
869       result = xstrdup (obstack_finish (&data->obstack));
870
871       if (depth == 0)
872         gdb_xml_debug (parser, _("XInclude processing succeeded:\n%s"),
873                        result);
874     }
875   else
876     result = NULL;
877
878   do_cleanups (back_to);
879   return result;
880 }
881 #endif /* HAVE_LIBEXPAT */
882 \f
883
884 /* Return an XML document which was compiled into GDB, from
885    the given FILENAME, or NULL if the file was not compiled in.  */
886
887 const char *
888 fetch_xml_builtin (const char *filename)
889 {
890   const char *(*p)[2];
891
892   for (p = xml_builtin; (*p)[0]; p++)
893     if (strcmp ((*p)[0], filename) == 0)
894       return (*p)[1];
895
896   return NULL;
897 }
898
899 /* A to_xfer_partial helper function which reads XML files which were
900    compiled into GDB.  The target may call this function from its own
901    to_xfer_partial handler, after converting object and annex to the
902    appropriate filename.  */
903
904 LONGEST
905 xml_builtin_xfer_partial (const char *filename,
906                           gdb_byte *readbuf, const gdb_byte *writebuf,
907                           ULONGEST offset, LONGEST len)
908 {
909   const char *buf;
910   LONGEST len_avail;
911
912   gdb_assert (readbuf != NULL && writebuf == NULL);
913   gdb_assert (filename != NULL);
914
915   buf = fetch_xml_builtin (filename);
916   if (buf == NULL)
917     return -1;
918
919   len_avail = strlen (buf);
920   if (offset >= len_avail)
921     return 0;
922
923   if (len > len_avail - offset)
924     len = len_avail - offset;
925   memcpy (readbuf, buf + offset, len);
926   return len;
927 }
928 \f
929
930 static void
931 show_debug_xml (struct ui_file *file, int from_tty,
932                 struct cmd_list_element *c, const char *value)
933 {
934   fprintf_filtered (file, _("XML debugging is %s.\n"), value);
935 }
936
937 void _initialize_xml_support (void);
938
939 void
940 _initialize_xml_support (void)
941 {
942   add_setshow_boolean_cmd ("xml", class_maintenance, &debug_xml,
943                            _("Set XML parser debugging."),
944                            _("Show XML parser debugging."),
945                            _("When set, debugging messages for XML parsers "
946                              "are displayed."),
947                            NULL, show_debug_xml,
948                            &setdebuglist, &showdebuglist);
949 }