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