2009-07-17 11:10:31 +02:00
## @file
# preprocess source file
#
2018-03-30 02:19:31 +02:00
# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
2009-07-17 11:10:31 +02:00
#
2019-04-04 01:03:11 +02:00
# SPDX-License-Identifier: BSD-2-Clause-Patent
2009-07-17 11:10:31 +02:00
#
##
# Import Modules
#
2018-06-25 12:31:26 +02:00
from __future__ import print_function
2018-07-13 12:18:42 +02:00
from __future__ import absolute_import
2009-07-17 11:10:31 +02:00
import re
2014-08-15 05:06:48 +02:00
import Common . LongFilePathOs as os
2009-07-17 11:10:31 +02:00
import sys
2019-01-04 10:35:10 +01:00
if sys . version_info . major == 3 :
import antlr4 as antlr
from Ecc . CParser4 . CLexer import CLexer
from Ecc . CParser4 . CParser import CParser
else :
import antlr3 as antlr
2019-02-18 07:23:30 +01:00
antlr . InputStream = antlr . StringStream
2019-01-04 10:35:10 +01:00
from Ecc . CParser3 . CLexer import CLexer
from Ecc . CParser3 . CParser import CParser
2009-07-17 11:10:31 +02:00
2018-08-08 05:18:06 +02:00
from Ecc import FileProfile
from Ecc . CodeFragment import Comment
from Ecc . CodeFragment import PP_Directive
from Ecc . ParserWarning import Warning
2009-07-17 11:10:31 +02:00
##define T_CHAR_SPACE ' '
##define T_CHAR_NULL '\0'
##define T_CHAR_CR '\r'
##define T_CHAR_TAB '\t'
##define T_CHAR_LF '\n'
##define T_CHAR_SLASH '/'
##define T_CHAR_BACKSLASH '\\'
##define T_CHAR_DOUBLE_QUOTE '\"'
##define T_CHAR_SINGLE_QUOTE '\''
##define T_CHAR_STAR '*'
##define T_CHAR_HASH '#'
( T_CHAR_SPACE , T_CHAR_NULL , T_CHAR_CR , T_CHAR_TAB , T_CHAR_LF , T_CHAR_SLASH , \
T_CHAR_BACKSLASH , T_CHAR_DOUBLE_QUOTE , T_CHAR_SINGLE_QUOTE , T_CHAR_STAR , T_CHAR_HASH ) = \
( ' ' , ' \0 ' , ' \r ' , ' \t ' , ' \n ' , ' / ' , ' \\ ' , ' \" ' , ' \' ' , ' * ' , ' # ' )
2018-07-05 11:40:04 +02:00
SEPERATOR_TUPLE = ( ' = ' , ' | ' , ' , ' , ' { ' , ' } ' )
2009-07-17 11:10:31 +02:00
( T_COMMENT_TWO_SLASH , T_COMMENT_SLASH_STAR ) = ( 0 , 1 )
( T_PP_INCLUDE , T_PP_DEFINE , T_PP_OTHERS ) = ( 0 , 1 , 2 )
## The collector for source code fragments.
#
# PreprocessFile method should be called prior to ParseFile
#
# GetNext*** procedures mean these procedures will get next token first, then make judgement.
# Get*** procedures mean these procedures will make judgement on current token only.
2018-07-05 11:40:04 +02:00
#
2009-07-17 11:10:31 +02:00
class CodeFragmentCollector :
## The constructor
#
# @param self The object pointer
# @param FileName The file that to be parsed
#
def __init__ ( self , FileName ) :
self . Profile = FileProfile . FileProfile ( FileName )
self . Profile . FileLinesList . append ( T_CHAR_LF )
self . FileName = FileName
self . CurrentLineNumber = 1
self . CurrentOffsetWithinLine = 0
BaseTools:ECC report errors on account of analyze special characters
BZ:https://bugzilla.tianocore.org/show_bug.cgi?id=1751
In case that a C function body contains the string of L'', L'\"',
L"\"", L''', L""", L"\"\"", L"\"^", L" \"", L"\" \"", ('L",\\\""')
ECC tool running under python3 interpreter will report error.
The antlr4 module misidentified this character
This patch is going to fix that issue.
Cc: Bob Feng <bob.c.feng@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Signed-off-by: Zhiju.Fan <zhijux.fan@intel.com>
Reviewed-by: Bob Feng <bob.c.feng@intel.com>
2019-05-06 04:35:07 +02:00
self . TokenReleaceList = [ ]
2009-07-17 11:10:31 +02:00
self . __Token = " "
self . __SkippedChars = " "
## __EndOfFile() method
#
# Judge current buffer pos is at file end
#
# @param self The object pointer
# @retval True Current File buffer position is at file end
# @retval False Current File buffer position is NOT at file end
#
def __EndOfFile ( self ) :
NumberOfLines = len ( self . Profile . FileLinesList )
SizeOfLastLine = NumberOfLines
if NumberOfLines > 0 :
SizeOfLastLine = len ( self . Profile . FileLinesList [ - 1 ] )
2018-07-05 11:40:04 +02:00
2009-07-17 11:10:31 +02:00
if self . CurrentLineNumber == NumberOfLines and self . CurrentOffsetWithinLine > = SizeOfLastLine - 1 :
return True
elif self . CurrentLineNumber > NumberOfLines :
return True
else :
return False
## __EndOfLine() method
#
# Judge current buffer pos is at line end
#
# @param self The object pointer
# @retval True Current File buffer position is at line end
# @retval False Current File buffer position is NOT at line end
#
def __EndOfLine ( self ) :
SizeOfCurrentLine = len ( self . Profile . FileLinesList [ self . CurrentLineNumber - 1 ] )
if self . CurrentOffsetWithinLine > = SizeOfCurrentLine - 1 :
return True
else :
return False
2018-07-05 11:40:04 +02:00
2009-07-17 11:10:31 +02:00
## Rewind() method
#
# Reset file data buffer to the initial state
#
# @param self The object pointer
#
def Rewind ( self ) :
self . CurrentLineNumber = 1
self . CurrentOffsetWithinLine = 0
2018-07-05 11:40:04 +02:00
2009-07-17 11:10:31 +02:00
## __UndoOneChar() method
#
# Go back one char in the file buffer
#
# @param self The object pointer
# @retval True Successfully go back one char
# @retval False Not able to go back one char as file beginning reached
2018-07-05 11:40:04 +02:00
#
2009-07-17 11:10:31 +02:00
def __UndoOneChar ( self ) :
2018-07-05 11:40:04 +02:00
2009-07-17 11:10:31 +02:00
if self . CurrentLineNumber == 1 and self . CurrentOffsetWithinLine == 0 :
return False
elif self . CurrentOffsetWithinLine == 0 :
self . CurrentLineNumber - = 1
self . CurrentOffsetWithinLine = len ( self . __CurrentLine ( ) ) - 1
else :
self . CurrentOffsetWithinLine - = 1
return True
2018-07-05 11:40:04 +02:00
2009-07-17 11:10:31 +02:00
## __GetOneChar() method
#
# Move forward one char in the file buffer
#
# @param self The object pointer
2018-07-05 11:40:04 +02:00
#
2009-07-17 11:10:31 +02:00
def __GetOneChar ( self ) :
if self . CurrentOffsetWithinLine == len ( self . Profile . FileLinesList [ self . CurrentLineNumber - 1 ] ) - 1 :
self . CurrentLineNumber + = 1
self . CurrentOffsetWithinLine = 0
else :
self . CurrentOffsetWithinLine + = 1
## __CurrentChar() method
#
# Get the char pointed to by the file buffer pointer
#
# @param self The object pointer
# @retval Char Current char
2018-07-05 11:40:04 +02:00
#
2009-07-17 11:10:31 +02:00
def __CurrentChar ( self ) :
CurrentChar = self . Profile . FileLinesList [ self . CurrentLineNumber - 1 ] [ self . CurrentOffsetWithinLine ]
# if CurrentChar > 255:
# raise Warning("Non-Ascii char found At Line %d, offset %d" % (self.CurrentLineNumber, self.CurrentOffsetWithinLine), self.FileName, self.CurrentLineNumber)
return CurrentChar
2018-07-05 11:40:04 +02:00
2009-07-17 11:10:31 +02:00
## __NextChar() method
#
# Get the one char pass the char pointed to by the file buffer pointer
#
# @param self The object pointer
# @retval Char Next char
#
def __NextChar ( self ) :
if self . CurrentOffsetWithinLine == len ( self . Profile . FileLinesList [ self . CurrentLineNumber - 1 ] ) - 1 :
return self . Profile . FileLinesList [ self . CurrentLineNumber ] [ 0 ]
else :
return self . Profile . FileLinesList [ self . CurrentLineNumber - 1 ] [ self . CurrentOffsetWithinLine + 1 ]
2018-07-05 11:40:04 +02:00
2009-07-17 11:10:31 +02:00
## __SetCurrentCharValue() method
#
# Modify the value of current char
#
# @param self The object pointer
# @param Value The new value of current char
#
def __SetCurrentCharValue ( self , Value ) :
self . Profile . FileLinesList [ self . CurrentLineNumber - 1 ] [ self . CurrentOffsetWithinLine ] = Value
2018-07-05 11:40:04 +02:00
2009-07-17 11:10:31 +02:00
## __SetCharValue() method
#
# Modify the value of current char
#
# @param self The object pointer
# @param Value The new value of current char
#
def __SetCharValue ( self , Line , Offset , Value ) :
self . Profile . FileLinesList [ Line - 1 ] [ Offset ] = Value
2018-07-05 11:40:04 +02:00
2009-07-17 11:10:31 +02:00
## __CurrentLine() method
#
# Get the list that contains current line contents
#
# @param self The object pointer
# @retval List current line contents
#
def __CurrentLine ( self ) :
return self . Profile . FileLinesList [ self . CurrentLineNumber - 1 ]
2018-07-05 11:40:04 +02:00
2009-07-17 11:10:31 +02:00
## __InsertComma() method
#
# Insert ',' to replace PP
#
# @param self The object pointer
# @retval List current line contents
#
def __InsertComma ( self , Line ) :
2018-07-05 11:40:04 +02:00
2009-07-17 11:10:31 +02:00
if self . Profile . FileLinesList [ Line - 1 ] [ 0 ] != T_CHAR_HASH :
BeforeHashPart = str ( self . Profile . FileLinesList [ Line - 1 ] ) . split ( T_CHAR_HASH ) [ 0 ]
if BeforeHashPart . rstrip ( ) . endswith ( T_CHAR_COMMA ) or BeforeHashPart . rstrip ( ) . endswith ( ' ; ' ) :
return
2018-07-05 11:40:04 +02:00
2009-07-17 11:10:31 +02:00
if Line - 2 > = 0 and str ( self . Profile . FileLinesList [ Line - 2 ] ) . rstrip ( ) . endswith ( ' , ' ) :
return
2018-07-05 11:40:04 +02:00
2009-07-17 11:10:31 +02:00
if Line - 2 > = 0 and str ( self . Profile . FileLinesList [ Line - 2 ] ) . rstrip ( ) . endswith ( ' ; ' ) :
return
2018-07-05 11:40:04 +02:00
2009-07-17 11:10:31 +02:00
if str ( self . Profile . FileLinesList [ Line ] ) . lstrip ( ) . startswith ( ' , ' ) or str ( self . Profile . FileLinesList [ Line ] ) . lstrip ( ) . startswith ( ' ; ' ) :
return
2018-07-05 11:40:04 +02:00
2009-07-17 11:10:31 +02:00
self . Profile . FileLinesList [ Line - 1 ] . insert ( self . CurrentOffsetWithinLine , ' , ' )
2018-07-05 11:40:04 +02:00
2009-07-17 11:10:31 +02:00
## PreprocessFile() method
#
# Preprocess file contents, replace comments with spaces.
# In the end, rewind the file buffer pointer to the beginning
# BUGBUG: No !include statement processing contained in this procedure
# !include statement should be expanded at the same FileLinesList[CurrentLineNumber - 1]
#
# @param self The object pointer
2018-07-05 11:40:04 +02:00
#
2009-07-17 11:10:31 +02:00
def PreprocessFile ( self ) :
self . Rewind ( )
InComment = False
DoubleSlashComment = False
HashComment = False
PPExtend = False
CommentObj = None
PPDirectiveObj = None
# HashComment in quoted string " " is ignored.
InString = False
2018-07-05 11:40:04 +02:00
InCharLiteral = False
2009-07-17 11:10:31 +02:00
self . Profile . FileLinesList = [ list ( s ) for s in self . Profile . FileLinesListFromFile ]
while not self . __EndOfFile ( ) :
2018-07-05 11:40:04 +02:00
2009-07-17 11:10:31 +02:00
if not InComment and self . __CurrentChar ( ) == T_CHAR_DOUBLE_QUOTE :
InString = not InString
2018-07-05 11:40:04 +02:00
2009-07-17 11:10:31 +02:00
if not InComment and self . __CurrentChar ( ) == T_CHAR_SINGLE_QUOTE :
InCharLiteral = not InCharLiteral
# meet new line, then no longer in a comment for // and '#'
if self . __CurrentChar ( ) == T_CHAR_LF :
2018-03-26 22:25:43 +02:00
if HashComment and PPDirectiveObj is not None :
2009-07-17 11:10:31 +02:00
if PPDirectiveObj . Content . rstrip ( T_CHAR_CR ) . endswith ( T_CHAR_BACKSLASH ) :
PPDirectiveObj . Content + = T_CHAR_LF
PPExtend = True
else :
PPExtend = False
2018-07-05 11:40:04 +02:00
2009-07-17 11:10:31 +02:00
EndLinePos = ( self . CurrentLineNumber , self . CurrentOffsetWithinLine )
2018-07-05 11:40:04 +02:00
2009-07-17 11:10:31 +02:00
if InComment and DoubleSlashComment :
InComment = False
DoubleSlashComment = False
CommentObj . Content + = T_CHAR_LF
CommentObj . EndPos = EndLinePos
FileProfile . CommentList . append ( CommentObj )
CommentObj = None
if InComment and HashComment and not PPExtend :
InComment = False
HashComment = False
PPDirectiveObj . Content + = T_CHAR_LF
PPDirectiveObj . EndPos = EndLinePos
FileProfile . PPDirectiveList . append ( PPDirectiveObj )
PPDirectiveObj = None
2018-07-05 11:40:04 +02:00
2009-07-17 11:10:31 +02:00
if InString or InCharLiteral :
CurrentLine = " " . join ( self . __CurrentLine ( ) )
if CurrentLine . rstrip ( T_CHAR_LF ) . rstrip ( T_CHAR_CR ) . endswith ( T_CHAR_BACKSLASH ) :
SlashIndex = CurrentLine . rindex ( T_CHAR_BACKSLASH )
self . __SetCharValue ( self . CurrentLineNumber , SlashIndex , T_CHAR_SPACE )
2018-07-05 11:40:04 +02:00
2009-07-17 11:10:31 +02:00
if InComment and not DoubleSlashComment and not HashComment :
CommentObj . Content + = T_CHAR_LF
self . CurrentLineNumber + = 1
2018-07-05 11:40:04 +02:00
self . CurrentOffsetWithinLine = 0
2009-07-17 11:10:31 +02:00
# check for */ comment end
elif InComment and not DoubleSlashComment and not HashComment and self . __CurrentChar ( ) == T_CHAR_STAR and self . __NextChar ( ) == T_CHAR_SLASH :
CommentObj . Content + = self . __CurrentChar ( )
# self.__SetCurrentCharValue(T_CHAR_SPACE)
self . __GetOneChar ( )
CommentObj . Content + = self . __CurrentChar ( )
# self.__SetCurrentCharValue(T_CHAR_SPACE)
CommentObj . EndPos = ( self . CurrentLineNumber , self . CurrentOffsetWithinLine )
FileProfile . CommentList . append ( CommentObj )
CommentObj = None
self . __GetOneChar ( )
InComment = False
# set comments to spaces
2018-07-05 11:40:04 +02:00
elif InComment :
2009-07-17 11:10:31 +02:00
if HashComment :
# // follows hash PP directive
if self . __CurrentChar ( ) == T_CHAR_SLASH and self . __NextChar ( ) == T_CHAR_SLASH :
InComment = False
HashComment = False
PPDirectiveObj . EndPos = ( self . CurrentLineNumber , self . CurrentOffsetWithinLine - 1 )
FileProfile . PPDirectiveList . append ( PPDirectiveObj )
PPDirectiveObj = None
continue
else :
PPDirectiveObj . Content + = self . __CurrentChar ( )
if PPExtend :
self . __SetCurrentCharValue ( T_CHAR_SPACE )
else :
CommentObj . Content + = self . __CurrentChar ( )
# self.__SetCurrentCharValue(T_CHAR_SPACE)
self . __GetOneChar ( )
# check for // comment
elif self . __CurrentChar ( ) == T_CHAR_SLASH and self . __NextChar ( ) == T_CHAR_SLASH :
InComment = True
DoubleSlashComment = True
CommentObj = Comment ( ' ' , ( self . CurrentLineNumber , self . CurrentOffsetWithinLine ) , None , T_COMMENT_TWO_SLASH )
# check for '#' comment
elif self . __CurrentChar ( ) == T_CHAR_HASH and not InString and not InCharLiteral :
InComment = True
2018-07-05 11:40:04 +02:00
HashComment = True
2009-07-17 11:10:31 +02:00
PPDirectiveObj = PP_Directive ( ' ' , ( self . CurrentLineNumber , self . CurrentOffsetWithinLine ) , None )
# check for /* comment start
elif self . __CurrentChar ( ) == T_CHAR_SLASH and self . __NextChar ( ) == T_CHAR_STAR :
CommentObj = Comment ( ' ' , ( self . CurrentLineNumber , self . CurrentOffsetWithinLine ) , None , T_COMMENT_SLASH_STAR )
CommentObj . Content + = self . __CurrentChar ( )
# self.__SetCurrentCharValue( T_CHAR_SPACE)
self . __GetOneChar ( )
CommentObj . Content + = self . __CurrentChar ( )
# self.__SetCurrentCharValue( T_CHAR_SPACE)
self . __GetOneChar ( )
InComment = True
else :
self . __GetOneChar ( )
2018-07-05 11:40:04 +02:00
2009-07-17 11:10:31 +02:00
EndLinePos = ( self . CurrentLineNumber , self . CurrentOffsetWithinLine )
2018-07-05 11:40:04 +02:00
2009-07-17 11:10:31 +02:00
if InComment and DoubleSlashComment :
CommentObj . EndPos = EndLinePos
FileProfile . CommentList . append ( CommentObj )
if InComment and HashComment and not PPExtend :
PPDirectiveObj . EndPos = EndLinePos
FileProfile . PPDirectiveList . append ( PPDirectiveObj )
self . Rewind ( )
def PreprocessFileWithClear ( self ) :
self . Rewind ( )
InComment = False
DoubleSlashComment = False
HashComment = False
PPExtend = False
CommentObj = None
PPDirectiveObj = None
# HashComment in quoted string " " is ignored.
InString = False
2018-07-05 11:40:04 +02:00
InCharLiteral = False
2009-07-17 11:10:31 +02:00
self . Profile . FileLinesList = [ list ( s ) for s in self . Profile . FileLinesListFromFile ]
while not self . __EndOfFile ( ) :
2018-07-05 11:40:04 +02:00
2009-07-17 11:10:31 +02:00
if not InComment and self . __CurrentChar ( ) == T_CHAR_DOUBLE_QUOTE :
InString = not InString
2018-07-05 11:40:04 +02:00
2009-07-17 11:10:31 +02:00
if not InComment and self . __CurrentChar ( ) == T_CHAR_SINGLE_QUOTE :
InCharLiteral = not InCharLiteral
# meet new line, then no longer in a comment for // and '#'
if self . __CurrentChar ( ) == T_CHAR_LF :
2018-03-26 22:25:43 +02:00
if HashComment and PPDirectiveObj is not None :
2009-07-17 11:10:31 +02:00
if PPDirectiveObj . Content . rstrip ( T_CHAR_CR ) . endswith ( T_CHAR_BACKSLASH ) :
PPDirectiveObj . Content + = T_CHAR_LF
PPExtend = True
else :
PPExtend = False
2018-07-05 11:40:04 +02:00
2009-07-17 11:10:31 +02:00
EndLinePos = ( self . CurrentLineNumber , self . CurrentOffsetWithinLine )
2018-07-05 11:40:04 +02:00
2009-07-17 11:10:31 +02:00
if InComment and DoubleSlashComment :
InComment = False
DoubleSlashComment = False
CommentObj . Content + = T_CHAR_LF
CommentObj . EndPos = EndLinePos
FileProfile . CommentList . append ( CommentObj )
CommentObj = None
if InComment and HashComment and not PPExtend :
InComment = False
HashComment = False
PPDirectiveObj . Content + = T_CHAR_LF
PPDirectiveObj . EndPos = EndLinePos
FileProfile . PPDirectiveList . append ( PPDirectiveObj )
PPDirectiveObj = None
2018-07-05 11:40:04 +02:00
2009-07-17 11:10:31 +02:00
if InString or InCharLiteral :
CurrentLine = " " . join ( self . __CurrentLine ( ) )
if CurrentLine . rstrip ( T_CHAR_LF ) . rstrip ( T_CHAR_CR ) . endswith ( T_CHAR_BACKSLASH ) :
SlashIndex = CurrentLine . rindex ( T_CHAR_BACKSLASH )
self . __SetCharValue ( self . CurrentLineNumber , SlashIndex , T_CHAR_SPACE )
2018-07-05 11:40:04 +02:00
2009-07-17 11:10:31 +02:00
if InComment and not DoubleSlashComment and not HashComment :
CommentObj . Content + = T_CHAR_LF
self . CurrentLineNumber + = 1
2018-07-05 11:40:04 +02:00
self . CurrentOffsetWithinLine = 0
2009-07-17 11:10:31 +02:00
# check for */ comment end
elif InComment and not DoubleSlashComment and not HashComment and self . __CurrentChar ( ) == T_CHAR_STAR and self . __NextChar ( ) == T_CHAR_SLASH :
CommentObj . Content + = self . __CurrentChar ( )
self . __SetCurrentCharValue ( T_CHAR_SPACE )
self . __GetOneChar ( )
CommentObj . Content + = self . __CurrentChar ( )
self . __SetCurrentCharValue ( T_CHAR_SPACE )
CommentObj . EndPos = ( self . CurrentLineNumber , self . CurrentOffsetWithinLine )
FileProfile . CommentList . append ( CommentObj )
CommentObj = None
self . __GetOneChar ( )
InComment = False
# set comments to spaces
2018-07-05 11:40:04 +02:00
elif InComment :
2009-07-17 11:10:31 +02:00
if HashComment :
# // follows hash PP directive
if self . __CurrentChar ( ) == T_CHAR_SLASH and self . __NextChar ( ) == T_CHAR_SLASH :
InComment = False
HashComment = False
PPDirectiveObj . EndPos = ( self . CurrentLineNumber , self . CurrentOffsetWithinLine - 1 )
FileProfile . PPDirectiveList . append ( PPDirectiveObj )
PPDirectiveObj = None
continue
else :
PPDirectiveObj . Content + = self . __CurrentChar ( )
# if PPExtend:
# self.__SetCurrentCharValue(T_CHAR_SPACE)
else :
CommentObj . Content + = self . __CurrentChar ( )
self . __SetCurrentCharValue ( T_CHAR_SPACE )
self . __GetOneChar ( )
# check for // comment
elif self . __CurrentChar ( ) == T_CHAR_SLASH and self . __NextChar ( ) == T_CHAR_SLASH :
InComment = True
DoubleSlashComment = True
CommentObj = Comment ( ' ' , ( self . CurrentLineNumber , self . CurrentOffsetWithinLine ) , None , T_COMMENT_TWO_SLASH )
# check for '#' comment
elif self . __CurrentChar ( ) == T_CHAR_HASH and not InString and not InCharLiteral :
InComment = True
2018-07-05 11:40:04 +02:00
HashComment = True
2009-07-17 11:10:31 +02:00
PPDirectiveObj = PP_Directive ( ' ' , ( self . CurrentLineNumber , self . CurrentOffsetWithinLine ) , None )
# check for /* comment start
elif self . __CurrentChar ( ) == T_CHAR_SLASH and self . __NextChar ( ) == T_CHAR_STAR :
CommentObj = Comment ( ' ' , ( self . CurrentLineNumber , self . CurrentOffsetWithinLine ) , None , T_COMMENT_SLASH_STAR )
CommentObj . Content + = self . __CurrentChar ( )
self . __SetCurrentCharValue ( T_CHAR_SPACE )
self . __GetOneChar ( )
CommentObj . Content + = self . __CurrentChar ( )
self . __SetCurrentCharValue ( T_CHAR_SPACE )
self . __GetOneChar ( )
InComment = True
else :
self . __GetOneChar ( )
EndLinePos = ( self . CurrentLineNumber , self . CurrentOffsetWithinLine )
2018-07-05 11:40:04 +02:00
2009-07-17 11:10:31 +02:00
if InComment and DoubleSlashComment :
CommentObj . EndPos = EndLinePos
FileProfile . CommentList . append ( CommentObj )
if InComment and HashComment and not PPExtend :
PPDirectiveObj . EndPos = EndLinePos
FileProfile . PPDirectiveList . append ( PPDirectiveObj )
self . Rewind ( )
## ParseFile() method
#
# Parse the file profile buffer to extract fd, fv ... information
# Exception will be raised if syntax error found
#
# @param self The object pointer
#
def ParseFile ( self ) :
self . PreprocessFile ( )
# restore from ListOfList to ListOfString
self . Profile . FileLinesList = [ " " . join ( list ) for list in self . Profile . FileLinesList ]
FileStringContents = ' '
for fileLine in self . Profile . FileLinesList :
FileStringContents + = fileLine
BaseTools:ECC report errors on account of analyze special characters
BZ:https://bugzilla.tianocore.org/show_bug.cgi?id=1751
In case that a C function body contains the string of L'', L'\"',
L"\"", L''', L""", L"\"\"", L"\"^", L" \"", L"\" \"", ('L",\\\""')
ECC tool running under python3 interpreter will report error.
The antlr4 module misidentified this character
This patch is going to fix that issue.
Cc: Bob Feng <bob.c.feng@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Signed-off-by: Zhiju.Fan <zhijux.fan@intel.com>
Reviewed-by: Bob Feng <bob.c.feng@intel.com>
2019-05-06 04:35:07 +02:00
for Token in self . TokenReleaceList :
if Token in FileStringContents :
FileStringContents = FileStringContents . replace ( Token , ' TOKENSTRING ' )
2019-01-04 10:35:10 +01:00
cStream = antlr . InputStream ( FileStringContents )
2009-07-17 11:10:31 +02:00
lexer = CLexer ( cStream )
2019-01-04 10:35:10 +01:00
tStream = antlr . CommonTokenStream ( lexer )
2009-07-17 11:10:31 +02:00
parser = CParser ( tStream )
parser . translation_unit ( )
2018-07-05 11:40:04 +02:00
2009-07-17 11:10:31 +02:00
def ParseFileWithClearedPPDirective ( self ) :
self . PreprocessFileWithClear ( )
# restore from ListOfList to ListOfString
self . Profile . FileLinesList = [ " " . join ( list ) for list in self . Profile . FileLinesList ]
FileStringContents = ' '
for fileLine in self . Profile . FileLinesList :
FileStringContents + = fileLine
2019-01-04 10:35:10 +01:00
cStream = antlr . InputStream ( FileStringContents )
2009-07-17 11:10:31 +02:00
lexer = CLexer ( cStream )
2019-01-04 10:35:10 +01:00
tStream = antlr . CommonTokenStream ( lexer )
2009-07-17 11:10:31 +02:00
parser = CParser ( tStream )
parser . translation_unit ( )
2018-07-05 11:40:04 +02:00
2009-07-17 11:10:31 +02:00
def CleanFileProfileBuffer ( self ) :
FileProfile . CommentList = [ ]
FileProfile . PPDirectiveList = [ ]
FileProfile . PredicateExpressionList = [ ]
FileProfile . FunctionDefinitionList = [ ]
FileProfile . VariableDeclarationList = [ ]
FileProfile . EnumerationDefinitionList = [ ]
FileProfile . StructUnionDefinitionList = [ ]
FileProfile . TypedefDefinitionList = [ ]
FileProfile . FunctionCallingList = [ ]
2018-07-05 11:40:04 +02:00
2009-07-17 11:10:31 +02:00
def PrintFragments ( self ) :
2018-07-05 11:40:04 +02:00
2018-06-25 12:31:26 +02:00
print ( ' ################# ' + self . FileName + ' ##################### ' )
2018-07-05 11:40:04 +02:00
2018-06-25 12:31:26 +02:00
print ( ' /****************************************/ ' )
print ( ' /*************** COMMENTS ***************/ ' )
print ( ' /****************************************/ ' )
2009-07-17 11:10:31 +02:00
for comment in FileProfile . CommentList :
2018-06-25 12:31:26 +02:00
print ( str ( comment . StartPos ) + comment . Content )
2018-07-05 11:40:04 +02:00
2018-06-25 12:31:26 +02:00
print ( ' /****************************************/ ' )
print ( ' /********* PREPROCESS DIRECTIVES ********/ ' )
print ( ' /****************************************/ ' )
2009-07-17 11:10:31 +02:00
for pp in FileProfile . PPDirectiveList :
2018-06-25 12:31:26 +02:00
print ( str ( pp . StartPos ) + pp . Content )
2018-07-05 11:40:04 +02:00
2018-06-25 12:31:26 +02:00
print ( ' /****************************************/ ' )
print ( ' /********* VARIABLE DECLARATIONS ********/ ' )
print ( ' /****************************************/ ' )
2009-07-17 11:10:31 +02:00
for var in FileProfile . VariableDeclarationList :
2018-06-25 12:31:26 +02:00
print ( str ( var . StartPos ) + var . Modifier + ' ' + var . Declarator )
2018-07-05 11:40:04 +02:00
2018-06-25 12:31:26 +02:00
print ( ' /****************************************/ ' )
print ( ' /********* FUNCTION DEFINITIONS *********/ ' )
print ( ' /****************************************/ ' )
2009-07-17 11:10:31 +02:00
for func in FileProfile . FunctionDefinitionList :
2018-06-25 12:31:26 +02:00
print ( str ( func . StartPos ) + func . Modifier + ' ' + func . Declarator + ' ' + str ( func . NamePos ) )
2018-07-05 11:40:04 +02:00
2018-06-25 12:31:26 +02:00
print ( ' /****************************************/ ' )
print ( ' /************ ENUMERATIONS **************/ ' )
print ( ' /****************************************/ ' )
2009-07-17 11:10:31 +02:00
for enum in FileProfile . EnumerationDefinitionList :
2018-06-25 12:31:26 +02:00
print ( str ( enum . StartPos ) + enum . Content )
2018-07-05 11:40:04 +02:00
2018-06-25 12:31:26 +02:00
print ( ' /****************************************/ ' )
print ( ' /*********** STRUCTS/UNIONS *************/ ' )
print ( ' /****************************************/ ' )
2009-07-17 11:10:31 +02:00
for su in FileProfile . StructUnionDefinitionList :
2018-06-25 12:31:26 +02:00
print ( str ( su . StartPos ) + su . Content )
2018-07-05 11:40:04 +02:00
2018-06-25 12:31:26 +02:00
print ( ' /****************************************/ ' )
print ( ' /********* PREDICATE EXPRESSIONS ********/ ' )
print ( ' /****************************************/ ' )
2009-07-17 11:10:31 +02:00
for predexp in FileProfile . PredicateExpressionList :
2018-06-25 12:31:26 +02:00
print ( str ( predexp . StartPos ) + predexp . Content )
2018-07-05 11:40:04 +02:00
2018-06-25 12:31:26 +02:00
print ( ' /****************************************/ ' )
print ( ' /************** TYPEDEFS ****************/ ' )
print ( ' /****************************************/ ' )
2009-07-17 11:10:31 +02:00
for typedef in FileProfile . TypedefDefinitionList :
2018-06-25 12:31:26 +02:00
print ( str ( typedef . StartPos ) + typedef . ToType )
2018-07-05 11:40:04 +02:00
2009-07-17 11:10:31 +02:00
if __name__ == " __main__ " :
2018-07-05 11:40:04 +02:00
2009-07-17 11:10:31 +02:00
collector = CodeFragmentCollector ( sys . argv [ 1 ] )
collector . PreprocessFile ( )
2018-06-25 12:31:26 +02:00
print ( " For Test. " )