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
51jmp_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 */
58static String *
59grow(s)
60String *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 */
83static String *
84ror(s, n)
85String *s;
86int 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 */
112String *
113prep_String(c, s)
114char *c;
115String *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 */
124String *
125nprep_String(c, s, n)
126const char *c;
127String *s;
128int 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 */
145String *
146app_String(s, c)
147String *s;
148const 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 */
157String *
158napp_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 */
181String *
182mk_String(s)
183String *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
196void
197free_String(s)
198String *s;
199{
200	if (s)
201		free(s);
202}
203
204/*
205 * This function copies
206 * c into s.
207 * Used for initialization.
208 */
209String *
210set_String(s, c)
211String *s;
212char *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 */
226String *
227trunc_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