]>
git.proxmox.com Git - ceph.git/blob - ceph/src/boost/tools/build/src/engine/strings.c
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 memcpy( self
->value
+ self
->size
, start
, rhs_size
);
152 self
->size
= new_size
;
153 self
->value
[ new_size
] = 0;
155 assert_invariants( self
);
159 void string_copy( string
* s
, char const * rhs
)
162 string_append( s
, rhs
);
165 void string_truncate( string
* self
, size_t n
)
167 assert_invariants( self
);
168 assert( n
<= self
->capacity
);
169 self
->value
[ self
->size
= n
] = 0;
170 assert_invariants( self
);
174 void string_pop_back( string
* self
)
176 string_truncate( self
, self
->size
- 1 );
180 void string_push_back( string
* self
, char x
)
182 string_append_range( self
, &x
, &x
+ 1 );
186 char string_back( string
* self
)
188 assert_invariants( self
);
189 return self
->value
[ self
->size
- 1 ];
192 void string_rtrim( string
* self
)
195 assert_invariants( self
);
196 p
= self
->value
+ self
->size
- 1;
197 for ( ; p
>= self
->value
&& ( *p
== '\0' || isspace( *p
) ); *p
-- = 0 );
201 void string_unit_test()
206 int const limit
= sizeof( s
->opt
) * 2 + 2;
208 assert( s
->value
== s
->opt
);
209 for ( i
= 0; i
< limit
; ++i
)
211 string_push_back( s
, (char)( i
+ 1 ) );
212 assert( s
->size
== i
+ 1 );
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 ) );
222 char * const original
= " \n\t\v Foo \r\n\v \tBar\n\n\r\r\t\n\v\t \t";
224 string_copy( copy
, original
);
225 assert( !strcmp( copy
->value
, original
) );
226 assert( copy
->size
== strlen( original
) );
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" ) );
237 string_rtrim( foo_copy
);
238 assert( !strcmp( foo_copy
->value
, "Foo" ) );
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" ) );
247 string_rtrim( bar_copy
);
248 assert( !strcmp( bar_copy
->value
, "Bar" ) );