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