xref: /netbsd-src/external/gpl3/gdb.old/dist/gdbsupport/buffer.cc (revision 6881a4007f077b54e5f51159c52b9b25f57deb0d)
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