2 * Copyright 1993, 1995 Christopher Seiwald.
4 * This file is part of Jam - see jam.c for Copyright information.
8 * lists.c - maintain lists of strings
10 * This implementation essentially uses a singly linked list, but
11 * guarantees that the head element of every list has a valid pointer
12 * to the tail of the list, so the new elements can efficiently and
13 * properly be appended to the end of a list.
15 * To avoid massive allocation, list_free() just tacks the whole freed
16 * chain onto freelist and list_new() looks on freelist first for an
17 * available list struct. list_free() does not free the strings in the
18 * chain: it lazily lets list_new() do so.
20 * 08/23/94 (seiwald) - new list_append()
21 * 09/07/00 (seiwald) - documented lol_*() functions
22 * 10/22/02 (seiwald) - list_new() now does its own newstr()/copystr()
23 * 11/04/02 (seiwald) - const-ing for string literals
24 * 12/09/02 (seiwald) - new list_printq() for writing lists to Jambase
31 static LIST
*freelist
= 0; /* junkpile for list_free() */
34 * list_append() - append a list onto another one, returning total
52 /* Graft two non-empty lists. */
61 * list_new() - tack a string onto the end of a list of strings
73 printf( "list > %s <\n", string
);
75 /* Copy/newstr as needed */
77 string
= copy
? copystr( string
) : newstr( string
);
79 /* Get list struct from freelist, if one available. */
80 /* Otherwise allocate. */
81 /* If from freelist, must free string first */
87 freelist
= freelist
->next
;
91 l
= (LIST
*)malloc( sizeof( *l
) );
94 /* If first on chain, head points here. */
95 /* If adding to chain, tack us on. */
96 /* Tail must point to this new, last element. */
99 else head
->tail
->next
= l
;
109 * list_copy() - copy a whole list of strings (nl) onto end of another (l)
117 for( ; nl
; nl
= list_next( nl
) )
118 l
= list_new( l
, nl
->string
, 1 );
124 * list_sublist() - copy a subset of a list of strings
135 for( ; l
&& start
--; l
= list_next( l
) )
138 for( ; l
&& count
--; l
= list_next( l
) )
139 nl
= list_new( nl
, l
->string
, 1 );
145 * list_free() - free a list of strings
149 list_free( LIST
*head
)
151 /* Just tack onto freelist. */
155 head
->tail
->next
= freelist
;
161 * list_print() - print a list of strings to stdout
165 list_print( LIST
*l
)
167 for( ; l
; l
= list_next( l
) )
168 printf( "%s ", l
->string
);
172 * list_printq() - print a list of safely quoted strings to a file
176 list_printq( FILE *out
, LIST
*l
)
178 /* Dump each word, enclosed in "s */
179 /* Suitable for Jambase use. */
181 for( ; l
; l
= list_next( l
) )
183 const char *p
= l
->string
;
184 const char *ep
= p
+ strlen( p
);
191 /* Any embedded "'s? Escape them */
193 while( p
= (char *)memchr( op
, '"', ep
- op
) )
195 fwrite( op
, p
- op
, 1, out
);
201 /* Write remainder */
203 fwrite( op
, ep
- op
, 1, out
);
210 * list_length() - return the number of items in the list
214 list_length( LIST
*l
)
218 for( ; l
; l
= list_next( l
), ++n
)
225 * lol_init() - initialize a LOL (list of lists)
235 * lol_add() - append a LIST onto an LOL
243 if( lol
->count
< LOL_MAX
)
244 lol
->list
[ lol
->count
++ ] = l
;
248 * lol_free() - free the LOL and its LISTs
256 for( i
= 0; i
< lol
->count
; i
++ )
257 list_free( lol
->list
[i
] );
263 * lol_get() - return one of the LISTs in the LOL
271 return i
< lol
->count
? lol
->list
[i
] : 0;
275 * lol_print() - debug print LISTS separated by ":"
279 lol_print( LOL
*lol
)
283 for( i
= 0; i
< lol
->count
; i
++ )
287 list_print( lol
->list
[i
] );