summaryrefslogtreecommitdiff
path: root/dwarfdump/esb.c
diff options
context:
space:
mode:
Diffstat (limited to 'dwarfdump/esb.c')
-rw-r--r--dwarfdump/esb.c242
1 files changed, 242 insertions, 0 deletions
diff --git a/dwarfdump/esb.c b/dwarfdump/esb.c
new file mode 100644
index 0000000..8c806c8
--- /dev/null
+++ b/dwarfdump/esb.c
@@ -0,0 +1,242 @@
+/*
+ Copyright (C) 2005 Silicon Graphics, Inc. All Rights Reserved.
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of version 2 of the GNU General Public License as
+ published by the Free Software Foundation.
+
+ This program is distributed in the hope that it would be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+ Further, this software is distributed without any warranty that it is
+ free of the rightful claim of any third person regarding infringement
+ or the like. Any license provided herein, whether implied or
+ otherwise, applies only to this software file. Patent licenses, if
+ any, provided herein do not apply to combinations of this program with
+ other software, or any other product whatsoever.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write the Free Software Foundation, Inc., 51
+ Franklin Street - Fifth Floor, Boston MA 02110-1301, USA.
+
+ Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane,
+ Mountain View, CA 94043, or:
+
+ http://www.sgi.com
+
+ For further information regarding this notice, see:
+
+ http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+
+$Header: /plroot/cmplrs.src/v7.4.5m/.RCS/PL/dwarfdump/RCS/esb.c,v 1.1 2005/08/04 05:09:37 davea Exp $ */
+
+/* esb.c
+ extensible string buffer.
+
+ A simple means (vaguely like a C++ class) that
+ enables safely saving strings of arbitrary length built up
+ in small pieces.
+
+*/
+
+#include "globals.h"
+#include <stdarg.h> /* For va_start etc. */
+#include "esb.h"
+
+#define INITIAL_ALLOC 1024
+static size_t alloc_size = INITIAL_ALLOC;
+
+
+static void
+init_esb_string(struct esb_s *data, size_t min_len)
+{
+ string d;
+
+ if (data->esb_allocated_size > 0) {
+ return;
+ }
+ if (min_len < alloc_size) {
+ min_len = alloc_size;
+ }
+ d = malloc(min_len);
+ if (!d) {
+ fprintf(stderr,
+ "dwarfdump is out of memory allocating %lu bytes\n",
+ (unsigned long) min_len);
+ exit(5);
+ }
+ data->esb_string = d;
+ data->esb_allocated_size = min_len;
+ data->esb_string[0] = 0;
+ data->esb_used_bytes = 0;
+}
+
+/* Make more room. Leaving contents unchanged, effectively.
+*/
+static void
+allocate_more(struct esb_s *data, size_t len)
+{
+ size_t new_size = data->esb_allocated_size + len;
+ string newd = 0;
+
+ if (new_size < alloc_size)
+ new_size = alloc_size;
+ newd = realloc(data->esb_string, new_size);
+ if (!newd) {
+ fprintf(stderr, "dwarfdump is out of memory re-allocating "
+ "%lu bytes\n", (unsigned long) new_size);
+ exit(5);
+ }
+ data->esb_string = newd;
+ data->esb_allocated_size = new_size;
+}
+
+static void
+esb_appendn_internal(struct esb_s *data, const char * in_string, size_t len);
+
+void
+esb_appendn(struct esb_s *data, const char * in_string, size_t len)
+{
+ size_t full_len = strlen(in_string);
+
+ if (full_len < len) {
+ fprintf(stderr, "dwarfdump internal error, bad string length "
+ " %lu < %lu \n",
+ (unsigned long) full_len, (unsigned long) len);
+ len = full_len;
+ }
+
+ esb_appendn_internal(data, in_string, len);
+}
+
+/* The length is gotten from the in_string itself. */
+void
+esb_append(struct esb_s *data, const char * in_string)
+{
+ size_t len = strlen(in_string);
+
+ esb_appendn_internal(data, in_string, len);
+}
+
+/* The 'len' is believed. Do not pass in strings < len bytes long. */
+static void
+esb_appendn_internal(struct esb_s *data, const char * in_string, size_t len)
+{
+ size_t remaining = 0;
+ size_t needed = len + 1;
+
+ if (data->esb_allocated_size == 0) {
+ size_t maxlen = (len > alloc_size) ? len : alloc_size;
+
+ init_esb_string(data, maxlen);
+ }
+ remaining = data->esb_allocated_size - data->esb_used_bytes;
+ if (remaining < needed) {
+ allocate_more(data, needed);
+ }
+ strncpy(&data->esb_string[data->esb_used_bytes], in_string, len);
+ data->esb_used_bytes += len;
+ /* Insist on explicit NUL terminator */
+ data->esb_string[data->esb_used_bytes] = 0;
+}
+
+/* Always returns an empty string or a non-empty string. Never 0. */
+string
+esb_get_string(struct esb_s *data)
+{
+ if (data->esb_allocated_size == 0) {
+ init_esb_string(data, alloc_size);
+ }
+ return data->esb_string;
+}
+
+
+/* Sets esb_used_bytes to zero. The string is not freed and
+ esb_allocated_size is unchanged. */
+void
+esb_empty_string(struct esb_s *data)
+{
+ if (data->esb_allocated_size == 0) {
+ init_esb_string(data, alloc_size);
+ }
+ data->esb_used_bytes = 0;
+ data->esb_string[0] = 0;
+
+}
+
+
+/* Return esb_used_bytes. */
+size_t
+esb_string_len(struct esb_s *data)
+{
+ return data->esb_used_bytes;
+}
+
+
+/* The following are for testing esb, not use by dwarfdump. */
+
+/* *data is presumed to contain garbage, not values, and
+ is properly initialized. */
+void
+esb_constructor(struct esb_s *data)
+{
+ memset(data, 0, sizeof(*data));
+}
+
+/* The string is freed, contents of *data set to zeroes. */
+void
+esb_destructor(struct esb_s *data)
+{
+ if (data->esb_string) {
+ free(data->esb_string);
+ }
+ esb_constructor(data);
+}
+
+
+/* To get all paths in the code tested, this sets the
+ allocation/reallocation to the given value, which can be quite small
+ but must not be zero. */
+void
+esb_alloc_size(size_t size)
+{
+ alloc_size = size;
+}
+
+size_t
+esb_get_allocated_size(struct esb_s *data)
+{
+ return data->esb_allocated_size;
+}
+
+/* Append a formatted string */
+void
+esb_append_printf(struct esb_s *data,const char *in_string, ...)
+{
+#if WIN32
+ #define NULL_DEVICE_FILE "NUL"
+#else
+ #define NULL_DEVICE_FILE "/dev/null"
+#endif /* WIN32 */
+
+ static FILE *null_file = NULL;
+
+ int needed_size = 0;
+ int length = 0;
+ va_list ap;
+ va_start(ap,in_string);
+ if (null_file == NULL) {
+ null_file = fopen(NULL_DEVICE_FILE,"w");
+ }
+ length = vfprintf(null_file,in_string,ap);
+
+ /* Check if we require allocate more space */
+ needed_size = data->esb_used_bytes + length;
+ if (needed_size > data->esb_allocated_size) {
+ allocate_more(data,length);
+ }
+ vsprintf(&data->esb_string[data->esb_used_bytes],in_string,ap);
+ data->esb_used_bytes += length;
+ va_end(ap);
+}