1da2e3ebdSchin /***********************************************************************
2da2e3ebdSchin *                                                                      *
3da2e3ebdSchin *               This software is part of the ast package               *
4*b30d1939SAndy Fiddaman *          Copyright (c) 1985-2012 AT&T Intellectual Property          *
5da2e3ebdSchin *                      and is licensed under the                       *
6*b30d1939SAndy Fiddaman *                 Eclipse Public License, Version 1.0                  *
77c2fbfb3SApril Chin *                    by AT&T Intellectual Property                     *
8da2e3ebdSchin *                                                                      *
9da2e3ebdSchin *                A copy of the License is available at                 *
10*b30d1939SAndy Fiddaman *          http://www.eclipse.org/org/documents/epl-v10.html           *
11*b30d1939SAndy Fiddaman *         (with md5 checksum b35adb5213ca9657e911e9befb180842)         *
12da2e3ebdSchin *                                                                      *
13da2e3ebdSchin *              Information and Software Systems Research               *
14da2e3ebdSchin *                            AT&T Research                             *
15da2e3ebdSchin *                           Florham Park NJ                            *
16da2e3ebdSchin *                                                                      *
17da2e3ebdSchin *                 Glenn Fowler <gsf@research.att.com>                  *
18da2e3ebdSchin *                  David Korn <dgk@research.att.com>                   *
19da2e3ebdSchin *                   Phong Vo <kpv@research.att.com>                    *
20da2e3ebdSchin *                                                                      *
21da2e3ebdSchin ***********************************************************************/
22da2e3ebdSchin #pragma prototyped
23da2e3ebdSchin 
24da2e3ebdSchin /*
25da2e3ebdSchin  * Glenn Fowler
26da2e3ebdSchin  * AT&T Research
27da2e3ebdSchin  *
28da2e3ebdSchin  * generate a license comment -- see proto(1)
29da2e3ebdSchin  *
30da2e3ebdSchin  * NOTE: coded for minimal library dependence
31da2e3ebdSchin  *	 not so for the legal department
32da2e3ebdSchin  */
33da2e3ebdSchin 
34da2e3ebdSchin #ifndef	_PPLIB_H
35da2e3ebdSchin #include <ast.h>
36da2e3ebdSchin #include <time.h>
37da2e3ebdSchin #endif
38da2e3ebdSchin 
39*b30d1939SAndy Fiddaman #ifndef O_cloexec
40*b30d1939SAndy Fiddaman #ifdef	O_CLOEXEC
41*b30d1939SAndy Fiddaman #define O_cloexec		0
42*b30d1939SAndy Fiddaman #else
43*b30d1939SAndy Fiddaman #define O_cloexec		0
44*b30d1939SAndy Fiddaman #endif
45*b30d1939SAndy Fiddaman #endif
46*b30d1939SAndy Fiddaman 
47da2e3ebdSchin #undef	copy
48da2e3ebdSchin #undef	BSD			/* guess who defines this */
49da2e3ebdSchin #undef	END
50da2e3ebdSchin #undef	INLINE
51da2e3ebdSchin #undef	TEST
52da2e3ebdSchin #undef	VERBOSE
53da2e3ebdSchin 
54da2e3ebdSchin #define NONE			0
55da2e3ebdSchin #define INLINE			1
56da2e3ebdSchin #define TEST			2
57da2e3ebdSchin #define VERBOSE			3
58da2e3ebdSchin #define USAGE			4
59da2e3ebdSchin #define OPEN			5
60da2e3ebdSchin #define CPL			6
613e14f97fSRoger A. Faulkner #define EPL			7
623e14f97fSRoger A. Faulkner #define BSD			8
633e14f97fSRoger A. Faulkner #define ZLIB			9
643e14f97fSRoger A. Faulkner #define MIT			10
653e14f97fSRoger A. Faulkner #define GPL			11
663e14f97fSRoger A. Faulkner #define SPECIAL			12
673e14f97fSRoger A. Faulkner #define NONEXCLUSIVE		13
683e14f97fSRoger A. Faulkner #define NONCOMMERCIAL		14
693e14f97fSRoger A. Faulkner #define PROPRIETARY		15
70da2e3ebdSchin 
71da2e3ebdSchin #define AUTHOR			0
72da2e3ebdSchin #define CLASS			1
73da2e3ebdSchin #define COMPANY			2
74*b30d1939SAndy Fiddaman #define COMPONENT		3
75*b30d1939SAndy Fiddaman #define CONTRIBUTOR		4
76*b30d1939SAndy Fiddaman #define CORPORATION		5
77*b30d1939SAndy Fiddaman #define DOMAIN			6
78*b30d1939SAndy Fiddaman #define ID			7
79*b30d1939SAndy Fiddaman #define INCORPORATION		8
80*b30d1939SAndy Fiddaman #define LICENSE			9
81*b30d1939SAndy Fiddaman #define LOCATION		10
82*b30d1939SAndy Fiddaman #define NAME			11
83*b30d1939SAndy Fiddaman #define NOTICE			12
84*b30d1939SAndy Fiddaman #define ORGANIZATION		13
85*b30d1939SAndy Fiddaman #define PACKAGE			14
86*b30d1939SAndy Fiddaman #define PARENT			15
87*b30d1939SAndy Fiddaman #define QUERY			16
88*b30d1939SAndy Fiddaman #define SINCE			17
89*b30d1939SAndy Fiddaman #define SOURCE			18
90*b30d1939SAndy Fiddaman #define START			19
91*b30d1939SAndy Fiddaman #define STYLE			20
92*b30d1939SAndy Fiddaman #define URL			21
93*b30d1939SAndy Fiddaman #define URLMD5			22
94*b30d1939SAndy Fiddaman #define VERSION			23
95da2e3ebdSchin 
96da2e3ebdSchin #define IDS			64
97da2e3ebdSchin 
98da2e3ebdSchin #define COMDATA			70
99da2e3ebdSchin #define COMLINE			(COMDATA+4)
100da2e3ebdSchin #define COMLONG			(COMDATA-32)
101da2e3ebdSchin #define COMMENT(x,b,s,u)	comment(x,b,s,sizeof(s)-1,u)
102da2e3ebdSchin 
103da2e3ebdSchin #define PUT(b,c)		(((b)->nxt<(b)->end)?(*(b)->nxt++=(c)):((c),(-1)))
104da2e3ebdSchin #define BUF(b)			((b)->buf)
105da2e3ebdSchin #define USE(b)			((b)->siz=(b)->nxt-(b)->buf,(b)->nxt=(b)->buf,(b)->siz)
106da2e3ebdSchin #define SIZ(b)			((b)->nxt-(b)->buf)
107da2e3ebdSchin #define END(b)			(*((b)->nxt>=(b)->end?((b)->nxt=(b)->end-1):(b)->nxt)=0,(b)->nxt-(b)->buf)
108da2e3ebdSchin 
109da2e3ebdSchin #ifndef NiL
110da2e3ebdSchin #define NiL			((char*)0)
111da2e3ebdSchin #endif
112da2e3ebdSchin 
113da2e3ebdSchin typedef struct Buffer_s
114da2e3ebdSchin {
115da2e3ebdSchin 	char*		buf;
116da2e3ebdSchin 	char*		nxt;
117da2e3ebdSchin 	char*		end;
118da2e3ebdSchin 	int		siz;
119da2e3ebdSchin } Buffer_t;
120da2e3ebdSchin 
121da2e3ebdSchin typedef struct Item_s
122da2e3ebdSchin {
123da2e3ebdSchin 	char*		data;
124da2e3ebdSchin 	int		size;
125da2e3ebdSchin 	int		quote;
126da2e3ebdSchin } Item_t;
127da2e3ebdSchin 
128da2e3ebdSchin typedef struct Id_s
129da2e3ebdSchin {
130da2e3ebdSchin 	Item_t		name;
131da2e3ebdSchin 	Item_t		value;
132da2e3ebdSchin } Id_t;
133da2e3ebdSchin 
134da2e3ebdSchin /*
135da2e3ebdSchin  * NOTE: key[] element order must match the corresponding macro
136da2e3ebdSchin  */
137da2e3ebdSchin 
138da2e3ebdSchin #define KEY(s)			{s,sizeof(s)-1,0}
139da2e3ebdSchin 
140da2e3ebdSchin static const Item_t	key[] =
141da2e3ebdSchin {
142da2e3ebdSchin 	KEY("author"),
143da2e3ebdSchin 	KEY("class"),
144da2e3ebdSchin 	KEY("company"),
145*b30d1939SAndy Fiddaman 	KEY("component"),
146da2e3ebdSchin 	KEY("contributor"),
147da2e3ebdSchin 	KEY("corporation"),
148da2e3ebdSchin 	KEY("domain"),
149*b30d1939SAndy Fiddaman 	KEY("id"),
150da2e3ebdSchin 	KEY("incorporation"),
151da2e3ebdSchin 	KEY("license"),
152da2e3ebdSchin 	KEY("location"),
153*b30d1939SAndy Fiddaman 	KEY("name"),
154da2e3ebdSchin 	KEY("notice"),
155da2e3ebdSchin 	KEY("organization"),
156da2e3ebdSchin 	KEY("package"),
157da2e3ebdSchin 	KEY("parent"),
158da2e3ebdSchin 	KEY("query"),
159da2e3ebdSchin 	KEY("since"),
160*b30d1939SAndy Fiddaman 	KEY("source"),
161*b30d1939SAndy Fiddaman 	KEY("start"),
162da2e3ebdSchin 	KEY("type"),
163da2e3ebdSchin 	KEY("url"),
164da2e3ebdSchin 	KEY("urlmd5"),
165da2e3ebdSchin 	KEY("version"),
166da2e3ebdSchin 	{0}
167da2e3ebdSchin };
168da2e3ebdSchin 
169da2e3ebdSchin #define ITEMS			(sizeof(key)/sizeof(key[0])-1)
170da2e3ebdSchin 
171da2e3ebdSchin #define LIC(s,c)		{s,sizeof(s)-1,c}
172da2e3ebdSchin 
173da2e3ebdSchin static const Item_t	lic[] =
174da2e3ebdSchin {
175da2e3ebdSchin 	LIC("none", NONE),
176da2e3ebdSchin 	LIC("inline", SPECIAL),
177da2e3ebdSchin 	LIC("test", TEST),
178da2e3ebdSchin 	LIC("verbose", VERBOSE),
179da2e3ebdSchin 	LIC("usage", USAGE),
180da2e3ebdSchin 	LIC("open", OPEN),
181da2e3ebdSchin 	LIC("cpl", OPEN),
1823e14f97fSRoger A. Faulkner 	LIC("epl", OPEN),
183da2e3ebdSchin 	LIC("bsd", OPEN),
184da2e3ebdSchin 	LIC("zlib", OPEN),
185da2e3ebdSchin 	LIC("mit", OPEN),
186da2e3ebdSchin 	LIC("gpl", GPL),
187da2e3ebdSchin 	LIC("special", SPECIAL),
188da2e3ebdSchin 	LIC("nonexclusive", SPECIAL),
189da2e3ebdSchin 	LIC("noncommercial", SPECIAL),
190da2e3ebdSchin 	LIC("proprietary", PROPRIETARY),
191da2e3ebdSchin 	{0}
192da2e3ebdSchin };
193da2e3ebdSchin 
194da2e3ebdSchin typedef struct Notice_s
195da2e3ebdSchin {
196da2e3ebdSchin 	int		test;
197da2e3ebdSchin 	int		type;
198da2e3ebdSchin 	int		verbose;
199da2e3ebdSchin 	int		ids;
200da2e3ebdSchin 	Item_t		item[ITEMS];
201da2e3ebdSchin 	Id_t		id[IDS];
202da2e3ebdSchin 	char		cc[3];
203da2e3ebdSchin } Notice_t;
204da2e3ebdSchin 
205da2e3ebdSchin /*
206da2e3ebdSchin  * return index given <name,size>
207da2e3ebdSchin  */
208da2e3ebdSchin 
209da2e3ebdSchin static int
lookup(register const Item_t * item,const char * name,int size)210da2e3ebdSchin lookup(register const Item_t* item, const char* name, int size)
211da2e3ebdSchin {
212da2e3ebdSchin 	register int	c;
213da2e3ebdSchin 	register int	i;
214da2e3ebdSchin 
215da2e3ebdSchin 	c = name[0];
216da2e3ebdSchin 	for (i = 0; item[i].data; i++)
217da2e3ebdSchin 		if (c == item[i].data[0] && size == item[i].size && !strncmp(name, item[i].data, size))
218da2e3ebdSchin 			return i;
219da2e3ebdSchin 	return -1;
220da2e3ebdSchin }
221da2e3ebdSchin 
222da2e3ebdSchin /*
223da2e3ebdSchin  * copy s of size n to b
224da2e3ebdSchin  * n<0 means 0 terminated string
225da2e3ebdSchin  */
226da2e3ebdSchin 
227da2e3ebdSchin static void
copy(register Buffer_t * b,register char * s,int n)228da2e3ebdSchin copy(register Buffer_t* b, register char* s, int n)
229da2e3ebdSchin {
230da2e3ebdSchin 	if (n < 0)
231da2e3ebdSchin 		n = strlen(s);
232da2e3ebdSchin 	while (n--)
233da2e3ebdSchin 		PUT(b, *s++);
234da2e3ebdSchin }
235da2e3ebdSchin 
236da2e3ebdSchin /*
237da2e3ebdSchin  * center and copy comment line s to p
238da2e3ebdSchin  * if s==0 then
239da2e3ebdSchin  *	n>0	first frame line
240da2e3ebdSchin  *	n=0	blank line
241da2e3ebdSchin  *	n<0	last frame line
242da2e3ebdSchin  * if u>0 then s converted to upper case
243da2e3ebdSchin  * if u<0 then s is left justified
244da2e3ebdSchin  */
245da2e3ebdSchin 
246da2e3ebdSchin static void
comment(Notice_t * notice,register Buffer_t * b,register char * s,register int n,int u)247da2e3ebdSchin comment(Notice_t* notice, register Buffer_t* b, register char* s, register int n, int u)
248da2e3ebdSchin {
249da2e3ebdSchin 	register int	i;
250da2e3ebdSchin 	register int	m;
251da2e3ebdSchin 	register int	x;
252da2e3ebdSchin 	int		cc;
253da2e3ebdSchin 
254da2e3ebdSchin 	cc = notice->cc[1];
255da2e3ebdSchin 	if (!s)
256da2e3ebdSchin 	{
257da2e3ebdSchin 		if (n)
258da2e3ebdSchin 		{
259da2e3ebdSchin 			PUT(b, notice->cc[n > 0 ? 0 : 1]);
260da2e3ebdSchin 			for (i = 0; i < COMDATA; i++)
261da2e3ebdSchin 				PUT(b, cc);
262da2e3ebdSchin 			PUT(b, notice->cc[n > 0 ? 1 : 2]);
263da2e3ebdSchin 		}
264da2e3ebdSchin 		else
265da2e3ebdSchin 			s = "";
266da2e3ebdSchin 	}
267da2e3ebdSchin 	if (s)
268da2e3ebdSchin 	{
269da2e3ebdSchin 		if (n > COMDATA)
270da2e3ebdSchin 			n = COMDATA;
271da2e3ebdSchin 		PUT(b, cc);
272da2e3ebdSchin 		m = (u < 0) ? 1 : (COMDATA - n) / 2;
273da2e3ebdSchin 		if ((x = COMDATA - m - n) < 0)
274da2e3ebdSchin 			n--;
275da2e3ebdSchin 		while (m-- > 0)
276da2e3ebdSchin 			PUT(b, ' ');
277da2e3ebdSchin 		while (n-- > 0)
278da2e3ebdSchin 		{
279da2e3ebdSchin 			i = *s++;
280da2e3ebdSchin 			if (u > 0 && i >= 'a' && i <= 'z')
281da2e3ebdSchin 				i = i - 'a' + 'A';
282da2e3ebdSchin 			PUT(b, i);
283da2e3ebdSchin 		}
284da2e3ebdSchin 		while (x-- > 0)
285da2e3ebdSchin 			PUT(b, ' ');
286da2e3ebdSchin 		PUT(b, cc);
287da2e3ebdSchin 	}
288da2e3ebdSchin 	PUT(b, '\n');
289da2e3ebdSchin }
290da2e3ebdSchin 
291da2e3ebdSchin /*
292da2e3ebdSchin  * expand simple ${...}
293da2e3ebdSchin  */
294da2e3ebdSchin 
295da2e3ebdSchin static void
expand(Notice_t * notice,register Buffer_t * b,const Item_t * item)296da2e3ebdSchin expand(Notice_t* notice, register Buffer_t* b, const Item_t* item)
297da2e3ebdSchin {
298da2e3ebdSchin 	register char*	t;
299da2e3ebdSchin 	register char*	e;
300da2e3ebdSchin 	register int	q;
301da2e3ebdSchin 	register char*	x;
302da2e3ebdSchin 	register char*	z;
303da2e3ebdSchin 	register int	c;
3043e14f97fSRoger A. Faulkner 	int		m;
305*b30d1939SAndy Fiddaman 	int		i;
306*b30d1939SAndy Fiddaman 	int		k;
307da2e3ebdSchin 
308da2e3ebdSchin 	if (t = item->data)
309da2e3ebdSchin 	{
310da2e3ebdSchin 		q = item->quote;
311da2e3ebdSchin 		e = t + item->size;
312*b30d1939SAndy Fiddaman 		i = 0;
313da2e3ebdSchin 		while (t < e)
314da2e3ebdSchin 		{
315da2e3ebdSchin 			if (*t == '$' && t < (e + 2) && *(t + 1) == '{')
316da2e3ebdSchin 			{
317*b30d1939SAndy Fiddaman 				k = m = 0;
318da2e3ebdSchin 				x = t += 2;
319da2e3ebdSchin 				while (t < e && (c = *t++) != '}')
320da2e3ebdSchin 					if (c == '.')
321da2e3ebdSchin 						x = t;
322*b30d1939SAndy Fiddaman 					else if (c == '-')
323*b30d1939SAndy Fiddaman 					{
324*b30d1939SAndy Fiddaman 						k = 1;
325*b30d1939SAndy Fiddaman 						break;
326*b30d1939SAndy Fiddaman 					}
3273e14f97fSRoger A. Faulkner 					else if (c == '/')
3283e14f97fSRoger A. Faulkner 					{
3293e14f97fSRoger A. Faulkner 						m = 1;
3303e14f97fSRoger A. Faulkner 						break;
3313e14f97fSRoger A. Faulkner 					}
332da2e3ebdSchin 				if ((c = lookup(key, x, t - x - 1)) >= 0 && (x = notice->item[c].data))
333da2e3ebdSchin 				{
334da2e3ebdSchin 					z = x + notice->item[c].size;
335da2e3ebdSchin 					while (x < z)
3363e14f97fSRoger A. Faulkner 					{
3373e14f97fSRoger A. Faulkner 						c = *x++;
3383e14f97fSRoger A. Faulkner 						if (!m || c >= '0' && c <= '9')
3393e14f97fSRoger A. Faulkner 							PUT(b, c);
3403e14f97fSRoger A. Faulkner 					}
341da2e3ebdSchin 				}
342*b30d1939SAndy Fiddaman 				else if (k)
343*b30d1939SAndy Fiddaman 				{
344*b30d1939SAndy Fiddaman 					k = 0;
345*b30d1939SAndy Fiddaman 					i++;
346*b30d1939SAndy Fiddaman 				}
347*b30d1939SAndy Fiddaman 				if (k || m)
348*b30d1939SAndy Fiddaman 				{
349*b30d1939SAndy Fiddaman 					k = 1;
350*b30d1939SAndy Fiddaman 					while (t < e)
351*b30d1939SAndy Fiddaman 						if ((c = *t++) == '{')
352*b30d1939SAndy Fiddaman 							k++;
353*b30d1939SAndy Fiddaman 						else if (c == '}' && !--k)
354*b30d1939SAndy Fiddaman 							break;
355*b30d1939SAndy Fiddaman 				}
356da2e3ebdSchin 			}
357da2e3ebdSchin 			else if (q > 0 && *t == '\\' && (*(t + 1) == q || *(t + 1) == '\\'))
358da2e3ebdSchin 				t++;
359*b30d1939SAndy Fiddaman 			else if (*t == '}' && i)
360*b30d1939SAndy Fiddaman 			{
361*b30d1939SAndy Fiddaman 				t++;
362*b30d1939SAndy Fiddaman 				i--;
363*b30d1939SAndy Fiddaman 			}
364da2e3ebdSchin 			else
365da2e3ebdSchin 				PUT(b, *t++);
366da2e3ebdSchin 		}
367da2e3ebdSchin 	}
368da2e3ebdSchin }
369da2e3ebdSchin 
370da2e3ebdSchin /*
371da2e3ebdSchin  * generate a copright notice
372da2e3ebdSchin  */
373da2e3ebdSchin 
374da2e3ebdSchin static void
copyright(Notice_t * notice,register Buffer_t * b)375da2e3ebdSchin copyright(Notice_t* notice, register Buffer_t* b)
376da2e3ebdSchin {
377da2e3ebdSchin 	register char*	x;
378da2e3ebdSchin 	register char*	t;
379da2e3ebdSchin 	time_t		clock;
380da2e3ebdSchin 
381da2e3ebdSchin 	copy(b, "Copyright (c) ", -1);
382da2e3ebdSchin 	if (notice->test)
383*b30d1939SAndy Fiddaman 	{
384da2e3ebdSchin 		clock = (time_t)1000212300;
385*b30d1939SAndy Fiddaman 		t = ctime(&clock) + 20;
386*b30d1939SAndy Fiddaman 	}
387*b30d1939SAndy Fiddaman 	else if (!(t = notice->item[SOURCE].data))
388*b30d1939SAndy Fiddaman 	{
389da2e3ebdSchin 		time(&clock);
390*b30d1939SAndy Fiddaman 		t = ctime(&clock) + 20;
391*b30d1939SAndy Fiddaman 	}
392*b30d1939SAndy Fiddaman 	if ((x = notice->item[START].data) && strncmp(t, x, 4) < 0)
393*b30d1939SAndy Fiddaman 		t = x;
394*b30d1939SAndy Fiddaman 	if ((x = notice->item[SINCE].data) && strncmp(x, t, 4) < 0)
395da2e3ebdSchin 	{
396da2e3ebdSchin 		expand(notice, b, &notice->item[SINCE]);
397da2e3ebdSchin 		PUT(b, '-');
398da2e3ebdSchin 	}
399da2e3ebdSchin 	copy(b, t, 4);
400da2e3ebdSchin 	if (notice->item[PARENT].data)
401da2e3ebdSchin 	{
402da2e3ebdSchin 		PUT(b, ' ');
403da2e3ebdSchin 		expand(notice, b, &notice->item[PARENT]);
404da2e3ebdSchin 	}
405da2e3ebdSchin 	if (notice->item[CORPORATION].data)
406da2e3ebdSchin 	{
407da2e3ebdSchin 		PUT(b, ' ');
408da2e3ebdSchin 		expand(notice, b, &notice->item[CORPORATION]);
409da2e3ebdSchin 		if (notice->item[INCORPORATION].data)
410da2e3ebdSchin 		{
411da2e3ebdSchin 			PUT(b, ' ');
412da2e3ebdSchin 			expand(notice, b, &notice->item[INCORPORATION]);
413da2e3ebdSchin 		}
414da2e3ebdSchin 	}
415da2e3ebdSchin 	else if (notice->item[COMPANY].data)
416da2e3ebdSchin 	{
417da2e3ebdSchin 		PUT(b, ' ');
418da2e3ebdSchin 		expand(notice, b, &notice->item[COMPANY]);
419da2e3ebdSchin 	}
420da2e3ebdSchin }
421da2e3ebdSchin 
422*b30d1939SAndy Fiddaman typedef struct Stack_s
423*b30d1939SAndy Fiddaman {
424*b30d1939SAndy Fiddaman 	char*	info;
425*b30d1939SAndy Fiddaman 	char*	file;
426*b30d1939SAndy Fiddaman 	int	line;
427*b30d1939SAndy Fiddaman 	int	size;
428*b30d1939SAndy Fiddaman } Stack_t;
429*b30d1939SAndy Fiddaman 
430*b30d1939SAndy Fiddaman static int
push(Stack_t * sp,char * file,char * parent,char * info,int size,Buffer_t * buf)431*b30d1939SAndy Fiddaman push(Stack_t* sp, char* file, char* parent, char* info, int size, Buffer_t* buf)
432*b30d1939SAndy Fiddaman {
433*b30d1939SAndy Fiddaman 	char*		s;
434*b30d1939SAndy Fiddaman 	char*		t;
435*b30d1939SAndy Fiddaman 	int		i;
436*b30d1939SAndy Fiddaman 	int		n;
437*b30d1939SAndy Fiddaman 	char		path[1024];
438*b30d1939SAndy Fiddaman 
439*b30d1939SAndy Fiddaman 	if (size <= 8)
440*b30d1939SAndy Fiddaman 	{
441*b30d1939SAndy Fiddaman 		copy(buf, file, -1);
442*b30d1939SAndy Fiddaman 		copy(buf, ": no space", -1);
443*b30d1939SAndy Fiddaman 		PUT(buf, 0);
444*b30d1939SAndy Fiddaman 		return -1;
445*b30d1939SAndy Fiddaman 	}
446*b30d1939SAndy Fiddaman 	if (*file != '/' && parent && (s = strrchr(parent, '/')))
447*b30d1939SAndy Fiddaman 	{
448*b30d1939SAndy Fiddaman 		n = s - parent + 1;
449*b30d1939SAndy Fiddaman 		if ((strlen(file) + n + 1) <= sizeof(path))
450*b30d1939SAndy Fiddaman 		{
451*b30d1939SAndy Fiddaman 			memcpy(path, parent, n);
452*b30d1939SAndy Fiddaman 			strcpy(path + n, file);
453*b30d1939SAndy Fiddaman 			file = path;
454*b30d1939SAndy Fiddaman 		}
455*b30d1939SAndy Fiddaman 	}
456*b30d1939SAndy Fiddaman 	if ((i = open(file, O_RDONLY|O_cloexec)) < 0)
457*b30d1939SAndy Fiddaman 	{
458*b30d1939SAndy Fiddaman 		/* this hack viewpath lookup works for default package setups */
459*b30d1939SAndy Fiddaman 		if (file == path)
460*b30d1939SAndy Fiddaman 			for (s = path; *s; s++)
461*b30d1939SAndy Fiddaman 				if (s[0] == '/' && s[1] == 'a' && s[2] == 'r' && s[3] == 'c' && s[4] == 'h' && s[5] == '/')
462*b30d1939SAndy Fiddaman 				{
463*b30d1939SAndy Fiddaman 					t = s;
464*b30d1939SAndy Fiddaman 					for (s += 6; *s && *s != '/'; s++);
465*b30d1939SAndy Fiddaman 					while (*t++ = *s++);
466*b30d1939SAndy Fiddaman 					i = open(file, O_RDONLY|O_cloexec);
467*b30d1939SAndy Fiddaman 				}
468*b30d1939SAndy Fiddaman 		if (i < 0)
469*b30d1939SAndy Fiddaman 		{
470*b30d1939SAndy Fiddaman 			copy(buf, file, -1);
471*b30d1939SAndy Fiddaman 			copy(buf, ": cannot open", -1);
472*b30d1939SAndy Fiddaman 			PUT(buf, 0);
473*b30d1939SAndy Fiddaman 			return -1;
474*b30d1939SAndy Fiddaman 		}
475*b30d1939SAndy Fiddaman 	}
476*b30d1939SAndy Fiddaman 	n = read(i, info, size - 1);
477*b30d1939SAndy Fiddaman 	close(i);
478*b30d1939SAndy Fiddaman 	if (n < 0)
479*b30d1939SAndy Fiddaman 	{
480*b30d1939SAndy Fiddaman 		copy(buf, file, -1);
481*b30d1939SAndy Fiddaman 		copy(buf, ": cannot read", -1);
482*b30d1939SAndy Fiddaman 		PUT(buf, 0);
483*b30d1939SAndy Fiddaman 		return -1;
484*b30d1939SAndy Fiddaman 	}
485*b30d1939SAndy Fiddaman 	info[n++] = 0;
486*b30d1939SAndy Fiddaman 	sp->file = file;
487*b30d1939SAndy Fiddaman 	sp->info = info;
488*b30d1939SAndy Fiddaman 	sp->line = 0;
489*b30d1939SAndy Fiddaman 	sp->size = n;
490*b30d1939SAndy Fiddaman 	return 0;
491*b30d1939SAndy Fiddaman }
492*b30d1939SAndy Fiddaman 
493da2e3ebdSchin /*
494da2e3ebdSchin  * read the license file and generate a comment in p, length size
495da2e3ebdSchin  * license length in p returned, -1 on error
496da2e3ebdSchin  * -1 return places 0 terminated error string in p
497da2e3ebdSchin  */
498da2e3ebdSchin 
499da2e3ebdSchin int
astlicense(char * p,int size,char * file,char * options,int cc1,int cc2,int cc3)500da2e3ebdSchin astlicense(char* p, int size, char* file, char* options, int cc1, int cc2, int cc3)
501da2e3ebdSchin {
502da2e3ebdSchin 	register char*	s;
503da2e3ebdSchin 	register char*	v;
504da2e3ebdSchin 	register char*	x;
505da2e3ebdSchin 	register int	c;
506da2e3ebdSchin 	int		i;
507da2e3ebdSchin 	int		h;
508da2e3ebdSchin 	int		k;
509da2e3ebdSchin 	int		n;
510da2e3ebdSchin 	int		q;
511da2e3ebdSchin 	int		contributor;
512da2e3ebdSchin 	int		first;
513*b30d1939SAndy Fiddaman 	int		level;
514da2e3ebdSchin 	int		quote;
515*b30d1939SAndy Fiddaman 	char*		data;
516da2e3ebdSchin 	char		tmpbuf[COMLINE];
517da2e3ebdSchin 	char		info[8 * 1024];
518*b30d1939SAndy Fiddaman 	Stack_t		input[4];
519da2e3ebdSchin 	Notice_t	notice;
520da2e3ebdSchin 	Item_t		item;
521da2e3ebdSchin 	Buffer_t	buf;
522da2e3ebdSchin 	Buffer_t	tmp;
523da2e3ebdSchin 
524da2e3ebdSchin 	buf.end = (buf.buf = buf.nxt = p) + size;
525da2e3ebdSchin 	tmp.end = (tmp.buf = tmp.nxt = tmpbuf) + sizeof(tmpbuf);
526*b30d1939SAndy Fiddaman 	level = 0;
527*b30d1939SAndy Fiddaman 	data = info;
528*b30d1939SAndy Fiddaman 	level = -1;
529*b30d1939SAndy Fiddaman 	if (options)
530*b30d1939SAndy Fiddaman 	{
531*b30d1939SAndy Fiddaman 		level++;
532*b30d1939SAndy Fiddaman 		input[level].file = "<options>";
533*b30d1939SAndy Fiddaman 		input[level].info = options;
534*b30d1939SAndy Fiddaman 		input[level].line = 0;
535*b30d1939SAndy Fiddaman 	}
536da2e3ebdSchin 	if (file && *file)
537da2e3ebdSchin 	{
538*b30d1939SAndy Fiddaman 		if (push(&input[++level], file, 0, data, &info[sizeof(info)] - data, &buf))
539da2e3ebdSchin 			return -1;
540*b30d1939SAndy Fiddaman 		data += input[level].size;
541da2e3ebdSchin 	}
542*b30d1939SAndy Fiddaman 	if (level < 0)
543da2e3ebdSchin 		return 0;
544*b30d1939SAndy Fiddaman 	s = input[level].info;
545da2e3ebdSchin 	notice.test = 0;
546da2e3ebdSchin 	notice.type = NONE;
547da2e3ebdSchin 	notice.verbose = 0;
548da2e3ebdSchin 	notice.ids = 0;
549da2e3ebdSchin 	notice.cc[0] = cc1;
550da2e3ebdSchin 	notice.cc[1] = cc2;
551da2e3ebdSchin 	notice.cc[2] = cc3;
552da2e3ebdSchin 	for (i = 0; i < ITEMS; i++)
553da2e3ebdSchin 		notice.item[i].data = 0;
554da2e3ebdSchin 	notice.item[STYLE] = notice.item[CLASS] = lic[notice.type];
555da2e3ebdSchin 	notice.item[STYLE].quote = notice.item[CLASS].quote = 0;
556da2e3ebdSchin 	contributor = i = k = 0;
557da2e3ebdSchin 	for (;;)
558da2e3ebdSchin 	{
55934f9b3eeSRoland Mainz 		first = 1;
56034f9b3eeSRoland Mainz 		while (c = *s)
561da2e3ebdSchin 		{
562*b30d1939SAndy Fiddaman 			while (c == ' ' || c == '\t' || c == '\n' && ++input[level].line || c == '\r' || c == ',' || c == ';' || c == ')')
563da2e3ebdSchin 				c = *++s;
564da2e3ebdSchin 			if (!c)
565da2e3ebdSchin 				break;
566da2e3ebdSchin 			if (c == '#')
567da2e3ebdSchin 			{
568da2e3ebdSchin 				while (*++s && *s != '\n');
569da2e3ebdSchin 				if (*s)
570da2e3ebdSchin 					s++;
571*b30d1939SAndy Fiddaman 				input[level].line++;
572*b30d1939SAndy Fiddaman 				continue;
573*b30d1939SAndy Fiddaman 			}
574*b30d1939SAndy Fiddaman 			if (c == '.')
575*b30d1939SAndy Fiddaman 			{
576*b30d1939SAndy Fiddaman 				while ((c = *++s) && (c == ' ' || c == '\t'));
577*b30d1939SAndy Fiddaman 				file = s;
578*b30d1939SAndy Fiddaman 				while (c && c != ' ' && c != '\t' && c != '\r' && c != '\n')
579*b30d1939SAndy Fiddaman 					c = *++s;
580*b30d1939SAndy Fiddaman 				*s = 0;
581*b30d1939SAndy Fiddaman 				while (c && c != '\n')
582*b30d1939SAndy Fiddaman 					c = *++s;
583*b30d1939SAndy Fiddaman 				if (*file)
584*b30d1939SAndy Fiddaman 				{
585*b30d1939SAndy Fiddaman 					input[level].info = s + (c != 0);
586*b30d1939SAndy Fiddaman 					if (++level >= (sizeof(input) / sizeof(input[0])) || push(&input[level], file, input[level-1].file, data, &info[sizeof(info)] - data, &buf))
587*b30d1939SAndy Fiddaman 						return -1;
588*b30d1939SAndy Fiddaman 					data += input[level].size;
589*b30d1939SAndy Fiddaman 					s = input[level].info;
590*b30d1939SAndy Fiddaman 				}
591da2e3ebdSchin 				continue;
592da2e3ebdSchin 			}
593da2e3ebdSchin 			if (c == '\n')
594da2e3ebdSchin 			{
595da2e3ebdSchin 				s++;
596*b30d1939SAndy Fiddaman 				input[level].line++;
597da2e3ebdSchin 				continue;
598da2e3ebdSchin 			}
599da2e3ebdSchin 			if (c == '[')
600da2e3ebdSchin 				c = *++s;
601da2e3ebdSchin 			x = s;
602da2e3ebdSchin 			n = 0;
603*b30d1939SAndy Fiddaman 			while (c && c != '+' && c != '=' && c != ']' && c != ')' && c != ',' && c != ' ' && c != '\t' && c != '\n' && c != '\r')
604da2e3ebdSchin 				c = *++s;
605da2e3ebdSchin 			n = s - x;
606da2e3ebdSchin 			h = lookup(key, x, n);
607*b30d1939SAndy Fiddaman 			if (c == '+' || c == ']')
608da2e3ebdSchin 				c = *++s;
6093e14f97fSRoger A. Faulkner 			quote = 0;
610da2e3ebdSchin 			if (c == '=' || first)
611da2e3ebdSchin 			{
612da2e3ebdSchin 				if (c == '=')
613da2e3ebdSchin 				{
614da2e3ebdSchin 					q = ((c = *++s) == '"' || c == '\'') ? *s++ : 0;
615da2e3ebdSchin 					if (c == '(')
616da2e3ebdSchin 					{
617da2e3ebdSchin 						s++;
618da2e3ebdSchin 						if (h == LICENSE)
619da2e3ebdSchin 							contributor = 0;
620da2e3ebdSchin 						else if (h == CONTRIBUTOR)
621da2e3ebdSchin 							contributor = 1;
622da2e3ebdSchin 						else
623da2e3ebdSchin 						{
624da2e3ebdSchin 							q = 1;
625da2e3ebdSchin 							i = 0;
626da2e3ebdSchin 							for (;;)
627da2e3ebdSchin 							{
628da2e3ebdSchin 								switch (*s++)
629da2e3ebdSchin 								{
630da2e3ebdSchin 								case 0:
631da2e3ebdSchin 									s--;
632da2e3ebdSchin 									break;
633da2e3ebdSchin 								case '(':
634da2e3ebdSchin 									if (!i)
635da2e3ebdSchin 										q++;
636da2e3ebdSchin 									continue;
637da2e3ebdSchin 								case ')':
638da2e3ebdSchin 									if (!i && !--q)
639da2e3ebdSchin 										break;
640da2e3ebdSchin 									continue;
641da2e3ebdSchin 								case '"':
642da2e3ebdSchin 								case '\'':
643da2e3ebdSchin 									if (!i)
644da2e3ebdSchin 										i = *(s - 1);
645da2e3ebdSchin 									else if (i == *(s - 1))
646da2e3ebdSchin 										i = 0;
647da2e3ebdSchin 									continue;
648da2e3ebdSchin 								case '\\':
649da2e3ebdSchin 									if (*s == i && i == '"')
650da2e3ebdSchin 										i++;
651da2e3ebdSchin 									continue;
652da2e3ebdSchin 								case '\n':
653*b30d1939SAndy Fiddaman 									input[level].line++;
654da2e3ebdSchin 									continue;
655da2e3ebdSchin 								default:
656da2e3ebdSchin 									continue;
657da2e3ebdSchin 								}
658da2e3ebdSchin 								break;
659da2e3ebdSchin 							}
660da2e3ebdSchin 						}
661da2e3ebdSchin 						continue;
662da2e3ebdSchin 					}
663da2e3ebdSchin 					v = s;
664da2e3ebdSchin 					while ((c = *s) && (q == '"' && (c == '\\' && (*(s + 1) == '"' || *(s + 1) == '\\') && s++ && (quote = q)) || q && c != q || !q && c != ' ' && c != '\t' && c != '\n' && c != '\r' && c != ',' && c != ';'))
665da2e3ebdSchin 					{
666da2e3ebdSchin 						if (c == '\n')
667*b30d1939SAndy Fiddaman 							input[level].line++;
668da2e3ebdSchin 						s++;
669da2e3ebdSchin 					}
670da2e3ebdSchin 				}
671da2e3ebdSchin 				else
672da2e3ebdSchin 				{
673da2e3ebdSchin 					h = STYLE;
674da2e3ebdSchin 					v = x;
675da2e3ebdSchin 				}
676da2e3ebdSchin 				if (c == '\n')
677*b30d1939SAndy Fiddaman 					input[level].line++;
678da2e3ebdSchin 				if (contributor)
679da2e3ebdSchin 				{
680da2e3ebdSchin 					for (i = 0; i < notice.ids; i++)
681da2e3ebdSchin 						if (n == notice.id[i].name.size && !strncmp(x, notice.id[i].name.data, n))
682da2e3ebdSchin 							break;
683da2e3ebdSchin 					if (i < IDS)
684da2e3ebdSchin 					{
685da2e3ebdSchin 						notice.id[i].name.data = x;
686da2e3ebdSchin 						notice.id[i].name.size = n;
687da2e3ebdSchin 						notice.id[i].name.quote = 0;
688da2e3ebdSchin 						notice.id[i].value.data = v;
689da2e3ebdSchin 						notice.id[i].value.size = s - v;
690da2e3ebdSchin 						notice.id[i].value.quote = quote;
691da2e3ebdSchin 						if (notice.ids <= i)
692da2e3ebdSchin 							notice.ids = i + 1;
693da2e3ebdSchin 					}
694da2e3ebdSchin 				}
695da2e3ebdSchin 				else if (h == QUERY)
696da2e3ebdSchin 				{
697da2e3ebdSchin 					if ((s - v) == 3 && v[0] == 'a' && v[1] == 'l' && v[2] == 'l')
698da2e3ebdSchin 					{
699da2e3ebdSchin 						for (i = 0; i < ITEMS; i++)
700da2e3ebdSchin 							if (notice.item[i].size)
701da2e3ebdSchin 							{
702da2e3ebdSchin 								expand(&notice, &buf, &key[i]);
703da2e3ebdSchin 								PUT(&buf, '=');
704da2e3ebdSchin 								for (h = 0;; h++)
705da2e3ebdSchin 									if (h >= notice.item[i].size)
706da2e3ebdSchin 									{
707da2e3ebdSchin 										h = 0;
708da2e3ebdSchin 										break;
709da2e3ebdSchin 									}
710da2e3ebdSchin 									else if (notice.item[i].data[h] == ' ' || notice.item[i].data[h] == '\t')
711da2e3ebdSchin 										break;
712da2e3ebdSchin 								if (h)
713da2e3ebdSchin 									PUT(&buf, '\'');
714da2e3ebdSchin 								expand(&notice, &buf, &notice.item[i]);
715da2e3ebdSchin 								if (h)
716da2e3ebdSchin 									PUT(&buf, '\'');
717da2e3ebdSchin 								PUT(&buf, '\n');
718da2e3ebdSchin 							}
719da2e3ebdSchin 					}
720da2e3ebdSchin 					else
721da2e3ebdSchin 					{
722da2e3ebdSchin 						if ((h = lookup(key, v, s - v)) < 0)
723da2e3ebdSchin 						{
724da2e3ebdSchin 							item.data = v;
725da2e3ebdSchin 							item.size = s - v;
726da2e3ebdSchin 							item.quote = 0;
727da2e3ebdSchin 							expand(&notice, &buf, &item);
728da2e3ebdSchin 						}
729da2e3ebdSchin 						else
730da2e3ebdSchin 							expand(&notice, &buf, &notice.item[h]);
731da2e3ebdSchin 						PUT(&buf, '\n');
732da2e3ebdSchin 					}
733da2e3ebdSchin 					return END(&buf);
734da2e3ebdSchin 				}
735da2e3ebdSchin 				else
736da2e3ebdSchin 				{
737da2e3ebdSchin 					if (h == STYLE)
738da2e3ebdSchin 						switch (c = lookup(lic, v, s - v))
739da2e3ebdSchin 						{
740da2e3ebdSchin 						case NONE:
741da2e3ebdSchin 							return 0;
742da2e3ebdSchin 						case TEST:
743da2e3ebdSchin 							notice.test = 1;
744da2e3ebdSchin 							h = -1;
745da2e3ebdSchin 							break;
746da2e3ebdSchin 						case VERBOSE:
747da2e3ebdSchin 							notice.verbose = 1;
748da2e3ebdSchin 							h = -1;
749da2e3ebdSchin 							break;
750da2e3ebdSchin 						case USAGE:
751da2e3ebdSchin 							notice.type = c;
752da2e3ebdSchin 							h = -1;
753da2e3ebdSchin 							break;
754da2e3ebdSchin 						case -1:
755da2e3ebdSchin 							c = SPECIAL;
756da2e3ebdSchin 							/*FALLTHROUGH*/
757da2e3ebdSchin 						default:
758da2e3ebdSchin 							notice.type = c;
759da2e3ebdSchin 							notice.item[CLASS].data = lic[lic[c].quote].data;
760da2e3ebdSchin 							notice.item[CLASS].size = lic[lic[c].quote].size;
761*b30d1939SAndy Fiddaman 							if (notice.item[STYLE].data != lic[NONE].data)
762*b30d1939SAndy Fiddaman 								h = -1;
763da2e3ebdSchin 							break;
764da2e3ebdSchin 						}
765da2e3ebdSchin 					if (h >= 0)
766da2e3ebdSchin 					{
767da2e3ebdSchin 						notice.item[h].data = (notice.item[h].size = s - v) ? v : (char*)0;
768da2e3ebdSchin 						notice.item[h].quote = quote;
769da2e3ebdSchin 						k = 1;
770da2e3ebdSchin 					}
771da2e3ebdSchin 				}
772da2e3ebdSchin 			}
773da2e3ebdSchin 			else
774da2e3ebdSchin 			{
775*b30d1939SAndy Fiddaman 				if (input[level].file)
776da2e3ebdSchin 				{
777da2e3ebdSchin 					copy(&buf, "\"", -1);
778*b30d1939SAndy Fiddaman 					copy(&buf, input[level].file, -1);
779da2e3ebdSchin 					copy(&buf, "\", line ", -1);
780da2e3ebdSchin 					x = &tmpbuf[sizeof(tmpbuf)];
781da2e3ebdSchin 					*--x = 0;
782*b30d1939SAndy Fiddaman 					n = ++input[level].line;
783*b30d1939SAndy Fiddaman 					do *--x = ("0123456789")[n % 10]; while (n /= 10);
784da2e3ebdSchin 					copy(&buf, x, -1);
785da2e3ebdSchin 					copy(&buf, ": ", -1);
786da2e3ebdSchin 				}
787da2e3ebdSchin 				copy(&buf, "option error: assignment expected", -1);
788da2e3ebdSchin 				PUT(&buf, 0);
789da2e3ebdSchin 				return -1;
790da2e3ebdSchin 			}
791da2e3ebdSchin 			if (*s)
792da2e3ebdSchin 				s++;
79334f9b3eeSRoland Mainz 			first = 0;
794da2e3ebdSchin 		}
795*b30d1939SAndy Fiddaman 		if (!level--)
796da2e3ebdSchin 			break;
797*b30d1939SAndy Fiddaman 		s = input[level].info;
798da2e3ebdSchin 	}
799da2e3ebdSchin 	if (!k)
800da2e3ebdSchin 		return 0;
801da2e3ebdSchin 	if (notice.type == INLINE && (!notice.verbose || !notice.item[NOTICE].data))
802da2e3ebdSchin 		return 0;
803da2e3ebdSchin 	if (notice.type != USAGE)
804da2e3ebdSchin 	{
805da2e3ebdSchin 		if (!notice.type)
806da2e3ebdSchin 			notice.type = SPECIAL;
807da2e3ebdSchin 		comment(&notice, &buf, NiL, 1, 0);
808da2e3ebdSchin 		comment(&notice, &buf, NiL, 0, 0);
809da2e3ebdSchin 		if (notice.item[PACKAGE].data)
810da2e3ebdSchin 		{
811da2e3ebdSchin 			copy(&tmp, "This software is part of the ", -1);
812da2e3ebdSchin 			expand(&notice, &tmp, &notice.item[PACKAGE]);
813da2e3ebdSchin 			copy(&tmp, " package", -1);
814da2e3ebdSchin 			comment(&notice, &buf, BUF(&tmp), USE(&tmp), 0);
815da2e3ebdSchin 		}
816da2e3ebdSchin 		if (notice.type >= OPEN)
817da2e3ebdSchin 		{
818da2e3ebdSchin 			copyright(&notice, &tmp);
819da2e3ebdSchin 			comment(&notice, &buf, BUF(&tmp), USE(&tmp), 0);
820da2e3ebdSchin 			if (notice.type >= SPECIAL)
821da2e3ebdSchin 				COMMENT(&notice, &buf, "All Rights Reserved", 0);
822da2e3ebdSchin 		}
8233e14f97fSRoger A. Faulkner 		if (notice.type == CPL || notice.type == EPL)
824da2e3ebdSchin 		{
825da2e3ebdSchin 			copy(&tmp, notice.item[PACKAGE].data ? "and" : "This software", -1);
826da2e3ebdSchin 			copy(&tmp, " is licensed under the", -1);
827da2e3ebdSchin 			comment(&notice, &buf, BUF(&tmp), USE(&tmp), 0);
8283e14f97fSRoger A. Faulkner 			if (notice.type == EPL)
8293e14f97fSRoger A. Faulkner 				copy(&tmp, "Eclipse Public License", -1);
8303e14f97fSRoger A. Faulkner 			else
8313e14f97fSRoger A. Faulkner 				copy(&tmp, "Common Public License", -1);
832da2e3ebdSchin 			if (notice.item[VERSION].data)
833da2e3ebdSchin 			{
834da2e3ebdSchin 				copy(&tmp, ", Version ", -1);
835da2e3ebdSchin 				expand(&notice, &tmp, &notice.item[VERSION]);
836da2e3ebdSchin 			}
837da2e3ebdSchin 			comment(&notice, &buf, BUF(&tmp), USE(&tmp), 0);
838da2e3ebdSchin 			if (notice.item[CORPORATION].data || notice.item[COMPANY].data)
839da2e3ebdSchin 			{
840da2e3ebdSchin 				copy(&tmp, "by ", -1);
841da2e3ebdSchin 				if (notice.item[PARENT].data)
842da2e3ebdSchin 				{
843da2e3ebdSchin 					expand(&notice, &tmp, &notice.item[PARENT]);
844da2e3ebdSchin 					copy(&tmp, " ", -1);
845da2e3ebdSchin 				}
846da2e3ebdSchin 				if (notice.item[CORPORATION].data)
847da2e3ebdSchin 				{
848da2e3ebdSchin 					expand(&notice, &tmp, &notice.item[CORPORATION]);
849da2e3ebdSchin 					if (notice.item[INCORPORATION].data)
850da2e3ebdSchin 					{
851da2e3ebdSchin 						copy(&tmp, " ", -1);
852da2e3ebdSchin 						expand(&notice, &tmp, &notice.item[INCORPORATION]);
853da2e3ebdSchin 					}
854da2e3ebdSchin 				}
855da2e3ebdSchin 				else if (notice.item[COMPANY].data)
856da2e3ebdSchin 					expand(&notice, &tmp, &notice.item[COMPANY]);
857da2e3ebdSchin 				comment(&notice, &buf, BUF(&tmp), USE(&tmp), 0);
858da2e3ebdSchin 			}
859da2e3ebdSchin 			comment(&notice, &buf, NiL, 0, 0);
860da2e3ebdSchin 			COMMENT(&notice, &buf, "A copy of the License is available at", 0);
861da2e3ebdSchin 			if (notice.item[URL].data)
862da2e3ebdSchin 			{
863da2e3ebdSchin 				expand(&notice, &tmp, &notice.item[URL]);
864da2e3ebdSchin 				comment(&notice, &buf, BUF(&tmp), USE(&tmp), 0);
865da2e3ebdSchin 				if (notice.item[URLMD5].data)
866da2e3ebdSchin 				{
867da2e3ebdSchin 					copy(&tmp, "(with md5 checksum ", -1);
868da2e3ebdSchin 					expand(&notice, &tmp, &notice.item[URLMD5]);
869da2e3ebdSchin 					copy(&tmp, ")", -1);
870da2e3ebdSchin 					comment(&notice, &buf, BUF(&tmp), USE(&tmp), 0);
871da2e3ebdSchin 				}
872da2e3ebdSchin 			}
8733e14f97fSRoger A. Faulkner 			else if (notice.type == EPL)
8743e14f97fSRoger A. Faulkner 				COMMENT(&notice, &buf, "http://www.eclipse.org/org/documents/epl-v10.html", 0);
875da2e3ebdSchin 			else
876da2e3ebdSchin 				COMMENT(&notice, &buf, "http://www.opensource.org/licenses/cpl", 0);
877da2e3ebdSchin 			comment(&notice, &buf, NiL, 0, 0);
878da2e3ebdSchin 		}
879da2e3ebdSchin 		else if (notice.type == OPEN)
880da2e3ebdSchin 		{
881da2e3ebdSchin 			copy(&tmp, notice.item[PACKAGE].data ? "and it" : "This software", -1);
882da2e3ebdSchin 			copy(&tmp, " may only be used by you under license from", -1);
883da2e3ebdSchin 			comment(&notice, &buf, BUF(&tmp), USE(&tmp), 0);
884da2e3ebdSchin 			if (notice.item[i = CORPORATION].data)
885da2e3ebdSchin 			{
886da2e3ebdSchin 				if (notice.item[PARENT].data)
887da2e3ebdSchin 				{
888da2e3ebdSchin 					expand(&notice, &tmp, &notice.item[i = PARENT]);
889da2e3ebdSchin 					copy(&tmp, " ", -1);
890da2e3ebdSchin 				}
891da2e3ebdSchin 				expand(&notice, &tmp, &notice.item[CORPORATION]);
892da2e3ebdSchin 				comment(&notice, &buf, BUF(&tmp), USE(&tmp), 0);
893da2e3ebdSchin 			}
894da2e3ebdSchin 			else if (notice.item[i = COMPANY].data)
895da2e3ebdSchin 			{
896da2e3ebdSchin 				if (notice.item[PARENT].data)
897da2e3ebdSchin 				{
898da2e3ebdSchin 					expand(&notice, &tmp, &notice.item[i = PARENT]);
899da2e3ebdSchin 					copy(&tmp, " ", -1);
900da2e3ebdSchin 				}
901da2e3ebdSchin 				expand(&notice, &tmp, &notice.item[COMPANY]);
902da2e3ebdSchin 				comment(&notice, &buf, BUF(&tmp), USE(&tmp), 0);
903da2e3ebdSchin 			}
904da2e3ebdSchin 			else
905da2e3ebdSchin 				i = -1;
906da2e3ebdSchin 			if (notice.item[URL].data)
907da2e3ebdSchin 			{
908da2e3ebdSchin 				COMMENT(&notice, &buf, "A copy of the Source Code Agreement is available", 0);
909da2e3ebdSchin 				copy(&tmp, "at the ", -1);
910da2e3ebdSchin 				if (i >= 0)
911da2e3ebdSchin 					expand(&notice, &tmp, &notice.item[i]);
912da2e3ebdSchin 				copy(&tmp, " Internet web site URL", -1);
913da2e3ebdSchin 				comment(&notice, &buf, BUF(&tmp), USE(&tmp), 0);
914da2e3ebdSchin 				comment(&notice, &buf, NiL, 0, 0);
915da2e3ebdSchin 				expand(&notice, &tmp, &notice.item[URL]);
916da2e3ebdSchin 				comment(&notice, &buf, BUF(&tmp), USE(&tmp), 0);
917da2e3ebdSchin 				if (notice.item[URLMD5].data)
918da2e3ebdSchin 				{
919da2e3ebdSchin 					copy(&tmp, "(with an md5 checksum of ", -1);
920da2e3ebdSchin 					expand(&notice, &tmp, &notice.item[URLMD5]);
921da2e3ebdSchin 					copy(&tmp, ")", -1);
922da2e3ebdSchin 					comment(&notice, &buf, BUF(&tmp), USE(&tmp), 0);
923da2e3ebdSchin 				}
924da2e3ebdSchin 				comment(&notice, &buf, NiL, 0, 0);
925da2e3ebdSchin 			}
926da2e3ebdSchin 			COMMENT(&notice, &buf, "If you have copied or used this software without agreeing", 0);
927da2e3ebdSchin 			COMMENT(&notice, &buf, "to the terms of the license you are infringing on", 0);
928da2e3ebdSchin 			COMMENT(&notice, &buf, "the license and copyright and are violating", 0);
929da2e3ebdSchin 			if (i >= 0)
930da2e3ebdSchin 				expand(&notice, &tmp, &notice.item[i]);
931da2e3ebdSchin 			copy(&tmp, "'s", -1);
932da2e3ebdSchin 			if (n >= COMLONG)
933da2e3ebdSchin 				comment(&notice, &buf, BUF(&tmp), USE(&tmp), 0);
934da2e3ebdSchin 			else
935da2e3ebdSchin 				PUT(&tmp, ' ');
936da2e3ebdSchin 			copy(&tmp, "intellectual property rights.", -1);
937da2e3ebdSchin 			comment(&notice, &buf, BUF(&tmp), USE(&tmp), 0);
938da2e3ebdSchin 			comment(&notice, &buf, NiL, 0, 0);
939da2e3ebdSchin 		}
940da2e3ebdSchin 		else if (notice.type == GPL)
941da2e3ebdSchin 		{
942da2e3ebdSchin 			comment(&notice, &buf, NiL, 0, 0);
943da2e3ebdSchin 			COMMENT(&notice, &buf, "This is free software; you can redistribute it and/or", 0);
944da2e3ebdSchin 			COMMENT(&notice, &buf, "modify it under the terms of the GNU General Public License", 0);
945da2e3ebdSchin 			COMMENT(&notice, &buf, "as published by the Free Software Foundation;", 0);
946da2e3ebdSchin 			COMMENT(&notice, &buf, "either version 2, or (at your option) any later version.", 0);
947da2e3ebdSchin 			comment(&notice, &buf, NiL, 0, 0);
948da2e3ebdSchin 			COMMENT(&notice, &buf, "This software is distributed in the hope that it", 0);
949da2e3ebdSchin 			COMMENT(&notice, &buf, "will be useful, but WITHOUT ANY WARRANTY;", 0);
950da2e3ebdSchin 			COMMENT(&notice, &buf, "without even the implied warranty of MERCHANTABILITY", 0);
951da2e3ebdSchin 			COMMENT(&notice, &buf, "or FITNESS FOR A PARTICULAR PURPOSE.", 0);
952da2e3ebdSchin 			COMMENT(&notice, &buf, "See the GNU General Public License for more details.", 0);
953da2e3ebdSchin 			comment(&notice, &buf, NiL, 0, 0);
954da2e3ebdSchin 			COMMENT(&notice, &buf, "You should have received a copy of the", 0);
955da2e3ebdSchin 			COMMENT(&notice, &buf, "GNU General Public License", 0);
956da2e3ebdSchin 			COMMENT(&notice, &buf, "along with this software (see the file COPYING.)", 0);
957da2e3ebdSchin 			COMMENT(&notice, &buf, "If not, a copy is available at", 0);
958da2e3ebdSchin 			COMMENT(&notice, &buf, "http://www.gnu.org/copyleft/gpl.html", 0);
959da2e3ebdSchin 			comment(&notice, &buf, NiL, 0, 0);
960da2e3ebdSchin 		}
961da2e3ebdSchin 		else if (notice.type == BSD)
962da2e3ebdSchin 		{
963da2e3ebdSchin 			comment(&notice, &buf, NiL, 0, 0);
964da2e3ebdSchin 			COMMENT(&notice, &buf, "Redistribution and use in source and binary forms, with or", -1);
965da2e3ebdSchin 			COMMENT(&notice, &buf, "without modification, are permitted provided that the following", -1);
966da2e3ebdSchin 			COMMENT(&notice, &buf, "conditions are met:", -1);
967da2e3ebdSchin 			comment(&notice, &buf, NiL, 0, 0);
968da2e3ebdSchin 			COMMENT(&notice, &buf, "   1. Redistributions of source code must retain the above", -1);
969da2e3ebdSchin 			COMMENT(&notice, &buf, "      copyright notice, this list of conditions and the", -1);
970da2e3ebdSchin 			COMMENT(&notice, &buf, "      following disclaimer.", -1);
971da2e3ebdSchin 			comment(&notice, &buf, NiL, 0, 0);
972da2e3ebdSchin 			COMMENT(&notice, &buf, "   2. Redistributions in binary form must reproduce the above", -1);
973da2e3ebdSchin 			COMMENT(&notice, &buf, "      copyright notice, this list of conditions and the", -1);
974da2e3ebdSchin 			COMMENT(&notice, &buf, "      following disclaimer in the documentation and/or other", -1);
975da2e3ebdSchin 			COMMENT(&notice, &buf, "      materials provided with the distribution.", -1);
976da2e3ebdSchin 			comment(&notice, &buf, NiL, 0, 0);
977da2e3ebdSchin 			copy(&tmp, "   3. Neither the name of ", -1);
978da2e3ebdSchin 			if (notice.item[i = PARENT].data || notice.item[i = CORPORATION].data || notice.item[i = COMPANY].data)
979da2e3ebdSchin 				expand(&notice, &tmp, &notice.item[i]);
980da2e3ebdSchin 			else
981da2e3ebdSchin 				copy(&tmp, "the copyright holder", -1);
982da2e3ebdSchin 			copy(&tmp, " nor the", -1);
983da2e3ebdSchin 			comment(&notice, &buf, BUF(&tmp), USE(&tmp), -1);
984da2e3ebdSchin 			COMMENT(&notice, &buf, "      names of its contributors may be used to endorse or", -1);
985da2e3ebdSchin 			COMMENT(&notice, &buf, "      promote products derived from this software without", -1);
986da2e3ebdSchin 			COMMENT(&notice, &buf, "      specific prior written permission.", -1);
987da2e3ebdSchin 			comment(&notice, &buf, NiL, 0, 0);
988da2e3ebdSchin 			COMMENT(&notice, &buf, "THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND", -1);
989da2e3ebdSchin 			COMMENT(&notice, &buf, "CONTRIBUTORS \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES,", -1);
990da2e3ebdSchin 			COMMENT(&notice, &buf, "INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF", -1);
991da2e3ebdSchin 			COMMENT(&notice, &buf, "MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE", -1);
992da2e3ebdSchin 			COMMENT(&notice, &buf, "DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS", -1);
993da2e3ebdSchin 			COMMENT(&notice, &buf, "BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,", -1);
994da2e3ebdSchin 			COMMENT(&notice, &buf, "EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED", -1);
995da2e3ebdSchin 			COMMENT(&notice, &buf, "TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,", -1);
996da2e3ebdSchin 			COMMENT(&notice, &buf, "DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON", -1);
997da2e3ebdSchin 			COMMENT(&notice, &buf, "ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,", -1);
998da2e3ebdSchin 			COMMENT(&notice, &buf, "OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY", -1);
999da2e3ebdSchin 			COMMENT(&notice, &buf, "OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE", -1);
1000da2e3ebdSchin 			COMMENT(&notice, &buf, "POSSIBILITY OF SUCH DAMAGE.", -1);
1001da2e3ebdSchin 			comment(&notice, &buf, NiL, 0, 0);
1002da2e3ebdSchin 		}
1003da2e3ebdSchin 		else if (notice.type == ZLIB)
1004da2e3ebdSchin 		{
1005da2e3ebdSchin 			comment(&notice, &buf, NiL, 0, 0);
1006da2e3ebdSchin 			COMMENT(&notice, &buf, "This software is provided 'as-is', without any express or implied", -1);
1007da2e3ebdSchin 			COMMENT(&notice, &buf, "warranty. In no event will the authors be held liable for any", -1);
1008da2e3ebdSchin 			COMMENT(&notice, &buf, "damages arising from the use of this software.", -1);
1009da2e3ebdSchin 			comment(&notice, &buf, NiL, 0, 0);
1010da2e3ebdSchin 			COMMENT(&notice, &buf, "Permission is granted to anyone to use this software for any", -1);
1011da2e3ebdSchin 			COMMENT(&notice, &buf, "purpose, including commercial applications, and to alter it and", -1);
1012da2e3ebdSchin 			COMMENT(&notice, &buf, "redistribute it freely, subject to the following restrictions:", -1);
1013da2e3ebdSchin 			comment(&notice, &buf, NiL, 0, 0);
1014da2e3ebdSchin 			COMMENT(&notice, &buf, " 1. The origin of this software must not be misrepresented;", -1);
1015da2e3ebdSchin 			COMMENT(&notice, &buf, "    you must not claim that you wrote the original software. If", -1);
1016da2e3ebdSchin 			COMMENT(&notice, &buf, "    you use this software in a product, an acknowledgment in the", -1);
1017da2e3ebdSchin 			COMMENT(&notice, &buf, "    product documentation would be appreciated but is not", -1);
1018da2e3ebdSchin 			COMMENT(&notice, &buf, "    required.", -1);
1019da2e3ebdSchin 			comment(&notice, &buf, NiL, 0, 0);
1020da2e3ebdSchin 			COMMENT(&notice, &buf, " 2. Altered source versions must be plainly marked as such,", -1);
1021da2e3ebdSchin 			COMMENT(&notice, &buf, "    and must not be misrepresented as being the original", -1);
1022da2e3ebdSchin 			COMMENT(&notice, &buf, "    software.", -1);
1023da2e3ebdSchin 			comment(&notice, &buf, NiL, 0, 0);
1024da2e3ebdSchin 			COMMENT(&notice, &buf, " 3. This notice may not be removed or altered from any source", -1);
1025da2e3ebdSchin 			COMMENT(&notice, &buf, "    distribution.", -1);
1026da2e3ebdSchin 			comment(&notice, &buf, NiL, 0, 0);
1027da2e3ebdSchin 		}
1028da2e3ebdSchin 		else if (notice.type == MIT)
1029da2e3ebdSchin 		{
1030da2e3ebdSchin 			comment(&notice, &buf, NiL, 0, 0);
1031da2e3ebdSchin 			COMMENT(&notice, &buf, "Permission is hereby granted, free of charge, to any person", 0);
1032da2e3ebdSchin 			COMMENT(&notice, &buf, "obtaining a copy of this software and associated", 0);
1033da2e3ebdSchin 			COMMENT(&notice, &buf, "documentation files (the \"Software\"), to deal in the", 0);
1034da2e3ebdSchin 			COMMENT(&notice, &buf, "Software without restriction, including without limitation", 0);
1035da2e3ebdSchin 			COMMENT(&notice, &buf, "the rights to use, copy, modify, merge, publish, distribute,", 0);
1036da2e3ebdSchin 			COMMENT(&notice, &buf, "sublicense, and/or sell copies of the Software, and to", 0);
1037da2e3ebdSchin 			COMMENT(&notice, &buf, "permit persons to whom the Software is furnished to do so,", 0);
1038da2e3ebdSchin 			COMMENT(&notice, &buf, "subject to the following conditions:", 0);
1039da2e3ebdSchin 			comment(&notice, &buf, NiL, 0, 0);
1040da2e3ebdSchin 			COMMENT(&notice, &buf, "The above copyright notice and this permission notice shall", 0);
1041da2e3ebdSchin 			COMMENT(&notice, &buf, "be included in all copies or substantial portions of the", 0);
1042da2e3ebdSchin 			COMMENT(&notice, &buf, "Software.", 0);
1043da2e3ebdSchin 			comment(&notice, &buf, NiL, 0, 0);
1044da2e3ebdSchin 			COMMENT(&notice, &buf, "THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY", 0);
1045da2e3ebdSchin 			COMMENT(&notice, &buf, "KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE", 0);
1046da2e3ebdSchin 			COMMENT(&notice, &buf, "WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR", 0);
1047da2e3ebdSchin 			COMMENT(&notice, &buf, "PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS", 0);
1048da2e3ebdSchin 			COMMENT(&notice, &buf, "OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR", 0);
1049da2e3ebdSchin 			COMMENT(&notice, &buf, "OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR", 0);
1050da2e3ebdSchin 			COMMENT(&notice, &buf, "OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE", 0);
1051da2e3ebdSchin 			COMMENT(&notice, &buf, "SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.", 0);
1052da2e3ebdSchin 			comment(&notice, &buf, NiL, 0, 0);
1053da2e3ebdSchin 		}
1054da2e3ebdSchin 		else
1055da2e3ebdSchin 		{
1056da2e3ebdSchin 			if (notice.type == PROPRIETARY)
1057da2e3ebdSchin 			{
1058da2e3ebdSchin 				if (notice.item[i = PARENT].data || notice.item[i = CORPORATION].data || notice.item[i = COMPANY].data)
1059da2e3ebdSchin 				{
1060da2e3ebdSchin 					expand(&notice, &tmp, &notice.item[i]);
1061da2e3ebdSchin 					copy(&tmp, " - ", -1);
1062da2e3ebdSchin 				}
1063da2e3ebdSchin 				else
1064da2e3ebdSchin 					i = -1;
1065da2e3ebdSchin 				copy(&tmp, "Proprietary", -1);
1066da2e3ebdSchin 				comment(&notice, &buf, BUF(&tmp), USE(&tmp), 1);
1067da2e3ebdSchin 				comment(&notice, &buf, NiL, 0, 0);
1068da2e3ebdSchin 				if (notice.item[URL].data)
1069da2e3ebdSchin 				{
1070da2e3ebdSchin 					copy(&tmp, "This is proprietary source code", -1);
1071da2e3ebdSchin 					if (i >= 0)
1072da2e3ebdSchin 						copy(&tmp, " licensed by", -1);
1073da2e3ebdSchin 					comment(&notice, &buf, BUF(&tmp), USE(&tmp), 1);
1074da2e3ebdSchin 					if (notice.item[PARENT].data)
1075da2e3ebdSchin 					{
1076da2e3ebdSchin 						expand(&notice, &tmp, &notice.item[PARENT]);
1077da2e3ebdSchin 						copy(&tmp, " ", -1);
1078da2e3ebdSchin 					}
1079da2e3ebdSchin 					if (notice.item[CORPORATION].data)
1080da2e3ebdSchin 					{
1081da2e3ebdSchin 						expand(&notice, &tmp, &notice.item[CORPORATION]);
1082da2e3ebdSchin 						comment(&notice, &buf, BUF(&tmp), USE(&tmp), 1);
1083da2e3ebdSchin 					}
1084da2e3ebdSchin 					else if (notice.item[COMPANY].data)
1085da2e3ebdSchin 					{
1086da2e3ebdSchin 						expand(&notice, &tmp, &notice.item[COMPANY]);
1087da2e3ebdSchin 						comment(&notice, &buf, BUF(&tmp), USE(&tmp), 1);
1088da2e3ebdSchin 					}
1089da2e3ebdSchin 				}
1090da2e3ebdSchin 				else
1091da2e3ebdSchin 				{
1092da2e3ebdSchin 					copy(&tmp, "This is unpublished proprietary source code", -1);
1093da2e3ebdSchin 					if (i >= 0)
1094da2e3ebdSchin 						copy(&tmp, " of", -1);
1095da2e3ebdSchin 					comment(&notice, &buf, BUF(&tmp), USE(&tmp), 1);
1096da2e3ebdSchin 					if (notice.item[i = PARENT].data || notice.item[i = CORPORATION].data)
1097da2e3ebdSchin 						expand(&notice, &tmp, &notice.item[i]);
1098da2e3ebdSchin 					if (notice.item[COMPANY].data)
1099da2e3ebdSchin 					{
1100da2e3ebdSchin 						if (SIZ(&tmp))
1101da2e3ebdSchin 							PUT(&tmp, ' ');
1102da2e3ebdSchin 						expand(&notice, &tmp, &notice.item[COMPANY]);
1103da2e3ebdSchin 					}
1104da2e3ebdSchin 					if (SIZ(&tmp))
1105da2e3ebdSchin 						comment(&notice, &buf, BUF(&tmp), USE(&tmp), 1);
1106da2e3ebdSchin 					COMMENT(&notice, &buf, "and is not to be disclosed or used except in", 1);
1107da2e3ebdSchin 					COMMENT(&notice, &buf, "accordance with applicable agreements", 1);
1108da2e3ebdSchin 				}
1109da2e3ebdSchin 				comment(&notice, &buf, NiL, 0, 0);
1110da2e3ebdSchin 			}
1111da2e3ebdSchin 			else if (notice.type == NONEXCLUSIVE)
1112da2e3ebdSchin 			{
1113da2e3ebdSchin 				COMMENT(&notice, &buf, "For nonexclusive individual use", 1);
1114da2e3ebdSchin 				comment(&notice, &buf, NiL, 0, 0);
1115da2e3ebdSchin 			}
1116da2e3ebdSchin 			else if (notice.type == NONCOMMERCIAL)
1117da2e3ebdSchin 			{
1118da2e3ebdSchin 				COMMENT(&notice, &buf, "For noncommercial use", 1);
1119da2e3ebdSchin 				comment(&notice, &buf, NiL, 0, 0);
1120da2e3ebdSchin 			}
1121da2e3ebdSchin 			if (notice.type >= PROPRIETARY && !notice.item[URL].data)
1122da2e3ebdSchin 			{
1123da2e3ebdSchin 				COMMENT(&notice, &buf, "Unpublished & Not for Publication", 0);
1124da2e3ebdSchin 				comment(&notice, &buf, NiL, 0, 0);
1125da2e3ebdSchin 			}
1126da2e3ebdSchin 			if (notice.item[URL].data)
1127da2e3ebdSchin 			{
1128da2e3ebdSchin 				copy(&tmp, "This software is licensed", -1);
1129da2e3ebdSchin 				if (notice.item[CORPORATION].data || notice.item[COMPANY].data)
1130da2e3ebdSchin 				{
1131da2e3ebdSchin 					copy(&tmp, " by", -1);
1132da2e3ebdSchin 					if ((notice.item[PARENT].size + (notice.item[CORPORATION].data ? (notice.item[CORPORATION].size + notice.item[INCORPORATION].size) : notice.item[COMPANY].size)) >= (COMLONG - 6))
1133da2e3ebdSchin 						comment(&notice, &buf, BUF(&tmp), USE(&tmp), 0);
1134da2e3ebdSchin 					else
1135da2e3ebdSchin 						PUT(&tmp, ' ');
1136da2e3ebdSchin 					if (notice.item[PARENT].data)
1137da2e3ebdSchin 					{
1138da2e3ebdSchin 						expand(&notice, &tmp, &notice.item[PARENT]);
1139da2e3ebdSchin 						copy(&tmp, " ", -1);
1140da2e3ebdSchin 					}
1141da2e3ebdSchin 					if (notice.item[CORPORATION].data)
1142da2e3ebdSchin 					{
1143da2e3ebdSchin 						expand(&notice, &tmp, &notice.item[CORPORATION]);
1144da2e3ebdSchin 						if (notice.item[INCORPORATION].data)
1145da2e3ebdSchin 						{
1146da2e3ebdSchin 							copy(&tmp, " ", -1);
1147da2e3ebdSchin 							expand(&notice, &tmp, &notice.item[INCORPORATION]);
1148da2e3ebdSchin 						}
1149da2e3ebdSchin 					}
1150da2e3ebdSchin 					else if (notice.item[COMPANY].data)
1151da2e3ebdSchin 						expand(&notice, &tmp, &notice.item[COMPANY]);
1152da2e3ebdSchin 				}
1153da2e3ebdSchin 				comment(&notice, &buf, BUF(&tmp), USE(&tmp), 0);
1154da2e3ebdSchin 				COMMENT(&notice, &buf, "under the terms and conditions of the license in", 0);
1155da2e3ebdSchin 				expand(&notice, &tmp, &notice.item[URL]);
1156da2e3ebdSchin 				comment(&notice, &buf, BUF(&tmp), USE(&tmp), 0);
1157da2e3ebdSchin 				if (notice.item[URLMD5].data)
1158da2e3ebdSchin 				{
1159da2e3ebdSchin 					copy(&tmp, "(with an md5 checksum of ", -1);
1160da2e3ebdSchin 					expand(&notice, &tmp, &notice.item[URLMD5]);
1161da2e3ebdSchin 					copy(&tmp, ")", -1);
1162da2e3ebdSchin 					comment(&notice, &buf, BUF(&tmp), USE(&tmp), 0);
1163da2e3ebdSchin 				}
1164da2e3ebdSchin 				comment(&notice, &buf, NiL, 0, 0);
1165da2e3ebdSchin 			}
1166da2e3ebdSchin 			else if (notice.type == PROPRIETARY)
1167da2e3ebdSchin 			{
1168da2e3ebdSchin 				COMMENT(&notice, &buf, "The copyright notice above does not evidence any", 0);
1169da2e3ebdSchin 				COMMENT(&notice, &buf, "actual or intended publication of such source code", 0);
1170da2e3ebdSchin 				comment(&notice, &buf, NiL, 0, 0);
1171da2e3ebdSchin 			}
1172da2e3ebdSchin 		}
1173da2e3ebdSchin 		if (v = notice.item[NOTICE].data)
1174da2e3ebdSchin 		{
1175da2e3ebdSchin 			x = v + notice.item[NOTICE].size;
1176da2e3ebdSchin 			if (*v == '\n')
1177da2e3ebdSchin 				v++;
1178da2e3ebdSchin 			item.quote = notice.item[NOTICE].quote;
1179da2e3ebdSchin 			do
1180da2e3ebdSchin 			{
1181da2e3ebdSchin 				for (item.data = v; v < x && *v != '\n'; v++);
1182da2e3ebdSchin 				if ((item.size = v - item.data) && *item.data == '\t')
1183da2e3ebdSchin 				{
1184da2e3ebdSchin 					item.data++;
1185da2e3ebdSchin 					item.size--;
1186da2e3ebdSchin 					h = 0;
1187da2e3ebdSchin 				}
1188da2e3ebdSchin 				else
1189da2e3ebdSchin 					h = -1;
1190da2e3ebdSchin 				expand(&notice, &tmp, &item);
1191da2e3ebdSchin 				comment(&notice, &buf, BUF(&tmp), USE(&tmp), h);
1192da2e3ebdSchin 			} while (v++ < x);
1193da2e3ebdSchin 			if (item.size)
1194da2e3ebdSchin 				comment(&notice, &buf, NiL, 0, 0);
1195da2e3ebdSchin 		}
1196da2e3ebdSchin 		if (notice.item[ORGANIZATION].data)
1197da2e3ebdSchin 		{
1198da2e3ebdSchin 			expand(&notice, &tmp, &notice.item[ORGANIZATION]);
1199da2e3ebdSchin 			comment(&notice, &buf, BUF(&tmp), USE(&tmp), 0);
1200da2e3ebdSchin 			if (notice.item[i = PARENT].data || notice.item[i = CORPORATION].data)
1201da2e3ebdSchin 				expand(&notice, &tmp, &notice.item[i]);
1202da2e3ebdSchin 			if (notice.item[COMPANY].data)
1203da2e3ebdSchin 			{
1204da2e3ebdSchin 				if (SIZ(&tmp))
1205da2e3ebdSchin 					PUT(&tmp, ' ');
1206da2e3ebdSchin 				expand(&notice, &tmp, &notice.item[COMPANY]);
1207da2e3ebdSchin 			}
1208da2e3ebdSchin 			if (SIZ(&tmp))
1209da2e3ebdSchin 				comment(&notice, &buf, BUF(&tmp), USE(&tmp), 0);
1210da2e3ebdSchin 			if (notice.item[LOCATION].data)
1211da2e3ebdSchin 			{
1212da2e3ebdSchin 				expand(&notice, &tmp, &notice.item[LOCATION]);
1213da2e3ebdSchin 				comment(&notice, &buf, BUF(&tmp), USE(&tmp), 0);
1214da2e3ebdSchin 			}
1215da2e3ebdSchin 			comment(&notice, &buf, NiL, 0, 0);
1216da2e3ebdSchin 		}
1217da2e3ebdSchin 	}
1218da2e3ebdSchin 	if (v = notice.item[AUTHOR].data)
1219da2e3ebdSchin 	{
1220da2e3ebdSchin 		x = v + notice.item[AUTHOR].size;
1221da2e3ebdSchin 		q = (x - v) == 1 && (*v == '*' || *v == '-');
1222da2e3ebdSchin 		k = q && notice.type != USAGE ? -1 : 0;
1223da2e3ebdSchin 		for (;;)
1224da2e3ebdSchin 		{
1225da2e3ebdSchin 			if (!q)
1226da2e3ebdSchin 			{
1227da2e3ebdSchin 				while (v < x && (*v == ' ' || *v == '\t' || *v == '\r' || *v == '\n' || *v == ',' || *v == '+'))
1228da2e3ebdSchin 					v++;
1229da2e3ebdSchin 				if (v >= x)
1230da2e3ebdSchin 					break;
1231da2e3ebdSchin 				item.data = v;
1232da2e3ebdSchin 				while (v < x && *v != ',' && *v != '+' && *v++ != '>');
1233da2e3ebdSchin 				item.size = v - item.data;
1234da2e3ebdSchin 				item.quote = notice.item[AUTHOR].quote;
1235da2e3ebdSchin 			}
1236da2e3ebdSchin 			h = 0;
1237da2e3ebdSchin 			for (i = 0; i < notice.ids; i++)
1238da2e3ebdSchin 				if (q || item.size == notice.id[i].name.size && !strncmp(item.data, notice.id[i].name.data, item.size))
1239da2e3ebdSchin 				{
1240da2e3ebdSchin 					h = 1;
1241da2e3ebdSchin 					if (notice.type == USAGE)
1242da2e3ebdSchin 					{
1243da2e3ebdSchin 						copy(&buf, "[-author?", -1);
1244da2e3ebdSchin 						expand(&notice, &buf, &notice.id[i].value);
1245da2e3ebdSchin 						PUT(&buf, ']');
1246da2e3ebdSchin 					}
1247da2e3ebdSchin 					else
1248da2e3ebdSchin 					{
1249da2e3ebdSchin 						if (k < 0)
1250da2e3ebdSchin 						{
1251da2e3ebdSchin 							COMMENT(&notice, &buf, "CONTRIBUTORS", 0);
1252da2e3ebdSchin 							comment(&notice, &buf, NiL, 0, 0);
1253da2e3ebdSchin 						}
1254da2e3ebdSchin 						k = 1;
1255da2e3ebdSchin 						expand(&notice, &tmp, &notice.id[i].value);
1256da2e3ebdSchin 						comment(&notice, &buf, BUF(&tmp), USE(&tmp), 0);
1257da2e3ebdSchin 					}
1258da2e3ebdSchin 					if (!q)
1259da2e3ebdSchin 						break;
1260da2e3ebdSchin 				}
1261da2e3ebdSchin 			if (q)
1262da2e3ebdSchin 				break;
1263da2e3ebdSchin 			if (!h)
1264da2e3ebdSchin 			{
1265da2e3ebdSchin 				if (notice.type == USAGE)
1266da2e3ebdSchin 				{
1267da2e3ebdSchin 					copy(&buf, "[-author?", -1);
1268da2e3ebdSchin 					expand(&notice, &buf, &item);
1269da2e3ebdSchin 					PUT(&buf, ']');
1270da2e3ebdSchin 				}
1271da2e3ebdSchin 				else
1272da2e3ebdSchin 				{
1273da2e3ebdSchin 					if (k < 0)
1274da2e3ebdSchin 					{
1275da2e3ebdSchin 						COMMENT(&notice, &buf, "CONTRIBUTORS", 0);
1276da2e3ebdSchin 						comment(&notice, &buf, NiL, 0, 0);
1277da2e3ebdSchin 					}
1278da2e3ebdSchin 					k = 1;
1279da2e3ebdSchin 					expand(&notice, &tmp, &item);
1280da2e3ebdSchin 					comment(&notice, &buf, BUF(&tmp), USE(&tmp), 0);
1281da2e3ebdSchin 				}
1282da2e3ebdSchin 			}
1283da2e3ebdSchin 		}
1284da2e3ebdSchin 		if (k > 0)
1285da2e3ebdSchin 			comment(&notice, &buf, NiL, 0, 0);
1286da2e3ebdSchin 	}
1287da2e3ebdSchin 	if (notice.type == USAGE)
1288da2e3ebdSchin 	{
1289da2e3ebdSchin 		copy(&buf, "[-copyright?", -1);
1290da2e3ebdSchin 		copyright(&notice, &buf);
1291da2e3ebdSchin 		PUT(&buf, ']');
1292da2e3ebdSchin 		if (notice.item[URL].data)
1293da2e3ebdSchin 		{
1294da2e3ebdSchin 			copy(&buf, "[-license?", -1);
1295da2e3ebdSchin 			expand(&notice, &buf, &notice.item[URL]);
1296da2e3ebdSchin 			PUT(&buf, ']');
1297da2e3ebdSchin 		}
1298da2e3ebdSchin 		PUT(&buf, '\n');
1299da2e3ebdSchin 	}
1300da2e3ebdSchin 	else
1301da2e3ebdSchin 		comment(&notice, &buf, NiL, -1, 0);
1302da2e3ebdSchin 	return END(&buf);
1303da2e3ebdSchin }
1304