xref: /illumos-gate/usr/src/cmd/sgs/libelf/misc/String.c (revision 86d949f9497332fe19be6b5d711d265eb957439f)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 /*	Copyright (c) 1988 AT&T	*/
28 /*	  All Rights Reserved  	*/
29 
30 /*
31  * C++ Demangler Source Code
32  * @(#)master	1.5
33  * 7/27/88 13:54:37
34  */
35 #include <stdio.h>
36 #include <setjmp.h>
37 #include <assert.h>
38 #include <string.h>
39 #include <malloc.h>
40 #include "elf_dem.h"
41 #include "String.h"
42 
43 /*
44  * This code emulates the C++ String package
45  * in a crude way.
46  */
47 
48 jmp_buf jbuf;
49 
50 /*
51  * This function will expand the space
52  * available to a String so that more data
53  * can be appended to it
54  */
55 static String *
56 grow(s)
57 String *s;
58 {
59 	String *ns;
60 	int sz = s->sg.max * 2;
61 	assert(sz > 0);
62 #ifdef ELF
63 	if ((ns = (String *)malloc(sz + sizeof (StringGuts) + 1)) == NULL)
64 		longjmp(jbuf, 1);
65 	(void) memcpy(ns, s, s->sg.max + sizeof (StringGuts) + 1);
66 	free(s);
67 #else
68 	if ((ns = (String *)realloc(s, sz + sizeof (StringGuts) + 1)) == NULL)
69 		longjmp(jbuf, 1);
70 #endif
71 	ns->sg.max = sz;
72 	return (ns);
73 }
74 
75 /*
76  * This function will expand the space
77  * available to a String so that more data
78  * can be prepended to it.
79  */
80 static String *
81 ror(s, n)
82 String *s;
83 int n;
84 {
85 	assert(s != 0);
86 	while (s->sg.end + n > s->sg.max)
87 		s = grow(s);
88 #ifdef __STDC__
89 	assert(n >= 0);
90 	assert(s->sg.end >= s->sg.start);
91 	(void) memmove(s->data + n, s->data, s->sg.end - s->sg.start);
92 #else
93 	{
94 		int i;
95 		for (i = s->sg.end - 1; i >= s->sg.start; i--)
96 			s->data[i+n] = s->data[i];
97 	}
98 #endif
99 	s->sg.end += n;
100 	s->sg.start += n;
101 	s->data[s->sg.end] = 0;
102 	return (s);
103 }
104 
105 /*
106  * This function will prepend c
107  * to s
108  */
109 String *
110 prep_String(c, s)
111 char *c;
112 String *s;
113 {
114 	return (nprep_String(c, s, ID_NAME_MAX));
115 }
116 
117 /*
118  * This function will prepend the
119  * first n characters of c to s
120  */
121 String *
122 nprep_String(c, s, n)
123 const char *c;
124 String *s;
125 int n;
126 {
127 	int len = strlen(c);
128 	assert(s != 0);
129 	if (len > n)
130 		len = n;
131 	if (len > s->sg.start)
132 		s = ror(s, len - s->sg.start);
133 	s->sg.start -= len;
134 	(void) memcpy(s->data + s->sg.start, c, len);
135 	return (s);
136 }
137 
138 /*
139  * This function will append
140  * c to s.
141  */
142 String *
143 app_String(s, c)
144 String *s;
145 const char *c;
146 {
147 	return (napp_String(s, c, ID_NAME_MAX));
148 }
149 
150 /*
151  * This function will append the
152  * first n characters of c to s
153  */
154 String *
155 napp_String(String *s, const char *c, int n)
156 {
157 	int len = strlen(c);
158 	int catlen;
159 	assert(s != 0);
160 	if (n < len)
161 		len = n;
162 	catlen = s->sg.end + len;
163 	while (catlen > s->sg.max)
164 		s = grow(s);
165 	(void) memcpy(s->data + s->sg.end, c, len);
166 	s->sg.end += len;
167 	s->data[s->sg.end] = '\0';
168 	return (s);
169 }
170 
171 /*
172  * This function initializes a
173  * String.  It returns its argument if
174  * its argument is non-zero.
175  * This prevents the same string
176  * from being re-initialized.
177  */
178 String *
179 mk_String(s)
180 String *s;
181 {
182 	if (s)
183 		return (s);
184 	s = (String *)malloc(STRING_START + sizeof (StringGuts) + 1);
185 	if (s == NULL)
186 		longjmp(jbuf, 1);
187 	s->sg.start = s->sg.end = STRING_START/2;
188 	s->sg.max = STRING_START;
189 	s->data[s->sg.end] = '\0';
190 	return (s);
191 }
192 
193 void
194 free_String(s)
195 String *s;
196 {
197 	if (s)
198 		free(s);
199 }
200 
201 /*
202  * This function copies
203  * c into s.
204  * Used for initialization.
205  */
206 String *
207 set_String(s, c)
208 String *s;
209 char *c;
210 {
211 	int len = strlen(c)*2;
212 	while (len > s->sg.max)
213 		s = grow(s);
214 	s->sg.start = s->sg.end = s->sg.max / 2;
215 	s = app_String(s, c);
216 	return (s);
217 }
218 
219 /*
220  * Chop n characters off the end of a string.
221  * Return the truncated string.
222  */
223 String *
224 trunc_String(String *s, int n)
225 {
226 	assert(n <= s->sg.end - s->sg.start);
227 	s->sg.end -= n;
228 	s->data[s->sg.end] = '\0';
229 	return (s);
230 }
231