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