* memory-map.c (XML_STATUS_OK, XML_STATUS_ERROR): Provide default
[external/binutils.git] / gdb / xml-support.c
1 /* Helper routines for parsing XML using Expat.
2
3    Copyright (C) 2006
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 2 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, write to the Free Software
20    Foundation, Inc., 51 Franklin Street, Fifth Floor,
21    Boston, MA 02110-1301, USA.  */
22
23 #include "defs.h"
24
25 /* The contents of this file are only useful if XML support is
26    available.  */
27 #ifdef HAVE_LIBEXPAT
28
29 #include "exceptions.h"
30 #include "xml-support.h"
31
32 #include <expat.h>
33
34 #include "gdb_string.h"
35
36 #ifndef XML_STATUS_OK
37 # define XML_STATUS_OK    1
38 # define XML_STATUS_ERROR 0
39 #endif
40
41 /* Returns the value of attribute ATTR from expat attribute list
42    ATTRLIST.  If not found, throws an exception.  */
43
44 const XML_Char *
45 xml_get_required_attribute (const XML_Char **attrs,
46                             const XML_Char *attr)
47 {
48   const XML_Char **p;
49   for (p = attrs; *p; p += 2)
50     {
51       const char *name = p[0];
52       const char *val = p[1];
53
54       if (strcmp (name, attr) == 0)
55         return val;
56     }
57   throw_error (XML_PARSE_ERROR, _("Can't find attribute %s"), attr);
58 }
59
60 /* Parse a field VALSTR that we expect to contain an integer value.
61    The integer is returned in *VALP.  The string is parsed with an
62    equivalent to strtoul.
63
64    Returns 0 for success, -1 for error.  */
65
66 static int
67 xml_parse_unsigned_integer (const char *valstr, ULONGEST *valp)
68 {
69   const char *endptr;
70   ULONGEST result;
71
72   if (*valstr == '\0')
73     return -1;
74
75   result = strtoulst (valstr, &endptr, 0);
76   if (*endptr != '\0')
77     return -1;
78
79   *valp = result;
80   return 0;
81 }
82
83 /* Gets the value of an integer attribute named ATTR, if it's present.
84    If the attribute is not found, or can't be parsed as integer,
85    throws an exception.  */
86
87 ULONGEST
88 xml_get_integer_attribute (const XML_Char **attrs,
89                            const XML_Char *attr)
90 {
91   ULONGEST result;
92   const XML_Char *value = xml_get_required_attribute (attrs, attr);
93
94   if (xml_parse_unsigned_integer (value, &result) != 0)
95     {
96       throw_error (XML_PARSE_ERROR,
97                    _("Can't convert value of attribute %s, %s, to integer"),
98                    attr, value);
99     }
100   return result;
101 }
102
103 /* Obtains a value of attribute with enumerated type. In XML, enumerated
104    attributes have string as a value, and in C, they are represented as
105    values of enumerated type. This function maps the attribute onto
106    an integer value that can be immediately converted into enumerated
107    type.
108
109    First, obtains the string value of ATTR in ATTRS.
110    Then, finds the index of that value in XML_NAMES, which is a zero-terminated
111    array of strings. If found, returns the element of VALUES with that index.
112    Otherwise throws.  */
113
114 int
115 xml_get_enum_value (const XML_Char **attrs,
116                     const XML_Char *attr,
117                     const XML_Char **xml_names,
118                     int *values)
119 {
120   const XML_Char *value = xml_get_required_attribute (attrs, attr);
121
122   int i;
123   for (i = 0; xml_names[i]; ++i)
124     {
125       if (strcmp (xml_names[i], value) == 0)
126         return values[i];
127     }
128   throw_error (XML_PARSE_ERROR,
129                _("Invalid enumerated value in XML: %s"), value);
130 }
131
132 /* Cleanup wrapper for XML_ParserFree, with the correct type
133    for make_cleanup.  */
134
135 static void
136 free_xml_parser (void *parser)
137 {
138   XML_ParserFree (parser);
139 }
140
141 /* Register a cleanup to release PARSER.  Only the parser itself
142    is freed; another cleanup may be necessary to discard any
143    associated user data.  */
144
145 void
146 make_cleanup_free_xml_parser (XML_Parser parser)
147 {
148   make_cleanup (free_xml_parser, parser);
149 }
150
151 #endif /* HAVE_LIBEXPAT */