1 /*********************************************************************** 2 * * 3 * This software is part of the ast package * 4 * Copyright (c) 1986-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 * * 19 ***********************************************************************/ 20 #pragma prototyped 21 /* 22 * Glenn Fowler 23 * AT&T Research 24 * 25 * convert C prototypes to ANSI, K&R and C++ styles or K&R to ANSI 26 * slips into the pp block read 27 * 28 * define PROTOMAIN for standalone proto 29 * PROTOMAIN is coded for minimal library support 30 */ 31 32 static const char id[] = "\n@(#)$Id: proto (AT&T Research) 2008-05-11 $\0\n"; 33 34 #if PROTOMAIN 35 36 #include "ppfsm.c" 37 38 #include <hashkey.h> 39 40 #if PROTO_STANDALONE 41 #undef O_RDONLY 42 #endif 43 44 #else 45 46 #include "pplib.h" 47 #include "ppfsm.h" 48 49 #endif 50 51 #define MAGICGEN "/* : : generated by proto : : */\n" 52 53 #define MAGICDIR "pragma" /* proto magic directive */ 54 #define MAGICARG "prototyped" /* proto magic directive arg */ 55 #define MAGICOFF "noticed" /* no notice if found in pragma */ 56 #define MAGICTOP 64 /* must be in these top lines */ 57 #define NOTICED "Copyright" /* no notice if found in magic */ 58 #define PUBLICDOMAIN "Public Domain" /* no notice if found in magic */ 59 60 struct proto /* proto buffer state */ 61 { 62 int brace; /* {..} level */ 63 int call; /* call level */ 64 int fd; /* input file descriptor */ 65 char* file; /* input file name */ 66 long flags; /* coupled flags */ 67 long options; /* uncoupled flags */ 68 char* package; /* header package */ 69 int line; /* input line count */ 70 int test; /* testing */ 71 72 char* tp; /* input token base */ 73 74 int iz; /* input buffer size */ 75 char* ib; /* input buffer base */ 76 char* ip; /* input buffer pointer */ 77 78 int oz; /* output buffer size */ 79 char* ob; /* output buffer base */ 80 char* op; /* output buffer pointer */ 81 char* ox; /* output buffer externalize */ 82 83 char cc[3]; /* beg mid end comment char */ 84 char pushback[4]; /* pushback area for caller */ 85 86 char variadic[256]; /* variadic args buffer */ 87 88 /* output buffer */ 89 /* slide buffer */ 90 /* input buffer */ 91 }; 92 93 /* 94 * proto is separate from pp so these undef's are ok 95 */ 96 97 #undef CLASSIC 98 #define CLASSIC (1L<<0) 99 #undef DECLARE 100 #define DECLARE (1L<<1) 101 #undef DEFINE 102 #define DEFINE (1L<<2) 103 #undef DIRECTIVE 104 #define DIRECTIVE (1L<<3) 105 #undef ERROR 106 #define ERROR (1L<<4) 107 #undef EXTERN 108 #define EXTERN (1L<<5) 109 #undef EXTERNALIZE 110 #define EXTERNALIZE (1L<<6) 111 #undef IDID 112 #define IDID (1L<<7) 113 #undef INDIRECT 114 #define INDIRECT (1L<<8) 115 #undef INIT 116 #define INIT (1L<<9) 117 #undef INIT_DEFINE 118 #define INIT_DEFINE (1L<<10) 119 #undef INIT_INCLUDE 120 #define INIT_INCLUDE (1L<<11) 121 #undef JUNK 122 #define JUNK (1L<<12) 123 #undef LINESYNC 124 #define LINESYNC (1L<<13) 125 #undef MANGLE 126 #define MANGLE (1L<<14) 127 #undef MATCH 128 #define MATCH (1L<<15) 129 #undef MORE 130 #define MORE (1L<<16) 131 #undef OTHER 132 #define OTHER (1L<<17) 133 #undef PASS 134 #define PASS (1L<<18) 135 #undef PLUSONLY 136 #define PLUSONLY (1L<<19) 137 #undef PLUSPLUS 138 #define PLUSPLUS (1L<<20) 139 #undef RECURSIVE 140 #define RECURSIVE (1L<<21) 141 #undef SHARP 142 #define SHARP (1L<<22) 143 #undef SKIP 144 #define SKIP (1L<<23) 145 #undef SLIDE 146 #define SLIDE (1L<<24) 147 #undef TOKENS 148 #define TOKENS (1L<<25) 149 #undef TYPEDEF 150 #define TYPEDEF (1L<<26) 151 #undef VARIADIC 152 #define VARIADIC (1L<<27) 153 #undef VARIADIC2 154 #define VARIADIC2 (1L<<28) 155 #undef YACC 156 #define YACC (1L<<29) 157 #undef YACCSPLIT 158 #define YACCSPLIT (1L<<30) 159 #undef YACC2 160 #define YACC2 (1L<<31) 161 162 #undef GLOBAL 163 #define GLOBAL (MORE) 164 165 #undef REGULAR 166 #define REGULAR (1L<<0) 167 168 #ifndef CHUNK 169 #define CHUNK 1024 170 #endif 171 #define BLOCK (8*CHUNK) 172 173 #define T_VA_START (N_TOKEN+1) 174 175 #define RESERVED(b,e,n) ((((long)(b))<<16)|(((long)(e))<<8)|((long)(n))) 176 177 /* 178 * generate integer 179 * pointer to end returned 180 */ 181 182 static char* 183 number(register char* p, register long n) 184 { 185 register long d; 186 187 for (d = 1000000; d > 1; d /= 10) 188 if (n >= d) *p++ = '0' + (n / d) % 10; 189 *p++ = '0' + n % 10; 190 return p; 191 } 192 193 #if PROTOMAIN 194 195 static int errors; 196 197 #if PROTO_STANDALONE 198 199 /* 200 * namespace pollution forces us to claim parts of libc 201 */ 202 203 #undef memcpy 204 #define memcpy(t,f,n) memcopy(t,f,n) 205 #undef strcpy 206 #define strcpy(t,f) strcopy(t,f) 207 #undef strlen 208 #define strlen(s) sstrlen(s) 209 #undef strncmp 210 #define strncmp(s,t,n) sstrncmp(s,t,n) 211 212 /* 213 * environmentally safe strlen() 214 */ 215 216 static int 217 sstrlen(register const char* s) 218 { 219 register const char* b; 220 221 for (b = s; *s; s++); 222 return s - b; 223 } 224 225 /* 226 * environmentally safe strncmp() 227 */ 228 229 static int 230 sstrncmp(register const char* s, register char* t, register int n) 231 { 232 register const char* e = s + n; 233 234 while (s < e) 235 { 236 if (*s != *t || !*s) 237 return *s - *t; 238 s++; 239 t++; 240 } 241 return 0; 242 } 243 244 /* 245 * strcpy() except pointer to end returned 246 */ 247 248 static char* 249 strcopy(register char* s, register const char* t) 250 { 251 while (*s++ = *t++); 252 return s - 1; 253 } 254 255 #endif 256 257 static void 258 proto_error(char* iob, int level, char* msg, char* arg) 259 { 260 register char* p; 261 char buf[1024]; 262 263 p = strcopy(buf, "proto: "); 264 if (iob) 265 { 266 register struct proto* proto = (struct proto*)(iob - sizeof(struct proto)); 267 268 if (proto->line) 269 { 270 if (proto->file) 271 { 272 *p++ = '"'; 273 p = strcopy(p, proto->file); 274 *p++ = '"'; 275 *p++ = ','; 276 *p++ = ' '; 277 } 278 p = strcopy(p, "line "); 279 p = number(p, proto->line); 280 } 281 else if (proto->file) 282 p = strcopy(p, proto->file); 283 } 284 else 285 { 286 p = strcopy(p, msg); 287 msg = arg; 288 arg = 0; 289 } 290 if (*(p - 1) != ' ') 291 { 292 *p++ = ':'; 293 *p++ = ' '; 294 } 295 if (level == 1) 296 p = strcopy(p, "warning: "); 297 p = strcopy(p, msg); 298 if (arg) 299 { 300 *p++ = ' '; 301 p = strcopy(p, arg); 302 } 303 *p++ = '\n'; 304 write(2, buf, p - buf); 305 if (level >= 3) 306 exit(level - 2); 307 if (level >= 2) 308 errors++; 309 } 310 311 /* 312 * memcpy() but pointer to end returned 313 */ 314 315 static char* 316 memcopy(register char* s, register char* t, int n) 317 { 318 register char* e = t + n; 319 320 while (t < e) *s++ = *t++; 321 return s; 322 } 323 324 #include "../libast/port/astlicense.c" 325 326 #else 327 328 #define memcopy(s,t,n) (((char*)memcpy(s,t,n))+(n)) 329 330 #endif 331 332 /* 333 * generate line sync 334 * pointer to end returned 335 */ 336 337 static char* 338 linesync(register struct proto* proto, register char* p, register long n) 339 { 340 #if PROTOMAIN 341 if (proto->flags & LINESYNC) 342 #endif 343 { 344 #if PROTOMAIN 345 p = strcopy(p, "\n#line "); 346 #else 347 p = strcopy(p, "\n# "); 348 #endif 349 p = number(p, n); 350 *p++ = '\n'; 351 } 352 return p; 353 } 354 355 /* 356 * output init header 357 * pointer to end returned 358 */ 359 360 static char* 361 init(struct proto* proto, char* op, int flags) 362 { 363 register char* s; 364 365 if (flags & INIT_DEFINE) 366 { 367 op = strcopy(op, "\ 368 \n\ 369 #if !defined(__PROTO__)\n\ 370 # if defined(__STDC__) || defined(__cplusplus) || defined(_proto) || defined(c_plusplus)\n\ 371 # if defined(__cplusplus)\n\ 372 # define __LINKAGE__ \"C\"\n\ 373 # else\n\ 374 # define __LINKAGE__\n\ 375 # endif\n\ 376 # define __STDARG__\n\ 377 # define __PROTO__(x) x\n\ 378 # define __OTORP__(x)\n\ 379 # define __PARAM__(n,o) n\n\ 380 # if !defined(__STDC__) && !defined(__cplusplus)\n\ 381 # if !defined(c_plusplus)\n\ 382 # define const\n\ 383 # endif\n\ 384 # define signed\n\ 385 # define void int\n\ 386 # define volatile\n\ 387 # define __V_ char\n\ 388 # else\n\ 389 # define __V_ void\n\ 390 # endif\n\ 391 # else\n\ 392 # define __PROTO__(x) ()\n\ 393 # define __OTORP__(x) x\n\ 394 # define __PARAM__(n,o) o\n\ 395 # define __LINKAGE__\n\ 396 # define __V_ char\n\ 397 # define const\n\ 398 # define signed\n\ 399 # define void int\n\ 400 # define volatile\n\ 401 # endif\n\ 402 # define __MANGLE__ __LINKAGE__\n\ 403 # if defined(__cplusplus) || defined(c_plusplus)\n\ 404 # define __VARARG__ ...\n\ 405 # else\n\ 406 # define __VARARG__\n\ 407 # endif\n\ 408 # if defined(__STDARG__)\n\ 409 # define __VA_START__(p,a) va_start(p,a)\n\ 410 # else\n\ 411 # define __VA_START__(p,a) va_start(p)\n\ 412 # endif\n\ 413 # if !defined(__INLINE__)\n\ 414 # if defined(__cplusplus)\n\ 415 # define __INLINE__ extern __MANGLE__ inline\n\ 416 # else\n\ 417 # if defined(_WIN32) && !defined(__GNUC__)\n\ 418 # define __INLINE__ __inline\n\ 419 # endif\n\ 420 # endif\n\ 421 # endif\n\ 422 #endif\n\ 423 #if !defined(__LINKAGE__)\n\ 424 #define __LINKAGE__ /* 2004-08-11 transition */\n\ 425 #endif\n\ 426 "); 427 } 428 else 429 op = strcopy(op, "\ 430 \n\ 431 #if !defined(__PROTO__)\n\ 432 #include <prototyped.h>\n\ 433 #endif\n\ 434 #if !defined(__LINKAGE__)\n\ 435 #define __LINKAGE__ /* 2004-08-11 transition */\n\ 436 #endif\n\ 437 "); 438 if (proto->package) 439 { 440 s = "\ 441 #ifndef __MANGLE_%_DATA__\n\ 442 # ifdef _BLD_%\n\ 443 # ifdef __EXPORT__\n\ 444 # define __MANGLE_%_DATA__ __MANGLE__ __EXPORT__\n\ 445 # else\n\ 446 # define __MANGLE_%_DATA__ __MANGLE__\n\ 447 # endif\n\ 448 # define __MANGLE_%_FUNC__ __MANGLE__\n\ 449 # else\n\ 450 # ifdef __IMPORT__\n\ 451 # define __MANGLE_%_DATA__ __MANGLE__ __IMPORT__\n\ 452 # else\n\ 453 # define __MANGLE_%_DATA__ __MANGLE__\n\ 454 # endif\n\ 455 # define __MANGLE_%_FUNC__ __MANGLE__\n\ 456 # endif\n\ 457 #endif\n\ 458 "; 459 for (;;) 460 { 461 switch (*op++ = *s++) 462 { 463 case 0: 464 op--; 465 break; 466 case '%': 467 op = strcopy(op - 1, proto->package); 468 continue; 469 default: 470 continue; 471 } 472 break; 473 } 474 } 475 return op; 476 } 477 478 #define BACKOUT() (op=ko) 479 #define CACHE() do{CACHEIN();CACHEOUT();call=proto->call;}while(0) 480 #define CACHEIN() (ip=proto->ip) 481 #define CACHEOUT() (op=proto->op) 482 #define GETCHR() (*(unsigned char*)ip++) 483 #define KEEPOUT() (ko=op) 484 #define LASTOUT() (*(op-1)) 485 #define PUTCHR(c) (*op++=(c)) 486 #define SYNC() do{SYNCIN();SYNCOUT();proto->flags&=~(EXTERN|INIT|OTHER|VARIADIC|VARIADIC2);proto->flags|=flags&(EXTERN|INIT|OTHER|VARIADIC|VARIADIC2);proto->call=call;}while(0) 487 #define SYNCIN() (proto->ip=ip) 488 #define SYNCOUT() (proto->op=op) 489 #define UNGETCHR() (ip--) 490 #define UNPUTCHR() (op--) 491 492 /* 493 * advance to the next non-space character 494 */ 495 496 static char* 497 nns(register char* s) 498 { 499 while (*s == ' ' || *s == '\t' || *s == '\n') 500 s++; 501 return s; 502 } 503 504 #define DIR_if 01 505 #define DIR_el 02 506 #define DIR_en 03 507 #define DIR 03 508 509 /* 510 * update directive mask 511 */ 512 513 static int 514 directive(register char* s, int dir) 515 { 516 switch (*(s = nns(s))) 517 { 518 case 'e': 519 case 'i': 520 dir <<= 2; 521 switch (*++s) 522 { 523 case 'f': 524 dir |= DIR_if; 525 break; 526 case 'l': 527 dir |= DIR_el; 528 break; 529 case 'n': 530 dir |= DIR_en; 531 break; 532 } 533 break; 534 } 535 return dir; 536 } 537 538 /* 539 * the tokenizer 540 * top level calls loop until EOB 541 * recursive calls just return the next token 542 */ 543 544 static int 545 lex(register struct proto* proto, register long flags) 546 { 547 register char* ip; 548 register char* op; 549 register int c; 550 register int state; 551 register short* rp; 552 char* m; 553 char* e; 554 char* t; 555 char* bp; 556 char* v; 557 char* im; 558 char* ko; 559 char* aom; 560 int n; 561 int line; 562 int quot; 563 int brack; 564 int sub; 565 int x; 566 int vc; 567 568 char* ie = 0; 569 char* om = 0; 570 char* aim = 0; 571 char* aie = 0; 572 char* func = 0; 573 int call = 0; 574 int dir = 0; 575 int group = 0; 576 int last = 0; 577 int paren = 0; 578 #if PROTOMAIN 579 char* qe = 0; 580 int qn = 0; 581 int args = 0; 582 #endif 583 584 CACHE(); 585 #if PROTOMAIN 586 if (flags & EXTERN) KEEPOUT(); 587 #endif 588 fsm_start: 589 proto->tp = ip; 590 state = PROTO; 591 bp = ip; 592 do 593 { 594 rp = fsm[state]; 595 fsm_get: 596 while (!(state = rp[c = GETCHR()])); 597 fsm_next: 598 ; 599 } while (state > 0); 600 if ((n = ip - bp - 1) > 0) 601 { 602 ip = bp; 603 MEMCPY(op, ip, n); 604 ip++; 605 } 606 state = ~state; 607 fsm_terminal: 608 switch (TERM(state)) 609 { 610 case S_CHR: 611 if (op > proto->ob && *(op - 1) == '=' && (op == proto->ob + 1 || *(op - 2) != '=')) switch (c) 612 { 613 case '+': 614 case '-': 615 case '*': 616 case '&': 617 PUTCHR(' '); 618 break; 619 } 620 PUTCHR(c); 621 break; 622 623 case S_CHRB: 624 UNGETCHR(); 625 c = LASTOUT(); 626 break; 627 628 case S_COMMENT: 629 switch (c) 630 { 631 case '\n': 632 if (INCOMMENTXX(rp)) goto fsm_newline; 633 PUTCHR(c); 634 proto->line++; 635 rp = fsm[COM2]; 636 break; 637 case '/': 638 #if PROTOMAIN 639 if ((flags & (EXTERN|MATCH)) == EXTERN) BACKOUT(); 640 else 641 #endif 642 PUTCHR(c); 643 if (INCOMMENTXX(rp)) 644 { 645 rp = fsm[COM5]; 646 break; 647 } 648 goto fsm_start; 649 case EOF: 650 break; 651 default: 652 #if PROTOMAIN 653 if ((flags & (EXTERN|MATCH)) == EXTERN) BACKOUT(); 654 else 655 #endif 656 PUTCHR(c); 657 rp = fsm[INCOMMENTXX(rp) ? COM5 : COM3]; 658 break; 659 } 660 bp = ip; 661 goto fsm_get; 662 663 case S_EOB: 664 if (c) 665 { 666 if (state = fsm[TERMINAL][INDEX(rp)+1]) 667 goto fsm_terminal; 668 SYNC(); 669 return 0; 670 } 671 UNGETCHR(); 672 fsm_eob: 673 if ((flags & (DECLARE|GLOBAL|RECURSIVE)) == GLOBAL && (proto->flags & MORE)) 674 { 675 #if PROTOMAIN 676 if (!(flags & EXTERN)) /* XXX */ 677 #endif 678 flags |= SLIDE; 679 c = ip - proto->ib; 680 if (!(flags & MATCH)) 681 im = proto->tp; 682 if (ip > proto->ib) 683 { 684 n = ip - im; 685 if (ip - n < proto->ib) 686 proto->flags |= ERROR; 687 memcopy(proto->ib - n, ip - n, n); 688 ip = proto->ib; 689 } 690 proto->tp -= c; 691 if (flags & MATCH) 692 { 693 im -= c; 694 ie -= c; 695 } 696 if (aim) 697 aim -= c; 698 if (aie) 699 aie -= c; 700 if ((n = read(proto->fd, ip, proto->iz)) > 0) 701 { 702 if ((proto->options & REGULAR) && n < proto->iz) 703 { 704 proto->flags &= ~MORE; 705 close(proto->fd); 706 } 707 *(ip + n) = 0; 708 if (state & SPLICE) 709 goto fsm_splice; 710 bp = ip; 711 goto fsm_get; 712 } 713 *ip = 0; 714 proto->flags &= ~MORE; 715 close(proto->fd); 716 } 717 if (state & SPLICE) 718 goto fsm_splice; 719 /* NOTE: RECURSIVE lex() should really SLIDE too */ 720 if (!(flags & RECURSIVE) && (state = rp[c = EOF])) 721 { 722 bp = ip; 723 goto fsm_next; 724 } 725 SYNC(); 726 return 0; 727 728 case S_LITBEG: 729 quot = c; 730 #if PROTOMAIN 731 if (c == '"' && qe) 732 { 733 for (n = 0, t = qe + 1; t < op && (*t == ' ' || *t == '\t' || *t == '\n' && ++n || *t >= 'A' && *t <= 'Z' || *t == '_'); t++); 734 if (t == op) 735 { 736 op = qe; 737 qe = 0; 738 qn = n; 739 } 740 else PUTCHR(c); 741 } 742 else 743 #endif 744 PUTCHR(c); 745 rp = fsm[LIT1]; 746 bp = ip; 747 goto fsm_get; 748 749 case S_LITEND: 750 if (c == quot) 751 { 752 #if PROTOMAIN 753 if (!(flags & DIRECTIVE)) 754 qe = (c == '"') ? op : (char*)0; 755 #endif 756 PUTCHR(c); 757 #if PROTOMAIN 758 while (qn > 0) 759 { 760 qn--; 761 PUTCHR('\n'); 762 } 763 #endif 764 } 765 else if (c != '\n' && c != EOF) 766 { 767 PUTCHR(c); 768 bp = ip; 769 goto fsm_get; 770 } 771 else 772 { 773 #if PROTOMAIN 774 while (qn > 0) 775 { 776 qn--; 777 PUTCHR('\n'); 778 } 779 #endif 780 UNGETCHR(); 781 } 782 c = T_INVALID; 783 break; 784 785 case S_LITESC: 786 #if PROTOMAIN 787 if (flags & CLASSIC) PUTCHR(c); 788 else 789 #endif 790 switch (c) 791 { 792 case 'a': 793 n = CC_bel; 794 goto fsm_oct; 795 case 'E': 796 n = CC_esc; 797 goto fsm_oct; 798 case 'v': 799 n = CC_vt; 800 goto fsm_oct; 801 case 'x': 802 SYNC(); 803 lex(proto, (flags & GLOBAL) | RECURSIVE); 804 for (n = x = 0; (c = GETCHR()), x < 3; x++) switch (c) 805 { 806 case '0': case '1': case '2': case '3': 807 case '4': case '5': case '6': case '7': 808 case '8': case '9': 809 n = (n << 4) + c - '0'; 810 break; 811 case 'a': case 'b': case 'c': case 'd': 812 case 'e': case 'f': 813 n = (n << 4) + c - 'a' + 10; 814 break; 815 case 'A': case 'B': case 'C': case 'D': 816 case 'E': case 'F': 817 n = (n << 4) + c - 'A' + 10; 818 break; 819 default: 820 goto fsm_hex; 821 } 822 fsm_hex: 823 UNGETCHR(); 824 fsm_oct: 825 PUTCHR(((n >> 6) & 07) + '0'); 826 PUTCHR(((n >> 3) & 07) + '0'); 827 PUTCHR((n & 07) + '0'); 828 break; 829 default: 830 PUTCHR(c); 831 break; 832 } 833 rp = fsm[LIT1]; 834 bp = ip; 835 goto fsm_get; 836 837 case S_MACRO: 838 UNGETCHR(); 839 #if PROTOMAIN 840 if ((flags & EXTERN) && *proto->tp == 's' && !strncmp(proto->tp, "static", 6)) 841 { 842 c = T_EXTERN; 843 break; 844 } 845 #endif 846 if (*proto->tp == '_' && !strncmp(proto->tp, "__STDPP__directive", 6)) c = '#'; 847 else c = T_ID; 848 849 break; 850 851 case S_NL: 852 fsm_newline: 853 proto->line++; 854 #if PROTOMAIN 855 if (flags & EXTERN) 856 { 857 if (op != proto->ob && LASTOUT() != ' ' && LASTOUT() != '\n') 858 PUTCHR(' '); 859 } 860 else 861 #endif 862 PUTCHR(c); 863 if (flags & DIRECTIVE) 864 { 865 #if PROTOMAIN 866 if (flags & CLASSIC) 867 { 868 if (flags & EXTERN) BACKOUT(); 869 if (flags & JUNK) 870 { 871 *(ip - 1) = 0; 872 op = strcopy(om, "/* "); 873 op = strcopy(op, im); 874 op = strcopy(op, " */\n"); 875 } 876 flags &= ~(DEFINE|DIRECTIVE|IDID|INDIRECT|JUNK|MATCH|SHARP|TYPEDEF); 877 } 878 else 879 #endif 880 { 881 if ((flags & (DEFINE|SHARP)) == (DEFINE|SHARP)) 882 { 883 *(ip - 1) = 0; 884 op = strcopy(om, "#if defined(__STDC__) || defined(__STDPP__)\n"); 885 op = strcopy(op, im); 886 op = strcopy(op, "\n#else\n"); 887 bp = ip; 888 ip = im; 889 *op++ = *ip++; 890 while (*op = *ip++) 891 if (*op++ == '#' && *ip != '(') 892 { 893 op--; 894 while (*--op == ' ' || *op == '\t'); 895 if (*ip == '#') 896 { 897 op = strcopy(op + 1, "/**/"); 898 while (*++ip == ' ' || *ip == '\t'); 899 } 900 else 901 { 902 if (*op != '"') *++op = '"'; 903 op++; 904 while (*ip == ' ' || *ip == '\t') ip++; 905 while ((c = *ip) >= 'A' && c <= 'Z' || c >= 'a' && c <= 'z' || c >= '0' && c <= '9' || c == '_') *op++ = *ip++; 906 while (*ip == ' ' || *ip == '\t') ip++; 907 if (*ip == '"') ip++; 908 else *op++ = '"'; 909 } 910 } 911 ip = bp; 912 op = strcopy(op, "\n#endif\n"); 913 op = linesync(proto, op, proto->line); 914 } 915 flags &= ~(DEFINE|DIRECTIVE|IDID|INDIRECT|MATCH|OTHER|SHARP|SKIP|TOKENS|TYPEDEF); 916 } 917 call = 0; 918 group = 0; 919 paren = 0; 920 last = '\n'; 921 } 922 if (paren == 0 && (flags & (MATCH|RECURSIVE|SKIP|SLIDE)) == SLIDE) 923 { 924 #if PROTOMAIN 925 if (flags & EXTERN) BACKOUT(); 926 #endif 927 SYNC(); 928 return 0; 929 } 930 goto fsm_start; 931 932 case S_QUAL: 933 PUTCHR(c); 934 rp = fsm[NEXT(state)]; 935 bp = ip; 936 goto fsm_get; 937 938 case S_TOK: 939 PUTCHR(c); 940 c = TYPE(state); 941 break; 942 943 case S_TOKB: 944 UNGETCHR(); 945 c = TYPE(state); 946 break; 947 948 case S_RESERVED: 949 UNGETCHR(); 950 c = T_ID; 951 if (!(flags & DECLARE)) switch (RESERVED(*proto->tp, *(ip - 1), ip - proto->tp)) 952 { 953 case RESERVED('N', 'N', 3): 954 if (proto->tp[1] == 'o') 955 c = T_DO; 956 break; 957 case RESERVED('d', 'o', 2): 958 c = T_DO; 959 break; 960 case RESERVED('e', 'e', 4): 961 if (!(flags & RECURSIVE) && (flags & (DIRECTIVE|TOKENS)) != DIRECTIVE && !strncmp(proto->tp, "else", 4)) 962 { 963 c = T_ELSE; 964 goto fsm_id; 965 } 966 break; 967 case RESERVED('e', 'n', 6): 968 if (!strncmp(proto->tp, "extern", 6)) 969 c = T_EXTERN; 970 break; 971 case RESERVED('f', 'r', 3): 972 if (!(flags & RECURSIVE) && !strncmp(proto->tp, "for", 3)) 973 { 974 c = T_FOR; 975 goto fsm_id; 976 } 977 break; 978 case RESERVED('i', 'f', 2): 979 c = T_IF; 980 break; 981 case RESERVED('i', 'e', 6): 982 if (!strncmp(proto->tp, "inline", 6) && !(flags & (MATCH|SKIP|TOKENS|TYPEDEF)) && proto->brace == 0 && paren == 0 && group == 0 && (last == ';' || last == '}' || last == '\n' || last == 0)) 983 { 984 flags |= SKIP; 985 SYNC(); 986 line = proto->line; 987 op = strcopy(op - 6, "__INLINE__"); 988 SYNC(); 989 } 990 break; 991 case RESERVED('r', 'n', 6): 992 if (!(flags & RECURSIVE) && !strncmp(proto->tp, "return", 6)) 993 { 994 c = T_RETURN; 995 goto fsm_id; 996 } 997 break; 998 case RESERVED('s', 'c', 6): 999 if ((proto->options & EXTERNALIZE) && !strncmp(proto->tp, "static", 6)) 1000 { 1001 proto->ox = op - 6; 1002 flags |= EXTERNALIZE; 1003 } 1004 break; 1005 case RESERVED('t', 'f', 7): 1006 if (!(flags & RECURSIVE) && !strncmp(proto->tp, "typedef", 7)) 1007 { 1008 flags |= TYPEDEF; 1009 c = T_EXTERN; 1010 } 1011 break; 1012 case RESERVED('v', 't', 8): 1013 if (*ip == '(' && !strncmp(proto->tp, "va_start", 8)) c = T_VA_START; 1014 break; 1015 case RESERVED('v', 'd', 4): 1016 if (!strncmp(proto->tp, "void", 4)) 1017 { 1018 if (flags & (CLASSIC|PLUSONLY|INIT_DEFINE|INIT_INCLUDE)) c = T_VOID; 1019 else 1020 { 1021 SYNC(); 1022 line = proto->line; 1023 if (lex(proto, (flags & GLOBAL) | RECURSIVE) == '*') 1024 { 1025 memcopy(op - 4, "__V_", 4); 1026 memcopy(ip - 4, "__V_", 4); 1027 } 1028 else c = T_VOID; 1029 proto->line = line; 1030 SYNC(); 1031 bp = ip; 1032 } 1033 } 1034 break; 1035 case RESERVED('w', 'e', 5): 1036 if (!(flags & RECURSIVE) && !strncmp(proto->tp, "while", 5)) 1037 { 1038 c = T_WHILE; 1039 goto fsm_id; 1040 } 1041 break; 1042 } 1043 #if PROTOMAIN 1044 if ((flags & CLASSIC) && c != T_EXTERN) 1045 c = T_ID; 1046 #endif 1047 break; 1048 1049 case S_VS: 1050 goto fsm_start; 1051 1052 case S_WS: 1053 UNGETCHR(); 1054 #if PROTOMAIN 1055 if ((flags & (EXTERN|MATCH)) == EXTERN) 1056 { 1057 while (op > proto->ob && (*(op - 1) == ' ' || *(op - 1) == '\t')) 1058 op--; 1059 if (op > proto->ob && *(op - 1) != '\n') *op++ = ' '; 1060 } 1061 #endif 1062 goto fsm_start; 1063 1064 default: 1065 if (state & SPLICE) 1066 { 1067 if (c == '\\') 1068 { 1069 if (!(n = GETCHR())) 1070 { 1071 goto fsm_eob; 1072 fsm_splice: 1073 c = '\\'; 1074 n = GETCHR(); 1075 } 1076 if (n == '\n') 1077 { 1078 proto->line++; 1079 PUTCHR('\\'); 1080 PUTCHR('\n'); 1081 bp = ip; 1082 goto fsm_get; 1083 } 1084 UNGETCHR(); 1085 } 1086 state &= ~SPLICE; 1087 if (state >= TERMINAL) 1088 goto fsm_terminal; 1089 rp = fsm[state]; 1090 } 1091 PUTCHR(c); 1092 bp = ip; 1093 goto fsm_get; 1094 } 1095 if (!(flags & (INIT_DEFINE|INIT_INCLUDE|RECURSIVE))) 1096 { 1097 if (!(flags & DIRECTIVE)) switch (c) 1098 { 1099 case '(': 1100 #if PROTOMAIN 1101 if (!(flags & CLASSIC) || proto->brace == 0) 1102 #endif 1103 { 1104 if (paren++ == 0) 1105 { 1106 #if PROTOMAIN 1107 if (!(flags & CLASSIC) || group <= 1) 1108 #endif 1109 { 1110 #if PROTOMAIN 1111 args = 0; 1112 #endif 1113 if (group++ == 0) group++; 1114 else if (flags & INDIRECT) call++; 1115 flags |= MATCH; 1116 im = ip - 1; 1117 om = op - 1; 1118 } 1119 sub = 0; 1120 } 1121 else if (paren == 2 && !aim) 1122 { 1123 sub++; 1124 if (last == '(') 1125 { 1126 flags &= ~MATCH; 1127 om = 0; 1128 } 1129 else if (flags & INDIRECT) 1130 { 1131 aim = ip - 1; 1132 aom = op - 1; 1133 } 1134 else if ((flags & (MATCH|TOKENS)) == MATCH) 1135 { 1136 for (m = ip - 2; m > im && (*m == ' ' || *m == '\t'); m--); 1137 if (m != im && sub == 1) 1138 { 1139 m = im + (*nns(ip) == '*'); 1140 } 1141 if (m == im) 1142 { 1143 flags &= ~MATCH; 1144 om = 0; 1145 } 1146 } 1147 else if ((flags & MATCH) && sub == 1 && *nns(ip) != '*') 1148 { 1149 flags &= ~MATCH; 1150 om = 0; 1151 } 1152 } 1153 flags &= ~TOKENS; 1154 } 1155 break; 1156 case ')': 1157 #if PROTOMAIN 1158 if (!(flags & CLASSIC) || proto->brace == 0) 1159 #endif 1160 if (--paren == 0) 1161 { 1162 #if PROTOMAIN 1163 if (flags & CLASSIC) 1164 { 1165 if (group != 2) 1166 { 1167 c = T_ID; 1168 break; 1169 } 1170 group++; 1171 } 1172 #endif 1173 ie = ip; 1174 } 1175 else if (paren == 1 && (flags & INDIRECT) && !aie) 1176 aie = ip; 1177 break; 1178 case '*': 1179 if (last == '(' && group == 2) 1180 { 1181 group--; 1182 if (paren == 1) 1183 { 1184 flags |= INDIRECT; 1185 aim = aie = 0; 1186 } 1187 } 1188 break; 1189 case '#': 1190 dir = directive(ip, dir); 1191 if (proto->brace == 0 && paren == 0 && last != '=' && (flags & (CLASSIC|DECLARE|DIRECTIVE|MATCH|PLUSONLY|SKIP|TOKENS)) == (MATCH|TOKENS) && ((dir & DIR) != DIR_en || ((dir>>2) & DIR) != DIR_if)) 1192 flags |= DIRECTIVE; 1193 else if (!(flags & (DECLARE|DIRECTIVE))) 1194 { 1195 flags |= DIRECTIVE; 1196 if (!(flags & PLUSONLY)) 1197 { 1198 bp = ip; 1199 while (*ip == ' ' || *ip == '\t') ip++; 1200 if (*ip == 'l' && *++ip == 'i' && *++ip == 'n' && *++ip == 'e') 1201 { 1202 if (*++ip == ' ' || *ip == '\t') 1203 { 1204 proto->line = 0; 1205 while (*++ip >= '0' && *ip <= '9') 1206 proto->line = proto->line * 10 + *ip - '0'; 1207 proto->line--; 1208 } 1209 } 1210 #if PROTOMAIN 1211 else if ((flags & (CLASSIC|EXTERN)) == CLASSIC) 1212 { 1213 n = 0; 1214 t = ip + 6; 1215 while (ip < t && *ip >= 'a' && *ip <= 'z') 1216 n = HASHKEYPART(n, *ip++); 1217 switch (n) 1218 { 1219 case HASHKEY4('e','l','s','e'): 1220 case HASHKEY5('e','n','d','i','f'): 1221 while (*ip == ' ' || *ip == '\t') ip++; 1222 if (*ip != '\n' && *ip != '/' && *(ip + 1) != '*') 1223 { 1224 flags |= JUNK|MATCH; 1225 im = ip; 1226 om = op + (ip - bp); 1227 } 1228 break; 1229 case HASHKEY4('e','l','i','f'): 1230 case HASHKEY5('e','r','r','o','r'): 1231 case HASHKEY2('i','f'): 1232 case HASHKEY5('i','f','d','e','f'): 1233 case HASHKEY6('i','f','n','d','e','f'): 1234 case HASHKEY5('u','n','d','e','f'): 1235 break; 1236 case HASHKEY6('i','n','c','l','u','d'): 1237 if (*ip == 'e') ip++; 1238 /*FALLTHROUGH*/ 1239 case HASHKEY6('d','e','f','i','n','e'): 1240 case HASHKEY6('p','r','a','g','m','a'): 1241 if (*ip < 'a' || *ip > 'z') break; 1242 /*FALLTHROUGH*/ 1243 default: 1244 flags |= JUNK|MATCH; 1245 im = bp - 1; 1246 om = op - 1; 1247 break; 1248 } 1249 } 1250 else 1251 #endif 1252 { 1253 if (*ip == 'i' && *++ip == 'n' && *++ip == 'c' && *++ip == 'l' && *++ip == 'u' && *++ip == 'd' && *++ip == 'e') 1254 { 1255 while (*++ip == ' ' || *ip == '\t'); 1256 if (*ip++ == '<' && *ip++ == 's' && *ip++ == 't' && *ip++ == 'd' && *ip++ == 'a' && *ip++ == 'r' && *ip++ == 'g' && *ip++ == '.' && *ip++ == 'h' && *ip++ == '>') 1257 { 1258 op = strcopy(op, "\ 1259 if !defined(va_start)\n\ 1260 #if defined(__STDARG__)\n\ 1261 #include <stdarg.h>\n\ 1262 #else\n\ 1263 #include <varargs.h>\n\ 1264 #endif\n\ 1265 #endif\n\ 1266 "); 1267 op = linesync(proto, op, proto->line); 1268 break; 1269 } 1270 } 1271 else if (*ip == 'd' && *++ip == 'e' && *++ ip == 'f' && *++ip == 'i' && *++ip == 'n' && *++ip == 'e' && (*++ip == ' ' || *ip == '\t')) 1272 { 1273 while (*++ip == ' ' || *ip == '\t'); 1274 if (*ip == 'e' && *++ip == 'x' && *++ ip == 't' && *++ip == 'e' && *++ip == 'r' && *++ip == 'n' && (*++ip == ' ' || *ip == '\t')) 1275 { 1276 t = ip; 1277 while (*++t == ' ' || *t == '\t'); 1278 if (*t == 'e' && *++t == 'x' && *++ t == 't' && *++t == 'e' && *++t == 'r' && *++t == 'n' && (*++t == ' ' || *t == '\t' || *t == '\n' || *t == '\r')) 1279 ip = t; 1280 t = ip; 1281 while (*++t == ' ' || *t == '\t'); 1282 if (*t == '_' && *(t + 1) == '_') 1283 { 1284 op = strcopy(op, "undef __MANGLE__\n"); 1285 op = linesync(proto, op, proto->line); 1286 op = strcopy(op, "#define __MANGLE__ __LINKAGE__"); 1287 break; 1288 } 1289 } 1290 flags |= DEFINE|MATCH; 1291 im = bp - 1; 1292 om = op - 1; 1293 } 1294 else if (*ip == 'u' && *++ip == 'n' && *++ ip == 'd' && *++ip == 'e' && *++ip == 'f' && (*++ip == ' ' || *ip == '\t')) 1295 { 1296 while (*++ip == ' ' || *ip == '\t'); 1297 if (*ip == 'e' && *++ip == 'x' && *++ ip == 't' && *++ip == 'e' && *++ip == 'r' && *++ip == 'n' && (*++ip == ' ' || *ip == '\t' || *ip == '\n' || *ip == '\r')) 1298 { 1299 op = strcopy(op, "undef __MANGLE__\n"); 1300 op = linesync(proto, op, proto->line); 1301 op = strcopy(op, "#define __MANGLE__ __LINKAGE__"); 1302 break; 1303 } 1304 flags |= DEFINE|MATCH; 1305 im = bp - 1; 1306 om = op - 1; 1307 } 1308 } 1309 ip = bp; 1310 } 1311 break; 1312 } 1313 else 1314 break; 1315 /*FALLTHROUGH*/ 1316 case '{': 1317 if (proto->brace++ == 0 && paren == 0) 1318 { 1319 if (last == '=') flags |= INIT; 1320 #if PROTOMAIN 1321 else if (flags & CLASSIC) 1322 { 1323 if ((flags & (MATCH|OTHER|SKIP)) == MATCH) 1324 { 1325 if (args) 1326 { 1327 v = number(op, args < 0 ? -args : args); 1328 v = strcopy(v, " argument actual/formal mismatch"); 1329 *v++ = ' '; 1330 v = memcopy(v, im, ie - im); 1331 *v = 0; 1332 proto_error((char*)proto + sizeof(struct proto), 2, op, NiL); 1333 } 1334 ip--; 1335 /*UNDENT...*/ 1336 v = ie; 1337 while (ie < ip) 1338 if (*ie++ == '/' && *ie == '*') 1339 { 1340 e = ie - 1; 1341 while (++ie < ip) 1342 { 1343 if (*ie == '*') 1344 { 1345 while (ie < ip && *ie == '*') ie++; 1346 if (ie < ip && *ie == '/') 1347 { 1348 while (++ie < ip && (*ie == ' ' || *ie == '\t')); 1349 while (e > v && (*(e - 1) == ' ' || *(e - 1) == '\t')) e--; 1350 if (e > v && *e != '\n') *e++ = ' '; 1351 t = ie; 1352 while (--e >= v) 1353 *--t = *e; 1354 v = t; 1355 break; 1356 } 1357 } 1358 } 1359 } 1360 ie = v; 1361 /*...INDENT*/ 1362 op = om++; 1363 if (flags & EXTERN) 1364 { 1365 v = op; 1366 while (v > ko && *--v != ' '); 1367 if (*v != ' ') 1368 { 1369 om = (v = (op += 4)) + 1; 1370 while (v >= ko + 4) 1371 { 1372 *v = *(v - 4); 1373 v--; 1374 } 1375 memcopy(ko, "int ", 4); 1376 } 1377 if (*v == ' ') 1378 { 1379 while (*(v + 1) == '*') 1380 *v++ = '*'; 1381 *v = '\t'; 1382 if ((v - ko) <= 8) 1383 { 1384 om = (e = ++op) + 1; 1385 while (e > v) 1386 { 1387 *e = *(e - 1); 1388 e--; 1389 } 1390 } 1391 } 1392 om = (v = (op += 7)) + 1; 1393 while (v >= ko + 7) 1394 { 1395 *v = *(v - 7); 1396 v--; 1397 } 1398 memcopy(ko, "extern ", 7); 1399 } 1400 PUTCHR('('); 1401 t = op; 1402 e = 0; 1403 /*UNDENT...*/ 1404 while (ie < ip) 1405 { 1406 if ((c = *ie) == ' ' || c == '\t' || c == '\n') 1407 { 1408 while ((c = *++ie) == ' ' || c == '\t' || c == '\n'); 1409 if (ie >= ip) break; 1410 if (c != '*' && op > om) PUTCHR(' '); 1411 } 1412 if ((n = ((c = *ie) == ',')) || c == ';') 1413 { 1414 if (flags & EXTERN) 1415 { 1416 m = op; 1417 while (op > om && ((c = *(op - 1)) == '(' || c == ')' || c == '[' || c == ']')) 1418 op--; 1419 v = op; 1420 while (op > om && (c = *(op - 1)) != ' ' && c != '*') 1421 op--; 1422 while (*(op - 1) == ' ') 1423 op--; 1424 if (!e) 1425 { 1426 e = op; 1427 while (e > om && *(e - 1) == '*') 1428 e--; 1429 } 1430 #if _s5r4_386_compiler_bug_fixed_ 1431 if (op <= om || *(op - 1) == ',' && (*op++ = ' ')) 1432 op = strcopy(op, "int"); 1433 #else 1434 if (op <= om) 1435 op = strcopy(op, "int"); 1436 else if (*(op - 1) == ',') 1437 op = strcopy(op, " int"); 1438 #endif 1439 while (v < m) 1440 PUTCHR(*v++); 1441 } 1442 PUTCHR(','); 1443 if (n) 1444 { 1445 if (x = !e) e = op - 1; 1446 PUTCHR(' '); 1447 m = t; 1448 while (m < e) 1449 PUTCHR(*m++); 1450 if (x) 1451 { 1452 m = e; 1453 while (*--e != ' '); 1454 while (*(e - 1) == '*') e--; 1455 op -= m - e; 1456 } 1457 } 1458 while ((c = *++ie) == ' ' || c == '\t' || c == '\n'); 1459 if (ie >= ip) UNPUTCHR(); 1460 else PUTCHR(' '); 1461 if (!n) 1462 { 1463 t = op; 1464 e = 0; 1465 } 1466 } 1467 else if (*ie == '*') 1468 { 1469 if (op > om && (c = *(op - 1)) == ' ') op--; 1470 while (*ie == '*') PUTCHR(*ie++); 1471 while (*ie == ' ' || *ie == '\t' || *ie == '\n') ie++; 1472 if (c != '(') PUTCHR(' '); 1473 } 1474 else if (*ie == '(') 1475 { 1476 if (op > om && *(op - 1) == ' ') op--; 1477 PUTCHR(*ie++); 1478 while (*ie == ' ' || *ie == '\t' || *ie == '\n') ie++; 1479 } 1480 else if (*ie == ')') 1481 { 1482 if (op > om && *(op - 1) == '(') 1483 proto_error((char*)proto + sizeof(struct proto), 1, "function pointer argument prototype omitted", NiL); 1484 PUTCHR(*ie++); 1485 while (*ie == ' ' || *ie == '\t' || *ie == '\n') ie++; 1486 } 1487 else if ((flags & EXTERN) && (op == om || *(op - 1) == ' ') && *ie == 'r' && !strncmp(ie, "register", 8) && (*(ie + 8) == ' ' || *(ie + 8) == '\t' || *(ie + 8) == '\n')) 1488 { 1489 ie += 8; 1490 if (op > om) UNPUTCHR(); 1491 } 1492 else PUTCHR(*ie++); 1493 } 1494 /*...INDENT*/ 1495 if (op <= om) op = strcopy(op, "void"); 1496 PUTCHR(')'); 1497 if (flags & EXTERN) 1498 { 1499 PUTCHR(';'); 1500 PUTCHR('\n'); 1501 SYNCOUT(); 1502 KEEPOUT(); 1503 } 1504 else 1505 { 1506 PUTCHR('\n'); 1507 PUTCHR(*ip); 1508 } 1509 ip++; 1510 flags &= ~(MATCH|SKIP); 1511 } 1512 } 1513 #endif 1514 else if ((flags & (MATCH|PLUSONLY|SKIP|TOKENS)) == (MATCH|TOKENS)) 1515 { 1516 line = proto->line; 1517 op = strcopy(om, " __PARAM__("); 1518 op = memcopy(op, im, ie - im); 1519 PUTCHR(','); 1520 PUTCHR(' '); 1521 PUTCHR('('); 1522 flags &= ~(MATCH|SKIP); 1523 if (flags & VARIADIC) 1524 { 1525 if ((vc = ie - im + 1) > sizeof(proto->variadic)) vc = sizeof(proto->variadic); 1526 memcopy(proto->variadic, im, vc); 1527 op = strcopy(op, "va_alist)) __OTORP__(va_dcl)\n{"); 1528 } 1529 else 1530 { 1531 flags |= SKIP; 1532 proto->ip = im; 1533 proto->op = op; 1534 group = 0; 1535 brack = 0; 1536 for (;;) 1537 { 1538 switch (lex(proto, (flags & GLOBAL) | RECURSIVE)) 1539 { 1540 case '[': 1541 brack++; 1542 continue; 1543 case ']': 1544 brack--; 1545 continue; 1546 case '(': 1547 if (paren++) group++; 1548 continue; 1549 case ')': 1550 if (--paren == 0) 1551 { 1552 group = 0; 1553 if (flags & MATCH) 1554 { 1555 flags &= ~(MATCH|SKIP); 1556 op = memcopy(op, m, e - m); 1557 } 1558 break; 1559 } 1560 continue; 1561 case ',': 1562 if (paren == 1) 1563 { 1564 group = 0; 1565 if (flags & MATCH) 1566 { 1567 flags &= ~(MATCH|SKIP); 1568 op = memcopy(op, m, e - m); 1569 } 1570 PUTCHR(','); 1571 PUTCHR(' '); 1572 proto->op = op; 1573 } 1574 continue; 1575 case T_ID: 1576 if (group <= 1 && !brack) 1577 { 1578 flags |= MATCH; 1579 m = proto->tp; 1580 e = proto->ip; 1581 } 1582 continue; 1583 default: 1584 continue; 1585 } 1586 break; 1587 } 1588 PUTCHR(')'); 1589 PUTCHR(')'); 1590 } 1591 if (!(flags & SKIP)) 1592 { 1593 flags |= SKIP; 1594 proto->op = strcopy(op, " __OTORP__("); 1595 proto->ip = im + 1; 1596 n = *(ie - 1); 1597 *(ie - 1) = ';'; 1598 c = *ie; 1599 *ie = 0; 1600 lex(proto, (flags & GLOBAL) | DECLARE); 1601 *(ie - 1) = n; 1602 *ie = c; 1603 proto->ip = ie; 1604 op = proto->op; 1605 PUTCHR(')'); 1606 } 1607 if (flags & EXTERNALIZE) memcpy(proto->ox, "extern", 6); 1608 op = linesync(proto, op, proto->line = line); 1609 if (flags & DIRECTIVE) 1610 { 1611 proto->brace = 0; 1612 PUTCHR('\n'); 1613 PUTCHR('#'); 1614 } 1615 else if (!(flags & VARIADIC)) PUTCHR('{'); 1616 } 1617 } 1618 flags &= ~(IDID|INDIRECT|MATCH|OTHER|SKIP); 1619 call = 0; 1620 group = 0; 1621 break; 1622 case '}': 1623 flags &= ~(IDID|INDIRECT|MATCH|OTHER|SKIP|TOKENS); 1624 if (--proto->brace == 0) 1625 { 1626 flags &= ~(INIT|VARIADIC|VARIADIC2); 1627 #if PROTOMAIN 1628 if (flags & EXTERN) BACKOUT(); 1629 #endif 1630 } 1631 call = 0; 1632 group = 0; 1633 paren = 0; 1634 break; 1635 case '=': 1636 if (last == '?') flags |= DIRECTIVE; 1637 else if (paren == 0 && (flags & (INIT|MATCH|SKIP)) == MATCH) 1638 { 1639 if (last == ')' && proto->brace && (group != 2 || call != 2)) flags |= SKIP; 1640 else goto fsm_statement; 1641 } 1642 goto fsm_other; 1643 case ',': 1644 #if PROTOMAIN 1645 if (flags & CLASSIC) 1646 { 1647 if (paren == 1) args++; 1648 else 1649 { 1650 args--; 1651 flags &= ~MATCH; 1652 } 1653 break; 1654 } 1655 #endif 1656 if (paren == 0 && (flags & DECLARE)) *(op - 1) = c = ';'; 1657 /*FALLTHROUGH*/ 1658 case ';': 1659 fsm_statement: 1660 if (flags & INIT) /* ignore */; 1661 #if PROTOMAIN 1662 else if (flags & CLASSIC) 1663 { 1664 if (paren == 0) 1665 { 1666 if ((flags & MATCH) && last == ')') 1667 flags &= ~MATCH; 1668 if (!(flags & MATCH)) 1669 { 1670 call = 0; 1671 group = 0; 1672 flags &= ~SKIP; 1673 if (flags & EXTERN) BACKOUT(); 1674 if (flags & SLIDE) 1675 { 1676 SYNC(); 1677 return 0; 1678 } 1679 } 1680 else 1681 { 1682 args--; 1683 if ((flags & (EXTERN|SKIP)) == (EXTERN|SKIP)) 1684 BACKOUT(); 1685 } 1686 } 1687 } 1688 #endif 1689 else if (paren == 0) 1690 { 1691 if ((flags & (MATCH|OTHER|SKIP)) == MATCH && call > 1) 1692 { 1693 if ((flags & MANGLE) && func) 1694 { 1695 func[0] = 'F'; 1696 func[1] = 'U'; 1697 func[2] = 'N'; 1698 func[3] = 'C'; 1699 func = 0; 1700 } 1701 if ((flags & (DECLARE|INDIRECT)) == INDIRECT && aim && aie < im) 1702 { 1703 while (aie < ip && (*aie == ' ' || *aie == '\t' || *aie == '\n')) aie++; 1704 v = aim; 1705 while (v < aie) 1706 if (*v++ == ')') break; 1707 while (v < aie && (*v == ' ' || *v == '\t' || *v == '\n')) v++; 1708 if (v == aie || !(flags & PLUSPLUS)) 1709 { 1710 if (flags & PLUSPLUS) n = 3; 1711 else if (v == aie && *v == '(') n = 10; 1712 else n = 11; 1713 ko = op; 1714 om += n; 1715 v = op += n; 1716 while (v >= ko + n) 1717 { 1718 *v = *(v - n); 1719 v--; 1720 } 1721 if (flags & PLUSPLUS) memcopy(aom, "(...))", 6); 1722 else if (n == 10) memcopy(aom, "(__VARARG__))", 13); 1723 else 1724 { 1725 ko = strcopy(aom, " __PROTO__("); 1726 ko = memcopy(ko, aim, aie - aim); 1727 *ko = ')'; 1728 if (++ko >= om) 1729 { 1730 *ko++ = ')'; 1731 om = ko; 1732 } 1733 } 1734 } 1735 } 1736 else if (flags & TYPEDEF) 1737 { 1738 op = om; 1739 while (*--op == ' ' || *op == '\t' || *op == '\n'); 1740 if (*op != ')') 1741 { 1742 op = om += 14; 1743 *--op = ')'; 1744 while ((x = *(op - 14)) >= 'A' && x <= 'Z' || x >= 'a' && x <= 'z' || x >= '0' && x <= '9' || x == '_') 1745 *--op = x; 1746 memcopy(op - 13, "(__OTORP__(*)", 13); 1747 } 1748 } 1749 if (flags & OTHER) 1750 ; 1751 else if (flags & PLUSPLUS) 1752 { 1753 op = om; 1754 if (!(flags & TOKENS)) op = strcopy(op, "(...)"); 1755 else op = memcopy(op, im, ie - im); 1756 PUTCHR(c); 1757 } 1758 else 1759 { 1760 if (flags & DECLARE) op = strcopy(om, "()"); 1761 else if (!(flags & TOKENS)) op = strcopy(om, "(__VARARG__)"); 1762 else 1763 { 1764 op = strcopy(om, " __PROTO__("); 1765 op = memcopy(op, im, ie - im); 1766 PUTCHR(')'); 1767 } 1768 if (flags & EXTERNALIZE) memcpy(proto->ox, "extern", 6); 1769 PUTCHR(c); 1770 } 1771 flags &= ~(MATCH|VARIADIC|VARIADIC2); 1772 if (c == ',' && !(flags & INDIRECT)) 1773 { 1774 call = 1; 1775 group = 0; 1776 break; 1777 } 1778 } 1779 else if (flags & (OTHER|SKIP)) call = 0; 1780 if (c == ';') 1781 { 1782 flags &= ~(EXTERNALIZE|MANGLE|TOKENS|TYPEDEF); 1783 call = 0; 1784 if (flags & SLIDE) 1785 { 1786 SYNC(); 1787 return 0; 1788 } 1789 } 1790 else call = call > 1 && c == ','; 1791 group = 0; 1792 flags &= ~(IDID|INDIRECT|MATCH|OTHER|SKIP); 1793 } 1794 else if (paren == 1 && group == 1 && !(flags & (IDID|MANGLE))) flags |= TOKENS|OTHER; 1795 break; 1796 case T_DO: 1797 case T_IF: 1798 flags |= TOKENS|SKIP; 1799 break; 1800 case T_EXTERN: 1801 #if PROTOMAIN 1802 if (flags & CLASSIC) 1803 { 1804 if (proto->brace == 0) 1805 flags |= SKIP; 1806 } 1807 else 1808 #endif 1809 if (paren == 0 && !(flags & TYPEDEF)) 1810 { 1811 flags |= MANGLE; 1812 if (!(flags & PLUSONLY) || proto->package) 1813 { 1814 op = strcopy(op, " __MANGLE__"); 1815 if (proto->package) 1816 { 1817 op = strcopy(op - 1, proto->package); 1818 func = op + 1; 1819 op = strcopy(op, "_DATA__"); 1820 } 1821 } 1822 else 1823 func = 0; 1824 } 1825 break; 1826 case T_VARIADIC: 1827 if (paren == 0 && (flags & (DECLARE|VARIADIC)) == DECLARE) 1828 { 1829 op -= 3; 1830 SYNC(); 1831 return c; 1832 } 1833 if (paren == 1 && !(flags & SKIP)) 1834 flags |= VARIADIC; 1835 flags |= TOKENS; 1836 break; 1837 case T_VOID: 1838 goto fsm_id; 1839 case T_VA_START: 1840 if ((flags & (PLUSONLY|VARIADIC)) == VARIADIC) 1841 { 1842 flags &= ~MATCH; 1843 line = proto->line; 1844 op = strcopy(op - 8, "__VA_START__"); 1845 SYNC(); 1846 for (;;) 1847 { 1848 switch (lex(proto, (flags & GLOBAL) | RECURSIVE)) 1849 { 1850 case 0: 1851 case ';': 1852 break; 1853 case T_ID: 1854 if (!(flags & MATCH)) 1855 { 1856 flags |= MATCH; 1857 m = proto->tp; 1858 e = proto->ip; 1859 } 1860 continue; 1861 default: 1862 continue; 1863 } 1864 break; 1865 } 1866 CACHE(); 1867 if (flags & MATCH) 1868 { 1869 v = m; 1870 n = e - m; 1871 } 1872 else 1873 { 1874 v = "ap"; 1875 n = 2; 1876 } 1877 op = strcopy(op, " __OTORP__("); 1878 proto->ip = proto->variadic; 1879 proto->op = op; 1880 flags &= ~MATCH; 1881 group = 0; 1882 bp = proto->ip + 1; 1883 if (*bp == 'r' && !strncmp(bp, "register", 8) && (*(bp + 8) == ' ' || *(bp + 8) == '\t')) bp += 9; 1884 for (;;) 1885 { 1886 switch (lex(proto, (flags & GLOBAL) | RECURSIVE)) 1887 { 1888 case '(': 1889 if (paren++) group++; 1890 continue; 1891 case ')': 1892 if (--paren == 0) 1893 { 1894 if (flags & MATCH) 1895 { 1896 flags &= ~MATCH; 1897 if (!(flags & VARIADIC2)) 1898 { 1899 op = memcopy(op, m, e - m); 1900 op = strcopy(op, " = "); 1901 } 1902 op = strcopy(op, "va_arg("); 1903 op = memcopy(op, v, n); 1904 PUTCHR(','); 1905 PUTCHR(' '); 1906 if (m > bp) op = memcopy(op, bp, m - bp); 1907 else op = strcopy(op, "int "); 1908 if (group > 1) op = strcopy(op, ")()"); 1909 else op = memcopy(op, e, proto->ip - e - 1); 1910 PUTCHR(')'); 1911 PUTCHR(';'); 1912 } 1913 group = 0; 1914 break; 1915 } 1916 continue; 1917 case ',': 1918 if (paren == 1) 1919 { 1920 if (flags & MATCH) 1921 { 1922 flags &= ~MATCH; 1923 if (!(flags & VARIADIC2)) 1924 { 1925 op = memcopy(op, m, e - m); 1926 op = strcopy(op, " = "); 1927 } 1928 op = strcopy(op, "va_arg("); 1929 op = memcopy(op, v, n); 1930 PUTCHR(','); 1931 PUTCHR(' '); 1932 if (m > bp) op = memcopy(op, bp, m - bp); 1933 else op = strcopy(op, "int "); 1934 if (group > 1) op = strcopy(op, ")()"); 1935 else op = memcopy(op, e, proto->ip - e - 1); 1936 PUTCHR(')'); 1937 PUTCHR(';'); 1938 bp = proto->ip + 1; 1939 if (*bp == 'r' && !strncmp(bp, "register", 8) && (*(bp + 8) == ' ' || *(bp + 8) == '\t')) bp += 9; 1940 } 1941 group = 0; 1942 proto->op = op; 1943 } 1944 continue; 1945 case T_ID: 1946 if (group <= 1) 1947 { 1948 flags |= MATCH; 1949 m = proto->tp; 1950 e = proto->ip; 1951 } 1952 continue; 1953 default: 1954 continue; 1955 } 1956 break; 1957 } 1958 op = strcopy(op, ")"); 1959 flags |= VARIADIC2; 1960 proto->line = line; 1961 call = 0; 1962 break; 1963 } 1964 /*FALLTHROUGH*/ 1965 case T_ID: 1966 fsm_id: 1967 #if PROTOMAIN 1968 if (flags & CLASSIC) 1969 { 1970 if (!args && paren == 1) args++; 1971 break; 1972 } 1973 #endif 1974 if (paren == 0) 1975 { 1976 if (last == ')') 1977 { 1978 if (proto->brace == 0 && !(flags & DECLARE)) flags |= SKIP; 1979 call = !call; 1980 } 1981 else if ((flags & SKIP) || c == T_ID || c == T_VOID) call++; 1982 else flags |= SKIP; 1983 if (last == T_ID) flags |= IDID; 1984 } 1985 c = T_ID; 1986 flags |= TOKENS; 1987 break; 1988 case T_INVALID: 1989 if (*proto->tp >= '0' && *proto->tp <= '9') 1990 { 1991 n = 0; 1992 for (;; op--) 1993 { 1994 switch (*(op - 1)) 1995 { 1996 case 'f': 1997 case 'F': 1998 t = op; 1999 while ((c = *--t) >= '0' && c <= '9' || c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z'); 2000 if (*t == '.') 2001 op--; 2002 n = 0; 2003 break; 2004 case 'l': 2005 case 'L': 2006 if (!(n & 01)) 2007 { 2008 n |= 01; 2009 t = op; 2010 while ((c = *--t) >= '0' && c <= '9' || c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z'); 2011 if (*t == '.') 2012 { 2013 n = 0; 2014 op--; 2015 break; 2016 } 2017 } 2018 continue; 2019 case 'u': 2020 case 'U': 2021 n |= 02; 2022 continue; 2023 } 2024 break; 2025 } 2026 if (n & 01) 2027 *op++ = 'L'; 2028 if (n & 02) 2029 { 2030 m = op; 2031 t = op = m + 10; 2032 while ((c = *--m) >= '0' && c <= '9' || c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z') 2033 *--t = c; 2034 c = *t; 2035 strcopy(m + 1, "(unsigned)"); 2036 *t = c; 2037 break; 2038 } 2039 } 2040 goto fsm_other; 2041 #if PROTOMAIN 2042 case '[': 2043 if ((flags & CLASSIC) && paren == 0 && group <= 2) flags |= SKIP; 2044 /*FALLTHROUGH*/ 2045 #endif 2046 default: 2047 fsm_other: 2048 #if PROTOMAIN 2049 if (flags & CLASSIC) break; 2050 #endif 2051 flags |= TOKENS; 2052 if (paren == 0) flags |= OTHER; 2053 break; 2054 } 2055 else if (c == '#' && *ip != '(') flags |= SHARP; 2056 last = c; 2057 #if PROTOMAIN 2058 if ((flags & (EXTERN|MATCH)) == (EXTERN|MATCH) && ((flags & (DIRECTIVE|SKIP)) || proto->brace || c != '(' && c != ')' && c != '*' && c != T_ID)) 2059 CACHEOUT(); 2060 else 2061 #endif 2062 SYNCOUT(); 2063 goto fsm_start; 2064 } 2065 else if (flags & (INIT_DEFINE|INIT_INCLUDE)) 2066 { 2067 #if PROTOMAIN 2068 if ((flags & YACC) && c == '%' && *ip == '{') t = 0; 2069 else 2070 #endif 2071 { 2072 if (c == '#') for (t = ip; *t == ' ' || *t == '\t'; t++); 2073 else t = ""; 2074 if (*t++ == 'i' && *t++ == 'f' && *t++ == 'n' && *t++ == 'd' && *t++ == 'e' && *t++ == 'f') 2075 { 2076 #if !PROTOMAIN 2077 while (*t == ' ' || *t == '\t') t++; 2078 if (*t != '_') 2079 #endif 2080 t = 0; 2081 } 2082 } 2083 if (t) 2084 { 2085 ip = bp; 2086 op = proto->op; 2087 } 2088 else while (*ip != '\n') *op++ = *ip++; 2089 op = init(proto, op, flags); 2090 op = linesync(proto, op, proto->line); 2091 flags &= ~(INIT_DEFINE|INIT_INCLUDE); 2092 proto->flags &= ~(INIT_DEFINE|INIT_INCLUDE); 2093 goto fsm_start; 2094 } 2095 SYNC(); 2096 return c; 2097 } 2098 2099 /* 2100 * close a proto buffer stream 2101 */ 2102 2103 void 2104 pppclose(char* iob) 2105 { 2106 register struct proto* proto = (struct proto*)(iob - sizeof(struct proto)); 2107 2108 if (proto->flags & MORE) close(proto->fd); 2109 free((char*)proto); /* some ANSI cc's botch the free() prototype */ 2110 } 2111 2112 /* 2113 * open a new proto buffer stream 2114 * read buffer pointer returned 2115 * 0 returned on error or if no magic 2116 * 2117 * file !=0 file path to open, otherwise use fd 2118 * fd open file fd if file==0 2119 * notice !=0 copyright notice info commented at the top 2120 * options !=0 additional notice name=value pairs, space or ; separated 2121 * package !=0 generate header for this package 2122 */ 2123 2124 char* 2125 pppopen(char* file, int fd, char* notice, char* options, char* package, char* comment, int flags) 2126 { 2127 register struct proto* proto; 2128 register char* iob; 2129 register long n; 2130 register char* s; 2131 int pragma; 2132 char* b; 2133 #if PROTOMAIN 2134 int comlen; 2135 char com[80]; 2136 #endif 2137 int m = 0; 2138 2139 static int retain; 2140 2141 /* 2142 * initialize proto 2143 */ 2144 2145 #if PROTOMAIN 2146 if (flags & PROTO_CLASSIC) flags &= ~PROTO_INCLUDE; 2147 #endif 2148 if (flags & PROTO_RETAIN) flags &= ~retain; 2149 else retain &= PROTO_INITIALIZED; 2150 if (file && (fd = open(file, O_RDONLY)) < 0) return 0; 2151 #if !PROTOMAIN 2152 if ((n = lseek(fd, 0L, 2)) > 0) 2153 { 2154 if (lseek(fd, 0L, 0)) return 0; 2155 if (n < CHUNK) n = CHUNK; 2156 else if (n > 2 * BLOCK) n = 0; 2157 m = 1; 2158 } 2159 if (n > 0) 2160 { 2161 /* 2162 * file read in one chunk 2163 */ 2164 2165 if (!(proto = newof(0, struct proto, 1, 4 * n + 2))) 2166 return 0; 2167 proto->iz = n; 2168 proto->oz = 3 * n; 2169 n = 0; 2170 } 2171 else 2172 #endif 2173 { 2174 /* 2175 * file read in BLOCK chunks 2176 */ 2177 2178 n = BLOCK; 2179 if (!(proto = newof(0, struct proto, 1, 5 * n + 2))) 2180 return 0; 2181 proto->iz = n; 2182 proto->oz = 3 * n; 2183 proto->flags |= MORE; 2184 } 2185 proto->fd = fd; 2186 proto->package = package; 2187 iob = (char*)proto + sizeof(struct proto); 2188 proto->op = proto->ob = iob; 2189 proto->ip = proto->ib = iob + proto->oz + n; 2190 if (m) proto->options |= REGULAR; 2191 if (!comment) 2192 comment = "/*"; 2193 if (!(proto->cc[0] = comment[0])) 2194 notice = options = 0; 2195 else if (comment[1]) 2196 { 2197 proto->cc[1] = comment[1]; 2198 proto->cc[2] = comment[2] ? comment[2] : comment[0]; 2199 } 2200 else 2201 proto->cc[1] = proto->cc[2] = comment[0]; 2202 2203 /* 2204 * read the first chunk 2205 */ 2206 2207 n = read(fd, proto->ip, proto->iz); 2208 if (!(proto->flags & MORE)) 2209 close(fd); 2210 if (n < 0) 2211 { 2212 pppclose(iob); 2213 return 0; 2214 } 2215 *(proto->ip + n) = 0; 2216 2217 /* 2218 * check for proto pragma in first block of lines 2219 * pragma blanked out if found 2220 * 2221 * -1 no pragma 2222 * 0 #pragma noprototyped 2223 * 1 #pragma prototyped 2224 * 2225 * NOTE: matches may occur inside comments and quotes 2226 */ 2227 2228 #if PROTOMAIN 2229 if (!notice && !options || (comlen = astlicense(com, sizeof(com), NiL, "type=check", proto->cc[0], proto->cc[1], proto->cc[2])) <= 0) 2230 *com = 0; 2231 #endif 2232 pragma = -1; 2233 s = proto->ip; 2234 m = MAGICTOP; 2235 while (m-- > 0 && *s) 2236 { 2237 while (*s == ' ' || *s == '\t') s++; 2238 if (*s == '#') 2239 { 2240 b = s++; 2241 while (*s == ' ' || *s == '\t') s++; 2242 if (!strncmp(s, MAGICDIR, sizeof(MAGICDIR) - 1) && (*(s += sizeof(MAGICDIR) - 1) == ' ' || *s == '\t')) 2243 { 2244 while (*s == ' ' || *s == '\t') s++; 2245 if (*s == 'n' && *(s + 1) == 'o') 2246 { 2247 s += 2; 2248 pragma = -2; 2249 } 2250 if (!strncmp(s, MAGICARG, sizeof(MAGICARG) - 1) && (*(s += sizeof(MAGICARG) - 1) == ' ' || *s == '\t' || *s == '\n' || *s == '\r')) 2251 while (*s) 2252 { 2253 if ((*(s - 1) == ' ' || *(s - 1) == '\t') && *s == *MAGICOFF && !strncmp(s, MAGICOFF, sizeof(MAGICOFF) - 1)) 2254 notice = options = 0; 2255 if (*s++ == '\n') 2256 { 2257 pragma += 2; 2258 #if PROTOMAIN 2259 if (!(flags & PROTO_DISABLE) || (flags & PROTO_NOPRAGMA)) 2260 #endif 2261 for (s--; b < s; *b++ = ' '); 2262 goto magic; 2263 } 2264 } 2265 pragma = -1; 2266 } 2267 } 2268 else if (*s == '/' && !strncmp(s, MAGICGEN, sizeof(MAGICGEN) - 1)) 2269 { 2270 pragma = 0; 2271 break; 2272 } 2273 #if PROTOMAIN 2274 else if (*s == '%' && *(s + 1) == '{') 2275 proto->flags |= YACC; 2276 if (notice || options) 2277 { 2278 if (*s == *com && !strncmp(s, com, comlen)) 2279 notice = options = 0; 2280 else 2281 while (*s) 2282 { 2283 if (*s == *NOTICED && !strncmp(s, NOTICED, sizeof(NOTICED) - 1)) 2284 { 2285 s += sizeof(NOTICED) - 1; 2286 while (*s == ' ' || *s == '\t') 2287 s++; 2288 if (*s == '(' && (*(s + 1) == 'c' || *(s + 1) == 'C') && *(s + 2) == ')' || *s >= '0' && *s <= '9' && *(s + 1) >= '0' && *(s + 1) <= '9') 2289 { 2290 notice = options = 0; 2291 break; 2292 } 2293 } 2294 if (*s == *PUBLICDOMAIN && !strncmp(s, PUBLICDOMAIN, sizeof(PUBLICDOMAIN) - 1)) 2295 { 2296 notice = options = 0; 2297 break; 2298 } 2299 else if (*s++ == '\n') 2300 { 2301 s--; 2302 break; 2303 } 2304 } 2305 } 2306 #endif 2307 while (*s && *s++ != '\n'); 2308 } 2309 magic: 2310 if (flags & PROTO_PLUSPLUS) proto->flags |= PLUSPLUS; 2311 if (flags & PROTO_TEST) proto->test = 1; 2312 if (flags & PROTO_EXTERNALIZE) proto->options |= EXTERNALIZE; 2313 #if PROTOMAIN 2314 if (flags & PROTO_CLASSIC) pragma = -pragma; 2315 if (flags & PROTO_DISABLE) pragma = 0; 2316 if (flags & PROTO_LINESYNC) proto->flags |= LINESYNC; 2317 if (!(proto->flags & YACC) && file && (m = strlen(file)) > 2 && file[--m] == 'y' && file[--m] == '.') 2318 proto->flags |= YACC; 2319 #endif 2320 if (pragma <= 0) 2321 { 2322 if (flags & PROTO_PLUSPLUS) 2323 { 2324 flags &= ~(PROTO_HEADER|PROTO_INCLUDE); 2325 proto->flags |= PLUSONLY; 2326 } 2327 else if (!(flags & (PROTO_FORCE|PROTO_PASS))) 2328 { 2329 pppclose(iob); 2330 return 0; 2331 } 2332 else if ((flags & (PROTO_FORCE|PROTO_PASS)) == PROTO_PASS || !pragma) 2333 { 2334 proto->flags |= PASS; 2335 if (proto->flags & MORE) 2336 proto->oz += proto->iz; 2337 proto->iz = n; 2338 if (notice || options) 2339 { 2340 if (proto->cc[0] == '#' && proto->ip[0] == '#' && proto->ip[1] == '!') 2341 { 2342 s = proto->ip; 2343 while (*s && *s++ != '\n'); 2344 m = s - proto->ip; 2345 proto->op = memcopy(proto->op, proto->ip, m); 2346 proto->ip = s; 2347 proto->iz = n -= m; 2348 } 2349 #if PROTOMAIN 2350 if (proto->cc[0]) 2351 { 2352 if ((comlen = astlicense(proto->op, proto->oz, notice, options, proto->cc[0], proto->cc[1], proto->cc[2])) < 0) 2353 proto_error((char*)proto + sizeof(struct proto), 1, proto->op, NiL); 2354 else 2355 proto->op += comlen; 2356 } 2357 if (!(flags & PROTO_CLASSIC) && !(proto->flags & YACC)) 2358 #endif 2359 proto->op = linesync(proto, proto->op, 1); 2360 proto->iz += proto->op - proto->ob; 2361 } 2362 memcopy(proto->op, proto->ip, n); 2363 return iob; 2364 } 2365 } 2366 #if PROTOMAIN 2367 if (!(retain & PROTO_INITIALIZED)) 2368 { 2369 retain |= PROTO_INITIALIZED; 2370 ppfsm(FSM_INIT, NiL); 2371 } 2372 #endif 2373 proto->line = 1; 2374 #if CHUNK >= 512 2375 if (notice || options || (flags & (PROTO_HEADER|PROTO_INCLUDE))) 2376 { 2377 #if PROTOMAIN 2378 if (notice || options) 2379 { 2380 if ((comlen = astlicense(proto->op, proto->oz, notice, options, proto->cc[0], proto->cc[1], proto->cc[2])) < 0) 2381 proto_error((char*)proto + sizeof(struct proto), 1, proto->op, NiL); 2382 else 2383 proto->op += comlen; 2384 } 2385 #endif 2386 if (flags & PROTO_INCLUDE) 2387 { 2388 proto->flags |= INIT_INCLUDE; 2389 if (flags & PROTO_RETAIN) 2390 retain |= PROTO_INCLUDE; 2391 } 2392 else if (flags & PROTO_HEADER) 2393 { 2394 if (flags & PROTO_RETAIN) retain |= PROTO_HEADER; 2395 #if PROTOMAIN 2396 if (flags & PROTO_CLASSIC) 2397 { 2398 *proto->op++ = '#'; 2399 proto->op = strcopy(proto->op, MAGICDIR); 2400 *proto->op++ = ' '; 2401 proto->op = strcopy(proto->op, MAGICARG); 2402 *proto->op++ = '\n'; 2403 } 2404 else 2405 #endif 2406 proto->flags |= INIT_DEFINE; 2407 } 2408 #if PROTOMAIN 2409 if (!(flags & PROTO_CLASSIC)) 2410 { 2411 if (proto->flags & YACC) 2412 { 2413 proto->op = strcopy(proto->op, "\n%{\n" + !notice); 2414 proto->op = strcopy(proto->op, MAGICGEN); 2415 proto->op = strcopy(proto->op, "%}\n"); 2416 } 2417 else 2418 { 2419 if (n || notice || options) 2420 *proto->op++ = '\n'; 2421 proto->op = strcopy(proto->op, MAGICGEN); 2422 if (n) 2423 proto->op = linesync(proto, proto->op, proto->line); 2424 else if (proto->flags & (INIT_DEFINE|INIT_INCLUDE)) 2425 proto->op = init(proto, proto->op, proto->flags); 2426 } 2427 } 2428 #endif 2429 } 2430 #endif 2431 #if PROTOMAIN 2432 proto->file = file; 2433 if (flags & PROTO_CLASSIC) 2434 { 2435 proto->flags |= CLASSIC; 2436 if (!(flags & PROTO_HEADER)) proto->flags |= EXTERN; 2437 } 2438 #endif 2439 return iob; 2440 } 2441 2442 /* 2443 * read next proto'd chunk into iob 2444 * the chunk is 0 terminated and its size is returned 2445 */ 2446 2447 int 2448 pppread(char* iob) 2449 { 2450 register struct proto* proto = (struct proto*)(iob - sizeof(struct proto)); 2451 register int n; 2452 2453 if (proto->flags & PASS) 2454 { 2455 if (proto->iz) 2456 { 2457 n = proto->iz; 2458 proto->iz = 0; 2459 } 2460 else if (!(proto->flags & MORE)) n = 0; 2461 else if ((n = read(proto->fd, proto->ob, proto->oz)) <= 0 || (proto->options & REGULAR) && n < proto->oz) 2462 { 2463 proto->flags &= ~MORE; 2464 close(proto->fd); 2465 } 2466 } 2467 else 2468 { 2469 if (proto->op == proto->ob) 2470 { 2471 if (proto->flags & ERROR) return -1; 2472 #if PROTOMAIN 2473 if (proto->flags & YACC) 2474 { 2475 register char* ip = proto->ip; 2476 register char* op = proto->ob; 2477 register char* ep = proto->ob + proto->oz - 2; 2478 2479 if (!*ip) 2480 { 2481 ip = proto->ip = proto->ib; 2482 if (!(proto->flags & MORE)) n = 0; 2483 else if ((n = read(proto->fd, ip, proto->iz)) <= 0 || (proto->options & REGULAR) && n < proto->iz) 2484 { 2485 if (n < 0) n = 0; 2486 proto->flags &= ~MORE; 2487 close(proto->fd); 2488 } 2489 ip[n] = 0; 2490 } 2491 if (proto->flags & YACCSPLIT) 2492 { 2493 proto->flags &= ~YACCSPLIT; 2494 if (*ip == '%') 2495 { 2496 *op++ = *ip++; 2497 if (proto->flags & YACC2) proto->flags &= ~YACC; 2498 else proto->flags |= YACC2; 2499 } 2500 } 2501 if (proto->flags & YACC) 2502 while (op < ep && (n = *op++ = *ip)) 2503 { 2504 ip++; 2505 if (n == '%') 2506 { 2507 if (*ip == '%' && (ip == proto->ip + 1 || *(ip - 2) == '\n')) 2508 { 2509 *op++ = *ip++; 2510 if (proto->flags & YACC2) proto->flags &= ~YACC; 2511 else proto->flags |= YACC2; 2512 break; 2513 } 2514 if (!*ip) 2515 { 2516 *op++ = '%'; 2517 proto->flags |= YACCSPLIT; 2518 break; 2519 } 2520 } 2521 else if (n == '\n') proto->line++; 2522 } 2523 proto->op = memcopy(proto->ob, proto->ip, ip - proto->ip); 2524 proto->ip = ip; 2525 } 2526 else 2527 #endif 2528 lex(proto, proto->flags); 2529 if ((proto->flags & (ERROR|MORE)) == ERROR) 2530 proto->op = strcopy(proto->op, "/* NOTE: some constructs may not have been converted */\n"); 2531 } 2532 n = proto->op - proto->ob; 2533 proto->op = proto->ob; 2534 } 2535 return n; 2536 } 2537 2538 #if !PROTOMAIN 2539 2540 /* 2541 * drop control of iob after first pppread() 2542 * return value is input fd 2543 * if fd<0 then all data in iob 2544 */ 2545 2546 int 2547 pppdrop(char* iob) 2548 { 2549 register struct proto* proto = (struct proto*)(iob - sizeof(struct proto)); 2550 2551 if (proto->flags & MORE) 2552 { 2553 proto->flags &= ~MORE; 2554 return proto->fd; 2555 } 2556 return -1; 2557 } 2558 2559 #endif 2560