/*
* 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() */
#ifdef OPT_DEBUG_MEM_TOTALS_EXT
static long list_bytes = 0;
static long list_allocs = 0;
#endif
#ifdef OPT_IMPROVED_MEMUSE_EXT
#include "mempool.h"
static MEMPOOL* list_pool = NULL;
#endif
/*
* 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
{
#ifdef OPT_IMPROVED_MEMUSE_EXT
if (!list_pool) {
list_pool = mempool_create(sizeof(LIST), &list_allocs);
}
l = mempool_alloc(list_pool);
#else
l = (LIST *)malloc( sizeof( *l ) );
#endif
#ifdef OPT_DEBUG_MEM_TOTALS_EXT
list_bytes += sizeof(*l);
#ifndef OPT_IMPROVED_MEMUSE_EXT
++list_allocs;
#endif
#endif /* OPT_DEBUG_MEM_TOTALS_EXT */
}
/* 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( head )
{
head->tail->next = freelist;
freelist = head;
}
}
/*
* 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] );
}
}
#ifdef OPT_DEBUG_MEM_TOTALS_EXT
void
list_done(void)
{
#ifdef OPT_DEBUG_MEM_TOTALS_EXT
if (DEBUG_MEM || DEBUG_MEM_TOTALS) {
printf("%ldK in list items (%ld allocs)\n",
list_bytes / 1024, list_allocs);
}
#endif
}
#endif /* OPT_DEBUG_MEM_TOTALS_EXT */
| # | 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 | ||