]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/tools/build/src/engine/strings.c
Add patch for failing prerm scripts
[ceph.git] / ceph / src / boost / tools / build / src / engine / strings.c
CommitLineData
7c673cae
FG
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 "jam.h"
6#include "strings.h"
7
8#include <assert.h>
9#include <stdlib.h>
10#include <string.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 if ( self->value == 0 )
21 {
22 assert( self->size == 0 );
23 assert( self->capacity == 0 );
24 assert( self->opt[ 0 ] == 0 );
25 return;
26 }
27
28 assert( self->size < self->capacity );
29 assert( ( self->capacity <= sizeof( self->opt ) ) == ( self->value == self->opt ) );
30 assert( self->value[ self->size ] == 0 );
31 /* String objects modified manually after construction to contain embedded
32 * '\0' characters are considered structurally valid.
33 */
34 assert( strlen( self->value ) <= self->size );
35
36 for ( i = 0; i < 4; ++i )
37 {
38 assert( self->magic[ i ] == JAM_STRING_MAGIC );
39 assert( self->value[ self->capacity + i ] == JAM_STRING_MAGIC );
40 }
41}
42#else
43# define JAM_STRING_MAGIC_SIZE 0
44# define assert_invariants(x) do {} while (0)
45#endif
46
47
48void string_new( string * s )
49{
50 s->value = s->opt;
51 s->size = 0;
52 s->capacity = sizeof( s->opt );
53 s->opt[ 0 ] = 0;
54#ifndef NDEBUG
55 memset( s->magic, JAM_STRING_MAGIC, sizeof( s->magic ) );
56#endif
57 assert_invariants( s );
58}
59
60
61void string_free( string * s )
62{
63 assert_invariants( s );
64 if ( s->value != s->opt )
65 BJAM_FREE( s->value );
66 string_new( s );
67}
68
69
70static void string_reserve_internal( string * self, size_t capacity )
71{
72 if ( self->value == self->opt )
73 {
74 self->value = (char *)BJAM_MALLOC_ATOMIC( capacity +
75 JAM_STRING_MAGIC_SIZE );
76 self->value[ 0 ] = 0;
77 strncat( self->value, self->opt, sizeof(self->opt) );
78 assert( strlen( self->value ) <= self->capacity && "Regression test" );
79 }
80 else
81 {
82 self->value = (char *)BJAM_REALLOC( self->value, capacity +
83 JAM_STRING_MAGIC_SIZE );
84 }
85#ifndef NDEBUG
86 memcpy( self->value + capacity, self->magic, JAM_STRING_MAGIC_SIZE );
87#endif
88 self->capacity = capacity;
89}
90
91
92void string_reserve( string * self, size_t capacity )
93{
94 assert_invariants( self );
95 if ( capacity <= self->capacity )
96 return;
97 string_reserve_internal( self, capacity );
98 assert_invariants( self );
99}
100
101
102static void extend_full( string * self, char const * start, char const * finish )
103{
104 size_t new_size = self->capacity + ( finish - start );
105 size_t new_capacity = self->capacity;
106 size_t old_size = self->capacity;
107 while ( new_capacity < new_size + 1)
108 new_capacity <<= 1;
109 string_reserve_internal( self, new_capacity );
110 memcpy( self->value + old_size, start, new_size - old_size );
111 self->value[ new_size ] = 0;
112 self->size = new_size;
113}
114
115static void maybe_reserve( string * self, size_t new_size )
116{
117 size_t capacity = self->capacity;
118 if ( capacity <= new_size )
119 {
120 size_t new_capacity = capacity;
121 while ( new_capacity <= new_size )
122 new_capacity <<= 1;
123 string_reserve_internal( self, new_capacity );
124 }
125}
126
127
128void string_append( string * self, char const * rhs )
129{
130 size_t rhs_size = strlen( rhs );
131 size_t new_size = self->size + rhs_size;
132 assert_invariants( self );
133
134 maybe_reserve( self, new_size );
135
136 memcpy( self->value + self->size, rhs, rhs_size + 1 );
137 self->size = new_size;
138
139 assert_invariants( self );
140}
141
142
143void string_append_range( string * self, char const * start, char const * finish )
144{
145 size_t rhs_size = finish - start;
146 size_t new_size = self->size + rhs_size;
147 assert_invariants( self );
148
149 maybe_reserve( self, new_size );
150
151 memcpy( self->value + self->size, start, rhs_size );
152 self->size = new_size;
153 self->value[ new_size ] = 0;
154
155 assert_invariants( self );
156}
157
158
159void string_copy( string * s, char const * rhs )
160{
161 string_new( s );
162 string_append( s, rhs );
163}
164
165void string_truncate( string * self, size_t n )
166{
167 assert_invariants( self );
168 assert( n <= self->capacity );
169 self->value[ self->size = n ] = 0;
170 assert_invariants( self );
171}
172
173
174void string_pop_back( string * self )
175{
176 string_truncate( self, self->size - 1 );
177}
178
179
180void string_push_back( string * self, char x )
181{
182 string_append_range( self, &x, &x + 1 );
183}
184
185
186char string_back( string * self )
187{
188 assert_invariants( self );
189 return self->value[ self->size - 1 ];
190}
191
b32b8144
FG
192void string_rtrim( string * self )
193{
194 char *p;
195 assert_invariants( self );
196 p = self->value + self->size - 1;
197 for ( ; p >= self->value && ( *p == '\0' || isspace( *p ) ); *p-- = 0 );
198}
7c673cae
FG
199
200#ifndef NDEBUG
201void string_unit_test()
202{
203 {
204 string s[ 1 ];
205 int i;
206 int const limit = sizeof( s->opt ) * 2 + 2;
207 string_new( s );
208 assert( s->value == s->opt );
209 for ( i = 0; i < limit; ++i )
210 {
211 string_push_back( s, (char)( i + 1 ) );
212 assert( s->size == i + 1 );
213 }
214 assert( s->size == limit );
215 assert( s->value != s->opt );
216 for ( i = 0; i < limit; ++i )
217 assert( s->value[ i ] == (char)( i + 1 ) );
218 string_free( s );
219 }
220
221 {
222 char * const original = " \n\t\v Foo \r\n\v \tBar\n\n\r\r\t\n\v\t \t";
223 string copy[ 1 ];
224 string_copy( copy, original );
225 assert( !strcmp( copy->value, original ) );
226 assert( copy->size == strlen( original ) );
227 string_free( copy );
228 }
b32b8144
FG
229
230 {
231 char * const foo = "Foo ";
232 string foo_copy[ 1 ];
233 string_copy( foo_copy, foo );
234 string_rtrim( foo_copy );
235 assert( !strcmp( foo_copy->value, "Foo" ) );
236
237 string_rtrim( foo_copy );
238 assert( !strcmp( foo_copy->value, "Foo" ) );
239 }
240 {
241 char * const bar = "Bar\0\0\0";
242 string bar_copy[ 1 ];
243 string_copy( bar_copy, bar );
244 string_rtrim( bar_copy );
245 assert( !strcmp( bar_copy->value, "Bar" ) );
246
247 string_rtrim( bar_copy );
248 assert( !strcmp( bar_copy->value, "Bar" ) );
249 }
7c673cae
FG
250}
251#endif