1 #include <u.h> 2 #include <libc.h> 3 #include <bio.h> 4 #include "cb.h" 5 #include "cbtype.h" 6 7 static void 8 usage(void) 9 { 10 fprint(2, "usage: cb [-sj] [-l width]\n"); 11 exits("usage"); 12 } 13 14 void 15 main(int argc, char *argv[]) 16 { 17 Biobuf stdin, stdout; 18 19 ARGBEGIN{ 20 case 'j': 21 join = 1; 22 break; 23 case 'l': 24 maxleng = atoi(EARGF(usage())); 25 maxtabs = maxleng/TABLENG - 2; 26 maxleng -= (maxleng + 5)/10; 27 break; 28 case 's': 29 strict = 1; 30 break; 31 default: 32 usage(); 33 }ARGEND 34 35 Binit(&stdout, 1, OWRITE); 36 output = &stdout; 37 if (argc <= 0){ 38 Binit(&stdin, 0, OREAD); 39 input = &stdin; 40 work(); 41 Bterm(input); 42 } else { 43 while (argc-- > 0){ 44 if ((input = Bopen(*argv, OREAD)) == 0) 45 sysfatal("can't open input file %s: %r", *argv); 46 work(); 47 Bterm(input); 48 argv++; 49 } 50 } 51 exits(0); 52 } 53 void 54 work(void) 55 { 56 int c, cc; 57 struct keyw *lptr; 58 char *pt; 59 int ct; 60 61 while ((c = getch()) != Beof){ 62 switch (c){ 63 case '{': 64 if ((lptr = lookup(lastlook,p)) != 0){ 65 if (lptr->type == ELSE)gotelse(); 66 else if(lptr->type == DO)gotdo(); 67 else if(lptr->type == STRUCT)structlev++; 68 } 69 if(++clev >= &ind[CLEVEL-1]){ 70 fprint(2,"too many levels of curly brackets\n"); 71 clev = &ind[CLEVEL-1]; 72 } 73 clev->pdepth = 0; 74 clev->tabs = (clev-1)->tabs; 75 clearif(clev); 76 if(strict && clev->tabs > 0) 77 putspace(' ',NO); 78 putch(c,NO); 79 getnl(); 80 if(keyflag == DATADEF){ 81 OUT; 82 } 83 else { 84 OUTK; 85 } 86 clev->tabs++; 87 pt = getnext(0); /* to handle initialized structures */ 88 if(*pt == '{'){ /* hide one level of {} */ 89 while((c=getch()) != '{') 90 if(c == Beof)error("{"); 91 putch(c,NO); 92 if(strict){ 93 putch(' ',NO); 94 eatspace(); 95 } 96 keyflag = SINIT; 97 } 98 continue; 99 case '}': 100 pt = getnext(0); /* to handle initialized structures */ 101 if(*pt == ','){ 102 if(strict){ 103 putspace(' ',NO); 104 eatspace(); 105 } 106 putch(c,NO); 107 putch(*pt,NO); 108 *pt = '\0'; 109 ct = getnl(); 110 pt = getnext(0); 111 if(*pt == '{'){ 112 OUT; 113 while((cc = getch()) != '{') 114 if(cc == Beof)error("}"); 115 putch(cc,NO); 116 if(strict){ 117 putch(' ',NO); 118 eatspace(); 119 } 120 getnext(0); 121 continue; 122 } 123 else if(strict || ct){ 124 OUT; 125 } 126 continue; 127 } 128 else if(keyflag == SINIT && *pt == '}'){ 129 if(strict) 130 putspace(' ',NO); 131 putch(c,NO); 132 getnl(); 133 OUT; 134 keyflag = DATADEF; 135 *pt = '\0'; 136 pt = getnext(0); 137 } 138 outs(clev->tabs); 139 if(--clev < ind)clev = ind; 140 ptabs(clev->tabs); 141 putch(c,NO); 142 lbegin = 0; 143 lptr=lookup(pt,lastplace+1); 144 c = *pt; 145 if(*pt == ';' || *pt == ','){ 146 putch(*pt,NO); 147 *pt = '\0'; 148 lastplace=pt; 149 } 150 ct = getnl(); 151 if((dolevel && clev->tabs <= dotabs[dolevel]) || (structlev ) 152 || (lptr != 0 &&lptr->type == ELSE&& clev->pdepth == 0)){ 153 if(c == ';'){ 154 OUTK; 155 } 156 else if(strict || (lptr != 0 && lptr->type == ELSE && ct == 0)){ 157 putspace(' ',NO); 158 eatspace(); 159 } 160 else if(lptr != 0 && lptr->type == ELSE){ 161 OUTK; 162 } 163 if(structlev){ 164 structlev--; 165 keyflag = DATADEF; 166 } 167 } 168 else { 169 OUTK; 170 if(strict && clev->tabs == 0){ 171 if((c=getch()) != '\n'){ 172 Bputc(output, '\n'); 173 Bputc(output, '\n'); 174 unget(c); 175 } 176 else { 177 lineno++; 178 Bputc(output, '\n'); 179 if((c=getch()) != '\n')unget(c); 180 else lineno++; 181 Bputc(output, '\n'); 182 } 183 } 184 } 185 if(lptr != 0 && lptr->type == ELSE && clev->pdepth != 0){ 186 UNBUMP; 187 } 188 if(lptr == 0 || lptr->type != ELSE){ 189 clev->iflev = 0; 190 if(dolevel && docurly[dolevel] == NO && clev->tabs == dotabs[dolevel]+1) 191 clev->tabs--; 192 else if(clev->pdepth != 0){ 193 UNBUMP; 194 } 195 } 196 continue; 197 case '(': 198 paren++; 199 if ((lptr = lookup(lastlook,p)) != 0){ 200 if(!(lptr->type == TYPE || lptr->type == STRUCT))keyflag=KEYWORD; 201 if (strict){ 202 putspace(lptr->punc,NO); 203 opflag = 1; 204 } 205 putch(c,NO); 206 if (lptr->type == IF)gotif(); 207 } 208 else { 209 putch(c,NO); 210 lastlook = p; 211 opflag = 1; 212 } 213 continue; 214 case ')': 215 if(--paren < 0)paren = 0; 216 putch(c,NO); 217 if((lptr = lookup(lastlook,p)) != 0){ 218 if(lptr->type == TYPE || lptr->type == STRUCT) 219 opflag = 1; 220 } 221 else if(keyflag == DATADEF)opflag = 1; 222 else opflag = 0; 223 outs(clev->tabs); 224 pt = getnext(1); 225 if ((ct = getnl()) == 1 && !strict){ 226 if(dolevel && clev->tabs <= dotabs[dolevel]) 227 resetdo(); 228 if(clev->tabs > 0 && (paren != 0 || keyflag == 0)){ 229 if(join){ 230 eatspace(); 231 putch(' ',YES); 232 continue; 233 } else { 234 OUT; 235 split = 1; 236 continue; 237 } 238 } 239 else if(clev->tabs > 0 && *pt != '{'){ 240 BUMP; 241 } 242 OUTK; 243 } 244 else if(strict){ 245 if(clev->tabs == 0){ 246 if(*pt != ';' && *pt != ',' && *pt != '(' && *pt != '['){ 247 OUTK; 248 } 249 } 250 else { 251 if(keyflag == KEYWORD && paren == 0){ 252 if(dolevel && clev->tabs <= dotabs[dolevel]){ 253 resetdo(); 254 eatspace(); 255 continue; 256 } 257 if(*pt != '{'){ 258 BUMP; 259 OUTK; 260 } 261 else { 262 *pt='\0'; 263 eatspace(); 264 unget('{'); 265 } 266 } 267 else if(ct){ 268 if(paren){ 269 if(join){ 270 eatspace(); 271 } else { 272 split = 1; 273 OUT; 274 } 275 } 276 else { 277 OUTK; 278 } 279 } 280 } 281 } 282 else if(dolevel && clev->tabs <= dotabs[dolevel]) 283 resetdo(); 284 continue; 285 case ' ': 286 case '\t': 287 if ((lptr = lookup(lastlook,p)) != 0){ 288 if(!(lptr->type==TYPE||lptr->type==STRUCT)) 289 keyflag = KEYWORD; 290 else if(paren == 0)keyflag = DATADEF; 291 if(strict){ 292 if(lptr->type != ELSE){ 293 if(lptr->type == TYPE){ 294 if(paren != 0)putch(' ',YES); 295 } 296 else 297 putch(lptr->punc,NO); 298 eatspace(); 299 } 300 } 301 else putch(c,YES); 302 switch(lptr->type){ 303 case CASE: 304 outs(clev->tabs-1); 305 continue; 306 case ELSE: 307 pt = getnext(1); 308 eatspace(); 309 if((cc = getch()) == '\n' && !strict){ 310 unget(cc); 311 } 312 else { 313 unget(cc); 314 if(checkif(pt))continue; 315 } 316 gotelse(); 317 if(strict) unget(c); 318 if(getnl() == 1 && !strict){ 319 OUTK; 320 if(*pt != '{'){ 321 BUMP; 322 } 323 } 324 else if(strict){ 325 if(*pt != '{'){ 326 OUTK; 327 BUMP; 328 } 329 } 330 continue; 331 case IF: 332 gotif(); 333 continue; 334 case DO: 335 gotdo(); 336 pt = getnext(1); 337 if(*pt != '{'){ 338 eatallsp(); 339 OUTK; 340 docurly[dolevel] = NO; 341 dopdepth[dolevel] = clev->pdepth; 342 clev->pdepth = 0; 343 clev->tabs++; 344 } 345 continue; 346 case TYPE: 347 if(paren)continue; 348 if(!strict)continue; 349 gottype(lptr); 350 continue; 351 case STRUCT: 352 gotstruct(); 353 continue; 354 } 355 } 356 else if (lbegin == 0 || p > string) 357 if(strict) 358 putch(c,NO); 359 else putch(c,YES); 360 continue; 361 case ';': 362 putch(c,NO); 363 if(paren != 0){ 364 if(strict){ 365 putch(' ',YES); 366 eatspace(); 367 } 368 opflag = 1; 369 continue; 370 } 371 outs(clev->tabs); 372 pt = getnext(0); 373 lptr=lookup(pt,lastplace+1); 374 if(lptr == 0 || lptr->type != ELSE){ 375 clev->iflev = 0; 376 if(clev->pdepth != 0){ 377 UNBUMP; 378 } 379 if(dolevel && docurly[dolevel] == NO && clev->tabs <= dotabs[dolevel]+1) 380 clev->tabs--; 381 /* 382 else if(clev->pdepth != 0){ 383 UNBUMP; 384 } 385 */ 386 } 387 getnl(); 388 OUTK; 389 continue; 390 case '\n': 391 if ((lptr = lookup(lastlook,p)) != 0){ 392 pt = getnext(1); 393 if (lptr->type == ELSE){ 394 if(strict) 395 if(checkif(pt))continue; 396 gotelse(); 397 OUTK; 398 if(*pt != '{'){ 399 BUMP; 400 } 401 } 402 else if(lptr->type == DO){ 403 OUTK; 404 gotdo(); 405 if(*pt != '{'){ 406 docurly[dolevel] = NO; 407 dopdepth[dolevel] = clev->pdepth; 408 clev->pdepth = 0; 409 clev->tabs++; 410 } 411 } 412 else { 413 OUTK; 414 if(lptr->type == STRUCT)gotstruct(); 415 } 416 } 417 else if(p == string)Bputc(output, '\n'); 418 else { 419 if(clev->tabs > 0 &&(paren != 0 || keyflag == 0)){ 420 if(join){ 421 putch(' ',YES); 422 eatspace(); 423 continue; 424 } else { 425 OUT; 426 split = 1; 427 continue; 428 } 429 } 430 else if(keyflag == KEYWORD){ 431 OUTK; 432 continue; 433 } 434 OUT; 435 } 436 continue; 437 case '"': 438 case '\'': 439 putch(c,NO); 440 while ((cc = getch()) != c){ 441 if(cc == Beof) 442 error("\" or '"); 443 putch(cc,NO); 444 if (cc == '\\'){ 445 putch(getch(),NO); 446 } 447 if (cc == '\n'){ 448 outs(clev->tabs); 449 lbegin = 1; 450 count = 0; 451 } 452 } 453 putch(cc,NO); 454 opflag=0; 455 if (getnl() == 1){ 456 unget('\n'); 457 } 458 continue; 459 case '\\': 460 putch(c,NO); 461 putch(getch(),NO); 462 continue; 463 case '?': 464 question = 1; 465 gotop(c); 466 continue; 467 case ':': 468 if ((cc = getch()) == ':') { 469 putch(c,NO); 470 putch(cc,NO); 471 continue; 472 } 473 unget(cc); 474 if (question == 1){ 475 question = 0; 476 gotop(c); 477 continue; 478 } 479 putch(c,NO); 480 if(structlev)continue; 481 if ((lptr = lookup(lastlook,p)) != 0){ 482 if (lptr->type == CASE)outs(clev->tabs - 1); 483 } 484 else { 485 lbegin = 0; 486 outs(clev->tabs); 487 } 488 getnl(); 489 OUTK; 490 continue; 491 case '/': 492 if ((cc = getch()) == '/') { 493 putch(c,NO); 494 putch(cc,NO); 495 cpp_comment(YES); 496 OUT; 497 lastlook = 0; 498 continue; 499 } 500 else if (cc != '*') { 501 unget(cc); 502 gotop(c); 503 continue; 504 } 505 putch(c,NO); 506 putch(cc,NO); 507 cc = comment(YES); 508 if(getnl() == 1){ 509 if(cc == 0){ 510 OUT; 511 } 512 else { 513 outs(0); 514 Bputc(output, '\n'); 515 lbegin = 1; 516 count = 0; 517 } 518 lastlook = 0; 519 } 520 continue; 521 case '[': 522 putch(c,NO); 523 ct = 0; 524 while((c = getch()) != ']' || ct > 0){ 525 if(c == Beof)error("]"); 526 putch(c,NO); 527 if(c == '[')ct++; 528 if(c == ']')ct--; 529 } 530 putch(c,NO); 531 continue; 532 case '#': 533 putch(c,NO); 534 while ((cc = getch()) != '\n'){ 535 if(cc == Beof)error("newline"); 536 if (cc == '\\'){ 537 putch(cc,NO); 538 cc = getch(); 539 } 540 putch(cc,NO); 541 } 542 putch(cc,NO); 543 lbegin = 0; 544 outs(clev->tabs); 545 lbegin = 1; 546 count = 0; 547 continue; 548 default: 549 if (c == ','){ 550 opflag = 1; 551 putch(c,YES); 552 if (strict){ 553 if ((cc = getch()) != ' ')unget(cc); 554 if(cc != '\n')putch(' ',YES); 555 } 556 } 557 else if(isop(c))gotop(c); 558 else { 559 if(isalnum(c) && lastlook == 0)lastlook = p; 560 if(isdigit(c)){ 561 putch(c,NO); 562 while(isdigit(c=Bgetc(input))||c == '.')putch(c,NO); 563 if(c == 'e'){ 564 putch(c,NO); 565 c = Bgetc(input); 566 putch(c, NO); 567 while(isdigit(c=Bgetc(input)))putch(c,NO); 568 } 569 Bungetc(input); 570 } 571 else putch(c,NO); 572 if(keyflag != DATADEF)opflag = 0; 573 } 574 } 575 } 576 } 577 void 578 gotif(void){ 579 outs(clev->tabs); 580 if(++clev->iflev >= IFLEVEL-1){ 581 fprint(2,"too many levels of if %d\n",clev->iflev ); 582 clev->iflev = IFLEVEL-1; 583 } 584 clev->ifc[clev->iflev] = clev->tabs; 585 clev->spdepth[clev->iflev] = clev->pdepth; 586 } 587 void 588 gotelse(void){ 589 clev->tabs = clev->ifc[clev->iflev]; 590 clev->pdepth = clev->spdepth[clev->iflev]; 591 if(--(clev->iflev) < 0)clev->iflev = 0; 592 } 593 int 594 checkif(char *pt) 595 { 596 struct keyw *lptr; 597 int cc; 598 if((lptr=lookup(pt,lastplace+1))!= 0){ 599 if(lptr->type == IF){ 600 if(strict)putch(' ',YES); 601 copy(lptr->name); 602 *pt='\0'; 603 lastplace = pt; 604 if(strict){ 605 putch(lptr->punc,NO); 606 eatallsp(); 607 } 608 clev->tabs = clev->ifc[clev->iflev]; 609 clev->pdepth = clev->spdepth[clev->iflev]; 610 keyflag = KEYWORD; 611 return(1); 612 } 613 } 614 return(0); 615 } 616 void 617 gotdo(void){ 618 if(++dolevel >= DOLEVEL-1){ 619 fprint(2,"too many levels of do %d\n",dolevel); 620 dolevel = DOLEVEL-1; 621 } 622 dotabs[dolevel] = clev->tabs; 623 docurly[dolevel] = YES; 624 } 625 void 626 resetdo(void){ 627 if(docurly[dolevel] == NO) 628 clev->pdepth = dopdepth[dolevel]; 629 if(--dolevel < 0)dolevel = 0; 630 } 631 void 632 gottype(struct keyw *lptr) 633 { 634 char *pt; 635 struct keyw *tlptr; 636 int c; 637 while(1){ 638 pt = getnext(1); 639 if((tlptr=lookup(pt,lastplace+1))!=0){ 640 putch(' ',YES); 641 copy(tlptr->name); 642 *pt='\0'; 643 lastplace = pt; 644 if(tlptr->type == STRUCT){ 645 putch(tlptr->punc,YES); 646 gotstruct(); 647 break; 648 } 649 lptr=tlptr; 650 continue; 651 } 652 else{ 653 putch(lptr->punc,NO); 654 while((c=getch())== ' ' || c == '\t'); 655 unget(c); 656 break; 657 } 658 } 659 } 660 void 661 gotstruct(void){ 662 int c; 663 int cc; 664 char *pt; 665 while((c=getch()) == ' ' || c == '\t') 666 if(!strict)putch(c,NO); 667 if(c == '{'){ 668 structlev++; 669 unget(c); 670 return; 671 } 672 if(isalpha(c)){ 673 putch(c,NO); 674 while(isalnum(c=getch()))putch(c,NO); 675 } 676 unget(c); 677 pt = getnext(1); 678 if(*pt == '{')structlev++; 679 if(strict){ 680 eatallsp(); 681 putch(' ',NO); 682 } 683 } 684 void 685 gotop(int c) 686 { 687 char optmp[OPLENGTH]; 688 char *op_ptr; 689 struct op *s_op; 690 char *a, *b; 691 op_ptr = optmp; 692 *op_ptr++ = c; 693 while (isop(( *op_ptr = getch())))op_ptr++; 694 if(!strict)unget(*op_ptr); 695 else if (*op_ptr != ' ')unget( *op_ptr); 696 *op_ptr = '\0'; 697 s_op = op; 698 b = optmp; 699 while ((a = s_op->name) != 0){ 700 op_ptr = b; 701 while ((*op_ptr == *a) && (*op_ptr != '\0')){ 702 a++; 703 op_ptr++; 704 } 705 if (*a == '\0'){ 706 keep(s_op); 707 opflag = s_op->setop; 708 if (*op_ptr != '\0'){ 709 b = op_ptr; 710 s_op = op; 711 continue; 712 } 713 else break; 714 } 715 else s_op++; 716 } 717 } 718 void 719 keep(struct op *o) 720 { 721 char *s; 722 int ok; 723 if(o->blanks == NEVER)ok = NO; 724 else ok = YES; 725 if (strict && ((o->blanks & ALWAYS) 726 || ((opflag == 0 && o->blanks & SOMETIMES) && clev->tabs != 0))) 727 putspace(' ',YES); 728 for(s=o->name; *s != '\0'; s++){ 729 if(*(s+1) == '\0')putch(*s,ok); 730 else 731 putch(*s,NO); 732 } 733 if (strict && ((o->blanks & ALWAYS) 734 || ((opflag == 0 && o->blanks & SOMETIMES) && clev->tabs != 0))) putch(' ',YES); 735 } 736 int 737 getnl(void){ 738 int ch; 739 char *savp; 740 int gotcmt; 741 gotcmt = 0; 742 savp = p; 743 while ((ch = getch()) == '\t' || ch == ' ')putch(ch,NO); 744 if (ch == '/'){ 745 if ((ch = getch()) == '*'){ 746 putch('/',NO); 747 putch('*',NO); 748 comment(NO); 749 ch = getch(); 750 gotcmt=1; 751 } 752 else if (ch == '/') { 753 putch('/',NO); 754 putch('/',NO); 755 cpp_comment(NO); 756 ch = getch(); 757 gotcmt = 1; 758 } 759 else { 760 if(inswitch)*(++lastplace) = ch; 761 else { 762 inswitch = 1; 763 *lastplace = ch; 764 } 765 unget('/'); 766 return(0); 767 } 768 } 769 if(ch == '\n'){ 770 if(gotcmt == 0)p=savp; 771 return(1); 772 } 773 unget(ch); 774 return(0); 775 } 776 void 777 ptabs(int n){ 778 int i; 779 int num; 780 if(n > maxtabs){ 781 if(!folded){ 782 Bprint(output, "/* code folded from here */\n"); 783 folded = 1; 784 } 785 num = n-maxtabs; 786 } 787 else { 788 num = n; 789 if(folded){ 790 folded = 0; 791 Bprint(output, "/* unfolding */\n"); 792 } 793 } 794 for (i = 0; i < num; i++)Bputc(output, '\t'); 795 } 796 void 797 outs(int n){ 798 if (p > string){ 799 if (lbegin){ 800 ptabs(n); 801 lbegin = 0; 802 if (split == 1){ 803 split = 0; 804 if (clev->tabs > 0)Bprint(output, "\t"); 805 } 806 } 807 *p = '\0'; 808 Bprint(output, "%s", string); 809 lastlook = p = string; 810 } 811 else { 812 if (lbegin != 0){ 813 lbegin = 0; 814 split = 0; 815 } 816 } 817 } 818 void 819 putch(char c,int ok) 820 { 821 int cc; 822 if(p < &string[LINE-1]){ 823 if(count+TABLENG*clev->tabs >= maxleng && ok && !folded){ 824 if(c != ' ')*p++ = c; 825 OUT; 826 split = 1; 827 if((cc=getch()) != '\n')unget(cc); 828 } 829 else { 830 *p++ = c; 831 count++; 832 } 833 } 834 else { 835 outs(clev->tabs); 836 *p++ = c; 837 count = 0; 838 } 839 } 840 struct keyw * 841 lookup(char *first, char *last) 842 { 843 struct keyw *ptr; 844 char *cptr, *ckey, *k; 845 846 if(first == last || first == 0)return(0); 847 cptr = first; 848 while (*cptr == ' ' || *cptr == '\t')cptr++; 849 if(cptr >= last)return(0); 850 ptr = key; 851 while ((ckey = ptr->name) != 0){ 852 for (k = cptr; (*ckey == *k && *ckey != '\0'); k++, ckey++); 853 if(*ckey=='\0' && (k==last|| (k<last && !isalnum(*k)))){ 854 opflag = 1; 855 lastlook = 0; 856 return(ptr); 857 } 858 ptr++; 859 } 860 return(0); 861 } 862 int 863 comment(int ok) 864 { 865 int ch; 866 int hitnl; 867 868 hitnl = 0; 869 while ((ch = getch()) != Beof){ 870 putch(ch, NO); 871 if (ch == '*'){ 872 gotstar: 873 if ((ch = getch()) == '/'){ 874 putch(ch,NO); 875 return(hitnl); 876 } 877 putch(ch,NO); 878 if (ch == '*')goto gotstar; 879 } 880 if (ch == '\n'){ 881 if(ok && !hitnl){ 882 outs(clev->tabs); 883 } 884 else { 885 outs(0); 886 } 887 lbegin = 1; 888 count = 0; 889 hitnl = 1; 890 } 891 } 892 return(hitnl); 893 } 894 int 895 cpp_comment(int ok) 896 { 897 int ch; 898 int hitnl; 899 900 hitnl = 0; 901 while ((ch = getch()) != -1) { 902 if (ch == '\n') { 903 if (ok && !hitnl) 904 outs(clev->tabs); 905 else 906 outs(0); 907 lbegin = 1; 908 count = 0; 909 hitnl = 1; 910 break; 911 } 912 putch(ch, NO); 913 } 914 return hitnl; 915 } 916 void 917 putspace(char ch, int ok) 918 { 919 if(p == string)putch(ch,ok); 920 else if (*(p - 1) != ch) putch(ch,ok); 921 } 922 int 923 getch(void){ 924 char c; 925 if(inswitch){ 926 if(next != '\0'){ 927 c=next; 928 next = '\0'; 929 return(c); 930 } 931 if(tptr <= lastplace){ 932 if(*tptr != '\0')return(*tptr++); 933 else if(++tptr <= lastplace)return(*tptr++); 934 } 935 inswitch=0; 936 lastplace = tptr = temp; 937 } 938 return(Bgetc(input)); 939 } 940 void 941 unget(char c) 942 { 943 if(inswitch){ 944 if(tptr != temp) 945 *(--tptr) = c; 946 else next = c; 947 } 948 else Bungetc(input); 949 } 950 char * 951 getnext(int must){ 952 int c; 953 char *beg; 954 int prect,nlct; 955 prect = nlct = 0; 956 if(tptr > lastplace){ 957 tptr = lastplace = temp; 958 err = 0; 959 inswitch = 0; 960 } 961 tp = lastplace; 962 if(inswitch && tptr <= lastplace) 963 if (isalnum(*lastplace)||ispunct(*lastplace)||isop(*lastplace))return(lastplace); 964 space: 965 while(isspace(c=Bgetc(input)))puttmp(c,1); 966 beg = tp; 967 puttmp(c,1); 968 if(c == '/'){ 969 if(puttmp(Bgetc(input),1) == '*'){ 970 cont: 971 while((c=Bgetc(input)) != '*'){ 972 puttmp(c,0); 973 if(must == 0 && c == '\n') 974 if(nlct++ > 2)goto done; 975 } 976 puttmp(c,1); 977 star: 978 if(puttmp((c=Bgetc(input)),1) == '/'){ 979 beg = tp; 980 puttmp((c=Bgetc(input)),1); 981 } 982 else if(c == '*')goto star; 983 else goto cont; 984 } 985 else goto done; 986 } 987 if(isspace(c))goto space; 988 if(c == '#' && tp > temp+1 && *(tp-2) == '\n'){ 989 if(prect++ > 2)goto done; 990 while(puttmp((c=Bgetc(input)),1) != '\n') 991 if(c == '\\')puttmp(Bgetc(input),1); 992 goto space; 993 } 994 if(isalnum(c)){ 995 while(isalnum(c = Bgetc(input)))puttmp(c,1); 996 Bungetc(input); 997 } 998 done: 999 puttmp('\0',1); 1000 lastplace = tp-1; 1001 inswitch = 1; 1002 return(beg); 1003 } 1004 void 1005 copy(char *s) 1006 { 1007 while(*s != '\0')putch(*s++,NO); 1008 } 1009 void 1010 clearif(struct indent *cl) 1011 { 1012 int i; 1013 for(i=0;i<IFLEVEL-1;i++)cl->ifc[i] = 0; 1014 } 1015 char 1016 puttmp(char c, int keep) 1017 { 1018 if(tp < &temp[TEMP-120]) 1019 *tp++ = c; 1020 else { 1021 if(keep){ 1022 if(tp >= &temp[TEMP-1]){ 1023 fprint(2,"can't look past huge comment - quiting\n"); 1024 exits("boom"); 1025 } 1026 *tp++ = c; 1027 } 1028 else if(err == 0){ 1029 err++; 1030 fprint(2,"truncating long comment\n"); 1031 } 1032 } 1033 return(c); 1034 } 1035 void 1036 error(char *s) 1037 { 1038 fprint(2,"saw EOF while looking for %s\n",s); 1039 exits("boom"); 1040 } 1041