From 1a3cb9d9b0ab24d21d7e4edb70bb4a939f621082 Mon Sep 17 00:00:00 2001 From: Kenneth Heafield Date: Sat, 12 May 2012 14:01:52 -0400 Subject: Give in and copy bjam into cdec source code --- jam-files/engine/strings.c | 201 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 201 insertions(+) create mode 100644 jam-files/engine/strings.c (limited to 'jam-files/engine/strings.c') diff --git a/jam-files/engine/strings.c b/jam-files/engine/strings.c new file mode 100644 index 00000000..89561237 --- /dev/null +++ b/jam-files/engine/strings.c @@ -0,0 +1,201 @@ +/* Copyright David Abrahams 2004. Distributed under the Boost */ +/* Software License, Version 1.0. (See accompanying */ +/* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ + +#include "jam.h" +#include "strings.h" +#include +#include +#include +#include + + +#ifndef NDEBUG +# define JAM_STRING_MAGIC ((char)0xcf) +# define JAM_STRING_MAGIC_SIZE 4 +static void assert_invariants( string* self ) +{ + int i; + + if ( self->value == 0 ) + { + assert( self->size == 0 ); + assert( self->capacity == 0 ); + assert( self->opt[0] == 0 ); + return; + } + + assert( self->size < self->capacity ); + assert( ( self->capacity <= sizeof(self->opt) ) == ( self->value == self->opt ) ); + assert( strlen( self->value ) == self->size ); + + for (i = 0; i < 4; ++i) + { + assert( self->magic[i] == JAM_STRING_MAGIC ); + assert( self->value[self->capacity + i] == JAM_STRING_MAGIC ); + } +} +#else +# define JAM_STRING_MAGIC_SIZE 0 +# define assert_invariants(x) do {} while (0) +#endif + +void string_new( string* s ) +{ + s->value = s->opt; + s->size = 0; + s->capacity = sizeof(s->opt); + s->opt[0] = 0; +#ifndef NDEBUG + memset(s->magic, JAM_STRING_MAGIC, sizeof(s->magic)); +#endif + assert_invariants( s ); +} + +void string_free( string* s ) +{ + assert_invariants( s ); + if ( s->value != s->opt ) + BJAM_FREE( s->value ); + string_new( s ); +} + +static void string_reserve_internal( string* self, size_t capacity ) +{ + if ( self->value == self->opt ) + { + self->value = (char*)BJAM_MALLOC_ATOMIC( capacity + JAM_STRING_MAGIC_SIZE ); + self->value[0] = 0; + strncat( self->value, self->opt, sizeof(self->opt) ); + assert( strlen( self->value ) <= self->capacity ); /* This is a regression test */ + } + else + { + self->value = (char*)BJAM_REALLOC( self->value, capacity + JAM_STRING_MAGIC_SIZE ); + } +#ifndef NDEBUG + memcpy( self->value + capacity, self->magic, JAM_STRING_MAGIC_SIZE ); +#endif + self->capacity = capacity; +} + +void string_reserve( string* self, size_t capacity ) +{ + assert_invariants( self ); + if ( capacity <= self->capacity ) + return; + string_reserve_internal( self, capacity ); + assert_invariants( self ); +} + +static void extend_full( string* self, char const* start, char const* finish ) +{ + size_t new_size = self->capacity + ( finish - start ); + size_t new_capacity = self->capacity; + size_t old_size = self->capacity; + while ( new_capacity < new_size + 1) + new_capacity <<= 1; + string_reserve_internal( self, new_capacity ); + memcpy( self->value + old_size, start, new_size - old_size ); + self->value[new_size] = 0; + self->size = new_size; +} + +void string_append( string* self, char const* rhs ) +{ + char* p = self->value + self->size; + char* end = self->value + self->capacity; + assert_invariants( self ); + + while ( *rhs && p != end) + *p++ = *rhs++; + + if ( p != end ) + { + *p = 0; + self->size = p - self->value; + } + else + { + extend_full( self, rhs, rhs + strlen(rhs) ); + } + assert_invariants( self ); +} + +void string_append_range( string* self, char const* start, char const* finish ) +{ + char* p = self->value + self->size; + char* end = self->value + self->capacity; + assert_invariants( self ); + + while ( p != end && start != finish ) + *p++ = *start++; + + if ( p != end ) + { + *p = 0; + self->size = p - self->value; + } + else + { + extend_full( self, start, finish ); + } + assert_invariants( self ); +} + +void string_copy( string* s, char const* rhs ) +{ + string_new( s ); + string_append( s, rhs ); +} + +void string_truncate( string* self, size_t n ) +{ + assert_invariants( self ); + assert( n <= self->capacity ); + self->value[self->size = n] = 0; + assert_invariants( self ); +} + +void string_pop_back( string* self ) +{ + string_truncate( self, self->size - 1 ); +} + +void string_push_back( string* self, char x ) +{ + string_append_range( self, &x, &x + 1 ); +} + +char string_back( string* self ) +{ + assert_invariants( self ); + return self->value[self->size - 1]; +} + +#ifndef NDEBUG +void string_unit_test() +{ + string s[1]; + int i; + char buffer[sizeof(s->opt) * 2 + 2]; + int limit = sizeof(buffer) > 254 ? 254 : sizeof(buffer); + + string_new(s); + + for (i = 0; i < limit; ++i) + { + string_push_back( s, (char)(i + 1) ); + }; + + for (i = 0; i < limit; ++i) + { + assert( i < s->size ); + assert( s->value[i] == (char)(i + 1)); + } + + string_free(s); + +} +#endif + -- cgit v1.2.3