~ubuntu-branches/ubuntu/hoary/binutils/hoary

« back to all changes in this revision

Viewing changes to gas/sb.c

  • Committer: Bazaar Package Importer
  • Author(s): James Troup
  • Date: 2004-05-19 10:35:44 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20040519103544-17h3o6e8pwndydrg
Tags: 2.14.90.0.7-8
debian/rules: don't use gcc-2.95 on m68k.  Thanks to Adam Conrad for
pointing this out.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* sb.c - string buffer manipulation routines
 
2
   Copyright 1994, 1995, 2000 Free Software Foundation, Inc.
 
3
 
 
4
   Written by Steve and Judy Chamberlain of Cygnus Support,
 
5
      sac@cygnus.com
 
6
 
 
7
   This file is part of GAS, the GNU Assembler.
 
8
 
 
9
   GAS is free software; you can redistribute it and/or modify
 
10
   it under the terms of the GNU General Public License as published by
 
11
   the Free Software Foundation; either version 2, or (at your option)
 
12
   any later version.
 
13
 
 
14
   GAS is distributed in the hope that it will be useful,
 
15
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
16
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
17
   GNU General Public License for more details.
 
18
 
 
19
   You should have received a copy of the GNU General Public License
 
20
   along with GAS; see the file COPYING.  If not, write to the Free
 
21
   Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 
22
   02111-1307, USA.  */
 
23
 
 
24
#include "config.h"
 
25
#include <stdio.h>
 
26
#ifdef HAVE_STDLIB_H
 
27
#include <stdlib.h>
 
28
#endif
 
29
#ifdef HAVE_STRING_H
 
30
#include <string.h>
 
31
#else
 
32
#include <strings.h>
 
33
#endif
 
34
#include "libiberty.h"
 
35
#include "sb.h"
 
36
 
 
37
/* These routines are about manipulating strings.
 
38
 
 
39
   They are managed in things called `sb's which is an abbreviation
 
40
   for string buffers.  An sb has to be created, things can be glued
 
41
   on to it, and at the end of it's life it should be freed.  The
 
42
   contents should never be pointed at whilst it is still growing,
 
43
   since it could be moved at any time
 
44
 
 
45
   eg:
 
46
   sb_new (&foo);
 
47
   sb_grow... (&foo,...);
 
48
   use foo->ptr[*];
 
49
   sb_kill (&foo);
 
50
 
 
51
*/
 
52
 
 
53
#define dsize 5
 
54
 
 
55
static void sb_check PARAMS ((sb *, int));
 
56
 
 
57
/* Statistics of sb structures.  */
 
58
 
 
59
int string_count[sb_max_power_two];
 
60
 
 
61
/* Free list of sb structures.  */
 
62
 
 
63
static sb_list_vector free_list;
 
64
 
 
65
/* initializes an sb.  */
 
66
 
 
67
void
 
68
sb_build (ptr, size)
 
69
     sb *ptr;
 
70
     int size;
 
71
{
 
72
  /* see if we can find one to allocate */
 
73
  sb_element *e;
 
74
 
 
75
  if (size > sb_max_power_two)
 
76
    abort ();
 
77
 
 
78
  e = free_list.size[size];
 
79
  if (!e)
 
80
    {
 
81
      /* nothing there, allocate one and stick into the free list */
 
82
      e = (sb_element *) xmalloc (sizeof (sb_element) + (1 << size));
 
83
      e->next = free_list.size[size];
 
84
      e->size = 1 << size;
 
85
      free_list.size[size] = e;
 
86
      string_count[size]++;
 
87
    }
 
88
 
 
89
  /* remove from free list */
 
90
 
 
91
  free_list.size[size] = e->next;
 
92
 
 
93
  /* copy into callers world */
 
94
  ptr->ptr = e->data;
 
95
  ptr->pot = size;
 
96
  ptr->len = 0;
 
97
  ptr->item = e;
 
98
}
 
99
 
 
100
void
 
101
sb_new (ptr)
 
102
     sb *ptr;
 
103
{
 
104
  sb_build (ptr, dsize);
 
105
}
 
106
 
 
107
/* deallocate the sb at ptr */
 
108
 
 
109
void
 
110
sb_kill (ptr)
 
111
     sb *ptr;
 
112
{
 
113
  /* return item to free list */
 
114
  ptr->item->next = free_list.size[ptr->pot];
 
115
  free_list.size[ptr->pot] = ptr->item;
 
116
}
 
117
 
 
118
/* add the sb at s to the end of the sb at ptr */
 
119
 
 
120
void
 
121
sb_add_sb (ptr, s)
 
122
     sb *ptr;
 
123
     sb *s;
 
124
{
 
125
  sb_check (ptr, s->len);
 
126
  memcpy (ptr->ptr + ptr->len, s->ptr, s->len);
 
127
  ptr->len += s->len;
 
128
}
 
129
 
 
130
/* make sure that the sb at ptr has room for another len characters,
 
131
   and grow it if it doesn't.  */
 
132
 
 
133
static void
 
134
sb_check (ptr, len)
 
