lists.c #4

  • //
  • guest/
  • matt_armstrong/
  • jam/
  • patched_version/
  • lists.c
  • View
  • Commits
  • Open Download .zip Download (5 KB)
/*
 * Copyright 1993, 1995 Christopher Seiwald.
 *
 * This file is part of Jam - see jam.c for Copyright information.
 */

/*
 * lists.c - maintain lists of strings
 *
 * This implementation essentially uses a singly linked list, but
 * guarantees that the head element of every list has a valid pointer
 * to the tail of the list, so the new elements can efficiently and 
 * properly be appended to the end of a list.
 *
 * To avoid massive allocation, list_free() just tacks the whole freed
 * chain onto freelist and list_new() looks on freelist first for an
 * available list struct.  list_free() does not free the strings in the 
 * chain: it lazily lets list_new() do so.
 *
 * 08/23/94 (seiwald) - new list_append()
 * 09/07/00 (seiwald) - documented lol_*() functions
 * 10/22/02 (seiwald) - list_new() now does its own newstr()/copystr()
 * 11/04/02 (seiwald) - const-ing for string literals
 * 12/09/02 (seiwald) - new list_printq() for writing lists to Jambase
 */

# include "jam.h"
# include "newstr.h"
# include "lists.h"

static LIST *freelist = 0;	/* junkpile for list_free() */

/*
 * list_append() - append a list onto another one, returning total
 */

LIST *
list_append( 
	LIST	*l,
	LIST	*nl )
{
	if( !nl )
	{
	    /* Just return l */
	}
	else if( !l )
	{
	    l = nl;
	}
	else
	{
	    /* Graft two non-empty lists. */
	    l->tail->next = nl;
	    l->tail = nl->tail;
	}

	return l;
}

/*
 * list_new() - tack a string onto the end of a list of strings
 */

LIST *
list_new( 
	LIST	*head,
	const char *string,
	int	copy )
{
	LIST *l;

	if( DEBUG_LISTS )
	    printf( "list > %s <\n", string );

	/* Copy/newstr as needed */

	string = copy ? copystr( string ) : newstr( string );

	/* Get list struct from freelist, if one available.  */
	/* Otherwise allocate. */
	/* If from freelist, must free string first */

	if( freelist )
	{
	    l = freelist;
	    freestr( l->string );
	    freelist = freelist->next;
	}
	else
	{
	    l = (LIST *)malloc( sizeof( *l ) );
	}

	/* If first on chain, head points here. */
	/* If adding to chain, tack us on. */
	/* Tail must point to this new, last element. */

	if( !head ) head = l;
	else head->tail->next = l;
	head->tail = l;
	l->next = 0;

	l->string = string;

	return head;
}

/*
 * list_copy() - copy a whole list of strings (nl) onto end of another (l)
 */

LIST *
list_copy( 
	LIST	*l,
	LIST 	*nl )
{
	for( ; nl; nl = list_next( nl ) )
	    l = list_new( l, nl->string, 1 );

	return l;
}

/*
 * list_sublist() - copy a subset of a list of strings
 */

LIST *
list_sublist( 
	LIST	*l,
	int	start,
	int	count )
{
	LIST	*nl = 0;

	for( ; l && start--; l = list_next( l ) )
	    ;

	for( ; l && count--; l = list_next( l ) )
	    nl = list_new( nl, l->string, 1 );

	return nl;
}

/*
 * list_free() - free a list of strings
 */

void
list_free( LIST	*head )
{
#if !defined(PURE) || defined(NT)
	/* Just tack onto freelist. */

#if defined(PURE) || defined(DEBUG)
	{
	    /* just 0 out the string to avoid unintended re-use */
	    LIST* l = head;
	    while ( l )
	    {
		l->string = 0;
		l = l->next;
	    }
	}
#endif
	if( head )
	{
	    head->tail->next = freelist;
	    freelist = head;
	}
#else
	while (head) {
	    LIST* next = head->next;
	    freestr(head->string);
	    free(head);
	    head = next;
	}
#endif
}

