📄 lists.c
字号:
/*
* Copyright 1993, 1995 Christopher Seiwald.
*
* This file is part of Jam - see jam.c for Copyright information.
*/
# include "jam.h"
# include "newstr.h"
# include "lists.h"
/*
* 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
*/
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,
char *string )
{
LIST *l;
if( DEBUG_LISTS )
printf( "list > %s <\n", 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, copystr( nl->string ) );
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, copystr( l->string ) );
return nl;
}
LIST *
list_sort(
LIST *l)
{
LIST* first = 0;
LIST* second = 0;
LIST* merged = l;
LIST* result;
if (!l)
return L0;
for(;;) {
/* Split the list in two */
LIST** dst = &first;
LIST* src = merged;
for(;;) {
*dst = list_append(*dst, list_new(0, src->string));
if (!src->next)
break;
if (strcmp(src->string, src->next->string) > 0)
{
if (dst == &first)
dst = &second;
else
dst = &first;
}
src = src->next;
}
if (merged != l)
list_free( merged );
merged = 0;
if (second == 0) {
result = first;
break;
}
/* Merge lists 'first' and 'second' into 'merged' and free
'first'/'second'. */
{
LIST* f = first;
LIST* s = second;
while(f && s)
{
if (strcmp(f->string, s->string) < 0)
{
merged = list_append( merged, list_new(0, f->string ));
f = f->next;
}
else
{
merged = list_append( merged, list_new(0, s->string ));
s = s->next;
}
}
merged = list_copy( merged, f );
merged = list_copy( merged, s );
list_free( first );
list_free( second );
first = 0;
second = 0;
}
}
return result;
}
/*
* list_free() - free a list of strings
*/
void
list_free( LIST *head )
{
/* Just tack onto freelist. */
if( head )
{
head->tail->next = freelist;
freelist = head;
}
}
/*
* list_pop_front() - remove the front element from a list of strings
*/
LIST * list_pop_front( LIST *l )
{
LIST * result = l->next;
if( result )
{
result->tail = l->tail;
l->next = L0;
l->tail = l;
}
list_free( l );
return result;
}
/*
* list_print() - print a list of strings to stdout
*/
void
list_print( LIST *l )
{
LIST *p = 0;
for( ; l; p = l, l = list_next( l ) )
if ( p )
printf( "%s ", p->string );
if ( p )
printf( "%s", p->string );
}
/*
* 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;
}
int
list_in(LIST* l, char* value)
{
for(; l; l = l->next)
if (strcmp(l->string, value) == 0)
return 1;
return 0;
}
LIST *
list_unique( LIST *sorted_list)
{
LIST* result = 0;
LIST* last_added = 0;
for(; sorted_list; sorted_list = sorted_list->next)
{
if (!last_added || strcmp(sorted_list->string, last_added->string) != 0)
{
result = list_new(result, sorted_list->string);
last_added = sorted_list;
}
}
return result;
}
/*
* 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] );
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -