]>
git.proxmox.com Git - ceph.git/blob - ceph/src/boost/tools/build/src/engine/jam_strings.cpp
c9ed8a17f0a0903fbdb8b90c63ac89b836ecd751
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) */
6 #include "jam_strings.h"
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 size_t opt_size
= sizeof(self
->opt
); // Workaround sizeof in strncat warning.
78 strncat( self
->value
, self
->opt
, opt_size
);
79 assert( strlen( self
->value
) <= self
->capacity
&& "Regression test" );
83 self
->value
= (char *)BJAM_REALLOC( self
->value
, capacity
+
84 JAM_STRING_MAGIC_SIZE
);
87 memcpy( self
->value
+ capacity
, self
->magic
, JAM_STRING_MAGIC_SIZE
);
89 self
->capacity
= capacity
;
93 void string_reserve( string
* self
, size_t capacity
)
95 assert_invariants( self
);
96 if ( capacity
<= self
->capacity
)
98 string_reserve_internal( self
, capacity
);
99 assert_invariants( self
);
103 static void maybe_reserve( string
* self
, size_t new_size
)
105 size_t capacity
= self
->capacity
;
106 if ( capacity
<= new_size
)
108 size_t new_capacity
= capacity
;
109 while ( new_capacity
<= new_size
)
111 string_reserve_internal( self
, new_capacity
);
116 void string_append( string
* self
, char const * rhs
)
118 size_t rhs_size
= strlen( rhs
);
119 size_t new_size
= self
->size
+ rhs_size
;
120 assert_invariants( self
);
122 maybe_reserve( self
, new_size
);
124 memcpy( self
->value
+ self
->size
, rhs
, rhs_size
+ 1 );
125 self
->size
= new_size
;
127 assert_invariants( self
);
131 void string_append_range( string
* self
, char const * start
, char const * finish
)
133 size_t rhs_size
= finish
- start
;
134 size_t new_size
= self
->size
+ rhs_size
;
135 assert_invariants( self
);
137 maybe_reserve( self
, new_size
);
139 if ( start
!= finish
)
140 memcpy( self
->value
+ self
->size
, start
, rhs_size
);
141 self
->size
= new_size
;
142 self
->value
[ new_size
] = 0;
144 assert_invariants( self
);
148 void string_copy( string
* s
, char const * rhs
)
151 string_append( s
, rhs
);
154 void string_truncate( string
* self
, size_t n
)
156 assert_invariants( self
);
157 assert( n
<= self
->capacity
);
158 self
->value
[ self
->size
= n
] = 0;
159 assert_invariants( self
);
163 void string_pop_back( string
* self
)
165 string_truncate( self
, self
->size
- 1 );
169 void string_push_back( string
* self
, char x
)
171 string_append_range( self
, &x
, &x
+ 1 );
175 char string_back( string
* self
)
177 assert_invariants( self
);
178 return self
->value
[ self
->size
- 1 ];
181 void string_rtrim( string
* self
)
184 assert_invariants( self
);
185 p
= self
->value
+ self
->size
- 1;
186 for ( ; p
>= self
->value
&& ( *p
== '\0' || isspace( *p
) ); *p
-- = 0 );
190 void string_unit_test()
195 unsigned long const limit
= sizeof( s
->opt
) * 2 + 2;
197 assert( s
->value
== s
->opt
);
198 for ( i
= 0; i
< limit
; ++i
)
200 string_push_back( s
, (char)( i
+ 1 ) );
201 assert( s
->size
== i
+ 1 );
203 assert( s
->size
== limit
);
204 assert( s
->value
!= s
->opt
);
205 for ( i
= 0; i
< limit
; ++i
)
206 assert( s
->value
[ i
] == (char)( i
+ 1 ) );
211 const char * const original
= " \n\t\v Foo \r\n\v \tBar\n\n\r\r\t\n\v\t \t";
213 string_copy( copy
, original
);
214 assert( !strcmp( copy
->value
, original
) );
215 assert( copy
->size
== strlen( original
) );
220 const char * const foo
= "Foo ";
221 string foo_copy
[ 1 ];
222 string_copy( foo_copy
, foo
);
223 string_rtrim( foo_copy
);
224 assert( !strcmp( foo_copy
->value
, "Foo" ) );
226 string_rtrim( foo_copy
);
227 assert( !strcmp( foo_copy
->value
, "Foo" ) );
230 const char * const bar
= "Bar\0\0\0";
231 string bar_copy
[ 1 ];
232 string_copy( bar_copy
, bar
);
233 string_rtrim( bar_copy
);
234 assert( !strcmp( bar_copy
->value
, "Bar" ) );
236 string_rtrim( bar_copy
);
237 assert( !strcmp( bar_copy
->value
, "Bar" ) );