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