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