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