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 += "'"; 458dffb485Schristos break; 468dffb485Schristos case '\"': 474b169a6bSchristos result += """; 488dffb485Schristos break; 498dffb485Schristos case '&': 504b169a6bSchristos result += "&"; 518dffb485Schristos break; 528dffb485Schristos case '<': 534b169a6bSchristos result += "<"; 548dffb485Schristos break; 558dffb485Schristos case '>': 564b169a6bSchristos result += ">"; 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