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 += "'"; 45 break; 46 case '\"': 47 result += """; 48 break; 49 case '&': 50 result += "&"; 51 break; 52 case '<': 53 result += "<"; 54 break; 55 case '>': 56 result += ">"; 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