1115013Smarcel/*
2160157SmarcelCopyright (c) 2003-2006 Hewlett-Packard Development Company, L.P.
3121642SmarcelPermission is hereby granted, free of charge, to any person
4121642Smarcelobtaining a copy of this software and associated documentation
5121642Smarcelfiles (the "Software"), to deal in the Software without
6121642Smarcelrestriction, including without limitation the rights to use,
7121642Smarcelcopy, modify, merge, publish, distribute, sublicense, and/or sell
8121642Smarcelcopies of the Software, and to permit persons to whom the
9121642SmarcelSoftware is furnished to do so, subject to the following
10121642Smarcelconditions:
11115013Smarcel
12121642SmarcelThe above copyright notice and this permission notice shall be
13121642Smarcelincluded in all copies or substantial portions of the Software.
14121642Smarcel
15121642SmarcelTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16121642SmarcelEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
17121642SmarcelOF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18121642SmarcelNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
19121642SmarcelHOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20121642SmarcelWHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21121642SmarcelFROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22121642SmarcelOTHER DEALINGS IN THE SOFTWARE.
23121642Smarcel*/
24121642Smarcel
25160163Smarcel#ifndef _KERNEL
26160157Smarcel#include <string.h>
27160163Smarcel#endif
28160157Smarcel
29115013Smarcel#include "uwx_env.h"
30115013Smarcel#include "uwx_str.h"
31115013Smarcel
32160163Smarcel#ifdef _KERNEL
33160163Smarcelstatic struct uwx_str_pool	uwx_str_pool;
34160163Smarcel#define	free(p)		/* nullified */
35160163Smarcel#define	malloc(sz)	((sz == sizeof(uwx_str_pool)) ? &uwx_str_pool : NULL)
36160163Smarcel#endif
37160163Smarcel
38115013Smarcel/*
39115013Smarcel *  uwx_str.c
40115013Smarcel *
41115013Smarcel *  This file contains the routines for maintaining a string
42115013Smarcel *  pool for the unwind environment. We preallocate enough
43115013Smarcel *  space for most purposes so that no memory allocation is
44115013Smarcel *  necessary during a normal unwind. If we do need more,
45115013Smarcel *  we use the allocate callback, if one is provided.
46115013Smarcel *
47115013Smarcel *  The string pool is reused with each call to step(),
48115013Smarcel *  and is completely freed when the unwind environment is
49115013Smarcel *  freed.
50115013Smarcel */
51115013Smarcel
52115013Smarcel
53160157Smarcelint uwx_init_str_pool(struct uwx_env *env, struct uwx_str_pool *pool)
54115013Smarcel{
55160157Smarcel    if (pool == 0)
56115013Smarcel	return UWX_ERR_NOMEM;
57115013Smarcel
58160157Smarcel    pool->next = 0;
59160157Smarcel    pool->size = STRPOOLSIZE;
60160157Smarcel    pool->used = 0;
61115013Smarcel
62160157Smarcel    env->string_pool = pool;
63160157Smarcel
64115013Smarcel    return UWX_OK;
65115013Smarcel}
66115013Smarcel
67115013Smarcelvoid uwx_free_str_pool(struct uwx_env *env)
68115013Smarcel{
69115013Smarcel    struct uwx_str_pool *pool;
70115013Smarcel    struct uwx_str_pool *next;
71115013Smarcel
72160157Smarcel    /* The first pool is preallocated as part of the uwx_env. Don't free it! */
73160157Smarcel    pool = env->string_pool;
74160157Smarcel    if (pool != 0)
75160157Smarcel	pool = pool->next;
76160157Smarcel    for (; pool != 0; pool = next) {
77115013Smarcel	next = pool->next;
78115013Smarcel	if (env->free_cb == 0)
79115013Smarcel	    free(pool);
80115013Smarcel	else
81115013Smarcel	    (*env->free_cb)(pool);
82115013Smarcel    }
83115013Smarcel}
84115013Smarcel
85115013Smarcelchar *uwx_alloc_str(struct uwx_env *env, char *str)
86115013Smarcel{
87115013Smarcel    int len;
88115013Smarcel    int size;
89115013Smarcel    struct uwx_str_pool *pool;
90115013Smarcel    struct uwx_str_pool *prev;
91115013Smarcel    char *p;
92115013Smarcel
93115013Smarcel    len = strlen(str) + 1;
94115013Smarcel    prev = 0;
95115013Smarcel    for (pool = env->string_pool; pool != 0; pool = pool->next) {
96115013Smarcel	prev = pool;
97115013Smarcel	if (pool->size - pool->used >= len)
98115013Smarcel	    break;
99115013Smarcel    }
100115013Smarcel    if (pool == 0) {
101115013Smarcel	size = STRPOOLSIZE;
102115013Smarcel	if (len > size)
103115013Smarcel	    size = len;
104115013Smarcel	size += sizeof(struct uwx_str_pool) - STRPOOLSIZE;
105115013Smarcel	if (env->allocate_cb == 0)
106115013Smarcel	    pool = (struct uwx_str_pool *) malloc(size);
107115013Smarcel	else
108115013Smarcel	    pool = (struct uwx_str_pool *) (*env->allocate_cb)(size);
109115013Smarcel	if (env->string_pool == 0)
110115013Smarcel	    return 0;
111115013Smarcel	pool->next = 0;
112115013Smarcel	pool->size = size;
113115013Smarcel	pool->used = 0;
114115013Smarcel	prev->next = pool;
115115013Smarcel    }
116115013Smarcel    p = pool->pool + pool->used;
117115013Smarcel    strcpy(p, str);
118115013Smarcel    pool->used += len;
119115013Smarcel    return p;
120115013Smarcel}
121115013Smarcel
122115013Smarcelvoid uwx_reset_str_pool(struct uwx_env *env)
123115013Smarcel{
124115013Smarcel    struct uwx_str_pool *pool;
125115013Smarcel
126115013Smarcel    for (pool = env->string_pool; pool != 0; pool = pool->next)
127115013Smarcel	pool->used = 0;
128115013Smarcel}
129