view src/dynamicstring.c @ 58:b4e6f7f96135 noffle

[svn] Add some intermediate variables for easier debugging in needsMark(). It seems that thread mode is sometimes not working. Changed some variable types and used some casts to avoid compiler warnings about signedness. In general, int should be used for parameters for allowing a signedness assertion in the function.
author enz
date Fri, 12 May 2000 17:52:07 +0100
parents 125d79c9e586
children e612b263934f
line wrap: on
line source

/*
  dynamicstring.c

  $Id: dynamicstring.c 60 2000-05-09 22:28:38Z uh1763 $
*/

#if HAVE_CONFIG_H
#include <config.h>
#endif

#include "dynamicstring.h"

#include <sys/types.h>
#include "log.h"
#include "portable.h"

struct DynStr
{
    size_t len; /* Current length (without trailing '\0') */
    size_t max; /* Max length that fits into buffer (incl. trailing '\0') */
    char *str;
};

static void
reallocStr( DynStr *self, size_t max )
{
    if ( max <= self->max )
        return;
    if ( ! ( self->str = (char *)realloc( self->str, max ) ) )
    {
        Log_err( "Realloc of DynStr failed" );
        exit( EXIT_FAILURE );
    } 
    if ( self->max == 0 ) /* First allocation? */
        *(self->str) = '\0';
    self->max = max;
}

DynStr *
new_DynStr( size_t reserve )
{
    DynStr *s;
    
    if ( ! ( s = malloc( sizeof( DynStr ) ) ) )
    {
        Log_err( "Allocation of DynStr failed" );
        exit( EXIT_FAILURE );
    }
    s->len = 0;
    s->max = 0;
    s->str = NULL;
    if ( reserve > 0 )
        reallocStr( s, reserve + 1 );
    return s;
}

void
del_DynStr( DynStr *self )
{
    if ( ! self )
        return;
    free( self->str );
    self->str = NULL;
    free( self );
}

size_t
DynStr_len( const DynStr *self )
{
    return self->len;
}

const char *
DynStr_str( const DynStr *self )
{
    return self->str;
}

void
DynStr_app( DynStr *self, const char *s )
{
    size_t len;

    len = strlen( s );
    if ( self->len + len + 1 > self->max )
        reallocStr( self, self->len * 2 + len + 1 );
    strcpy( self->str + self->len, s );
    self->len += len;
}

void
DynStr_appDynStr( DynStr *self, const DynStr *s )
{
    if ( self->len + s->len + 1 > self->max )
        reallocStr( self, self->len * 2 + s->len + 1 );
    memcpy( self->str + self->len, s->str, s->len + 1 );
    self->len += s->len;
}

void
DynStr_appLn( DynStr *self, const char *s )
{
    DynStr_app( self, s );
    DynStr_app( self, "\n" );
}

void
DynStr_appN( DynStr *self, const char *s, size_t n )
{
    size_t len = self->len;

    if ( len + n + 1 > self->max )
        reallocStr( self, len * 2 + n + 1 );
    strncat( self->str + len, s, n );
    self->len = len + strlen( self->str + len );
}

void
DynStr_clear( DynStr *self )
{
    self->len = 0;
    if ( self->max > 0 )
        *(self->str) = '\0';
}