xref: /netbsd-src/external/gpl3/gdb/dist/gdbsupport/xml-utils.cc (revision 5ba1f45f2a09259cc846f20c7c5501604d633c90)
18dffb485Schristos /* Shared helper routines for manipulating XML.
28dffb485Schristos 
3*5ba1f45fSchristos    Copyright (C) 2006-2024 Free Software Foundation, Inc.
48dffb485Schristos 
58dffb485Schristos    This file is part of GDB.
68dffb485Schristos 
78dffb485Schristos    This program is free software; you can redistribute it and/or modify
88dffb485Schristos    it under the terms of the GNU General Public License as published by
98dffb485Schristos    the Free Software Foundation; either version 3 of the License, or
108dffb485Schristos    (at your option) any later version.
118dffb485Schristos 
128dffb485Schristos    This program is distributed in the hope that it will be useful,
138dffb485Schristos    but WITHOUT ANY WARRANTY; without even the implied warranty of
148dffb485Schristos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
158dffb485Schristos    GNU General Public License for more details.
168dffb485Schristos 
178dffb485Schristos    You should have received a copy of the GNU General Public License
188dffb485Schristos    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
198dffb485Schristos 
208dffb485Schristos #include "xml-utils.h"
218dffb485Schristos 
228dffb485Schristos /* See xml-utils.h.  */
238dffb485Schristos 
248dffb485Schristos std::string
258dffb485Schristos xml_escape_text (const char *text)
268dffb485Schristos {
278dffb485Schristos   std::string result;
288dffb485Schristos 
294b169a6bSchristos   xml_escape_text_append (result, text);
308dffb485Schristos 
318dffb485Schristos   return result;
328dffb485Schristos }
338dffb485Schristos 
348dffb485Schristos /* See xml-utils.h.  */
358dffb485Schristos 
368dffb485Schristos void
374b169a6bSchristos xml_escape_text_append (std::string &result, const char *text)
388dffb485Schristos {
398dffb485Schristos   /* Expand the result.  */
408dffb485Schristos   for (int i = 0; text[i] != '\0'; i++)
418dffb485Schristos     switch (text[i])
428dffb485Schristos       {
438dffb485Schristos       case '\'':
444b169a6bSchristos 	result += "&apos;";
458dffb485Schristos 	break;
468dffb485Schristos       case '\"':
474b169a6bSchristos 	result += "&quot;";
488dffb485Schristos 	break;
498dffb485Schristos       case '&':
504b169a6bSchristos 	result += "&amp;";
518dffb485Schristos 	break;
528dffb485Schristos       case '<':
534b169a6bSchristos 	result += "&lt;";
548dffb485Schristos 	break;
558dffb485Schristos       case '>':
564b169a6bSchristos 	result += "&gt;";
578dffb485Schristos 	break;
588dffb485Schristos       default:
594b169a6bSchristos 	result += text[i];
608dffb485Schristos 	break;
618dffb485Schristos       }
628dffb485Schristos }
634b169a6bSchristos 
644b169a6bSchristos /* See xml-utils.h.  */
654b169a6bSchristos 
664b169a6bSchristos void
674b169a6bSchristos string_xml_appendf (std::string &buffer, const char *format, ...)
684b169a6bSchristos {
694b169a6bSchristos   va_list ap;
704b169a6bSchristos   const char *f;
714b169a6bSchristos   const char *prev;
724b169a6bSchristos   int percent = 0;
734b169a6bSchristos 
744b169a6bSchristos   va_start (ap, format);
754b169a6bSchristos 
764b169a6bSchristos   prev = format;
774b169a6bSchristos   for (f = format; *f; f++)
784b169a6bSchristos     {
794b169a6bSchristos       if (percent)
804b169a6bSchristos 	{
814b169a6bSchristos 	  char buf[32];
824b169a6bSchristos 	  char *str = buf;
834b169a6bSchristos 	  const char *f_old = f;
844b169a6bSchristos 
854b169a6bSchristos 	  switch (*f)
864b169a6bSchristos 	    {
874b169a6bSchristos 	    case 's':
884b169a6bSchristos 	      str = va_arg (ap, char *);
894b169a6bSchristos 	      break;
904b169a6bSchristos 	    case 'd':
914b169a6bSchristos 	      sprintf (str, "%d", va_arg (ap, int));
924b169a6bSchristos 	      break;
934b169a6bSchristos 	    case 'u':
944b169a6bSchristos 	      sprintf (str, "%u", va_arg (ap, unsigned int));
954b169a6bSchristos 	      break;
964b169a6bSchristos 	    case 'x':
974b169a6bSchristos 	      sprintf (str, "%x", va_arg (ap, unsigned int));
984b169a6bSchristos 	      break;
994b169a6bSchristos 	    case 'o':
1004b169a6bSchristos 	      sprintf (str, "%o", va_arg (ap, unsigned int));
1014b169a6bSchristos 	      break;
1024b169a6bSchristos 	    case 'l':
1034b169a6bSchristos 	      f++;
1044b169a6bSchristos 	      switch (*f)
1054b169a6bSchristos 		{
1064b169a6bSchristos 		case 'd':
1074b169a6bSchristos 		  sprintf (str, "%ld", va_arg (ap, long));
1084b169a6bSchristos 		  break;
1094b169a6bSchristos 		case 'u':
1104b169a6bSchristos 		  sprintf (str, "%lu", va_arg (ap, unsigned long));
1114b169a6bSchristos 		  break;
1124b169a6bSchristos 		case 'x':
1134b169a6bSchristos 		  sprintf (str, "%lx", va_arg (ap, unsigned long));
1144b169a6bSchristos 		  break;
1154b169a6bSchristos 		case 'o':
1164b169a6bSchristos 		  sprintf (str, "%lo", va_arg (ap, unsigned long));
1174b169a6bSchristos 		  break;
1184b169a6bSchristos 		case 'l':
1194b169a6bSchristos 		  f++;
1204b169a6bSchristos 		  switch (*f)
1214b169a6bSchristos 		    {
1224b169a6bSchristos 		    case 'd':
1234b169a6bSchristos 		      sprintf (str, "%" PRId64,
1244b169a6bSchristos 			       (int64_t) va_arg (ap, long long));
1254b169a6bSchristos 		      break;
1264b169a6bSchristos 		    case 'u':
1274b169a6bSchristos 		      sprintf (str, "%" PRIu64,
1284b169a6bSchristos 			       (uint64_t) va_arg (ap, unsigned long long));
1294b169a6bSchristos 		      break;
1304b169a6bSchristos 		    case 'x':
1314b169a6bSchristos 		      sprintf (str, "%" PRIx64,
1324b169a6bSchristos 			       (uint64_t) va_arg (ap, unsigned long long));
1334b169a6bSchristos 		      break;
1344b169a6bSchristos 		    case 'o':
1354b169a6bSchristos 		      sprintf (str, "%" PRIo64,
1364b169a6bSchristos 			       (uint64_t) va_arg (ap, unsigned long long));
1374b169a6bSchristos 		      break;
1384b169a6bSchristos 		    default:
1394b169a6bSchristos 		      str = 0;
1404b169a6bSchristos 		      break;
1414b169a6bSchristos 		    }
1424b169a6bSchristos 		  break;
1434b169a6bSchristos 		default:
1444b169a6bSchristos 		  str = 0;
1454b169a6bSchristos 		  break;
1464b169a6bSchristos 		}
1474b169a6bSchristos 	      break;
1484b169a6bSchristos 	    default:
1494b169a6bSchristos 	      str = 0;
1504b169a6bSchristos 	      break;
1514b169a6bSchristos 	    }
1524b169a6bSchristos 
1534b169a6bSchristos 	  if (str)
1544b169a6bSchristos 	    {
1554b169a6bSchristos 	      buffer.append (prev, f_old - prev - 1);
1564b169a6bSchristos 	      xml_escape_text_append (buffer, str);
1574b169a6bSchristos 	      prev = f + 1;
1584b169a6bSchristos 	    }
1594b169a6bSchristos 	  percent = 0;
1604b169a6bSchristos 	}
1614b169a6bSchristos       else if (*f == '%')
1624b169a6bSchristos 	percent = 1;
1634b169a6bSchristos     }
1644b169a6bSchristos 
1654b169a6bSchristos   buffer.append (prev);
1664b169a6bSchristos   va_end (ap);
1674b169a6bSchristos }
168