Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_33_1/tools/build/jam_src/newstr.c @ 12

Last change on this file since 12 was 12, checked in by landauf, 18 years ago

added boost

File size: 3.4 KB
Line 
1/*
2 * Copyright 1993, 1995 Christopher Seiwald.
3 *
4 * This file is part of Jam - see jam.c for Copyright information.
5 */
6
7# include "jam.h"
8# include "newstr.h"
9# include "hash.h"
10# include <stddef.h>
11# include <stdlib.h>
12
13/*
14 * newstr.c - string manipulation routines
15 *
16 * To minimize string copying, string creation, copying, and freeing
17 * is done through newstr.
18 *
19 * External functions:
20 *
21 *    newstr() - return a dynamically allocated copy of a string
22 *    copystr() - return a copy of a string previously returned by newstr()
23 *    freestr() - free a string returned by newstr() or copystr()
24 *    donestr() - free string tables
25 *
26 * Once a string is passed to newstr(), the returned string is readonly.
27 *
28 * This implementation builds a hash table of all strings, so that multiple
29 * calls of newstr() on the same string allocate memory for the string once.
30 * Strings are never actually freed.
31 */
32
33typedef char *STRING;
34
35static struct hash *strhash = 0;
36static int strtotal = 0;
37
38/*
39 * Immortal string allocator implementation speeds string allocation
40 * and cuts down on internal fragmentation
41 */
42
43# define STRING_BLOCK 4096
44typedef struct strblock
45{
46    struct strblock* next;
47    char data[STRING_BLOCK];
48} strblock;
49
50static strblock* strblock_chain = 0;
51
52/* Storage remaining in the current strblock */
53static char* storage_start = 0;
54static char* storage_finish = 0;
55
56/*
57 * allocate() - Allocate n bytes of immortal string storage
58 */
59static char* allocate(size_t n)
60{
61    /* See if we can grab storage from an existing block */
62    size_t remaining = storage_finish - storage_start;
63    if ( remaining >= n )
64    {
65        char* result = storage_start;
66        storage_start += n;
67        return result;
68    }
69    else /* Must allocate a new block */
70    {
71        strblock* new_block;
72        size_t nalloc = n;
73        if ( nalloc < STRING_BLOCK )
74            nalloc = STRING_BLOCK;
75
76        /* allocate a new block and link into the chain */
77        new_block = (strblock*)malloc( offsetof( strblock, data[0] ) + nalloc * sizeof(new_block->data[0]) );
78        if ( new_block == 0 )
79            return 0;
80        new_block->next = strblock_chain;
81        strblock_chain = new_block;
82
83        /* Take future allocations out of the larger remaining space */
84        if ( remaining < nalloc - n )
85        {
86            storage_start = new_block->data + n;
87            storage_finish = new_block->data + nalloc;
88        }
89        return new_block->data;
90    }
91}
92
93/*
94 * newstr() - return a dynamically allocated copy of a string
95 */
96
97char *
98newstr( char *string )
99{
100        STRING str, *s = &str;
101
102        if( !strhash )
103            strhash = hashinit( sizeof( STRING ), "strings" );
104
105        *s = string;
106
107        if( hashenter( strhash, (HASHDATA **)&s ) )
108        {
109            int l = strlen( string );
110            char *m = (char *)allocate( l + 1 );
111
112            strtotal += l + 1;
113            memcpy( m, string, l + 1 );
114            *s = m;
115        }
116
117        return *s;
118}
119
120/*
121 * copystr() - return a copy of a string previously returned by newstr()
122 */
123
124char *
125copystr( char *s )
126{
127        return s;
128}
129
130/*
131 * freestr() - free a string returned by newstr() or copystr()
132 */
133
134void
135freestr( char *s )
136{
137}
138
139/*
140 * donestr() - free string tables
141 */
142
143void
144donestr()
145{
146    /* Reclaim string blocks */
147    while ( strblock_chain != 0 )
148    {
149        strblock* n = strblock_chain->next;
150        free(strblock_chain);
151        strblock_chain = n;
152    }
153   
154    hashdone( strhash );
155   
156    if( DEBUG_MEM )
157        printf( "%dK in strings\n", strtotal / 1024 );
158}
Note: See TracBrowser for help on using the repository browser.