tools/elf4rom/libs/dwarf-20071209/dwarfdump/esb.c
changeset 34 92d87f2e53c2
equal deleted inserted replaced
33:1af5c1be89f8 34:92d87f2e53c2
       
     1 /*
       
     2   Copyright (C) 2005 Silicon Graphics, Inc.  All Rights Reserved.
       
     3   This program is free software; you can redistribute it and/or modify it
       
     4   under the terms of version 2 of the GNU General Public License as
       
     5   published by the Free Software Foundation.
       
     6 
       
     7   This program is distributed in the hope that it would be useful, but
       
     8   WITHOUT ANY WARRANTY; without even the implied warranty of
       
     9   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
       
    10 
       
    11   Further, this software is distributed without any warranty that it is
       
    12   free of the rightful claim of any third person regarding infringement
       
    13   or the like.  Any license provided herein, whether implied or
       
    14   otherwise, applies only to this software file.  Patent licenses, if
       
    15   any, provided herein do not apply to combinations of this program with
       
    16   other software, or any other product whatsoever.
       
    17 
       
    18   You should have received a copy of the GNU General Public License along
       
    19   with this program; if not, write the Free Software Foundation, Inc., 51
       
    20   Franklin Street - Fifth Floor, Boston MA 02110-1301, USA.
       
    21 
       
    22   Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
       
    23   Mountain View, CA 94043, or:
       
    24 
       
    25   http://www.sgi.com
       
    26 
       
    27   For further information regarding this notice, see:
       
    28 
       
    29   http://oss.sgi.com/projects/GenInfo/NoticeExplan
       
    30 
       
    31 
       
    32 $Header: /plroot/cmplrs.src/v7.4.5m/.RCS/PL/dwarfdump/RCS/esb.c,v 1.1 2005/08/04 05:09:37 davea Exp $ */
       
    33 
       
    34 /* esb.c 
       
    35    extensible string buffer.
       
    36 
       
    37    A simple means (vaguely like a C++ class) that
       
    38    enables safely saving strings of arbitrary length built up
       
    39    in small pieces.
       
    40 
       
    41 */
       
    42 
       
    43 #include "globals.h"
       
    44 #include "esb.h"
       
    45 
       
    46 #define INITIAL_ALLOC 1024
       
    47 static size_t alloc_size = INITIAL_ALLOC;
       
    48 
       
    49 
       
    50 static void
       
    51 init_esb_string(struct esb_s *data, size_t min_len)
       
    52 {
       
    53     string d;
       
    54 
       
    55     if (data->esb_allocated_size > 0) {
       
    56 	return;
       
    57     }
       
    58     if (min_len < alloc_size) {
       
    59 	min_len = alloc_size;
       
    60     }
       
    61     d = malloc(min_len);
       
    62     if (!d) {
       
    63 	fprintf(stderr,
       
    64 		"dwarfdump is out of memory allocating %lu bytes\n",
       
    65 		(unsigned long) min_len);
       
    66 	exit(5);
       
    67     }
       
    68     data->esb_string = d;
       
    69     data->esb_allocated_size = min_len;
       
    70     data->esb_string[0] = 0;
       
    71     data->esb_used_bytes = 0;
       
    72 }
       
    73 
       
    74 /* Make more room. Leaving  contents unchanged, effectively.
       
    75 */
       
    76 static void
       
    77 allocate_more(struct esb_s *data, size_t len)
       
    78 {
       
    79     size_t new_size = data->esb_allocated_size + len;
       
    80     string newd = 0;
       
    81 
       
    82     if (new_size < alloc_size)
       
    83 	new_size = alloc_size;
       
    84     newd = realloc(data->esb_string, new_size);
       
    85     if (!newd) {
       
    86 	fprintf(stderr, "dwarfdump is out of memory re-allocating "
       
    87 		"%lu bytes\n", (unsigned long) new_size);
       
    88 	exit(5);
       
    89     }
       
    90     data->esb_string = newd;
       
    91     data->esb_allocated_size = new_size;
       
    92 }
       
    93 
       
    94 static void
       
    95   esb_appendn_internal(struct esb_s *data, string in_string, size_t len);
       
    96 
       
    97 void
       
    98 esb_appendn(struct esb_s *data, string in_string, size_t len)
       
    99 {
       
   100     size_t full_len = strlen(in_string);
       
   101 
       
   102     if (full_len < len) {
       
   103 	fprintf(stderr, "dwarfdump internal error, bad string length "
       
   104 		" %lu  < %lu \n",
       
   105 		(unsigned long) full_len, (unsigned long) len);
       
   106 	len = full_len;
       
   107     }
       
   108 
       
   109     esb_appendn_internal(data, in_string, len);
       
   110 }
       
   111 
       
   112 /* The length is gotten from the in_string itself. */
       
   113 void
       
   114 esb_append(struct esb_s *data, string in_string)
       
   115 {
       
   116     size_t len = strlen(in_string);
       
   117 
       
   118     esb_appendn_internal(data, in_string, len);
       
   119 }
       
   120 
       
   121 /* The 'len' is believed. Do not pass in strings < len bytes long. */
       
   122 static void
       
   123 esb_appendn_internal(struct esb_s *data, string in_string, size_t len)
       
   124 {
       
   125     size_t remaining = 0;
       
   126     size_t needed = len + 1;
       
   127 
       
   128     if (data->esb_allocated_size == 0) {
       
   129 	size_t maxlen = (len > alloc_size) ? len : alloc_size;
       
   130 
       
   131 	init_esb_string(data, maxlen);
       
   132     }
       
   133     remaining = data->esb_allocated_size - data->esb_used_bytes;
       
   134     if (remaining < needed) {
       
   135 	allocate_more(data, needed);
       
   136     }
       
   137     strncpy(&data->esb_string[data->esb_used_bytes], in_string, len);
       
   138     data->esb_used_bytes += len;
       
   139     /* Insist on explicit NUL terminator */
       
   140     data->esb_string[data->esb_used_bytes] = 0;
       
   141 }
       
   142 
       
   143 /* Always returns an empty string or a non-empty string. Never 0. */
       
   144 string
       
   145 esb_get_string(struct esb_s *data)
       
   146 {
       
   147     if (data->esb_allocated_size == 0) {
       
   148 	init_esb_string(data, alloc_size);
       
   149     }
       
   150     return data->esb_string;
       
   151 }
       
   152 
       
   153 
       
   154 /* Sets esb_used_bytes to zero. The string is not freed and
       
   155    esb_allocated_size is unchanged.  */
       
   156 void
       
   157 esb_empty_string(struct esb_s *data)
       
   158 {
       
   159     if (data->esb_allocated_size == 0) {
       
   160 	init_esb_string(data, alloc_size);
       
   161     }
       
   162     data->esb_used_bytes = 0;
       
   163     data->esb_string[0] = 0;
       
   164 
       
   165 }
       
   166 
       
   167 
       
   168 /* Return esb_used_bytes. */
       
   169 size_t
       
   170 esb_string_len(struct esb_s *data)
       
   171 {
       
   172     return data->esb_used_bytes;
       
   173 }
       
   174 
       
   175 
       
   176 /* The following are for testing esb, not use by dwarfdump. */
       
   177 
       
   178 /* *data is presumed to contain garbage, not values, and
       
   179    is properly initialized. */
       
   180 void
       
   181 esb_constructor(struct esb_s *data)
       
   182 {
       
   183     memset(data, 0, sizeof(*data));
       
   184 }
       
   185 
       
   186 /*  The string is freed, contents of *data set to zeroes. */
       
   187 void
       
   188 esb_destructor(struct esb_s *data)
       
   189 {
       
   190     if (data->esb_string) {
       
   191 	free(data->esb_string);
       
   192     }
       
   193     esb_constructor(data);
       
   194 }
       
   195 
       
   196 
       
   197 /* To get all paths in the code tested, this sets the
       
   198    allocation/reallocation to the given value, which can be quite small
       
   199    but must not be zero. */
       
   200 void
       
   201 esb_alloc_size(size_t size)
       
   202 {
       
   203     alloc_size = size;
       
   204 }
       
   205 
       
   206 size_t
       
   207 esb_get_allocated_size(struct esb_s *data)
       
   208 {
       
   209     return data->esb_allocated_size;
       
   210 }