/*
 * list_print() - print a list of strings to stdout
 */

void
list_print( LIST *l )
{
	for( ; l; l = list_next( l ) )
	    printf( "%s ", l->string );
}

/*
 * list_printq() - print a list of safely quoted strings to a file
 */

void
list_printq( FILE *out, LIST *l )
{
	/* Dump each word, enclosed in "s */
	/* Suitable for Jambase use. */

	for( ; l; l = list_next( l ) )
	{
	    const char *p = l->string;
	    const char *ep = p + strlen( p );
	    const char *op = p;

	    fputc( '\n', out );
	    fputc( '\t', out );
	    fputc( '"', out );

	    /* Any embedded "'s?  Escape them */

	    while( p = (char *)memchr( op, '"',  ep - op ) )
	    {
		fwrite( op, p - op, 1, out );
		fputc( '\\', out );
		fputc( '"', out );
		op = p + 1;
	    }

	    /* Write remainder */

	    fwrite( op, ep - op, 1, out );
	    fputc( '"', out );
	    fputc( ' ', out );
	}
}

/*
 * list_length() - return the number of items in the list
 */

int
list_length( LIST *l )
{
	int n = 0;

	for( ; l; l = list_next( l ), ++n )
	    ;

	return n;
}

/*
 * lol_init() - initialize a LOL (list of lists)
 */

void
lol_init( LOL *lol )
{
	lol->count = 0;
}

/*
 * lol_add() - append a LIST onto an LOL
 */

void
lol_add( 
	LOL	*lol,
	LIST	*l )
{
	if( lol->count < LOL_MAX )
	    lol->list[ lol->count++ ] = l;
}

/*
 * lol_free() - free the LOL and its LISTs
 */

void
lol_free( LOL *lol )
{
	int i;

	for( i = 0; i < lol->count; i++ )
	    list_free( lol->list[i] );

	lol->count = 0;
}

/*
 * lol_get() - return one of the LISTs in the LOL
 */

LIST *
lol_get( 
	LOL	*lol,
	int	i )
{
	return i < lol->count ? lol->list[i] : 0;
}

/*
 * lol_print() - debug print LISTS separated by ":"
 */

void
lol_print( LOL *lol )
{
	int i;

	for( i = 0; i < lol->count; i++ )
	{
	    if( i )
		printf( " : " );
	    list_print( lol->list[i] );
	}
}
# Change User Description Committed
#10 4047 Matt Armstrong 20% reduction in memory use.
#9 3969 Matt Armstrong Integrate from //guest/matt_armstrong/jam/fix/2/...@3963 -- no
real changes.
#8 3950 Matt Armstrong Integrate from //guest/matt_armstrong/jam/fix/1/...
thru change
3948 and make no changes.
#7 3686 Matt Armstrong Get rid of purify specific code.
#6 3683 Matt Armstrong Checkpoint improved memory use canges.
#5 3656 Matt Armstrong Partial support for a -T flag that prints out more detailed
memory usage statistics.
#4 3327 Matt Armstrong Patchlevel a.c.

Remove OPT_IMPROVE_TEMP_FILE_DELETE_EXT since upstream has a fix.

Implement OPT_FIX_NT_ARSCAN_LEAK to fix a memory leak in the NT arscan
functions.

Get Pure builds running on NT.
#3 3321 Matt Armstrong Under Pure builds, lists are freed immediately.
#2 2507 Matt Armstrong update from the mainline
#1 1270 Matt Armstrong In prep for publishing all my patches to jam.
//guest/perforce_software/jam/src/lists.c
#2 486 Perforce staff Jam 2.3.
 See RELNOTES for a list of changes from 2.2.x.

Just about every source file was touched when jam got ANSI-fied.
#1 2 laura Add Jam/MR 2.2 source