uwx_str.c revision 160157
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
25160157Smarcel#include <string.h>
26160157Smarcel
27115013Smarcel#include "uwx_env.h"
28115013Smarcel#include "uwx_str.h"
29115013Smarcel
30115013Smarcel/*
31115013Smarcel *  uwx_str.c
32115013Smarcel *
33115013Smarcel *  This file contains the routines for maintaining a string
34115013Smarcel *  pool for the unwind environment. We preallocate enough
35115013Smarcel *  space for most purposes so that no memory allocation is
36115013Smarcel *  necessary during a normal unwind. If we do need more,
37115013Smarcel *  we use the allocate callback, if one is provided.
38115013Smarcel *
39115013Smarcel *  The string pool is reused with each call to step(),
40115013Smarcel *  and is completely freed when the unwind environment is
41115013Smarcel *  freed.
42115013Smarcel */
43115013Smarcel
44115013Smarcel
45160157Smarcelint uwx_init_str_pool(struct uwx_env *env, struct uwx_str_pool *pool)
46115013Smarcel{
47160157Smarcel    if (pool == 0)
48115013Smarcel	return UWX_ERR_NOMEM;
49115013Smarcel
50160157Smarcel    pool->next = 0;
51160157Smarcel    pool->size = STRPOOLSIZE;
52160157Smarcel    pool->used = 0;
53115013Smarcel
54160157Smarcel    env->string_pool = pool;
55160157Smarcel
56115013Smarcel    return UWX_OK;
57115013Smarcel}
58115013Smarcel
59115013Smarcelvoid uwx_free_str_pool(struct uwx_env *env)
60115013Smarcel{
61115013Smarcel    struct uwx_str_pool *pool;
62115013Smarcel    struct uwx_str_pool *next;
63115013Smarcel
64160157Smarcel    /* The first pool is preallocated as part of the uwx_env. Don't free it! */
65160157Smarcel    pool = env->string_pool;
66160157Smarcel    if (pool != 0)
67160157Smarcel	pool = pool->next;
68160157Smarcel    for (; pool != 0; pool = next) {
69115013Smarcel	next = pool->next;
70115013Smarcel	if (env->free_cb == 0)
71115013Smarcel	    free(pool);
72115013Smarcel	else
73115013Smarcel	    (*env->free_cb)(pool);
74115013Smarcel    }
75115013Smarcel}
76115013Smarcel
77115013Smarcelchar *uwx_alloc_str(struct uwx_env *env, char *str)
78115013Smarcel{
79115013Smarcel    int len;
80115013Smarcel    int size;
81115013Smarcel    struct uwx_str_pool *pool;
82115013Smarcel    struct uwx_str_pool *prev;
83115013Smarcel    char *p;
84115013Smarcel
85115013Smarcel    len = strlen(str) + 1;
86115013Smarcel    prev = 0;
87115013Smarcel    for (pool = env->string_pool; pool != 0; pool = pool->next) {
88115013Smarcel	prev = pool;
89115013Smarcel	if (pool->size - pool->used >= len)
90115013Smarcel	    break;
91115013Smarcel    }
92115013Smarcel    if (pool == 0) {
93115013Smarcel	size = STRPOOLSIZE;
94115013Smarcel	if (len > size)
95115013Smarcel	    size = len;
96115013Smarcel	size += sizeof(struct uwx_str_pool) - STRPOOLSIZE;
97115013Smarcel	if (env->allocate_cb == 0)
98115013Smarcel	    pool = (struct uwx_str_pool *) malloc(size);
99115013Smarcel	else
100115013Smarcel	    pool = (struct uwx_str_pool *) (*env->allocate_cb)(size);
101115013Smarcel	if (env->string_pool == 0)
102115013Smarcel	    return 0;
103115013Smarcel	pool->next = 0;
104115013Smarcel	pool->size = size;
105115013Smarcel	pool->used = 0;
106115013Smarcel	prev->next = pool;
107115013Smarcel    }
108115013Smarcel    p = pool->pool + pool->used;
109115013Smarcel    strcpy(p, str);
110115013Smarcel    pool->used += len;
111115013Smarcel    return p;
112115013Smarcel}
113115013Smarcel
114115013Smarcelvoid uwx_reset_str_pool(struct uwx_env *env)
115115013Smarcel{
116115013Smarcel    struct uwx_str_pool *pool;
117115013Smarcel
118115013Smarcel    for (pool = env->string_pool; pool != 0; pool = pool->next)
119115013Smarcel	pool->used = 0;
120115013Smarcel}
121