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 *
grow(s)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 *
ror(s,n)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 *
prep_String(c,s)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 *
nprep_String(c,s,n)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 *
app_String(s,c)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 *
napp_String(String * s,const char * c,int n)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 *
mk_String(s)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
free_String(s)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 *
set_String(s,c)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 *
trunc_String(String * s,int n)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