1 /******************************************************************************
3 * Module Name: asconvrt - Source conversion code
5 *****************************************************************************/
8 * Copyright (C) 2000 - 2014, Intel Corp.
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
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.
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.
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.
46 /* Local prototypes */
49 AsCheckAndSkipLiterals (
58 /* Opening signature of the Intel legal header */
60 char *HeaderBegin = "/******************************************************************************\n *\n * 1. Copyright Notice";
63 /******************************************************************************
65 * FUNCTION: AsRemoveExtraLines
67 * DESCRIPTION: Remove all extra lines at the start and end of the file.
69 ******************************************************************************/
80 /* Remove any extra lines at the start of the file */
82 while (*FileBuffer == '\n')
84 printf ("Removing extra line at start of file: %s\n", Filename);
85 AsRemoveData (FileBuffer, FileBuffer + 1);
88 /* Remove any extra lines at the end of the file */
90 Length = strlen (FileBuffer);
91 FileEnd = FileBuffer + (Length - 2);
93 while (*FileEnd == '\n')
95 printf ("Removing extra line at end of file: %s\n", Filename);
96 AsRemoveData (FileEnd, FileEnd + 1);
102 /******************************************************************************
104 * FUNCTION: AsRemoveSpacesAfterPeriod
106 * DESCRIPTION: Remove an extra space after a period.
108 ******************************************************************************/
111 AsRemoveSpacesAfterPeriod (
115 int ReplaceCount = 0;
119 Possible = FileBuffer;
122 Possible = strstr (Possible, ". ");
125 if ((*(Possible -1) == '.') ||
126 (*(Possible -1) == '\"') ||
127 (*(Possible -1) == '\n'))
133 Possible = AsReplaceData (Possible, 3, ". ", 2);
140 printf ("Removed %d extra blanks after a period: %s\n",
141 ReplaceCount, Filename);
146 /******************************************************************************
148 * FUNCTION: AsMatchExactWord
150 * DESCRIPTION: Check previous and next characters for whitespace
152 ******************************************************************************/
163 NextChar = Word[WordLength];
164 PrevChar = * (Word -1);
166 if (isalnum ((int) NextChar) ||
168 isalnum ((int) PrevChar) ||
178 /******************************************************************************
182 * DESCRIPTION: Common formatted print
184 ******************************************************************************/
198 printf ("-- %4u %28.28s : %s\n", Count, Message, Filename);
202 /******************************************************************************
204 * FUNCTION: AsCheckAndSkipLiterals
206 * DESCRIPTION: Generic routine to skip comments and quoted string literals.
207 * Keeps a line count.
209 ******************************************************************************/
212 AsCheckAndSkipLiterals (
217 char *SubBuffer = Buffer;
221 /* Ignore comments */
223 if ((SubBuffer[0] == '/') &&
224 (SubBuffer[1] == '*'))
226 LiteralEnd = strstr (SubBuffer, "*/");
227 SubBuffer += 2; /* Get past comment opening */
234 while (SubBuffer < LiteralEnd)
236 if (*SubBuffer == '\n')
244 SubBuffer += 2; /* Get past comment close */
247 /* Ignore quoted strings */
249 else if (*SubBuffer == '\"')
252 LiteralEnd = AsSkipPastChar (SubBuffer, '\"');
261 (*TotalLines) += NewLines;
267 /******************************************************************************
269 * FUNCTION: AsAsCheckForBraces
271 * DESCRIPTION: Check for an open brace after each if statement
273 ******************************************************************************/
280 char *SubBuffer = Buffer;
284 UINT32 TotalLines = 1;
290 SubBuffer = AsCheckAndSkipLiterals (SubBuffer, &TotalLines);
292 if (*SubBuffer == '\n')
296 else if (!(strncmp (" if", SubBuffer, 3)))
299 NextBrace = strstr (SubBuffer, "{");
300 NextSemicolon = strstr (SubBuffer, ";");
301 NextIf = strstr (SubBuffer, " if");
304 (NextSemicolon && (NextBrace > NextSemicolon)) ||
305 (NextIf && (NextBrace > NextIf)))
311 printf ("Missing braces for <if>, line %u: %s\n", TotalLines, Filename);
315 else if (!(strncmp (" else if", SubBuffer, 8)))
318 NextBrace = strstr (SubBuffer, "{");
319 NextSemicolon = strstr (SubBuffer, ";");
320 NextIf = strstr (SubBuffer, " if");
323 (NextSemicolon && (NextBrace > NextSemicolon)) ||
324 (NextIf && (NextBrace > NextIf)))
330 printf ("Missing braces for <if>, line %u: %s\n", TotalLines, Filename);
334 else if (!(strncmp (" else", SubBuffer, 5)))
337 NextBrace = strstr (SubBuffer, "{");
338 NextSemicolon = strstr (SubBuffer, ";");
339 NextIf = strstr (SubBuffer, " if");
342 (NextSemicolon && (NextBrace > NextSemicolon)) ||
343 (NextIf && (NextBrace > NextIf)))
349 printf ("Missing braces for <else>, line %u: %s\n", TotalLines, Filename);
359 /******************************************************************************
361 * FUNCTION: AsTrimLines
363 * DESCRIPTION: Remove extra blanks from the end of source lines. Does not
366 ******************************************************************************/
373 char *SubBuffer = Buffer;
374 char *StartWhiteSpace = NULL;
375 UINT32 SpaceCount = 0;
380 while (*SubBuffer != '\n')
387 if (*SubBuffer == ' ')
389 if (!StartWhiteSpace)
391 StartWhiteSpace = SubBuffer;
396 StartWhiteSpace = NULL;
404 SpaceCount += (SubBuffer - StartWhiteSpace);
406 /* Remove the spaces */
408 SubBuffer = AsRemoveData (StartWhiteSpace, SubBuffer);
409 StartWhiteSpace = NULL;
419 Gbl_MadeChanges = TRUE;
420 AsPrint ("Extraneous spaces removed", SpaceCount, Filename);
425 /******************************************************************************
427 * FUNCTION: AsTrimWhitespace
429 * DESCRIPTION: Remove "excess" blank lines - any more than 2 blank lines.
430 * this can happen during the translation when lines are removed.
432 ******************************************************************************/
438 int ReplaceCount = 1;
443 ReplaceCount = AsReplaceString ("\n\n\n\n", "\n\n\n", REPLACE_SUBSTRINGS, Buffer);
448 /******************************************************************************
450 * FUNCTION: AsReplaceHeader
452 * DESCRIPTION: Replace the default Intel legal header with a new header
454 ******************************************************************************/
465 /* Find the original header */
467 SubBuffer = strstr (Buffer, HeaderBegin);
473 /* Find the end of the original header */
475 TokenEnd = strstr (SubBuffer, "*/");
476 TokenEnd = AsSkipPastChar (TokenEnd, '\n');
478 /* Delete old header, insert new one */
480 AsReplaceData (SubBuffer, TokenEnd - SubBuffer, NewHeader, strlen (NewHeader));
484 /******************************************************************************
486 * FUNCTION: AsReplaceString
488 * DESCRIPTION: Replace all instances of a target string with a replacement
489 * string. Returns count of the strings replaced.
491 ******************************************************************************/
504 int ReplacementLength;
505 int ReplaceCount = 0;
508 TargetLength = strlen (Target);
509 ReplacementLength = strlen (Replacement);
516 /* Find the target string */
518 SubString1 = strstr (SubBuffer, Target);
521 return (ReplaceCount);
525 * Check for translation escape string -- means to ignore
526 * blocks of code while replacing
528 if (Gbl_IgnoreTranslationEscapes)
534 SubString2 = strstr (SubBuffer, AS_START_IGNORE);
538 (SubString2 < SubString1))
540 /* Find end of the escape block starting at "Substring2" */
542 SubString2 = strstr (SubString2, AS_STOP_IGNORE);
545 /* Didn't find terminator */
547 return (ReplaceCount);
550 /* Move buffer to end of escape block and continue */
552 SubBuffer = SubString2;
555 /* Do the actual replace if the target was found */
559 if ((Type & REPLACE_MASK) == REPLACE_WHOLE_WORD)
561 if (!AsMatchExactWord (SubString1, TargetLength))
563 SubBuffer = SubString1 + 1;
568 SubBuffer = AsReplaceData (SubString1, TargetLength, Replacement, ReplacementLength);
570 if ((Type & EXTRA_INDENT_C) &&
573 SubBuffer = AsInsertData (SubBuffer, " ", 8);
580 return (ReplaceCount);
584 /******************************************************************************
586 * FUNCTION: AsConvertToLineFeeds
590 ******************************************************************************/
593 AsConvertToLineFeeds (
605 /* Find the target string */
607 SubString = strstr (SubBuffer, "\r\n");
613 SubBuffer = AsReplaceData (SubString, 1, NULL, 0);
619 /******************************************************************************
621 * FUNCTION: AsInsertCarriageReturns
625 ******************************************************************************/
628 AsInsertCarriageReturns (
640 /* Find the target string */
642 SubString = strstr (SubBuffer, "\n");
648 SubBuffer = AsInsertData (SubString, "\r", 1);
655 /******************************************************************************
657 * FUNCTION: AsBracesOnSameLine
659 * DESCRIPTION: Move opening braces up to the same line as an if, for, else,
660 * or while statement (leave function opening brace on separate
663 ******************************************************************************/
669 char *SubBuffer = Buffer;
671 char *StartOfThisLine;
673 BOOLEAN BlockBegin = TRUE;
678 /* Ignore comments */
680 if ((SubBuffer[0] == '/') &&
681 (SubBuffer[1] == '*'))
683 SubBuffer = strstr (SubBuffer, "*/");
693 /* Ignore quoted strings */
695 if (*SubBuffer == '\"')
698 SubBuffer = AsSkipPastChar (SubBuffer, '\"');
705 if (!strncmp ("\n}", SubBuffer, 2))
708 * A newline followed by a closing brace closes a function
709 * or struct or initializer block
715 * Move every standalone brace up to the previous line
716 * Check for digit will ignore initializer lists surrounded by braces.
717 * This will work until we we need more complex detection.
719 if ((*SubBuffer == '{') && !isdigit ((int) SubBuffer[1]))
728 * Backup to previous non-whitespace
730 Beginning = SubBuffer - 1;
731 while ((*Beginning == ' ') ||
732 (*Beginning == '\n'))
737 StartOfThisLine = Beginning;
738 while (*StartOfThisLine != '\n')
744 * Move the brace up to the previous line, UNLESS:
746 * 1) There is a conditional compile on the line (starts with '#')
747 * 2) Previous line ends with an '=' (Start of initializer block)
748 * 3) Previous line ends with a comma (part of an init list)
749 * 4) Previous line ends with a backslash (part of a macro)
751 if ((StartOfThisLine[1] != '#') &&
752 (*Beginning != '\\') &&
753 (*Beginning != '/') &&
754 (*Beginning != '{') &&
755 (*Beginning != '=') &&
761 Gbl_MadeChanges = TRUE;
763 #ifdef ADD_EXTRA_WHITESPACE
764 AsReplaceData (Beginning, SubBuffer - Beginning, " {\n", 3);
766 /* Find non-whitespace start of next line */
768 Next = SubBuffer + 1;
769 while ((*Next == ' ') ||
775 /* Find non-whitespace start of this line */
778 while ((*StartOfThisLine == ' ') ||
779 (*StartOfThisLine == '\t'))
785 * Must be a single-line comment to need more whitespace
786 * Even then, we don't need more if the previous statement
789 if ((Next[0] == '/') &&
793 (!strncmp (StartOfThisLine, "else if", 7) ||
794 !strncmp (StartOfThisLine, "else while", 10) ||
795 strncmp (StartOfThisLine, "else", 4)))
797 AsReplaceData (Beginning, SubBuffer - Beginning, " {\n", 3);
801 AsReplaceData (Beginning, SubBuffer - Beginning, " {", 2);
813 /******************************************************************************
815 * FUNCTION: AsTabify4
817 * DESCRIPTION: Convert the text to tabbed text. Alignment of text is
820 ******************************************************************************/
826 char *SubBuffer = Buffer;
828 UINT32 SpaceCount = 0;
834 if (*SubBuffer == '\n')
843 /* Ignore comments */
845 if ((SubBuffer[0] == '/') &&
846 (SubBuffer[1] == '*'))
848 SubBuffer = strstr (SubBuffer, "*/");
858 /* Ignore quoted strings */
860 if (*SubBuffer == '\"')
863 SubBuffer = AsSkipPastChar (SubBuffer, '\"');
871 if (*SubBuffer == ' ')
879 NewSubBuffer = (SubBuffer + 1) - 4;
880 *NewSubBuffer = '\t';
883 /* Remove the spaces */
885 SubBuffer = AsRemoveData (NewSubBuffer, SubBuffer + 1);
888 if ((Column % 4) == 0)
903 /******************************************************************************
905 * FUNCTION: AsTabify8
907 * DESCRIPTION: Convert the text to tabbed text. Alignment of text is
910 ******************************************************************************/
916 char *SubBuffer = Buffer;
918 char *CommentEnd = NULL;
919 UINT32 SpaceCount = 0;
922 UINT32 LastLineTabCount = 0;
923 UINT32 LastLineColumnStart = 0;
924 UINT32 ThisColumnStart = 0;
925 UINT32 ThisTabCount = 0;
926 char *FirstNonBlank = NULL;
931 if (*SubBuffer == '\n')
933 /* This is a standalone blank line */
935 FirstNonBlank = NULL;
945 /* Find the first non-blank character on this line */
947 FirstNonBlank = SubBuffer;
948 while (*FirstNonBlank == ' ')
954 * This mechanism limits the difference in tab counts from
955 * line to line. It helps avoid the situation where a second
956 * continuation line (which was indented correctly for tabs=4) would
957 * get indented off the screen if we just blindly converted to tabs.
959 ThisColumnStart = FirstNonBlank - SubBuffer;
961 if (LastLineTabCount == 0)
965 else if (ThisColumnStart == LastLineColumnStart)
967 ThisTabCount = LastLineTabCount -1;
971 ThisTabCount = LastLineTabCount + 1;
977 /* Check if we are in a comment */
979 if ((SubBuffer[0] == '*') &&
980 (SubBuffer[1] == '/'))
985 if (*SubBuffer == '\n')
989 LastLineTabCount = TabCount;
992 FirstNonBlank = NULL;
993 LastLineColumnStart = ThisColumnStart;
1000 /* Check for comment open */
1002 if ((SubBuffer[0] == '/') &&
1003 (SubBuffer[1] == '*'))
1005 /* Find the end of the comment, it must exist */
1007 CommentEnd = strstr (SubBuffer, "*/");
1013 /* Toss the rest of this line or single-line comment */
1015 while ((SubBuffer < CommentEnd) &&
1016 (*SubBuffer != '\n'))
1021 if (*SubBuffer == '\n')
1025 LastLineTabCount = TabCount;
1028 FirstNonBlank = NULL;
1029 LastLineColumnStart = ThisColumnStart;
1036 /* Ignore quoted strings */
1038 if ((!CommentEnd) && (*SubBuffer == '\"'))
1041 SubBuffer = AsSkipPastChar (SubBuffer, '\"');
1049 if (*SubBuffer != ' ')
1051 /* Not a space, skip to end of line */
1053 SubBuffer = AsSkipUntilChar (SubBuffer, '\n');
1060 LastLineTabCount = TabCount;
1064 FirstNonBlank = NULL;
1065 LastLineColumnStart = ThisColumnStart;
1075 if (SpaceCount >= 4)
1077 /* Replace this group of spaces with a tab character */
1081 NewSubBuffer = SubBuffer - 3;
1083 if (TabCount <= ThisTabCount ? (ThisTabCount +1) : 0)
1085 *NewSubBuffer = '\t';
1091 /* Remove the spaces */
1093 SubBuffer = AsRemoveData (NewSubBuffer, SubBuffer);
1103 /******************************************************************************
1105 * FUNCTION: AsCountLines
1107 * DESCRIPTION: Count the number of lines in the input buffer. Also count
1108 * the number of long lines (lines longer than 80 chars).
1110 ******************************************************************************/
1117 char *SubBuffer = Buffer;
1119 UINT32 LineCount = 0;
1120 UINT32 LongLineCount = 0;
1125 EndOfLine = AsSkipUntilChar (SubBuffer, '\n');
1128 Gbl_TotalLines += LineCount;
1132 if ((EndOfLine - SubBuffer) > 80)
1135 VERBOSE_PRINT (("long: %.80s\n", SubBuffer));
1139 SubBuffer = EndOfLine + 1;
1144 VERBOSE_PRINT (("%u Lines longer than 80 found in %s\n", LongLineCount, Filename));
1145 Gbl_LongLines += LongLineCount;
1148 Gbl_TotalLines += LineCount;
1153 /******************************************************************************
1155 * FUNCTION: AsCountTabs
1157 * DESCRIPTION: Simply count the number of tabs in the input file buffer
1159 ******************************************************************************/
1167 UINT32 TabCount = 0;
1170 for (i = 0; Buffer[i]; i++)
1172 if (Buffer[i] == '\t')
1180 AsPrint ("Tabs found", TabCount, Filename);
1181 Gbl_Tabs += TabCount;
1184 AsCountLines (Buffer, Filename);
1188 /******************************************************************************
1190 * FUNCTION: AsCountNonAnsiComments
1192 * DESCRIPTION: Count the number of "//" comments. This type of comment is
1195 ******************************************************************************/
1198 AsCountNonAnsiComments (
1202 char *SubBuffer = Buffer;
1203 UINT32 CommentCount = 0;
1208 SubBuffer = strstr (SubBuffer, "//");
1218 AsPrint ("Non-ANSI Comments found", CommentCount, Filename);
1219 Gbl_NonAnsiComments += CommentCount;
1224 /******************************************************************************
1226 * FUNCTION: AsCountSourceLines
1228 * DESCRIPTION: Count the number of C source lines. Defined by 1) not a
1229 * comment, and 2) not a blank line.
1231 ******************************************************************************/
1234 AsCountSourceLines (
1238 char *SubBuffer = Buffer;
1239 UINT32 LineCount = 0;
1240 UINT32 WhiteCount = 0;
1241 UINT32 CommentCount = 0;
1246 /* Detect comments (// comments are not used, non-ansii) */
1248 if ((SubBuffer[0] == '/') &&
1249 (SubBuffer[1] == '*'))
1253 /* First line of multi-line comment is often just whitespace */
1255 if (SubBuffer[0] == '\n')
1265 /* Find end of comment */
1267 while (SubBuffer[0] && SubBuffer[1] &&
1268 !(((SubBuffer[0] == '*') &&
1269 (SubBuffer[1] == '/'))))
1271 if (SubBuffer[0] == '\n')
1280 /* A linefeed followed by a non-linefeed is a valid source line */
1282 else if ((SubBuffer[0] == '\n') &&
1283 (SubBuffer[1] != '\n'))
1288 /* Two back-to-back linefeeds indicate a whitespace line */
1290 else if ((SubBuffer[0] == '\n') &&
1291 (SubBuffer[1] == '\n'))
1299 /* Adjust comment count for legal header */
1301 if (Gbl_HeaderSize < CommentCount)
1303 CommentCount -= Gbl_HeaderSize;
1304 Gbl_HeaderLines += Gbl_HeaderSize;
1307 Gbl_SourceLines += LineCount;
1308 Gbl_WhiteLines += WhiteCount;
1309 Gbl_CommentLines += CommentCount;
1311 VERBOSE_PRINT (("%u Comment %u White %u Code %u Lines in %s\n",
1312 CommentCount, WhiteCount, LineCount, LineCount+WhiteCount+CommentCount, Filename));
1316 /******************************************************************************
1318 * FUNCTION: AsInsertPrefix
1320 * DESCRIPTION: Insert struct or union prefixes
1322 ******************************************************************************/
1336 char LowerKeyword[128];
1342 case SRC_TYPE_STRUCT:
1344 InsertString = "struct ";
1347 case SRC_TYPE_UNION:
1349 InsertString = "union ";
1357 strcpy (LowerKeyword, Keyword);
1358 AsStrlwr (LowerKeyword);
1362 InsertLength = strlen (InsertString);
1363 KeywordLength = strlen (Keyword);
1368 /* Find an instance of the keyword */
1370 SubString = strstr (SubBuffer, LowerKeyword);
1376 SubBuffer = SubString;
1378 /* Must be standalone word, not a substring */
1380 if (AsMatchExactWord (SubString, KeywordLength))
1382 /* Make sure the keyword isn't already prefixed with the insert */
1384 if (!strncmp (SubString - InsertLength, InsertString, InsertLength))
1386 /* Add spaces if not already at the end-of-line */
1388 if (*(SubBuffer + KeywordLength) != '\n')
1390 /* Already present, add spaces after to align structure members */
1393 /* ONLY FOR C FILES */
1394 AsInsertData (SubBuffer + KeywordLength, " ", 8);
1400 /* Make sure the keyword isn't at the end of a struct/union */
1401 /* Note: This code depends on a single space after the brace */
1403 if (*(SubString - 2) == '}')
1408 /* Prefix the keyword with the insert string */
1410 Gbl_MadeChanges = TRUE;
1412 /* Is there room for insertion */
1414 EndKeyword = SubString + strlen (LowerKeyword);
1417 while (EndKeyword[TrailingSpaces] == ' ')
1423 * Use "if (TrailingSpaces > 1)" if we want to ignore casts
1425 SubBuffer = SubString + InsertLength;
1427 if (TrailingSpaces > InsertLength)
1429 /* Insert the keyword */
1431 memmove (SubBuffer, SubString, KeywordLength);
1433 /* Insert the keyword */
1435 memmove (SubString, InsertString, InsertLength);
1439 AsInsertData (SubString, InsertString, InsertLength);
1444 SubBuffer += KeywordLength;
1448 #ifdef ACPI_FUTURE_IMPLEMENTATION
1449 /******************************************************************************
1451 * FUNCTION: AsTrimComments
1453 * DESCRIPTION: Finds 3-line comments with only a single line of text
1455 ******************************************************************************/
1462 char *SubBuffer = Buffer;
1466 UINT32 ShortCommentCount = 0;
1471 /* Find comment open, within procedure level */
1473 SubBuffer = strstr (SubBuffer, " /*");
1479 /* Find comment terminator */
1481 Ptr1 = strstr (SubBuffer, "*/");
1487 /* Find next EOL (from original buffer) */
1489 Ptr2 = strstr (SubBuffer, "\n");
1495 /* Ignore one-line comments */
1499 /* Normal comment, ignore and continue; */
1505 /* Examine multi-line comment */
1513 Ptr2 = strstr (Ptr2, "\n");
1526 ShortCommentCount++;
1533 if (ShortCommentCount)
1535 AsPrint ("Short Comments found", ShortCommentCount, Filename);