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, ¬ice->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, ¬ice->item[PARENT]);
404da2e3ebdSchin }
405da2e3ebdSchin if (notice->item[CORPORATION].data)
406da2e3ebdSchin {
407da2e3ebdSchin PUT(b, ' ');
408da2e3ebdSchin expand(notice, b, ¬ice->item[CORPORATION]);
409da2e3ebdSchin if (notice->item[INCORPORATION].data)
410da2e3ebdSchin {
411da2e3ebdSchin PUT(b, ' ');
412da2e3ebdSchin expand(notice, b, ¬ice->item[INCORPORATION]);
413da2e3ebdSchin }
414da2e3ebdSchin }
415da2e3ebdSchin else if (notice->item[COMPANY].data)
416da2e3ebdSchin {
417da2e3ebdSchin PUT(b, ' ');
418da2e3ebdSchin expand(notice, b, ¬ice->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(¬ice, &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(¬ice, &buf, ¬ice.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(¬ice, &buf, &item);
728da2e3ebdSchin }
729da2e3ebdSchin else
730da2e3ebdSchin expand(¬ice, &buf, ¬ice.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(¬ice, &buf, NiL, 1, 0);
808da2e3ebdSchin comment(¬ice, &buf, NiL, 0, 0);
809da2e3ebdSchin if (notice.item[PACKAGE].data)
810da2e3ebdSchin {
811da2e3ebdSchin copy(&tmp, "This software is part of the ", -1);
812da2e3ebdSchin expand(¬ice, &tmp, ¬ice.item[PACKAGE]);
813da2e3ebdSchin copy(&tmp, " package", -1);
814da2e3ebdSchin comment(¬ice, &buf, BUF(&tmp), USE(&tmp), 0);
815da2e3ebdSchin }
816da2e3ebdSchin if (notice.type >= OPEN)
817da2e3ebdSchin {
818da2e3ebdSchin copyright(¬ice, &tmp);
819da2e3ebdSchin comment(¬ice, &buf, BUF(&tmp), USE(&tmp), 0);
820da2e3ebdSchin if (notice.type >= SPECIAL)
821da2e3ebdSchin COMMENT(¬ice, &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(¬ice, &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(¬ice, &tmp, ¬ice.item[VERSION]);
836da2e3ebdSchin }
837da2e3ebdSchin comment(¬ice, &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(¬ice, &tmp, ¬ice.item[PARENT]);
844da2e3ebdSchin copy(&tmp, " ", -1);
845da2e3ebdSchin }
846da2e3ebdSchin if (notice.item[CORPORATION].data)
847da2e3ebdSchin {
848da2e3ebdSchin expand(¬ice, &tmp, ¬ice.item[CORPORATION]);
849da2e3ebdSchin if (notice.item[INCORPORATION].data)
850da2e3ebdSchin {
851da2e3ebdSchin copy(&tmp, " ", -1);
852da2e3ebdSchin expand(¬ice, &tmp, ¬ice.item[INCORPORATION]);
853da2e3ebdSchin }
854da2e3ebdSchin }
855da2e3ebdSchin else if (notice.item[COMPANY].data)
856da2e3ebdSchin expand(¬ice, &tmp, ¬ice.item[COMPANY]);
857da2e3ebdSchin comment(¬ice, &buf, BUF(&tmp), USE(&tmp), 0);
858da2e3ebdSchin }
859da2e3ebdSchin comment(¬ice, &buf, NiL, 0, 0);
860da2e3ebdSchin COMMENT(¬ice, &buf, "A copy of the License is available at", 0);
861da2e3ebdSchin if (notice.item[URL].data)
862da2e3ebdSchin {
863da2e3ebdSchin expand(¬ice, &tmp, ¬ice.item[URL]);
864da2e3ebdSchin comment(¬ice, &buf, BUF(&tmp), USE(&tmp), 0);
865da2e3ebdSchin if (notice.item[URLMD5].data)
866da2e3ebdSchin {
867da2e3ebdSchin copy(&tmp, "(with md5 checksum ", -1);
868da2e3ebdSchin expand(¬ice, &tmp, ¬ice.item[URLMD5]);
869da2e3ebdSchin copy(&tmp, ")", -1);
870da2e3ebdSchin comment(¬ice, &buf, BUF(&tmp), USE(&tmp), 0);
871da2e3ebdSchin }
872da2e3ebdSchin }
8733e14f97fSRoger A. Faulkner else if (notice.type == EPL)
8743e14f97fSRoger A. Faulkner COMMENT(¬ice, &buf, "http://www.eclipse.org/org/documents/epl-v10.html", 0);
875da2e3ebdSchin else
876da2e3ebdSchin COMMENT(¬ice, &buf, "http://www.opensource.org/licenses/cpl", 0);
877da2e3ebdSchin comment(¬ice, &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(¬ice, &buf, BUF(&tmp), USE(&tmp), 0);
884da2e3ebdSchin if (notice.item[i = CORPORATION].data)
885da2e3ebdSchin {
886da2e3ebdSchin if (notice.item[PARENT].data)
887da2e3ebdSchin {
888da2e3ebdSchin expand(¬ice, &tmp, ¬ice.item[i = PARENT]);
889da2e3ebdSchin copy(&tmp, " ", -1);
890da2e3ebdSchin }
891da2e3ebdSchin expand(¬ice, &tmp, ¬ice.item[CORPORATION]);
892da2e3ebdSchin comment(¬ice, &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(¬ice, &tmp, ¬ice.item[i = PARENT]);
899da2e3ebdSchin copy(&tmp, " ", -1);
900da2e3ebdSchin }
901da2e3ebdSchin expand(¬ice, &tmp, ¬ice.item[COMPANY]);
902da2e3ebdSchin comment(¬ice, &buf, BUF(&tmp), USE(&tmp), 0);
903da2e3ebdSchin }
904da2e3ebdSchin else
905da2e3ebdSchin i = -1;
906da2e3ebdSchin if (notice.item[URL].data)
907da2e3ebdSchin {
908da2e3ebdSchin COMMENT(¬ice, &buf, "A copy of the Source Code Agreement is available", 0);
909da2e3ebdSchin copy(&tmp, "at the ", -1);
910da2e3ebdSchin if (i >= 0)
911da2e3ebdSchin expand(¬ice, &tmp, ¬ice.item[i]);
912da2e3ebdSchin copy(&tmp, " Internet web site URL", -1);
913da2e3ebdSchin comment(¬ice, &buf, BUF(&tmp), USE(&tmp), 0);
914da2e3ebdSchin comment(¬ice, &buf, NiL, 0, 0);
915da2e3ebdSchin expand(¬ice, &tmp, ¬ice.item[URL]);
916da2e3ebdSchin comment(¬ice, &buf, BUF(&tmp), USE(&tmp), 0);
917da2e3ebdSchin if (notice.item[URLMD5].data)
918da2e3ebdSchin {
919da2e3ebdSchin copy(&tmp, "(with an md5 checksum of ", -1);
920da2e3ebdSchin expand(¬ice, &tmp, ¬ice.item[URLMD5]);
921da2e3ebdSchin copy(&tmp, ")", -1);
922da2e3ebdSchin comment(¬ice, &buf, BUF(&tmp), USE(&tmp), 0);
923da2e3ebdSchin }
924da2e3ebdSchin comment(¬ice, &buf, NiL, 0, 0);
925da2e3ebdSchin }
926da2e3ebdSchin COMMENT(¬ice, &buf, "If you have copied or used this software without agreeing", 0);
927da2e3ebdSchin COMMENT(¬ice, &buf, "to the terms of the license you are infringing on", 0);
928da2e3ebdSchin COMMENT(¬ice, &buf, "the license and copyright and are violating", 0);
929da2e3ebdSchin if (i >= 0)
930da2e3ebdSchin expand(¬ice, &tmp, ¬ice.item[i]);
931da2e3ebdSchin copy(&tmp, "'s", -1);
932da2e3ebdSchin if (n >= COMLONG)
933da2e3ebdSchin comment(¬ice, &buf, BUF(&tmp), USE(&tmp), 0);
934da2e3ebdSchin else
935da2e3ebdSchin PUT(&tmp, ' ');
936da2e3ebdSchin copy(&tmp, "intellectual property rights.", -1);
937da2e3ebdSchin comment(¬ice, &buf, BUF(&tmp), USE(&tmp), 0);
938da2e3ebdSchin comment(¬ice, &buf, NiL, 0, 0);
939da2e3ebdSchin }
940da2e3ebdSchin else if (notice.type == GPL)
941da2e3ebdSchin {
942da2e3ebdSchin comment(¬ice, &buf, NiL, 0, 0);
943da2e3ebdSchin COMMENT(¬ice, &buf, "This is free software; you can redistribute it and/or", 0);
944da2e3ebdSchin COMMENT(¬ice, &buf, "modify it under the terms of the GNU General Public License", 0);
945da2e3ebdSchin COMMENT(¬ice, &buf, "as published by the Free Software Foundation;", 0);
946da2e3ebdSchin COMMENT(¬ice, &buf, "either version 2, or (at your option) any later version.", 0);
947da2e3ebdSchin comment(¬ice, &buf, NiL, 0, 0);
948da2e3ebdSchin COMMENT(¬ice, &buf, "This software is distributed in the hope that it", 0);
949da2e3ebdSchin COMMENT(¬ice, &buf, "will be useful, but WITHOUT ANY WARRANTY;", 0);
950da2e3ebdSchin COMMENT(¬ice, &buf, "without even the implied warranty of MERCHANTABILITY", 0);
951da2e3ebdSchin COMMENT(¬ice, &buf, "or FITNESS FOR A PARTICULAR PURPOSE.", 0);
952da2e3ebdSchin COMMENT(¬ice, &buf, "See the GNU General Public License for more details.", 0);
953da2e3ebdSchin comment(¬ice, &buf, NiL, 0, 0);
954da2e3ebdSchin COMMENT(¬ice, &buf, "You should have received a copy of the", 0);
955da2e3ebdSchin COMMENT(¬ice, &buf, "GNU General Public License", 0);
956da2e3ebdSchin COMMENT(¬ice, &buf, "along with this software (see the file COPYING.)", 0);
957da2e3ebdSchin COMMENT(¬ice, &buf, "If not, a copy is available at", 0);
958da2e3ebdSchin COMMENT(¬ice, &buf, "http://www.gnu.org/copyleft/gpl.html", 0);
959da2e3ebdSchin comment(¬ice, &buf, NiL, 0, 0);
960da2e3ebdSchin }
961da2e3ebdSchin else if (notice.type == BSD)
962da2e3ebdSchin {
963da2e3ebdSchin comment(¬ice, &buf, NiL, 0, 0);
964da2e3ebdSchin COMMENT(¬ice, &buf, "Redistribution and use in source and binary forms, with or", -1);
965da2e3ebdSchin COMMENT(¬ice, &buf, "without modification, are permitted provided that the following", -1);
966da2e3ebdSchin COMMENT(¬ice, &buf, "conditions are met:", -1);
967da2e3ebdSchin comment(¬ice, &buf, NiL, 0, 0);
968da2e3ebdSchin COMMENT(¬ice, &buf, " 1. Redistributions of source code must retain the above", -1);
969da2e3ebdSchin COMMENT(¬ice, &buf, " copyright notice, this list of conditions and the", -1);
970da2e3ebdSchin COMMENT(¬ice, &buf, " following disclaimer.", -1);
971da2e3ebdSchin comment(¬ice, &buf, NiL, 0, 0);
972da2e3ebdSchin COMMENT(¬ice, &buf, " 2. Redistributions in binary form must reproduce the above", -1);
973da2e3ebdSchin COMMENT(¬ice, &buf, " copyright notice, this list of conditions and the", -1);
974da2e3ebdSchin COMMENT(¬ice, &buf, " following disclaimer in the documentation and/or other", -1);
975da2e3ebdSchin COMMENT(¬ice, &buf, " materials provided with the distribution.", -1);
976da2e3ebdSchin comment(¬ice, &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(¬ice, &tmp, ¬ice.item[i]);
980da2e3ebdSchin else
981da2e3ebdSchin copy(&tmp, "the copyright holder", -1);
982da2e3ebdSchin copy(&tmp, " nor the", -1);
983da2e3ebdSchin comment(¬ice, &buf, BUF(&tmp), USE(&tmp), -1);
984da2e3ebdSchin COMMENT(¬ice, &buf, " names of its contributors may be used to endorse or", -1);
985da2e3ebdSchin COMMENT(¬ice, &buf, " promote products derived from this software without", -1);
986da2e3ebdSchin COMMENT(¬ice, &buf, " specific prior written permission.", -1);
987da2e3ebdSchin comment(¬ice, &buf, NiL, 0, 0);
988da2e3ebdSchin COMMENT(¬ice, &buf, "THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND", -1);
989da2e3ebdSchin COMMENT(¬ice, &buf, "CONTRIBUTORS \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES,", -1);
990da2e3ebdSchin COMMENT(¬ice, &buf, "INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF", -1);
991da2e3ebdSchin COMMENT(¬ice, &buf, "MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE", -1);
992da2e3ebdSchin COMMENT(¬ice, &buf, "DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS", -1);
993da2e3ebdSchin COMMENT(¬ice, &buf, "BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,", -1);
994da2e3ebdSchin COMMENT(¬ice, &buf, "EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED", -1);
995da2e3ebdSchin COMMENT(¬ice, &buf, "TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,", -1);
996da2e3ebdSchin COMMENT(¬ice, &buf, "DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON", -1);
997da2e3ebdSchin COMMENT(¬ice, &buf, "ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,", -1);
998da2e3ebdSchin COMMENT(¬ice, &buf, "OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY", -1);
999da2e3ebdSchin COMMENT(¬ice, &buf, "OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE", -1);
1000da2e3ebdSchin COMMENT(¬ice, &buf, "POSSIBILITY OF SUCH DAMAGE.", -1);
1001da2e3ebdSchin comment(¬ice, &buf, NiL, 0, 0);
1002da2e3ebdSchin }
1003da2e3ebdSchin else if (notice.type == ZLIB)
1004da2e3ebdSchin {
1005da2e3ebdSchin comment(¬ice, &buf, NiL, 0, 0);
1006da2e3ebdSchin COMMENT(¬ice, &buf, "This software is provided 'as-is', without any express or implied", -1);
1007da2e3ebdSchin COMMENT(¬ice, &buf, "warranty. In no event will the authors be held liable for any", -1);
1008da2e3ebdSchin COMMENT(¬ice, &buf, "damages arising from the use of this software.", -1);
1009da2e3ebdSchin comment(¬ice, &buf, NiL, 0, 0);
1010da2e3ebdSchin COMMENT(¬ice, &buf, "Permission is granted to anyone to use this software for any", -1);
1011da2e3ebdSchin COMMENT(¬ice, &buf, "purpose, including commercial applications, and to alter it and", -1);
1012da2e3ebdSchin COMMENT(¬ice, &buf, "redistribute it freely, subject to the following restrictions:", -1);
1013da2e3ebdSchin comment(¬ice, &buf, NiL, 0, 0);
1014da2e3ebdSchin COMMENT(¬ice, &buf, " 1. The origin of this software must not be misrepresented;", -1);
1015da2e3ebdSchin COMMENT(¬ice, &buf, " you must not claim that you wrote the original software. If", -1);
1016da2e3ebdSchin COMMENT(¬ice, &buf, " you use this software in a product, an acknowledgment in the", -1);
1017da2e3ebdSchin COMMENT(¬ice, &buf, " product documentation would be appreciated but is not", -1);
1018da2e3ebdSchin COMMENT(¬ice, &buf, " required.", -1);
1019da2e3ebdSchin comment(¬ice, &buf, NiL, 0, 0);
1020da2e3ebdSchin COMMENT(¬ice, &buf, " 2. Altered source versions must be plainly marked as such,", -1);
1021da2e3ebdSchin COMMENT(¬ice, &buf, " and must not be misrepresented as being the original", -1);
1022da2e3ebdSchin COMMENT(¬ice, &buf, " software.", -1);
1023da2e3ebdSchin comment(¬ice, &buf, NiL, 0, 0);
1024da2e3ebdSchin COMMENT(¬ice, &buf, " 3. This notice may not be removed or altered from any source", -1);
1025da2e3ebdSchin COMMENT(¬ice, &buf, " distribution.", -1);
1026da2e3ebdSchin comment(¬ice, &buf, NiL, 0, 0);
1027da2e3ebdSchin }
1028da2e3ebdSchin else if (notice.type == MIT)
1029da2e3ebdSchin {
1030da2e3ebdSchin comment(¬ice, &buf, NiL, 0, 0);
1031da2e3ebdSchin COMMENT(¬ice, &buf, "Permission is hereby granted, free of charge, to any person", 0);
1032da2e3ebdSchin COMMENT(¬ice, &buf, "obtaining a copy of this software and associated", 0);
1033da2e3ebdSchin COMMENT(¬ice, &buf, "documentation files (the \"Software\"), to deal in the", 0);
1034da2e3ebdSchin COMMENT(¬ice, &buf, "Software without restriction, including without limitation", 0);
1035da2e3ebdSchin COMMENT(¬ice, &buf, "the rights to use, copy, modify, merge, publish, distribute,", 0);
1036da2e3ebdSchin COMMENT(¬ice, &buf, "sublicense, and/or sell copies of the Software, and to", 0);
1037da2e3ebdSchin COMMENT(¬ice, &buf, "permit persons to whom the Software is furnished to do so,", 0);
1038da2e3ebdSchin COMMENT(¬ice, &buf, "subject to the following conditions:", 0);
1039da2e3ebdSchin comment(¬ice, &buf, NiL, 0, 0);
1040da2e3ebdSchin COMMENT(¬ice, &buf, "The above copyright notice and this permission notice shall", 0);
1041da2e3ebdSchin COMMENT(¬ice, &buf, "be included in all copies or substantial portions of the", 0);
1042da2e3ebdSchin COMMENT(¬ice, &buf, "Software.", 0);
1043da2e3ebdSchin comment(¬ice, &buf, NiL, 0, 0);
1044da2e3ebdSchin COMMENT(¬ice, &buf, "THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY", 0);
1045da2e3ebdSchin COMMENT(¬ice, &buf, "KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE", 0);
1046da2e3ebdSchin COMMENT(¬ice, &buf, "WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR", 0);
1047da2e3ebdSchin COMMENT(¬ice, &buf, "PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS", 0);
1048da2e3ebdSchin COMMENT(¬ice, &buf, "OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR", 0);
1049da2e3ebdSchin COMMENT(¬ice, &buf, "OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR", 0);
1050da2e3ebdSchin COMMENT(¬ice, &buf, "OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE", 0);
1051da2e3ebdSchin COMMENT(¬ice, &buf, "SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.", 0);
1052da2e3ebdSchin comment(¬ice, &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(¬ice, &tmp, ¬ice.item[i]);
1061da2e3ebdSchin copy(&tmp, " - ", -1);
1062da2e3ebdSchin }
1063da2e3ebdSchin else
1064da2e3ebdSchin i = -1;
1065da2e3ebdSchin copy(&tmp, "Proprietary", -1);
1066da2e3ebdSchin comment(¬ice, &buf, BUF(&tmp), USE(&tmp), 1);
1067da2e3ebdSchin comment(¬ice, &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(¬ice, &buf, BUF(&tmp), USE(&tmp), 1);
1074da2e3ebdSchin if (notice.item[PARENT].data)
1075da2e3ebdSchin {
1076da2e3ebdSchin expand(¬ice, &tmp, ¬ice.item[PARENT]);
1077da2e3ebdSchin copy(&tmp, " ", -1);
1078da2e3ebdSchin }
1079da2e3ebdSchin if (notice.item[CORPORATION].data)
1080da2e3ebdSchin {
1081da2e3ebdSchin expand(¬ice, &tmp, ¬ice.item[CORPORATION]);
1082da2e3ebdSchin comment(¬ice, &buf, BUF(&tmp), USE(&tmp), 1);
1083da2e3ebdSchin }
1084da2e3ebdSchin else if (notice.item[COMPANY].data)
1085da2e3ebdSchin {
1086da2e3ebdSchin expand(¬ice, &tmp, ¬ice.item[COMPANY]);
1087da2e3ebdSchin comment(¬ice, &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(¬ice, &buf, BUF(&tmp), USE(&tmp), 1);
1096da2e3ebdSchin if (notice.item[i = PARENT].data || notice.item[i = CORPORATION].data)
1097da2e3ebdSchin expand(¬ice, &tmp, ¬ice.item[i]);
1098da2e3ebdSchin if (notice.item[COMPANY].data)
1099da2e3ebdSchin {
1100da2e3ebdSchin if (SIZ(&tmp))
1101da2e3ebdSchin PUT(&tmp, ' ');
1102da2e3ebdSchin expand(¬ice, &tmp, ¬ice.item[COMPANY]);
1103da2e3ebdSchin }
1104da2e3ebdSchin if (SIZ(&tmp))
1105da2e3ebdSchin comment(¬ice, &buf, BUF(&tmp), USE(&tmp), 1);
1106da2e3ebdSchin COMMENT(¬ice, &buf, "and is not to be disclosed or used except in", 1);
1107da2e3ebdSchin COMMENT(¬ice, &buf, "accordance with applicable agreements", 1);
1108da2e3ebdSchin }
1109da2e3ebdSchin comment(¬ice, &buf, NiL, 0, 0);
1110da2e3ebdSchin }
1111da2e3ebdSchin else if (notice.type == NONEXCLUSIVE)
1112da2e3ebdSchin {
1113da2e3ebdSchin COMMENT(¬ice, &buf, "For nonexclusive individual use", 1);
1114da2e3ebdSchin comment(¬ice, &buf, NiL, 0, 0);
1115da2e3ebdSchin }
1116da2e3ebdSchin else if (notice.type == NONCOMMERCIAL)
1117da2e3ebdSchin {
1118da2e3ebdSchin COMMENT(¬ice, &buf, "For noncommercial use", 1);
1119da2e3ebdSchin comment(¬ice, &buf, NiL, 0, 0);
1120da2e3ebdSchin }
1121da2e3ebdSchin if (notice.type >= PROPRIETARY && !notice.item[URL].data)
1122da2e3ebdSchin {
1123da2e3ebdSchin COMMENT(¬ice, &buf, "Unpublished & Not for Publication", 0);
1124da2e3ebdSchin comment(¬ice, &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(¬ice, &buf, BUF(&tmp), USE(&tmp), 0);
1134da2e3ebdSchin else
1135da2e3ebdSchin PUT(&tmp, ' ');
1136da2e3ebdSchin if (notice.item[PARENT].data)
1137da2e3ebdSchin {
1138da2e3ebdSchin expand(¬ice, &tmp, ¬ice.item[PARENT]);
1139da2e3ebdSchin copy(&tmp, " ", -1);
1140da2e3ebdSchin }
1141da2e3ebdSchin if (notice.item[CORPORATION].data)
1142da2e3ebdSchin {
1143da2e3ebdSchin expand(¬ice, &tmp, ¬ice.item[CORPORATION]);
1144da2e3ebdSchin if (notice.item[INCORPORATION].data)
1145da2e3ebdSchin {
1146da2e3ebdSchin copy(&tmp, " ", -1);
1147da2e3ebdSchin expand(¬ice, &tmp, ¬ice.item[INCORPORATION]);
1148da2e3ebdSchin }
1149da2e3ebdSchin }
1150da2e3ebdSchin else if (notice.item[COMPANY].data)
1151da2e3ebdSchin expand(¬ice, &tmp, ¬ice.item[COMPANY]);
1152da2e3ebdSchin }
1153da2e3ebdSchin comment(¬ice, &buf, BUF(&tmp), USE(&tmp), 0);
1154da2e3ebdSchin COMMENT(¬ice, &buf, "under the terms and conditions of the license in", 0);
1155da2e3ebdSchin expand(¬ice, &tmp, ¬ice.item[URL]);
1156da2e3ebdSchin comment(¬ice, &buf, BUF(&tmp), USE(&tmp), 0);
1157da2e3ebdSchin if (notice.item[URLMD5].data)
1158da2e3ebdSchin {
1159da2e3ebdSchin copy(&tmp, "(with an md5 checksum of ", -1);
1160da2e3ebdSchin expand(¬ice, &tmp, ¬ice.item[URLMD5]);
1161da2e3ebdSchin copy(&tmp, ")", -1);
1162da2e3ebdSchin comment(¬ice, &buf, BUF(&tmp), USE(&tmp), 0);
1163da2e3ebdSchin }
1164da2e3ebdSchin comment(¬ice, &buf, NiL, 0, 0);
1165da2e3ebdSchin }
1166da2e3ebdSchin else if (notice.type == PROPRIETARY)
1167da2e3ebdSchin {
1168da2e3ebdSchin COMMENT(¬ice, &buf, "The copyright notice above does not evidence any", 0);
1169da2e3ebdSchin COMMENT(¬ice, &buf, "actual or intended publication of such source code", 0);
1170da2e3ebdSchin comment(¬ice, &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(¬ice, &tmp, &item);
1191da2e3ebdSchin comment(¬ice, &buf, BUF(&tmp), USE(&tmp), h);
1192da2e3ebdSchin } while (v++ < x);
1193da2e3ebdSchin if (item.size)
1194da2e3ebdSchin comment(¬ice, &buf, NiL, 0, 0);
1195da2e3ebdSchin }
1196da2e3ebdSchin if (notice.item[ORGANIZATION].data)
1197da2e3ebdSchin {
1198da2e3ebdSchin expand(¬ice, &tmp, ¬ice.item[ORGANIZATION]);
1199da2e3ebdSchin comment(¬ice, &buf, BUF(&tmp), USE(&tmp), 0);
1200da2e3ebdSchin if (notice.item[i = PARENT].data || notice.item[i = CORPORATION].data)
1201da2e3ebdSchin expand(¬ice, &tmp, ¬ice.item[i]);
1202da2e3ebdSchin if (notice.item[COMPANY].data)
1203da2e3ebdSchin {
1204da2e3ebdSchin if (SIZ(&tmp))
1205da2e3ebdSchin PUT(&tmp, ' ');
1206da2e3ebdSchin expand(¬ice, &tmp, ¬ice.item[COMPANY]);
1207da2e3ebdSchin }
1208da2e3ebdSchin if (SIZ(&tmp))
1209da2e3ebdSchin comment(¬ice, &buf, BUF(&tmp), USE(&tmp), 0);
1210da2e3ebdSchin if (notice.item[LOCATION].data)
1211da2e3ebdSchin {
1212da2e3ebdSchin expand(¬ice, &tmp, ¬ice.item[LOCATION]);
1213da2e3ebdSchin comment(¬ice, &buf, BUF(&tmp), USE(&tmp), 0);
1214da2e3ebdSchin }
1215da2e3ebdSchin comment(¬ice, &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(¬ice, &buf, ¬ice.id[i].value);
1245da2e3ebdSchin PUT(&buf, ']');
1246da2e3ebdSchin }
1247da2e3ebdSchin else
1248da2e3ebdSchin {
1249da2e3ebdSchin if (k < 0)
1250da2e3ebdSchin {
1251da2e3ebdSchin COMMENT(¬ice, &buf, "CONTRIBUTORS", 0);
1252da2e3ebdSchin comment(¬ice, &buf, NiL, 0, 0);
1253da2e3ebdSchin }
1254da2e3ebdSchin k = 1;
1255da2e3ebdSchin expand(¬ice, &tmp, ¬ice.id[i].value);
1256da2e3ebdSchin comment(¬ice, &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(¬ice, &buf, &item);
1269da2e3ebdSchin PUT(&buf, ']');
1270da2e3ebdSchin }
1271da2e3ebdSchin else
1272da2e3ebdSchin {
1273da2e3ebdSchin if (k < 0)
1274da2e3ebdSchin {
1275da2e3ebdSchin COMMENT(¬ice, &buf, "CONTRIBUTORS", 0);
1276da2e3ebdSchin comment(¬ice, &buf, NiL, 0, 0);
1277da2e3ebdSchin }
1278da2e3ebdSchin k = 1;
1279da2e3ebdSchin expand(¬ice, &tmp, &item);
1280da2e3ebdSchin comment(¬ice, &buf, BUF(&tmp), USE(&tmp), 0);
1281da2e3ebdSchin }
1282da2e3ebdSchin }
1283da2e3ebdSchin }
1284da2e3ebdSchin if (k > 0)
1285da2e3ebdSchin comment(¬ice, &buf, NiL, 0, 0);
1286da2e3ebdSchin }
1287da2e3ebdSchin if (notice.type == USAGE)
1288da2e3ebdSchin {
1289da2e3ebdSchin copy(&buf, "[-copyright?", -1);
1290da2e3ebdSchin copyright(¬ice, &buf);
1291da2e3ebdSchin PUT(&buf, ']');
1292da2e3ebdSchin if (notice.item[URL].data)
1293da2e3ebdSchin {
1294da2e3ebdSchin copy(&buf, "[-license?", -1);
1295da2e3ebdSchin expand(¬ice, &buf, ¬ice.item[URL]);
1296da2e3ebdSchin PUT(&buf, ']');
1297da2e3ebdSchin }
1298da2e3ebdSchin PUT(&buf, '\n');
1299da2e3ebdSchin }
1300da2e3ebdSchin else
1301da2e3ebdSchin comment(¬ice, &buf, NiL, -1, 0);
1302da2e3ebdSchin return END(&buf);
1303da2e3ebdSchin }
1304