view src/itemlist.c @ 244:4e69e9b722ae noffle

[svn] * src/database.c,src/protocol.c,src/util.c,src/util.h: The latest IETF article format draft draft-ietf-usefor-article-06.txt recommends that Xref: references contain the FQDN of the server. We were using the host name without the domain. So split the routine used for obtaining the FQDN from protocol.c into util.c, and use it when adding Xrefs.
author bears
date Fri, 15 Mar 2002 10:50:33 +0000
parents 24d4cd032da5
children 5eece4dfd945
line wrap: on
line source

/*
  itemlist.c

  $Id: itemlist.c 316 2001-10-31 11:44:53Z bears $
*/

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

#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#include "common.h"
#include "itemlist.h"
#include "log.h"
#include "portable.h"

#if defined(ITEMLIST_TEST)
#define	Log_err	printf
#endif

#define	SEP_CHAR	'\1'	/* Replace all separators with this */

struct ItemList
{
    char *list;
    char *next;
    size_t count;
};

/* Make a new item list. */
ItemList *
new_Itl( const char *list, const char *separators )
{
    ItemList * res;
    char *p;
    Bool inItem;

    res = malloc( sizeof( ItemList ) );
    if ( res == NULL )
    {
	Log_err( "Malloc of ItemList failed." );
	exit( EXIT_FAILURE );
    }
    
    res->list = malloc ( strlen(list) + 2 );
    if ( res->list == NULL )
    {
	Log_err( "Malloc of ItemList.list failed." );
	exit( EXIT_FAILURE );
    }
    strcpy( res->list, list );

    res->count = 0;
    res->next = res->list;

    /* Separate items into strings and have final zero-length string. */
    for( p = res->list, inItem = FALSE; *p != '\0'; p++ )
    {
	Bool isSep = ( strchr( separators, p[ 0 ] ) != NULL );
	
	if ( inItem )
	{
	    if ( isSep )
	    {
		p[ 0 ] = '\0';
		inItem = FALSE;
		res->count++;
	    }
	}
	else
	{
	    if ( isSep )
		p[ 0 ] = SEP_CHAR;
	    else
		inItem = TRUE;
	}
    }
    if ( inItem )
	res->count++;
    p[ 1 ] = '\0';
    return res;
}

/* Delete an item list. */
void
del_Itl( ItemList *self )
{
    if ( self == NULL )
	return;
    free( self->list );
    free( self );
}

/* Get first item. */
const char *
Itl_first( ItemList *self)
{
    self->next = self->list;
    return Itl_next( self );
}

/* Get next item or NULL. */
const char *
Itl_next( ItemList *self )
{
    char *res = self->next;

    if ( res[ 0 ] == '\0' )
	return NULL;

    while ( res[ 0 ] == SEP_CHAR )
	res++;

    if ( res[ 0 ] == '\0' && res[ 1 ] == '\0' )
	return NULL;

    self->next = res + strlen( res ) + 1;
    return res;
}

/* Get count of items in list. */
size_t
Itl_count( const ItemList *self )
{
    return self->count;
}

#if defined(ITEMLIST_TEST)

/* Test code borrowed from wildmat.c. Yep, still uses gets(). */
extern char	*gets();

int
main()
{
    Str line;
    Str seps;
    ItemList * itl;
    int count;
    const char *item;

    printf( "Itemlist tester.  Enter seperators, then strings to test.\n" );
    printf( "A blank line gets prompts for new seperators; blank separators\n" );
    printf( "exits the program.\n" );

    for ( ; ; )
    {
	printf( "\nEnter seperators:  " );
	(void) fflush( stdout );
	if ( gets( seps ) == NULL || seps[0] == '\0' )
	    break;
	for ( ; ; )
	{
	    printf( "Enter line:  " );
	    (void) fflush( stdout );
	    if ( gets( line ) == NULL )
		exit( 0 );
	    if ( line[0] == '\0' )
		break;
	    itl = new_Itl( line, seps );
	    printf( "%d items on list\n", Itl_count( itl ) );
	    count = 0;
	    for ( item = Itl_first( itl );
		  item != NULL;
		  item = Itl_next( itl ) )
		printf( "  Item %d is '%s'\n", ++count, item );
	    if ( count != Itl_count( itl ) )
		printf( "*** Warning - counts don't match ***\n" );
	    del_Itl( itl );
	}
    }

    exit(0);
    /* NOTREACHED */
}
#endif	/* defined(TEST) */