xref: /netbsd-src/external/gpl3/gdb.old/dist/gdbsupport/xml-utils.cc (revision 8e33eff89e26cf71871ead62f0d5063e1313c33a)
1 /* Shared helper routines for manipulating XML.
2 
3    Copyright (C) 2006-2023 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 "common-defs.h"
21 #include "xml-utils.h"
22 
23 /* See xml-utils.h.  */
24 
25 std::string
26 xml_escape_text (const char *text)
27 {
28   std::string result;
29 
30   xml_escape_text_append (result, text);
31 
32   return result;
33 }
34 
35 /* See xml-utils.h.  */
36 
37 void
38 xml_escape_text_append (std::string &result, const char *text)
39 {
40   /* Expand the result.  */
41   for (int i = 0; text[i] != '\0'; i++)
42     switch (text[i])
43       {
44       case '\'':
45 	result += "&apos;";
46 	break;
47       case '\"':
48 	result += "&quot;";
49 	break;
50       case '&':
51 	result += "&amp;";
52 	break;
53       case '<':
54 	result += "&lt;";
55 	break;
56       case '>':
57 	result += "&gt;";
58 	break;
59       default:
60 	result += text[i];
61 	break;
62       }
63 }
64 
65 /* See xml-utils.h.  */
66 
67 void
68 string_xml_appendf (std::string &buffer, const char *format, ...)
69 {
70   va_list ap;
71   const char *f;
72   const char *prev;
73   int percent = 0;
74 
75   va_start (ap, format);
76 
77   prev = format;
78   for (f = format; *f; f++)
79     {
80       if (percent)
81 	{
82 	  char buf[32];
83 	  char *str = buf;
84 	  const char *f_old = f;
85 
86 	  switch (*f)
87 	    {
88 	    case 's':
89 	      str = va_arg (ap, char *);
90 	      break;
91 	    case 'd':
92 	      sprintf (str, "%d", va_arg (ap, int));
93 	      break;
94 	    case 'u':
95 	      sprintf (str, "%u", va_arg (ap, unsigned int));
96 	      break;
97 	    case 'x':
98 	      sprintf (str, "%x", va_arg (ap, unsigned int));
99 	      break;
100 	    case 'o':
101 	      sprintf (str, "%o", va_arg (ap, unsigned int));
102 	      break;
103 	    case 'l':
104 	      f++;
105 	      switch (*f)
106 		{
107 		case 'd':
108 		  sprintf (str, "%ld", va_arg (ap, long));
109 		  break;
110 		case 'u':
111 		  sprintf (str, "%lu", va_arg (ap, unsigned long));
112 		  break;
113 		case 'x':
114 		  sprintf (str, "%lx", va_arg (ap, unsigned long));
115 		  break;
116 		case 'o':
117 		  sprintf (str, "%lo", va_arg (ap, unsigned long));
118 		  break;
119 		case 'l':
120 		  f++;
121 		  switch (*f)
122 		    {
123 		    case 'd':
124 		      sprintf (str, "%" PRId64,
125 			       (int64_t) va_arg (ap, long long));
126 		      break;
127 		    case 'u':
128 		      sprintf (str, "%" PRIu64,
129 			       (uint64_t) va_arg (ap, unsigned long long));
130 		      break;
131 		    case 'x':
132 		      sprintf (str, "%" PRIx64,
133 			       (uint64_t) va_arg (ap, unsigned long long));
134 		      break;
135 		    case 'o':
136 		      sprintf (str, "%" PRIo64,
137 			       (uint64_t) va_arg (ap, unsigned long long));
138 		      break;
139 		    default:
140 		      str = 0;
141 		      break;
142 		    }
143 		  break;
144 		default:
145 		  str = 0;
146 		  break;
147 		}
148 	      break;
149 	    default:
150 	      str = 0;
151 	      break;
152 	    }
153 
154 	  if (str)
155 	    {
156 	      buffer.append (prev, f_old - prev - 1);
157 	      xml_escape_text_append (buffer, str);
158 	      prev = f + 1;
159 	    }
160 	  percent = 0;
161 	}
162       else if (*f == '%')
163 	percent = 1;
164     }
165 
166   buffer.append (prev);
167   va_end (ap);
168 }
169