17d62b00eSchristos /* A simple growing buffer for GDB. 27d62b00eSchristos 3*6881a400Schristos Copyright (C) 2009-2023 Free Software Foundation, Inc. 47d62b00eSchristos 57d62b00eSchristos This file is part of GDB. 67d62b00eSchristos 77d62b00eSchristos This program is free software; you can redistribute it and/or modify 87d62b00eSchristos it under the terms of the GNU General Public License as published by 97d62b00eSchristos the Free Software Foundation; either version 3 of the License, or 107d62b00eSchristos (at your option) any later version. 117d62b00eSchristos 127d62b00eSchristos This program is distributed in the hope that it will be useful, 137d62b00eSchristos but WITHOUT ANY WARRANTY; without even the implied warranty of 147d62b00eSchristos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 157d62b00eSchristos GNU General Public License for more details. 167d62b00eSchristos 177d62b00eSchristos You should have received a copy of the GNU General Public License 187d62b00eSchristos along with this program. If not, see <http://www.gnu.org/licenses/>. */ 197d62b00eSchristos 207d62b00eSchristos #include "common-defs.h" 217d62b00eSchristos #include "xml-utils.h" 227d62b00eSchristos #include "buffer.h" 237d62b00eSchristos #include "inttypes.h" 247d62b00eSchristos void 257d62b00eSchristos buffer_grow (struct buffer *buffer, const char *data, size_t size) 267d62b00eSchristos { 277d62b00eSchristos char *new_buffer; 287d62b00eSchristos size_t new_buffer_size; 297d62b00eSchristos 307d62b00eSchristos if (size == 0) 317d62b00eSchristos return; 327d62b00eSchristos 337d62b00eSchristos new_buffer_size = buffer->buffer_size; 347d62b00eSchristos 357d62b00eSchristos if (new_buffer_size == 0) 367d62b00eSchristos new_buffer_size = 1; 377d62b00eSchristos 387d62b00eSchristos while (buffer->used_size + size > new_buffer_size) 397d62b00eSchristos new_buffer_size *= 2; 407d62b00eSchristos new_buffer = (char *) xrealloc (buffer->buffer, new_buffer_size); 417d62b00eSchristos memcpy (new_buffer + buffer->used_size, data, size); 427d62b00eSchristos buffer->buffer = new_buffer; 437d62b00eSchristos buffer->buffer_size = new_buffer_size; 447d62b00eSchristos buffer->used_size += size; 457d62b00eSchristos } 467d62b00eSchristos 477d62b00eSchristos void 487d62b00eSchristos buffer_free (struct buffer *buffer) 497d62b00eSchristos { 507d62b00eSchristos if (!buffer) 517d62b00eSchristos return; 527d62b00eSchristos 537d62b00eSchristos xfree (buffer->buffer); 547d62b00eSchristos buffer->buffer = NULL; 557d62b00eSchristos buffer->buffer_size = 0; 567d62b00eSchristos buffer->used_size = 0; 577d62b00eSchristos } 587d62b00eSchristos 597d62b00eSchristos void 607d62b00eSchristos buffer_init (struct buffer *buffer) 617d62b00eSchristos { 627d62b00eSchristos memset (buffer, 0, sizeof (*buffer)); 637d62b00eSchristos } 647d62b00eSchristos 657d62b00eSchristos char* 667d62b00eSchristos buffer_finish (struct buffer *buffer) 677d62b00eSchristos { 687d62b00eSchristos char *ret = buffer->buffer; 697d62b00eSchristos buffer->buffer = NULL; 707d62b00eSchristos buffer->buffer_size = 0; 717d62b00eSchristos buffer->used_size = 0; 727d62b00eSchristos return ret; 737d62b00eSchristos } 747d62b00eSchristos 757d62b00eSchristos void 767d62b00eSchristos buffer_xml_printf (struct buffer *buffer, const char *format, ...) 777d62b00eSchristos { 787d62b00eSchristos va_list ap; 797d62b00eSchristos const char *f; 807d62b00eSchristos const char *prev; 817d62b00eSchristos int percent = 0; 827d62b00eSchristos 837d62b00eSchristos va_start (ap, format); 847d62b00eSchristos 857d62b00eSchristos prev = format; 867d62b00eSchristos for (f = format; *f; f++) 877d62b00eSchristos { 887d62b00eSchristos if (percent) 897d62b00eSchristos { 907d62b00eSchristos char buf[32]; 917d62b00eSchristos char *str = buf; 927d62b00eSchristos const char *f_old = f; 937d62b00eSchristos 947d62b00eSchristos switch (*f) 957d62b00eSchristos { 967d62b00eSchristos case 's': 977d62b00eSchristos str = va_arg (ap, char *); 987d62b00eSchristos break; 997d62b00eSchristos case 'd': 1007d62b00eSchristos sprintf (str, "%d", va_arg (ap, int)); 1017d62b00eSchristos break; 1027d62b00eSchristos case 'u': 1037d62b00eSchristos sprintf (str, "%u", va_arg (ap, unsigned int)); 1047d62b00eSchristos break; 1057d62b00eSchristos case 'x': 1067d62b00eSchristos sprintf (str, "%x", va_arg (ap, unsigned int)); 1077d62b00eSchristos break; 1087d62b00eSchristos case 'o': 1097d62b00eSchristos sprintf (str, "%o", va_arg (ap, unsigned int)); 1107d62b00eSchristos break; 1117d62b00eSchristos case 'l': 1127d62b00eSchristos f++; 1137d62b00eSchristos switch (*f) 1147d62b00eSchristos { 1157d62b00eSchristos case 'd': 1167d62b00eSchristos sprintf (str, "%ld", va_arg (ap, long)); 1177d62b00eSchristos break; 1187d62b00eSchristos case 'u': 1197d62b00eSchristos sprintf (str, "%lu", va_arg (ap, unsigned long)); 1207d62b00eSchristos break; 1217d62b00eSchristos case 'x': 1227d62b00eSchristos sprintf (str, "%lx", va_arg (ap, unsigned long)); 1237d62b00eSchristos break; 1247d62b00eSchristos case 'o': 1257d62b00eSchristos sprintf (str, "%lo", va_arg (ap, unsigned long)); 1267d62b00eSchristos break; 1277d62b00eSchristos case 'l': 1287d62b00eSchristos f++; 1297d62b00eSchristos switch (*f) 1307d62b00eSchristos { 1317d62b00eSchristos case 'd': 1327d62b00eSchristos sprintf (str, "%" PRId64, 1337d62b00eSchristos (int64_t) va_arg (ap, long long)); 1347d62b00eSchristos break; 1357d62b00eSchristos case 'u': 1367d62b00eSchristos sprintf (str, "%" PRIu64, 1377d62b00eSchristos (uint64_t) va_arg (ap, unsigned long long)); 1387d62b00eSchristos break; 1397d62b00eSchristos case 'x': 1407d62b00eSchristos sprintf (str, "%" PRIx64, 1417d62b00eSchristos (uint64_t) va_arg (ap, unsigned long long)); 1427d62b00eSchristos break; 1437d62b00eSchristos case 'o': 1447d62b00eSchristos sprintf (str, "%" PRIo64, 1457d62b00eSchristos (uint64_t) va_arg (ap, unsigned long long)); 1467d62b00eSchristos break; 1477d62b00eSchristos default: 1487d62b00eSchristos str = 0; 1497d62b00eSchristos break; 1507d62b00eSchristos } 1517d62b00eSchristos break; 1527d62b00eSchristos default: 1537d62b00eSchristos str = 0; 1547d62b00eSchristos break; 1557d62b00eSchristos } 1567d62b00eSchristos break; 1577d62b00eSchristos default: 1587d62b00eSchristos str = 0; 1597d62b00eSchristos break; 1607d62b00eSchristos } 1617d62b00eSchristos 1627d62b00eSchristos if (str) 1637d62b00eSchristos { 1647d62b00eSchristos buffer_grow (buffer, prev, f_old - prev - 1); 1657d62b00eSchristos std::string p = xml_escape_text (str); 1667d62b00eSchristos buffer_grow_str (buffer, p.c_str ()); 1677d62b00eSchristos prev = f + 1; 1687d62b00eSchristos } 1697d62b00eSchristos percent = 0; 1707d62b00eSchristos } 1717d62b00eSchristos else if (*f == '%') 1727d62b00eSchristos percent = 1; 1737d62b00eSchristos } 1747d62b00eSchristos 1757d62b00eSchristos buffer_grow_str (buffer, prev); 1767d62b00eSchristos va_end (ap); 1777d62b00eSchristos } 1787d62b00eSchristos 179