view src/dynamicstring.c @ 193:021d145e34e9 noffle

[svn] * src/fetch.c: Only leave articles in the requested list if the error fetching them was fatal. Otherwise article requests will accumulate indefinitely (e.g retrieving through NNTPcache when it can't find the body of an article, now or event. Yes, this happened to me; I had nearly 2000 requests backed up and never being cleared). * src/group.c: The weekend's change introduced code that causes a bus error on Sparc ( *(time_t *)p = xxx ). Replace with a safe memcpy, and also use memcpy when reading the Entry and time items to remove warnings on Sparc compilation.
author bears
date Mon, 22 Oct 2001 14:41:43 +0100
parents e612b263934f
children 24d4cd032da5
line wrap: on
line source

/*
  dynamicstring.c

  $Id: dynamicstring.c 65 2000-05-12 16:52:41Z enz $
*/

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

#include "dynamicstring.h"

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

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

static void
reallocStr( DynStr *self, int max )
{
    ASSERT( max >= 0 );
    if ( max <= self->max )
        return;
    if ( ! ( self->str = (char *)realloc( self->str, (size_t)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( int 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 );
}

int
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 )
{
    int 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, (size_t)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, int n )
{
    int len = self->len;

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

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