xref: /netbsd-src/external/gpl3/gdb.old/dist/gdbsupport/buffer.cc (revision d16b7486a53dcb8072b60ec6fcb4373a2d0c27b7)
1 /* A simple growing buffer for GDB.
2 
3    Copyright (C) 2009-2020 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 #include "buffer.h"
23 #include "inttypes.h"
24 void
25 buffer_grow (struct buffer *buffer, const char *data, size_t size)
26 {
27   char *new_buffer;
28   size_t new_buffer_size;
29 
30   if (size == 0)
31     return;
32 
33   new_buffer_size = buffer->buffer_size;
34 
35   if (new_buffer_size == 0)
36     new_buffer_size = 1;
37 
38   while (buffer->used_size + size > new_buffer_size)
39     new_buffer_size *= 2;
40   new_buffer = (char *) xrealloc (buffer->buffer, new_buffer_size);
41   memcpy (new_buffer + buffer->used_size, data, size);
42   buffer->buffer = new_buffer;
43   buffer->buffer_size = new_buffer_size;
44   buffer->used_size += size;
45 }
46 
47 void
48 buffer_free (struct buffer *buffer)
49 {
50   if (!buffer)
51     return;
52 
53   xfree (buffer->buffer);
54   buffer->buffer = NULL;
55   buffer->buffer_size = 0;
56   buffer->used_size = 0;
57 }
58 
59 void
60 buffer_init (struct buffer *buffer)
61 {
62   memset (buffer, 0, sizeof (*buffer));
63 }
64 
65 char*
66 buffer_finish (struct buffer *buffer)
67 {
68   char *ret = buffer->buffer;
69   buffer->buffer = NULL;
70   buffer->buffer_size = 0;
71   buffer->used_size = 0;
72   return ret;
73 }
74 
75 void
76 buffer_xml_printf (struct buffer *buffer, const char *format, ...)
77 {
78   va_list ap;
79   const char *f;
80   const char *prev;
81   int percent = 0;
82 
83   va_start (ap, format);
84 
85   prev = format;
86   for (f = format; *f; f++)
87     {
88       if (percent)
89 	{
90 	  char buf[32];
91 	  char *str = buf;
92 	  const char *f_old = f;
93 
94 	  switch (*f)
95 	    {
96 	    case 's':
97 	      str = va_arg (ap, char *);
98 	      break;
99 	    case 'd':
100 	      sprintf (str, "%d", va_arg (ap, int));
101 	      break;
102 	    case 'u':
103 	      sprintf (str, "%u", va_arg (ap, unsigned int));
104 	      break;
105 	    case 'x':
106 	      sprintf (str, "%x", va_arg (ap, unsigned int));
107 	      break;
108 	    case 'o':
109 	      sprintf (str, "%o", va_arg (ap, unsigned int));
110 	      break;
111 	    case 'l':
112 	      f++;
113 	      switch (*f)
114 		{
115 		case 'd':
116 		  sprintf (str, "%ld", va_arg (ap, long));
117 		  break;
118 		case 'u':
119 		  sprintf (str, "%lu", va_arg (ap, unsigned long));
120 		  break;
121 		case 'x':
122 		  sprintf (str, "%lx", va_arg (ap, unsigned long));
123 		  break;
124 		case 'o':
125 		  sprintf (str, "%lo", va_arg (ap, unsigned long));
126 		  break;
127 		case 'l':
128 		  f++;
129 		  switch (*f)
130 		    {
131 		    case 'd':
132 		      sprintf (str, "%" PRId64,
133 			       (int64_t) va_arg (ap, long long));
134 		      break;
135 		    case 'u':
136 		      sprintf (str, "%" PRIu64,
137 			       (uint64_t) va_arg (ap, unsigned long long));
138 		      break;
139 		    case 'x':
140 		      sprintf (str, "%" PRIx64,
141 			       (uint64_t) va_arg (ap, unsigned long long));
142 		      break;
143 		    case 'o':
144 		      sprintf (str, "%" PRIo64,
145 			       (uint64_t) va_arg (ap, unsigned long long));
146 		      break;
147 		    default:
148 		      str = 0;
149 		      break;
150 		    }
151 		  break;
152 		default:
153 		  str = 0;
154 		  break;
155 		}
156 	      break;
157 	    default:
158 	      str = 0;
159 	      break;
160 	    }
161 
162 	  if (str)
163 	    {
164 	      buffer_grow (buffer, prev, f_old - prev - 1);
165 	      std::string p = xml_escape_text (str);
166 	      buffer_grow_str (buffer, p.c_str ());
167 	      prev = f + 1;
168 	    }
169 	  percent = 0;
170 	}
171       else if (*f == '%')
172 	percent = 1;
173     }
174 
175   buffer_grow_str (buffer, prev);
176   va_end (ap);
177 }
178 
179