xref: /illumos-gate/usr/src/cmd/mailx/stralloc.c (revision 41e0a469c3dbc14deb2b200f6ca6f6e00b5865d0)
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 /*
24  * Copyright 1997 Sun Microsystems, Inc.  All rights reserved.
25  * Use is subject to license terms.
26  */
27 
28 /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
29 /*	  All Rights Reserved  	*/
30 
31 
32 /*
33  * University Copyright- Copyright (c) 1982, 1986, 1988
34  * The Regents of the University of California
35  * All Rights Reserved
36  *
37  * University Acknowledgment- Portions of this document are derived from
38  * software developed by the University of California, Berkeley, and its
39  * contributors.
40  */
41 
42 /*
43  * mailx -- a modified version of a University of California at Berkeley
44  *	mail program
45  *
46  * Memory allocation routines.
47  * Memory handed out here are reclaimed at the top of the command
48  * loop each time, so they need not be freed.
49  */
50 
51 #include "rcv.h"
52 #include <locale.h>
53 
54 static void		*lastptr;	/* addr of last buffer allocated */
55 static struct strings	*lastsp;	/* last string space allocated from */
56 
57 /*
58  * Allocate size more bytes of space and return the address of the
59  * first byte to the caller.  An even number of bytes are always
60  * allocated so that the space will always be on a word boundary.
61  * The string spaces are of exponentially increasing size, to satisfy
62  * the occasional user with enormous string size requests.
63  */
64 
65 void *
66 salloc(unsigned size)
67 {
68 	register char *t;
69 	register unsigned s;
70 	register struct strings *sp;
71 	int index;
72 
73 	s = size;
74 #if defined(u3b) || defined(sparc)
75 	s += 3;		/* needs alignment on quad boundary */
76 	s &= ~03;
77 #elif defined(i386)
78 	s++;
79 	s &= ~01;
80 #else
81 #error Unknown architecture!
82 #endif
83 	index = 0;
84 	for (sp = &stringdope[0]; sp < &stringdope[NSPACE]; sp++) {
85 		if (sp->s_topFree == NOSTR && (STRINGSIZE << index) >= s)
86 			break;
87 		if (sp->s_nleft >= s)
88 			break;
89 		index++;
90 	}
91 	if (sp >= &stringdope[NSPACE])
92 		panic("String too large");
93 	if (sp->s_topFree == NOSTR) {
94 		index = sp - &stringdope[0];
95 		sp->s_topFree = (char *) calloc(STRINGSIZE << index,
96 		    (unsigned) 1);
97 		if (sp->s_topFree == NOSTR) {
98 			fprintf(stderr, gettext("No room for space %d\n"),
99 			    index);
100 			panic("Internal error");
101 		}
102 		sp->s_nextFree = sp->s_topFree;
103 		sp->s_nleft = STRINGSIZE << index;
104 	}
105 	sp->s_nleft -= s;
106 	t = sp->s_nextFree;
107 	sp->s_nextFree += s;
108 	lastptr = t;
109 	lastsp = sp;
110 	return(t);
111 }
112 
113 /*
114  * Reallocate size bytes of space and return the address of the
115  * first byte to the caller.  The old data is copied into the new area.
116  */
117 
118 void *
119 srealloc(void *optr, unsigned size)
120 {
121 	void *nptr;
122 
123 	/* if we just want to expand the last allocation, that's easy */
124 	if (optr == lastptr) {
125 		register unsigned s, delta;
126 		register struct strings *sp = lastsp;
127 
128 		s = size;
129 #if defined(u3b) || defined(sparc)
130 		s += 3;		/* needs alignment on quad boundary */
131 		s &= ~03;
132 #elif defined(i386)
133 		s++;
134 		s &= ~01;
135 #else
136 #error Unknown architecture!
137 #endif /* defined(u3b) || defined(sparc) */
138 		delta = s - (sp->s_nextFree - (char *)optr);
139 		if (delta <= sp->s_nleft) {
140 			sp->s_nextFree += delta;
141 			sp->s_nleft -= delta;
142 			return (optr);
143 		}
144 	}
145 	nptr = salloc(size);
146 	if (nptr)
147 		memcpy(nptr, optr, size);	/* XXX - copying too much */
148 	return nptr;
149 }
150 
151 /*
152  * Reset the string area to be empty.
153  * Called to free all strings allocated
154  * since last reset.
155  */
156 void
157 sreset(void)
158 {
159 	register struct strings *sp;
160 	register int index;
161 
162 	if (noreset)
163 		return;
164 	minit();
165 	index = 0;
166 	for (sp = &stringdope[0]; sp < &stringdope[NSPACE]; sp++) {
167 		if (sp->s_topFree == NOSTR)
168 			continue;
169 		sp->s_nextFree = sp->s_topFree;
170 		sp->s_nleft = STRINGSIZE << index;
171 		index++;
172 	}
173 	lastptr = NULL;
174 	lastsp = NULL;
175 }
176