1 /****************************************************************************** 2 * 3 * Module Name: asconvrt - Source conversion code 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2014, Intel Corp. 9 * All rights reserved. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions, and the following disclaimer, 16 * without modification. 17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18 * substantially similar to the "NO WARRANTY" disclaimer below 19 * ("Disclaimer") and any redistribution must be conditioned upon 20 * including a substantially similar Disclaimer requirement for further 21 * binary redistribution. 22 * 3. Neither the names of the above-listed copyright holders nor the names 23 * of any contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 26 * Alternatively, this software may be distributed under the terms of the 27 * GNU General Public License ("GPL") version 2 as published by the Free 28 * Software Foundation. 29 * 30 * NO WARRANTY 31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41 * POSSIBILITY OF SUCH DAMAGES. 42 */ 43 44 #include "acpisrc.h" 45 46 /* Local prototypes */ 47 48 char * 49 AsCheckAndSkipLiterals ( 50 char *Buffer, 51 UINT32 *TotalLines); 52 53 UINT32 54 AsCountLines ( 55 char *Buffer, 56 char *Filename); 57 58 /* Opening signature of the Intel legal header */ 59 60 char *HeaderBegin = "/******************************************************************************\n *\n * 1. Copyright Notice"; 61 62 63 /****************************************************************************** 64 * 65 * FUNCTION: AsRemoveExtraLines 66 * 67 * DESCRIPTION: Remove all extra lines at the start and end of the file. 68 * 69 ******************************************************************************/ 70 71 void 72 AsRemoveExtraLines ( 73 char *FileBuffer, 74 char *Filename) 75 { 76 char *FileEnd; 77 int Length; 78 79 80 /* Remove any extra lines at the start of the file */ 81 82 while (*FileBuffer == '\n') 83 { 84 printf ("Removing extra line at start of file: %s\n", Filename); 85 AsRemoveData (FileBuffer, FileBuffer + 1); 86 } 87 88 /* Remove any extra lines at the end of the file */ 89 90 Length = strlen (FileBuffer); 91 FileEnd = FileBuffer + (Length - 2); 92 93 while (*FileEnd == '\n') 94 { 95 printf ("Removing extra line at end of file: %s\n", Filename); 96 AsRemoveData (FileEnd, FileEnd + 1); 97 FileEnd--; 98 } 99 } 100 101 102 /****************************************************************************** 103 * 104 * FUNCTION: AsRemoveSpacesAfterPeriod 105 * 106 * DESCRIPTION: Remove an extra space after a period. 107 * 108 ******************************************************************************/ 109 110 void 111 AsRemoveSpacesAfterPeriod ( 112 char *FileBuffer, 113 char *Filename) 114 { 115 int ReplaceCount = 0; 116 char *Possible; 117 118 119 Possible = FileBuffer; 120 while (Possible) 121 { 122 Possible = strstr (Possible, ". "); 123 if (Possible) 124 { 125 if ((*(Possible -1) == '.') || 126 (*(Possible -1) == '\"') || 127 (*(Possible -1) == '\n')) 128 { 129 Possible += 3; 130 continue; 131 } 132 133 Possible = AsReplaceData (Possible, 3, ". ", 2); 134 ReplaceCount++; 135 } 136 } 137 138 if (ReplaceCount) 139 { 140 printf ("Removed %d extra blanks after a period: %s\n", 141 ReplaceCount, Filename); 142 } 143 } 144 145 146 /****************************************************************************** 147 * 148 * FUNCTION: AsMatchExactWord 149 * 150 * DESCRIPTION: Check previous and next characters for whitespace 151 * 152 ******************************************************************************/ 153 154 BOOLEAN 155 AsMatchExactWord ( 156 char *Word, 157 UINT32 WordLength) 158 { 159 char NextChar; 160 char PrevChar; 161 162 163 NextChar = Word[WordLength]; 164 PrevChar = * (Word -1); 165 166 if (isalnum ((int) NextChar) || 167 (NextChar == '_') || 168 isalnum ((int) PrevChar) || 169 (PrevChar == '_')) 170 { 171 return (FALSE); 172 } 173 174 return (TRUE); 175 } 176 177 178 /****************************************************************************** 179 * 180 * FUNCTION: AsPrint 181 * 182 * DESCRIPTION: Common formatted print 183 * 184 ******************************************************************************/ 185 186 void 187 AsPrint ( 188 char *Message, 189 UINT32 Count, 190 char *Filename) 191 { 192 193 if (Gbl_QuietMode) 194 { 195 return; 196 } 197 198 printf ("-- %4u %28.28s : %s\n", Count, Message, Filename); 199 } 200 201 202 /****************************************************************************** 203 * 204 * FUNCTION: AsCheckAndSkipLiterals 205 * 206 * DESCRIPTION: Generic routine to skip comments and quoted string literals. 207 * Keeps a line count. 208 * 209 ******************************************************************************/ 210 211 char * 212 AsCheckAndSkipLiterals ( 213 char *Buffer, 214 UINT32 *TotalLines) 215 { 216 UINT32 NewLines = 0; 217 char *SubBuffer = Buffer; 218 char *LiteralEnd; 219 220 221 /* Ignore comments */ 222 223 if ((SubBuffer[0] == '/') && 224 (SubBuffer[1] == '*')) 225 { 226 LiteralEnd = strstr (SubBuffer, "*/"); 227 SubBuffer += 2; /* Get past comment opening */ 228 229 if (!LiteralEnd) 230 { 231 return (SubBuffer); 232 } 233 234 while (SubBuffer < LiteralEnd) 235 { 236 if (*SubBuffer == '\n') 237 { 238 NewLines++; 239 } 240 241 SubBuffer++; 242 } 243 244 SubBuffer += 2; /* Get past comment close */ 245 } 246 247 /* Ignore quoted strings */ 248 249 else if (*SubBuffer == '\"') 250 { 251 SubBuffer++; 252 LiteralEnd = AsSkipPastChar (SubBuffer, '\"'); 253 if (!LiteralEnd) 254 { 255 return (SubBuffer); 256 } 257 } 258 259 if (TotalLines) 260 { 261 (*TotalLines) += NewLines; 262 } 263 return (SubBuffer); 264 } 265 266 267 /****************************************************************************** 268 * 269 * FUNCTION: AsAsCheckForBraces 270 * 271 * DESCRIPTION: Check for an open brace after each if statement 272 * 273 ******************************************************************************/ 274 275 void 276 AsCheckForBraces ( 277 char *Buffer, 278 char *Filename) 279 { 280 char *SubBuffer = Buffer; 281 char *NextBrace; 282 char *NextSemicolon; 283 char *NextIf; 284 UINT32 TotalLines = 1; 285 286 287 while (*SubBuffer) 288 { 289 290 SubBuffer = AsCheckAndSkipLiterals (SubBuffer, &TotalLines); 291 292 if (*SubBuffer == '\n') 293 { 294 TotalLines++; 295 } 296 else if (!(strncmp (" if", SubBuffer, 3))) 297 { 298 SubBuffer += 2; 299 NextBrace = strstr (SubBuffer, "{"); 300 NextSemicolon = strstr (SubBuffer, ";"); 301 NextIf = strstr (SubBuffer, " if"); 302 303 if ((!NextBrace) || 304 (NextSemicolon && (NextBrace > NextSemicolon)) || 305 (NextIf && (NextBrace > NextIf))) 306 { 307 Gbl_MissingBraces++; 308 309 if (!Gbl_QuietMode) 310 { 311 printf ("Missing braces for <if>, line %u: %s\n", TotalLines, Filename); 312 } 313 } 314 } 315 else if (!(strncmp (" else if", SubBuffer, 8))) 316 { 317 SubBuffer += 7; 318 NextBrace = strstr (SubBuffer, "{"); 319 NextSemicolon = strstr (SubBuffer, ";"); 320 NextIf = strstr (SubBuffer, " if"); 321 322 if ((!NextBrace) || 323 (NextSemicolon && (NextBrace > NextSemicolon)) || 324 (NextIf && (NextBrace > NextIf))) 325 { 326 Gbl_MissingBraces++; 327 328 if (!Gbl_QuietMode) 329 { 330 printf ("Missing braces for <if>, line %u: %s\n", TotalLines, Filename); 331 } 332 } 333 } 334 else if (!(strncmp (" else", SubBuffer, 5))) 335 { 336 SubBuffer += 4; 337 NextBrace = strstr (SubBuffer, "{"); 338 NextSemicolon = strstr (SubBuffer, ";"); 339 NextIf = strstr (SubBuffer, " if"); 340 341 if ((!NextBrace) || 342 (NextSemicolon && (NextBrace > NextSemicolon)) || 343 (NextIf && (NextBrace > NextIf))) 344 { 345 Gbl_MissingBraces++; 346 347 if (!Gbl_QuietMode) 348 { 349 printf ("Missing braces for <else>, line %u: %s\n", TotalLines, Filename); 350 } 351 } 352 } 353 354 SubBuffer++; 355 } 356 } 357 358 359 /****************************************************************************** 360 * 361 * FUNCTION: AsTrimLines 362 * 363 * DESCRIPTION: Remove extra blanks from the end of source lines. Does not 364 * check for tabs. 365 * 366 ******************************************************************************/ 367 368 void 369 AsTrimLines ( 370 char *Buffer, 371 char *Filename) 372 { 373 char *SubBuffer = Buffer; 374 char *StartWhiteSpace = NULL; 375 UINT32 SpaceCount = 0; 376 377 378 while (*SubBuffer) 379 { 380 while (*SubBuffer != '\n') 381 { 382 if (!*SubBuffer) 383 { 384 goto Exit; 385 } 386 387 if (*SubBuffer == ' ') 388 { 389 if (!StartWhiteSpace) 390 { 391 StartWhiteSpace = SubBuffer; 392 } 393 } 394 else 395 { 396 StartWhiteSpace = NULL; 397 } 398 399 SubBuffer++; 400 } 401 402 if (StartWhiteSpace) 403 { 404 SpaceCount += (SubBuffer - StartWhiteSpace); 405 406 /* Remove the spaces */ 407 408 SubBuffer = AsRemoveData (StartWhiteSpace, SubBuffer); 409 StartWhiteSpace = NULL; 410 } 411 412 SubBuffer++; 413 } 414 415 416 Exit: 417 if (SpaceCount) 418 { 419 Gbl_MadeChanges = TRUE; 420 AsPrint ("Extraneous spaces removed", SpaceCount, Filename); 421 } 422 } 423 424 425 /****************************************************************************** 426 * 427 * FUNCTION: AsTrimWhitespace 428 * 429 * DESCRIPTION: Remove "excess" blank lines - any more than 2 blank lines. 430 * this can happen during the translation when lines are removed. 431 * 432 ******************************************************************************/ 433 434 void 435 AsTrimWhitespace ( 436 char *Buffer) 437 { 438 int ReplaceCount = 1; 439 440 441 while (ReplaceCount) 442 { 443 ReplaceCount = AsReplaceString ("\n\n\n\n", "\n\n\n", REPLACE_SUBSTRINGS, Buffer); 444 } 445 } 446 447 448 /****************************************************************************** 449 * 450 * FUNCTION: AsReplaceHeader 451 * 452 * DESCRIPTION: Replace the default Intel legal header with a new header 453 * 454 ******************************************************************************/ 455 456 void 457 AsReplaceHeader ( 458 char *Buffer, 459 char *NewHeader) 460 { 461 char *SubBuffer; 462 char *TokenEnd; 463 464 465 /* Find the original header */ 466 467 SubBuffer = strstr (Buffer, HeaderBegin); 468 if (!SubBuffer) 469 { 470 return; 471 } 472 473 /* Find the end of the original header */ 474 475 TokenEnd = strstr (SubBuffer, "*/"); 476 TokenEnd = AsSkipPastChar (TokenEnd, '\n'); 477 478 /* Delete old header, insert new one */ 479 480 AsReplaceData (SubBuffer, TokenEnd - SubBuffer, NewHeader, strlen (NewHeader)); 481 } 482 483 484 /****************************************************************************** 485 * 486 * FUNCTION: AsReplaceString 487 * 488 * DESCRIPTION: Replace all instances of a target string with a replacement 489 * string. Returns count of the strings replaced. 490 * 491 ******************************************************************************/ 492 493 int 494 AsReplaceString ( 495 char *Target, 496 char *Replacement, 497 UINT8 Type, 498 char *Buffer) 499 { 500 char *SubString1; 501 char *SubString2; 502 char *SubBuffer; 503 int TargetLength; 504 int ReplacementLength; 505 int ReplaceCount = 0; 506 507 508 TargetLength = strlen (Target); 509 ReplacementLength = strlen (Replacement); 510 511 SubBuffer = Buffer; 512 SubString1 = Buffer; 513 514 while (SubString1) 515 { 516 /* Find the target string */ 517 518 SubString1 = strstr (SubBuffer, Target); 519 if (!SubString1) 520 { 521 return (ReplaceCount); 522 } 523 524 /* 525 * Check for translation escape string -- means to ignore 526 * blocks of code while replacing 527 */ 528 if (Gbl_IgnoreTranslationEscapes) 529 { 530 SubString2 = NULL; 531 } 532 else 533 { 534 SubString2 = strstr (SubBuffer, AS_START_IGNORE); 535 } 536 537 if ((SubString2) && 538 (SubString2 < SubString1)) 539 { 540 /* Find end of the escape block starting at "Substring2" */ 541 542 SubString2 = strstr (SubString2, AS_STOP_IGNORE); 543 if (!SubString2) 544 { 545 /* Didn't find terminator */ 546 547 return (ReplaceCount); 548 } 549 550 /* Move buffer to end of escape block and continue */ 551 552 SubBuffer = SubString2; 553 } 554 555 /* Do the actual replace if the target was found */ 556 557 else 558 { 559 if ((Type & REPLACE_MASK) == REPLACE_WHOLE_WORD) 560 { 561 if (!AsMatchExactWord (SubString1, TargetLength)) 562 { 563 SubBuffer = SubString1 + 1; 564 continue; 565 } 566 } 567 568 SubBuffer = AsReplaceData (SubString1, TargetLength, Replacement, ReplacementLength); 569 570 if ((Type & EXTRA_INDENT_C) && 571 (!Gbl_StructDefs)) 572 { 573 SubBuffer = AsInsertData (SubBuffer, " ", 8); 574 } 575 576 ReplaceCount++; 577 } 578 } 579 580 return (ReplaceCount); 581 } 582 583 584 /****************************************************************************** 585 * 586 * FUNCTION: AsConvertToLineFeeds 587 * 588 * DESCRIPTION: 589 * 590 ******************************************************************************/ 591 592 void 593 AsConvertToLineFeeds ( 594 char *Buffer) 595 { 596 char *SubString; 597 char *SubBuffer; 598 599 600 SubBuffer = Buffer; 601 SubString = Buffer; 602 603 while (SubString) 604 { 605 /* Find the target string */ 606 607 SubString = strstr (SubBuffer, "\r\n"); 608 if (!SubString) 609 { 610 return; 611 } 612 613 SubBuffer = AsReplaceData (SubString, 1, NULL, 0); 614 } 615 return; 616 } 617 618 619 /****************************************************************************** 620 * 621 * FUNCTION: AsInsertCarriageReturns 622 * 623 * DESCRIPTION: 624 * 625 ******************************************************************************/ 626 627 void 628 AsInsertCarriageReturns ( 629 char *Buffer) 630 { 631 char *SubString; 632 char *SubBuffer; 633 634 635 SubBuffer = Buffer; 636 SubString = Buffer; 637 638 while (SubString) 639 { 640 /* Find the target string */ 641 642 SubString = strstr (SubBuffer, "\n"); 643 if (!SubString) 644 { 645 return; 646 } 647 648 SubBuffer = AsInsertData (SubString, "\r", 1); 649 SubBuffer += 1; 650 } 651 return; 652 } 653 654 655 /****************************************************************************** 656 * 657 * FUNCTION: AsBracesOnSameLine 658 * 659 * DESCRIPTION: Move opening braces up to the same line as an if, for, else, 660 * or while statement (leave function opening brace on separate 661 * line). 662 * 663 ******************************************************************************/ 664 665 void 666 AsBracesOnSameLine ( 667 char *Buffer) 668 { 669 char *SubBuffer = Buffer; 670 char *Beginning; 671 char *StartOfThisLine; 672 char *Next; 673 BOOLEAN BlockBegin = TRUE; 674 675 676 while (*SubBuffer) 677 { 678 /* Ignore comments */ 679 680 if ((SubBuffer[0] == '/') && 681 (SubBuffer[1] == '*')) 682 { 683 SubBuffer = strstr (SubBuffer, "*/"); 684 if (!SubBuffer) 685 { 686 return; 687 } 688 689 SubBuffer += 2; 690 continue; 691 } 692 693 /* Ignore quoted strings */ 694 695 if (*SubBuffer == '\"') 696 { 697 SubBuffer++; 698 SubBuffer = AsSkipPastChar (SubBuffer, '\"'); 699 if (!SubBuffer) 700 { 701 return; 702 } 703 } 704 705 if (!strncmp ("\n}", SubBuffer, 2)) 706 { 707 /* 708 * A newline followed by a closing brace closes a function 709 * or struct or initializer block 710 */ 711 BlockBegin = TRUE; 712 } 713 714 /* 715 * Move every standalone brace up to the previous line 716 * Check for digit will ignore initializer lists surrounded by braces. 717 * This will work until we we need more complex detection. 718 */ 719 if ((*SubBuffer == '{') && !isdigit ((int) SubBuffer[1])) 720 { 721 if (BlockBegin) 722 { 723 BlockBegin = FALSE; 724 } 725 else 726 { 727 /* 728 * Backup to previous non-whitespace 729 */ 730 Beginning = SubBuffer - 1; 731 while ((*Beginning == ' ') || 732 (*Beginning == '\n')) 733 { 734 Beginning--; 735 } 736 737 StartOfThisLine = Beginning; 738 while (*StartOfThisLine != '\n') 739 { 740 StartOfThisLine--; 741 } 742 743 /* 744 * Move the brace up to the previous line, UNLESS: 745 * 746 * 1) There is a conditional compile on the line (starts with '#') 747 * 2) Previous line ends with an '=' (Start of initializer block) 748 * 3) Previous line ends with a comma (part of an init list) 749 * 4) Previous line ends with a backslash (part of a macro) 750 */ 751 if ((StartOfThisLine[1] != '#') && 752 (*Beginning != '\\') && 753 (*Beginning != '/') && 754 (*Beginning != '{') && 755 (*Beginning != '=') && 756 (*Beginning != ',')) 757 { 758 Beginning++; 759 SubBuffer++; 760 761 Gbl_MadeChanges = TRUE; 762 763 #ifdef ADD_EXTRA_WHITESPACE 764 AsReplaceData (Beginning, SubBuffer - Beginning, " {\n", 3); 765 #else 766 /* Find non-whitespace start of next line */ 767 768 Next = SubBuffer + 1; 769 while ((*Next == ' ') || 770 (*Next == '\t')) 771 { 772 Next++; 773 } 774 775 /* Find non-whitespace start of this line */ 776 777 StartOfThisLine++; 778 while ((*StartOfThisLine == ' ') || 779 (*StartOfThisLine == '\t')) 780 { 781 StartOfThisLine++; 782 } 783 784 /* 785 * Must be a single-line comment to need more whitespace 786 * Even then, we don't need more if the previous statement 787 * is an "else". 788 */ 789 if ((Next[0] == '/') && 790 (Next[1] == '*') && 791 (Next[2] != '\n') && 792 793 (!strncmp (StartOfThisLine, "else if", 7) || 794 !strncmp (StartOfThisLine, "else while", 10) || 795 strncmp (StartOfThisLine, "else", 4))) 796 { 797 AsReplaceData (Beginning, SubBuffer - Beginning, " {\n", 3); 798 } 799 else 800 { 801 AsReplaceData (Beginning, SubBuffer - Beginning, " {", 2); 802 } 803 #endif 804 } 805 } 806 } 807 808 SubBuffer++; 809 } 810 } 811 812 813 /****************************************************************************** 814 * 815 * FUNCTION: AsTabify4 816 * 817 * DESCRIPTION: Convert the text to tabbed text. Alignment of text is 818 * preserved. 819 * 820 ******************************************************************************/ 821 822 void 823 AsTabify4 ( 824 char *Buffer) 825 { 826 char *SubBuffer = Buffer; 827 char *NewSubBuffer; 828 UINT32 SpaceCount = 0; 829 UINT32 Column = 0; 830 831 832 while (*SubBuffer) 833 { 834 if (*SubBuffer == '\n') 835 { 836 Column = 0; 837 } 838 else 839 { 840 Column++; 841 } 842 843 /* Ignore comments */ 844 845 if ((SubBuffer[0] == '/') && 846 (SubBuffer[1] == '*')) 847 { 848 SubBuffer = strstr (SubBuffer, "*/"); 849 if (!SubBuffer) 850 { 851 return; 852 } 853 854 SubBuffer += 2; 855 continue; 856 } 857 858 /* Ignore quoted strings */ 859 860 if (*SubBuffer == '\"') 861 { 862 SubBuffer++; 863 SubBuffer = AsSkipPastChar (SubBuffer, '\"'); 864 if (!SubBuffer) 865 { 866 return; 867 } 868 SpaceCount = 0; 869 } 870 871 if (*SubBuffer == ' ') 872 { 873 SpaceCount++; 874 875 if (SpaceCount >= 4) 876 { 877 SpaceCount = 0; 878 879 NewSubBuffer = (SubBuffer + 1) - 4; 880 *NewSubBuffer = '\t'; 881 NewSubBuffer++; 882 883 /* Remove the spaces */ 884 885 SubBuffer = AsRemoveData (NewSubBuffer, SubBuffer + 1); 886 } 887 888 if ((Column % 4) == 0) 889 { 890 SpaceCount = 0; 891 } 892 } 893 else 894 { 895 SpaceCount = 0; 896 } 897 898 SubBuffer++; 899 } 900 } 901 902 903 /****************************************************************************** 904 * 905 * FUNCTION: AsTabify8 906 * 907 * DESCRIPTION: Convert the text to tabbed text. Alignment of text is 908 * preserved. 909 * 910 ******************************************************************************/ 911 912 void 913 AsTabify8 ( 914 char *Buffer) 915 { 916 char *SubBuffer = Buffer; 917 char *NewSubBuffer; 918 char *CommentEnd = NULL; 919 UINT32 SpaceCount = 0; 920 UINT32 Column = 0; 921 UINT32 TabCount = 0; 922 UINT32 LastLineTabCount = 0; 923 UINT32 LastLineColumnStart = 0; 924 UINT32 ThisColumnStart = 0; 925 UINT32 ThisTabCount = 0; 926 char *FirstNonBlank = NULL; 927 928 929 while (*SubBuffer) 930 { 931 if (*SubBuffer == '\n') 932 { 933 /* This is a standalone blank line */ 934 935 FirstNonBlank = NULL; 936 Column = 0; 937 SpaceCount = 0; 938 TabCount = 0; 939 SubBuffer++; 940 continue; 941 } 942 943 if (!FirstNonBlank) 944 { 945 /* Find the first non-blank character on this line */ 946 947 FirstNonBlank = SubBuffer; 948 while (*FirstNonBlank == ' ') 949 { 950 FirstNonBlank++; 951 } 952 953 /* 954 * This mechanism limits the difference in tab counts from 955 * line to line. It helps avoid the situation where a second 956 * continuation line (which was indented correctly for tabs=4) would 957 * get indented off the screen if we just blindly converted to tabs. 958 */ 959 ThisColumnStart = FirstNonBlank - SubBuffer; 960 961 if (LastLineTabCount == 0) 962 { 963 ThisTabCount = 0; 964 } 965 else if (ThisColumnStart == LastLineColumnStart) 966 { 967 ThisTabCount = LastLineTabCount -1; 968 } 969 else 970 { 971 ThisTabCount = LastLineTabCount + 1; 972 } 973 } 974 975 Column++; 976 977 /* Check if we are in a comment */ 978 979 if ((SubBuffer[0] == '*') && 980 (SubBuffer[1] == '/')) 981 { 982 SpaceCount = 0; 983 SubBuffer += 2; 984 985 if (*SubBuffer == '\n') 986 { 987 if (TabCount > 0) 988 { 989 LastLineTabCount = TabCount; 990 TabCount = 0; 991 } 992 FirstNonBlank = NULL; 993 LastLineColumnStart = ThisColumnStart; 994 SubBuffer++; 995 } 996 997 continue; 998 } 999 1000 /* Check for comment open */ 1001 1002 if ((SubBuffer[0] == '/') && 1003 (SubBuffer[1] == '*')) 1004 { 1005 /* Find the end of the comment, it must exist */ 1006 1007 CommentEnd = strstr (SubBuffer, "*/"); 1008 if (!CommentEnd) 1009 { 1010 return; 1011 } 1012 1013 /* Toss the rest of this line or single-line comment */ 1014 1015 while ((SubBuffer < CommentEnd) && 1016 (*SubBuffer != '\n')) 1017 { 1018 SubBuffer++; 1019 } 1020 1021 if (*SubBuffer == '\n') 1022 { 1023 if (TabCount > 0) 1024 { 1025 LastLineTabCount = TabCount; 1026 TabCount = 0; 1027 } 1028 FirstNonBlank = NULL; 1029 LastLineColumnStart = ThisColumnStart; 1030 } 1031 1032 SpaceCount = 0; 1033 continue; 1034 } 1035 1036 /* Ignore quoted strings */ 1037 1038 if ((!CommentEnd) && (*SubBuffer == '\"')) 1039 { 1040 SubBuffer++; 1041 SubBuffer = AsSkipPastChar (SubBuffer, '\"'); 1042 if (!SubBuffer) 1043 { 1044 return; 1045 } 1046 SpaceCount = 0; 1047 } 1048 1049 if (*SubBuffer != ' ') 1050 { 1051 /* Not a space, skip to end of line */ 1052 1053 SubBuffer = AsSkipUntilChar (SubBuffer, '\n'); 1054 if (!SubBuffer) 1055 { 1056 return; 1057 } 1058 if (TabCount > 0) 1059 { 1060 LastLineTabCount = TabCount; 1061 TabCount = 0; 1062 } 1063 1064 FirstNonBlank = NULL; 1065 LastLineColumnStart = ThisColumnStart; 1066 Column = 0; 1067 SpaceCount = 0; 1068 } 1069 else 1070 { 1071 /* Another space */ 1072 1073 SpaceCount++; 1074 1075 if (SpaceCount >= 4) 1076 { 1077 /* Replace this group of spaces with a tab character */ 1078 1079 SpaceCount = 0; 1080 1081 NewSubBuffer = SubBuffer - 3; 1082 1083 if (TabCount <= ThisTabCount ? (ThisTabCount +1) : 0) 1084 { 1085 *NewSubBuffer = '\t'; 1086 NewSubBuffer++; 1087 SubBuffer++; 1088 TabCount++; 1089 } 1090 1091 /* Remove the spaces */ 1092 1093 SubBuffer = AsRemoveData (NewSubBuffer, SubBuffer); 1094 continue; 1095 } 1096 } 1097 1098 SubBuffer++; 1099 } 1100 } 1101 1102 1103 /****************************************************************************** 1104 * 1105 * FUNCTION: AsCountLines 1106 * 1107 * DESCRIPTION: Count the number of lines in the input buffer. Also count 1108 * the number of long lines (lines longer than 80 chars). 1109 * 1110 ******************************************************************************/ 1111 1112 UINT32 1113 AsCountLines ( 1114 char *Buffer, 1115 char *Filename) 1116 { 1117 char *SubBuffer = Buffer; 1118 char *EndOfLine; 1119 UINT32 LineCount = 0; 1120 UINT32 LongLineCount = 0; 1121 1122 1123 while (*SubBuffer) 1124 { 1125 EndOfLine = AsSkipUntilChar (SubBuffer, '\n'); 1126 if (!EndOfLine) 1127 { 1128 Gbl_TotalLines += LineCount; 1129 return (LineCount); 1130 } 1131 1132 if ((EndOfLine - SubBuffer) > 80) 1133 { 1134 LongLineCount++; 1135 VERBOSE_PRINT (("long: %.80s\n", SubBuffer)); 1136 } 1137 1138 LineCount++; 1139 SubBuffer = EndOfLine + 1; 1140 } 1141 1142 if (LongLineCount) 1143 { 1144 VERBOSE_PRINT (("%u Lines longer than 80 found in %s\n", LongLineCount, Filename)); 1145 Gbl_LongLines += LongLineCount; 1146 } 1147 1148 Gbl_TotalLines += LineCount; 1149 return (LineCount); 1150 } 1151 1152 1153 /****************************************************************************** 1154 * 1155 * FUNCTION: AsCountTabs 1156 * 1157 * DESCRIPTION: Simply count the number of tabs in the input file buffer 1158 * 1159 ******************************************************************************/ 1160 1161 void 1162 AsCountTabs ( 1163 char *Buffer, 1164 char *Filename) 1165 { 1166 UINT32 i; 1167 UINT32 TabCount = 0; 1168 1169 1170 for (i = 0; Buffer[i]; i++) 1171 { 1172 if (Buffer[i] == '\t') 1173 { 1174 TabCount++; 1175 } 1176 } 1177 1178 if (TabCount) 1179 { 1180 AsPrint ("Tabs found", TabCount, Filename); 1181 Gbl_Tabs += TabCount; 1182 } 1183 1184 AsCountLines (Buffer, Filename); 1185 } 1186 1187 1188 /****************************************************************************** 1189 * 1190 * FUNCTION: AsCountNonAnsiComments 1191 * 1192 * DESCRIPTION: Count the number of "//" comments. This type of comment is 1193 * non-ANSI C. 1194 * 1195 ******************************************************************************/ 1196 1197 void 1198 AsCountNonAnsiComments ( 1199 char *Buffer, 1200 char *Filename) 1201 { 1202 char *SubBuffer = Buffer; 1203 UINT32 CommentCount = 0; 1204 1205 1206 while (SubBuffer) 1207 { 1208 SubBuffer = strstr (SubBuffer, "//"); 1209 if (SubBuffer) 1210 { 1211 CommentCount++; 1212 SubBuffer += 2; 1213 } 1214 } 1215 1216 if (CommentCount) 1217 { 1218 AsPrint ("Non-ANSI Comments found", CommentCount, Filename); 1219 Gbl_NonAnsiComments += CommentCount; 1220 } 1221 } 1222 1223 1224 /****************************************************************************** 1225 * 1226 * FUNCTION: AsCountSourceLines 1227 * 1228 * DESCRIPTION: Count the number of C source lines. Defined by 1) not a 1229 * comment, and 2) not a blank line. 1230 * 1231 ******************************************************************************/ 1232 1233 void 1234 AsCountSourceLines ( 1235 char *Buffer, 1236 char *Filename) 1237 { 1238 char *SubBuffer = Buffer; 1239 UINT32 LineCount = 0; 1240 UINT32 WhiteCount = 0; 1241 UINT32 CommentCount = 0; 1242 1243 1244 while (*SubBuffer) 1245 { 1246 /* Detect comments (// comments are not used, non-ansii) */ 1247 1248 if ((SubBuffer[0] == '/') && 1249 (SubBuffer[1] == '*')) 1250 { 1251 SubBuffer += 2; 1252 1253 /* First line of multi-line comment is often just whitespace */ 1254 1255 if (SubBuffer[0] == '\n') 1256 { 1257 WhiteCount++; 1258 SubBuffer++; 1259 } 1260 else 1261 { 1262 CommentCount++; 1263 } 1264 1265 /* Find end of comment */ 1266 1267 while (SubBuffer[0] && SubBuffer[1] && 1268 !(((SubBuffer[0] == '*') && 1269 (SubBuffer[1] == '/')))) 1270 { 1271 if (SubBuffer[0] == '\n') 1272 { 1273 CommentCount++; 1274 } 1275 1276 SubBuffer++; 1277 } 1278 } 1279 1280 /* A linefeed followed by a non-linefeed is a valid source line */ 1281 1282 else if ((SubBuffer[0] == '\n') && 1283 (SubBuffer[1] != '\n')) 1284 { 1285 LineCount++; 1286 } 1287 1288 /* Two back-to-back linefeeds indicate a whitespace line */ 1289 1290 else if ((SubBuffer[0] == '\n') && 1291 (SubBuffer[1] == '\n')) 1292 { 1293 WhiteCount++; 1294 } 1295 1296 SubBuffer++; 1297 } 1298 1299 /* Adjust comment count for legal header */ 1300 1301 if (Gbl_HeaderSize < CommentCount) 1302 { 1303 CommentCount -= Gbl_HeaderSize; 1304 Gbl_HeaderLines += Gbl_HeaderSize; 1305 } 1306 1307 Gbl_SourceLines += LineCount; 1308 Gbl_WhiteLines += WhiteCount; 1309 Gbl_CommentLines += CommentCount; 1310 1311 VERBOSE_PRINT (("%u Comment %u White %u Code %u Lines in %s\n", 1312 CommentCount, WhiteCount, LineCount, LineCount+WhiteCount+CommentCount, Filename)); 1313 } 1314 1315 1316 /****************************************************************************** 1317 * 1318 * FUNCTION: AsInsertPrefix 1319 * 1320 * DESCRIPTION: Insert struct or union prefixes 1321 * 1322 ******************************************************************************/ 1323 1324 void 1325 AsInsertPrefix ( 1326 char *Buffer, 1327 char *Keyword, 1328 UINT8 Type) 1329 { 1330 char *SubString; 1331 char *SubBuffer; 1332 char *EndKeyword; 1333 int InsertLength; 1334 char *InsertString; 1335 int TrailingSpaces; 1336 char LowerKeyword[128]; 1337 int KeywordLength; 1338 1339 1340 switch (Type) 1341 { 1342 case SRC_TYPE_STRUCT: 1343 1344 InsertString = "struct "; 1345 break; 1346 1347 case SRC_TYPE_UNION: 1348 1349 InsertString = "union "; 1350 break; 1351 1352 default: 1353 1354 return; 1355 } 1356 1357 strcpy (LowerKeyword, Keyword); 1358 AsStrlwr (LowerKeyword); 1359 1360 SubBuffer = Buffer; 1361 SubString = Buffer; 1362 InsertLength = strlen (InsertString); 1363 KeywordLength = strlen (Keyword); 1364 1365 1366 while (SubString) 1367 { 1368 /* Find an instance of the keyword */ 1369 1370 SubString = strstr (SubBuffer, LowerKeyword); 1371 if (!SubString) 1372 { 1373 return; 1374 } 1375 1376 SubBuffer = SubString; 1377 1378 /* Must be standalone word, not a substring */ 1379 1380 if (AsMatchExactWord (SubString, KeywordLength)) 1381 { 1382 /* Make sure the keyword isn't already prefixed with the insert */ 1383 1384 if (!strncmp (SubString - InsertLength, InsertString, InsertLength)) 1385 { 1386 /* Add spaces if not already at the end-of-line */ 1387 1388 if (*(SubBuffer + KeywordLength) != '\n') 1389 { 1390 /* Already present, add spaces after to align structure members */ 1391 1392 #if 0 1393 /* ONLY FOR C FILES */ 1394 AsInsertData (SubBuffer + KeywordLength, " ", 8); 1395 #endif 1396 } 1397 goto Next; 1398 } 1399 1400 /* Make sure the keyword isn't at the end of a struct/union */ 1401 /* Note: This code depends on a single space after the brace */ 1402 1403 if (*(SubString - 2) == '}') 1404 { 1405 goto Next; 1406 } 1407 1408 /* Prefix the keyword with the insert string */ 1409 1410 Gbl_MadeChanges = TRUE; 1411 1412 /* Is there room for insertion */ 1413 1414 EndKeyword = SubString + strlen (LowerKeyword); 1415 1416 TrailingSpaces = 0; 1417 while (EndKeyword[TrailingSpaces] == ' ') 1418 { 1419 TrailingSpaces++; 1420 } 1421 1422 /* 1423 * Use "if (TrailingSpaces > 1)" if we want to ignore casts 1424 */ 1425 SubBuffer = SubString + InsertLength; 1426 1427 if (TrailingSpaces > InsertLength) 1428 { 1429 /* Insert the keyword */ 1430 1431 memmove (SubBuffer, SubString, KeywordLength); 1432 1433 /* Insert the keyword */ 1434 1435 memmove (SubString, InsertString, InsertLength); 1436 } 1437 else 1438 { 1439 AsInsertData (SubString, InsertString, InsertLength); 1440 } 1441 } 1442 1443 Next: 1444 SubBuffer += KeywordLength; 1445 } 1446 } 1447 1448 #ifdef ACPI_FUTURE_IMPLEMENTATION 1449 /****************************************************************************** 1450 * 1451 * FUNCTION: AsTrimComments 1452 * 1453 * DESCRIPTION: Finds 3-line comments with only a single line of text 1454 * 1455 ******************************************************************************/ 1456 1457 void 1458 AsTrimComments ( 1459 char *Buffer, 1460 char *Filename) 1461 { 1462 char *SubBuffer = Buffer; 1463 char *Ptr1; 1464 char *Ptr2; 1465 UINT32 LineCount; 1466 UINT32 ShortCommentCount = 0; 1467 1468 1469 while (1) 1470 { 1471 /* Find comment open, within procedure level */ 1472 1473 SubBuffer = strstr (SubBuffer, " /*"); 1474 if (!SubBuffer) 1475 { 1476 goto Exit; 1477 } 1478 1479 /* Find comment terminator */ 1480 1481 Ptr1 = strstr (SubBuffer, "*/"); 1482 if (!Ptr1) 1483 { 1484 goto Exit; 1485 } 1486 1487 /* Find next EOL (from original buffer) */ 1488 1489 Ptr2 = strstr (SubBuffer, "\n"); 1490 if (!Ptr2) 1491 { 1492 goto Exit; 1493 } 1494 1495 /* Ignore one-line comments */ 1496 1497 if (Ptr1 < Ptr2) 1498 { 1499 /* Normal comment, ignore and continue; */ 1500 1501 SubBuffer = Ptr2; 1502 continue; 1503 } 1504 1505 /* Examine multi-line comment */ 1506 1507 LineCount = 1; 1508 while (Ptr1 > Ptr2) 1509 { 1510 /* Find next EOL */ 1511 1512 Ptr2++; 1513 Ptr2 = strstr (Ptr2, "\n"); 1514 if (!Ptr2) 1515 { 1516 goto Exit; 1517 } 1518 1519 LineCount++; 1520 } 1521 1522 SubBuffer = Ptr1; 1523 1524 if (LineCount <= 3) 1525 { 1526 ShortCommentCount++; 1527 } 1528 } 1529 1530 1531 Exit: 1532 1533 if (ShortCommentCount) 1534 { 1535 AsPrint ("Short Comments found", ShortCommentCount, Filename); 1536 } 1537 } 1538 #endif