mkjambase strips comments at the end of line and spaces before such comments
[k8jam.git] / lists.c
blobfd5d34a1a51df58f83727c9fa186c3aac9562c7b
1 /*
2 * Copyright 1993, 1995 Christopher Seiwald.
4 * This file is part of Jam - see jam.c for Copyright information.
5 */
7 /*
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
27 # include "jam.h"
28 # include "newstr.h"
29 # include "lists.h"
31 static LIST *freelist = 0; /* junkpile for list_free() */
34 * list_append() - append a list onto another one, returning total
37 LIST *
38 list_append(
39 LIST *l,
40 LIST *nl )
42 if( !nl )
44 /* Just return l */
46 else if( !l )
48 l = nl;
50 else
52 /* Graft two non-empty lists. */
53 l->tail->next = nl;
54 l->tail = nl->tail;
57 return l;
61 * list_new() - tack a string onto the end of a list of strings
64 LIST *
65 list_new(
66 LIST *head,
67 const char *string,
68 int copy )
70 LIST *l;
72 if( DEBUG_LISTS )
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 */
83 if( freelist )
85 l = freelist;
86 freestr( l->string );
87 freelist = freelist->next;
89 else
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. */
98 if( !head ) head = l;
99 else head->tail->next = l;
100 head->tail = l;
101 l->next = 0;
103 l->string = string;
105 return head;
109 * list_copy() - copy a whole list of strings (nl) onto end of another (l)
112 LIST *
113 list_copy(
114 LIST *l,
115 LIST *nl )
117 for( ; nl; nl = list_next( nl ) )
118 l = list_new( l, nl->string, 1 );
120 return l;
124 * list_sublist() - copy a subset of a list of strings
127 LIST *
128 list_sublist(
129 LIST *l,
130 int start,
131 int count )
133 LIST *nl = 0;
135 for( ; l && start--; l = list_next( l ) )
138 for( ; l && count--; l = list_next( l ) )
139 nl = list_new( nl, l->string, 1 );
141 return nl;
145 * list_free() - free a list of strings
148 void
149 list_free( LIST *head )
151 /* Just tack onto freelist. */
153 if( head )
155 head->tail->next = freelist;
156 freelist = head;
161 * list_print() - print a list of strings to stdout
164 void
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
175 void
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 );
185 const char *op = p;
187 fputc( '\n', out );
188 fputc( '\t', out );
189 fputc( '"', out );
191 /* Any embedded "'s? Escape them */
193 while( p = (char *)memchr( op, '"', ep - op ) )
195 fwrite( op, p - op, 1, out );
196 fputc( '\\', out );
197 fputc( '"', out );
198 op = p + 1;
201 /* Write remainder */
203 fwrite( op, ep - op, 1, out );
204 fputc( '"', out );
205 fputc( ' ', out );
210 * list_length() - return the number of items in the list
214 list_length( LIST *l )
216 int n = 0;
218 for( ; l; l = list_next( l ), ++n )
221 return n;
225 * lol_init() - initialize a LOL (list of lists)
228 void
229 lol_init( LOL *lol )
231 lol->count = 0;
235 * lol_add() - append a LIST onto an LOL
238 void
239 lol_add(
240 LOL *lol,
241 LIST *l )
243 if( lol->count < LOL_MAX )
244 lol->list[ lol->count++ ] = l;
248 * lol_free() - free the LOL and its LISTs
251 void
252 lol_free( LOL *lol )
254 int i;
256 for( i = 0; i < lol->count; i++ )
257 list_free( lol->list[i] );
259 lol->count = 0;
263 * lol_get() - return one of the LISTs in the LOL
266 LIST *
267 lol_get(
268 LOL *lol,
269 int i )
271 return i < lol->count ? lol->list[i] : 0;
275 * lol_print() - debug print LISTS separated by ":"
278 void
279 lol_print( LOL *lol )
281 int i;
283 for( i = 0; i < lol->count; i++ )
285 if( i )
286 printf( " : " );
287 list_print( lol->list[i] );