135
     sb *ptr;
 
136
     int len;
 
137
{
 
138
  if (ptr->len + len >= 1 << ptr->pot)
 
139
    {
 
140
      sb tmp;
 
141
      int pot = ptr->pot;
 
142
      while (ptr->len + len >= 1 << pot)
 
143
        pot++;
 
144
      sb_build (&tmp, pot);
 
145
      sb_add_sb (&tmp, ptr);
 
146
      sb_kill (ptr);
 
147
      *ptr = tmp;
 
148
    }
 
149
}
 
150
 
 
151
/* make the sb at ptr point back to the beginning.  */
 
152
 
 
153
void
 
154
sb_reset (ptr)
 
155
     sb *ptr;
 
156
{
 
157
  ptr->len = 0;
 
158
}
 
159
 
 
160
/* add character c to the end of the sb at ptr.  */
 
161
 
 
162
void
 
163
sb_add_char (ptr, c)
 
164
     sb *ptr;
 
165
     int c;
 
166
{
 
167
  sb_check (ptr, 1);
 
168
  ptr->ptr[ptr->len++] = c;
 
169
}
 
170
 
 
171
/* add null terminated string s to the end of sb at ptr.  */
 
172
 
 
173
void
 
174
sb_add_string (ptr, s)
 
175
     sb *ptr;
 
176
     const char *s;
 
177
{
 
178
  int len = strlen (s);
 
179
  sb_check (ptr, len);
 
180
  memcpy (ptr->ptr + ptr->len, s, len);
 
181
  ptr->len += len;
 
182
}
 
183
 
 
184
/* add string at s of length len to sb at ptr */
 
185
 
 
186
void
 
187
sb_add_buffer (ptr, s, len)
 
188
     sb *ptr;
 
189
     const char *s;
 
190
     int len;
 
191
{
 
192
  sb_check (ptr, len);
 
193
  memcpy (ptr->ptr + ptr->len, s, len);
 
194
  ptr->len += len;
 
195
}
 
196
 
 
197
/* print the sb at ptr to the output file */
 
198
 
 
199
void
 
200
sb_print (outfile, ptr)
 
201
     FILE *outfile;
 
202
     sb *ptr;
 
203
{
 
204
  int i;
 
205
  int nc = 0;
 
206
 
 
207
  for (i = 0; i < ptr->len; i++)
 
208
    {
 
209
      if (nc)
 
210
        {
 
211
          fprintf (outfile, ",");
 
212
        }
 
213
      fprintf (outfile, "%d", ptr->ptr[i]);
 
214
      nc = 1;
 
215
    }
 
216
}
 
217
 
 
218
void
 
219
sb_print_at (outfile, idx, ptr)
 
220
     FILE *outfile;
 
221
     int idx;
 
222
     sb *ptr;
 
223
{
 
224
  int i;
 
225
  for (i = idx; i < ptr->len; i++)
 
226
    putc (ptr->ptr[i], outfile);
 
227
}
 
228
 
 
229
/* put a null at the end of the sb at in and return the start of the
 
230
   string, so that it can be used as an arg to printf %s.  */
 
231
 
 
232
char *
 
233
sb_name (in)
 
234
     sb *in;
 
235
{
 
236
  /* stick a null on the end of the string */
 
237
  sb_add_char (in, 0);
 
238
  return in->ptr;
 
239
}
 
240
 
 
241
/* like sb_name, but don't include the null byte in the string.  */
 
242
 
 
243
char *
 
244
sb_terminate (in)
 
245
     sb *in;
 
246
{
 
247
  sb_add_char (in, 0);
 
248
  --in->len;
 
249
  return in->ptr;
 
250
}
 
251
 
 
252
/* start at the index idx into the string in sb at ptr and skip
 
253
   whitespace. return the index of the first non whitespace character */
 
254
 
 
255
int
 
256
sb_skip_white (idx, ptr)
 
257
     int idx;
 
258
     sb *ptr;
 
259
{
 
260
  while (idx < ptr->len
 
261
         && (ptr->ptr[idx] == ' '
 
262
             || ptr->ptr[idx] == '\t'))
 
263
    idx++;
 
264
  return idx;
 
265
}
 
266
 
 
267
/* start at the index idx into the sb at ptr. skips whitespace,
 
268
   a comma and any following whitespace. returns the index of the
 
269
   next character.  */
 
270
 
 
271
int
 
272
sb_skip_comma (idx, ptr)
 
273
     int idx;
 
274
     sb *ptr;
 
275
{
 
276
  while (idx < ptr->len
 
277
         && (ptr->ptr[idx] == ' '
 
278
             || ptr->ptr[idx] == '\t'))
 
279
    idx++;
 
280
 
 
281
  if (idx < ptr->len
 
282
      && ptr->ptr[idx] == ',')
 
283
    idx++;
 
284
 
 
285
  while (idx < ptr->len
 
286
         && (ptr->ptr[idx] == ' '
 
287
             || ptr->ptr[idx] == '\t'))
 
288
    idx++;
 
289
 
 
290
  return idx;
 
291
}