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 25std::string 26xml_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 37void 38xml_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 += "'"; 46 break; 47 case '\"': 48 result += """; 49 break; 50 case '&': 51 result += "&"; 52 break; 53 case '<': 54 result += "<"; 55 break; 56 case '>': 57 result += ">"; 58 break; 59 default: 60 result += text[i]; 61 break; 62 } 63} 64 65/* See xml-utils.h. */ 66 67void 68string_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