| /****************************************************************************** |
| * |
| * Module Name: asconvrt - Source conversion code |
| * |
| *****************************************************************************/ |
| |
| /* |
| * Copyright (C) 2000 - 2016, Intel Corp. |
| * All rights reserved. |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions |
| * are met: |
| * 1. Redistributions of source code must retain the above copyright |
| * notice, this list of conditions, and the following disclaimer, |
| * without modification. |
| * 2. Redistributions in binary form must reproduce at minimum a disclaimer |
| * substantially similar to the "NO WARRANTY" disclaimer below |
| * ("Disclaimer") and any redistribution must be conditioned upon |
| * including a substantially similar Disclaimer requirement for further |
| * binary redistribution. |
| * 3. Neither the names of the above-listed copyright holders nor the names |
| * of any contributors may be used to endorse or promote products derived |
| * from this software without specific prior written permission. |
| * |
| * Alternatively, this software may be distributed under the terms of the |
| * GNU General Public License ("GPL") version 2 as published by the Free |
| * Software Foundation. |
| * |
| * NO WARRANTY |
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR |
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
| * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
| * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
| * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, |
| * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING |
| * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
| * POSSIBILITY OF SUCH DAMAGES. |
| */ |
| |
| #include "acpisrc.h" |
| |
| AS_BRACE_INFO Gbl_BraceInfo[] = |
| { |
| {" if", 3}, |
| {" else if", 8}, |
| {" else while", 11}, |
| {" else", 5}, |
| {" do ", 4}, |
| {NULL, 0} |
| }; |
| |
| |
| /* Local prototypes */ |
| |
| static char * |
| AsMatchValidToken ( |
| char *Buffer, |
| char *Filename, |
| char TargetChar, |
| AS_SCAN_CALLBACK Callback); |
| |
| static char * |
| AsCheckBracesCallback ( |
| char *Buffer, |
| char *Filename, |
| UINT32 LineNumber); |
| |
| static UINT32 |
| AsCountLines ( |
| char *Buffer, |
| char *Filename); |
| |
| |
| /* Opening signature of the Intel legal header */ |
| |
| char *HeaderBegin = "/******************************************************************************\n *\n * 1. Copyright Notice"; |
| |
| UINT32 NonAnsiCommentCount; |
| |
| |
| /****************************************************************************** |
| * |
| * FUNCTION: AsCountNonAnsiComments |
| * |
| * DESCRIPTION: Count the number of "//" comments. This type of comment is |
| * non-ANSI C. |
| * |
| * NOTE: July 2014: Allows // within quoted strings and within normal |
| * comments. Eliminates extraneous warnings from this utility. |
| * |
| ******************************************************************************/ |
| |
| void |
| AsCountNonAnsiComments ( |
| char *Buffer, |
| char *Filename) |
| { |
| |
| AsMatchValidToken (Buffer, Filename, 0, NULL); |
| |
| /* Error if any slash-slash comments found */ |
| |
| if (NonAnsiCommentCount) |
| { |
| AsPrint ("Non-ANSI // Comments Found", NonAnsiCommentCount, Filename); |
| Gbl_NonAnsiComments += NonAnsiCommentCount; |
| } |
| } |
| |
| |
| /****************************************************************************** |
| * |
| * FUNCTION: AsCheckForBraces |
| * |
| * DESCRIPTION: Check for an open brace after each if/else/do (etc.) |
| * statement |
| * |
| ******************************************************************************/ |
| |
| void |
| AsCheckForBraces ( |
| char *Buffer, |
| char *Filename) |
| { |
| |
| AsMatchValidToken (Buffer, Filename, 0, AsCheckBracesCallback); |
| } |
| |
| |
| /****************************************************************************** |
| * |
| * FUNCTION: AsCheckBracesCallback |
| * |
| * DESCRIPTION: Check if/else/do statements. Ensure that braces |
| * are always used. |
| * |
| * TBD: Currently, don't check while() statements. The problem is that there |
| * are two forms: do {} while (); and while () {}. |
| * |
| ******************************************************************************/ |
| |
| static char * |
| AsCheckBracesCallback ( |
| char *Buffer, |
| char *Filename, |
| UINT32 LineNumber) |
| { |
| char *SubBuffer = Buffer; |
| char *NextBrace; |
| char *NextSemicolon; |
| AS_BRACE_INFO *BraceInfo; |
| |
| |
| for (BraceInfo = Gbl_BraceInfo; BraceInfo->Operator; BraceInfo++) |
| { |
| if (!(strncmp (BraceInfo->Operator, SubBuffer, BraceInfo->Length))) |
| { |
| SubBuffer += (BraceInfo->Length - 1); |
| |
| /* Find next brace and the next semicolon */ |
| |
| NextBrace = AsMatchValidToken (SubBuffer, Filename, '{', NULL); |
| NextSemicolon = AsMatchValidToken (SubBuffer, Filename, ';', NULL); |
| |
| /* Next brace should appear before next semicolon */ |
| |
| if ((!NextBrace) || |
| (NextSemicolon && (NextBrace > NextSemicolon))) |
| { |
| Gbl_MissingBraces++; |
| |
| if (!Gbl_QuietMode) |
| { |
| printf ("Missing braces for <%s>, line %u: %s\n", |
| BraceInfo->Operator + 1, LineNumber, Filename); |
| } |
| } |
| |
| return (SubBuffer); |
| } |
| } |
| |
| /* No match, just return original buffer */ |
| |
| return (Buffer); |
| } |
| |
| |
| /****************************************************************************** |
| * |
| * FUNCTION: AsMatchValidToken |
| * |
| * DESCRIPTION: Find the next matching token in the input buffer. |
| * |
| ******************************************************************************/ |
| |
| static char * |
| AsMatchValidToken ( |
| char *Buffer, |
| char *Filename, |
| char TargetChar, |
| AS_SCAN_CALLBACK Callback) |
| { |
| char *SubBuffer = Buffer; |
| char *StringStart; |
| UINT32 TotalLines; |
| |
| |
| TotalLines = 1; |
| NonAnsiCommentCount = 0; |
| |
| /* Scan from current position up to the end if necessary */ |
| |
| while (*SubBuffer) |
| { |
| /* Skip normal comments */ |
| |
| if ((*SubBuffer == '/') && |
| (*(SubBuffer + 1) == '*')) |
| { |
| /* Must maintain line count */ |
| |
| SubBuffer += 2; |
| while (strncmp ("*/", SubBuffer, 2)) |
| { |
| if (*SubBuffer == '\n') |
| { |
| TotalLines++; |
| } |
| SubBuffer++; |
| } |
| |
| SubBuffer += 2; |
| continue; |
| } |
| |
| /* Skip single quoted chars */ |
| |
| if (*SubBuffer == '\'') |
| { |
| SubBuffer++; |
| if (!(*SubBuffer)) |
| { |
| break; |
| } |
| |
| if (*SubBuffer == '\\') |
| { |
| SubBuffer++; |
| } |
| |
| SubBuffer++; |
| continue; |
| } |
| |
| /* Skip quoted strings */ |
| |
| if (*SubBuffer == '"') |
| { |
| StringStart = SubBuffer; |
| SubBuffer++; |
| if (!(*SubBuffer)) |
| { |
| break; |
| } |
| |
| while (*SubBuffer != '"') |
| { |
| if ((*SubBuffer == '\n') || |
| (!(*SubBuffer))) |
| { |
| AsPrint ("Unbalanced quoted string",1, Filename); |
| printf (" %.32s (line %u)\n", StringStart, TotalLines); |
| break; |
| } |
| |
| /* Handle escapes within the string */ |
| |
| if (*SubBuffer == '\\') |
| { |
| SubBuffer++; |
| } |
| |
| SubBuffer++; |
| } |
| |
| SubBuffer++; |
| continue; |
| } |
| |
| /* Now we can check for a slash-slash comment */ |
| |
| if ((*SubBuffer == '/') && |
| (*(SubBuffer + 1) == '/')) |
| { |
| NonAnsiCommentCount++; |
| |
| /* Skip to end-of-line */ |
| |
| while ((*SubBuffer != '\n') && |
| (*SubBuffer)) |
| { |
| SubBuffer++; |
| } |
| |
| if (!(*SubBuffer)) |
| { |
| break; |
| } |
| |
| if (*SubBuffer == '\n') |
| { |
| TotalLines++; |
| } |
| |
| SubBuffer++; |
| continue; |
| } |
| |
| /* Finally, check for a newline */ |
| |
| if (*SubBuffer == '\n') |
| { |
| TotalLines++; |
| SubBuffer++; |
| continue; |
| } |
| |
| /* Normal character, do the user actions */ |
| |
| if (Callback) |
| { |
| SubBuffer = Callback (SubBuffer, Filename, TotalLines); |
| } |
| |
| if (TargetChar && (*SubBuffer == TargetChar)) |
| { |
| return (SubBuffer); |
| } |
| |
| SubBuffer++; |
| } |
| |
| return (NULL); |
| } |
| |
| |
| /****************************************************************************** |
| * |
| * FUNCTION: AsRemoveExtraLines |
| * |
| * DESCRIPTION: Remove all extra lines at the start and end of the file. |
| * |
| ******************************************************************************/ |
| |
| void |
| AsRemoveExtraLines ( |
| char *FileBuffer, |
| char *Filename) |
| { |
| char *FileEnd; |
| int Length; |
| |
| |
| /* Remove any extra lines at the start of the file */ |
| |
| while (*FileBuffer == '\n') |
| { |
| printf ("Removing extra line at start of file: %s\n", Filename); |
| AsRemoveData (FileBuffer, FileBuffer + 1); |
| } |
| |
| /* Remove any extra lines at the end of the file */ |
| |
| Length = strlen (FileBuffer); |
| FileEnd = FileBuffer + (Length - 2); |
| |
| while (*FileEnd == '\n') |
| { |
| printf ("Removing extra line at end of file: %s\n", Filename); |
| AsRemoveData (FileEnd, FileEnd + 1); |
| FileEnd--; |
| } |
| } |
| |
| |
| /****************************************************************************** |
| * |
| * FUNCTION: AsRemoveSpacesAfterPeriod |
| * |
| * DESCRIPTION: Remove an extra space after a period. |
| * |
| ******************************************************************************/ |
| |
| void |
| AsRemoveSpacesAfterPeriod ( |
| char *FileBuffer, |
| char *Filename) |
| { |
| int ReplaceCount = 0; |
| char *Possible; |
| |
| |
| Possible = FileBuffer; |
| while (Possible) |
| { |
| Possible = strstr (Possible, ". "); |
| if (Possible) |
| { |
| if ((*(Possible -1) == '.') || |
| (*(Possible -1) == '\"') || |
| (*(Possible -1) == '\n')) |
| { |
| Possible += 3; |
| continue; |
| } |
| |
| Possible = AsReplaceData (Possible, 3, ". ", 2); |
| ReplaceCount++; |
| } |
| } |
| |
| if (ReplaceCount) |
| { |
| printf ("Removed %d extra blanks after a period: %s\n", |
| ReplaceCount, Filename); |
| } |
| } |
| |
| |
| /****************************************************************************** |
| * |
| * FUNCTION: AsMatchExactWord |
| * |
| * DESCRIPTION: Check previous and next characters for whitespace |
| * |
| ******************************************************************************/ |
| |
| BOOLEAN |
| AsMatchExactWord ( |
| char *Word, |
| UINT32 WordLength) |
| { |
| char NextChar; |
| char PrevChar; |
| |
| |
| NextChar = Word[WordLength]; |
| PrevChar = * (Word -1); |
| |
| if (isalnum ((int) NextChar) || |
| (NextChar == '_') || |
| isalnum ((int) PrevChar) || |
| (PrevChar == '_')) |
| { |
| return (FALSE); |
| } |
| |
| return (TRUE); |
| } |
| |
| |
| /****************************************************************************** |
| * |
| * FUNCTION: AsPrint |
| * |
| * DESCRIPTION: Common formatted print |
| * |
| ******************************************************************************/ |
| |
| void |
| AsPrint ( |
| char *Message, |
| UINT32 Count, |
| char *Filename) |
| { |
| |
| if (Gbl_QuietMode) |
| { |
| return; |
| } |
| |
| printf ("-- %4u %28.28s : %s\n", Count, Message, Filename); |
| } |
| |
| |
| /****************************************************************************** |
| * |
| * FUNCTION: AsTrimLines |
| * |
| * DESCRIPTION: Remove extra blanks from the end of source lines. Does not |
| * check for tabs. |
| * |
| ******************************************************************************/ |
| |
| void |
| AsTrimLines ( |
| char *Buffer, |
| char *Filename) |
| { |
| char *SubBuffer = Buffer; |
| char *StartWhiteSpace = NULL; |
| UINT32 SpaceCount = 0; |
| |
| |
| while (*SubBuffer) |
| { |
| while (*SubBuffer != '\n') |
| { |
| if (!*SubBuffer) |
| { |
| goto Exit; |
| } |
| |
| if (*SubBuffer == ' ') |
| { |
| if (!StartWhiteSpace) |
| { |
| StartWhiteSpace = SubBuffer; |
| } |
| } |
| else |
| { |
| StartWhiteSpace = NULL; |
| } |
| |
| SubBuffer++; |
| } |
| |
| if (StartWhiteSpace) |
| { |
| SpaceCount += (SubBuffer - StartWhiteSpace); |
| |
| /* Remove the spaces */ |
| |
| SubBuffer = AsRemoveData (StartWhiteSpace, SubBuffer); |
| StartWhiteSpace = NULL; |
| } |
| |
| SubBuffer++; |
| } |
| |
| |
| Exit: |
| if (SpaceCount) |
| { |
| Gbl_MadeChanges = TRUE; |
| AsPrint ("Extraneous spaces removed", SpaceCount, Filename); |
| } |
| } |
| |
| |
| /****************************************************************************** |
| * |
| * FUNCTION: AsTrimWhitespace |
| * |
| * DESCRIPTION: Remove "excess" blank lines - any more than 2 blank lines. |
| * this can happen during the translation when lines are removed. |
| * |
| ******************************************************************************/ |
| |
| void |
| AsTrimWhitespace ( |
| char *Buffer) |
| { |
| char *SubBuffer; |
| int ReplaceCount = 1; |
| |
| |
| while (ReplaceCount) |
| { |
| ReplaceCount = AsReplaceString ("\n\n\n\n", "\n\n\n", |
| REPLACE_SUBSTRINGS, Buffer); |
| } |
| |
| /* |
| * Check for exactly one blank line after the copyright header |
| */ |
| |
| /* Find the header */ |
| |
| SubBuffer = strstr (Buffer, HeaderBegin); |
| if (!SubBuffer) |
| { |
| return; |
| } |
| |
| /* Find the end of the header */ |
| |
| SubBuffer = strstr (SubBuffer, "*/"); |
| SubBuffer = AsSkipPastChar (SubBuffer, '\n'); |
| |
| /* Replace a double blank line with a single */ |
| |
| if (!strncmp (SubBuffer, "\n\n", 2)) |
| { |
| AsReplaceData (SubBuffer, 2, "\n", 1); |
| AcpiOsPrintf ("Found multiple blank lines after copyright\n"); |
| } |
| |
| /* If no blank line after header, insert one */ |
| |
| else if (*SubBuffer != '\n') |
| { |
| AsInsertData (SubBuffer, "\n", 1); |
| AcpiOsPrintf ("Inserted blank line after copyright\n"); |
| } |
| } |
| |
| |
| /****************************************************************************** |
| * |
| * FUNCTION: AsReplaceHeader |
| * |
| * DESCRIPTION: Replace the default Intel legal header with a new header |
| * |
| ******************************************************************************/ |
| |
| void |
| AsReplaceHeader ( |
| char *Buffer, |
| char *NewHeader) |
| { |
| char *SubBuffer; |
| char *TokenEnd; |
| |
| |
| /* Find the original header */ |
| |
| SubBuffer = strstr (Buffer, HeaderBegin); |
| if (!SubBuffer) |
| { |
| return; |
| } |
| |
| /* Find the end of the original header */ |
| |
| TokenEnd = strstr (SubBuffer, "*/"); |
| TokenEnd = AsSkipPastChar (TokenEnd, '\n'); |
| |
| /* Delete old header, insert new one */ |
| |
| AsReplaceData (SubBuffer, TokenEnd - SubBuffer, |
| NewHeader, strlen (NewHeader)); |
| } |
| |
| |
| /****************************************************************************** |
| * |
| * FUNCTION: AsReplaceString |
| * |
| * DESCRIPTION: Replace all instances of a target string with a replacement |
| * string. Returns count of the strings replaced. |
| * |
| ******************************************************************************/ |
| |
| int |
| AsReplaceString ( |
| char *Target, |
| char *Replacement, |
| UINT8 Type, |
| char *Buffer) |
| { |
| char *SubString1; |
| char *SubString2; |
| char *SubBuffer; |
| int TargetLength; |
| int ReplacementLength; |
| int ReplaceCount = 0; |
| |
| |
| TargetLength = strlen (Target); |
| ReplacementLength = strlen (Replacement); |
| |
| SubBuffer = Buffer; |
| SubString1 = Buffer; |
| |
| while (SubString1) |
| { |
| /* Find the target string */ |
| |
| SubString1 = strstr (SubBuffer, Target); |
| if (!SubString1) |
| { |
| return (ReplaceCount); |
| } |
| |
| /* |
| * Check for translation escape string -- means to ignore |
| * blocks of code while replacing |
| */ |
| if (Gbl_IgnoreTranslationEscapes) |
| { |
| SubString2 = NULL; |
| } |
| else |
| { |
| SubString2 = strstr (SubBuffer, AS_START_IGNORE); |
| } |
| |
| if ((SubString2) && |
| (SubString2 < SubString1)) |
| { |
| /* Find end of the escape block starting at "Substring2" */ |
| |
| SubString2 = strstr (SubString2, AS_STOP_IGNORE); |
| if (!SubString2) |
| { |
| /* Didn't find terminator */ |
| |
| return (ReplaceCount); |
| } |
| |
| /* Move buffer to end of escape block and continue */ |
| |
| SubBuffer = SubString2; |
| } |
| |
| /* Do the actual replace if the target was found */ |
| |
| else |
| { |
| if ((Type & REPLACE_MASK) == REPLACE_WHOLE_WORD) |
| { |
| if (!AsMatchExactWord (SubString1, TargetLength)) |
| { |
| SubBuffer = SubString1 + 1; |
| continue; |
| } |
| } |
| |
| SubBuffer = AsReplaceData (SubString1, TargetLength, |
| Replacement, ReplacementLength); |
| |
| if ((Type & EXTRA_INDENT_C) && |
| (!Gbl_StructDefs)) |
| { |
| SubBuffer = AsInsertData (SubBuffer, " ", 8); |
| } |
| |
| ReplaceCount++; |
| } |
| } |
| |
| return (ReplaceCount); |
| } |
| |
| |
| /****************************************************************************** |
| * |
| * FUNCTION: AsConvertToLineFeeds |
| * |
| * DESCRIPTION: Convert all CR/LF pairs to LF only. |
| * |
| ******************************************************************************/ |
| |
| void |
| AsConvertToLineFeeds ( |
| char *Buffer) |
| { |
| char *SubString; |
| char *SubBuffer; |
| |
| |
| SubBuffer = Buffer; |
| SubString = Buffer; |
| |
| while (SubString) |
| { |
| /* Find the target string */ |
| |
| SubString = strstr (SubBuffer, "\r\n"); |
| if (!SubString) |
| { |
| return; |
| } |
| |
| SubBuffer = AsReplaceData (SubString, 1, NULL, 0); |
| } |
| } |
| |
| |
| /****************************************************************************** |
| * |
| * FUNCTION: AsInsertCarriageReturns |
| * |
| * DESCRIPTION: Convert lone LFs to CR/LF pairs. |
| * |
| ******************************************************************************/ |
| |
| void |
| AsInsertCarriageReturns ( |
| char *Buffer) |
| { |
| char *SubString; |
| char *SubBuffer; |
| |
| |
| SubBuffer = Buffer; |
| SubString = Buffer; |
| |
| while (SubString) |
| { |
| /* Find the target string */ |
| |
| SubString = strstr (SubBuffer, "\n"); |
| if (!SubString) |
| { |
| return; |
| } |
| |
| SubBuffer = AsInsertData (SubString, "\r", 1); |
| SubBuffer += 1; |
| } |
| } |
| |
| |
| /****************************************************************************** |
| * |
| * FUNCTION: AsBracesOnSameLine |
| * |
| * DESCRIPTION: Move opening braces up to the same line as an if, for, else, |
| * or while statement (leave function opening brace on separate |
| * line). |
| * |
| ******************************************************************************/ |
| |
| void |
| AsBracesOnSameLine ( |
| char *Buffer) |
| { |
| char *SubBuffer = Buffer; |
| char *Beginning; |
| char *StartOfThisLine; |
| char *Next; |
| BOOLEAN BlockBegin = TRUE; |
| |
| |
| while (*SubBuffer) |
| { |
| /* Ignore comments */ |
| |
| if ((SubBuffer[0] == '/') && |
| (SubBuffer[1] == '*')) |
| { |
| SubBuffer = strstr (SubBuffer, "*/"); |
| if (!SubBuffer) |
| { |
| return; |
| } |
| |
| SubBuffer += 2; |
| continue; |
| } |
| |
| /* Ignore quoted strings */ |
| |
| if (*SubBuffer == '\"') |
| { |
| SubBuffer++; |
| SubBuffer = AsSkipPastChar (SubBuffer, '\"'); |
| if (!SubBuffer) |
| { |
| return; |
| } |
| } |
| |
| if (!strncmp ("\n}", SubBuffer, 2)) |
| { |
| /* |
| * A newline followed by a closing brace closes a function |
| * or struct or initializer block |
| */ |
| BlockBegin = TRUE; |
| } |
| |
| /* |
| * Move every standalone brace up to the previous line |
| * Check for digit will ignore initializer lists surrounded by braces. |
| * This will work until we we need more complex detection. |
| */ |
| if ((*SubBuffer == '{') && !isdigit ((int) SubBuffer[1])) |
| { |
| if (BlockBegin) |
| { |
| BlockBegin = FALSE; |
| } |
| else |
| { |
| /* |
| * Backup to previous non-whitespace |
| */ |
| Beginning = SubBuffer - 1; |
| while ((*Beginning == ' ') || |
| (*Beginning == '\n')) |
| { |
| Beginning--; |
| } |
| |
| StartOfThisLine = Beginning; |
| while (*StartOfThisLine != '\n') |
| { |
| StartOfThisLine--; |
| } |
| |
| /* |
| * Move the brace up to the previous line, UNLESS: |
| * |
| * 1) There is a conditional compile on the line (starts with '#') |
| * 2) Previous line ends with an '=' (Start of initializer block) |
| * 3) Previous line ends with a comma (part of an init list) |
| * 4) Previous line ends with a backslash (part of a macro) |
| */ |
| if ((StartOfThisLine[1] != '#') && |
| (*Beginning != '\\') && |
| (*Beginning != '/') && |
| (*Beginning != '{') && |
| (*Beginning != '=') && |
| (*Beginning != ',')) |
| { |
| Beginning++; |
| SubBuffer++; |
| |
| Gbl_MadeChanges = TRUE; |
| |
| #ifdef ADD_EXTRA_WHITESPACE |
| AsReplaceData (Beginning, SubBuffer - Beginning, " {\n", 3); |
| #else |
| /* Find non-whitespace start of next line */ |
| |
| Next = SubBuffer + 1; |
| while ((*Next == ' ') || |
| (*Next == '\t')) |
| { |
| Next++; |
| } |
| |
| /* Find non-whitespace start of this line */ |
| |
| StartOfThisLine++; |
| while ((*StartOfThisLine == ' ') || |
| (*StartOfThisLine == '\t')) |
| { |
| StartOfThisLine++; |
| } |
| |
| /* |
| * Must be a single-line comment to need more whitespace |
| * Even then, we don't need more if the previous statement |
| * is an "else". |
| */ |
| if ((Next[0] == '/') && |
| (Next[1] == '*') && |
| (Next[2] != '\n') && |
| |
| (!strncmp (StartOfThisLine, "else if", 7) || |
| !strncmp (StartOfThisLine, "else while", 10) || |
| strncmp (StartOfThisLine, "else", 4))) |
| { |
| AsReplaceData (Beginning, SubBuffer - Beginning, " {\n", 3); |
| } |
| else |
| { |
| AsReplaceData (Beginning, SubBuffer - Beginning, " {", 2); |
| } |
| #endif |
| } |
| } |
| } |
| |
| SubBuffer++; |
| } |
| } |
| |
| |
| /****************************************************************************** |
| * |
| * FUNCTION: AsTabify4 |
| * |
| * DESCRIPTION: Convert the text to tabbed text. Alignment of text is |
| * preserved. |
| * |
| ******************************************************************************/ |
| |
| void |
| AsTabify4 ( |
| char *Buffer) |
| { |
| char *SubBuffer = Buffer; |
| char *NewSubBuffer; |
| UINT32 SpaceCount = 0; |
| UINT32 Column = 0; |
| |
| |
| while (*SubBuffer) |
| { |
| if (*SubBuffer == '\n') |
| { |
| Column = 0; |
| } |
| else |
| { |
| Column++; |
| } |
| |
| /* Ignore comments */ |
| |
| if ((SubBuffer[0] == '/') && |
| (SubBuffer[1] == '*')) |
| { |
| SubBuffer = strstr (SubBuffer, "*/"); |
| if (!SubBuffer) |
| { |
| return; |
| } |
| |
| SubBuffer += 2; |
| continue; |
| } |
| |
| /* Ignore quoted strings */ |
| |
| if (*SubBuffer == '\"') |
| { |
| SubBuffer++; |
| SubBuffer = AsSkipPastChar (SubBuffer, '\"'); |
| if (!SubBuffer) |
| { |
| return; |
| } |
| SpaceCount = 0; |
| } |
| |
| if (*SubBuffer == ' ') |
| { |
| SpaceCount++; |
| |
| if (SpaceCount >= 4) |
| { |
| SpaceCount = 0; |
| |
| NewSubBuffer = (SubBuffer + 1) - 4; |
| *NewSubBuffer = '\t'; |
| NewSubBuffer++; |
| |
| /* Remove the spaces */ |
| |
| SubBuffer = AsRemoveData (NewSubBuffer, SubBuffer + 1); |
| } |
| |
| if ((Column % 4) == 0) |
| { |
| SpaceCount = 0; |
| } |
| } |
| else |
| { |
| SpaceCount = 0; |
| } |
| |
| SubBuffer++; |
| } |
| } |
| |
| |
| /****************************************************************************** |
| * |
| * FUNCTION: AsTabify8 |
| * |
| * DESCRIPTION: Convert the text to tabbed text. Alignment of text is |
| * preserved. |
| * |
| ******************************************************************************/ |
| |
| void |
| AsTabify8 ( |
| char *Buffer) |
| { |
| char *SubBuffer = Buffer; |
| char *NewSubBuffer; |
| char *CommentEnd = NULL; |
| UINT32 SpaceCount = 0; |
| UINT32 Column = 0; |
| UINT32 TabCount = 0; |
| UINT32 LastLineTabCount = 0; |
| UINT32 LastLineColumnStart = 0; |
| UINT32 ThisColumnStart = 0; |
| UINT32 ThisTabCount = 0; |
| char *FirstNonBlank = NULL; |
| |
| |
| while (*SubBuffer) |
| { |
| if (*SubBuffer == '\n') |
| { |
| /* This is a standalone blank line */ |
| |
| FirstNonBlank = NULL; |
| Column = 0; |
| SpaceCount = 0; |
| TabCount = 0; |
| SubBuffer++; |
| continue; |
| } |
| |
| if (!FirstNonBlank) |
| { |
| /* Find the first non-blank character on this line */ |
| |
| FirstNonBlank = SubBuffer; |
| while (*FirstNonBlank == ' ') |
| { |
| FirstNonBlank++; |
| } |
| |
| /* |
| * This mechanism limits the difference in tab counts from |
| * line to line. It helps avoid the situation where a second |
| * continuation line (which was indented correctly for tabs=4) would |
| * get indented off the screen if we just blindly converted to tabs. |
| */ |
| ThisColumnStart = FirstNonBlank - SubBuffer; |
| |
| if (LastLineTabCount == 0) |
| { |
| ThisTabCount = 0; |
| } |
| else if (ThisColumnStart == LastLineColumnStart) |
| { |
| ThisTabCount = LastLineTabCount -1; |
| } |
| else |
| { |
| ThisTabCount = LastLineTabCount + 1; |
| } |
| } |
| |
| Column++; |
| |
| /* Check if we are in a comment */ |
| |
| if ((SubBuffer[0] == '*') && |
| (SubBuffer[1] == '/')) |
| { |
| SpaceCount = 0; |
| SubBuffer += 2; |
| |
| if (*SubBuffer == '\n') |
| { |
| if (TabCount > 0) |
| { |
| LastLineTabCount = TabCount; |
| TabCount = 0; |
| } |
| |
| FirstNonBlank = NULL; |
| LastLineColumnStart = ThisColumnStart; |
| SubBuffer++; |
| } |
| |
| continue; |
| } |
| |
| /* Check for comment open */ |
| |
| if ((SubBuffer[0] == '/') && |
| (SubBuffer[1] == '*')) |
| { |
| /* Find the end of the comment, it must exist */ |
| |
| CommentEnd = strstr (SubBuffer, "*/"); |
| if (!CommentEnd) |
| { |
| return; |
| } |
| |
| /* Toss the rest of this line or single-line comment */ |
| |
| while ((SubBuffer < CommentEnd) && |
| (*SubBuffer != '\n')) |
| { |
| SubBuffer++; |
| } |
| |
| if (*SubBuffer == '\n') |
| { |
| if (TabCount > 0) |
| { |
| LastLineTabCount = TabCount; |
| TabCount = 0; |
| } |
| |
| FirstNonBlank = NULL; |
| LastLineColumnStart = ThisColumnStart; |
| } |
| |
| SpaceCount = 0; |
| continue; |
| } |
| |
| /* Ignore quoted strings */ |
| |
| if ((!CommentEnd) && (*SubBuffer == '\"')) |
| { |
| SubBuffer++; |
| SubBuffer = AsSkipPastChar (SubBuffer, '\"'); |
| if (!SubBuffer) |
| { |
| return; |
| } |
| |
| SpaceCount = 0; |
| } |
| |
| if (*SubBuffer != ' ') |
| { |
| /* Not a space, skip to end of line */ |
| |
| SubBuffer = AsSkipUntilChar (SubBuffer, '\n'); |
| if (!SubBuffer) |
| { |
| return; |
| } |
| if (TabCount > 0) |
| { |
| LastLineTabCount = TabCount; |
| TabCount = 0; |
| } |
| |
| FirstNonBlank = NULL; |
| LastLineColumnStart = ThisColumnStart; |
| Column = 0; |
| SpaceCount = 0; |
| } |
| else |
| { |
| /* Another space */ |
| |
| SpaceCount++; |
| |
| if (SpaceCount >= 4) |
| { |
| /* Replace this group of spaces with a tab character */ |
| |
| SpaceCount = 0; |
| |
| NewSubBuffer = SubBuffer - 3; |
| |
| if (TabCount <= ThisTabCount ? (ThisTabCount +1) : 0) |
| { |
| *NewSubBuffer = '\t'; |
| NewSubBuffer++; |
| SubBuffer++; |
| TabCount++; |
| } |
| |
| /* Remove the spaces */ |
| |
| SubBuffer = AsRemoveData (NewSubBuffer, SubBuffer); |
| continue; |
| } |
| } |
| |
| SubBuffer++; |
| } |
| } |
| |
| |
| /****************************************************************************** |
| * |
| * FUNCTION: AsCountLines |
| * |
| * DESCRIPTION: Count the number of lines in the input buffer. Also count |
| * the number of long lines (lines longer than 80 chars). |
| * |
| ******************************************************************************/ |
| |
| static UINT32 |
| AsCountLines ( |
| char *Buffer, |
| char *Filename) |
| { |
| char *SubBuffer = Buffer; |
| char *EndOfLine; |
| UINT32 LineCount = 0; |
| UINT32 LongLineCount = 0; |
| |
| |
| while (*SubBuffer) |
| { |
| EndOfLine = AsSkipUntilChar (SubBuffer, '\n'); |
| if (!EndOfLine) |
| { |
| Gbl_TotalLines += LineCount; |
| return (LineCount); |
| } |
| |
| if ((EndOfLine - SubBuffer) > 80) |
| { |
| LongLineCount++; |
| VERBOSE_PRINT (("long: %.80s\n", SubBuffer)); |
| } |
| |
| LineCount++; |
| SubBuffer = EndOfLine + 1; |
| } |
| |
| if (LongLineCount) |
| { |
| VERBOSE_PRINT (("%u Lines longer than 80 found in %s\n", |
| LongLineCount, Filename)); |
| |
| Gbl_LongLines += LongLineCount; |
| } |
| |
| Gbl_TotalLines += LineCount; |
| return (LineCount); |
| } |
| |
| |
| /****************************************************************************** |
| * |
| * FUNCTION: AsCountTabs |
| * |
| * DESCRIPTION: Simply count the number of tabs in the input file buffer |
| * |
| ******************************************************************************/ |
| |
| void |
| AsCountTabs ( |
| char *Buffer, |
| char *Filename) |
| { |
| UINT32 i; |
| UINT32 TabCount = 0; |
| |
| |
| for (i = 0; Buffer[i]; i++) |
| { |
| if (Buffer[i] == '\t') |
| { |
| TabCount++; |
| } |
| } |
| |
| if (TabCount) |
| { |
| AsPrint ("Tabs found", TabCount, Filename); |
| Gbl_Tabs += TabCount; |
| } |
| |
| AsCountLines (Buffer, Filename); |
| } |
| |
| |
| /****************************************************************************** |
| * |
| * FUNCTION: AsCountSourceLines |
| * |
| * DESCRIPTION: Count the number of C source lines. Defined by 1) not a |
| * comment, and 2) not a blank line. |
| * |
| ******************************************************************************/ |
| |
| void |
| AsCountSourceLines ( |
| char *Buffer, |
| char *Filename) |
| { |
| char *SubBuffer = Buffer; |
| UINT32 LineCount = 0; |
| UINT32 WhiteCount = 0; |
| UINT32 CommentCount = 0; |
| |
| |
| while (*SubBuffer) |
| { |
| /* Detect comments (// comments are not used, non-ansii) */ |
| |
| if ((SubBuffer[0] == '/') && |
| (SubBuffer[1] == '*')) |
| { |
| SubBuffer += 2; |
| |
| /* First line of multi-line comment is often just whitespace */ |
| |
| if (SubBuffer[0] == '\n') |
| { |
| WhiteCount++; |
| SubBuffer++; |
| } |
| else |
| { |
| CommentCount++; |
| } |
| |
| /* Find end of comment */ |
| |
| while (SubBuffer[0] && SubBuffer[1] && |
| !(((SubBuffer[0] == '*') && |
| (SubBuffer[1] == '/')))) |
| { |
| if (SubBuffer[0] == '\n') |
| { |
| CommentCount++; |
| } |
| |
| SubBuffer++; |
| } |
| } |
| |
| /* A linefeed followed by a non-linefeed is a valid source line */ |
| |
| else if ((SubBuffer[0] == '\n') && |
| (SubBuffer[1] != '\n')) |
| { |
| LineCount++; |
| } |
| |
| /* Two back-to-back linefeeds indicate a whitespace line */ |
| |
| else if ((SubBuffer[0] == '\n') && |
| (SubBuffer[1] == '\n')) |
| { |
| WhiteCount++; |
| } |
| |
| SubBuffer++; |
| } |
| |
| /* Adjust comment count for legal header */ |
| |
| if (Gbl_HeaderSize < CommentCount) |
| { |
| CommentCount -= Gbl_HeaderSize; |
| Gbl_HeaderLines += Gbl_HeaderSize; |
| } |
| |
| Gbl_SourceLines += LineCount; |
| Gbl_WhiteLines += WhiteCount; |
| Gbl_CommentLines += CommentCount; |
| |
| VERBOSE_PRINT (("%u Comment %u White %u Code %u Lines in %s\n", |
| CommentCount, WhiteCount, LineCount, |
| LineCount + WhiteCount + CommentCount, Filename)); |
| } |
| |
| |
| /****************************************************************************** |
| * |
| * FUNCTION: AsInsertPrefix |
| * |
| * DESCRIPTION: Insert struct or union prefixes |
| * |
| ******************************************************************************/ |
| |
| void |
| AsInsertPrefix ( |
| char *Buffer, |
| char *Keyword, |
| UINT8 Type) |
| { |
| char *SubString; |
| char *SubBuffer; |
| char *EndKeyword; |
| int InsertLength; |
| char *InsertString; |
| int TrailingSpaces; |
| char LowerKeyword[128]; |
| int KeywordLength; |
| |
| |
| switch (Type) |
| { |
| case SRC_TYPE_STRUCT: |
| |
| InsertString = "struct "; |
| break; |
| |
| case SRC_TYPE_UNION: |
| |
| InsertString = "union "; |
| break; |
| |
| default: |
| |
| return; |
| } |
| |
| strcpy (LowerKeyword, Keyword); |
| AcpiUtStrlwr (LowerKeyword); |
| |
| SubBuffer = Buffer; |
| SubString = Buffer; |
| InsertLength = strlen (InsertString); |
| KeywordLength = strlen (Keyword); |
| |
| |
| while (SubString) |
| { |
| /* Find an instance of the keyword */ |
| |
| SubString = strstr (SubBuffer, LowerKeyword); |
| if (!SubString) |
| { |
| return; |
| } |
| |
| SubBuffer = SubString; |
| |
| /* Must be standalone word, not a substring */ |
| |
| if (AsMatchExactWord (SubString, KeywordLength)) |
| { |
| /* Make sure the keyword isn't already prefixed with the insert */ |
| |
| if (!strncmp (SubString - InsertLength, InsertString, InsertLength)) |
| { |
| /* Add spaces if not already at the end-of-line */ |
| |
| if (*(SubBuffer + KeywordLength) != '\n') |
| { |
| /* Already present, add spaces after to align structure members */ |
| |
| #if 0 |
| /* ONLY FOR C FILES */ |
| AsInsertData (SubBuffer + KeywordLength, " ", 8); |
| #endif |
| } |
| goto Next; |
| } |
| |
| /* Make sure the keyword isn't at the end of a struct/union */ |
| /* Note: This code depends on a single space after the brace */ |
| |
| if (*(SubString - 2) == '}') |
| { |
| goto Next; |
| } |
| |
| /* Prefix the keyword with the insert string */ |
| |
| Gbl_MadeChanges = TRUE; |
| |
| /* Is there room for insertion */ |
| |
| EndKeyword = SubString + strlen (LowerKeyword); |
| |
| TrailingSpaces = 0; |
| while (EndKeyword[TrailingSpaces] == ' ') |
| { |
| TrailingSpaces++; |
| } |
| |
| /* |
| * Use "if (TrailingSpaces > 1)" if we want to ignore casts |
| */ |
| SubBuffer = SubString + InsertLength; |
| |
| if (TrailingSpaces > InsertLength) |
| { |
| /* Insert the keyword */ |
| |
| memmove (SubBuffer, SubString, KeywordLength); |
| |
| /* Insert the keyword */ |
| |
| memmove (SubString, InsertString, InsertLength); |
| } |
| else |
| { |
| AsInsertData (SubString, InsertString, InsertLength); |
| } |
| } |
| |
| Next: |
| SubBuffer += KeywordLength; |
| } |
| } |
| |
| #ifdef ACPI_FUTURE_IMPLEMENTATION |
| /****************************************************************************** |
| * |
| * FUNCTION: AsTrimComments |
| * |
| * DESCRIPTION: Finds 3-line comments with only a single line of text |
| * |
| ******************************************************************************/ |
| |
| void |
| AsTrimComments ( |
| char *Buffer, |
| char *Filename) |
| { |
| char *SubBuffer = Buffer; |
| char *Ptr1; |
| char *Ptr2; |
| UINT32 LineCount; |
| UINT32 ShortCommentCount = 0; |
| |
| |
| while (1) |
| { |
| /* Find comment open, within procedure level */ |
| |
| SubBuffer = strstr (SubBuffer, " /*"); |
| if (!SubBuffer) |
| { |
| goto Exit; |
| } |
| |
| /* Find comment terminator */ |
| |
| Ptr1 = strstr (SubBuffer, "*/"); |
| if (!Ptr1) |
| { |
| goto Exit; |
| } |
| |
| /* Find next EOL (from original buffer) */ |
| |
| Ptr2 = strstr (SubBuffer, "\n"); |
| if (!Ptr2) |
| { |
| goto Exit; |
| } |
| |
| /* Ignore one-line comments */ |
| |
| if (Ptr1 < Ptr2) |
| { |
| /* Normal comment, ignore and continue; */ |
| |
| SubBuffer = Ptr2; |
| continue; |
| } |
| |
| /* Examine multi-line comment */ |
| |
| LineCount = 1; |
| while (Ptr1 > Ptr2) |
| { |
| /* Find next EOL */ |
| |
| Ptr2++; |
| Ptr2 = strstr (Ptr2, "\n"); |
| if (!Ptr2) |
| { |
| goto Exit; |
| } |
| |
| LineCount++; |
| } |
| |
| SubBuffer = Ptr1; |
| |
| if (LineCount <= 3) |
| { |
| ShortCommentCount++; |
| } |
| } |
| |
| |
| Exit: |
| |
| if (ShortCommentCount) |
| { |
| AsPrint ("Short Comments found", ShortCommentCount, Filename); |
| } |
| } |
| #endif |
| |
| #ifdef ACPI_UNUSED_FUNCTIONS |
| /****************************************************************************** |
| * |
| * FUNCTION: AsCheckAndSkipLiterals |
| * |
| * DESCRIPTION: Generic routine to skip comments and quoted string literals. |
| * Keeps a line count. |
| * |
| ******************************************************************************/ |
| |
| static char * |
| AsCheckAndSkipLiterals ( |
| char *Buffer, |
| UINT32 *TotalLines); |
| |
| |
| static char * |
| AsCheckAndSkipLiterals ( |
| char *Buffer, |
| UINT32 *TotalLines) |
| { |
| UINT32 NewLines = 0; |
| char *SubBuffer = Buffer; |
| char *LiteralEnd; |
| |
| |
| /* Ignore comments */ |
| |
| if ((SubBuffer[0] == '/') && |
| (SubBuffer[1] == '*')) |
| { |
| LiteralEnd = strstr (SubBuffer, "*/"); |
| SubBuffer += 2; /* Get past comment opening */ |
| |
| if (!LiteralEnd) |
| { |
| return (SubBuffer); |
| } |
| |
| while (SubBuffer < LiteralEnd) |
| { |
| if (*SubBuffer == '\n') |
| { |
| NewLines++; |
| } |
| |
| SubBuffer++; |
| } |
| |
| SubBuffer += 2; /* Get past comment close */ |
| } |
| |
| /* Ignore quoted strings */ |
| |
| else if (*SubBuffer == '\"') |
| { |
| SubBuffer++; |
| LiteralEnd = AsSkipPastChar (SubBuffer, '\"'); |
| if (!LiteralEnd) |
| { |
| return (SubBuffer); |
| } |
| } |
| |
| if (TotalLines) |
| { |
| (*TotalLines) += NewLines; |
| } |
| return (SubBuffer); |
| } |
| #endif |