+2018-06-18 Tom Tromey <tom@tromey.com>
+
+ * valprint.h (read_string): Update.
+ * valprint.c (read_string): Change type of "buffer".
+ (val_print_string): Update.
+ * python/py-value.c (valpy_string): Update.
+ * language.h (struct language_defn) <la_get_string>: Change
+ type of "buffer".
+ (default_get_string, c_get_string): Update.
+ * language.c (default_get_string): Change type of "buffer".
+ * guile/scm-value.c (gdbscm_value_to_string): Update.
+ * c-lang.c (c_get_string): Change type of "buffer".
+
2018-06-18 Tom Tromey <tom@tromey.com>
* ser-mingw.c (struct pipe_state_destroyer): New.
target charset. */
void
-c_get_string (struct value *value, gdb_byte **buffer,
+c_get_string (struct value *value, gdb::unique_xmalloc_ptr<gdb_byte> *buffer,
int *length, struct type **char_type,
const char **charset)
{
/* I is now either a user-defined length, the number of non-null
characters, or FETCHLIMIT. */
*length = i * width;
- *buffer = (gdb_byte *) xmalloc (*length);
- memcpy (*buffer, contents, *length);
+ buffer->reset ((gdb_byte *) xmalloc (*length));
+ memcpy (buffer->get (), contents, *length);
err = 0;
}
else
err = read_string (addr, *length, width, fetchlimit,
byte_order, buffer, length);
if (err != 0)
- {
- xfree (*buffer);
- memory_error (TARGET_XFER_E_IO, addr);
- }
+ memory_error (TARGET_XFER_E_IO, addr);
}
/* If the LENGTH is specified at -1, we want to return the string
if (req_length == -1)
/* If the last character is null, subtract it from LENGTH. */
if (*length > 0
- && extract_unsigned_integer (*buffer + *length - width,
+ && extract_unsigned_integer (buffer->get () + *length - width,
width, byte_order) == 0)
*length -= width;
char *encoding = NULL;
SCM errors = SCM_BOOL_F;
int length = -1;
- gdb_byte *buffer = NULL;
+ gdb::unique_xmalloc_ptr<gdb_byte> buffer;
const char *la_encoding = NULL;
struct type *char_type = NULL;
SCM result;
scm_dynwind_begin ((scm_t_dynwind_flags) 0);
gdbscm_dynwind_xfree (encoding);
- gdbscm_dynwind_xfree (buffer);
+ gdb_byte *buffer_contents = buffer.release ();
+ gdbscm_dynwind_xfree (buffer_contents);
- result = scm_from_stringn ((const char *) buffer,
+ result = scm_from_stringn ((const char *) buffer_contents,
length * TYPE_LENGTH (char_type),
(encoding != NULL && *encoding != '\0'
? encoding
}
void
-default_get_string (struct value *value, gdb_byte **buffer, int *length,
- struct type **char_type, const char **charset)
+default_get_string (struct value *value,
+ gdb::unique_xmalloc_ptr<gdb_byte> *buffer,
+ int *length, struct type **char_type, const char **charset)
{
error (_("Getting a string is unsupported in this language."));
}
characters, excluding any eventual terminating null character.
Otherwise *LENGTH will include all characters - including any nulls.
CHARSET will hold the encoding used in the string. */
- void (*la_get_string) (struct value *value, gdb_byte **buffer, int *length,
- struct type **chartype, const char **charset);
+ void (*la_get_string) (struct value *value,
+ gdb::unique_xmalloc_ptr<gdb_byte> *buffer,
+ int *length, struct type **chartype,
+ const char **charset);
/* Return an expression that can be used for a location
watchpoint. TYPE is a pointer type that points to the memory
void default_print_typedef (struct type *type, struct symbol *new_symbol,
struct ui_file *stream);
-void default_get_string (struct value *value, gdb_byte **buffer, int *length,
- struct type **char_type, const char **charset);
+void default_get_string (struct value *value,
+ gdb::unique_xmalloc_ptr<gdb_byte> *buffer,
+ int *length, struct type **char_type,
+ const char **charset);
/* Default name hashing function. */
comparison operators hash to the same value. */
extern unsigned int default_search_name_hash (const char *search_name);
-void c_get_string (struct value *value, gdb_byte **buffer, int *length,
- struct type **char_type, const char **charset);
+void c_get_string (struct value *value,
+ gdb::unique_xmalloc_ptr<gdb_byte> *buffer,
+ int *length, struct type **char_type,
+ const char **charset);
/* The default implementation of la_symbol_name_matcher. Matches with
strncmp_iw. */
valpy_string (PyObject *self, PyObject *args, PyObject *kw)
{
int length = -1;
- gdb_byte *buffer;
+ gdb::unique_xmalloc_ptr<gdb_byte> buffer;
struct value *value = ((value_object *) self)->value;
- PyObject *unicode;
const char *encoding = NULL;
const char *errors = NULL;
const char *user_encoding = NULL;
END_CATCH
encoding = (user_encoding && *user_encoding) ? user_encoding : la_encoding;
- unicode = PyUnicode_Decode ((const char *) buffer,
- length * TYPE_LENGTH (char_type),
- encoding, errors);
- xfree (buffer);
-
- return unicode;
+ return PyUnicode_Decode ((const char *) buffer.get (),
+ length * TYPE_LENGTH (char_type),
+ encoding, errors);
}
/* A helper function that implements the various cast operators. */
return (nread);
}
-/* Read a string from the inferior, at ADDR, with LEN characters of WIDTH bytes
- each. Fetch at most FETCHLIMIT characters. BUFFER will be set to a newly
- allocated buffer containing the string, which the caller is responsible to
- free, and BYTES_READ will be set to the number of bytes read. Returns 0 on
+/* Read a string from the inferior, at ADDR, with LEN characters of
+ WIDTH bytes each. Fetch at most FETCHLIMIT characters. BUFFER
+ will be set to a newly allocated buffer containing the string, and
+ BYTES_READ will be set to the number of bytes read. Returns 0 on
success, or a target_xfer_status on failure.
If LEN > 0, reads the lesser of LEN or FETCHLIMIT characters
int
read_string (CORE_ADDR addr, int len, int width, unsigned int fetchlimit,
- enum bfd_endian byte_order, gdb_byte **buffer, int *bytes_read)
+ enum bfd_endian byte_order, gdb::unique_xmalloc_ptr<gdb_byte> *buffer,
+ int *bytes_read)
{
int errcode; /* Errno returned from bad reads. */
unsigned int nfetch; /* Chars to fetch / chars fetched. */
gdb_byte *bufptr; /* Pointer to next available byte in
buffer. */
- struct cleanup *old_chain = NULL; /* Top of the old cleanup chain. */
/* Loop until we either have all the characters, or we encounter
some error, such as bumping into the end of the address space. */
- *buffer = NULL;
-
- old_chain = make_cleanup (free_current_contents, buffer);
+ buffer->reset (nullptr);
if (len > 0)
{
one operation. */
unsigned int fetchlen = std::min ((unsigned) len, fetchlimit);
- *buffer = (gdb_byte *) xmalloc (fetchlen * width);
- bufptr = *buffer;
+ buffer->reset ((gdb_byte *) xmalloc (fetchlen * width));
+ bufptr = buffer->get ();
nfetch = partial_memory_read (addr, bufptr, fetchlen * width, &errcode)
/ width;
nfetch = std::min ((unsigned long) chunksize, fetchlimit - bufsize);
if (*buffer == NULL)
- *buffer = (gdb_byte *) xmalloc (nfetch * width);
+ buffer->reset ((gdb_byte *) xmalloc (nfetch * width));
else
- *buffer = (gdb_byte *) xrealloc (*buffer,
- (nfetch + bufsize) * width);
+ buffer->reset ((gdb_byte *) xrealloc (buffer->release (),
+ (nfetch + bufsize) * width));
- bufptr = *buffer + bufsize * width;
+ bufptr = buffer->get () + bufsize * width;
bufsize += nfetch;
/* Read as much as we can. */
}
}
while (errcode == 0 /* no error */
- && bufptr - *buffer < fetchlimit * width /* no overrun */
+ && bufptr - buffer->get () < fetchlimit * width /* no overrun */
&& !found_nul); /* haven't found NUL yet */
}
else
{ /* Length of string is really 0! */
/* We always allocate *buffer. */
- *buffer = bufptr = (gdb_byte *) xmalloc (1);
+ buffer->reset ((gdb_byte *) xmalloc (1));
+ bufptr = buffer->get ();
errcode = 0;
}
/* bufptr and addr now point immediately beyond the last byte which we
consider part of the string (including a '\0' which ends the string). */
- *bytes_read = bufptr - *buffer;
+ *bytes_read = bufptr - buffer->get ();
QUIT;
- discard_cleanups (old_chain);
-
return errcode;
}
int found_nul; /* Non-zero if we found the nul char. */
unsigned int fetchlimit; /* Maximum number of chars to print. */
int bytes_read;
- gdb_byte *buffer = NULL; /* Dynamically growable fetch buffer. */
- struct cleanup *old_chain = NULL; /* Top of the old cleanup chain. */
+ gdb::unique_xmalloc_ptr<gdb_byte> buffer; /* Dynamically growable fetch buffer. */
struct gdbarch *gdbarch = get_type_arch (elttype);
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
int width = TYPE_LENGTH (elttype);
err = read_string (addr, len, width, fetchlimit, byte_order,
&buffer, &bytes_read);
- old_chain = make_cleanup (xfree, buffer);
addr += bytes_read;
/* Determine found_nul by looking at the last character read. */
found_nul = 0;
if (bytes_read >= width)
- found_nul = extract_unsigned_integer (buffer + bytes_read - width, width,
- byte_order) == 0;
+ found_nul = extract_unsigned_integer (buffer.get () + bytes_read - width,
+ width, byte_order) == 0;
if (len == -1 && !found_nul)
{
gdb_byte *peekbuf;
and then the error message. */
if (err == 0 || bytes_read > 0)
{
- LA_PRINT_STRING (stream, elttype, buffer, bytes_read / width,
+ LA_PRINT_STRING (stream, elttype, buffer.get (), bytes_read / width,
encoding, force_ellipsis, options);
}
}
gdb_flush (stream);
- do_cleanups (old_chain);
return (bytes_read / width);
}
extern int read_string (CORE_ADDR addr, int len, int width,
unsigned int fetchlimit,
- enum bfd_endian byte_order, gdb_byte **buffer,
+ enum bfd_endian byte_order,
+ gdb::unique_xmalloc_ptr<gdb_byte> *buffer,
int *bytes_read);
extern void val_print_optimized_out (const struct value *val,