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