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