Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_34_1/tools/jam/src/strings.c @ 29

Last change on this file since 29 was 29, checked in by landauf, 17 years ago

updated boost from 1_33_1 to 1_34_1

File size: 4.5 KB
Line 
1/* Copyright David Abrahams 2004. Distributed under the Boost */
2/* Software License, Version 1.0. (See accompanying */
3/* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */
4
5#include "strings.h"
6#include "debug.h"
7#include <stdlib.h>
8#include <string.h>
9#include <assert.h>
10#include <stdio.h>
11
12
13#ifndef NDEBUG
14# define JAM_STRING_MAGIC ((char)0xcf)
15# define JAM_STRING_MAGIC_SIZE 4
16static void assert_invariants( string* self )
17{
18    int i;
19   
20    assert( self->size < self->capacity );
21    assert( ( self->capacity <= sizeof(self->opt) ) == ( self->value == self->opt ) );
22    assert( strlen( self->value ) == self->size );
23
24    for (i = 0; i < 4; ++i)
25    {
26        assert( self->magic[i] == JAM_STRING_MAGIC );
27        assert( self->value[self->capacity + i] == JAM_STRING_MAGIC );
28    }
29}
30#else
31# define JAM_STRING_MAGIC_SIZE 0
32# define assert_invariants(x) do {} while (0)
33#endif
34
35void string_new( string* s )
36{
37    s->value = s->opt;
38    s->size = 0;
39    s->capacity = sizeof(s->opt);
40    s->opt[0] = 0;
41#ifndef NDEBUG
42    memset(s->magic, JAM_STRING_MAGIC, sizeof(s->magic));
43#endif
44    assert_invariants( s );
45}
46
47void string_free( string* s )
48{
49    assert_invariants( s );
50    if ( s->value != s->opt )
51        free( s->value );
52}
53
54static void string_reserve_internal( string* self, size_t capacity )
55{
56    if ( self->value == self->opt )
57    {
58        self->value = (char*)malloc( capacity + JAM_STRING_MAGIC_SIZE );
59        if ( DEBUG_PROFILE )
60            profile_memory( capacity + JAM_STRING_MAGIC_SIZE );
61        self->value[0] = 0;
62        strncat( self->value, self->opt, sizeof(self->opt) );
63        assert( strlen( self->value ) <= self->capacity ); /* This is a regression test */
64    }
65    else
66    {
67        self->value = (char*)realloc( self->value, capacity + JAM_STRING_MAGIC_SIZE );
68    }
69#ifndef NDEBUG
70    memcpy( self->value + capacity, self->magic, JAM_STRING_MAGIC_SIZE );
71#endif
72    self->capacity = capacity;
73}
74
75void string_reserve( string* self, size_t capacity )
76{
77    assert_invariants( self );
78    if ( capacity <= self->capacity )
79        return;
80    string_reserve_internal( self, capacity );
81    assert_invariants( self );
82}
83
84static void extend_full( string* self, char const* start, char const* finish )
85{
86    size_t new_size = self->capacity + ( finish - start );
87    size_t new_capacity = self->capacity;
88    size_t old_size = self->capacity;
89    while ( new_capacity < new_size + 1)
90        new_capacity <<= 1;
91    string_reserve_internal( self, new_capacity );
92    memcpy( self->value + old_size, start, new_size - old_size );
93    self->value[new_size] = 0;
94    self->size = new_size;
95}
96
97void string_append( string* self, char const* rhs )
98{
99    char* p = self->value + self->size;
100    char* end = self->value + self->capacity;
101    assert_invariants( self );
102   
103    while ( *rhs && p != end)
104        *p++ = *rhs++;
105   
106    if ( p != end )
107    {
108        *p = 0;
109        self->size = p - self->value;
110    }
111    else
112    {
113        extend_full( self, rhs, rhs + strlen(rhs) );
114    }
115    assert_invariants( self );
116}
117
118void string_append_range( string* self, char const* start, char const* finish )
119{
120    char* p = self->value + self->size;
121    char* end = self->value + self->capacity;
122    assert_invariants( self );
123   
124    while ( p != end && start != finish )
125        *p++ = *start++;
126   
127    if ( p != end )
128    {
129        *p = 0;
130        self->size = p - self->value;
131    }
132    else
133    {
134        extend_full( self, start, finish );
135    }
136    assert_invariants( self );
137}
138
139void string_copy( string* s, char const* rhs )
140{
141    string_new( s );
142    string_append( s, rhs );
143}
144
145void string_truncate( string* self, size_t n )
146{
147    assert_invariants( self );
148    assert( n <= self->capacity );
149    self->value[self->size = n] = 0;
150    assert_invariants( self );
151}
152
153void string_pop_back( string* self )
154{
155    string_truncate( self, self->size - 1 );
156}
157
158void string_push_back( string* self, char x )
159{
160    string_append_range( self, &x, &x + 1 );
161}
162
163char string_back( string* self )
164{
165    assert_invariants( self );
166    return self->value[self->size - 1];
167}
168
169#ifndef NDEBUG
170void string_unit_test()
171{
172    string s[1];
173    int i;
174    char buffer[sizeof(s->opt) * 2 + 2];
175    int limit = sizeof(buffer) > 254 ? 254 : sizeof(buffer);
176
177    string_new(s);
178   
179    for (i = 0; i < limit; ++i)
180    {
181        string_push_back( s, (char)(i + 1) );
182    };
183
184    for (i = 0; i < limit; ++i)
185    {
186        assert( i < s->size );
187        assert( s->value[i] == (char)(i + 1));
188    }
189
190    string_free(s);
191   
192}
193#endif
194
Note: See TracBrowser for help on using the repository browser.