1 /*********************************************************************** 2 * * 3 * This software is part of the ast package * 4 * Copyright (c) 1985-2009 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 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 first = 1; 432 while (c = *s) 433 { 434 while (c == ' ' || c == '\t' || c == '\n' && ++line || c == '\r' || c == ',' || c == ';' || c == ')') 435 c = *++s; 436 if (!c) 437 break; 438 if (c == '#') 439 { 440 while (*++s && *s != '\n'); 441 if (*s) 442 s++; 443 line++; 444 continue; 445 } 446 if (c == '\n') 447 { 448 s++; 449 line++; 450 continue; 451 } 452 if (c == '[') 453 c = *++s; 454 x = s; 455 n = 0; 456 while (c && c != '=' && c != ']' && c != ')' && c != ',' && c != ' ' && c != '\t' && c != '\n' && c != '\r') 457 c = *++s; 458 n = s - x; 459 h = lookup(key, x, n); 460 if (c == ']') 461 c = *++s; 462 if (c == '=' || first) 463 { 464 if (c == '=') 465 { 466 q = ((c = *++s) == '"' || c == '\'') ? *s++ : 0; 467 if (c == '(') 468 { 469 s++; 470 if (h == LICENSE) 471 contributor = 0; 472 else if (h == CONTRIBUTOR) 473 contributor = 1; 474 else 475 { 476 q = 1; 477 i = 0; 478 for (;;) 479 { 480 switch (*s++) 481 { 482 case 0: 483 s--; 484 break; 485 case '(': 486 if (!i) 487 q++; 488 continue; 489 case ')': 490 if (!i && !--q) 491 break; 492 continue; 493 case '"': 494 case '\'': 495 if (!i) 496 i = *(s - 1); 497 else if (i == *(s - 1)) 498 i = 0; 499 continue; 500 case '\\': 501 if (*s == i && i == '"') 502 i++; 503 continue; 504 case '\n': 505 line++; 506 continue; 507 default: 508 continue; 509 } 510 break; 511 } 512 } 513 continue; 514 } 515 quote = 0; 516 v = s; 517 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 != ';')) 518 { 519 if (c == '\n') 520 line++; 521 s++; 522 } 523 } 524 else 525 { 526 h = STYLE; 527 v = x; 528 } 529 if (c == '\n') 530 line++; 531 if (contributor) 532 { 533 for (i = 0; i < notice.ids; i++) 534 if (n == notice.id[i].name.size && !strncmp(x, notice.id[i].name.data, n)) 535 break; 536 if (i < IDS) 537 { 538 notice.id[i].name.data = x; 539 notice.id[i].name.size = n; 540 notice.id[i].name.quote = 0; 541 notice.id[i].value.data = v; 542 notice.id[i].value.size = s - v; 543 notice.id[i].value.quote = quote; 544 if (notice.ids <= i) 545 notice.ids = i + 1; 546 } 547 } 548 else if (h == QUERY) 549 { 550 if ((s - v) == 3 && v[0] == 'a' && v[1] == 'l' && v[2] == 'l') 551 { 552 for (i = 0; i < ITEMS; i++) 553 if (notice.item[i].size) 554 { 555 expand(¬ice, &buf, &key[i]); 556 PUT(&buf, '='); 557 for (h = 0;; h++) 558 if (h >= notice.item[i].size) 559 { 560 h = 0; 561 break; 562 } 563 else if (notice.item[i].data[h] == ' ' || notice.item[i].data[h] == '\t') 564 break; 565 if (h) 566 PUT(&buf, '\''); 567 expand(¬ice, &buf, ¬ice.item[i]); 568 if (h) 569 PUT(&buf, '\''); 570 PUT(&buf, '\n'); 571 } 572 } 573 else 574 { 575 if ((h = lookup(key, v, s - v)) < 0) 576 { 577 item.data = v; 578 item.size = s - v; 579 item.quote = 0; 580 expand(¬ice, &buf, &item); 581 } 582 else 583 expand(¬ice, &buf, ¬ice.item[h]); 584 PUT(&buf, '\n'); 585 } 586 return END(&buf); 587 } 588 else 589 { 590 if (h == STYLE) 591 switch (c = lookup(lic, v, s - v)) 592 { 593 case NONE: 594 return 0; 595 case TEST: 596 notice.test = 1; 597 h = -1; 598 break; 599 case VERBOSE: 600 notice.verbose = 1; 601 h = -1; 602 break; 603 case USAGE: 604 notice.type = c; 605 h = -1; 606 break; 607 case -1: 608 c = SPECIAL; 609 /*FALLTHROUGH*/ 610 default: 611 notice.type = c; 612 notice.item[CLASS].data = lic[lic[c].quote].data; 613 notice.item[CLASS].size = lic[lic[c].quote].size; 614 break; 615 } 616 if (h >= 0) 617 { 618 notice.item[h].data = (notice.item[h].size = s - v) ? v : (char*)0; 619 notice.item[h].quote = quote; 620 k = 1; 621 } 622 } 623 } 624 else 625 { 626 if (file) 627 { 628 copy(&buf, "\"", -1); 629 copy(&buf, file, -1); 630 copy(&buf, "\", line ", -1); 631 x = &tmpbuf[sizeof(tmpbuf)]; 632 *--x = 0; 633 line++; 634 do *--x = ("0123456789")[line % 10]; while (line /= 10); 635 copy(&buf, x, -1); 636 copy(&buf, ": ", -1); 637 } 638 copy(&buf, "option error: assignment expected", -1); 639 PUT(&buf, 0); 640 return -1; 641 } 642 if (*s) 643 s++; 644 first = 0; 645 } 646 if (!options || !*(s = options)) 647 break; 648 options = 0; 649 } 650 if (!k) 651 return 0; 652 if (notice.type == INLINE && (!notice.verbose || !notice.item[NOTICE].data)) 653 return 0; 654 if (notice.type != USAGE) 655 { 656 if (!notice.type) 657 notice.type = SPECIAL; 658 comment(¬ice, &buf, NiL, 1, 0); 659 comment(¬ice, &buf, NiL, 0, 0); 660 if (notice.item[PACKAGE].data) 661 { 662 copy(&tmp, "This software is part of the ", -1); 663 expand(¬ice, &tmp, ¬ice.item[PACKAGE]); 664 copy(&tmp, " package", -1); 665 comment(¬ice, &buf, BUF(&tmp), USE(&tmp), 0); 666 } 667 if (notice.type >= OPEN) 668 { 669 copyright(¬ice, &tmp); 670 comment(¬ice, &buf, BUF(&tmp), USE(&tmp), 0); 671 if (notice.type >= SPECIAL) 672 COMMENT(¬ice, &buf, "All Rights Reserved", 0); 673 } 674 if (notice.type == CPL) 675 { 676 copy(&tmp, notice.item[PACKAGE].data ? "and" : "This software", -1); 677 copy(&tmp, " is licensed under the", -1); 678 comment(¬ice, &buf, BUF(&tmp), USE(&tmp), 0); 679 copy(&tmp, "Common Public License", -1); 680 if (notice.item[VERSION].data) 681 { 682 copy(&tmp, ", Version ", -1); 683 expand(¬ice, &tmp, ¬ice.item[VERSION]); 684 } 685 comment(¬ice, &buf, BUF(&tmp), USE(&tmp), 0); 686 if (notice.item[CORPORATION].data || notice.item[COMPANY].data) 687 { 688 copy(&tmp, "by ", -1); 689 if (notice.item[PARENT].data) 690 { 691 expand(¬ice, &tmp, ¬ice.item[PARENT]); 692 copy(&tmp, " ", -1); 693 } 694 if (notice.item[CORPORATION].data) 695 { 696 expand(¬ice, &tmp, ¬ice.item[CORPORATION]); 697 if (notice.item[INCORPORATION].data) 698 { 699 copy(&tmp, " ", -1); 700 expand(¬ice, &tmp, ¬ice.item[INCORPORATION]); 701 } 702 } 703 else if (notice.item[COMPANY].data) 704 expand(¬ice, &tmp, ¬ice.item[COMPANY]); 705 comment(¬ice, &buf, BUF(&tmp), USE(&tmp), 0); 706 } 707 comment(¬ice, &buf, NiL, 0, 0); 708 COMMENT(¬ice, &buf, "A copy of the License is available at", 0); 709 if (notice.item[URL].data) 710 { 711 expand(¬ice, &tmp, ¬ice.item[URL]); 712 comment(¬ice, &buf, BUF(&tmp), USE(&tmp), 0); 713 if (notice.item[URLMD5].data) 714 { 715 copy(&tmp, "(with md5 checksum ", -1); 716 expand(¬ice, &tmp, ¬ice.item[URLMD5]); 717 copy(&tmp, ")", -1); 718 comment(¬ice, &buf, BUF(&tmp), USE(&tmp), 0); 719 } 720 } 721 else 722 COMMENT(¬ice, &buf, "http://www.opensource.org/licenses/cpl", 0); 723 comment(¬ice, &buf, NiL, 0, 0); 724 } 725 else if (notice.type == OPEN) 726 { 727 copy(&tmp, notice.item[PACKAGE].data ? "and it" : "This software", -1); 728 copy(&tmp, " may only be used by you under license from", -1); 729 comment(¬ice, &buf, BUF(&tmp), USE(&tmp), 0); 730 if (notice.item[i = CORPORATION].data) 731 { 732 if (notice.item[PARENT].data) 733 { 734 expand(¬ice, &tmp, ¬ice.item[i = PARENT]); 735 copy(&tmp, " ", -1); 736 } 737 expand(¬ice, &tmp, ¬ice.item[CORPORATION]); 738 comment(¬ice, &buf, BUF(&tmp), USE(&tmp), 0); 739 } 740 else if (notice.item[i = COMPANY].data) 741 { 742 if (notice.item[PARENT].data) 743 { 744 expand(¬ice, &tmp, ¬ice.item[i = PARENT]); 745 copy(&tmp, " ", -1); 746 } 747 expand(¬ice, &tmp, ¬ice.item[COMPANY]); 748 comment(¬ice, &buf, BUF(&tmp), USE(&tmp), 0); 749 } 750 else 751 i = -1; 752 if (notice.item[URL].data) 753 { 754 COMMENT(¬ice, &buf, "A copy of the Source Code Agreement is available", 0); 755 copy(&tmp, "at the ", -1); 756 if (i >= 0) 757 expand(¬ice, &tmp, ¬ice.item[i]); 758 copy(&tmp, " Internet web site URL", -1); 759 comment(¬ice, &buf, BUF(&tmp), USE(&tmp), 0); 760 comment(¬ice, &buf, NiL, 0, 0); 761 expand(¬ice, &tmp, ¬ice.item[URL]); 762 comment(¬ice, &buf, BUF(&tmp), USE(&tmp), 0); 763 if (notice.item[URLMD5].data) 764 { 765 copy(&tmp, "(with an md5 checksum of ", -1); 766 expand(¬ice, &tmp, ¬ice.item[URLMD5]); 767 copy(&tmp, ")", -1); 768 comment(¬ice, &buf, BUF(&tmp), USE(&tmp), 0); 769 } 770 comment(¬ice, &buf, NiL, 0, 0); 771 } 772 COMMENT(¬ice, &buf, "If you have copied or used this software without agreeing", 0); 773 COMMENT(¬ice, &buf, "to the terms of the license you are infringing on", 0); 774 COMMENT(¬ice, &buf, "the license and copyright and are violating", 0); 775 if (i >= 0) 776 expand(¬ice, &tmp, ¬ice.item[i]); 777 copy(&tmp, "'s", -1); 778 if (n >= COMLONG) 779 comment(¬ice, &buf, BUF(&tmp), USE(&tmp), 0); 780 else 781 PUT(&tmp, ' '); 782 copy(&tmp, "intellectual property rights.", -1); 783 comment(¬ice, &buf, BUF(&tmp), USE(&tmp), 0); 784 comment(¬ice, &buf, NiL, 0, 0); 785 } 786 else if (notice.type == GPL) 787 { 788 comment(¬ice, &buf, NiL, 0, 0); 789 COMMENT(¬ice, &buf, "This is free software; you can redistribute it and/or", 0); 790 COMMENT(¬ice, &buf, "modify it under the terms of the GNU General Public License", 0); 791 COMMENT(¬ice, &buf, "as published by the Free Software Foundation;", 0); 792 COMMENT(¬ice, &buf, "either version 2, or (at your option) any later version.", 0); 793 comment(¬ice, &buf, NiL, 0, 0); 794 COMMENT(¬ice, &buf, "This software is distributed in the hope that it", 0); 795 COMMENT(¬ice, &buf, "will be useful, but WITHOUT ANY WARRANTY;", 0); 796 COMMENT(¬ice, &buf, "without even the implied warranty of MERCHANTABILITY", 0); 797 COMMENT(¬ice, &buf, "or FITNESS FOR A PARTICULAR PURPOSE.", 0); 798 COMMENT(¬ice, &buf, "See the GNU General Public License for more details.", 0); 799 comment(¬ice, &buf, NiL, 0, 0); 800 COMMENT(¬ice, &buf, "You should have received a copy of the", 0); 801 COMMENT(¬ice, &buf, "GNU General Public License", 0); 802 COMMENT(¬ice, &buf, "along with this software (see the file COPYING.)", 0); 803 COMMENT(¬ice, &buf, "If not, a copy is available at", 0); 804 COMMENT(¬ice, &buf, "http://www.gnu.org/copyleft/gpl.html", 0); 805 comment(¬ice, &buf, NiL, 0, 0); 806 } 807 else if (notice.type == BSD) 808 { 809 comment(¬ice, &buf, NiL, 0, 0); 810 COMMENT(¬ice, &buf, "Redistribution and use in source and binary forms, with or", -1); 811 COMMENT(¬ice, &buf, "without modification, are permitted provided that the following", -1); 812 COMMENT(¬ice, &buf, "conditions are met:", -1); 813 comment(¬ice, &buf, NiL, 0, 0); 814 COMMENT(¬ice, &buf, " 1. Redistributions of source code must retain the above", -1); 815 COMMENT(¬ice, &buf, " copyright notice, this list of conditions and the", -1); 816 COMMENT(¬ice, &buf, " following disclaimer.", -1); 817 comment(¬ice, &buf, NiL, 0, 0); 818 COMMENT(¬ice, &buf, " 2. Redistributions in binary form must reproduce the above", -1); 819 COMMENT(¬ice, &buf, " copyright notice, this list of conditions and the", -1); 820 COMMENT(¬ice, &buf, " following disclaimer in the documentation and/or other", -1); 821 COMMENT(¬ice, &buf, " materials provided with the distribution.", -1); 822 comment(¬ice, &buf, NiL, 0, 0); 823 copy(&tmp, " 3. Neither the name of ", -1); 824 if (notice.item[i = PARENT].data || notice.item[i = CORPORATION].data || notice.item[i = COMPANY].data) 825 expand(¬ice, &tmp, ¬ice.item[i]); 826 else 827 copy(&tmp, "the copyright holder", -1); 828 copy(&tmp, " nor the", -1); 829 comment(¬ice, &buf, BUF(&tmp), USE(&tmp), -1); 830 COMMENT(¬ice, &buf, " names of its contributors may be used to endorse or", -1); 831 COMMENT(¬ice, &buf, " promote products derived from this software without", -1); 832 COMMENT(¬ice, &buf, " specific prior written permission.", -1); 833 comment(¬ice, &buf, NiL, 0, 0); 834 COMMENT(¬ice, &buf, "THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND", -1); 835 COMMENT(¬ice, &buf, "CONTRIBUTORS \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES,", -1); 836 COMMENT(¬ice, &buf, "INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF", -1); 837 COMMENT(¬ice, &buf, "MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE", -1); 838 COMMENT(¬ice, &buf, "DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS", -1); 839 COMMENT(¬ice, &buf, "BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,", -1); 840 COMMENT(¬ice, &buf, "EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED", -1); 841 COMMENT(¬ice, &buf, "TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,", -1); 842 COMMENT(¬ice, &buf, "DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON", -1); 843 COMMENT(¬ice, &buf, "ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,", -1); 844 COMMENT(¬ice, &buf, "OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY", -1); 845 COMMENT(¬ice, &buf, "OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE", -1); 846 COMMENT(¬ice, &buf, "POSSIBILITY OF SUCH DAMAGE.", -1); 847 comment(¬ice, &buf, NiL, 0, 0); 848 } 849 else if (notice.type == ZLIB) 850 { 851 comment(¬ice, &buf, NiL, 0, 0); 852 COMMENT(¬ice, &buf, "This software is provided 'as-is', without any express or implied", -1); 853 COMMENT(¬ice, &buf, "warranty. In no event will the authors be held liable for any", -1); 854 COMMENT(¬ice, &buf, "damages arising from the use of this software.", -1); 855 comment(¬ice, &buf, NiL, 0, 0); 856 COMMENT(¬ice, &buf, "Permission is granted to anyone to use this software for any", -1); 857 COMMENT(¬ice, &buf, "purpose, including commercial applications, and to alter it and", -1); 858 COMMENT(¬ice, &buf, "redistribute it freely, subject to the following restrictions:", -1); 859 comment(¬ice, &buf, NiL, 0, 0); 860 COMMENT(¬ice, &buf, " 1. The origin of this software must not be misrepresented;", -1); 861 COMMENT(¬ice, &buf, " you must not claim that you wrote the original software. If", -1); 862 COMMENT(¬ice, &buf, " you use this software in a product, an acknowledgment in the", -1); 863 COMMENT(¬ice, &buf, " product documentation would be appreciated but is not", -1); 864 COMMENT(¬ice, &buf, " required.", -1); 865 comment(¬ice, &buf, NiL, 0, 0); 866 COMMENT(¬ice, &buf, " 2. Altered source versions must be plainly marked as such,", -1); 867 COMMENT(¬ice, &buf, " and must not be misrepresented as being the original", -1); 868 COMMENT(¬ice, &buf, " software.", -1); 869 comment(¬ice, &buf, NiL, 0, 0); 870 COMMENT(¬ice, &buf, " 3. This notice may not be removed or altered from any source", -1); 871 COMMENT(¬ice, &buf, " distribution.", -1); 872 comment(¬ice, &buf, NiL, 0, 0); 873 } 874 else if (notice.type == MIT) 875 { 876 comment(¬ice, &buf, NiL, 0, 0); 877 COMMENT(¬ice, &buf, "Permission is hereby granted, free of charge, to any person", 0); 878 COMMENT(¬ice, &buf, "obtaining a copy of this software and associated", 0); 879 COMMENT(¬ice, &buf, "documentation files (the \"Software\"), to deal in the", 0); 880 COMMENT(¬ice, &buf, "Software without restriction, including without limitation", 0); 881 COMMENT(¬ice, &buf, "the rights to use, copy, modify, merge, publish, distribute,", 0); 882 COMMENT(¬ice, &buf, "sublicense, and/or sell copies of the Software, and to", 0); 883 COMMENT(¬ice, &buf, "permit persons to whom the Software is furnished to do so,", 0); 884 COMMENT(¬ice, &buf, "subject to the following conditions:", 0); 885 comment(¬ice, &buf, NiL, 0, 0); 886 COMMENT(¬ice, &buf, "The above copyright notice and this permission notice shall", 0); 887 COMMENT(¬ice, &buf, "be included in all copies or substantial portions of the", 0); 888 COMMENT(¬ice, &buf, "Software.", 0); 889 comment(¬ice, &buf, NiL, 0, 0); 890 COMMENT(¬ice, &buf, "THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY", 0); 891 COMMENT(¬ice, &buf, "KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE", 0); 892 COMMENT(¬ice, &buf, "WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR", 0); 893 COMMENT(¬ice, &buf, "PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS", 0); 894 COMMENT(¬ice, &buf, "OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR", 0); 895 COMMENT(¬ice, &buf, "OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR", 0); 896 COMMENT(¬ice, &buf, "OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE", 0); 897 COMMENT(¬ice, &buf, "SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.", 0); 898 comment(¬ice, &buf, NiL, 0, 0); 899 } 900 else 901 { 902 if (notice.type == PROPRIETARY) 903 { 904 if (notice.item[i = PARENT].data || notice.item[i = CORPORATION].data || notice.item[i = COMPANY].data) 905 { 906 expand(¬ice, &tmp, ¬ice.item[i]); 907 copy(&tmp, " - ", -1); 908 } 909 else 910 i = -1; 911 copy(&tmp, "Proprietary", -1); 912 comment(¬ice, &buf, BUF(&tmp), USE(&tmp), 1); 913 comment(¬ice, &buf, NiL, 0, 0); 914 if (notice.item[URL].data) 915 { 916 copy(&tmp, "This is proprietary source code", -1); 917 if (i >= 0) 918 copy(&tmp, " licensed by", -1); 919 comment(¬ice, &buf, BUF(&tmp), USE(&tmp), 1); 920 if (notice.item[PARENT].data) 921 { 922 expand(¬ice, &tmp, ¬ice.item[PARENT]); 923 copy(&tmp, " ", -1); 924 } 925 if (notice.item[CORPORATION].data) 926 { 927 expand(¬ice, &tmp, ¬ice.item[CORPORATION]); 928 comment(¬ice, &buf, BUF(&tmp), USE(&tmp), 1); 929 } 930 else if (notice.item[COMPANY].data) 931 { 932 expand(¬ice, &tmp, ¬ice.item[COMPANY]); 933 comment(¬ice, &buf, BUF(&tmp), USE(&tmp), 1); 934 } 935 } 936 else 937 { 938 copy(&tmp, "This is unpublished proprietary source code", -1); 939 if (i >= 0) 940 copy(&tmp, " of", -1); 941 comment(¬ice, &buf, BUF(&tmp), USE(&tmp), 1); 942 if (notice.item[i = PARENT].data || notice.item[i = CORPORATION].data) 943 expand(¬ice, &tmp, ¬ice.item[i]); 944 if (notice.item[COMPANY].data) 945 { 946 if (SIZ(&tmp)) 947 PUT(&tmp, ' '); 948 expand(¬ice, &tmp, ¬ice.item[COMPANY]); 949 } 950 if (SIZ(&tmp)) 951 comment(¬ice, &buf, BUF(&tmp), USE(&tmp), 1); 952 COMMENT(¬ice, &buf, "and is not to be disclosed or used except in", 1); 953 COMMENT(¬ice, &buf, "accordance with applicable agreements", 1); 954 } 955 comment(¬ice, &buf, NiL, 0, 0); 956 } 957 else if (notice.type == NONEXCLUSIVE) 958 { 959 COMMENT(¬ice, &buf, "For nonexclusive individual use", 1); 960 comment(¬ice, &buf, NiL, 0, 0); 961 } 962 else if (notice.type == NONCOMMERCIAL) 963 { 964 COMMENT(¬ice, &buf, "For noncommercial use", 1); 965 comment(¬ice, &buf, NiL, 0, 0); 966 } 967 if (notice.type >= PROPRIETARY && !notice.item[URL].data) 968 { 969 COMMENT(¬ice, &buf, "Unpublished & Not for Publication", 0); 970 comment(¬ice, &buf, NiL, 0, 0); 971 } 972 if (notice.item[URL].data) 973 { 974 copy(&tmp, "This software is licensed", -1); 975 if (notice.item[CORPORATION].data || notice.item[COMPANY].data) 976 { 977 copy(&tmp, " by", -1); 978 if ((notice.item[PARENT].size + (notice.item[CORPORATION].data ? (notice.item[CORPORATION].size + notice.item[INCORPORATION].size) : notice.item[COMPANY].size)) >= (COMLONG - 6)) 979 comment(¬ice, &buf, BUF(&tmp), USE(&tmp), 0); 980 else 981 PUT(&tmp, ' '); 982 if (notice.item[PARENT].data) 983 { 984 expand(¬ice, &tmp, ¬ice.item[PARENT]); 985 copy(&tmp, " ", -1); 986 } 987 if (notice.item[CORPORATION].data) 988 { 989 expand(¬ice, &tmp, ¬ice.item[CORPORATION]); 990 if (notice.item[INCORPORATION].data) 991 { 992 copy(&tmp, " ", -1); 993 expand(¬ice, &tmp, ¬ice.item[INCORPORATION]); 994 } 995 } 996 else if (notice.item[COMPANY].data) 997 expand(¬ice, &tmp, ¬ice.item[COMPANY]); 998 } 999 comment(¬ice, &buf, BUF(&tmp), USE(&tmp), 0); 1000 COMMENT(¬ice, &buf, "under the terms and conditions of the license in", 0); 1001 expand(¬ice, &tmp, ¬ice.item[URL]); 1002 comment(¬ice, &buf, BUF(&tmp), USE(&tmp), 0); 1003 if (notice.item[URLMD5].data) 1004 { 1005 copy(&tmp, "(with an md5 checksum of ", -1); 1006 expand(¬ice, &tmp, ¬ice.item[URLMD5]); 1007 copy(&tmp, ")", -1); 1008 comment(¬ice, &buf, BUF(&tmp), USE(&tmp), 0); 1009 } 1010 comment(¬ice, &buf, NiL, 0, 0); 1011 } 1012 else if (notice.type == PROPRIETARY) 1013 { 1014 COMMENT(¬ice, &buf, "The copyright notice above does not evidence any", 0); 1015 COMMENT(¬ice, &buf, "actual or intended publication of such source code", 0); 1016 comment(¬ice, &buf, NiL, 0, 0); 1017 } 1018 } 1019 if (v = notice.item[NOTICE].data) 1020 { 1021 x = v + notice.item[NOTICE].size; 1022 if (*v == '\n') 1023 v++; 1024 item.quote = notice.item[NOTICE].quote; 1025 do 1026 { 1027 for (item.data = v; v < x && *v != '\n'; v++); 1028 if ((item.size = v - item.data) && *item.data == '\t') 1029 { 1030 item.data++; 1031 item.size--; 1032 h = 0; 1033 } 1034 else 1035 h = -1; 1036 expand(¬ice, &tmp, &item); 1037 comment(¬ice, &buf, BUF(&tmp), USE(&tmp), h); 1038 } while (v++ < x); 1039 if (item.size) 1040 comment(¬ice, &buf, NiL, 0, 0); 1041 } 1042 if (notice.item[ORGANIZATION].data) 1043 { 1044 expand(¬ice, &tmp, ¬ice.item[ORGANIZATION]); 1045 comment(¬ice, &buf, BUF(&tmp), USE(&tmp), 0); 1046 if (notice.item[i = PARENT].data || notice.item[i = CORPORATION].data) 1047 expand(¬ice, &tmp, ¬ice.item[i]); 1048 if (notice.item[COMPANY].data) 1049 { 1050 if (SIZ(&tmp)) 1051 PUT(&tmp, ' '); 1052 expand(¬ice, &tmp, ¬ice.item[COMPANY]); 1053 } 1054 if (SIZ(&tmp)) 1055 comment(¬ice, &buf, BUF(&tmp), USE(&tmp), 0); 1056 if (notice.item[LOCATION].data) 1057 { 1058 expand(¬ice, &tmp, ¬ice.item[LOCATION]); 1059 comment(¬ice, &buf, BUF(&tmp), USE(&tmp), 0); 1060 } 1061 comment(¬ice, &buf, NiL, 0, 0); 1062 } 1063 } 1064 if (v = notice.item[AUTHOR].data) 1065 { 1066 x = v + notice.item[AUTHOR].size; 1067 q = (x - v) == 1 && (*v == '*' || *v == '-'); 1068 k = q && notice.type != USAGE ? -1 : 0; 1069 for (;;) 1070 { 1071 if (!q) 1072 { 1073 while (v < x && (*v == ' ' || *v == '\t' || *v == '\r' || *v == '\n' || *v == ',' || *v == '+')) 1074 v++; 1075 if (v >= x) 1076 break; 1077 item.data = v; 1078 while (v < x && *v != ',' && *v != '+' && *v++ != '>'); 1079 item.size = v - item.data; 1080 item.quote = notice.item[AUTHOR].quote; 1081 } 1082 h = 0; 1083 for (i = 0; i < notice.ids; i++) 1084 if (q || item.size == notice.id[i].name.size && !strncmp(item.data, notice.id[i].name.data, item.size)) 1085 { 1086 h = 1; 1087 if (notice.type == USAGE) 1088 { 1089 copy(&buf, "[-author?", -1); 1090 expand(¬ice, &buf, ¬ice.id[i].value); 1091 PUT(&buf, ']'); 1092 } 1093 else 1094 { 1095 if (k < 0) 1096 { 1097 COMMENT(¬ice, &buf, "CONTRIBUTORS", 0); 1098 comment(¬ice, &buf, NiL, 0, 0); 1099 } 1100 k = 1; 1101 expand(¬ice, &tmp, ¬ice.id[i].value); 1102 comment(¬ice, &buf, BUF(&tmp), USE(&tmp), 0); 1103 } 1104 if (!q) 1105 break; 1106 } 1107 if (q) 1108 break; 1109 if (!h) 1110 { 1111 if (notice.type == USAGE) 1112 { 1113 copy(&buf, "[-author?", -1); 1114 expand(¬ice, &buf, &item); 1115 PUT(&buf, ']'); 1116 } 1117 else 1118 { 1119 if (k < 0) 1120 { 1121 COMMENT(¬ice, &buf, "CONTRIBUTORS", 0); 1122 comment(¬ice, &buf, NiL, 0, 0); 1123 } 1124 k = 1; 1125 expand(¬ice, &tmp, &item); 1126 comment(¬ice, &buf, BUF(&tmp), USE(&tmp), 0); 1127 } 1128 } 1129 } 1130 if (k > 0) 1131 comment(¬ice, &buf, NiL, 0, 0); 1132 } 1133 if (notice.type == USAGE) 1134 { 1135 copy(&buf, "[-copyright?", -1); 1136 copyright(¬ice, &buf); 1137 PUT(&buf, ']'); 1138 if (notice.item[URL].data) 1139 { 1140 copy(&buf, "[-license?", -1); 1141 expand(¬ice, &buf, ¬ice.item[URL]); 1142 PUT(&buf, ']'); 1143 } 1144 PUT(&buf, '\n'); 1145 } 1146 else 1147 comment(¬ice, &buf, NiL, -1, 0); 1148 return END(&buf); 1149 } 1150