]>
git.proxmox.com Git - ceph.git/blob - ceph/src/boost/tools/build/src/engine/strings.cpp
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) */
14 # define JAM_STRING_MAGIC ((char)0xcf)
15 # define JAM_STRING_MAGIC_SIZE 4
16 static void assert_invariants( string
* self
)
20 if ( self
->value
== 0 )
22 assert( self
->size
== 0 );
23 assert( self
->capacity
== 0 );
24 assert( self
->opt
[ 0 ] == 0 );
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.
34 assert( strlen( self
->value
) <= self
->size
);
36 for ( i
= 0; i
< 4; ++i
)
38 assert( self
->magic
[ i
] == JAM_STRING_MAGIC
);
39 assert( self
->value
[ self
->capacity
+ i
] == JAM_STRING_MAGIC
);
43 # define JAM_STRING_MAGIC_SIZE 0
44 # define assert_invariants(x) do {} while (0)
48 void string_new( string
* s
)
52 s
->capacity
= sizeof( s
->opt
);
55 memset( s
->magic
, JAM_STRING_MAGIC
, sizeof( s
->magic
) );
57 assert_invariants( s
);
61 void string_free( string
* s
)
63 assert_invariants( s
);
64 if ( s
->value
!= s
->opt
)
65 BJAM_FREE( s
->value
);
70 static void string_reserve_internal( string
* self
, size_t capacity
)
72 if ( self
->value
== self
->opt
)
74 self
->value
= (char *)BJAM_MALLOC_ATOMIC( capacity
+
75 JAM_STRING_MAGIC_SIZE
);
77 strncat( self
->value
, self
->opt
, sizeof(self
->opt
) );
78 assert( strlen( self
->value
) <= self
->capacity
&& "Regression test" );
82 self
->value
= (char *)BJAM_REALLOC( self
->value
, capacity
+
83 JAM_STRING_MAGIC_SIZE
);
86 memcpy( self
->value
+ capacity
, self
->magic
, JAM_STRING_MAGIC_SIZE
);
88 self
->capacity
= capacity
;
92 void string_reserve( string
* self
, size_t capacity
)
94 assert_invariants( self
);
95 if ( capacity
<= self
->capacity
)
97 string_reserve_internal( self
, capacity
);
98 assert_invariants( self
);
102 static void extend_full( string
* self
, char const * start
, char const * finish
)
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)
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
;
115 static void maybe_reserve( string
* self
, size_t new_size
)
117 size_t capacity
= self
->capacity
;
118 if ( capacity
<= new_size
)
120 size_t new_capacity
= capacity
;
121 while ( new_capacity
<= new_size
)
123 string_reserve_internal( self
, new_capacity
);
128 void string_append( string
* self
, char const * rhs
)
130 size_t rhs_size
= strlen( rhs
);
131 size_t new_size
= self
->size
+ rhs_size
;
132 assert_invariants( self
);
134 maybe_reserve( self
, new_size
);
136 memcpy( self
->value
+ self
->size
, rhs
, rhs_size
+ 1 );
137 self
->size
= new_size
;
139 assert_invariants( self
);
143 void string_append_range( string
* self
, char const * start
, char const * finish
)
145 size_t rhs_size
= finish
- start
;
146 size_t new_size
= self
->size
+ rhs_size
;
147 assert_invariants( self
);
149 maybe_reserve( self
, new_size
);
151 if ( start
!= finish
)
152 memcpy( self
->value
+ self
->size
, start
, rhs_size
);
153 self
->size
= new_size
;
154 self
->value
[ new_size
] = 0;
156 assert_invariants( self
);
160 void string_copy( string
* s
, char const * rhs
)
163 string_append( s
, rhs
);
166 void string_truncate( string
* self
, size_t n
)
168 assert_invariants( self
);
169 assert( n
<= self
->capacity
);
170 self
->value
[ self
->size
= n
] = 0;
171 assert_invariants( self
);
175 void string_pop_back( string
* self
)
177 string_truncate( self
, self
->size
- 1 );
181 void string_push_back( string
* self
, char x
)
183 string_append_range( self
, &x
, &x
+ 1 );
187 char string_back( string
* self
)
189 assert_invariants( self
);
190 return self
->value
[ self
->size
- 1 ];
193 void string_rtrim( string
* self
)
196 assert_invariants( self
);
197 p
= self
->value
+ self
->size
- 1;
198 for ( ; p
>= self
->value
&& ( *p
== '\0' || isspace( *p
) ); *p
-- = 0 );
202 void string_unit_test()
207 int const limit
= sizeof( s
->opt
) * 2 + 2;
209 assert( s
->value
== s
->opt
);
210 for ( i
= 0; i
< limit
; ++i
)
212 string_push_back( s
, (char)( i
+ 1 ) );
213 assert( s
->size
== i
+ 1 );
215 assert( s
->size
== limit
);
216 assert( s
->value
!= s
->opt
);
217 for ( i
= 0; i
< limit
; ++i
)
218 assert( s
->value
[ i
] == (char)( i
+ 1 ) );
223 const char * const original
= " \n\t\v Foo \r\n\v \tBar\n\n\r\r\t\n\v\t \t";
225 string_copy( copy
, original
);
226 assert( !strcmp( copy
->value
, original
) );
227 assert( copy
->size
== strlen( original
) );
232 const char * const foo
= "Foo ";
233 string foo_copy
[ 1 ];
234 string_copy( foo_copy
, foo
);
235 string_rtrim( foo_copy
);
236 assert( !strcmp( foo_copy
->value
, "Foo" ) );
238 string_rtrim( foo_copy
);
239 assert( !strcmp( foo_copy
->value
, "Foo" ) );
242 const char * const bar
= "Bar\0\0\0";
243 string bar_copy
[ 1 ];
244 string_copy( bar_copy
, bar
);
245 string_rtrim( bar_copy
);
246 assert( !strcmp( bar_copy
->value
, "Bar" ) );
248 string_rtrim( bar_copy
);
249 assert( !strcmp( bar_copy
->value
, "Bar" ) );