* sb.c (sb_build): Undefine abort before calling it, since gasp
[deliverable/binutils-gdb.git] / gas / sb.c
1 /* sb.c - string buffer manipulation routines
2 Copyright (C) 1994, 1995 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 #include "sb.h"
27
28 /* These routines are about manipulating strings.
29
30 They are managed in things called `sb's which is an abbreviation
31 for string buffers. An sb has to be created, things can be glued
32 on to it, and at the end of it's life it should be freed. The
33 contents should never be pointed at whilst it is still growing,
34 since it could be moved at any time
35
36 eg:
37 sb_new (&foo);
38 sb_grow... (&foo,...);
39 use foo->ptr[*];
40 sb_kill (&foo);
41
42 */
43
44 #define dsize 5
45
46 static void sb_check PARAMS ((sb *, int));
47
48 /* Statistics of sb structures. */
49
50 int string_count[sb_max_power_two];
51
52 /* Free list of sb structures. */
53
54 static sb_list_vector free_list;
55
56 /* initializes an sb. */
57
58 void
59 sb_build (ptr, size)
60 sb *ptr;
61 int size;
62 {
63 /* see if we can find one to allocate */
64 sb_element *e;
65
66 #undef abort
67 if (size > sb_max_power_two)
68 abort ();
69
70 e = free_list.size[size];
71 if (!e)
72 {
73 /* nothing there, allocate one and stick into the free list */
74 e = (sb_element *) xmalloc (sizeof (sb_element) + (1 << size));
75 e->next = free_list.size[size];
76 e->size = 1 << size;
77 free_list.size[size] = e;
78 string_count[size]++;
79 }
80
81 /* remove from free list */
82
83 free_list.size[size] = e->next;
84
85 /* copy into callers world */
86 ptr->ptr = e->data;
87 ptr->pot = size;
88 ptr->len = 0;
89 ptr->item = e;
90 }
91
92
93 void
94 sb_new (ptr)
95 sb *ptr;
96 {
97 sb_build (ptr, dsize);
98 }
99
100 /* deallocate the sb at ptr */
101
102 void
103 sb_kill (ptr)
104 sb *ptr;
105 {
106 /* return item to free list */
107 ptr->item->next = free_list.size[ptr->pot];
108 free_list.size[ptr->pot] = ptr->item;
109 }
110
111 /* add the sb at s to the end of the sb at ptr */
112
113 void
114 sb_add_sb (ptr, s)
115 sb *ptr;
116 sb *s;
117 {
118 sb_check (ptr, s->len);
119 memcpy (ptr->ptr + ptr->len, s->ptr, s->len);
120 ptr->len += s->len;
121 }
122
123 /* make sure that the sb at ptr has room for another len characters,
124 and grow it if it doesn't. */
125
126 static void
127 sb_check (ptr, len)
128 sb *ptr;
129 int len;
130 {
131 if (ptr->len + len >= 1 << ptr->pot)
132 {
133 sb tmp;
134 int pot = ptr->pot;
135 while (ptr->len + len >= 1 << pot)
136 pot++;
137 sb_build (&tmp, pot);
138 sb_add_sb (&tmp, ptr);
139 sb_kill (ptr);
140 *ptr = tmp;
141 }
142 }
143
144 /* make the sb at ptr point back to the beginning. */
145
146 void
147 sb_reset (ptr)
148 sb *ptr;
149 {
150 ptr->len = 0;
151 }
152
153 /* add character c to the end of the sb at ptr. */
154
155 void
156 sb_add_char (ptr, c)
157 sb *ptr;
158 int c;
159 {
160 sb_check (ptr, 1);
161 ptr->ptr[ptr->len++] = c;
162 }
163
164 /* add null terminated string s to the end of sb at ptr. */
165
166 void
167 sb_add_string (ptr, s)
168 sb *ptr;
169 const char *s;
170 {
171 int len = strlen (s);
172 sb_check (ptr, len);
173 memcpy (ptr->ptr + ptr->len, s, len);
174 ptr->len += len;
175 }
176
177 /* add string at s of length len to sb at ptr */
178
179 void
180 sb_add_buffer (ptr, s, len)
181 sb *ptr;
182 const char *s;
183 int len;
184 {
185 sb_check (ptr, len);
186 memcpy (ptr->ptr + ptr->len, s, len);
187 ptr->len += len;
188 }
189
190 /* print the sb at ptr to the output file */
191
192 void
193 sb_print (outfile, ptr)
194 FILE *outfile;
195 sb *ptr;
196 {
197 int i;
198 int nc = 0;
199
200 for (i = 0; i < ptr->len; i++)
201 {
202 if (nc)
203 {
204 fprintf (outfile, ",");
205 }
206 fprintf (outfile, "%d", ptr->ptr[i]);
207 nc = 1;
208 }
209 }
210
211 void
212 sb_print_at (outfile, idx, ptr)
213 FILE *outfile;
214 int idx;
215 sb *ptr;
216 {
217 int i;
218 for (i = idx; i < ptr->len; i++)
219 putc (ptr->ptr[i], outfile);
220 }
221
222 /* put a null at the end of the sb at in and return the start of the
223 string, so that it can be used as an arg to printf %s. */
224
225 char *
226 sb_name (in)
227 sb *in;
228 {
229 /* stick a null on the end of the string */
230 sb_add_char (in, 0);
231 return in->ptr;
232 }
233
234 /* like sb_name, but don't include the null byte in the string. */
235
236 char *
237 sb_terminate (in)
238 sb *in;
239 {
240 sb_add_char (in, 0);
241 --in->len;
242 return in->ptr;
243 }
244
245 /* start at the index idx into the string in sb at ptr and skip
246 whitespace. return the index of the first non whitespace character */
247
248 int
249 sb_skip_white (idx, ptr)
250 int idx;
251 sb *ptr;
252 {
253 while (idx < ptr->len
254 && (ptr->ptr[idx] == ' '
255 || ptr->ptr[idx] == '\t'))
256 idx++;
257 return idx;
258 }
259
260 /* start at the index idx into the sb at ptr. skips whitespace,
261 a comma and any following whitespace. returnes the index of the
262 next character. */
263
264 int
265 sb_skip_comma (idx, ptr)
266 int idx;
267 sb *ptr;
268 {
269 while (idx < ptr->len
270 && (ptr->ptr[idx] == ' '
271 || ptr->ptr[idx] == '\t'))
272 idx++;
273
274 if (idx < ptr->len
275 && ptr->ptr[idx] == ',')
276 idx++;
277
278 while (idx < ptr->len
279 && (ptr->ptr[idx] == ' '
280 || ptr->ptr[idx] == '\t'))
281 idx++;
282
283 return idx;
284 }
This page took 0.035322 seconds and 5 git commands to generate.