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/else 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 UINT32 TotalLines = 1; 284 char *EndBuffer; 285 286 287 EndBuffer = SubBuffer + strlen (SubBuffer); 288 289 while (SubBuffer <= EndBuffer) 290 { 291 /* TBD: Update this function to work properly, as per code below */ 292 /* SubBuffer = AsCheckAndSkipLiterals (SubBuffer, &TotalLines); */ 293 294 /* Skip normal comments */ 295 296 if ((*SubBuffer == '/') && 297 (*(SubBuffer + 1) == '*')) 298 { 299 /* Must maintain line count */ 300 301 SubBuffer += 2; 302 while (strncmp ("*/", SubBuffer, 2)) 303 { 304 if (*SubBuffer == '\n') 305 { 306 TotalLines++; 307 } 308 SubBuffer++; 309 } 310 SubBuffer += 2; 311 continue; 312 } 313 314 /* Skip single quoted chars */ 315 316 if (*SubBuffer == '\'') 317 { 318 SubBuffer++; 319 if (*SubBuffer == '\\') 320 { 321 SubBuffer++; 322 } 323 SubBuffer++; 324 continue; 325 } 326 327 /* Skip quoted strings */ 328 329 if (*SubBuffer == '"') 330 { 331 SubBuffer++; 332 while (*SubBuffer != '"') 333 { 334 /* Handle escapes within the string */ 335 336 if (*SubBuffer == '\\') 337 { 338 SubBuffer++; 339 } 340 SubBuffer++; 341 } 342 343 SubBuffer++; 344 continue; 345 } 346 347 if (*SubBuffer == '\n') 348 { 349 TotalLines++; 350 } 351 else if (!(strncmp (" if", SubBuffer, 3))) 352 { 353 SubBuffer += 2; 354 355 NextBrace = strstr (SubBuffer, "{"); 356 NextSemicolon = strstr (SubBuffer, ";"); 357 358 if ((!NextBrace) || 359 (NextSemicolon && (NextBrace > NextSemicolon))) 360 { 361 Gbl_MissingBraces++; 362 363 if (!Gbl_QuietMode) 364 { 365 printf ("Missing braces for <if>, line %u: %s\n", TotalLines, Filename); 366 } 367 } 368 } 369 else if (!(strncmp (" else if", SubBuffer, 8))) 370 { 371 SubBuffer += 7; 372 373 NextBrace = strstr (SubBuffer, "{"); 374 NextSemicolon = strstr (SubBuffer, ";"); 375 376 if ((!NextBrace) || 377 (NextSemicolon && (NextBrace > NextSemicolon))) 378 { 379 Gbl_MissingBraces++; 380 381 if (!Gbl_QuietMode) 382 { 383 printf ("Missing braces for <else if>, line %u: %s\n", TotalLines, Filename); 384 } 385 } 386 } 387 else if (!(strncmp (" else", SubBuffer, 5))) 388 { 389 SubBuffer += 4; 390 NextBrace = strstr (SubBuffer, "{"); 391 NextSemicolon = strstr (SubBuffer, ";"); 392 393 if ((!NextBrace) || 394 (NextSemicolon && (NextBrace > NextSemicolon))) 395 { 396 Gbl_MissingBraces++; 397 398 if (!Gbl_QuietMode) 399 { 400 printf ("Missing braces for <else>, line %u: %s\n", TotalLines, Filename); 401 } 402 } 403 } 404 405 SubBuffer++; 406 } 407 } 408 409 410 /****************************************************************************** 411 * 412 * FUNCTION: AsTrimLines 413 * 414 * DESCRIPTION: Remove extra blanks from the end of source lines. Does not 415 * check for tabs. 416 * 417 ******************************************************************************/ 418 419 void 420 AsTrimLines ( 421 char *Buffer, 422 char *Filename) 423 { 424 char *SubBuffer = Buffer; 425 char *StartWhiteSpace = NULL; 426 UINT32 SpaceCount = 0; 427 428 429 while (*SubBuffer) 430 { 431 while (*SubBuffer != '\n') 432 { 433 if (!*SubBuffer) 434 { 435 goto Exit; 436 } 437 438 if (*SubBuffer == ' ') 439 { 440 if (!StartWhiteSpace) 441 { 442 StartWhiteSpace = SubBuffer; 443 } 444 } 445 else 446 { 447 StartWhiteSpace = NULL; 448 } 449 450 SubBuffer++; 451 } 452 453 if (StartWhiteSpace) 454 { 455 SpaceCount += (SubBuffer - StartWhiteSpace); 456 457 /* Remove the spaces */ 458 459 SubBuffer = AsRemoveData (StartWhiteSpace, SubBuffer); 460 StartWhiteSpace = NULL; 461 } 462 463 SubBuffer++; 464 } 465 466 467 Exit: 468 if (SpaceCount) 469 { 470 Gbl_MadeChanges = TRUE; 471 AsPrint ("Extraneous spaces removed", SpaceCount, Filename); 472 } 473 } 474 475 476 /****************************************************************************** 477 * 478 * FUNCTION: AsTrimWhitespace 479 * 480 * DESCRIPTION: Remove "excess" blank lines - any more than 2 blank lines. 481 * this can happen during the translation when lines are removed. 482 * 483 ******************************************************************************/ 484 485 void 486 AsTrimWhitespace ( 487 char *Buffer) 488 { 489 int ReplaceCount = 1; 490 491 492 while (ReplaceCount) 493 { 494 ReplaceCount = AsReplaceString ("\n\n\n\n", "\n\n\n", REPLACE_SUBSTRINGS, Buffer); 495 } 496 } 497 498 499 /****************************************************************************** 500 * 501 * FUNCTION: AsReplaceHeader 502 * 503 * DESCRIPTION: Replace the default Intel legal header with a new header 504 * 505 ******************************************************************************/ 506 507 void 508 AsReplaceHeader ( 509 char *Buffer, 510 char *NewHeader) 511 { 512 char *SubBuffer; 513 char *TokenEnd; 514 515 516 /* Find the original header */ 517 518 SubBuffer = strstr (Buffer, HeaderBegin); 519 if (!SubBuffer) 520 { 521 return; 522 } 523 524 /* Find the end of the original header */ 525 526 TokenEnd = strstr (SubBuffer, "*/"); 527 TokenEnd = AsSkipPastChar (TokenEnd, '\n'); 528 529 /* Delete old header, insert new one */ 530 531 AsReplaceData (SubBuffer, TokenEnd - SubBuffer, NewHeader, strlen (NewHeader)); 532 } 533 534 535 /****************************************************************************** 536 * 537 * FUNCTION: AsReplaceString 538 * 539 * DESCRIPTION: Replace all instances of a target string with a replacement 540 * string. Returns count of the strings replaced. 541 * 542 ******************************************************************************/ 543 544 int 545 AsReplaceString ( 546 char *Target, 547 char *Replacement, 548 UINT8 Type, 549 char *Buffer) 550 { 551 char *SubString1; 552 char *SubString2; 553 char *SubBuffer; 554 int TargetLength; 555 int ReplacementLength; 556 int ReplaceCount = 0; 557 558 559 TargetLength = strlen (Target); 560 ReplacementLength = strlen (Replacement); 561 562 SubBuffer = Buffer; 563 SubString1 = Buffer; 564 565 while (SubString1) 566 { 567 /* Find the target string */ 568 569 SubString1 = strstr (SubBuffer, Target); 570 if (!SubString1) 571 { 572 return (ReplaceCount); 573 } 574 575 /* 576 * Check for translation escape string -- means to ignore 577 * blocks of code while replacing 578 */ 579 if (Gbl_IgnoreTranslationEscapes) 580 { 581 SubString2 = NULL; 582 } 583 else 584 { 585 SubString2 = strstr (SubBuffer, AS_START_IGNORE); 586 } 587 588 if ((SubString2) && 589 (SubString2 < SubString1)) 590 { 591 /* Find end of the escape block starting at "Substring2" */ 592 593 SubString2 = strstr (SubString2, AS_STOP_IGNORE); 594 if (!SubString2) 595 { 596 /* Didn't find terminator */ 597 598 return (ReplaceCount); 599 } 600 601 /* Move buffer to end of escape block and continue */ 602 603 SubBuffer = SubString2; 604 } 605 606 /* Do the actual replace if the target was found */ 607 608 else 609 { 610 if ((Type & REPLACE_MASK) == REPLACE_WHOLE_WORD) 611 { 612 if (!AsMatchExactWord (SubString1, TargetLength)) 613 { 614 SubBuffer = SubString1 + 1; 615 continue; 616 } 617 } 618 619 SubBuffer = AsReplaceData (SubString1, TargetLength, Replacement, ReplacementLength); 620 621 if ((Type & EXTRA_INDENT_C) && 622 (!Gbl_StructDefs)) 623 { 624 SubBuffer = AsInsertData (SubBuffer, " ", 8); 625 } 626 627 ReplaceCount++; 628 } 629 } 630 631 return (ReplaceCount); 632 } 633 634 635 /****************************************************************************** 636 * 637 * FUNCTION: AsConvertToLineFeeds 638 * 639 * DESCRIPTION: 640 * 641 ******************************************************************************/ 642 643 void 644 AsConvertToLineFeeds ( 645 char *Buffer) 646 { 647 char *SubString; 648 char *SubBuffer; 649 650 651 SubBuffer = Buffer; 652 SubString = Buffer; 653 654 while (SubString) 655 { 656 /* Find the target string */ 657 658 SubString = strstr (SubBuffer, "\r\n"); 659 if (!SubString) 660 { 661 return; 662 } 663 664 SubBuffer = AsReplaceData (SubString, 1, NULL, 0); 665 } 666 return; 667 } 668 669 670 /****************************************************************************** 671 * 672 * FUNCTION: AsInsertCarriageReturns 673 * 674 * DESCRIPTION: 675 * 676 ******************************************************************************/ 677 678 void 679 AsInsertCarriageReturns ( 680 char *Buffer) 681 { 682 char *SubString; 683 char *SubBuffer; 684 685 686 SubBuffer = Buffer; 687 SubString = Buffer; 688 689 while (SubString) 690 { 691 /* Find the target string */ 692 693 SubString = strstr (SubBuffer, "\n"); 694 if (!SubString) 695 { 696 return; 697 } 698 699 SubBuffer = AsInsertData (SubString, "\r", 1); 700 SubBuffer += 1; 701 } 702 return; 703 } 704 705 706 /****************************************************************************** 707 * 708 * FUNCTION: AsBracesOnSameLine 709 * 710 * DESCRIPTION: Move opening braces up to the same line as an if, for, else, 711 * or while statement (leave function opening brace on separate 712 * line). 713 * 714 ******************************************************************************/ 715 716 void 717 AsBracesOnSameLine ( 718 char *Buffer) 719 { 720 char *SubBuffer = Buffer; 721 char *Beginning; 722 char *StartOfThisLine; 723 char *Next; 724 BOOLEAN BlockBegin = TRUE; 725 726 727 while (*SubBuffer) 728 { 729 /* Ignore comments */ 730 731 if ((SubBuffer[0] == '/') && 732 (SubBuffer[1] == '*')) 733 { 734 SubBuffer = strstr (SubBuffer, "*/"); 735 if (!SubBuffer) 736 { 737 return; 738 } 739 740 SubBuffer += 2; 741 continue; 742 } 743 744 /* Ignore quoted strings */ 745 746 if (*SubBuffer == '\"') 747 { 748 SubBuffer++; 749 SubBuffer = AsSkipPastChar (SubBuffer, '\"'); 750 if (!SubBuffer) 751 { 752 return; 753 } 754 } 755 756 if (!strncmp ("\n}", SubBuffer, 2)) 757 { 758 /* 759 * A newline followed by a closing brace closes a function 760 * or struct or initializer block 761 */ 762 BlockBegin = TRUE; 763 } 764 765 /* 766 * Move every standalone brace up to the previous line 767 * Check for digit will ignore initializer lists surrounded by braces. 768 * This will work until we we need more complex detection. 769 */ 770 if ((*SubBuffer == '{') && !isdigit ((int) SubBuffer[1])) 771 { 772 if (BlockBegin) 773 { 774 BlockBegin = FALSE; 775 } 776 else 777 { 778 /* 779 * Backup to previous non-whitespace 780 */ 781 Beginning = SubBuffer - 1; 782 while ((*Beginning == ' ') || 783 (*Beginning == '\n')) 784 { 785 Beginning--; 786 } 787 788 StartOfThisLine = Beginning; 789 while (*StartOfThisLine != '\n') 790 { 791 StartOfThisLine--; 792 } 793 794 /* 795 * Move the brace up to the previous line, UNLESS: 796 * 797 * 1) There is a conditional compile on the line (starts with '#') 798 * 2) Previous line ends with an '=' (Start of initializer block) 799 * 3) Previous line ends with a comma (part of an init list) 800 * 4) Previous line ends with a backslash (part of a macro) 801 */ 802 if ((StartOfThisLine[1] != '#') && 803 (*Beginning != '\\') && 804 (*Beginning != '/') && 805 (*Beginning != '{') && 806 (*Beginning != '=') && 807 (*Beginning != ',')) 808 { 809 Beginning++; 810 SubBuffer++; 811 812 Gbl_MadeChanges = TRUE; 813 814 #ifdef ADD_EXTRA_WHITESPACE 815 AsReplaceData (Beginning, SubBuffer - Beginning, " {\n", 3); 816 #else 817 /* Find non-whitespace start of next line */ 818 819 Next = SubBuffer + 1; 820 while ((*Next == ' ') || 821 (*Next == '\t')) 822 { 823 Next++; 824 } 825 826 /* Find non-whitespace start of this line */ 827 828 StartOfThisLine++; 829 while ((*StartOfThisLine == ' ') || 830 (*StartOfThisLine == '\t')) 831 { 832 StartOfThisLine++; 833 } 834 835 /* 836 * Must be a single-line comment to need more whitespace 837 * Even then, we don't need more if the previous statement 838 * is an "else". 839 */ 840 if ((Next[0] == '/') && 841 (Next[1] == '*') && 842 (Next[2] != '\n') && 843 844 (!strncmp (StartOfThisLine, "else if", 7) || 845 !strncmp (StartOfThisLine, "else while", 10) || 846 strncmp (StartOfThisLine, "else", 4))) 847 { 848 AsReplaceData (Beginning, SubBuffer - Beginning, " {\n", 3); 849 } 850 else 851 { 852 AsReplaceData (Beginning, SubBuffer - Beginning, " {", 2); 853 } 854 #endif 855 } 856 } 857 } 858 859 SubBuffer++; 860 } 861 } 862 863 864 /****************************************************************************** 865 * 866 * FUNCTION: AsTabify4 867 * 868 * DESCRIPTION: Convert the text to tabbed text. Alignment of text is 869 * preserved. 870 * 871 ******************************************************************************/ 872 873 void 874 AsTabify4 ( 875 char *Buffer) 876 { 877 char *SubBuffer = Buffer; 878 char *NewSubBuffer; 879 UINT32 SpaceCount = 0; 880 UINT32 Column = 0; 881 882 883 while (*SubBuffer) 884 { 885 if (*SubBuffer == '\n') 886 { 887 Column = 0; 888 } 889 else 890 { 891 Column++; 892 } 893 894 /* Ignore comments */ 895 896 if ((SubBuffer[0] == '/') && 897 (SubBuffer[1] == '*')) 898 { 899 SubBuffer = strstr (SubBuffer, "*/"); 900 if (!SubBuffer) 901 { 902 return; 903 } 904 905 SubBuffer += 2; 906 continue; 907 } 908 909 /* Ignore quoted strings */ 910 911 if (*SubBuffer == '\"') 912 { 913 SubBuffer++; 914 SubBuffer = AsSkipPastChar (SubBuffer, '\"'); 915 if (!SubBuffer) 916 { 917 return; 918 } 919 SpaceCount = 0; 920 } 921 922 if (*SubBuffer == ' ') 923 { 924 SpaceCount++; 925 926 if (SpaceCount >= 4) 927 { 928 SpaceCount = 0; 929 930 NewSubBuffer = (SubBuffer + 1) - 4; 931 *NewSubBuffer = '\t'; 932 NewSubBuffer++; 933 934 /* Remove the spaces */ 935 936 SubBuffer = AsRemoveData (NewSubBuffer, SubBuffer + 1); 937 } 938 939 if ((Column % 4) == 0) 940 { 941 SpaceCount = 0; 942 } 943 } 944 else 945 { 946 SpaceCount = 0; 947 } 948 949 SubBuffer++; 950 } 951 } 952 953 954 /****************************************************************************** 955 * 956 * FUNCTION: AsTabify8 957 * 958 * DESCRIPTION: Convert the text to tabbed text. Alignment of text is 959 * preserved. 960 * 961 ******************************************************************************/ 962 963 void 964 AsTabify8 ( 965 char *Buffer) 966 { 967 char *SubBuffer = Buffer; 968 char *NewSubBuffer; 969 char *CommentEnd = NULL; 970 UINT32 SpaceCount = 0; 971 UINT32 Column = 0; 972 UINT32 TabCount = 0; 973 UINT32 LastLineTabCount = 0; 974 UINT32 LastLineColumnStart = 0; 975 UINT32 ThisColumnStart = 0; 976 UINT32 ThisTabCount = 0; 977 char *FirstNonBlank = NULL; 978 979 980 while (*SubBuffer) 981 { 982 if (*SubBuffer == '\n') 983 { 984 /* This is a standalone blank line */ 985 986 FirstNonBlank = NULL; 987 Column = 0; 988 SpaceCount = 0; 989 TabCount = 0; 990 SubBuffer++; 991 continue; 992 } 993 994 if (!FirstNonBlank) 995 { 996 /* Find the first non-blank character on this line */ 997 998 FirstNonBlank = SubBuffer; 999 while (*FirstNonBlank == ' ') 1000 { 1001 FirstNonBlank++; 1002 } 1003 1004 /* 1005 * This mechanism limits the difference in tab counts from 1006 * line to line. It helps avoid the situation where a second 1007 * continuation line (which was indented correctly for tabs=4) would 1008 * get indented off the screen if we just blindly converted to tabs. 1009 */ 1010 ThisColumnStart = FirstNonBlank - SubBuffer; 1011 1012 if (LastLineTabCount == 0) 1013 { 1014 ThisTabCount = 0; 1015 } 1016 else if (ThisColumnStart == LastLineColumnStart) 1017 { 1018 ThisTabCount = LastLineTabCount -1; 1019 } 1020 else 1021 { 1022 ThisTabCount = LastLineTabCount + 1; 1023 } 1024 } 1025 1026 Column++; 1027 1028 /* Check if we are in a comment */ 1029 1030 if ((SubBuffer[0] == '*') && 1031 (SubBuffer[1] == '/')) 1032 { 1033 SpaceCount = 0; 1034 SubBuffer += 2; 1035 1036 if (*SubBuffer == '\n') 1037 { 1038 if (TabCount > 0) 1039 { 1040 LastLineTabCount = TabCount; 1041 TabCount = 0; 1042 } 1043 FirstNonBlank = NULL; 1044 LastLineColumnStart = ThisColumnStart; 1045 SubBuffer++; 1046 } 1047 1048 continue; 1049 } 1050 1051 /* Check for comment open */ 1052 1053 if ((SubBuffer[0] == '/') && 1054 (SubBuffer[1] == '*')) 1055 { 1056 /* Find the end of the comment, it must exist */ 1057 1058 CommentEnd = strstr (SubBuffer, "*/"); 1059 if (!CommentEnd) 1060 { 1061 return; 1062 } 1063 1064 /* Toss the rest of this line or single-line comment */ 1065 1066 while ((SubBuffer < CommentEnd) && 1067 (*SubBuffer != '\n')) 1068 { 1069 SubBuffer++; 1070 } 1071 1072 if (*SubBuffer == '\n') 1073 { 1074 if (TabCount > 0) 1075 { 1076 LastLineTabCount = TabCount; 1077 TabCount = 0; 1078 } 1079 FirstNonBlank = NULL; 1080 LastLineColumnStart = ThisColumnStart; 1081 } 1082 1083 SpaceCount = 0; 1084 continue; 1085 } 1086 1087 /* Ignore quoted strings */ 1088 1089 if ((!CommentEnd) && (*SubBuffer == '\"')) 1090 { 1091 SubBuffer++; 1092 SubBuffer = AsSkipPastChar (SubBuffer, '\"'); 1093 if (!SubBuffer) 1094 { 1095 return; 1096 } 1097 SpaceCount = 0; 1098 } 1099 1100 if (*SubBuffer != ' ') 1101 { 1102 /* Not a space, skip to end of line */ 1103 1104 SubBuffer = AsSkipUntilChar (SubBuffer, '\n'); 1105 if (!SubBuffer) 1106 { 1107 return; 1108 } 1109 if (TabCount > 0) 1110 { 1111 LastLineTabCount = TabCount; 1112 TabCount = 0; 1113 } 1114 1115 FirstNonBlank = NULL; 1116 LastLineColumnStart = ThisColumnStart; 1117 Column = 0; 1118 SpaceCount = 0; 1119 } 1120 else 1121 { 1122 /* Another space */ 1123 1124 SpaceCount++; 1125 1126 if (SpaceCount >= 4) 1127 { 1128 /* Replace this group of spaces with a tab character */ 1129 1130 SpaceCount = 0; 1131 1132 NewSubBuffer = SubBuffer - 3; 1133 1134 if (TabCount <= ThisTabCount ? (ThisTabCount +1) : 0) 1135 { 1136 *NewSubBuffer = '\t'; 1137 NewSubBuffer++; 1138 SubBuffer++; 1139 TabCount++; 1140 } 1141 1142 /* Remove the spaces */ 1143 1144 SubBuffer = AsRemoveData (NewSubBuffer, SubBuffer); 1145 continue; 1146 } 1147 } 1148 1149 SubBuffer++; 1150 } 1151 } 1152 1153 1154 /****************************************************************************** 1155 * 1156 * FUNCTION: AsCountLines 1157 * 1158 * DESCRIPTION: Count the number of lines in the input buffer. Also count 1159 * the number of long lines (lines longer than 80 chars). 1160 * 1161 ******************************************************************************/ 1162 1163 UINT32 1164 AsCountLines ( 1165 char *Buffer, 1166 char *Filename) 1167 { 1168 char *SubBuffer = Buffer; 1169 char *EndOfLine; 1170 UINT32 LineCount = 0; 1171 UINT32 LongLineCount = 0; 1172 1173 1174 while (*SubBuffer) 1175 { 1176 EndOfLine = AsSkipUntilChar (SubBuffer, '\n'); 1177 if (!EndOfLine) 1178 { 1179 Gbl_TotalLines += LineCount; 1180 return (LineCount); 1181 } 1182 1183 if ((EndOfLine - SubBuffer) > 80) 1184 { 1185 LongLineCount++; 1186 VERBOSE_PRINT (("long: %.80s\n", SubBuffer)); 1187 } 1188 1189 LineCount++; 1190 SubBuffer = EndOfLine + 1; 1191 } 1192 1193 if (LongLineCount) 1194 { 1195 VERBOSE_PRINT (("%u Lines longer than 80 found in %s\n", LongLineCount, Filename)); 1196 Gbl_LongLines += LongLineCount; 1197 } 1198 1199 Gbl_TotalLines += LineCount; 1200 return (LineCount); 1201 } 1202 1203 1204 /****************************************************************************** 1205 * 1206 * FUNCTION: AsCountTabs 1207 * 1208 * DESCRIPTION: Simply count the number of tabs in the input file buffer 1209 * 1210 ******************************************************************************/ 1211 1212 void 1213 AsCountTabs ( 1214 char *Buffer, 1215 char *Filename) 1216 { 1217 UINT32 i; 1218 UINT32 TabCount = 0; 1219 1220 1221 for (i = 0; Buffer[i]; i++) 1222 { 1223 if (Buffer[i] == '\t') 1224 { 1225 TabCount++; 1226 } 1227 } 1228 1229 if (TabCount) 1230 { 1231 AsPrint ("Tabs found", TabCount, Filename); 1232 Gbl_Tabs += TabCount; 1233 } 1234 1235 AsCountLines (Buffer, Filename); 1236 } 1237 1238 1239 /****************************************************************************** 1240 * 1241 * FUNCTION: AsCountNonAnsiComments 1242 * 1243 * DESCRIPTION: Count the number of "//" comments. This type of comment is 1244 * non-ANSI C. 1245 * 1246 * NOTE: July 2014: Allows // within quoted strings and within normal 1247 * comments. Eliminates extraneous warnings from this utility. 1248 * 1249 ******************************************************************************/ 1250 1251 void 1252 AsCountNonAnsiComments ( 1253 char *Buffer, 1254 char *Filename) 1255 { 1256 char *SubBuffer = Buffer; 1257 char *EndBuffer; 1258 UINT32 CommentCount = 0; 1259 char *StartBuffer; 1260 1261 1262 EndBuffer = SubBuffer + strlen (SubBuffer); 1263 1264 while (SubBuffer <= EndBuffer) 1265 { 1266 /* Skip normal comments */ 1267 1268 if ((*SubBuffer == '/') && 1269 (*(SubBuffer + 1) == '*')) 1270 { 1271 SubBuffer = strstr (SubBuffer + 2, "*/"); 1272 if (!SubBuffer) 1273 { 1274 break; 1275 } 1276 1277 SubBuffer += 2; 1278 continue; 1279 } 1280 1281 /* Skip single quoted chars */ 1282 1283 if (*SubBuffer == '\'') 1284 { 1285 SubBuffer++; 1286 if (*SubBuffer == '\\') 1287 { 1288 SubBuffer++; 1289 } 1290 SubBuffer++; 1291 continue; 1292 } 1293 1294 /* Skip quoted strings */ 1295 1296 if (*SubBuffer == '"') 1297 { 1298 StartBuffer = SubBuffer; 1299 AcpiOsPrintf ("START STRING: %.64s\n", StartBuffer); 1300 SubBuffer++; 1301 while (*SubBuffer != '"') 1302 { 1303 /* Handle escapes within the string */ 1304 1305 if (*SubBuffer == '\\') 1306 { 1307 SubBuffer++; 1308 } 1309 SubBuffer++; 1310 } 1311 1312 SubBuffer++; 1313 continue; 1314 } 1315 1316 /* Finally: check for slash-slash comment */ 1317 1318 if ((*SubBuffer == '/') && 1319 (*(SubBuffer + 1) == '/')) 1320 { 1321 CommentCount++; 1322 SubBuffer++; 1323 } 1324 1325 SubBuffer++; 1326 } 1327 1328 /* Error if any slash-slash comments found */ 1329 1330 if (CommentCount) 1331 { 1332 AsPrint ("Non-ANSI // Comments Found", CommentCount, Filename); 1333 Gbl_NonAnsiComments += CommentCount; 1334 } 1335 } 1336 1337 1338 /****************************************************************************** 1339 * 1340 * FUNCTION: AsCountSourceLines 1341 * 1342 * DESCRIPTION: Count the number of C source lines. Defined by 1) not a 1343 * comment, and 2) not a blank line. 1344 * 1345 ******************************************************************************/ 1346 1347 void 1348 AsCountSourceLines ( 1349 char *Buffer, 1350 char *Filename) 1351 { 1352 char *SubBuffer = Buffer; 1353 UINT32 LineCount = 0; 1354 UINT32 WhiteCount = 0; 1355 UINT32 CommentCount = 0; 1356 1357 1358 while (*SubBuffer) 1359 { 1360 /* Detect comments (// comments are not used, non-ansii) */ 1361 1362 if ((SubBuffer[0] == '/') && 1363 (SubBuffer[1] == '*')) 1364 { 1365 SubBuffer += 2; 1366 1367 /* First line of multi-line comment is often just whitespace */ 1368 1369 if (SubBuffer[0] == '\n') 1370 { 1371 WhiteCount++; 1372 SubBuffer++; 1373 } 1374 else 1375 { 1376 CommentCount++; 1377 } 1378 1379 /* Find end of comment */ 1380 1381 while (SubBuffer[0] && SubBuffer[1] && 1382 !(((SubBuffer[0] == '*') && 1383 (SubBuffer[1] == '/')))) 1384 { 1385 if (SubBuffer[0] == '\n') 1386 { 1387 CommentCount++; 1388 } 1389 1390 SubBuffer++; 1391 } 1392 } 1393 1394 /* A linefeed followed by a non-linefeed is a valid source line */ 1395 1396 else if ((SubBuffer[0] == '\n') && 1397 (SubBuffer[1] != '\n')) 1398 { 1399 LineCount++; 1400 } 1401 1402 /* Two back-to-back linefeeds indicate a whitespace line */ 1403 1404 else if ((SubBuffer[0] == '\n') && 1405 (SubBuffer[1] == '\n')) 1406 { 1407 WhiteCount++; 1408 } 1409 1410 SubBuffer++; 1411 } 1412 1413 /* Adjust comment count for legal header */ 1414 1415 if (Gbl_HeaderSize < CommentCount) 1416 { 1417 CommentCount -= Gbl_HeaderSize; 1418 Gbl_HeaderLines += Gbl_HeaderSize; 1419 } 1420 1421 Gbl_SourceLines += LineCount; 1422 Gbl_WhiteLines += WhiteCount; 1423 Gbl_CommentLines += CommentCount; 1424 1425 VERBOSE_PRINT (("%u Comment %u White %u Code %u Lines in %s\n", 1426 CommentCount, WhiteCount, LineCount, LineCount+WhiteCount+CommentCount, Filename)); 1427 } 1428 1429 1430 /****************************************************************************** 1431 * 1432 * FUNCTION: AsInsertPrefix 1433 * 1434 * DESCRIPTION: Insert struct or union prefixes 1435 * 1436 ******************************************************************************/ 1437 1438 void 1439 AsInsertPrefix ( 1440 char *Buffer, 1441 char *Keyword, 1442 UINT8 Type) 1443 { 1444 char *SubString; 1445 char *SubBuffer; 1446 char *EndKeyword; 1447 int InsertLength; 1448 char *InsertString; 1449 int TrailingSpaces; 1450 char LowerKeyword[128]; 1451 int KeywordLength; 1452 1453 1454 switch (Type) 1455 { 1456 case SRC_TYPE_STRUCT: 1457 1458 InsertString = "struct "; 1459 break; 1460 1461 case SRC_TYPE_UNION: 1462 1463 InsertString = "union "; 1464 break; 1465 1466 default: 1467 1468 return; 1469 } 1470 1471 strcpy (LowerKeyword, Keyword); 1472 AsStrlwr (LowerKeyword); 1473 1474 SubBuffer = Buffer; 1475 SubString = Buffer; 1476 InsertLength = strlen (InsertString); 1477 KeywordLength = strlen (Keyword); 1478 1479 1480 while (SubString) 1481 { 1482 /* Find an instance of the keyword */ 1483 1484 SubString = strstr (SubBuffer, LowerKeyword); 1485 if (!SubString) 1486 { 1487 return; 1488 } 1489 1490 SubBuffer = SubString; 1491 1492 /* Must be standalone word, not a substring */ 1493 1494 if (AsMatchExactWord (SubString, KeywordLength)) 1495 { 1496 /* Make sure the keyword isn't already prefixed with the insert */ 1497 1498 if (!strncmp (SubString - InsertLength, InsertString, InsertLength)) 1499 { 1500 /* Add spaces if not already at the end-of-line */ 1501 1502 if (*(SubBuffer + KeywordLength) != '\n') 1503 { 1504 /* Already present, add spaces after to align structure members */ 1505 1506 #if 0 1507 /* ONLY FOR C FILES */ 1508 AsInsertData (SubBuffer + KeywordLength, " ", 8); 1509 #endif 1510 } 1511 goto Next; 1512 } 1513 1514 /* Make sure the keyword isn't at the end of a struct/union */ 1515 /* Note: This code depends on a single space after the brace */ 1516 1517 if (*(SubString - 2) == '}') 1518 { 1519 goto Next; 1520 } 1521 1522 /* Prefix the keyword with the insert string */ 1523 1524 Gbl_MadeChanges = TRUE; 1525 1526 /* Is there room for insertion */ 1527 1528 EndKeyword = SubString + strlen (LowerKeyword); 1529 1530 TrailingSpaces = 0; 1531 while (EndKeyword[TrailingSpaces] == ' ') 1532 { 1533 TrailingSpaces++; 1534 } 1535 1536 /* 1537 * Use "if (TrailingSpaces > 1)" if we want to ignore casts 1538 */ 1539 SubBuffer = SubString + InsertLength; 1540 1541 if (TrailingSpaces > InsertLength) 1542 { 1543 /* Insert the keyword */ 1544 1545 memmove (SubBuffer, SubString, KeywordLength); 1546 1547 /* Insert the keyword */ 1548 1549 memmove (SubString, InsertString, InsertLength); 1550 } 1551 else 1552 { 1553 AsInsertData (SubString, InsertString, InsertLength); 1554 } 1555 } 1556 1557 Next: 1558 SubBuffer += KeywordLength; 1559 } 1560 } 1561 1562 #ifdef ACPI_FUTURE_IMPLEMENTATION 1563 /****************************************************************************** 1564 * 1565 * FUNCTION: AsTrimComments 1566 * 1567 * DESCRIPTION: Finds 3-line comments with only a single line of text 1568 * 1569 ******************************************************************************/ 1570 1571 void 1572 AsTrimComments ( 1573 char *Buffer, 1574 char *Filename) 1575 { 1576 char *SubBuffer = Buffer; 1577 char *Ptr1; 1578 char *Ptr2; 1579 UINT32 LineCount; 1580 UINT32 ShortCommentCount = 0; 1581 1582 1583 while (1) 1584 { 1585 /* Find comment open, within procedure level */ 1586 1587 SubBuffer = strstr (SubBuffer, " /*"); 1588 if (!SubBuffer) 1589 { 1590 goto Exit; 1591 } 1592 1593 /* Find comment terminator */ 1594 1595 Ptr1 = strstr (SubBuffer, "*/"); 1596 if (!Ptr1) 1597 { 1598 goto Exit; 1599 } 1600 1601 /* Find next EOL (from original buffer) */ 1602 1603 Ptr2 = strstr (SubBuffer, "\n"); 1604 if (!Ptr2) 1605 { 1606 goto Exit; 1607 } 1608 1609 /* Ignore one-line comments */ 1610 1611 if (Ptr1 < Ptr2) 1612 { 1613 /* Normal comment, ignore and continue; */ 1614 1615 SubBuffer = Ptr2; 1616 continue; 1617 } 1618 1619 /* Examine multi-line comment */ 1620 1621 LineCount = 1; 1622 while (Ptr1 > Ptr2) 1623 { 1624 /* Find next EOL */ 1625 1626 Ptr2++; 1627 Ptr2 = strstr (Ptr2, "\n"); 1628 if (!Ptr2) 1629 { 1630 goto Exit; 1631 } 1632 1633 LineCount++; 1634 } 1635 1636 SubBuffer = Ptr1; 1637 1638 if (LineCount <= 3) 1639 { 1640 ShortCommentCount++; 1641 } 1642 } 1643 1644 1645 Exit: 1646 1647 if (ShortCommentCount) 1648 { 1649 AsPrint ("Short Comments found", ShortCommentCount, Filename); 1650 } 1651 } 1652 #endif 1653