xref: /illumos-gate/usr/src/cmd/sgs/libelf/misc/String.c (revision 7c478bd9)
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 #pragma ident	"%Z%%M%	%I%	%E% SMI"
32 
33 /*
34  * C++ Demangler Source Code
35  * @(#)master	1.5
36  * 7/27/88 13:54:37
37  */
38 #include <stdio.h>
39 #include <setjmp.h>
40 #include <assert.h>
41 #include <string.h>
42 #include <malloc.h>
43 #include "elf_dem.h"
44 #include "String.h"
45 
46 /*
47  * This code emulates the C++ String package
48  * in a crude way.
49  */
50 
51 jmp_buf jbuf;
52 
53 /*
54  * This function will expand the space
55  * available to a String so that more data
56  * can be appended to it
57  */
58 static String *
grow(s)59 grow(s)
60 String *s;
61 {
62 	String *ns;
63 	int sz = s->sg.max * 2;
64 	assert(sz > 0);
65 #ifdef ELF
66 	if ((ns = (String *)malloc(sz + sizeof (StringGuts) + 1)) == NULL)
67 		longjmp(jbuf, 1);
68 	(void) memcpy(ns, s, s->sg.max + sizeof (StringGuts) + 1);
69 	free(s);
70 #else
71 	if ((ns = (String *)realloc(s, sz + sizeof (StringGuts) + 1)) == NULL)
72 		longjmp(jbuf, 1);
73 #endif
74 	ns->sg.max = sz;
75 	return (ns);
76 }
77 
78 /*
79  * This function will expand the space
80  * available to a String so that more data
81  * can be prepended to it.
82  */
83 static String *
ror(s,n)84 ror(s, n)
85 String *s;
86 int n;
87 {
88 	assert(s != 0);
89 	while (s->sg.end + n > s->sg.max)
90 		s = grow(s);
91 #ifdef __STDC__
92 	assert(n >= 0);
93 	assert(s->sg.end >= s->sg.start);
94 	(void) memmove(s->data + n, s->data, s->sg.end - s->sg.start);
95 #else
96 	{
97 		int i;
98 		for (i = s->sg.end - 1; i >= s->sg.start; i--)
99 			s->data[i+n] = s->data[i];
100 	}
101 #endif
102 	s->sg.end += n;
103 	s->sg.start += n;
104 	s->data[s->sg.end] = 0;
105 	return (s);
106 }
107 
108 /*
109  * This function will prepend c
110  * to s
111  */
112 String *
prep_String(c,s)113 prep_String(c, s)
114 char *c;
115 String *s;
116 {
117 	return (nprep_String(c, s, ID_NAME_MAX));
118 }
119 
120 /*
121  * This function will prepend the
122  * first n characters of c to s
123  */
124 String *
nprep_String(c,s,n)125 nprep_String(c, s, n)
126 const char *c;
127 String *s;
128 int n;
129 {
130 	int len = strlen(c);
131 	assert(s != 0);
132 	if (len > n)
133 		len = n;
134 	if (len > s->sg.start)
135 		s = ror(s, len - s->sg.start);
136 	s->sg.start -= len;
137 	(void) memcpy(s->data + s->sg.start, c, len);
138 	return (s);
139 }
140 
141 /*
142  * This function will append
143  * c to s.
144  */
145 String *
app_String(s,c)146 app_String(s, c)
147 String *s;
148 const char *c;
149 {
150 	return (napp_String(s, c, ID_NAME_MAX));
151 }
152 
153 /*
154  * This function will append the
155  * first n characters of c to s
156  */
157 String *
napp_String(String * s,const char * c,int n)158 napp_String(String *s, const char *c, int n)
159 {
160 	int len = strlen(c);
161 	int catlen;
162 	assert(s != 0);
163 	if (n < len)
164 		len = n;
165 	catlen = s->sg.end + len;
166 	while (catlen > s->sg.max)
167 		s = grow(s);
168 	(void) memcpy(s->data + s->sg.end, c, len);
169 	s->sg.end += len;
170 	s->data[s->sg.end] = '\0';
171 	return (s);
172 }
173 
174 /*
175  * This function initializes a
176  * String.  It returns its argument if
177  * its argument is non-zero.
178  * This prevents the same string
179  * from being re-initialized.
180  */
181 String *
mk_String(s)182 mk_String(s)
183 String *s;
184 {
185 	if (s)
186 		return (s);
187 	s = (String *)malloc(STRING_START + sizeof (StringGuts) + 1);
188 	if (s == NULL)
189 		longjmp(jbuf, 1);
190 	s->sg.start = s->sg.end = STRING_START/2;
191 	s->sg.max = STRING_START;
192 	s->data[s->sg.end] = '\0';
193 	return (s);
194 }
195 
196 void
free_String(s)197 free_String(s)
198 String *s;
199 {
200 	if (s)
201 		free(s);
202 }
203 
204 /*
205  * This function copies
206  * c into s.
207  * Used for initialization.
208  */
209 String *
set_String(s,c)210 set_String(s, c)
211 String *s;
212 char *c;
213 {
214 	int len = strlen(c)*2;
215 	while (len > s->sg.max)
216 		s = grow(s);
217 	s->sg.start = s->sg.end = s->sg.max / 2;
218 	s = app_String(s, c);
219 	return (s);
220 }
221 
222 /*
223  * Chop n characters off the end of a string.
224  * Return the truncated string.
225  */
226 String *
trunc_String(String * s,int n)227 trunc_String(String *s, int n)
228 {
229 	assert(n <= s->sg.end - s->sg.start);
230 	s->sg.end -= n;
231 	s->data[s->sg.end] = '\0';
232 	return (s);
233 }
234