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