Check In tool source code based on Build tool project revision r1655.
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@8964 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
626
BaseTools/Source/Python/Ecc/C.g
Normal file
626
BaseTools/Source/Python/Ecc/C.g
Normal file
@ -0,0 +1,626 @@
|
||||
|
||||
grammar C;
|
||||
options {
|
||||
language=Python;
|
||||
backtrack=true;
|
||||
memoize=true;
|
||||
k=2;
|
||||
}
|
||||
|
||||
@header {
|
||||
import CodeFragment
|
||||
import FileProfile
|
||||
}
|
||||
|
||||
@members {
|
||||
|
||||
def printTokenInfo(self, line, offset, tokenText):
|
||||
print str(line)+ ',' + str(offset) + ':' + str(tokenText)
|
||||
|
||||
def StorePredicateExpression(self, StartLine, StartOffset, EndLine, EndOffset, Text):
|
||||
PredExp = CodeFragment.PredicateExpression(Text, (StartLine, StartOffset), (EndLine, EndOffset))
|
||||
FileProfile.PredicateExpressionList.append(PredExp)
|
||||
|
||||
def StoreEnumerationDefinition(self, StartLine, StartOffset, EndLine, EndOffset, Text):
|
||||
EnumDef = CodeFragment.EnumerationDefinition(Text, (StartLine, StartOffset), (EndLine, EndOffset))
|
||||
FileProfile.EnumerationDefinitionList.append(EnumDef)
|
||||
|
||||
def StoreStructUnionDefinition(self, StartLine, StartOffset, EndLine, EndOffset, Text):
|
||||
SUDef = CodeFragment.StructUnionDefinition(Text, (StartLine, StartOffset), (EndLine, EndOffset))
|
||||
FileProfile.StructUnionDefinitionList.append(SUDef)
|
||||
|
||||
def StoreTypedefDefinition(self, StartLine, StartOffset, EndLine, EndOffset, FromText, ToText):
|
||||
Tdef = CodeFragment.TypedefDefinition(FromText, ToText, (StartLine, StartOffset), (EndLine, EndOffset))
|
||||
FileProfile.TypedefDefinitionList.append(Tdef)
|
||||
|
||||
def StoreFunctionDefinition(self, StartLine, StartOffset, EndLine, EndOffset, ModifierText, DeclText, LeftBraceLine, LeftBraceOffset, DeclLine, DeclOffset):
|
||||
FuncDef = CodeFragment.FunctionDefinition(ModifierText, DeclText, (StartLine, StartOffset), (EndLine, EndOffset), (LeftBraceLine, LeftBraceOffset), (DeclLine, DeclOffset))
|
||||
FileProfile.FunctionDefinitionList.append(FuncDef)
|
||||
|
||||
def StoreVariableDeclaration(self, StartLine, StartOffset, EndLine, EndOffset, ModifierText, DeclText):
|
||||
VarDecl = CodeFragment.VariableDeclaration(ModifierText, DeclText, (StartLine, StartOffset), (EndLine, EndOffset))
|
||||
FileProfile.VariableDeclarationList.append(VarDecl)
|
||||
|
||||
def StoreFunctionCalling(self, StartLine, StartOffset, EndLine, EndOffset, FuncName, ParamList):
|
||||
FuncCall = CodeFragment.FunctionCalling(FuncName, ParamList, (StartLine, StartOffset), (EndLine, EndOffset))
|
||||
FileProfile.FunctionCallingList.append(FuncCall)
|
||||
|
||||
}
|
||||
|
||||
translation_unit
|
||||
: external_declaration*
|
||||
;
|
||||
|
||||
|
||||
/*function_declaration
|
||||
@after{
|
||||
print $function_declaration.text
|
||||
}
|
||||
: declaration_specifiers IDENTIFIER '(' parameter_list ')' ';'
|
||||
;
|
||||
*/
|
||||
external_declaration
|
||||
options {k=1;}
|
||||
/*@after{
|
||||
print $external_declaration.text
|
||||
}*/
|
||||
: ( declaration_specifiers? declarator declaration* '{' )=> function_definition
|
||||
| declaration
|
||||
| macro_statement (';')?
|
||||
;
|
||||
|
||||
|
||||
|
||||
function_definition
|
||||
scope {
|
||||
ModifierText;
|
||||
DeclText;
|
||||
LBLine;
|
||||
LBOffset;
|
||||
DeclLine;
|
||||
DeclOffset;
|
||||
}
|
||||
@init {
|
||||
$function_definition::ModifierText = '';
|
||||
$function_definition::DeclText = '';
|
||||
$function_definition::LBLine = 0;
|
||||
$function_definition::LBOffset = 0;
|
||||
$function_definition::DeclLine = 0;
|
||||
$function_definition::DeclOffset = 0;
|
||||
}
|
||||
@after{
|
||||
self.StoreFunctionDefinition($function_definition.start.line, $function_definition.start.charPositionInLine, $function_definition.stop.line, $function_definition.stop.charPositionInLine, $function_definition::ModifierText, $function_definition::DeclText, $function_definition::LBLine, $function_definition::LBOffset, $function_definition::DeclLine, $function_definition::DeclOffset)
|
||||
}
|
||||
: d=declaration_specifiers? declarator
|
||||
( declaration+ a=compound_statement // K&R style
|
||||
| b=compound_statement // ANSI style
|
||||
) {
|
||||
if d != None:
|
||||
$function_definition::ModifierText = $declaration_specifiers.text
|
||||
else:
|
||||
$function_definition::ModifierText = ''
|
||||
$function_definition::DeclText = $declarator.text
|
||||
$function_definition::DeclLine = $declarator.start.line
|
||||
$function_definition::DeclOffset = $declarator.start.charPositionInLine
|
||||
if a != None:
|
||||
$function_definition::LBLine = $a.start.line
|
||||
$function_definition::LBOffset = $a.start.charPositionInLine
|
||||
else:
|
||||
$function_definition::LBLine = $b.start.line
|
||||
$function_definition::LBOffset = $b.start.charPositionInLine
|
||||
}
|
||||
;
|
||||
|
||||
declaration
|
||||
: a='typedef' b=declaration_specifiers?
|
||||
c=init_declarator_list d=';'
|
||||
{
|
||||
if b != None:
|
||||
self.StoreTypedefDefinition($a.line, $a.charPositionInLine, $d.line, $d.charPositionInLine, $b.text, $c.text)
|
||||
else:
|
||||
self.StoreTypedefDefinition($a.line, $a.charPositionInLine, $d.line, $d.charPositionInLine, '', $c.text)
|
||||
}
|
||||
| s=declaration_specifiers t=init_declarator_list? e=';'
|
||||
{
|
||||
if t != None:
|
||||
self.StoreVariableDeclaration($s.start.line, $s.start.charPositionInLine, $t.start.line, $t.start.charPositionInLine, $s.text, $t.text)
|
||||
}
|
||||
;
|
||||
|
||||
declaration_specifiers
|
||||
: ( storage_class_specifier
|
||||
| type_specifier
|
||||
| type_qualifier
|
||||
)+
|
||||
;
|
||||
|
||||
init_declarator_list
|
||||
: init_declarator (',' init_declarator)*
|
||||
;
|
||||
|
||||
init_declarator
|
||||
: declarator ('=' initializer)?
|
||||
;
|
||||
|
||||
storage_class_specifier
|
||||
: 'extern'
|
||||
| 'static'
|
||||
| 'auto'
|
||||
| 'register'
|
||||
| 'STATIC'
|
||||
;
|
||||
|
||||
type_specifier
|
||||
: 'void'
|
||||
| 'char'
|
||||
| 'short'
|
||||
| 'int'
|
||||
| 'long'
|
||||
| 'float'
|
||||
| 'double'
|
||||
| 'signed'
|
||||
| 'unsigned'
|
||||
| s=struct_or_union_specifier
|
||||
{
|
||||
if s.stop != None:
|
||||
self.StoreStructUnionDefinition($s.start.line, $s.start.charPositionInLine, $s.stop.line, $s.stop.charPositionInLine, $s.text)
|
||||
}
|
||||
| e=enum_specifier
|
||||
{
|
||||
if e.stop != None:
|
||||
self.StoreEnumerationDefinition($e.start.line, $e.start.charPositionInLine, $e.stop.line, $e.stop.charPositionInLine, $e.text)
|
||||
}
|
||||
| (IDENTIFIER type_qualifier* declarator)=> type_id
|
||||
;
|
||||
|
||||
type_id
|
||||
: IDENTIFIER
|
||||
//{self.printTokenInfo($a.line, $a.pos, $a.text)}
|
||||
;
|
||||
|
||||
struct_or_union_specifier
|
||||
options {k=3;}
|
||||
: struct_or_union IDENTIFIER? '{' struct_declaration_list '}'
|
||||
| struct_or_union IDENTIFIER
|
||||
;
|
||||
|
||||
struct_or_union
|
||||
: 'struct'
|
||||
| 'union'
|
||||
;
|
||||
|
||||
struct_declaration_list
|
||||
: struct_declaration+
|
||||
;
|
||||
|
||||
struct_declaration
|
||||
: specifier_qualifier_list struct_declarator_list ';'
|
||||
;
|
||||
|
||||
specifier_qualifier_list
|
||||
: ( type_qualifier | type_specifier )+
|
||||
;
|
||||
|
||||
struct_declarator_list
|
||||
: struct_declarator (',' struct_declarator)*
|
||||
;
|
||||
|
||||
struct_declarator
|
||||
: declarator (':' constant_expression)?
|
||||
| ':' constant_expression
|
||||
;
|
||||
|
||||
enum_specifier
|
||||
options {k=3;}
|
||||
: 'enum' '{' enumerator_list ','? '}'
|
||||
| 'enum' IDENTIFIER '{' enumerator_list ','? '}'
|
||||
| 'enum' IDENTIFIER
|
||||
;
|
||||
|
||||
enumerator_list
|
||||
: enumerator (',' enumerator)*
|
||||
;
|
||||
|
||||
enumerator
|
||||
: IDENTIFIER ('=' constant_expression)?
|
||||
;
|
||||
|
||||
type_qualifier
|
||||
: 'const'
|
||||
| 'volatile'
|
||||
| 'IN'
|
||||
| 'OUT'
|
||||
| 'OPTIONAL'
|
||||
| 'CONST'
|
||||
| 'UNALIGNED'
|
||||
| 'VOLATILE'
|
||||
| 'GLOBAL_REMOVE_IF_UNREFERENCED'
|
||||
| 'EFIAPI'
|
||||
| 'EFI_BOOTSERVICE'
|
||||
| 'EFI_RUNTIMESERVICE'
|
||||
;
|
||||
|
||||
declarator
|
||||
: pointer? ('EFIAPI')? ('EFI_BOOTSERVICE')? ('EFI_RUNTIMESERVICE')? direct_declarator
|
||||
// | ('EFIAPI')? ('EFI_BOOTSERVICE')? ('EFI_RUNTIMESERVICE')? pointer? direct_declarator
|
||||
| pointer
|
||||
;
|
||||
|
||||
direct_declarator
|
||||
: IDENTIFIER declarator_suffix*
|
||||
| '(' ('EFIAPI')? declarator ')' declarator_suffix+
|
||||
;
|
||||
|
||||
declarator_suffix
|
||||
: '[' constant_expression ']'
|
||||
| '[' ']'
|
||||
| '(' parameter_type_list ')'
|
||||
| '(' identifier_list ')'
|
||||
| '(' ')'
|
||||
;
|
||||
|
||||
pointer
|
||||
: '*' type_qualifier+ pointer?
|
||||
| '*' pointer
|
||||
| '*'
|
||||
;
|
||||
|
||||
parameter_type_list
|
||||
: parameter_list (',' ('OPTIONAL')? '...')?
|
||||
;
|
||||
|
||||
parameter_list
|
||||
: parameter_declaration (',' ('OPTIONAL')? parameter_declaration)*
|
||||
;
|
||||
|
||||
parameter_declaration
|
||||
: declaration_specifiers (declarator|abstract_declarator)* ('OPTIONAL')?
|
||||
//accomerdate user-defined type only, no declarator follow.
|
||||
| pointer* IDENTIFIER
|
||||
;
|
||||
|
||||
identifier_list
|
||||
: IDENTIFIER
|
||||
(',' IDENTIFIER)*
|
||||
;
|
||||
|
||||
type_name
|
||||
: specifier_qualifier_list abstract_declarator?
|
||||
| type_id
|
||||
;
|
||||
|
||||
abstract_declarator
|
||||
: pointer direct_abstract_declarator?
|
||||
| direct_abstract_declarator
|
||||
;
|
||||
|
||||
direct_abstract_declarator
|
||||
: ( '(' abstract_declarator ')' | abstract_declarator_suffix ) abstract_declarator_suffix*
|
||||
;
|
||||
|
||||
abstract_declarator_suffix
|
||||
: '[' ']'
|
||||
| '[' constant_expression ']'
|
||||
| '(' ')'
|
||||
| '(' parameter_type_list ')'
|
||||
;
|
||||
|
||||
initializer
|
||||
|
||||
: assignment_expression
|
||||
| '{' initializer_list ','? '}'
|
||||
;
|
||||
|
||||
initializer_list
|
||||
: initializer (',' initializer )*
|
||||
;
|
||||
|
||||
// E x p r e s s i o n s
|
||||
|
||||
argument_expression_list
|
||||
: assignment_expression ('OPTIONAL')? (',' assignment_expression ('OPTIONAL')?)*
|
||||
;
|
||||
|
||||
additive_expression
|
||||
: (multiplicative_expression) ('+' multiplicative_expression | '-' multiplicative_expression)*
|
||||
;
|
||||
|
||||
multiplicative_expression
|
||||
: (cast_expression) ('*' cast_expression | '/' cast_expression | '%' cast_expression)*
|
||||
;
|
||||
|
||||
cast_expression
|
||||
: '(' type_name ')' cast_expression
|
||||
| unary_expression
|
||||
;
|
||||
|
||||
unary_expression
|
||||
: postfix_expression
|
||||
| '++' unary_expression
|
||||
| '--' unary_expression
|
||||
| unary_operator cast_expression
|
||||
| 'sizeof' unary_expression
|
||||
| 'sizeof' '(' type_name ')'
|
||||
;
|
||||
|
||||
postfix_expression
|
||||
scope {
|
||||
FuncCallText;
|
||||
}
|
||||
@init {
|
||||
$postfix_expression::FuncCallText = '';
|
||||
}
|
||||
: p=primary_expression {$postfix_expression::FuncCallText += $p.text}
|
||||
( '[' expression ']'
|
||||
| '(' a=')'{self.StoreFunctionCalling($p.start.line, $p.start.charPositionInLine, $a.line, $a.charPositionInLine, $postfix_expression::FuncCallText, '')}
|
||||
| '(' c=argument_expression_list b=')' {self.StoreFunctionCalling($p.start.line, $p.start.charPositionInLine, $b.line, $b.charPositionInLine, $postfix_expression::FuncCallText, $c.text)}
|
||||
| '(' macro_parameter_list ')'
|
||||
| '.' x=IDENTIFIER {$postfix_expression::FuncCallText += '.' + $x.text}
|
||||
| '*' y=IDENTIFIER {$postfix_expression::FuncCallText = $y.text}
|
||||
| '->' z=IDENTIFIER {$postfix_expression::FuncCallText += '->' + $z.text}
|
||||
| '++'
|
||||
| '--'
|
||||
)*
|
||||
;
|
||||
|
||||
macro_parameter_list
|
||||
: parameter_declaration (',' parameter_declaration)*
|
||||
;
|
||||
|
||||
unary_operator
|
||||
: '&'
|
||||
| '*'
|
||||
| '+'
|
||||
| '-'
|
||||
| '~'
|
||||
| '!'
|
||||
;
|
||||
|
||||
primary_expression
|
||||
: IDENTIFIER
|
||||
| constant
|
||||
| '(' expression ')'
|
||||
;
|
||||
|
||||
constant
|
||||
: HEX_LITERAL
|
||||
| OCTAL_LITERAL
|
||||
| DECIMAL_LITERAL
|
||||
| CHARACTER_LITERAL
|
||||
| (IDENTIFIER* STRING_LITERAL+)+ IDENTIFIER*
|
||||
| FLOATING_POINT_LITERAL
|
||||
;
|
||||
|
||||
/////
|
||||
|
||||
expression
|
||||
: assignment_expression (',' assignment_expression)*
|
||||
;
|
||||
|
||||
constant_expression
|
||||
: conditional_expression
|
||||
;
|
||||
|
||||
assignment_expression
|
||||
: lvalue assignment_operator assignment_expression
|
||||
| conditional_expression
|
||||
;
|
||||
|
||||
lvalue
|
||||
: unary_expression
|
||||
;
|
||||
|
||||
assignment_operator
|
||||
: '='
|
||||
| '*='
|
||||
| '/='
|
||||
| '%='
|
||||
| '+='
|
||||
| '-='
|
||||
| '<<='
|
||||
| '>>='
|
||||
| '&='
|
||||
| '^='
|
||||
| '|='
|
||||
;
|
||||
|
||||
conditional_expression
|
||||
: e=logical_or_expression ('?' expression ':' conditional_expression {self.StorePredicateExpression($e.start.line, $e.start.charPositionInLine, $e.stop.line, $e.stop.charPositionInLine, $e.text)})?
|
||||
;
|
||||
|
||||
logical_or_expression
|
||||
: logical_and_expression ('||' logical_and_expression)*
|
||||
;
|
||||
|
||||
logical_and_expression
|
||||
: inclusive_or_expression ('&&' inclusive_or_expression)*
|
||||
;
|
||||
|
||||
inclusive_or_expression
|
||||
: exclusive_or_expression ('|' exclusive_or_expression)*
|
||||
;
|
||||
|
||||
exclusive_or_expression
|
||||
: and_expression ('^' and_expression)*
|
||||
;
|
||||
|
||||
and_expression
|
||||
: equality_expression ('&' equality_expression)*
|
||||
;
|
||||
equality_expression
|
||||
: relational_expression (('=='|'!=') relational_expression )*
|
||||
;
|
||||
|
||||
relational_expression
|
||||
: shift_expression (('<'|'>'|'<='|'>=') shift_expression)*
|
||||
;
|
||||
|
||||
shift_expression
|
||||
: additive_expression (('<<'|'>>') additive_expression)*
|
||||
;
|
||||
|
||||
// S t a t e m e n t s
|
||||
|
||||
statement
|
||||
: labeled_statement
|
||||
| compound_statement
|
||||
| expression_statement
|
||||
| selection_statement
|
||||
| iteration_statement
|
||||
| jump_statement
|
||||
| macro_statement
|
||||
| asm2_statement
|
||||
| asm1_statement
|
||||
| asm_statement
|
||||
| declaration
|
||||
;
|
||||
|
||||
asm2_statement
|
||||
: '__asm__'? IDENTIFIER '(' (~(';'))* ')' ';'
|
||||
;
|
||||
|
||||
asm1_statement
|
||||
: '_asm' '{' (~('}'))* '}'
|
||||
;
|
||||
|
||||
asm_statement
|
||||
: '__asm' '{' (~('}'))* '}'
|
||||
;
|
||||
|
||||
macro_statement
|
||||
: IDENTIFIER '(' declaration* statement_list? expression? ')'
|
||||
;
|
||||
|
||||
labeled_statement
|
||||
: IDENTIFIER ':' statement
|
||||
| 'case' constant_expression ':' statement
|
||||
| 'default' ':' statement
|
||||
;
|
||||
|
||||
compound_statement
|
||||
: '{' declaration* statement_list? '}'
|
||||
;
|
||||
|
||||
statement_list
|
||||
: statement+
|
||||
;
|
||||
|
||||
expression_statement
|
||||
: ';'
|
||||
| expression ';'
|
||||
;
|
||||
|
||||
selection_statement
|
||||
: 'if' '(' e=expression ')' {self.StorePredicateExpression($e.start.line, $e.start.charPositionInLine, $e.stop.line, $e.stop.charPositionInLine, $e.text)} statement (options {k=1; backtrack=false;}:'else' statement)?
|
||||
| 'switch' '(' expression ')' statement
|
||||
;
|
||||
|
||||
iteration_statement
|
||||
: 'while' '(' e=expression ')' statement {self.StorePredicateExpression($e.start.line, $e.start.charPositionInLine, $e.stop.line, $e.stop.charPositionInLine, $e.text)}
|
||||
| 'do' statement 'while' '(' e=expression ')' ';' {self.StorePredicateExpression($e.start.line, $e.start.charPositionInLine, $e.stop.line, $e.stop.charPositionInLine, $e.text)}
|
||||
| 'for' '(' expression_statement e=expression_statement expression? ')' statement {self.StorePredicateExpression($e.start.line, $e.start.charPositionInLine, $e.stop.line, $e.stop.charPositionInLine, $e.text)}
|
||||
;
|
||||
|
||||
jump_statement
|
||||
: 'goto' IDENTIFIER ';'
|
||||
| 'continue' ';'
|
||||
| 'break' ';'
|
||||
| 'return' ';'
|
||||
| 'return' expression ';'
|
||||
;
|
||||
|
||||
IDENTIFIER
|
||||
: LETTER (LETTER|'0'..'9')*
|
||||
;
|
||||
|
||||
fragment
|
||||
LETTER
|
||||
: '$'
|
||||
| 'A'..'Z'
|
||||
| 'a'..'z'
|
||||
| '_'
|
||||
;
|
||||
|
||||
CHARACTER_LITERAL
|
||||
: ('L')? '\'' ( EscapeSequence | ~('\''|'\\') ) '\''
|
||||
;
|
||||
|
||||
STRING_LITERAL
|
||||
: ('L')? '"' ( EscapeSequence | ~('\\'|'"') )* '"'
|
||||
;
|
||||
|
||||
HEX_LITERAL : '0' ('x'|'X') HexDigit+ IntegerTypeSuffix? ;
|
||||
|
||||
DECIMAL_LITERAL : ('0' | '1'..'9' '0'..'9'*) IntegerTypeSuffix? ;
|
||||
|
||||
OCTAL_LITERAL : '0' ('0'..'7')+ IntegerTypeSuffix? ;
|
||||
|
||||
fragment
|
||||
HexDigit : ('0'..'9'|'a'..'f'|'A'..'F') ;
|
||||
|
||||
fragment
|
||||
IntegerTypeSuffix
|
||||
: ('u'|'U')
|
||||
| ('l'|'L')
|
||||
| ('u'|'U') ('l'|'L')
|
||||
| ('u'|'U') ('l'|'L') ('l'|'L')
|
||||
;
|
||||
|
||||
FLOATING_POINT_LITERAL
|
||||
: ('0'..'9')+ '.' ('0'..'9')* Exponent? FloatTypeSuffix?
|
||||
| '.' ('0'..'9')+ Exponent? FloatTypeSuffix?
|
||||
| ('0'..'9')+ Exponent FloatTypeSuffix?
|
||||
| ('0'..'9')+ Exponent? FloatTypeSuffix
|
||||
;
|
||||
|
||||
fragment
|
||||
Exponent : ('e'|'E') ('+'|'-')? ('0'..'9')+ ;
|
||||
|
||||
fragment
|
||||
FloatTypeSuffix : ('f'|'F'|'d'|'D') ;
|
||||
|
||||
fragment
|
||||
EscapeSequence
|
||||
: '\\' ('b'|'t'|'n'|'f'|'r'|'\"'|'\''|'\\')
|
||||
| OctalEscape
|
||||
;
|
||||
|
||||
fragment
|
||||
OctalEscape
|
||||
: '\\' ('0'..'3') ('0'..'7') ('0'..'7')
|
||||
| '\\' ('0'..'7') ('0'..'7')
|
||||
| '\\' ('0'..'7')
|
||||
;
|
||||
|
||||
fragment
|
||||
UnicodeEscape
|
||||
: '\\' 'u' HexDigit HexDigit HexDigit HexDigit
|
||||
;
|
||||
|
||||
WS : (' '|'\r'|'\t'|'\u000C'|'\n') {$channel=HIDDEN;}
|
||||
;
|
||||
|
||||
// ingore '\' of line concatenation
|
||||
BS : ('\\') {$channel=HIDDEN;}
|
||||
;
|
||||
|
||||
// ingore function modifiers
|
||||
//FUNC_MODIFIERS : 'EFIAPI' {$channel=HIDDEN;}
|
||||
// ;
|
||||
|
||||
UnicodeVocabulary
|
||||
: '\u0003'..'\uFFFE'
|
||||
;
|
||||
COMMENT
|
||||
: '/*' ( options {greedy=false;} : . )* '*/' {$channel=HIDDEN;}
|
||||
;
|
||||
|
||||
|
||||
LINE_COMMENT
|
||||
: '//' ~('\n'|'\r')* '\r'? '\n' {$channel=HIDDEN;}
|
||||
;
|
||||
|
||||
// ignore #line info for now
|
||||
LINE_COMMAND
|
||||
: '#' ~('\n'|'\r')* '\r'? '\n' {$channel=HIDDEN;}
|
||||
;
|
4887
BaseTools/Source/Python/Ecc/CLexer.py
Normal file
4887
BaseTools/Source/Python/Ecc/CLexer.py
Normal file
File diff suppressed because it is too large
Load Diff
18825
BaseTools/Source/Python/Ecc/CParser.py
Normal file
18825
BaseTools/Source/Python/Ecc/CParser.py
Normal file
File diff suppressed because it is too large
Load Diff
865
BaseTools/Source/Python/Ecc/Check.py
Normal file
865
BaseTools/Source/Python/Ecc/Check.py
Normal file
@ -0,0 +1,865 @@
|
||||
## @file
|
||||
# This file is used to define checkpoints used by ECC tool
|
||||
#
|
||||
# Copyright (c) 2008, Intel Corporation
|
||||
# All rights reserved. This program and the accompanying materials
|
||||
# are licensed and made available under the terms and conditions of the BSD License
|
||||
# which accompanies this distribution. The full text of the license may be found at
|
||||
# http://opensource.org/licenses/bsd-license.php
|
||||
#
|
||||
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
#
|
||||
import os
|
||||
import re
|
||||
from CommonDataClass.DataClass import *
|
||||
from Common.DataType import SUP_MODULE_LIST_STRING, TAB_VALUE_SPLIT
|
||||
from EccToolError import *
|
||||
import EccGlobalData
|
||||
import c
|
||||
|
||||
## Check
|
||||
#
|
||||
# This class is to define checkpoints used by ECC tool
|
||||
#
|
||||
# @param object: Inherited from object class
|
||||
#
|
||||
class Check(object):
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
# Check all required checkpoints
|
||||
def Check(self):
|
||||
self.MetaDataFileCheck()
|
||||
self.DoxygenCheck()
|
||||
self.IncludeFileCheck()
|
||||
self.PredicateExpressionCheck()
|
||||
self.DeclAndDataTypeCheck()
|
||||
self.FunctionLayoutCheck()
|
||||
self.NamingConventionCheck()
|
||||
|
||||
# C Function Layout Checking
|
||||
def FunctionLayoutCheck(self):
|
||||
self.FunctionLayoutCheckReturnType()
|
||||
self.FunctionLayoutCheckModifier()
|
||||
self.FunctionLayoutCheckName()
|
||||
self.FunctionLayoutCheckPrototype()
|
||||
self.FunctionLayoutCheckBody()
|
||||
self.FunctionLayoutCheckLocalVariable()
|
||||
|
||||
def WalkTree(self):
|
||||
IgnoredPattern = c.GetIgnoredDirListPattern()
|
||||
for Dirpath, Dirnames, Filenames in os.walk(EccGlobalData.gTarget):
|
||||
for Dir in Dirnames:
|
||||
Dirname = os.path.join(Dirpath, Dir)
|
||||
if os.path.islink(Dirname):
|
||||
Dirname = os.path.realpath(Dirname)
|
||||
if os.path.isdir(Dirname):
|
||||
# symlinks to directories are treated as directories
|
||||
Dirnames.remove(Dir)
|
||||
Dirnames.append(Dirname)
|
||||
if IgnoredPattern.match(Dirpath.upper()):
|
||||
continue
|
||||
yield (Dirpath, Dirnames, Filenames)
|
||||
|
||||
# Check whether return type exists and in the first line
|
||||
def FunctionLayoutCheckReturnType(self):
|
||||
if EccGlobalData.gConfig.CFunctionLayoutCheckReturnType == '1' or EccGlobalData.gConfig.CFunctionLayoutCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
|
||||
EdkLogger.quiet("Checking function layout return type ...")
|
||||
|
||||
for Dirpath, Dirnames, Filenames in self.WalkTree():
|
||||
for F in Filenames:
|
||||
if os.path.splitext(F)[1] in ('.c', '.h'):
|
||||
FullName = os.path.join(Dirpath, F)
|
||||
c.CheckFuncLayoutReturnType(FullName)
|
||||
|
||||
# Check whether any optional functional modifiers exist and next to the return type
|
||||
def FunctionLayoutCheckModifier(self):
|
||||
if EccGlobalData.gConfig.CFunctionLayoutCheckOptionalFunctionalModifier == '1' or EccGlobalData.gConfig.CFunctionLayoutCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
|
||||
EdkLogger.quiet("Checking function layout modifier ...")
|
||||
|
||||
for Dirpath, Dirnames, Filenames in self.WalkTree():
|
||||
for F in Filenames:
|
||||
if os.path.splitext(F)[1] in ('.c', '.h'):
|
||||
FullName = os.path.join(Dirpath, F)
|
||||
c.CheckFuncLayoutModifier(FullName)
|
||||
|
||||
# Check whether the next line contains the function name, left justified, followed by the beginning of the parameter list
|
||||
# Check whether the closing parenthesis is on its own line and also indented two spaces
|
||||
def FunctionLayoutCheckName(self):
|
||||
if EccGlobalData.gConfig.CFunctionLayoutCheckFunctionName == '1' or EccGlobalData.gConfig.CFunctionLayoutCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
|
||||
EdkLogger.quiet("Checking function layout function name ...")
|
||||
|
||||
for Dirpath, Dirnames, Filenames in self.WalkTree():
|
||||
for F in Filenames:
|
||||
if os.path.splitext(F)[1] in ('.c', '.h'):
|
||||
FullName = os.path.join(Dirpath, F)
|
||||
c.CheckFuncLayoutName(FullName)
|
||||
# Check whether the function prototypes in include files have the same form as function definitions
|
||||
def FunctionLayoutCheckPrototype(self):
|
||||
if EccGlobalData.gConfig.CFunctionLayoutCheckFunctionPrototype == '1' or EccGlobalData.gConfig.CFunctionLayoutCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
|
||||
EdkLogger.quiet("Checking function layout function prototype ...")
|
||||
|
||||
for Dirpath, Dirnames, Filenames in self.WalkTree():
|
||||
for F in Filenames:
|
||||
if os.path.splitext(F)[1] in ('.c'):
|
||||
FullName = os.path.join(Dirpath, F)
|
||||
EdkLogger.quiet("[PROTOTYPE]" + FullName)
|
||||
c.CheckFuncLayoutPrototype(FullName)
|
||||
|
||||
# Check whether the body of a function is contained by open and close braces that must be in the first column
|
||||
def FunctionLayoutCheckBody(self):
|
||||
if EccGlobalData.gConfig.CFunctionLayoutCheckFunctionBody == '1' or EccGlobalData.gConfig.CFunctionLayoutCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
|
||||
EdkLogger.quiet("Checking function layout function body ...")
|
||||
|
||||
for Dirpath, Dirnames, Filenames in self.WalkTree():
|
||||
for F in Filenames:
|
||||
if os.path.splitext(F)[1] in ('.c'):
|
||||
FullName = os.path.join(Dirpath, F)
|
||||
c.CheckFuncLayoutBody(FullName)
|
||||
|
||||
# Check whether the data declarations is the first code in a module.
|
||||
# self.CFunctionLayoutCheckDataDeclaration = 1
|
||||
# Check whether no initialization of a variable as part of its declaration
|
||||
def FunctionLayoutCheckLocalVariable(self):
|
||||
if EccGlobalData.gConfig.CFunctionLayoutCheckNoInitOfVariable == '1' or EccGlobalData.gConfig.CFunctionLayoutCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
|
||||
EdkLogger.quiet("Checking function layout local variables ...")
|
||||
|
||||
for Dirpath, Dirnames, Filenames in self.WalkTree():
|
||||
for F in Filenames:
|
||||
if os.path.splitext(F)[1] in ('.c'):
|
||||
FullName = os.path.join(Dirpath, F)
|
||||
c.CheckFuncLayoutLocalVariable(FullName)
|
||||
|
||||
# Check whether no use of STATIC for functions
|
||||
# self.CFunctionLayoutCheckNoStatic = 1
|
||||
|
||||
# Declarations and Data Types Checking
|
||||
def DeclAndDataTypeCheck(self):
|
||||
self.DeclCheckNoUseCType()
|
||||
self.DeclCheckInOutModifier()
|
||||
self.DeclCheckEFIAPIModifier()
|
||||
self.DeclCheckEnumeratedType()
|
||||
self.DeclCheckStructureDeclaration()
|
||||
self.DeclCheckSameStructure()
|
||||
self.DeclCheckUnionType()
|
||||
|
||||
|
||||
# Check whether no use of int, unsigned, char, void, static, long in any .c, .h or .asl files.
|
||||
def DeclCheckNoUseCType(self):
|
||||
if EccGlobalData.gConfig.DeclarationDataTypeCheckNoUseCType == '1' or EccGlobalData.gConfig.DeclarationDataTypeCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
|
||||
EdkLogger.quiet("Checking Declaration No use C type ...")
|
||||
|
||||
for Dirpath, Dirnames, Filenames in self.WalkTree():
|
||||
for F in Filenames:
|
||||
if os.path.splitext(F)[1] in ('.h', '.c'):
|
||||
FullName = os.path.join(Dirpath, F)
|
||||
c.CheckDeclNoUseCType(FullName)
|
||||
|
||||
# Check whether the modifiers IN, OUT, OPTIONAL, and UNALIGNED are used only to qualify arguments to a function and should not appear in a data type declaration
|
||||
def DeclCheckInOutModifier(self):
|
||||
if EccGlobalData.gConfig.DeclarationDataTypeCheckInOutModifier == '1' or EccGlobalData.gConfig.DeclarationDataTypeCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
|
||||
EdkLogger.quiet("Checking Declaration argument modifier ...")
|
||||
|
||||
for Dirpath, Dirnames, Filenames in self.WalkTree():
|
||||
for F in Filenames:
|
||||
if os.path.splitext(F)[1] in ('.h', '.c'):
|
||||
FullName = os.path.join(Dirpath, F)
|
||||
c.CheckDeclArgModifier(FullName)
|
||||
|
||||
# Check whether the EFIAPI modifier should be used at the entry of drivers, events, and member functions of protocols
|
||||
def DeclCheckEFIAPIModifier(self):
|
||||
if EccGlobalData.gConfig.DeclarationDataTypeCheckEFIAPIModifier == '1' or EccGlobalData.gConfig.DeclarationDataTypeCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
|
||||
pass
|
||||
|
||||
# Check whether Enumerated Type has a 'typedef' and the name is capital
|
||||
def DeclCheckEnumeratedType(self):
|
||||
if EccGlobalData.gConfig.DeclarationDataTypeCheckEnumeratedType == '1' or EccGlobalData.gConfig.DeclarationDataTypeCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
|
||||
EdkLogger.quiet("Checking Declaration enum typedef ...")
|
||||
|
||||
for Dirpath, Dirnames, Filenames in self.WalkTree():
|
||||
for F in Filenames:
|
||||
if os.path.splitext(F)[1] in ('.h', '.c'):
|
||||
FullName = os.path.join(Dirpath, F)
|
||||
EdkLogger.quiet("[ENUM]" + FullName)
|
||||
c.CheckDeclEnumTypedef(FullName)
|
||||
|
||||
# Check whether Structure Type has a 'typedef' and the name is capital
|
||||
def DeclCheckStructureDeclaration(self):
|
||||
if EccGlobalData.gConfig.DeclarationDataTypeCheckStructureDeclaration == '1' or EccGlobalData.gConfig.DeclarationDataTypeCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
|
||||
EdkLogger.quiet("Checking Declaration struct typedef ...")
|
||||
|
||||
for Dirpath, Dirnames, Filenames in self.WalkTree():
|
||||
for F in Filenames:
|
||||
if os.path.splitext(F)[1] in ('.h', '.c'):
|
||||
FullName = os.path.join(Dirpath, F)
|
||||
EdkLogger.quiet("[STRUCT]" + FullName)
|
||||
c.CheckDeclStructTypedef(FullName)
|
||||
|
||||
# Check whether having same Structure
|
||||
def DeclCheckSameStructure(self):
|
||||
if EccGlobalData.gConfig.DeclarationDataTypeCheckSameStructure == '1' or EccGlobalData.gConfig.DeclarationDataTypeCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
|
||||
EdkLogger.quiet("Checking same struct ...")
|
||||
AllStructure = {}
|
||||
for IdentifierTable in EccGlobalData.gIdentifierTableList:
|
||||
SqlCommand = """select ID, Name, BelongsToFile from %s where Model = %s""" %(IdentifierTable, MODEL_IDENTIFIER_STRUCTURE)
|
||||
RecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand)
|
||||
for Record in RecordSet:
|
||||
if Record[1] != '':
|
||||
if Record[1] not in AllStructure.keys():
|
||||
AllStructure[Record[1]] = Record[2]
|
||||
else:
|
||||
ID = AllStructure[Record[1]]
|
||||
SqlCommand = """select FullPath from File where ID = %s """ % ID
|
||||
NewRecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand)
|
||||
OtherMsg = "The structure name '%s' is duplicate" % Record[1]
|
||||
if NewRecordSet != []:
|
||||
OtherMsg = "The structure name [%s] is duplicate with the one defined in %s, maybe struct NOT typedefed or the typedef new type NOT used to qualify variables" % (Record[1], NewRecordSet[0][0])
|
||||
if not EccGlobalData.gException.IsException(ERROR_DECLARATION_DATA_TYPE_CHECK_SAME_STRUCTURE, Record[1]):
|
||||
EccGlobalData.gDb.TblReport.Insert(ERROR_DECLARATION_DATA_TYPE_CHECK_SAME_STRUCTURE, OtherMsg = OtherMsg, BelongsToTable = IdentifierTable, BelongsToItem = Record[0])
|
||||
|
||||
# Check whether Union Type has a 'typedef' and the name is capital
|
||||
def DeclCheckUnionType(self):
|
||||
if EccGlobalData.gConfig.DeclarationDataTypeCheckUnionType == '1' or EccGlobalData.gConfig.DeclarationDataTypeCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
|
||||
EdkLogger.quiet("Checking Declaration union typedef ...")
|
||||
|
||||
for Dirpath, Dirnames, Filenames in self.WalkTree():
|
||||
for F in Filenames:
|
||||
if os.path.splitext(F)[1] in ('.h', '.c'):
|
||||
FullName = os.path.join(Dirpath, F)
|
||||
EdkLogger.quiet("[UNION]" + FullName)
|
||||
c.CheckDeclUnionTypedef(FullName)
|
||||
|
||||
# Predicate Expression Checking
|
||||
def PredicateExpressionCheck(self):
|
||||
self.PredicateExpressionCheckBooleanValue()
|
||||
self.PredicateExpressionCheckNonBooleanOperator()
|
||||
self.PredicateExpressionCheckComparisonNullType()
|
||||
|
||||
# Check whether Boolean values, variable type BOOLEAN not use explicit comparisons to TRUE or FALSE
|
||||
def PredicateExpressionCheckBooleanValue(self):
|
||||
if EccGlobalData.gConfig.PredicateExpressionCheckBooleanValue == '1' or EccGlobalData.gConfig.PredicateExpressionCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
|
||||
EdkLogger.quiet("Checking predicate expression Boolean value ...")
|
||||
|
||||
for Dirpath, Dirnames, Filenames in self.WalkTree():
|
||||
for F in Filenames:
|
||||
if os.path.splitext(F)[1] in ('.c'):
|
||||
FullName = os.path.join(Dirpath, F)
|
||||
EdkLogger.quiet("[BOOLEAN]" + FullName)
|
||||
c.CheckBooleanValueComparison(FullName)
|
||||
|
||||
# Check whether Non-Boolean comparisons use a compare operator (==, !=, >, < >=, <=).
|
||||
def PredicateExpressionCheckNonBooleanOperator(self):
|
||||
if EccGlobalData.gConfig.PredicateExpressionCheckNonBooleanOperator == '1' or EccGlobalData.gConfig.PredicateExpressionCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
|
||||
EdkLogger.quiet("Checking predicate expression Non-Boolean variable...")
|
||||
|
||||
for Dirpath, Dirnames, Filenames in self.WalkTree():
|
||||
for F in Filenames:
|
||||
if os.path.splitext(F)[1] in ('.c'):
|
||||
FullName = os.path.join(Dirpath, F)
|
||||
EdkLogger.quiet("[NON-BOOLEAN]" + FullName)
|
||||
c.CheckNonBooleanValueComparison(FullName)
|
||||
# Check whether a comparison of any pointer to zero must be done via the NULL type
|
||||
def PredicateExpressionCheckComparisonNullType(self):
|
||||
if EccGlobalData.gConfig.PredicateExpressionCheckComparisonNullType == '1' or EccGlobalData.gConfig.PredicateExpressionCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
|
||||
EdkLogger.quiet("Checking predicate expression NULL pointer ...")
|
||||
|
||||
for Dirpath, Dirnames, Filenames in self.WalkTree():
|
||||
for F in Filenames:
|
||||
if os.path.splitext(F)[1] in ('.c'):
|
||||
FullName = os.path.join(Dirpath, F)
|
||||
EdkLogger.quiet("[POINTER]" + FullName)
|
||||
c.CheckPointerNullComparison(FullName)
|
||||
# Include file checking
|
||||
def IncludeFileCheck(self):
|
||||
self.IncludeFileCheckIfndef()
|
||||
self.IncludeFileCheckData()
|
||||
self.IncludeFileCheckSameName()
|
||||
|
||||
# Check whether having include files with same name
|
||||
def IncludeFileCheckSameName(self):
|
||||
if EccGlobalData.gConfig.IncludeFileCheckSameName == '1' or EccGlobalData.gConfig.IncludeFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
|
||||
EdkLogger.quiet("Checking same header file name ...")
|
||||
SqlCommand = """select ID, FullPath from File
|
||||
where Model = 1002 order by Name """
|
||||
RecordDict = {}
|
||||
RecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand)
|
||||
for Record in RecordSet:
|
||||
List = Record[1].replace('/', '\\').split('\\')
|
||||
if len(List) >= 2:
|
||||
Key = List[-2] + '\\' + List[-1]
|
||||
else:
|
||||
Key = List[0]
|
||||
if Key not in RecordDict:
|
||||
RecordDict[Key] = [Record]
|
||||
else:
|
||||
RecordDict[Key].append(Record)
|
||||
|
||||
for Key in RecordDict:
|
||||
if len(RecordDict[Key]) > 1:
|
||||
for Item in RecordDict[Key]:
|
||||
EccGlobalData.gDb.TblReport.Insert(ERROR_INCLUDE_FILE_CHECK_NAME, OtherMsg = "The file name for '%s' is duplicate" % (Item[1]), BelongsToTable = 'File', BelongsToItem = Item[0])
|
||||
|
||||
# Check whether all include file contents is guarded by a #ifndef statement.
|
||||
def IncludeFileCheckIfndef(self):
|
||||
if EccGlobalData.gConfig.IncludeFileCheckIfndefStatement == '1' or EccGlobalData.gConfig.IncludeFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
|
||||
EdkLogger.quiet("Checking header file ifndef ...")
|
||||
|
||||
for Dirpath, Dirnames, Filenames in self.WalkTree():
|
||||
for F in Filenames:
|
||||
if os.path.splitext(F)[1] in ('.h'):
|
||||
FullName = os.path.join(Dirpath, F)
|
||||
MsgList = c.CheckHeaderFileIfndef(FullName)
|
||||
|
||||
# Check whether include files NOT contain code or define data variables
|
||||
def IncludeFileCheckData(self):
|
||||
if EccGlobalData.gConfig.IncludeFileCheckData == '1' or EccGlobalData.gConfig.IncludeFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
|
||||
EdkLogger.quiet("Checking header file data ...")
|
||||
|
||||
for Dirpath, Dirnames, Filenames in self.WalkTree():
|
||||
for F in Filenames:
|
||||
if os.path.splitext(F)[1] in ('.h'):
|
||||
FullName = os.path.join(Dirpath, F)
|
||||
MsgList = c.CheckHeaderFileData(FullName)
|
||||
|
||||
# Doxygen document checking
|
||||
def DoxygenCheck(self):
|
||||
self.DoxygenCheckFileHeader()
|
||||
self.DoxygenCheckFunctionHeader()
|
||||
self.DoxygenCheckCommentDescription()
|
||||
self.DoxygenCheckCommentFormat()
|
||||
self.DoxygenCheckCommand()
|
||||
|
||||
# Check whether the file headers are followed Doxygen special documentation blocks in section 2.3.5
|
||||
def DoxygenCheckFileHeader(self):
|
||||
if EccGlobalData.gConfig.DoxygenCheckFileHeader == '1' or EccGlobalData.gConfig.DoxygenCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
|
||||
EdkLogger.quiet("Checking Doxygen file header ...")
|
||||
|
||||
for Dirpath, Dirnames, Filenames in self.WalkTree():
|
||||
for F in Filenames:
|
||||
if os.path.splitext(F)[1] in ('.h', '.c'):
|
||||
FullName = os.path.join(Dirpath, F)
|
||||
MsgList = c.CheckFileHeaderDoxygenComments(FullName)
|
||||
|
||||
# Check whether the function headers are followed Doxygen special documentation blocks in section 2.3.5
|
||||
def DoxygenCheckFunctionHeader(self):
|
||||
if EccGlobalData.gConfig.DoxygenCheckFunctionHeader == '1' or EccGlobalData.gConfig.DoxygenCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
|
||||
EdkLogger.quiet("Checking Doxygen function header ...")
|
||||
|
||||
for Dirpath, Dirnames, Filenames in self.WalkTree():
|
||||
for F in Filenames:
|
||||
if os.path.splitext(F)[1] in ('.h', '.c'):
|
||||
FullName = os.path.join(Dirpath, F)
|
||||
MsgList = c.CheckFuncHeaderDoxygenComments(FullName)
|
||||
|
||||
# Check whether the first line of text in a comment block is a brief description of the element being documented.
|
||||
# The brief description must end with a period.
|
||||
def DoxygenCheckCommentDescription(self):
|
||||
if EccGlobalData.gConfig.DoxygenCheckCommentDescription == '1' or EccGlobalData.gConfig.DoxygenCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
|
||||
pass
|
||||
|
||||
# Check whether comment lines with '///< ... text ...' format, if it is used, it should be after the code section.
|
||||
def DoxygenCheckCommentFormat(self):
|
||||
if EccGlobalData.gConfig.DoxygenCheckCommentFormat == '1' or EccGlobalData.gConfig.DoxygenCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
|
||||
EdkLogger.quiet("Checking Doxygen comment ///< ...")
|
||||
|
||||
for Dirpath, Dirnames, Filenames in self.WalkTree():
|
||||
for F in Filenames:
|
||||
if os.path.splitext(F)[1] in ('.h', '.c'):
|
||||
FullName = os.path.join(Dirpath, F)
|
||||
MsgList = c.CheckDoxygenTripleForwardSlash(FullName)
|
||||
|
||||
# Check whether only Doxygen commands allowed to mark the code are @bug and @todo.
|
||||
def DoxygenCheckCommand(self):
|
||||
if EccGlobalData.gConfig.DoxygenCheckCommand == '1' or EccGlobalData.gConfig.DoxygenCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
|
||||
EdkLogger.quiet("Checking Doxygen command ...")
|
||||
|
||||
for Dirpath, Dirnames, Filenames in self.WalkTree():
|
||||
for F in Filenames:
|
||||
if os.path.splitext(F)[1] in ('.h', '.c'):
|
||||
FullName = os.path.join(Dirpath, F)
|
||||
MsgList = c.CheckDoxygenCommand(FullName)
|
||||
|
||||
# Meta-Data File Processing Checking
|
||||
def MetaDataFileCheck(self):
|
||||
self.MetaDataFileCheckPathName()
|
||||
self.MetaDataFileCheckGenerateFileList()
|
||||
self.MetaDataFileCheckLibraryInstance()
|
||||
self.MetaDataFileCheckLibraryInstanceDependent()
|
||||
self.MetaDataFileCheckLibraryInstanceOrder()
|
||||
self.MetaDataFileCheckLibraryNoUse()
|
||||
self.MetaDataFileCheckBinaryInfInFdf()
|
||||
self.MetaDataFileCheckPcdDuplicate()
|
||||
self.MetaDataFileCheckPcdFlash()
|
||||
self.MetaDataFileCheckPcdNoUse()
|
||||
self.MetaDataFileCheckGuidDuplicate()
|
||||
self.MetaDataFileCheckModuleFileNoUse()
|
||||
self.MetaDataFileCheckPcdType()
|
||||
|
||||
# Check whether each file defined in meta-data exists
|
||||
def MetaDataFileCheckPathName(self):
|
||||
if EccGlobalData.gConfig.MetaDataFileCheckPathName == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
|
||||
# This item is covered when parsing Inf/Dec/Dsc files
|
||||
pass
|
||||
|
||||
# Generate a list for all files defined in meta-data files
|
||||
def MetaDataFileCheckGenerateFileList(self):
|
||||
if EccGlobalData.gConfig.MetaDataFileCheckGenerateFileList == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
|
||||
# This item is covered when parsing Inf/Dec/Dsc files
|
||||
pass
|
||||
|
||||
# Check whether all Library Instances defined for a given module (or dependent library instance) match the module's type.
|
||||
# Each Library Instance must specify the Supported Module Types in its Inf file,
|
||||
# and any module specifying the library instance must be one of the supported types.
|
||||
def MetaDataFileCheckLibraryInstance(self):
|
||||
if EccGlobalData.gConfig.MetaDataFileCheckLibraryInstance == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
|
||||
EdkLogger.quiet("Checking for library instance type issue ...")
|
||||
SqlCommand = """select A.ID, A.Value2, B.Value2 from Inf as A left join Inf as B
|
||||
where A.Value1 = 'LIBRARY_CLASS' and A.Model = %s
|
||||
and B.Value1 = 'MODULE_TYPE' and B.Model = %s and A.BelongsToFile = B.BelongsToFile
|
||||
group by A.BelongsToFile""" % (MODEL_META_DATA_HEADER, MODEL_META_DATA_HEADER)
|
||||
RecordSet = EccGlobalData.gDb.TblInf.Exec(SqlCommand)
|
||||
LibraryClasses = {}
|
||||
for Record in RecordSet:
|
||||
List = Record[1].split('|', 1)
|
||||
SupModType = []
|
||||
if len(List) == 1:
|
||||
SupModType = SUP_MODULE_LIST_STRING.split(TAB_VALUE_SPLIT)
|
||||
elif len(List) == 2:
|
||||
SupModType = List[1].split()
|
||||
|
||||
if List[0] not in LibraryClasses:
|
||||
LibraryClasses[List[0]] = SupModType
|
||||
else:
|
||||
for Item in SupModType:
|
||||
if Item not in LibraryClasses[List[0]]:
|
||||
LibraryClasses[List[0]].append(Item)
|
||||
|
||||
if Record[2] != 'BASE' and Record[2] not in SupModType:
|
||||
EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_LIBRARY_INSTANCE_2, OtherMsg = "The Library Class '%s' does not specify its supported module types" % (List[0]), BelongsToTable = 'Inf', BelongsToItem = Record[0])
|
||||
|
||||
SqlCommand = """select A.ID, A.Value1, B.Value2 from Inf as A left join Inf as B
|
||||
where A.Model = %s and B.Value1 = '%s' and B.Model = %s
|
||||
and B.BelongsToFile = A.BelongsToFile""" \
|
||||
% (MODEL_EFI_LIBRARY_CLASS, 'MODULE_TYPE', MODEL_META_DATA_HEADER)
|
||||
RecordSet = EccGlobalData.gDb.TblInf.Exec(SqlCommand)
|
||||
# Merge all LibraryClasses' supmodlist
|
||||
RecordDict = {}
|
||||
for Record in RecordSet:
|
||||
if Record[1] not in RecordDict:
|
||||
RecordDict[Record[1]] = [str(Record[2])]
|
||||
else:
|
||||
if Record[2] not in RecordDict[Record[1]]:
|
||||
RecordDict[Record[1]].append(Record[2])
|
||||
|
||||
for Record in RecordSet:
|
||||
if Record[1] in LibraryClasses:
|
||||
if Record[2] not in LibraryClasses[Record[1]] and 'BASE' not in RecordDict[Record[1]]:
|
||||
if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_LIBRARY_INSTANCE_1, Record[1]):
|
||||
EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_LIBRARY_INSTANCE_1, OtherMsg = "The type of Library Class [%s] defined in Inf file does not match the type of the module" % (Record[1]), BelongsToTable = 'Inf', BelongsToItem = Record[0])
|
||||
else:
|
||||
if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_LIBRARY_INSTANCE_1, Record[1]):
|
||||
EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_LIBRARY_INSTANCE_1, OtherMsg = "The type of Library Class [%s] defined in Inf file does not match the type of the module" % (Record[1]), BelongsToTable = 'Inf', BelongsToItem = Record[0])
|
||||
|
||||
# Check whether a Library Instance has been defined for all dependent library classes
|
||||
def MetaDataFileCheckLibraryInstanceDependent(self):
|
||||
if EccGlobalData.gConfig.MetaDataFileCheckLibraryInstanceDependent == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
|
||||
EdkLogger.quiet("Checking for library instance dependent issue ...")
|
||||
SqlCommand = """select ID, Value1, Value2 from Dsc where Model = %s""" % MODEL_EFI_LIBRARY_CLASS
|
||||
LibraryClasses = EccGlobalData.gDb.TblDsc.Exec(SqlCommand)
|
||||
for LibraryClass in LibraryClasses:
|
||||
if LibraryClass[1].upper() != 'NULL':
|
||||
LibraryIns = os.path.normpath(os.path.join(EccGlobalData.gWorkspace, LibraryClass[2]))
|
||||
SqlCommand = """select Value2 from Inf where BelongsToFile =
|
||||
(select ID from File where lower(FullPath) = lower('%s'))
|
||||
and Value1 = '%s'""" % (LibraryIns, 'LIBRARY_CLASS')
|
||||
RecordSet = EccGlobalData.gDb.TblInf.Exec(SqlCommand)
|
||||
IsFound = False
|
||||
for Record in RecordSet:
|
||||
LibName = Record[0].split('|', 1)[0]
|
||||
if LibraryClass[1] == LibName:
|
||||
IsFound = True
|
||||
if not IsFound:
|
||||
if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_LIBRARY_INSTANCE_DEPENDENT, LibraryClass[1]):
|
||||
EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_LIBRARY_INSTANCE_DEPENDENT, OtherMsg = "The Library Class [%s] is not specified in '%s'" % (LibraryClass[1], LibraryClass[2]), BelongsToTable = 'Dsc', BelongsToItem = LibraryClass[0])
|
||||
|
||||
# Check whether the Library Instances specified by the LibraryClasses sections are listed in order of dependencies
|
||||
def MetaDataFileCheckLibraryInstanceOrder(self):
|
||||
if EccGlobalData.gConfig.MetaDataFileCheckLibraryInstanceOrder == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
|
||||
# This checkpoint is not necessary for Ecc check
|
||||
pass
|
||||
|
||||
# Check whether the unnecessary inclusion of library classes in the Inf file
|
||||
def MetaDataFileCheckLibraryNoUse(self):
|
||||
if EccGlobalData.gConfig.MetaDataFileCheckLibraryNoUse == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
|
||||
EdkLogger.quiet("Checking for library instance not used ...")
|
||||
SqlCommand = """select ID, Value1 from Inf as A where A.Model = %s and A.Value1 not in (select B.Value1 from Dsc as B where Model = %s)""" % (MODEL_EFI_LIBRARY_CLASS, MODEL_EFI_LIBRARY_CLASS)
|
||||
RecordSet = EccGlobalData.gDb.TblInf.Exec(SqlCommand)
|
||||
for Record in RecordSet:
|
||||
if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_LIBRARY_NO_USE, Record[1]):
|
||||
EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_LIBRARY_NO_USE, OtherMsg = "The Library Class [%s] is not used in any platform" % (Record[1]), BelongsToTable = 'Inf', BelongsToItem = Record[0])
|
||||
|
||||
# Check whether an Inf file is specified in the FDF file, but not in the Dsc file, then the Inf file must be for a Binary module only
|
||||
def MetaDataFileCheckBinaryInfInFdf(self):
|
||||
if EccGlobalData.gConfig.MetaDataFileCheckBinaryInfInFdf == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
|
||||
EdkLogger.quiet("Checking for non-binary modules defined in FDF files ...")
|
||||
SqlCommand = """select A.ID, A.Value1 from Fdf as A
|
||||
where A.Model = %s
|
||||
and A.Enabled > -1
|
||||
and A.Value1 not in
|
||||
(select B.Value1 from Dsc as B
|
||||
where B.Model = %s
|
||||
and B.Enabled > -1)""" % (MODEL_META_DATA_COMPONENT, MODEL_META_DATA_COMPONENT)
|
||||
RecordSet = EccGlobalData.gDb.TblFdf.Exec(SqlCommand)
|
||||
for Record in RecordSet:
|
||||
FdfID = Record[0]
|
||||
FilePath = Record[1]
|
||||
FilePath = os.path.normpath(os.path.join(EccGlobalData.gWorkspace, FilePath))
|
||||
SqlCommand = """select ID from Inf where Model = %s and BelongsToFile = (select ID from File where FullPath like '%s')
|
||||
""" % (MODEL_EFI_SOURCE_FILE, FilePath)
|
||||
NewRecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand)
|
||||
if NewRecordSet!= []:
|
||||
if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_BINARY_INF_IN_FDF, FilePath):
|
||||
EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_BINARY_INF_IN_FDF, OtherMsg = "File [%s] defined in FDF file and not in DSC file must be a binary module" % (FilePath), BelongsToTable = 'Fdf', BelongsToItem = FdfID)
|
||||
|
||||
# Check whether a PCD is set in a Dsc file or the FDF file, but not in both.
|
||||
def MetaDataFileCheckPcdDuplicate(self):
|
||||
if EccGlobalData.gConfig.MetaDataFileCheckPcdDuplicate == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
|
||||
EdkLogger.quiet("Checking for duplicate PCDs defined in both DSC and FDF files ...")
|
||||
SqlCommand = """
|
||||
select A.ID, A.Value2, B.ID, B.Value2 from Dsc as A, Fdf as B
|
||||
where A.Model >= %s and A.Model < %s
|
||||
and B.Model >= %s and B.Model < %s
|
||||
and A.Value2 = B.Value2
|
||||
and A.Enabled > -1
|
||||
and B.Enabled > -1
|
||||
group by A.ID
|
||||
"""% (MODEL_PCD, MODEL_META_DATA_HEADER, MODEL_PCD, MODEL_META_DATA_HEADER)
|
||||
RecordSet = EccGlobalData.gDb.TblDsc.Exec(SqlCommand)
|
||||
for Record in RecordSet:
|
||||
if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_PCD_DUPLICATE, Record[1]):
|
||||
EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_PCD_DUPLICATE, OtherMsg = "The PCD [%s] is defined in both FDF file and DSC file" % (Record[1]), BelongsToTable = 'Dsc', BelongsToItem = Record[0])
|
||||
if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_PCD_DUPLICATE, Record[3]):
|
||||
EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_PCD_DUPLICATE, OtherMsg = "The PCD [%s] is defined in both FDF file and DSC file" % (Record[3]), BelongsToTable = 'Fdf', BelongsToItem = Record[2])
|
||||
|
||||
EdkLogger.quiet("Checking for duplicate PCDs defined in DEC files ...")
|
||||
SqlCommand = """
|
||||
select A.ID, A.Value2 from Dec as A, Dec as B
|
||||
where A.Model >= %s and A.Model < %s
|
||||
and B.Model >= %s and B.Model < %s
|
||||
and A.Value2 = B.Value2
|
||||
and ((A.Arch = B.Arch) and (A.Arch != 'COMMON' or B.Arch != 'COMMON'))
|
||||
and A.ID != B.ID
|
||||
and A.Enabled > -1
|
||||
and B.Enabled > -1
|
||||
and A.BelongsToFile = B.BelongsToFile
|
||||
group by A.ID
|
||||
"""% (MODEL_PCD, MODEL_META_DATA_HEADER, MODEL_PCD, MODEL_META_DATA_HEADER)
|
||||
RecordSet = EccGlobalData.gDb.TblDsc.Exec(SqlCommand)
|
||||
for Record in RecordSet:
|
||||
if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_PCD_DUPLICATE, Record[1]):
|
||||
EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_PCD_DUPLICATE, OtherMsg = "The PCD [%s] is defined duplicated in DEC file" % (Record[1]), BelongsToTable = 'Dec', BelongsToItem = Record[0])
|
||||
|
||||
# Check whether PCD settings in the FDF file can only be related to flash.
|
||||
def MetaDataFileCheckPcdFlash(self):
|
||||
if EccGlobalData.gConfig.MetaDataFileCheckPcdFlash == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
|
||||
EdkLogger.quiet("Checking only Flash related PCDs are used in FDF ...")
|
||||
SqlCommand = """
|
||||
select ID, Value2, BelongsToFile from Fdf as A
|
||||
where A.Model >= %s and Model < %s
|
||||
and A.Enabled > -1
|
||||
and A.Value2 not like '%%Flash%%'
|
||||
"""% (MODEL_PCD, MODEL_META_DATA_HEADER)
|
||||
RecordSet = EccGlobalData.gDb.TblFdf.Exec(SqlCommand)
|
||||
for Record in RecordSet:
|
||||
if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_PCD_FLASH, Record[1]):
|
||||
EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_PCD_FLASH, OtherMsg = "The PCD [%s] defined in FDF file is not related to Flash" % (Record[1]), BelongsToTable = 'Fdf', BelongsToItem = Record[0])
|
||||
|
||||
# Check whether PCDs used in Inf files but not specified in Dsc or FDF files
|
||||
def MetaDataFileCheckPcdNoUse(self):
|
||||
if EccGlobalData.gConfig.MetaDataFileCheckPcdNoUse == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
|
||||
EdkLogger.quiet("Checking for non-specified PCDs ...")
|
||||
SqlCommand = """
|
||||
select ID, Value2, BelongsToFile from Inf as A
|
||||
where A.Model >= %s and Model < %s
|
||||
and A.Enabled > -1
|
||||
and A.Value2 not in
|
||||
(select Value2 from Dsc as B
|
||||
where B.Model >= %s and B.Model < %s
|
||||
and B.Enabled > -1)
|
||||
and A.Value2 not in
|
||||
(select Value2 from Fdf as C
|
||||
where C.Model >= %s and C.Model < %s
|
||||
and C.Enabled > -1)
|
||||
"""% (MODEL_PCD, MODEL_META_DATA_HEADER, MODEL_PCD, MODEL_META_DATA_HEADER, MODEL_PCD, MODEL_META_DATA_HEADER)
|
||||
RecordSet = EccGlobalData.gDb.TblInf.Exec(SqlCommand)
|
||||
for Record in RecordSet:
|
||||
if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_PCD_NO_USE, Record[1]):
|
||||
EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_PCD_NO_USE, OtherMsg = "The PCD [%s] defined in INF file is not specified in either DSC or FDF files" % (Record[1]), BelongsToTable = 'Inf', BelongsToItem = Record[0])
|
||||
|
||||
# Check whether having duplicate guids defined for Guid/Protocol/Ppi
|
||||
def MetaDataFileCheckGuidDuplicate(self):
|
||||
if EccGlobalData.gConfig.MetaDataFileCheckGuidDuplicate == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
|
||||
EdkLogger.quiet("Checking for duplicate GUID/PPI/PROTOCOL ...")
|
||||
# Check Guid
|
||||
self.CheckGuidProtocolPpi(ERROR_META_DATA_FILE_CHECK_DUPLICATE_GUID, MODEL_EFI_GUID, EccGlobalData.gDb.TblDec)
|
||||
self.CheckGuidProtocolPpi(ERROR_META_DATA_FILE_CHECK_DUPLICATE_GUID, MODEL_EFI_GUID, EccGlobalData.gDb.TblDsc)
|
||||
self.CheckGuidProtocolPpiValue(ERROR_META_DATA_FILE_CHECK_DUPLICATE_GUID, MODEL_EFI_GUID)
|
||||
# Check protocol
|
||||
self.CheckGuidProtocolPpi(ERROR_META_DATA_FILE_CHECK_DUPLICATE_PROTOCOL, MODEL_EFI_PROTOCOL, EccGlobalData.gDb.TblDec)
|
||||
self.CheckGuidProtocolPpi(ERROR_META_DATA_FILE_CHECK_DUPLICATE_PROTOCOL, MODEL_EFI_PROTOCOL, EccGlobalData.gDb.TblDsc)
|
||||
self.CheckGuidProtocolPpiValue(ERROR_META_DATA_FILE_CHECK_DUPLICATE_PROTOCOL, MODEL_EFI_PROTOCOL)
|
||||
# Check ppi
|
||||
self.CheckGuidProtocolPpi(ERROR_META_DATA_FILE_CHECK_DUPLICATE_PPI, MODEL_EFI_PPI, EccGlobalData.gDb.TblDec)
|
||||
self.CheckGuidProtocolPpi(ERROR_META_DATA_FILE_CHECK_DUPLICATE_PPI, MODEL_EFI_PPI, EccGlobalData.gDb.TblDsc)
|
||||
self.CheckGuidProtocolPpiValue(ERROR_META_DATA_FILE_CHECK_DUPLICATE_PPI, MODEL_EFI_PPI)
|
||||
|
||||
# Check whether all files under module directory are described in INF files
|
||||
def MetaDataFileCheckModuleFileNoUse(self):
|
||||
if EccGlobalData.gConfig.MetaDataFileCheckModuleFileNoUse == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
|
||||
EdkLogger.quiet("Checking for no used module files ...")
|
||||
SqlCommand = """
|
||||
select upper(Path) from File where ID in (select BelongsToFile from INF where BelongsToFile != -1)
|
||||
"""
|
||||
InfPathSet = EccGlobalData.gDb.TblInf.Exec(SqlCommand)
|
||||
InfPathList = []
|
||||
for Item in InfPathSet:
|
||||
if Item[0] not in InfPathList:
|
||||
InfPathList.append(Item[0])
|
||||
SqlCommand = """
|
||||
select ID, Path, FullPath from File where upper(FullPath) not in
|
||||
(select upper(A.Path) || '\\' || upper(B.Value1) from File as A, INF as B
|
||||
where A.ID in (select BelongsToFile from INF where Model = %s group by BelongsToFile) and
|
||||
B.BelongsToFile = A.ID and B.Model = %s)
|
||||
and (Model = %s or Model = %s)
|
||||
""" % (MODEL_EFI_SOURCE_FILE, MODEL_EFI_SOURCE_FILE, MODEL_FILE_C, MODEL_FILE_H)
|
||||
RecordSet = EccGlobalData.gDb.TblInf.Exec(SqlCommand)
|
||||
for Record in RecordSet:
|
||||
Path = Record[1]
|
||||
Path = Path.upper().replace('\X64', '').replace('\IA32', '').replace('\EBC', '').replace('\IPF', '').replace('\ARM', '')
|
||||
if Path in InfPathList:
|
||||
if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_MODULE_FILE_NO_USE, Record[2]):
|
||||
EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_MODULE_FILE_NO_USE, OtherMsg = "The source file [%s] is existing in module directory but it is not described in INF file." % (Record[2]), BelongsToTable = 'File', BelongsToItem = Record[0])
|
||||
|
||||
# Check whether the PCD is correctly used in C function via its type
|
||||
def MetaDataFileCheckPcdType(self):
|
||||
if EccGlobalData.gConfig.MetaDataFileCheckPcdType == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
|
||||
EdkLogger.quiet("Checking for pcd type in c code function usage ...")
|
||||
SqlCommand = """
|
||||
select ID, Model, Value1, BelongsToFile from INF where Model > %s and Model < %s
|
||||
""" % (MODEL_PCD, MODEL_META_DATA_HEADER)
|
||||
PcdSet = EccGlobalData.gDb.TblInf.Exec(SqlCommand)
|
||||
for Pcd in PcdSet:
|
||||
Model = Pcd[1]
|
||||
PcdName = Pcd[2]
|
||||
if len(Pcd[2].split(".")) > 1:
|
||||
PcdName = Pcd[2].split(".")[1]
|
||||
BelongsToFile = Pcd[3]
|
||||
SqlCommand = """
|
||||
select ID from File where FullPath in
|
||||
(select B.Path || '\\' || A.Value1 from INF as A, File as B where A.Model = %s and A.BelongsToFile = %s
|
||||
and B.ID = %s)
|
||||
""" %(MODEL_EFI_SOURCE_FILE, BelongsToFile, BelongsToFile)
|
||||
TableSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand)
|
||||
for Tbl in TableSet:
|
||||
TblName = 'Identifier' + str(Tbl[0])
|
||||
SqlCommand = """
|
||||
select Name, ID from %s where value like '%%%s%%' and Model = %s
|
||||
""" % (TblName, PcdName, MODEL_IDENTIFIER_FUNCTION_CALLING)
|
||||
RecordSet = EccGlobalData.gDb.TblInf.Exec(SqlCommand)
|
||||
TblNumber = TblName.replace('Identifier', '')
|
||||
for Record in RecordSet:
|
||||
FunName = Record[0]
|
||||
if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_PCD_TYPE, FunName):
|
||||
if Model in [MODEL_PCD_FIXED_AT_BUILD] and not FunName.startswith('FixedPcdGet'):
|
||||
EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_PCD_TYPE, OtherMsg = "The pcd '%s' is defined as a FixPcd but now it is called by c function [%s]" % (PcdName, FunName), BelongsToTable = TblName, BelongsToItem = Record[1])
|
||||
if Model in [MODEL_PCD_FEATURE_FLAG] and (not FunName.startswith('FeaturePcdGet') and not FunName.startswith('FeaturePcdSet')):
|
||||
EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_PCD_TYPE, OtherMsg = "The pcd '%s' is defined as a FeaturePcd but now it is called by c function [%s]" % (PcdName, FunName), BelongsToTable = TblName, BelongsToItem = Record[1])
|
||||
if Model in [MODEL_PCD_PATCHABLE_IN_MODULE] and (not FunName.startswith('PatchablePcdGet') and not FunName.startswith('PatchablePcdSet')):
|
||||
EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_PCD_TYPE, OtherMsg = "The pcd '%s' is defined as a PatchablePcd but now it is called by c function [%s]" % (PcdName, FunName), BelongsToTable = TblName, BelongsToItem = Record[1])
|
||||
|
||||
#ERROR_META_DATA_FILE_CHECK_PCD_TYPE
|
||||
pass
|
||||
|
||||
# Check whether these is duplicate Guid/Ppi/Protocol name
|
||||
def CheckGuidProtocolPpi(self, ErrorID, Model, Table):
|
||||
Name = ''
|
||||
if Model == MODEL_EFI_GUID:
|
||||
Name = 'guid'
|
||||
if Model == MODEL_EFI_PROTOCOL:
|
||||
Name = 'protocol'
|
||||
if Model == MODEL_EFI_PPI:
|
||||
Name = 'ppi'
|
||||
SqlCommand = """
|
||||
select A.ID, A.Value1 from %s as A, %s as B
|
||||
where A.Model = %s and B.Model = %s
|
||||
and A.Value1 = B.Value1 and A.ID <> B.ID
|
||||
and A.Enabled > -1
|
||||
and B.Enabled > -1
|
||||
group by A.ID
|
||||
""" % (Table.Table, Table.Table, Model, Model)
|
||||
RecordSet = Table.Exec(SqlCommand)
|
||||
for Record in RecordSet:
|
||||
if not EccGlobalData.gException.IsException(ErrorID, Record[1]):
|
||||
EccGlobalData.gDb.TblReport.Insert(ErrorID, OtherMsg = "The %s name [%s] is defined more than one time" % (Name.upper(), Record[1]), BelongsToTable = Table.Table, BelongsToItem = Record[0])
|
||||
|
||||
# Check whether these is duplicate Guid/Ppi/Protocol value
|
||||
def CheckGuidProtocolPpiValue(self, ErrorID, Model):
|
||||
Name = ''
|
||||
Table = EccGlobalData.gDb.TblDec
|
||||
if Model == MODEL_EFI_GUID:
|
||||
Name = 'guid'
|
||||
if Model == MODEL_EFI_PROTOCOL:
|
||||
Name = 'protocol'
|
||||
if Model == MODEL_EFI_PPI:
|
||||
Name = 'ppi'
|
||||
SqlCommand = """
|
||||
select A.ID, A.Value2 from %s as A, %s as B
|
||||
where A.Model = %s and B.Model = %s
|
||||
and A.Value2 = B.Value2 and A.ID <> B.ID
|
||||
group by A.ID
|
||||
""" % (Table.Table, Table.Table, Model, Model)
|
||||
RecordSet = Table.Exec(SqlCommand)
|
||||
for Record in RecordSet:
|
||||
if not EccGlobalData.gException.IsException(ErrorID, Record[1]):
|
||||
EccGlobalData.gDb.TblReport.Insert(ErrorID, OtherMsg = "The %s value [%s] is used more than one time" % (Name.upper(), Record[1]), BelongsToTable = Table.Table, BelongsToItem = Record[0])
|
||||
|
||||
# Naming Convention Check
|
||||
def NamingConventionCheck(self):
|
||||
|
||||
for Dirpath, Dirnames, Filenames in self.WalkTree():
|
||||
for F in Filenames:
|
||||
if os.path.splitext(F)[1] in ('.h', '.c'):
|
||||
FullName = os.path.join(Dirpath, F)
|
||||
Id = c.GetTableID(FullName)
|
||||
if Id < 0:
|
||||
continue
|
||||
FileTable = 'Identifier' + str(Id)
|
||||
self.NamingConventionCheckDefineStatement(FileTable)
|
||||
self.NamingConventionCheckTypedefStatement(FileTable)
|
||||
self.NamingConventionCheckIfndefStatement(FileTable)
|
||||
self.NamingConventionCheckVariableName(FileTable)
|
||||
self.NamingConventionCheckSingleCharacterVariable(FileTable)
|
||||
|
||||
self.NamingConventionCheckPathName()
|
||||
self.NamingConventionCheckFunctionName()
|
||||
|
||||
# Check whether only capital letters are used for #define declarations
|
||||
def NamingConventionCheckDefineStatement(self, FileTable):
|
||||
if EccGlobalData.gConfig.NamingConventionCheckDefineStatement == '1' or EccGlobalData.gConfig.NamingConventionCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
|
||||
EdkLogger.quiet("Checking naming covention of #define statement ...")
|
||||
|
||||
SqlCommand = """select ID, Value from %s where Model = %s""" %(FileTable, MODEL_IDENTIFIER_MACRO_DEFINE)
|
||||
RecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand)
|
||||
for Record in RecordSet:
|
||||
Name = Record[1].strip().split()[1]
|
||||
if Name.find('(') != -1:
|
||||
Name = Name[0:Name.find('(')]
|
||||
if Name.upper() != Name:
|
||||
if not EccGlobalData.gException.IsException(ERROR_NAMING_CONVENTION_CHECK_DEFINE_STATEMENT, Name):
|
||||
EccGlobalData.gDb.TblReport.Insert(ERROR_NAMING_CONVENTION_CHECK_DEFINE_STATEMENT, OtherMsg = "The #define name [%s] does not follow the rules" % (Name), BelongsToTable = FileTable, BelongsToItem = Record[0])
|
||||
|
||||
# Check whether only capital letters are used for typedef declarations
|
||||
def NamingConventionCheckTypedefStatement(self, FileTable):
|
||||
if EccGlobalData.gConfig.NamingConventionCheckTypedefStatement == '1' or EccGlobalData.gConfig.NamingConventionCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
|
||||
EdkLogger.quiet("Checking naming covention of #typedef statement ...")
|
||||
|
||||
SqlCommand = """select ID, Name from %s where Model = %s""" %(FileTable, MODEL_IDENTIFIER_TYPEDEF)
|
||||
RecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand)
|
||||
for Record in RecordSet:
|
||||
Name = Record[1].strip()
|
||||
if Name != '' and Name != None:
|
||||
if Name[0] == '(':
|
||||
Name = Name[1:Name.find(')')]
|
||||
if Name.find('(') > -1:
|
||||
Name = Name[Name.find('(') + 1 : Name.find(')')]
|
||||
Name = Name.replace('WINAPI', '')
|
||||
Name = Name.replace('*', '').strip()
|
||||
if Name.upper() != Name:
|
||||
if not EccGlobalData.gException.IsException(ERROR_NAMING_CONVENTION_CHECK_TYPEDEF_STATEMENT, Name):
|
||||
EccGlobalData.gDb.TblReport.Insert(ERROR_NAMING_CONVENTION_CHECK_TYPEDEF_STATEMENT, OtherMsg = "The #typedef name [%s] does not follow the rules" % (Name), BelongsToTable = FileTable, BelongsToItem = Record[0])
|
||||
|
||||
# Check whether the #ifndef at the start of an include file uses both prefix and postfix underscore characters, '_'.
|
||||
def NamingConventionCheckIfndefStatement(self, FileTable):
|
||||
if EccGlobalData.gConfig.NamingConventionCheckTypedefStatement == '1' or EccGlobalData.gConfig.NamingConventionCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
|
||||
EdkLogger.quiet("Checking naming covention of #ifndef statement ...")
|
||||
|
||||
SqlCommand = """select ID, Value from %s where Model = %s""" %(FileTable, MODEL_IDENTIFIER_MACRO_IFNDEF)
|
||||
RecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand)
|
||||
for Record in RecordSet:
|
||||
Name = Record[1].replace('#ifndef', '').strip()
|
||||
if Name[0] != '_' or Name[-1] != '_':
|
||||
if not EccGlobalData.gException.IsException(ERROR_NAMING_CONVENTION_CHECK_IFNDEF_STATEMENT, Name):
|
||||
EccGlobalData.gDb.TblReport.Insert(ERROR_NAMING_CONVENTION_CHECK_IFNDEF_STATEMENT, OtherMsg = "The #ifndef name [%s] does not follow the rules" % (Name), BelongsToTable = FileTable, BelongsToItem = Record[0])
|
||||
|
||||
# Rule for path name, variable name and function name
|
||||
# 1. First character should be upper case
|
||||
# 2. Existing lower case in a word
|
||||
# 3. No space existence
|
||||
# Check whether the path name followed the rule
|
||||
def NamingConventionCheckPathName(self):
|
||||
if EccGlobalData.gConfig.NamingConventionCheckPathName == '1' or EccGlobalData.gConfig.NamingConventionCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
|
||||
EdkLogger.quiet("Checking naming covention of file path name ...")
|
||||
Pattern = re.compile(r'^[A-Z]+\S*[a-z]\S*$')
|
||||
SqlCommand = """select ID, Name from File"""
|
||||
RecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand)
|
||||
for Record in RecordSet:
|
||||
if not Pattern.match(Record[1]):
|
||||
if not EccGlobalData.gException.IsException(ERROR_NAMING_CONVENTION_CHECK_PATH_NAME, Record[1]):
|
||||
EccGlobalData.gDb.TblReport.Insert(ERROR_NAMING_CONVENTION_CHECK_PATH_NAME, OtherMsg = "The file path [%s] does not follow the rules" % (Record[1]), BelongsToTable = 'File', BelongsToItem = Record[0])
|
||||
|
||||
# Rule for path name, variable name and function name
|
||||
# 1. First character should be upper case
|
||||
# 2. Existing lower case in a word
|
||||
# 3. No space existence
|
||||
# 4. Global variable name must start with a 'g'
|
||||
# Check whether the variable name followed the rule
|
||||
def NamingConventionCheckVariableName(self, FileTable):
|
||||
if EccGlobalData.gConfig.NamingConventionCheckVariableName == '1' or EccGlobalData.gConfig.NamingConventionCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
|
||||
EdkLogger.quiet("Checking naming covention of variable name ...")
|
||||
Pattern = re.compile(r'^[A-Zgm]+\S*[a-z]\S*$')
|
||||
|
||||
SqlCommand = """select ID, Name from %s where Model = %s""" %(FileTable, MODEL_IDENTIFIER_VARIABLE)
|
||||
RecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand)
|
||||
for Record in RecordSet:
|
||||
if not Pattern.match(Record[1]):
|
||||
if not EccGlobalData.gException.IsException(ERROR_NAMING_CONVENTION_CHECK_VARIABLE_NAME, Record[1]):
|
||||
EccGlobalData.gDb.TblReport.Insert(ERROR_NAMING_CONVENTION_CHECK_VARIABLE_NAME, OtherMsg = "The variable name [%s] does not follow the rules" % (Record[1]), BelongsToTable = FileTable, BelongsToItem = Record[0])
|
||||
|
||||
# Rule for path name, variable name and function name
|
||||
# 1. First character should be upper case
|
||||
# 2. Existing lower case in a word
|
||||
# 3. No space existence
|
||||
# Check whether the function name followed the rule
|
||||
def NamingConventionCheckFunctionName(self):
|
||||
if EccGlobalData.gConfig.NamingConventionCheckFunctionName == '1' or EccGlobalData.gConfig.NamingConventionCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
|
||||
EdkLogger.quiet("Checking naming covention of function name ...")
|
||||
Pattern = re.compile(r'^[A-Z]+\S*[a-z]\S*$')
|
||||
SqlCommand = """select ID, Name from Function"""
|
||||
RecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand)
|
||||
for Record in RecordSet:
|
||||
if not Pattern.match(Record[1]):
|
||||
if not EccGlobalData.gException.IsException(ERROR_NAMING_CONVENTION_CHECK_FUNCTION_NAME, Record[1]):
|
||||
EccGlobalData.gDb.TblReport.Insert(ERROR_NAMING_CONVENTION_CHECK_FUNCTION_NAME, OtherMsg = "The function name [%s] does not follow the rules" % (Record[1]), BelongsToTable = 'Function', BelongsToItem = Record[0])
|
||||
|
||||
# Check whether NO use short variable name with single character
|
||||
def NamingConventionCheckSingleCharacterVariable(self, FileTable):
|
||||
if EccGlobalData.gConfig.NamingConventionCheckSingleCharacterVariable == '1' or EccGlobalData.gConfig.NamingConventionCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
|
||||
EdkLogger.quiet("Checking naming covention of single character variable name ...")
|
||||
|
||||
SqlCommand = """select ID, Name from %s where Model = %s""" %(FileTable, MODEL_IDENTIFIER_VARIABLE)
|
||||
RecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand)
|
||||
for Record in RecordSet:
|
||||
Variable = Record[1].replace('*', '')
|
||||
if len(Variable) == 1:
|
||||
if not EccGlobalData.gException.IsException(ERROR_NAMING_CONVENTION_CHECK_SINGLE_CHARACTER_VARIABLE, Record[1]):
|
||||
EccGlobalData.gDb.TblReport.Insert(ERROR_NAMING_CONVENTION_CHECK_SINGLE_CHARACTER_VARIABLE, OtherMsg = "The variable name [%s] does not follow the rules" % (Record[1]), BelongsToTable = FileTable, BelongsToItem = Record[0])
|
||||
|
||||
##
|
||||
#
|
||||
# This acts like the main() function for the script, unless it is 'import'ed into another
|
||||
# script.
|
||||
#
|
||||
if __name__ == '__main__':
|
||||
Check = Check()
|
||||
Check.Check()
|
165
BaseTools/Source/Python/Ecc/CodeFragment.py
Normal file
165
BaseTools/Source/Python/Ecc/CodeFragment.py
Normal file
@ -0,0 +1,165 @@
|
||||
## @file
|
||||
# fragments of source file
|
||||
#
|
||||
# Copyright (c) 2007, Intel Corporation
|
||||
#
|
||||
# All rights reserved. This program and the accompanying materials
|
||||
# are licensed and made available under the terms and conditions of the BSD License
|
||||
# which accompanies this distribution. The full text of the license may be found at
|
||||
# http://opensource.org/licenses/bsd-license.php
|
||||
#
|
||||
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
#
|
||||
|
||||
|
||||
## The description of comment contents and start & end position
|
||||
#
|
||||
#
|
||||
class Comment :
|
||||
## The constructor
|
||||
#
|
||||
# @param self The object pointer
|
||||
# @param Str The message to record
|
||||
# @param Begin The start position tuple.
|
||||
# @param End The end position tuple.
|
||||
# @param CommentType The type of comment (T_COMMENT_TWO_SLASH or T_COMMENT_SLASH_STAR).
|
||||
#
|
||||
def __init__(self, Str, Begin, End, CommentType):
|
||||
self.Content = Str
|
||||
self.StartPos = Begin
|
||||
self.EndPos = End
|
||||
self.Type = CommentType
|
||||
|
||||
## The description of preprocess directives and start & end position
|
||||
#
|
||||
#
|
||||
class PP_Directive :
|
||||
## The constructor
|
||||
#
|
||||
# @param self The object pointer
|
||||
# @param Str The message to record
|
||||
# @param Begin The start position tuple.
|
||||
# @param End The end position tuple.
|
||||
#
|
||||
def __init__(self, Str, Begin, End):
|
||||
self.Content = Str
|
||||
self.StartPos = Begin
|
||||
self.EndPos = End
|
||||
|
||||
## The description of predicate expression and start & end position
|
||||
#
|
||||
#
|
||||
class PredicateExpression :
|
||||
## The constructor
|
||||
#
|
||||
# @param self The object pointer
|
||||
# @param Str The message to record
|
||||
# @param Begin The start position tuple.
|
||||
# @param End The end position tuple.
|
||||
#
|
||||
def __init__(self, Str, Begin, End):
|
||||
self.Content = Str
|
||||
self.StartPos = Begin
|
||||
self.EndPos = End
|
||||
|
||||
## The description of function definition and start & end position
|
||||
#
|
||||
#
|
||||
class FunctionDefinition :
|
||||
## The constructor
|
||||
#
|
||||
# @param self The object pointer
|
||||
# @param Str The message to record
|
||||
# @param Begin The start position tuple.
|
||||
# @param End The end position tuple.
|
||||
# @param LBPos The left brace position tuple.
|
||||
#
|
||||
def __init__(self, ModifierStr, DeclStr, Begin, End, LBPos, NamePos):
|
||||
self.Modifier = ModifierStr
|
||||
self.Declarator = DeclStr
|
||||
self.StartPos = Begin
|
||||
self.EndPos = End
|
||||
self.LeftBracePos = LBPos
|
||||
self.NamePos = NamePos
|
||||
|
||||
## The description of variable declaration and start & end position
|
||||
#
|
||||
#
|
||||
class VariableDeclaration :
|
||||
## The constructor
|
||||
#
|
||||
# @param self The object pointer
|
||||
# @param Str The message to record
|
||||
# @param Begin The start position tuple.
|
||||
# @param NamePos The name position tuple.
|
||||
#
|
||||
def __init__(self, ModifierStr, DeclStr, Begin, NamePos):
|
||||
self.Modifier = ModifierStr
|
||||
self.Declarator = DeclStr
|
||||
self.StartPos = Begin
|
||||
self.NameStartPos = NamePos
|
||||
|
||||
## The description of enum definition and start & end position
|
||||
#
|
||||
#
|
||||
class EnumerationDefinition :
|
||||
## The constructor
|
||||
#
|
||||
# @param self The object pointer
|
||||
# @param Str The message to record
|
||||
# @param Begin The start position tuple.
|
||||
# @param End The end position tuple.
|
||||
#
|
||||
def __init__(self, Str, Begin, End):
|
||||
self.Content = Str
|
||||
self.StartPos = Begin
|
||||
self.EndPos = End
|
||||
|
||||
## The description of struct/union definition and start & end position
|
||||
#
|
||||
#
|
||||
class StructUnionDefinition :
|
||||
## The constructor
|
||||
#
|
||||
# @param self The object pointer
|
||||
# @param Str The message to record
|
||||
# @param Begin The start position tuple.
|
||||
# @param End The end position tuple.
|
||||
#
|
||||
def __init__(self, Str, Begin, End):
|
||||
self.Content = Str
|
||||
self.StartPos = Begin
|
||||
self.EndPos = End
|
||||
|
||||
## The description of 'Typedef' definition and start & end position
|
||||
#
|
||||
#
|
||||
class TypedefDefinition :
|
||||
## The constructor
|
||||
#
|
||||
# @param self The object pointer
|
||||
# @param Str The message to record
|
||||
# @param Begin The start position tuple.
|
||||
# @param End The end position tuple.
|
||||
#
|
||||
def __init__(self, FromStr, ToStr, Begin, End):
|
||||
self.FromType = FromStr
|
||||
self.ToType = ToStr
|
||||
self.StartPos = Begin
|
||||
self.EndPos = End
|
||||
|
||||
class FunctionCalling:
|
||||
## The constructor
|
||||
#
|
||||
# @param self The object pointer
|
||||
# @param Str The message to record
|
||||
# @param Begin The start position tuple.
|
||||
# @param End The end position tuple.
|
||||
#
|
||||
def __init__(self, Name, Param, Begin, End):
|
||||
self.FuncName = Name
|
||||
self.ParamList = Param
|
||||
self.StartPos = Begin
|
||||
self.EndPos = End
|
||||
|
624
BaseTools/Source/Python/Ecc/CodeFragmentCollector.py
Normal file
624
BaseTools/Source/Python/Ecc/CodeFragmentCollector.py
Normal file
@ -0,0 +1,624 @@
|
||||
## @file
|
||||
# preprocess source file
|
||||
#
|
||||
# Copyright (c) 2007, Intel Corporation
|
||||
#
|
||||
# All rights reserved. This program and the accompanying materials
|
||||
# are licensed and made available under the terms and conditions of the BSD License
|
||||
# which accompanies this distribution. The full text of the license may be found at
|
||||
# http://opensource.org/licenses/bsd-license.php
|
||||
#
|
||||
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
#
|
||||
|
||||
##
|
||||
# Import Modules
|
||||
#
|
||||
|
||||
import re
|
||||
import os
|
||||
import sys
|
||||
|
||||
import antlr3
|
||||
from CLexer import CLexer
|
||||
from CParser import CParser
|
||||
|
||||
import FileProfile
|
||||
from CodeFragment import Comment
|
||||
from CodeFragment import PP_Directive
|
||||
from ParserWarning import Warning
|
||||
|
||||
|
||||
##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', '/', '\\', '\"', '\'', '*', '#')
|
||||
|
||||
SEPERATOR_TUPLE = ('=', '|', ',', '{', '}')
|
||||
|
||||
(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.
|
||||
#
|
||||
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
|
||||
|
||||
self.__Token = ""
|
||||
self.__SkippedChars = ""
|
||||
|
||||
## __IsWhiteSpace() method
|
||||
#
|
||||
# Whether char at current FileBufferPos is whitespace
|
||||
#
|
||||
# @param self The object pointer
|
||||
# @param Char The char to test
|
||||
# @retval True The char is a kind of white space
|
||||
# @retval False The char is NOT a kind of white space
|
||||
#
|
||||
def __IsWhiteSpace(self, Char):
|
||||
if Char in (T_CHAR_NULL, T_CHAR_CR, T_CHAR_SPACE, T_CHAR_TAB, T_CHAR_LF):
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
## __SkipWhiteSpace() method
|
||||
#
|
||||
# Skip white spaces from current char, return number of chars skipped
|
||||
#
|
||||
# @param self The object pointer
|
||||
# @retval Count The number of chars skipped
|
||||
#
|
||||
def __SkipWhiteSpace(self):
|
||||
Count = 0
|
||||
while not self.__EndOfFile():
|
||||
Count += 1
|
||||
if self.__CurrentChar() in (T_CHAR_NULL, T_CHAR_CR, T_CHAR_LF, T_CHAR_SPACE, T_CHAR_TAB):
|
||||
self.__SkippedChars += str(self.__CurrentChar())
|
||||
self.__GetOneChar()
|
||||
|
||||
else:
|
||||
Count = Count - 1
|
||||
return Count
|
||||
|
||||
## __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])
|
||||
|
||||
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
|
||||
|
||||
## Rewind() method
|
||||
#
|
||||
# Reset file data buffer to the initial state
|
||||
#
|
||||
# @param self The object pointer
|
||||
#
|
||||
def Rewind(self):
|
||||
self.CurrentLineNumber = 1
|
||||
self.CurrentOffsetWithinLine = 0
|
||||
|
||||
## __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
|
||||
#
|
||||
def __UndoOneChar(self):
|
||||
|
||||
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
|
||||
|
||||
## __GetOneChar() method
|
||||
#
|
||||
# Move forward one char in the file buffer
|
||||
#
|
||||
# @param self The object pointer
|
||||
#
|
||||
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
|
||||
#
|
||||
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
|
||||
|
||||
## __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]
|
||||
|
||||
## __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
|
||||
|
||||
## __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
|
||||
|
||||
## __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]
|
||||
|
||||
## __InsertComma() method
|
||||
#
|
||||
# Insert ',' to replace PP
|
||||
#
|
||||
# @param self The object pointer
|
||||
# @retval List current line contents
|
||||
#
|
||||
def __InsertComma(self, Line):
|
||||
|
||||
|
||||
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
|
||||
|
||||
if Line - 2 >= 0 and str(self.Profile.FileLinesList[Line - 2]).rstrip().endswith(','):
|
||||
return
|
||||
|
||||
if Line - 2 >= 0 and str(self.Profile.FileLinesList[Line - 2]).rstrip().endswith(';'):
|
||||
return
|
||||
|
||||
if str(self.Profile.FileLinesList[Line]).lstrip().startswith(',') or str(self.Profile.FileLinesList[Line]).lstrip().startswith(';'):
|
||||
return
|
||||
|
||||
self.Profile.FileLinesList[Line - 1].insert(self.CurrentOffsetWithinLine, ',')
|
||||
|
||||
## 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
|
||||
#
|
||||
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
|
||||
InCharLiteral = False
|
||||
|
||||
self.Profile.FileLinesList = [list(s) for s in self.Profile.FileLinesListFromFile]
|
||||
while not self.__EndOfFile():
|
||||
|
||||
if not InComment and self.__CurrentChar() == T_CHAR_DOUBLE_QUOTE:
|
||||
InString = not InString
|
||||
|
||||
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:
|
||||
if HashComment and PPDirectiveObj != None:
|
||||
if PPDirectiveObj.Content.rstrip(T_CHAR_CR).endswith(T_CHAR_BACKSLASH):
|
||||
PPDirectiveObj.Content += T_CHAR_LF
|
||||
PPExtend = True
|
||||
else:
|
||||
PPExtend = False
|
||||
|
||||
EndLinePos = (self.CurrentLineNumber, self.CurrentOffsetWithinLine)
|
||||
|
||||
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
|
||||
|
||||
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)
|
||||
|
||||
if InComment and not DoubleSlashComment and not HashComment:
|
||||
CommentObj.Content += T_CHAR_LF
|
||||
self.CurrentLineNumber += 1
|
||||
self.CurrentOffsetWithinLine = 0
|
||||
# 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
|
||||
elif InComment:
|
||||
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
|
||||
HashComment = True
|
||||
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)
|
||||
|
||||
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
|
||||
InCharLiteral = False
|
||||
|
||||
self.Profile.FileLinesList = [list(s) for s in self.Profile.FileLinesListFromFile]
|
||||
while not self.__EndOfFile():
|
||||
|
||||
if not InComment and self.__CurrentChar() == T_CHAR_DOUBLE_QUOTE:
|
||||
InString = not InString
|
||||
|
||||
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:
|
||||
if HashComment and PPDirectiveObj != None:
|
||||
if PPDirectiveObj.Content.rstrip(T_CHAR_CR).endswith(T_CHAR_BACKSLASH):
|
||||
PPDirectiveObj.Content += T_CHAR_LF
|
||||
PPExtend = True
|
||||
else:
|
||||
PPExtend = False
|
||||
|
||||
EndLinePos = (self.CurrentLineNumber, self.CurrentOffsetWithinLine)
|
||||
|
||||
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
|
||||
|
||||
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)
|
||||
|
||||
if InComment and not DoubleSlashComment and not HashComment:
|
||||
CommentObj.Content += T_CHAR_LF
|
||||
self.CurrentLineNumber += 1
|
||||
self.CurrentOffsetWithinLine = 0
|
||||
# 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
|
||||
elif InComment:
|
||||
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
|
||||
HashComment = True
|
||||
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)
|
||||
|
||||
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
|
||||
cStream = antlr3.StringStream(FileStringContents)
|
||||
lexer = CLexer(cStream)
|
||||
tStream = antlr3.CommonTokenStream(lexer)
|
||||
parser = CParser(tStream)
|
||||
parser.translation_unit()
|
||||
|
||||
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
|
||||
cStream = antlr3.StringStream(FileStringContents)
|
||||
lexer = CLexer(cStream)
|
||||
tStream = antlr3.CommonTokenStream(lexer)
|
||||
parser = CParser(tStream)
|
||||
parser.translation_unit()
|
||||
|
||||
def CleanFileProfileBuffer(self):
|
||||
FileProfile.CommentList = []
|
||||
FileProfile.PPDirectiveList = []
|
||||
FileProfile.PredicateExpressionList = []
|
||||
FileProfile.FunctionDefinitionList = []
|
||||
FileProfile.VariableDeclarationList = []
|
||||
FileProfile.EnumerationDefinitionList = []
|
||||
FileProfile.StructUnionDefinitionList = []
|
||||
FileProfile.TypedefDefinitionList = []
|
||||
FileProfile.FunctionCallingList = []
|
||||
|
||||
def PrintFragments(self):
|
||||
|
||||
print '################# ' + self.FileName + '#####################'
|
||||
|
||||
print '/****************************************/'
|
||||
print '/*************** COMMENTS ***************/'
|
||||
print '/****************************************/'
|
||||
for comment in FileProfile.CommentList:
|
||||
print str(comment.StartPos) + comment.Content
|
||||
|
||||
print '/****************************************/'
|
||||
print '/********* PREPROCESS DIRECTIVES ********/'
|
||||
print '/****************************************/'
|
||||
for pp in FileProfile.PPDirectiveList:
|
||||
print str(pp.StartPos) + pp.Content
|
||||
|
||||
print '/****************************************/'
|
||||
print '/********* VARIABLE DECLARATIONS ********/'
|
||||
print '/****************************************/'
|
||||
for var in FileProfile.VariableDeclarationList:
|
||||
print str(var.StartPos) + var.Modifier + ' '+ var.Declarator
|
||||
|
||||
print '/****************************************/'
|
||||
print '/********* FUNCTION DEFINITIONS *********/'
|
||||
print '/****************************************/'
|
||||
for func in FileProfile.FunctionDefinitionList:
|
||||
print str(func.StartPos) + func.Modifier + ' '+ func.Declarator + ' ' + str(func.NamePos)
|
||||
|
||||
print '/****************************************/'
|
||||
print '/************ ENUMERATIONS **************/'
|
||||
print '/****************************************/'
|
||||
for enum in FileProfile.EnumerationDefinitionList:
|
||||
print str(enum.StartPos) + enum.Content
|
||||
|
||||
print '/****************************************/'
|
||||
print '/*********** STRUCTS/UNIONS *************/'
|
||||
print '/****************************************/'
|
||||
for su in FileProfile.StructUnionDefinitionList:
|
||||
print str(su.StartPos) + su.Content
|
||||
|
||||
print '/****************************************/'
|
||||
print '/********* PREDICATE EXPRESSIONS ********/'
|
||||
print '/****************************************/'
|
||||
for predexp in FileProfile.PredicateExpressionList:
|
||||
print str(predexp.StartPos) + predexp.Content
|
||||
|
||||
print '/****************************************/'
|
||||
print '/************** TYPEDEFS ****************/'
|
||||
print '/****************************************/'
|
||||
for typedef in FileProfile.TypedefDefinitionList:
|
||||
print str(typedef.StartPos) + typedef.ToType
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
collector = CodeFragmentCollector(sys.argv[1])
|
||||
collector.PreprocessFile()
|
||||
print "For Test."
|
264
BaseTools/Source/Python/Ecc/Configuration.py
Normal file
264
BaseTools/Source/Python/Ecc/Configuration.py
Normal file
@ -0,0 +1,264 @@
|
||||
## @file
|
||||
# This file is used to define class Configuration
|
||||
#
|
||||
# Copyright (c) 2008, Intel Corporation
|
||||
# All rights reserved. This program and the accompanying materials
|
||||
# are licensed and made available under the terms and conditions of the BSD License
|
||||
# which accompanies this distribution. The full text of the license may be found at
|
||||
# http://opensource.org/licenses/bsd-license.php
|
||||
#
|
||||
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
#
|
||||
|
||||
##
|
||||
# Import Modules
|
||||
#
|
||||
import os
|
||||
import Common.EdkLogger as EdkLogger
|
||||
from Common.DataType import *
|
||||
from Common.String import *
|
||||
|
||||
## Configuration
|
||||
#
|
||||
# This class is used to define all items in configuration file
|
||||
#
|
||||
# @param Filename: The name of configuration file, the default is config.ini
|
||||
#
|
||||
class Configuration(object):
|
||||
def __init__(self, Filename):
|
||||
self.Filename = Filename
|
||||
|
||||
self.Version = 0.1
|
||||
|
||||
## Identify to if check all items
|
||||
# 1 - Check all items and ignore all other detailed items
|
||||
# 0 - Not check all items, the tool will go through all other detailed items to decide to check or not
|
||||
#
|
||||
self.CheckAll = 0
|
||||
|
||||
## Identify to if automatically correct mistakes
|
||||
# 1 - Automatically correct
|
||||
# 0 - Not automatically correct
|
||||
# Only the following check points can be automatically corrected, others not listed below are not supported even it is 1
|
||||
#
|
||||
# GeneralCheckTab
|
||||
# GeneralCheckIndentation
|
||||
# GeneralCheckLine
|
||||
# GeneralCheckCarriageReturn
|
||||
# SpaceCheckAll
|
||||
#
|
||||
self.AutoCorrect = 0
|
||||
|
||||
# List customized Modifer here, split with ','
|
||||
# Defaultly use the definition in class DataType
|
||||
self.ModifierList = MODIFIER_LIST
|
||||
|
||||
## General Checking
|
||||
self.GeneralCheckAll = 0
|
||||
|
||||
# Check whether NO Tab is used, replaced with spaces
|
||||
self.GeneralCheckNoTab = 1
|
||||
# The width of Tab
|
||||
self.GeneralCheckTabWidth = 2
|
||||
# Check whether the indentation is followed coding style
|
||||
self.GeneralCheckIndentation = 1
|
||||
# The width of indentation
|
||||
self.GeneralCheckIndentationWidth = 2
|
||||
# Check whether no line is exceeding defined widty
|
||||
self.GeneralCheckLine = 1
|
||||
# The width of a line
|
||||
self.GeneralCheckLineWidth = 120
|
||||
# Check whether no use of _asm in the source file
|
||||
self.GeneralCheckNo_Asm = 1
|
||||
# Check whether no use of "#progma" in source file except "#pragma pack(#)".
|
||||
self.GeneralCheckNoProgma = 1
|
||||
# Check whether there is a carriage return at the end of the file
|
||||
self.GeneralCheckCarriageReturn = 1
|
||||
# Check whether the file exists
|
||||
self.GeneralCheckFileExistence = 1
|
||||
|
||||
## Space Checking
|
||||
self.SpaceCheckAll = 1
|
||||
|
||||
## Predicate Expression Checking
|
||||
self.PredicateExpressionCheckAll = 0
|
||||
|
||||
# Check whether Boolean values, variable type BOOLEAN not use explicit comparisons to TRUE or FALSE
|
||||
self.PredicateExpressionCheckBooleanValue = 1
|
||||
# Check whether Non-Boolean comparisons use a compare operator (==, !=, >, < >=, <=).
|
||||
self.PredicateExpressionCheckNonBooleanOperator = 1
|
||||
# Check whether a comparison of any pointer to zero must be done via the NULL type
|
||||
self.PredicateExpressionCheckComparisonNullType = 1
|
||||
|
||||
## Headers Checking
|
||||
self.HeaderCheckAll = 0
|
||||
|
||||
# Check whether File header exists
|
||||
self.HeaderCheckFile = 1
|
||||
# Check whether Function header exists
|
||||
self.HeaderCheckFunction = 1
|
||||
|
||||
## C Function Layout Checking
|
||||
self.CFunctionLayoutCheckAll = 0
|
||||
|
||||
# Check whether return type exists and in the first line
|
||||
self.CFunctionLayoutCheckReturnType = 1
|
||||
# Check whether any optional functional modifiers exist and next to the return type
|
||||
self.CFunctionLayoutCheckOptionalFunctionalModifier = 1
|
||||
# Check whether the next line contains the function name, left justified, followed by the beginning of the parameter list
|
||||
# Check whether the closing parenthesis is on its own line and also indented two spaces
|
||||
self.CFunctionLayoutCheckFunctionName = 1
|
||||
# Check whether the function prototypes in include files have the same form as function definitions
|
||||
self.CFunctionLayoutCheckFunctionPrototype = 1
|
||||
# Check whether the body of a function is contained by open and close braces that must be in the first column
|
||||
self.CFunctionLayoutCheckFunctionBody = 1
|
||||
# Check whether the data declarations is the first code in a module.
|
||||
self.CFunctionLayoutCheckDataDeclaration = 1
|
||||
# Check whether no initialization of a variable as part of its declaration
|
||||
self.CFunctionLayoutCheckNoInitOfVariable = 1
|
||||
# Check whether no use of STATIC for functions
|
||||
self.CFunctionLayoutCheckNoStatic = 1
|
||||
|
||||
## Include Files Checking
|
||||
self.IncludeFileCheckAll = 0
|
||||
|
||||
#Check whether having include files with same name
|
||||
self.IncludeFileCheckSameName = 1
|
||||
# Check whether all include file contents is guarded by a #ifndef statement.
|
||||
# the #ifndef must be the first line of code following the file header comment
|
||||
# the #endif must appear on the last line in the file
|
||||
self.IncludeFileCheckIfndefStatement = 1
|
||||
# Check whether include files contain only public or only private data
|
||||
# Check whether include files NOT contain code or define data variables
|
||||
self.IncludeFileCheckData = 1
|
||||
|
||||
## Declarations and Data Types Checking
|
||||
self.DeclarationDataTypeCheckAll = 0
|
||||
|
||||
# Check whether no use of int, unsigned, char, void, static, long in any .c, .h or .asl files.
|
||||
self.DeclarationDataTypeCheckNoUseCType = 1
|
||||
# Check whether the modifiers IN, OUT, OPTIONAL, and UNALIGNED are used only to qualify arguments to a function and should not appear in a data type declaration
|
||||
self.DeclarationDataTypeCheckInOutModifier = 1
|
||||
# Check whether the EFIAPI modifier should be used at the entry of drivers, events, and member functions of protocols
|
||||
self.DeclarationDataTypeCheckEFIAPIModifier = 1
|
||||
# Check whether Enumerated Type has a 'typedef' and the name is capital
|
||||
self.DeclarationDataTypeCheckEnumeratedType = 1
|
||||
# Check whether Structure Type has a 'typedef' and the name is capital
|
||||
self.DeclarationDataTypeCheckStructureDeclaration = 1
|
||||
# Check whether having same Structure
|
||||
self.DeclarationDataTypeCheckSameStructure = 1
|
||||
# Check whether Union Type has a 'typedef' and the name is capital
|
||||
self.DeclarationDataTypeCheckUnionType = 1
|
||||
|
||||
## Naming Conventions Checking
|
||||
self.NamingConventionCheckAll = 0
|
||||
|
||||
# Check whether only capital letters are used for #define declarations
|
||||
self.NamingConventionCheckDefineStatement = 1
|
||||
# Check whether only capital letters are used for typedef declarations
|
||||
self.NamingConventionCheckTypedefStatement = 1
|
||||
# Check whether the #ifndef at the start of an include file uses both prefix and postfix underscore characters, '_'.
|
||||
self.NamingConventionCheckIfndefStatement = 1
|
||||
# Rule for path name, variable name and function name
|
||||
# 1. First character should be upper case
|
||||
# 2. Existing lower case in a word
|
||||
# 3. No space existence
|
||||
# Check whether the path name followed the rule
|
||||
self.NamingConventionCheckPathName = 1
|
||||
# Check whether the variable name followed the rule
|
||||
self.NamingConventionCheckVariableName = 1
|
||||
# Check whether the function name followed the rule
|
||||
self.NamingConventionCheckFunctionName = 1
|
||||
# Check whether NO use short variable name with single character
|
||||
self.NamingConventionCheckSingleCharacterVariable = 1
|
||||
|
||||
## Doxygen Checking
|
||||
self.DoxygenCheckAll = 0
|
||||
|
||||
# Check whether the file headers are followed Doxygen special documentation blocks in section 2.3.5
|
||||
self.DoxygenCheckFileHeader = 1
|
||||
# Check whether the function headers are followed Doxygen special documentation blocks in section 2.3.5
|
||||
self.DoxygenCheckFunctionHeader = 1
|
||||
# Check whether the first line of text in a comment block is a brief description of the element being documented.
|
||||
# The brief description must end with a period.
|
||||
self.DoxygenCheckCommentDescription = 1
|
||||
# Check whether comment lines with '///< ... text ...' format, if it is used, it should be after the code section.
|
||||
self.DoxygenCheckCommentFormat = 1
|
||||
# Check whether only Doxygen commands allowed to mark the code are @bug and @todo.
|
||||
self.DoxygenCheckCommand = 1
|
||||
|
||||
## Meta-Data File Processing Checking
|
||||
self.MetaDataFileCheckAll = 0
|
||||
|
||||
# Check whether each file defined in meta-data exists
|
||||
self.MetaDataFileCheckPathName = 1
|
||||
# Generate a list for all files defined in meta-data files
|
||||
self.MetaDataFileCheckGenerateFileList = 1
|
||||
# The path of log file
|
||||
self.MetaDataFileCheckPathOfGenerateFileList = 'File.log'
|
||||
# Check whether all Library Instances defined for a given module (or dependent library instance) match the module's type.
|
||||
# Each Library Instance must specify the Supported Module Types in its INF file,
|
||||
# and any module specifying the library instance must be one of the supported types.
|
||||
self.MetaDataFileCheckLibraryInstance = 1
|
||||
# Check whether a Library Instance has been defined for all dependent library classes
|
||||
self.MetaDataFileCheckLibraryInstanceDependent = 1
|
||||
# Check whether the Library Instances specified by the LibraryClasses sections are listed in order of dependencies
|
||||
self.MetaDataFileCheckLibraryInstanceOrder = 1
|
||||
# Check whether the unnecessary inclusion of library classes in the INF file
|
||||
self.MetaDataFileCheckLibraryNoUse = 1
|
||||
# Check whether an INF file is specified in the FDF file, but not in the DSC file, then the INF file must be for a Binary module only
|
||||
self.MetaDataFileCheckBinaryInfInFdf = 1
|
||||
# Not to report error and warning related OS include file such as "windows.h" and "stdio.h"
|
||||
# Check whether a PCD is set in a DSC file or the FDF file, but not in both.
|
||||
self.MetaDataFileCheckPcdDuplicate = 1
|
||||
# Check whether PCD settings in the FDF file can only be related to flash.
|
||||
self.MetaDataFileCheckPcdFlash = 1
|
||||
# Check whether PCDs used in INF files but not specified in DSC or FDF files
|
||||
self.MetaDataFileCheckPcdNoUse = 1
|
||||
# Check whether having duplicate guids defined for Guid/Protocol/Ppi
|
||||
self.MetaDataFileCheckGuidDuplicate = 1
|
||||
# Check whether all files under module directory are described in INF files
|
||||
self.MetaDataFileCheckModuleFileNoUse = 1
|
||||
# Check whether the PCD is correctly used in C function via its type
|
||||
self.MetaDataFileCheckPcdType = 1
|
||||
|
||||
#
|
||||
# The check points in this section are reserved
|
||||
#
|
||||
# GotoStatementCheckAll = 0
|
||||
#
|
||||
self.SpellingCheckAll = 0
|
||||
|
||||
# The directory listed here will not be parsed, split with ','
|
||||
self.SkipDirList = []
|
||||
|
||||
self.ParseConfig()
|
||||
|
||||
def ParseConfig(self):
|
||||
Filepath = os.path.normpath(self.Filename)
|
||||
if not os.path.isfile(Filepath):
|
||||
ErrorMsg = "Can't find configuration file '%s'" % Filepath
|
||||
EdkLogger.error("Ecc", EdkLogger.ECC_ERROR, ErrorMsg, File = Filepath)
|
||||
|
||||
LineNo = 0
|
||||
for Line in open(Filepath, 'r'):
|
||||
LineNo = LineNo + 1
|
||||
Line = CleanString(Line)
|
||||
if Line != '':
|
||||
List = GetSplitValueList(Line, TAB_EQUAL_SPLIT)
|
||||
if List[0] not in self.__dict__:
|
||||
ErrorMsg = "Invalid configuration option '%s' was found" % List[0]
|
||||
EdkLogger.error("Ecc", EdkLogger.ECC_ERROR, ErrorMsg, File = Filepath, Line = LineNo)
|
||||
if List[0] == 'ModifierList':
|
||||
List[1] = GetSplitValueList(List[1], TAB_COMMA_SPLIT)
|
||||
if List[0] == 'MetaDataFileCheckPathOfGenerateFileList' and List[1] == "":
|
||||
continue
|
||||
if List[0] == 'SkipDirList':
|
||||
List[1] = GetSplitValueList(List[1], TAB_COMMA_SPLIT)
|
||||
self.__dict__[List[0]] = List[1]
|
||||
|
||||
def ShowMe(self):
|
||||
print self.Filename
|
||||
for Key in self.__dict__.keys():
|
||||
print Key, '=', self.__dict__[Key]
|
344
BaseTools/Source/Python/Ecc/Database.py
Normal file
344
BaseTools/Source/Python/Ecc/Database.py
Normal file
@ -0,0 +1,344 @@
|
||||
## @file
|
||||
# This file is used to create a database used by ECC tool
|
||||
#
|
||||
# Copyright (c) 2007 ~ 2008, Intel Corporation
|
||||
# All rights reserved. This program and the accompanying materials
|
||||
# are licensed and made available under the terms and conditions of the BSD License
|
||||
# which accompanies this distribution. The full text of the license may be found at
|
||||
# http://opensource.org/licenses/bsd-license.php
|
||||
#
|
||||
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
#
|
||||
|
||||
##
|
||||
# Import Modules
|
||||
#
|
||||
import sqlite3
|
||||
import os, time
|
||||
|
||||
import Common.EdkLogger as EdkLogger
|
||||
import CommonDataClass.DataClass as DataClass
|
||||
|
||||
from Table.TableDataModel import TableDataModel
|
||||
from Table.TableFile import TableFile
|
||||
from Table.TableFunction import TableFunction
|
||||
from Table.TablePcd import TablePcd
|
||||
from Table.TableIdentifier import TableIdentifier
|
||||
from Table.TableReport import TableReport
|
||||
from Table.TableInf import TableInf
|
||||
from Table.TableDec import TableDec
|
||||
from Table.TableDsc import TableDsc
|
||||
from Table.TableFdf import TableFdf
|
||||
|
||||
##
|
||||
# Static definitions
|
||||
#
|
||||
DATABASE_PATH = "Ecc.db"
|
||||
|
||||
## Database
|
||||
#
|
||||
# This class defined the ECC databse
|
||||
# During the phase of initialization, the database will create all tables and
|
||||
# insert all records of table DataModel
|
||||
#
|
||||
# @param object: Inherited from object class
|
||||
# @param DbPath: A string for the path of the ECC database
|
||||
#
|
||||
# @var Conn: Connection of the ECC database
|
||||
# @var Cur: Cursor of the connection
|
||||
# @var TblDataModel: Local instance for TableDataModel
|
||||
#
|
||||
class Database(object):
|
||||
def __init__(self, DbPath):
|
||||
self.DbPath = DbPath
|
||||
self.Conn = None
|
||||
self.Cur = None
|
||||
self.TblDataModel = None
|
||||
self.TblFile = None
|
||||
self.TblFunction = None
|
||||
self.TblIdentifier = None
|
||||
self.TblPcd = None
|
||||
self.TblReport = None
|
||||
self.TblInf = None
|
||||
self.TblDec = None
|
||||
self.TblDsc = None
|
||||
self.TblFdf = None
|
||||
|
||||
## Initialize ECC database
|
||||
#
|
||||
# 1. Delete all old existing tables
|
||||
# 2. Create new tables
|
||||
# 3. Initialize table DataModel
|
||||
#
|
||||
def InitDatabase(self, NewDatabase = True):
|
||||
EdkLogger.verbose("\nInitialize ECC database started ...")
|
||||
#
|
||||
# Drop all old existing tables
|
||||
#
|
||||
if NewDatabase:
|
||||
if os.path.exists(self.DbPath):
|
||||
os.remove(self.DbPath)
|
||||
self.Conn = sqlite3.connect(self.DbPath, isolation_level = 'DEFERRED')
|
||||
self.Conn.execute("PRAGMA page_size=4096")
|
||||
self.Conn.execute("PRAGMA synchronous=OFF")
|
||||
# to avoid non-ascii charater conversion error
|
||||
self.Conn.text_factory = str
|
||||
self.Cur = self.Conn.cursor()
|
||||
|
||||
self.TblDataModel = TableDataModel(self.Cur)
|
||||
self.TblFile = TableFile(self.Cur)
|
||||
self.TblFunction = TableFunction(self.Cur)
|
||||
self.TblIdentifier = TableIdentifier(self.Cur)
|
||||
self.TblPcd = TablePcd(self.Cur)
|
||||
self.TblReport = TableReport(self.Cur)
|
||||
self.TblInf = TableInf(self.Cur)
|
||||
self.TblDec = TableDec(self.Cur)
|
||||
self.TblDsc = TableDsc(self.Cur)
|
||||
self.TblFdf = TableFdf(self.Cur)
|
||||
|
||||
#
|
||||
# Create new tables
|
||||
#
|
||||
if NewDatabase:
|
||||
self.TblDataModel.Create()
|
||||
self.TblFile.Create()
|
||||
self.TblFunction.Create()
|
||||
self.TblPcd.Create()
|
||||
self.TblReport.Create()
|
||||
self.TblInf.Create()
|
||||
self.TblDec.Create()
|
||||
self.TblDsc.Create()
|
||||
self.TblFdf.Create()
|
||||
|
||||
#
|
||||
# Init each table's ID
|
||||
#
|
||||
self.TblDataModel.InitID()
|
||||
self.TblFile.InitID()
|
||||
self.TblFunction.InitID()
|
||||
self.TblPcd.InitID()
|
||||
self.TblReport.InitID()
|
||||
self.TblInf.InitID()
|
||||
self.TblDec.InitID()
|
||||
self.TblDsc.InitID()
|
||||
self.TblFdf.InitID()
|
||||
|
||||
#
|
||||
# Initialize table DataModel
|
||||
#
|
||||
if NewDatabase:
|
||||
self.TblDataModel.InitTable()
|
||||
|
||||
EdkLogger.verbose("Initialize ECC database ... DONE!")
|
||||
|
||||
## Query a table
|
||||
#
|
||||
# @param Table: The instance of the table to be queried
|
||||
#
|
||||
def QueryTable(self, Table):
|
||||
Table.Query()
|
||||
|
||||
## Close entire database
|
||||
#
|
||||
# Commit all first
|
||||
# Close the connection and cursor
|
||||
#
|
||||
def Close(self):
|
||||
#
|
||||
# Commit to file
|
||||
#
|
||||
self.Conn.commit()
|
||||
|
||||
#
|
||||
# Close connection and cursor
|
||||
#
|
||||
self.Cur.close()
|
||||
self.Conn.close()
|
||||
|
||||
## Insert one file information
|
||||
#
|
||||
# Insert one file's information to the database
|
||||
# 1. Create a record in TableFile
|
||||
# 2. Create functions one by one
|
||||
# 2.1 Create variables of function one by one
|
||||
# 2.2 Create pcds of function one by one
|
||||
# 3. Create variables one by one
|
||||
# 4. Create pcds one by one
|
||||
#
|
||||
def InsertOneFile(self, File):
|
||||
#
|
||||
# Insert a record for file
|
||||
#
|
||||
FileID = self.TblFile.Insert(File.Name, File.ExtName, File.Path, File.FullPath, Model = File.Model, TimeStamp = File.TimeStamp)
|
||||
IdTable = TableIdentifier(self.Cur)
|
||||
IdTable.Table = "Identifier%s" % FileID
|
||||
IdTable.Create()
|
||||
|
||||
#
|
||||
# Insert function of file
|
||||
#
|
||||
for Function in File.FunctionList:
|
||||
FunctionID = self.TblFunction.Insert(Function.Header, Function.Modifier, Function.Name, Function.ReturnStatement, \
|
||||
Function.StartLine, Function.StartColumn, Function.EndLine, Function.EndColumn, \
|
||||
Function.BodyStartLine, Function.BodyStartColumn, FileID, \
|
||||
Function.FunNameStartLine, Function.FunNameStartColumn)
|
||||
#
|
||||
# Insert Identifier of function
|
||||
#
|
||||
for Identifier in Function.IdentifierList:
|
||||
IdentifierID = IdTable.Insert(Identifier.Modifier, Identifier.Type, Identifier.Name, Identifier.Value, Identifier.Model, \
|
||||
FileID, FunctionID, Identifier.StartLine, Identifier.StartColumn, Identifier.EndLine, Identifier.EndColumn)
|
||||
#
|
||||
# Insert Pcd of function
|
||||
#
|
||||
for Pcd in Function.PcdList:
|
||||
PcdID = self.TblPcd.Insert(Pcd.CName, Pcd.TokenSpaceGuidCName, Pcd.Token, Pcd.DatumType, Pcd.Model, \
|
||||
FileID, FunctionID, Pcd.StartLine, Pcd.StartColumn, Pcd.EndLine, Pcd.EndColumn)
|
||||
#
|
||||
# Insert Identifier of file
|
||||
#
|
||||
for Identifier in File.IdentifierList:
|
||||
IdentifierID = IdTable.Insert(Identifier.Modifier, Identifier.Type, Identifier.Name, Identifier.Value, Identifier.Model, \
|
||||
FileID, -1, Identifier.StartLine, Identifier.StartColumn, Identifier.EndLine, Identifier.EndColumn)
|
||||
#
|
||||
# Insert Pcd of file
|
||||
#
|
||||
for Pcd in File.PcdList:
|
||||
PcdID = self.TblPcd.Insert(Pcd.CName, Pcd.TokenSpaceGuidCName, Pcd.Token, Pcd.DatumType, Pcd.Model, \
|
||||
FileID, -1, Pcd.StartLine, Pcd.StartColumn, Pcd.EndLine, Pcd.EndColumn)
|
||||
|
||||
EdkLogger.verbose("Insert information from file %s ... DONE!" % File.FullPath)
|
||||
|
||||
## UpdateIdentifierBelongsToFunction
|
||||
#
|
||||
# Update the field "BelongsToFunction" for each Indentifier
|
||||
#
|
||||
#
|
||||
def UpdateIdentifierBelongsToFunction_disabled(self):
|
||||
EdkLogger.verbose("Update 'BelongsToFunction' for Identifiers started ...")
|
||||
|
||||
SqlCommand = """select ID, BelongsToFile, StartLine, EndLine, Model from Identifier"""
|
||||
EdkLogger.debug(4, "SqlCommand: %s" %SqlCommand)
|
||||
self.Cur.execute(SqlCommand)
|
||||
Records = self.Cur.fetchall()
|
||||
for Record in Records:
|
||||
IdentifierID = Record[0]
|
||||
BelongsToFile = Record[1]
|
||||
StartLine = Record[2]
|
||||
EndLine = Record[3]
|
||||
Model = Record[4]
|
||||
|
||||
#
|
||||
# Check whether an identifier belongs to a function
|
||||
#
|
||||
EdkLogger.debug(4, "For common identifiers ... ")
|
||||
SqlCommand = """select ID from Function
|
||||
where StartLine < %s and EndLine > %s
|
||||
and BelongsToFile = %s""" % (StartLine, EndLine, BelongsToFile)
|
||||
EdkLogger.debug(4, "SqlCommand: %s" %SqlCommand)
|
||||
self.Cur.execute(SqlCommand)
|
||||
IDs = self.Cur.fetchall()
|
||||
for ID in IDs:
|
||||
SqlCommand = """Update Identifier set BelongsToFunction = %s where ID = %s""" % (ID[0], IdentifierID)
|
||||
EdkLogger.debug(4, "SqlCommand: %s" %SqlCommand)
|
||||
self.Cur.execute(SqlCommand)
|
||||
|
||||
#
|
||||
# Check whether the identifier is a function header
|
||||
#
|
||||
EdkLogger.debug(4, "For function headers ... ")
|
||||
if Model == DataClass.MODEL_IDENTIFIER_COMMENT:
|
||||
SqlCommand = """select ID from Function
|
||||
where StartLine = %s + 1
|
||||
and BelongsToFile = %s""" % (EndLine, BelongsToFile)
|
||||
EdkLogger.debug(4, "SqlCommand: %s" %SqlCommand)
|
||||
self.Cur.execute(SqlCommand)
|
||||
IDs = self.Cur.fetchall()
|
||||
for ID in IDs:
|
||||
SqlCommand = """Update Identifier set BelongsToFunction = %s, Model = %s where ID = %s""" % (ID[0], DataClass.MODEL_IDENTIFIER_FUNCTION_HEADER, IdentifierID)
|
||||
EdkLogger.debug(4, "SqlCommand: %s" %SqlCommand)
|
||||
self.Cur.execute(SqlCommand)
|
||||
|
||||
EdkLogger.verbose("Update 'BelongsToFunction' for Identifiers ... DONE")
|
||||
|
||||
|
||||
## UpdateIdentifierBelongsToFunction
|
||||
#
|
||||
# Update the field "BelongsToFunction" for each Indentifier
|
||||
#
|
||||
#
|
||||
def UpdateIdentifierBelongsToFunction(self):
|
||||
EdkLogger.verbose("Update 'BelongsToFunction' for Identifiers started ...")
|
||||
|
||||
SqlCommand = """select ID, BelongsToFile, StartLine, EndLine from Function"""
|
||||
Records = self.TblFunction.Exec(SqlCommand)
|
||||
Data1 = []
|
||||
Data2 = []
|
||||
for Record in Records:
|
||||
FunctionID = Record[0]
|
||||
BelongsToFile = Record[1]
|
||||
StartLine = Record[2]
|
||||
EndLine = Record[3]
|
||||
#Data1.append(("'file%s'" % BelongsToFile, FunctionID, BelongsToFile, StartLine, EndLine))
|
||||
#Data2.append(("'file%s'" % BelongsToFile, FunctionID, DataClass.MODEL_IDENTIFIER_FUNCTION_HEADER, BelongsToFile, DataClass.MODEL_IDENTIFIER_COMMENT, StartLine - 1))
|
||||
|
||||
SqlCommand = """Update Identifier%s set BelongsToFunction = %s where BelongsToFile = %s and StartLine > %s and EndLine < %s""" % \
|
||||
(BelongsToFile, FunctionID, BelongsToFile, StartLine, EndLine)
|
||||
self.TblIdentifier.Exec(SqlCommand)
|
||||
|
||||
SqlCommand = """Update Identifier%s set BelongsToFunction = %s, Model = %s where BelongsToFile = %s and Model = %s and EndLine = %s""" % \
|
||||
(BelongsToFile, FunctionID, DataClass.MODEL_IDENTIFIER_FUNCTION_HEADER, BelongsToFile, DataClass.MODEL_IDENTIFIER_COMMENT, StartLine - 1)
|
||||
self.TblIdentifier.Exec(SqlCommand)
|
||||
# #
|
||||
# # Check whether an identifier belongs to a function
|
||||
# #
|
||||
# print Data1
|
||||
# SqlCommand = """Update ? set BelongsToFunction = ? where BelongsToFile = ? and StartLine > ? and EndLine < ?"""
|
||||
# print SqlCommand
|
||||
# EdkLogger.debug(4, "SqlCommand: %s" %SqlCommand)
|
||||
# self.Cur.executemany(SqlCommand, Data1)
|
||||
#
|
||||
# #
|
||||
# # Check whether the identifier is a function header
|
||||
# #
|
||||
# EdkLogger.debug(4, "For function headers ... ")
|
||||
# SqlCommand = """Update ? set BelongsToFunction = ?, Model = ? where BelongsToFile = ? and Model = ? and EndLine = ?"""
|
||||
# EdkLogger.debug(4, "SqlCommand: %s" %SqlCommand)
|
||||
# self.Cur.executemany(SqlCommand, Data2)
|
||||
#
|
||||
# EdkLogger.verbose("Update 'BelongsToFunction' for Identifiers ... DONE")
|
||||
|
||||
|
||||
##
|
||||
#
|
||||
# This acts like the main() function for the script, unless it is 'import'ed into another
|
||||
# script.
|
||||
#
|
||||
if __name__ == '__main__':
|
||||
EdkLogger.Initialize()
|
||||
#EdkLogger.SetLevel(EdkLogger.VERBOSE)
|
||||
EdkLogger.SetLevel(EdkLogger.DEBUG_0)
|
||||
EdkLogger.verbose("Start at " + time.strftime('%H:%M:%S', time.localtime()))
|
||||
|
||||
Db = Database(DATABASE_PATH)
|
||||
Db.InitDatabase()
|
||||
Db.QueryTable(Db.TblDataModel)
|
||||
|
||||
identifier1 = DataClass.IdentifierClass(-1, '', '', "i''1", 'aaa', DataClass.MODEL_IDENTIFIER_COMMENT, 1, -1, 32, 43, 54, 43)
|
||||
identifier2 = DataClass.IdentifierClass(-1, '', '', 'i1', 'aaa', DataClass.MODEL_IDENTIFIER_COMMENT, 1, -1, 15, 43, 20, 43)
|
||||
identifier3 = DataClass.IdentifierClass(-1, '', '', 'i1', 'aaa', DataClass.MODEL_IDENTIFIER_COMMENT, 1, -1, 55, 43, 58, 43)
|
||||
identifier4 = DataClass.IdentifierClass(-1, '', '', "i1'", 'aaa', DataClass.MODEL_IDENTIFIER_COMMENT, 1, -1, 77, 43, 88, 43)
|
||||
fun1 = DataClass.FunctionClass(-1, '', '', 'fun1', '', 21, 2, 60, 45, 1, 23, 0, [], [])
|
||||
file = DataClass.FileClass(-1, 'F1', 'c', 'C:\\', 'C:\\F1.exe', DataClass.MODEL_FILE_C, '2007-12-28', [fun1], [identifier1, identifier2, identifier3, identifier4], [])
|
||||
Db.InsertOneFile(file)
|
||||
Db.UpdateIdentifierBelongsToFunction()
|
||||
|
||||
Db.QueryTable(Db.TblFile)
|
||||
Db.QueryTable(Db.TblFunction)
|
||||
Db.QueryTable(Db.TblPcd)
|
||||
Db.QueryTable(Db.TblIdentifier)
|
||||
|
||||
Db.Close()
|
||||
EdkLogger.verbose("End at " + time.strftime('%H:%M:%S', time.localtime()))
|
||||
|
329
BaseTools/Source/Python/Ecc/Ecc.py
Normal file
329
BaseTools/Source/Python/Ecc/Ecc.py
Normal file
@ -0,0 +1,329 @@
|
||||
## @file
|
||||
# This file is used to be the main entrance of ECC tool
|
||||
#
|
||||
# Copyright (c) 2009, Intel Corporation
|
||||
# All rights reserved. This program and the accompanying materials
|
||||
# are licensed and made available under the terms and conditions of the BSD License
|
||||
# which accompanies this distribution. The full text of the license may be found at
|
||||
# http://opensource.org/licenses/bsd-license.php
|
||||
#
|
||||
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
#
|
||||
|
||||
##
|
||||
# Import Modules
|
||||
#
|
||||
import os, time, glob, sys
|
||||
import Common.EdkLogger as EdkLogger
|
||||
import Database
|
||||
import EccGlobalData
|
||||
from MetaDataParser import *
|
||||
from optparse import OptionParser
|
||||
from Configuration import Configuration
|
||||
from Check import Check
|
||||
from Common.InfClassObject import Inf
|
||||
from Common.DecClassObject import Dec
|
||||
from Common.DscClassObject import Dsc
|
||||
from Common.FdfClassObject import Fdf
|
||||
from Common.String import NormPath
|
||||
from Common import BuildToolError
|
||||
import c
|
||||
from Exception import *
|
||||
|
||||
## Ecc
|
||||
#
|
||||
# This class is used to define Ecc main entrance
|
||||
#
|
||||
# @param object: Inherited from object class
|
||||
#
|
||||
class Ecc(object):
|
||||
def __init__(self):
|
||||
# Version and Copyright
|
||||
self.VersionNumber = "0.01"
|
||||
self.Version = "%prog Version " + self.VersionNumber
|
||||
self.Copyright = "Copyright (c) 2009, Intel Corporation All rights reserved."
|
||||
|
||||
self.InitDefaultConfigIni()
|
||||
self.OutputFile = 'output.txt'
|
||||
self.ReportFile = 'Report.csv'
|
||||
self.ExceptionFile = 'exception.xml'
|
||||
self.IsInit = True
|
||||
self.ScanSourceCode = True
|
||||
self.ScanMetaData = True
|
||||
|
||||
# Parse the options and args
|
||||
self.ParseOption()
|
||||
|
||||
# Generate checkpoints list
|
||||
EccGlobalData.gConfig = Configuration(self.ConfigFile)
|
||||
|
||||
# Generate exception list
|
||||
EccGlobalData.gException = ExceptionCheck(self.ExceptionFile)
|
||||
|
||||
# Init Ecc database
|
||||
EccGlobalData.gDb = Database.Database(Database.DATABASE_PATH)
|
||||
EccGlobalData.gDb.InitDatabase(self.IsInit)
|
||||
|
||||
# Build ECC database
|
||||
self.BuildDatabase()
|
||||
|
||||
# Start to check
|
||||
self.Check()
|
||||
|
||||
# Show report
|
||||
self.GenReport()
|
||||
|
||||
# Close Database
|
||||
EccGlobalData.gDb.Close()
|
||||
|
||||
def InitDefaultConfigIni(self):
|
||||
paths = map(lambda p: os.path.join(p, 'Ecc', 'config.ini'), sys.path)
|
||||
paths = (os.path.realpath('config.ini'),) + tuple(paths)
|
||||
for path in paths:
|
||||
if os.path.exists(path):
|
||||
self.ConfigFile = path
|
||||
return
|
||||
self.ConfigFile = 'config.ini'
|
||||
|
||||
## BuildDatabase
|
||||
#
|
||||
# Build the database for target
|
||||
#
|
||||
def BuildDatabase(self):
|
||||
# Clean report table
|
||||
EccGlobalData.gDb.TblReport.Drop()
|
||||
EccGlobalData.gDb.TblReport.Create()
|
||||
|
||||
# Build database
|
||||
if self.IsInit:
|
||||
if self.ScanSourceCode:
|
||||
EdkLogger.quiet("Building database for source code ...")
|
||||
c.CollectSourceCodeDataIntoDB(EccGlobalData.gTarget)
|
||||
if self.ScanMetaData:
|
||||
EdkLogger.quiet("Building database for source code done!")
|
||||
self.BuildMetaDataFileDatabase()
|
||||
|
||||
EccGlobalData.gIdentifierTableList = GetTableList((MODEL_FILE_C, MODEL_FILE_H), 'Identifier', EccGlobalData.gDb)
|
||||
|
||||
## BuildMetaDataFileDatabase
|
||||
#
|
||||
# Build the database for meta data files
|
||||
#
|
||||
def BuildMetaDataFileDatabase(self):
|
||||
EdkLogger.quiet("Building database for meta data files ...")
|
||||
Op = open(EccGlobalData.gConfig.MetaDataFileCheckPathOfGenerateFileList, 'w+')
|
||||
#SkipDirs = Read from config file
|
||||
SkipDirs = EccGlobalData.gConfig.SkipDirList
|
||||
for Root, Dirs, Files in os.walk(EccGlobalData.gTarget):
|
||||
for Dir in Dirs:
|
||||
if Dir.upper() in SkipDirs:
|
||||
Dirs.remove(Dir)
|
||||
|
||||
for Dir in Dirs:
|
||||
Dirname = os.path.join(Root, Dir)
|
||||
if os.path.islink(Dirname):
|
||||
Dirname = os.path.realpath(Dirname)
|
||||
if os.path.isdir(Dirname):
|
||||
# symlinks to directories are treated as directories
|
||||
Dirs.remove(Dir)
|
||||
Dirs.append(Dirname)
|
||||
|
||||
for File in Files:
|
||||
if len(File) > 4 and File[-4:].upper() == ".DEC":
|
||||
Filename = os.path.normpath(os.path.join(Root, File))
|
||||
EdkLogger.quiet("Parsing %s" % Filename)
|
||||
Op.write("%s\r" % Filename)
|
||||
Dec(Filename, True, True, EccGlobalData.gWorkspace, EccGlobalData.gDb)
|
||||
continue
|
||||
if len(File) > 4 and File[-4:].upper() == ".DSC":
|
||||
Filename = os.path.normpath(os.path.join(Root, File))
|
||||
EdkLogger.quiet("Parsing %s" % Filename)
|
||||
Op.write("%s\r" % Filename)
|
||||
Dsc(Filename, True, True, EccGlobalData.gWorkspace, EccGlobalData.gDb)
|
||||
continue
|
||||
if len(File) > 4 and File[-4:].upper() == ".INF":
|
||||
Filename = os.path.normpath(os.path.join(Root, File))
|
||||
EdkLogger.quiet("Parsing %s" % Filename)
|
||||
Op.write("%s\r" % Filename)
|
||||
Inf(Filename, True, True, EccGlobalData.gWorkspace, EccGlobalData.gDb)
|
||||
continue
|
||||
if len(File) > 4 and File[-4:].upper() == ".FDF":
|
||||
Filename = os.path.normpath(os.path.join(Root, File))
|
||||
EdkLogger.quiet("Parsing %s" % Filename)
|
||||
Op.write("%s\r" % Filename)
|
||||
Fdf(Filename, True, EccGlobalData.gWorkspace, EccGlobalData.gDb)
|
||||
continue
|
||||
Op.close()
|
||||
|
||||
# Commit to database
|
||||
EccGlobalData.gDb.Conn.commit()
|
||||
|
||||
EdkLogger.quiet("Building database for meta data files done!")
|
||||
|
||||
##
|
||||
#
|
||||
# Check each checkpoint
|
||||
#
|
||||
def Check(self):
|
||||
EdkLogger.quiet("Checking ...")
|
||||
EccCheck = Check()
|
||||
EccCheck.Check()
|
||||
EdkLogger.quiet("Checking done!")
|
||||
|
||||
##
|
||||
#
|
||||
# Generate the scan report
|
||||
#
|
||||
def GenReport(self):
|
||||
EdkLogger.quiet("Generating report ...")
|
||||
EccGlobalData.gDb.TblReport.ToCSV(self.ReportFile)
|
||||
EdkLogger.quiet("Generating report done!")
|
||||
|
||||
def GetRealPathCase(self, path):
|
||||
TmpPath = path.rstrip(os.sep)
|
||||
PathParts = TmpPath.split(os.sep)
|
||||
if len(PathParts) == 0:
|
||||
return path
|
||||
if len(PathParts) == 1:
|
||||
if PathParts[0].strip().endswith(':'):
|
||||
return PathParts[0].upper()
|
||||
# Relative dir, list . current dir
|
||||
Dirs = os.listdir('.')
|
||||
for Dir in Dirs:
|
||||
if Dir.upper() == PathParts[0].upper():
|
||||
return Dir
|
||||
|
||||
if PathParts[0].strip().endswith(':'):
|
||||
PathParts[0] = PathParts[0].upper()
|
||||
ParentDir = PathParts[0]
|
||||
RealPath = ParentDir
|
||||
if PathParts[0] == '':
|
||||
RealPath = os.sep
|
||||
ParentDir = os.sep
|
||||
|
||||
PathParts.remove(PathParts[0]) # need to remove the parent
|
||||
for Part in PathParts:
|
||||
Dirs = os.listdir(ParentDir + os.sep)
|
||||
for Dir in Dirs:
|
||||
if Dir.upper() == Part.upper():
|
||||
RealPath += os.sep
|
||||
RealPath += Dir
|
||||
break
|
||||
ParentDir += os.sep
|
||||
ParentDir += Dir
|
||||
|
||||
return RealPath
|
||||
|
||||
## ParseOption
|
||||
#
|
||||
# Parse options
|
||||
#
|
||||
def ParseOption(self):
|
||||
EdkLogger.quiet("Loading ECC configuration ... done")
|
||||
(Options, Target) = self.EccOptionParser()
|
||||
|
||||
# Check workspace envirnoment
|
||||
if "WORKSPACE" not in os.environ:
|
||||
EdkLogger.error("ECC", BuildToolError.ATTRIBUTE_NOT_AVAILABLE, "Environment variable not found",
|
||||
ExtraData="WORKSPACE")
|
||||
else:
|
||||
EccGlobalData.gWorkspace = os.path.normpath(os.getenv("WORKSPACE"))
|
||||
if not os.path.exists(EccGlobalData.gWorkspace):
|
||||
EdkLogger.error("ECC", BuildToolError.FILE_NOT_FOUND, ExtraData="WORKSPACE = %s" % EccGlobalData.gWorkspace)
|
||||
os.environ["WORKSPACE"] = EccGlobalData.gWorkspace
|
||||
# Set log level
|
||||
self.SetLogLevel(Options)
|
||||
|
||||
# Set other options
|
||||
if Options.ConfigFile != None:
|
||||
self.ConfigFile = Options.ConfigFile
|
||||
if Options.OutputFile != None:
|
||||
self.OutputFile = Options.OutputFile
|
||||
if Options.ReportFile != None:
|
||||
self.ReportFile = Options.ReportFile
|
||||
if Options.Target != None:
|
||||
if not os.path.isdir(Options.Target):
|
||||
EdkLogger.error("ECC", BuildToolError.OPTION_VALUE_INVALID, ExtraData="Target [%s] does NOT exist" % Options.Target)
|
||||
else:
|
||||
EccGlobalData.gTarget = self.GetRealPathCase(os.path.normpath(Options.Target))
|
||||
else:
|
||||
EdkLogger.warn("Ecc", EdkLogger.ECC_ERROR, "The target source tree was not specified, using current WORKSPACE instead!")
|
||||
EccGlobalData.gTarget = os.path.normpath(os.getenv("WORKSPACE"))
|
||||
if Options.keepdatabase != None:
|
||||
self.IsInit = False
|
||||
if Options.metadata != None and Options.sourcecode != None:
|
||||
EdkLogger.error("ECC", BuildToolError.OPTION_CONFLICT, ExtraData="-m and -s can't be specified at one time")
|
||||
if Options.metadata != None:
|
||||
self.ScanSourceCode = False
|
||||
if Options.sourcecode != None:
|
||||
self.ScanMetaData = False
|
||||
|
||||
## SetLogLevel
|
||||
#
|
||||
# Set current log level of the tool based on args
|
||||
#
|
||||
# @param Option: The option list including log level setting
|
||||
#
|
||||
def SetLogLevel(self, Option):
|
||||
if Option.verbose != None:
|
||||
EdkLogger.SetLevel(EdkLogger.VERBOSE)
|
||||
elif Option.quiet != None:
|
||||
EdkLogger.SetLevel(EdkLogger.QUIET)
|
||||
elif Option.debug != None:
|
||||
EdkLogger.SetLevel(Option.debug + 1)
|
||||
else:
|
||||
EdkLogger.SetLevel(EdkLogger.INFO)
|
||||
|
||||
## Parse command line options
|
||||
#
|
||||
# Using standard Python module optparse to parse command line option of this tool.
|
||||
#
|
||||
# @retval Opt A optparse.Values object containing the parsed options
|
||||
# @retval Args Target of build command
|
||||
#
|
||||
def EccOptionParser(self):
|
||||
Parser = OptionParser(description = self.Copyright, version = self.Version, prog = "Ecc.exe", usage = "%prog [options]")
|
||||
Parser.add_option("-t", "--target sourcepath", action="store", type="string", dest='Target',
|
||||
help="Check all files under the target workspace.")
|
||||
Parser.add_option("-c", "--config filename", action="store", type="string", dest="ConfigFile",
|
||||
help="Specify a configuration file. Defaultly use config.ini under ECC tool directory.")
|
||||
Parser.add_option("-o", "--outfile filename", action="store", type="string", dest="OutputFile",
|
||||
help="Specify the name of an output file, if and only if one filename was specified.")
|
||||
Parser.add_option("-r", "--reportfile filename", action="store", type="string", dest="ReportFile",
|
||||
help="Specify the name of an report file, if and only if one filename was specified.")
|
||||
Parser.add_option("-m", "--metadata", action="store_true", type=None, help="Only scan meta-data files information if this option is specified.")
|
||||
Parser.add_option("-s", "--sourcecode", action="store_true", type=None, help="Only scan source code files information if this option is specified.")
|
||||
Parser.add_option("-k", "--keepdatabase", action="store_true", type=None, help="The existing Ecc database will not be cleaned except report information if this option is specified.")
|
||||
Parser.add_option("-l", "--log filename", action="store", dest="LogFile", help="""If specified, the tool should emit the changes that
|
||||
were made by the tool after printing the result message.
|
||||
If filename, the emit to the file, otherwise emit to
|
||||
standard output. If no modifications were made, then do not
|
||||
create a log file, or output a log message.""")
|
||||
Parser.add_option("-q", "--quiet", action="store_true", type=None, help="Disable all messages except FATAL ERRORS.")
|
||||
Parser.add_option("-v", "--verbose", action="store_true", type=None, help="Turn on verbose output with informational messages printed, "\
|
||||
"including library instances selected, final dependency expression, "\
|
||||
"and warning messages, etc.")
|
||||
Parser.add_option("-d", "--debug", action="store", type="int", help="Enable debug messages at specified level.")
|
||||
|
||||
(Opt, Args)=Parser.parse_args()
|
||||
|
||||
return (Opt, Args)
|
||||
|
||||
##
|
||||
#
|
||||
# This acts like the main() function for the script, unless it is 'import'ed into another
|
||||
# script.
|
||||
#
|
||||
if __name__ == '__main__':
|
||||
# Initialize log system
|
||||
EdkLogger.Initialize()
|
||||
EdkLogger.IsRaiseError = False
|
||||
EdkLogger.quiet(time.strftime("%H:%M:%S, %b.%d %Y ", time.localtime()) + "[00:00]" + "\n")
|
||||
|
||||
StartTime = time.clock()
|
||||
Ecc = Ecc()
|
||||
FinishTime = time.clock()
|
||||
|
||||
BuildDuration = time.strftime("%M:%S", time.gmtime(int(round(FinishTime - StartTime))))
|
||||
EdkLogger.quiet("\n%s [%s]" % (time.strftime("%H:%M:%S, %b.%d %Y", time.localtime()), BuildDuration))
|
24
BaseTools/Source/Python/Ecc/EccGlobalData.py
Normal file
24
BaseTools/Source/Python/Ecc/EccGlobalData.py
Normal file
@ -0,0 +1,24 @@
|
||||
## @file
|
||||
# This file is used to save global datas used by ECC tool
|
||||
#
|
||||
# Copyright (c) 2008, Intel Corporation
|
||||
# All rights reserved. This program and the accompanying materials
|
||||
# are licensed and made available under the terms and conditions of the BSD License
|
||||
# which accompanies this distribution. The full text of the license may be found at
|
||||
# http://opensource.org/licenses/bsd-license.php
|
||||
#
|
||||
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
#
|
||||
|
||||
##
|
||||
# Import Modules
|
||||
#
|
||||
import os
|
||||
|
||||
gWorkspace = ''
|
||||
gTarget = ''
|
||||
gConfig = None
|
||||
gDb = None
|
||||
gIdentifierTableList = []
|
||||
gException = None
|
179
BaseTools/Source/Python/Ecc/EccToolError.py
Normal file
179
BaseTools/Source/Python/Ecc/EccToolError.py
Normal file
@ -0,0 +1,179 @@
|
||||
## @file
|
||||
# Standardized Error Hanlding infrastructures.
|
||||
#
|
||||
# Copyright (c) 20087, Intel Corporation
|
||||
# All rights reserved. This program and the accompanying materials
|
||||
# are licensed and made available under the terms and conditions of the BSD License
|
||||
# which accompanies this distribution. The full text of the license may be found at
|
||||
# http://opensource.org/licenses/bsd-license.php
|
||||
#
|
||||
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
#
|
||||
|
||||
ERROR_GENERAL_CHECK_ALL = 1000
|
||||
ERROR_GENERAL_CHECK_NO_TAB = 1001
|
||||
ERROR_GENERAL_CHECK_INDENTATION = 1002
|
||||
ERROR_GENERAL_CHECK_LINE = 1003
|
||||
ERROR_GENERAL_CHECK_NO_ASM = 1004
|
||||
ERROR_GENERAL_CHECK_NO_PROGMA = 1005
|
||||
ERROR_GENERAL_CHECK_CARRIAGE_RETURN = 1006
|
||||
ERROR_GENERAL_CHECK_FILE_EXISTENCE = 1007
|
||||
|
||||
ERROR_SPACE_CHECK_ALL = 2000
|
||||
|
||||
ERROR_PREDICATE_EXPRESSION_CHECK_ALL = 3000
|
||||
ERROR_PREDICATE_EXPRESSION_CHECK_BOOLEAN_VALUE = 3001
|
||||
ERROR_PREDICATE_EXPRESSION_CHECK_NO_BOOLEAN_OPERATOR = 3002
|
||||
ERROR_PREDICATE_EXPRESSION_CHECK_COMPARISON_NULL_TYPE = 3003
|
||||
|
||||
ERROR_HEADER_CHECK_ALL = 4000
|
||||
ERROR_HEADER_CHECK_FILE = 4001
|
||||
ERROR_HEADER_CHECK_FUNCTION = 4002
|
||||
|
||||
ERROR_C_FUNCTION_LAYOUT_CHECK_ALL = 5000
|
||||
ERROR_C_FUNCTION_LAYOUT_CHECK_RETURN_TYPE = 5001
|
||||
ERROR_C_FUNCTION_LAYOUT_CHECK_OPTIONAL_FUNCTIONAL_MODIFIER = 5002
|
||||
ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_NAME = 5003
|
||||
ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_PROTO_TYPE = 5004
|
||||
ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_BODY = 5005
|
||||
ERROR_C_FUNCTION_LAYOUT_CHECK_DATA_DECLARATION = 5006
|
||||
ERROR_C_FUNCTION_LAYOUT_CHECK_NO_INIT_OF_VARIABLE = 5007
|
||||
ERROR_C_FUNCTION_LAYOUT_CHECK_NO_STATIC = 5008
|
||||
|
||||
ERROR_INCLUDE_FILE_CHECK_ALL = 6000
|
||||
ERROR_INCLUDE_FILE_CHECK_IFNDEF_STATEMENT_1 = 6001
|
||||
ERROR_INCLUDE_FILE_CHECK_IFNDEF_STATEMENT_2 = 6002
|
||||
ERROR_INCLUDE_FILE_CHECK_IFNDEF_STATEMENT_3 = 6003
|
||||
ERROR_INCLUDE_FILE_CHECK_DATA = 6004
|
||||
ERROR_INCLUDE_FILE_CHECK_NAME = 6005
|
||||
|
||||
ERROR_DECLARATION_DATA_TYPE_CHECK_ALL = 7000
|
||||
ERROR_DECLARATION_DATA_TYPE_CHECK_NO_USE_C_TYPE = 7001
|
||||
ERROR_DECLARATION_DATA_TYPE_CHECK_IN_OUT_MODIFIER = 7002
|
||||
ERROR_DECLARATION_DATA_TYPE_CHECK_EFI_API_MODIFIER = 7003
|
||||
ERROR_DECLARATION_DATA_TYPE_CHECK_ENUMERATED_TYPE = 7004
|
||||
ERROR_DECLARATION_DATA_TYPE_CHECK_STRUCTURE_DECLARATION = 7005
|
||||
ERROR_DECLARATION_DATA_TYPE_CHECK_SAME_STRUCTURE = 7007
|
||||
ERROR_DECLARATION_DATA_TYPE_CHECK_UNION_TYPE = 7006
|
||||
ERROR_DECLARATION_DATA_TYPE_CHECK_NESTED_STRUCTURE = 7008
|
||||
|
||||
ERROR_NAMING_CONVENTION_CHECK_ALL = 8000
|
||||
ERROR_NAMING_CONVENTION_CHECK_DEFINE_STATEMENT = 8001
|
||||
ERROR_NAMING_CONVENTION_CHECK_TYPEDEF_STATEMENT = 8002
|
||||
ERROR_NAMING_CONVENTION_CHECK_IFNDEF_STATEMENT = 8003
|
||||
ERROR_NAMING_CONVENTION_CHECK_PATH_NAME = 8004
|
||||
ERROR_NAMING_CONVENTION_CHECK_VARIABLE_NAME = 8005
|
||||
ERROR_NAMING_CONVENTION_CHECK_FUNCTION_NAME = 8006
|
||||
ERROR_NAMING_CONVENTION_CHECK_SINGLE_CHARACTER_VARIABLE = 8007
|
||||
|
||||
ERROR_DOXYGEN_CHECK_ALL = 9000
|
||||
ERROR_DOXYGEN_CHECK_FILE_HEADER = 9001
|
||||
ERROR_DOXYGEN_CHECK_FUNCTION_HEADER = 9002
|
||||
ERROR_DOXYGEN_CHECK_COMMENT_DESCRIPTION = 9003
|
||||
ERROR_DOXYGEN_CHECK_COMMENT_FORMAT = 9004
|
||||
ERROR_DOXYGEN_CHECK_COMMAND = 9005
|
||||
|
||||
ERROR_META_DATA_FILE_CHECK_ALL = 10000
|
||||
ERROR_META_DATA_FILE_CHECK_PATH_NAME = 10001
|
||||
ERROR_META_DATA_FILE_CHECK_LIBRARY_INSTANCE_1 = 10002
|
||||
ERROR_META_DATA_FILE_CHECK_LIBRARY_INSTANCE_2 = 10003
|
||||
ERROR_META_DATA_FILE_CHECK_LIBRARY_INSTANCE_DEPENDENT = 10004
|
||||
ERROR_META_DATA_FILE_CHECK_LIBRARY_INSTANCE_ORDER = 10005
|
||||
ERROR_META_DATA_FILE_CHECK_LIBRARY_NO_USE = 10006
|
||||
ERROR_META_DATA_FILE_CHECK_BINARY_INF_IN_FDF = 10007
|
||||
ERROR_META_DATA_FILE_CHECK_PCD_DUPLICATE = 10008
|
||||
ERROR_META_DATA_FILE_CHECK_PCD_FLASH = 10009
|
||||
ERROR_META_DATA_FILE_CHECK_PCD_NO_USE = 10010
|
||||
ERROR_META_DATA_FILE_CHECK_DUPLICATE_GUID = 10011
|
||||
ERROR_META_DATA_FILE_CHECK_DUPLICATE_PROTOCOL = 10012
|
||||
ERROR_META_DATA_FILE_CHECK_DUPLICATE_PPI = 10013
|
||||
ERROR_META_DATA_FILE_CHECK_MODULE_FILE_NO_USE = 10014
|
||||
ERROR_META_DATA_FILE_CHECK_PCD_TYPE = 10015
|
||||
|
||||
ERROR_SPELLING_CHECK_ALL = 11000
|
||||
|
||||
gEccErrorMessage = {
|
||||
ERROR_GENERAL_CHECK_ALL : "",
|
||||
ERROR_GENERAL_CHECK_NO_TAB : "'TAB' character is not allowed in source code, please replace each 'TAB' with two spaces",
|
||||
ERROR_GENERAL_CHECK_INDENTATION : "Indentation does not follow coding style",
|
||||
ERROR_GENERAL_CHECK_LINE : "The width of each line does not follow coding style",
|
||||
ERROR_GENERAL_CHECK_NO_ASM : "There should be no use of _asm in the source file",
|
||||
ERROR_GENERAL_CHECK_NO_PROGMA : """There should be no use of "#progma" in source file except "#pragma pack(#)\"""",
|
||||
ERROR_GENERAL_CHECK_CARRIAGE_RETURN : "There should be a carriage return at the end of the file",
|
||||
ERROR_GENERAL_CHECK_FILE_EXISTENCE : "File not found",
|
||||
|
||||
ERROR_SPACE_CHECK_ALL : "",
|
||||
|
||||
ERROR_PREDICATE_EXPRESSION_CHECK_ALL : "",
|
||||
ERROR_PREDICATE_EXPRESSION_CHECK_BOOLEAN_VALUE : "Boolean values and variable type BOOLEAN should not use explicit comparisons to TRUE or FALSE",
|
||||
ERROR_PREDICATE_EXPRESSION_CHECK_NO_BOOLEAN_OPERATOR : "Non-Boolean comparisons should use a compare operator (==, !=, >, < >=, <=)",
|
||||
ERROR_PREDICATE_EXPRESSION_CHECK_COMPARISON_NULL_TYPE : "A comparison of any pointer to zero must be done via the NULL type",
|
||||
|
||||
ERROR_HEADER_CHECK_ALL : "",
|
||||
ERROR_HEADER_CHECK_FILE : "File header doesn't exist",
|
||||
ERROR_HEADER_CHECK_FUNCTION : "Function header doesn't exist",
|
||||
|
||||
ERROR_C_FUNCTION_LAYOUT_CHECK_ALL : "",
|
||||
ERROR_C_FUNCTION_LAYOUT_CHECK_RETURN_TYPE : "Return type of a function should exist and in the first line",
|
||||
ERROR_C_FUNCTION_LAYOUT_CHECK_OPTIONAL_FUNCTIONAL_MODIFIER : "Any optional functional modifiers should exist and next to the return type",
|
||||
ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_NAME : """Function name should be left justified, followed by the beginning of the parameter list, with the closing parenthesis on its own line, indented two spaces""",
|
||||
ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_PROTO_TYPE : "Function prototypes in include files have the same form as function definitions",
|
||||
ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_BODY : "The body of a function should be contained by open and close braces that must be in the first column",
|
||||
ERROR_C_FUNCTION_LAYOUT_CHECK_DATA_DECLARATION : "The data declarations should be the first code in a module",
|
||||
ERROR_C_FUNCTION_LAYOUT_CHECK_NO_INIT_OF_VARIABLE : "There should be no initialization of a variable as part of its declaration",
|
||||
ERROR_C_FUNCTION_LAYOUT_CHECK_NO_STATIC : "There should be no use of STATIC for functions",
|
||||
|
||||
ERROR_INCLUDE_FILE_CHECK_ALL : "",
|
||||
ERROR_INCLUDE_FILE_CHECK_IFNDEF_STATEMENT_1 : "All include file contents should be guarded by a #ifndef statement.",
|
||||
ERROR_INCLUDE_FILE_CHECK_IFNDEF_STATEMENT_2 : "The #ifndef must be the first line of code following the file header comment",
|
||||
ERROR_INCLUDE_FILE_CHECK_IFNDEF_STATEMENT_3 : "The #endif must appear on the last line in the file",
|
||||
ERROR_INCLUDE_FILE_CHECK_DATA : "Include files should contain only public or only private data and cannot contain code or define data variables",
|
||||
ERROR_INCLUDE_FILE_CHECK_NAME : "No permission for the inlcude file with same names",
|
||||
|
||||
ERROR_DECLARATION_DATA_TYPE_CHECK_ALL : "",
|
||||
ERROR_DECLARATION_DATA_TYPE_CHECK_NO_USE_C_TYPE : "There should be no use of int, unsigned, char, void, static, long in any .c, .h or .asl files",
|
||||
ERROR_DECLARATION_DATA_TYPE_CHECK_IN_OUT_MODIFIER : """The modifiers IN, OUT, OPTIONAL, and UNALIGNED should be used only to qualify arguments to a function and should not appear in a data type declaration""",
|
||||
ERROR_DECLARATION_DATA_TYPE_CHECK_EFI_API_MODIFIER : "The EFIAPI modifier should be used at the entry of drivers, events, and member functions of protocols",
|
||||
ERROR_DECLARATION_DATA_TYPE_CHECK_ENUMERATED_TYPE : "Enumerated Type should have a 'typedef' and the name must be in capital letters",
|
||||
ERROR_DECLARATION_DATA_TYPE_CHECK_STRUCTURE_DECLARATION : "Structure Type should have a 'typedef' and the name must be in capital letters",
|
||||
ERROR_DECLARATION_DATA_TYPE_CHECK_SAME_STRUCTURE : "No permission for the structure with same names",
|
||||
ERROR_DECLARATION_DATA_TYPE_CHECK_UNION_TYPE : "Union Type should have a 'typedef' and the name must be in capital letters",
|
||||
ERROR_DECLARATION_DATA_TYPE_CHECK_NESTED_STRUCTURE : "Complex types should be typedef-ed",
|
||||
|
||||
ERROR_NAMING_CONVENTION_CHECK_ALL : "",
|
||||
ERROR_NAMING_CONVENTION_CHECK_DEFINE_STATEMENT : "Only capital letters are allowed to be used for #define declarations",
|
||||
ERROR_NAMING_CONVENTION_CHECK_TYPEDEF_STATEMENT : "Only capital letters are allowed to be used for typedef declarations",
|
||||
ERROR_NAMING_CONVENTION_CHECK_IFNDEF_STATEMENT : "The #ifndef at the start of an include file should use both prefix and postfix underscore characters, '_'",
|
||||
ERROR_NAMING_CONVENTION_CHECK_PATH_NAME : """Path name does not follow the rules: 1. First character should be upper case 2. Must contain lower case characters 3. No white space characters""",
|
||||
ERROR_NAMING_CONVENTION_CHECK_VARIABLE_NAME : """Variable name does not follow the rules: 1. First character should be upper case 2. Must contain lower case characters 3. No white space characters 4. Global variable name must start with a 'g'""",
|
||||
ERROR_NAMING_CONVENTION_CHECK_FUNCTION_NAME : """Function name does not follow the rules: 1. First character should be upper case 2. Must contain lower case characters 3. No white space characters""",
|
||||
ERROR_NAMING_CONVENTION_CHECK_SINGLE_CHARACTER_VARIABLE : "There should be no use of short (single character) variable names",
|
||||
|
||||
ERROR_DOXYGEN_CHECK_ALL : "",
|
||||
ERROR_DOXYGEN_CHECK_FILE_HEADER : "The file headers should follow Doxygen special documentation blocks in section 2.3.5",
|
||||
ERROR_DOXYGEN_CHECK_FUNCTION_HEADER : "The function headers should follow Doxygen special documentation blocks in section 2.3.5",
|
||||
ERROR_DOXYGEN_CHECK_COMMENT_DESCRIPTION : """The first line of text in a comment block should be a brief description of the element being documented and the brief description must end with a period.""",
|
||||
ERROR_DOXYGEN_CHECK_COMMENT_FORMAT : "For comment line with '///< ... text ...' format, if it is used, it should be after the code section",
|
||||
ERROR_DOXYGEN_CHECK_COMMAND : "Only Doxygen commands @bug and @todo are allowed to mark the code",
|
||||
|
||||
ERROR_META_DATA_FILE_CHECK_ALL : "",
|
||||
ERROR_META_DATA_FILE_CHECK_PATH_NAME : "The file defined in meta-data does not exist",
|
||||
ERROR_META_DATA_FILE_CHECK_LIBRARY_INSTANCE_1 : "A library instances defined for a given module (or dependent library instance) doesn't match the module's type.",
|
||||
ERROR_META_DATA_FILE_CHECK_LIBRARY_INSTANCE_2 : "A library instance must specify the Supported Module Types in its INF file",
|
||||
ERROR_META_DATA_FILE_CHECK_LIBRARY_INSTANCE_DEPENDENT : "A library instance must be defined for all dependent library classes",
|
||||
ERROR_META_DATA_FILE_CHECK_LIBRARY_INSTANCE_ORDER : "The library Instances specified by the LibraryClasses sections should be listed in order of dependencies",
|
||||
ERROR_META_DATA_FILE_CHECK_LIBRARY_NO_USE : "There should be no unnecessary inclusion of library classes in the INF file",
|
||||
ERROR_META_DATA_FILE_CHECK_BINARY_INF_IN_FDF : "An INF file is specified in the FDF file, but not in the DSC file, therefore the INF file must be for a Binary module only",
|
||||
ERROR_META_DATA_FILE_CHECK_PCD_DUPLICATE : "Duplicate PCDs found",
|
||||
ERROR_META_DATA_FILE_CHECK_PCD_FLASH : "PCD settings in the FDF file should only be related to flash",
|
||||
ERROR_META_DATA_FILE_CHECK_PCD_NO_USE : "There should be no PCDs declared in INF files that are not specified in in either a DSC or FDF file",
|
||||
ERROR_META_DATA_FILE_CHECK_DUPLICATE_GUID : "Duplicate GUID found",
|
||||
ERROR_META_DATA_FILE_CHECK_DUPLICATE_PROTOCOL : "Duplicate PROTOCOL found",
|
||||
ERROR_META_DATA_FILE_CHECK_DUPLICATE_PPI : "Duplicate PPI found",
|
||||
ERROR_META_DATA_FILE_CHECK_MODULE_FILE_NO_USE : "No used module files found",
|
||||
ERROR_META_DATA_FILE_CHECK_PCD_TYPE : "Wrong C code function used for this kind of PCD",
|
||||
|
||||
ERROR_SPELLING_CHECK_ALL : "",
|
||||
}
|
||||
|
87
BaseTools/Source/Python/Ecc/Exception.py
Normal file
87
BaseTools/Source/Python/Ecc/Exception.py
Normal file
@ -0,0 +1,87 @@
|
||||
## @file
|
||||
# This file is used to parse exception items found by ECC tool
|
||||
#
|
||||
# Copyright (c) 2009, Intel Corporation
|
||||
# All rights reserved. This program and the accompanying materials
|
||||
# are licensed and made available under the terms and conditions of the BSD License
|
||||
# which accompanies this distribution. The full text of the license may be found at
|
||||
# http://opensource.org/licenses/bsd-license.php
|
||||
#
|
||||
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
#
|
||||
|
||||
##
|
||||
# Import Modules
|
||||
#
|
||||
from Common.XmlRoutines import *
|
||||
import os.path
|
||||
|
||||
# ExceptionXml to parse Exception Node of XML file
|
||||
class ExceptionXml(object):
|
||||
def __init__(self):
|
||||
self.KeyWord = ''
|
||||
self.ErrorID = ''
|
||||
self.FilePath = ''
|
||||
|
||||
def FromXml(self, Item, Key):
|
||||
self.KeyWord = XmlElement(Item, '%s/KeyWord' % Key)
|
||||
self.ErrorID = XmlElement(Item, '%s/ErrorID' % Key)
|
||||
self.FilePath = os.path.normpath(XmlElement(Item, '%s/FilePath' % Key))
|
||||
|
||||
def __str__(self):
|
||||
return 'ErrorID = %s KeyWord = %s FilePath = %s' %(self.ErrorID, self.KeyWord, self.FilePath)
|
||||
|
||||
# ExceptionListXml to parse Exception Node List of XML file
|
||||
class ExceptionListXml(object):
|
||||
def __init__(self):
|
||||
self.List = []
|
||||
|
||||
def FromXmlFile(self, FilePath):
|
||||
XmlContent = XmlParseFile(FilePath)
|
||||
for Item in XmlList(XmlContent, '/ExceptionList/Exception'):
|
||||
Exp = ExceptionXml()
|
||||
Exp.FromXml(Item, 'Exception')
|
||||
self.List.append(Exp)
|
||||
|
||||
def ToList(self):
|
||||
RtnList = []
|
||||
for Item in self.List:
|
||||
#RtnList.append((Item.ErrorID, Item.KeyWord, Item.FilePath))
|
||||
RtnList.append((Item.ErrorID, Item.KeyWord))
|
||||
|
||||
return RtnList
|
||||
|
||||
def __str__(self):
|
||||
RtnStr = ''
|
||||
if self.List:
|
||||
for Item in self.List:
|
||||
RtnStr = RtnStr + str(Item) + '\n'
|
||||
return RtnStr
|
||||
|
||||
# A class to check exception
|
||||
class ExceptionCheck(object):
|
||||
def __init__(self, FilePath = None):
|
||||
self.ExceptionList = []
|
||||
self.ExceptionListXml = ExceptionListXml()
|
||||
self.LoadExceptionListXml(FilePath)
|
||||
|
||||
def LoadExceptionListXml(self, FilePath):
|
||||
if FilePath and os.path.isfile(FilePath):
|
||||
self.ExceptionListXml.FromXmlFile(FilePath)
|
||||
self.ExceptionList = self.ExceptionListXml.ToList()
|
||||
|
||||
def IsException(self, ErrorID, KeyWord, FileID=-1):
|
||||
if (str(ErrorID), KeyWord) in self.ExceptionList:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
##
|
||||
#
|
||||
# This acts like the main() function for the script, unless it is 'import'ed into another
|
||||
# script.
|
||||
#
|
||||
if __name__ == '__main__':
|
||||
El = ExceptionCheck('C:\\Hess\\Project\\BuildTool\\src\\Ecc\\exception.xml')
|
||||
print El.ExceptionList
|
57
BaseTools/Source/Python/Ecc/FileProfile.py
Normal file
57
BaseTools/Source/Python/Ecc/FileProfile.py
Normal file
@ -0,0 +1,57 @@
|
||||
## @file
|
||||
# fragments of source file
|
||||
#
|
||||
# Copyright (c) 2007, Intel Corporation
|
||||
#
|
||||
# All rights reserved. This program and the accompanying materials
|
||||
# are licensed and made available under the terms and conditions of the BSD License
|
||||
# which accompanies this distribution. The full text of the license may be found at
|
||||
# http://opensource.org/licenses/bsd-license.php
|
||||
#
|
||||
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
#
|
||||
|
||||
##
|
||||
# Import Modules
|
||||
#
|
||||
|
||||
import re
|
||||
import os
|
||||
from ParserWarning import Warning
|
||||
|
||||
CommentList = []
|
||||
PPDirectiveList = []
|
||||
PredicateExpressionList = []
|
||||
FunctionDefinitionList = []
|
||||
VariableDeclarationList = []
|
||||
EnumerationDefinitionList = []
|
||||
StructUnionDefinitionList = []
|
||||
TypedefDefinitionList = []
|
||||
FunctionCallingList = []
|
||||
|
||||
## record file data when parsing source
|
||||
#
|
||||
# May raise Exception when opening file.
|
||||
#
|
||||
class FileProfile :
|
||||
|
||||
## The constructor
|
||||
#
|
||||
# @param self The object pointer
|
||||
# @param FileName The file that to be parsed
|
||||
#
|
||||
def __init__(self, FileName):
|
||||
self.FileLinesList = []
|
||||
self.FileLinesListFromFile = []
|
||||
try:
|
||||
fsock = open(FileName, "rb", 0)
|
||||
try:
|
||||
self.FileLinesListFromFile = fsock.readlines()
|
||||
finally:
|
||||
fsock.close()
|
||||
|
||||
except IOError:
|
||||
raise Warning("Error when opening file %s" % FileName)
|
||||
|
||||
|
65
BaseTools/Source/Python/Ecc/MetaDataParser.py
Normal file
65
BaseTools/Source/Python/Ecc/MetaDataParser.py
Normal file
@ -0,0 +1,65 @@
|
||||
## @file
|
||||
# This file is used to define common parser functions for meta-data
|
||||
#
|
||||
# Copyright (c) 2008, Intel Corporation
|
||||
# All rights reserved. This program and the accompanying materials
|
||||
# are licensed and made available under the terms and conditions of the BSD License
|
||||
# which accompanies this distribution. The full text of the license may be found at
|
||||
# http://opensource.org/licenses/bsd-license.php
|
||||
#
|
||||
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
#
|
||||
|
||||
import os
|
||||
from CommonDataClass.DataClass import *
|
||||
|
||||
|
||||
## Get the inlcude path list for a source file
|
||||
#
|
||||
# 1. Find the source file belongs to which inf file
|
||||
# 2. Find the inf's package
|
||||
# 3. Return the include path list of the package
|
||||
#
|
||||
def GetIncludeListOfFile(WorkSpace, Filepath, Db):
|
||||
IncludeList = []
|
||||
Filepath = os.path.normpath(Filepath)
|
||||
SqlCommand = """
|
||||
select Value1, FullPath from Inf, File where Inf.Model = %s and Inf.BelongsToFile in(
|
||||
select distinct B.BelongsToFile from File as A left join Inf as B
|
||||
where A.ID = B.BelongsToFile and B.Model = %s and (A.Path || '%s' || B.Value1) = '%s')
|
||||
and Inf.BelongsToFile = File.ID""" \
|
||||
% (MODEL_META_DATA_PACKAGE, MODEL_EFI_SOURCE_FILE, '\\', Filepath)
|
||||
RecordSet = Db.TblFile.Exec(SqlCommand)
|
||||
for Record in RecordSet:
|
||||
DecFullPath = os.path.normpath(os.path.join(WorkSpace, Record[0]))
|
||||
InfFullPath = os.path.normpath(os.path.join(WorkSpace, Record[1]))
|
||||
(DecPath, DecName) = os.path.split(DecFullPath)
|
||||
(InfPath, InfName) = os.path.split(InfFullPath)
|
||||
SqlCommand = """select Value1 from Dec where BelongsToFile =
|
||||
(select ID from File where FullPath = '%s') and Model = %s""" \
|
||||
% (DecFullPath, MODEL_EFI_INCLUDE)
|
||||
NewRecordSet = Db.TblDec.Exec(SqlCommand)
|
||||
if InfPath not in IncludeList:
|
||||
IncludeList.append(InfPath)
|
||||
for NewRecord in NewRecordSet:
|
||||
IncludePath = os.path.normpath(os.path.join(DecPath, NewRecord[0]))
|
||||
if IncludePath not in IncludeList:
|
||||
IncludeList.append(IncludePath)
|
||||
|
||||
return IncludeList
|
||||
|
||||
## Get the table list
|
||||
#
|
||||
# Search table file and find all small tables
|
||||
#
|
||||
def GetTableList(FileModelList, Table, Db):
|
||||
TableList = []
|
||||
SqlCommand = """select ID from File where Model in %s""" % str(FileModelList)
|
||||
RecordSet = Db.TblFile.Exec(SqlCommand)
|
||||
for Record in RecordSet:
|
||||
TableName = Table + str(Record[0])
|
||||
TableList.append(TableName)
|
||||
|
||||
return TableList
|
||||
|
17
BaseTools/Source/Python/Ecc/ParserWarning.py
Normal file
17
BaseTools/Source/Python/Ecc/ParserWarning.py
Normal file
@ -0,0 +1,17 @@
|
||||
## The exception class that used to report error messages when preprocessing
|
||||
#
|
||||
# Currently the "ToolName" is set to be "ECC PP".
|
||||
#
|
||||
class Warning (Exception):
|
||||
## The constructor
|
||||
#
|
||||
# @param self The object pointer
|
||||
# @param Str The message to record
|
||||
# @param File The FDF name
|
||||
# @param Line The Line number that error occurs
|
||||
#
|
||||
def __init__(self, Str, File = None, Line = None):
|
||||
self.message = Str
|
||||
self.FileName = File
|
||||
self.LineNumber = Line
|
||||
self.ToolName = 'ECC PP'
|
0
BaseTools/Source/Python/Ecc/__init__.py
Normal file
0
BaseTools/Source/Python/Ecc/__init__.py
Normal file
2503
BaseTools/Source/Python/Ecc/c.py
Normal file
2503
BaseTools/Source/Python/Ecc/c.py
Normal file
File diff suppressed because it is too large
Load Diff
242
BaseTools/Source/Python/Ecc/config.ini
Normal file
242
BaseTools/Source/Python/Ecc/config.ini
Normal file
@ -0,0 +1,242 @@
|
||||
## @file
|
||||
# This file is used to set configuration of ECC tool
|
||||
# For the items listed below, 1 means valid, 0 means invalid
|
||||
#
|
||||
# Copyright (c) 2007, Intel Corporation
|
||||
# All rights reserved. This program and the accompanying materials
|
||||
# are licensed and made available under the terms and conditions of the BSD License
|
||||
# which accompanies this distribution. The full text of the license may be found at
|
||||
# http://opensource.org/licenses/bsd-license.php
|
||||
#
|
||||
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
#
|
||||
|
||||
#
|
||||
# Identify the version of current configuration
|
||||
#
|
||||
Version = 0.1
|
||||
|
||||
#
|
||||
# Identify to if check all items
|
||||
# 1 - Check all items and ignore all other detailed items
|
||||
# 0 - Not check all items, the tool will go through all other detailed items to decide to check or not
|
||||
#
|
||||
CheckAll = 0
|
||||
|
||||
#
|
||||
# Identify to if automatically correct mistakes
|
||||
# 1 - Automatically correct
|
||||
# 0 - Not automatically correct
|
||||
# Only the following check points can be automatically corrected, others not listed below are not supported even it is 1
|
||||
#
|
||||
# GeneralCheckTab
|
||||
# GeneralCheckIndentation
|
||||
# GeneralCheckLine
|
||||
# GeneralCheckCarriageReturn
|
||||
# SpaceCheckAll
|
||||
#
|
||||
AutoCorrect = 1
|
||||
|
||||
#
|
||||
# List customized Modifer here, split with ','
|
||||
#
|
||||
ModifierList = IN, OUT, OPTIONAL, UNALIGNED, EFI_RUNTIMESERVICE, EFI_BOOTSERVICE, EFIAPI, TPMINTERNALAPI
|
||||
|
||||
#
|
||||
# General Checking
|
||||
#
|
||||
GeneralCheckAll = 0
|
||||
|
||||
# Check whether NO Tab is used, replaced with spaces
|
||||
GeneralCheckNoTab = 1
|
||||
# The width of Tab
|
||||
GeneralCheckTabWidth = 2
|
||||
# Check whether the indentation is followed coding style
|
||||
GeneralCheckIndentation = 1
|
||||
# The width of indentation
|
||||
GeneralCheckIndentationWidth = 2
|
||||
# Check whether no line is exceeding defined widty
|
||||
GeneralCheckLine = 1
|
||||
# The width of a line
|
||||
GeneralCheckLineWidth = 120
|
||||
# Check whether no use of _asm in the source file
|
||||
GeneralCheckNo_Asm = 1
|
||||
# Check whether no use of "#progma" in source file except "#pragma pack(#)".
|
||||
GeneralCheckNoProgma = 1
|
||||
# Check whether there is a carriage return at the end of the file
|
||||
GeneralCheckCarriageReturn = 1
|
||||
# Check whether the file exists
|
||||
GeneralCheckFileExistence = 1
|
||||
|
||||
#
|
||||
# Space Checking
|
||||
#
|
||||
SpaceCheckAll = 1
|
||||
|
||||
#
|
||||
# Predicate Expression Checking
|
||||
#
|
||||
PredicateExpressionCheckAll = 0
|
||||
|
||||
# Check whether Boolean values, variable type BOOLEAN not use explicit comparisons to TRUE or FALSE
|
||||
PredicateExpressionCheckBooleanValue = 1
|
||||
# Check whether Non-Boolean comparisons use a compare operator (==, !=, >, < >=, <=).
|
||||
PredicateExpressionCheckNonBooleanOperator = 1
|
||||
# Check whether a comparison of any pointer to zero must be done via the NULL type
|
||||
PredicateExpressionCheckComparisonNullType = 1
|
||||
|
||||
#
|
||||
# Headers Checking
|
||||
#
|
||||
HeaderCheckAll = 0
|
||||
|
||||
# Check whether File header exists
|
||||
HeaderCheckFile = 1
|
||||
# Check whether Function header exists
|
||||
HeaderCheckFunction = 1
|
||||
|
||||
#
|
||||
# C Function Layout Checking
|
||||
#
|
||||
CFunctionLayoutCheckAll = 0
|
||||
|
||||
# Check whether return type exists and in the first line
|
||||
CFunctionLayoutCheckReturnType = 1
|
||||
# Check whether any optional functional modifiers exist and next to the return type
|
||||
CFunctionLayoutCheckOptionalFunctionalModifier = 1
|
||||
# Check whether the next line contains the function name, left justified, followed by the beginning of the parameter list
|
||||
# Check whether the closing parenthesis is on its own line and also indented two spaces
|
||||
CFunctionLayoutCheckFunctionName = 1
|
||||
# Check whether the function prototypes in include files have the same form as function definitions
|
||||
CFunctionLayoutCheckFunctionPrototype = 1
|
||||
# Check whether the body of a function is contained by open and close braces that must be in the first column
|
||||
CFunctionLayoutCheckFunctionBody = 1
|
||||
# Check whether the data declarations is the first code in a module.
|
||||
CFunctionLayoutCheckDataDeclaration = 1
|
||||
# Check whether no initialization of a variable as part of its declaration
|
||||
CFunctionLayoutCheckNoInitOfVariable = 1
|
||||
# Check whether no use of STATIC for functions
|
||||
CFunctionLayoutCheckNoStatic = 1
|
||||
|
||||
#
|
||||
# Include Files Checking
|
||||
#
|
||||
IncludeFileCheckAll = 0
|
||||
|
||||
#Check whether having include files with same name
|
||||
IncludeFileCheckSameName = 1
|
||||
# Check whether all include file contents is guarded by a #ifndef statement.
|
||||
# the #ifndef must be the first line of code following the file header comment
|
||||
# the #endif must appear on the last line in the file
|
||||
IncludeFileCheckIfndefStatement = 1
|
||||
# Check whether include files contain only public or only private data
|
||||
# Check whether include files NOT contain code or define data variables
|
||||
IncludeFileCheckData = 1
|
||||
|
||||
#
|
||||
# Declarations and Data Types Checking
|
||||
#
|
||||
DeclarationDataTypeCheckAll = 0
|
||||
|
||||
# Check whether no use of int, unsigned, char, void, static, long in any .c, .h or .asl files.
|
||||
DeclarationDataTypeCheckNoUseCType = 1
|
||||
# Check whether the modifiers IN, OUT, OPTIONAL, and UNALIGNED are used only to qualify arguments to a function and should not appear in a data type declaration
|
||||
DeclarationDataTypeCheckInOutModifier = 1
|
||||
# Check whether the EFIAPI modifier should be used at the entry of drivers, events, and member functions of protocols
|
||||
DeclarationDataTypeCheckEFIAPIModifier = 1
|
||||
# Check whether Enumerated Type has a 'typedef' and the name is capital
|
||||
DeclarationDataTypeCheckEnumeratedType = 1
|
||||
# Check whether Structure Type has a 'typedef' and the name is capital
|
||||
DeclarationDataTypeCheckStructureDeclaration = 1
|
||||
# Check whether having same Structure
|
||||
DeclarationDataTypeCheckSameStructure = 1
|
||||
# Check whether Union Type has a 'typedef' and the name is capital
|
||||
DeclarationDataTypeCheckUnionType = 1
|
||||
|
||||
|
||||
#
|
||||
# Naming Conventions Checking
|
||||
#
|
||||
NamingConventionCheckAll = 0
|
||||
|
||||
# Check whether only capital letters are used for #define declarations
|
||||
NamingConventionCheckDefineStatement = 1
|
||||
# Check whether only capital letters are used for typedef declarations
|
||||
NamingConventionCheckTypedefStatement = 1
|
||||
# Check whether the #ifndef at the start of an include file uses both prefix and postfix underscore characters, '_'.
|
||||
NamingConventionCheckIfndefStatement = 1
|
||||
# Rule for path name, variable name and function name
|
||||
# 1. First character should be upper case
|
||||
# 2. Existing lower case in a word
|
||||
# 3. No space existence
|
||||
# 4. Global variable name must start by a 'g'
|
||||
# Check whether the path name followed the rule
|
||||
NamingConventionCheckPathName = 1
|
||||
# Check whether the variable name followed the rule
|
||||
NamingConventionCheckVariableName = 1
|
||||
# Check whether the function name followed the rule
|
||||
NamingConventionCheckFunctionName = 1
|
||||
# Check whether NO use short variable name with single character
|
||||
NamingConventionCheckSingleCharacterVariable = 1
|
||||
|
||||
#
|
||||
# Doxygen Checking
|
||||
#
|
||||
DoxygenCheckAll = 0
|
||||
|
||||
# Check whether the file headers are followed Doxygen special documentation blocks in section 2.3.5
|
||||
DoxygenCheckFileHeader = 1
|
||||
# Check whether the function headers are followed Doxygen special documentation blocks in section 2.3.5
|
||||
DoxygenCheckFunctionHeader = 1
|
||||
# Check whether the first line of text in a comment block is a brief description of the element being documented.
|
||||
# The brief description must end with a period.
|
||||
DoxygenCheckCommentDescription = 1
|
||||
# Check whether comment lines with '///< ... text ...' format, if it is used, it should be after the code section.
|
||||
DoxygenCheckCommentFormat = 1
|
||||
# Check whether only Doxygen commands allowed to mark the code are @bug and @todo.
|
||||
DoxygenCheckCommand = 1
|
||||
|
||||
#
|
||||
# Meta-Data File Processing Checking
|
||||
#
|
||||
MetaDataFileCheckAll = 0
|
||||
|
||||
# Check whether each file defined in meta-data exists
|
||||
MetaDataFileCheckPathName = 1
|
||||
# Generate a list for all files defined in meta-data files
|
||||
MetaDataFileCheckGenerateFileList = 1
|
||||
# The path of log file
|
||||
MetaDataFileCheckPathOfGenerateFileList = File.log
|
||||
# Check whether all Library Instances defined for a given module (or dependent library instance) match the module's type.
|
||||
# Each Library Instance must specify the Supported Module Types in its INF file,
|
||||
# and any module specifying the library instance must be one of the supported types.
|
||||
MetaDataFileCheckLibraryInstance = 1
|
||||
# Check whether a Library Instance has been defined for all dependent library classes
|
||||
MetaDataFileCheckLibraryInstanceDependent = 1
|
||||
# Check whether the Library Instances specified by the LibraryClasses sections are listed in order of dependencies
|
||||
MetaDataFileCheckLibraryInstanceOrder = 1
|
||||
# Check whether the unnecessary inclusion of library classes in the INF file
|
||||
MetaDataFileCheckLibraryNoUse = 1
|
||||
# Check whether an INF file is specified in the FDF file, but not in the DSC file, then the INF file must be for a Binary module only
|
||||
MetaDataFileCheckBinaryInfInFdf = 1
|
||||
# Not to report error and warning related OS include file such as "windows.h" and "stdio.h".
|
||||
# Check whether a PCD is set in a DSC file or the FDF file, but not in both.
|
||||
MetaDataFileCheckPcdDuplicate = 1
|
||||
# Check whether PCD settings in the FDF file can only be related to flash.
|
||||
MetaDataFileCheckPcdFlash = 1
|
||||
# Check whether PCDs used in INF files but not specified in DSC or FDF files
|
||||
MetaDataFileCheckPcdNoUse = 1
|
||||
# Check whether having duplicate guids defined for Guid/Protocol/Ppi
|
||||
MetaDataFileCheckGuidDuplicate = 1
|
||||
# Check whether all files under module directory are described in INF files
|
||||
MetaDataFileCheckModuleFileNoUse = 1
|
||||
# Check whether the PCD is correctly used in C function via its type
|
||||
MetaDataFileCheckPcdType = 1
|
||||
|
||||
#
|
||||
# The check points in this section are reserved
|
||||
#
|
||||
# GotoStatementCheckAll = 0
|
||||
# SpellingCheckAll = 0
|
||||
#
|
310
BaseTools/Source/Python/Ecc/exception.xml
Normal file
310
BaseTools/Source/Python/Ecc/exception.xml
Normal file
@ -0,0 +1,310 @@
|
||||
<ExceptionList xmlns="http://www.uefi.org/2008/2.1" xmlns:xsi="http:/www.w3.org/2001/XMLSchema-instance">
|
||||
<Exception>
|
||||
<KeyWord>__debugbreak</KeyWord>
|
||||
<ErrorID>4002</ErrorID>
|
||||
</Exception>
|
||||
<Exception>
|
||||
<KeyWord>__readmsr</KeyWord>
|
||||
<ErrorID>4002</ErrorID>
|
||||
</Exception>
|
||||
<Exception>
|
||||
<KeyWord>__writemsr</KeyWord>
|
||||
<ErrorID>4002</ErrorID>
|
||||
</Exception>
|
||||
<Exception>
|
||||
<KeyWord>_InterlockedCompareExchange</KeyWord>
|
||||
<ErrorID>4002</ErrorID>
|
||||
</Exception>
|
||||
<Exception>
|
||||
<KeyWord>_InterlockedCompareExchange64</KeyWord>
|
||||
<ErrorID>4002</ErrorID>
|
||||
</Exception>
|
||||
<Exception>
|
||||
<KeyWord>_InterlockedDecrement</KeyWord>
|
||||
<ErrorID>4002</ErrorID>
|
||||
</Exception>
|
||||
<Exception>
|
||||
<KeyWord>_InterlockedIncrement</KeyWord>
|
||||
<ErrorID>4002</ErrorID>
|
||||
</Exception>
|
||||
<Exception>
|
||||
<KeyWord>_break</KeyWord>
|
||||
<ErrorID>4002</ErrorID>
|
||||
</Exception>
|
||||
<Exception>
|
||||
<KeyWord>_inp</KeyWord>
|
||||
<ErrorID>4002</ErrorID>
|
||||
</Exception>
|
||||
<Exception>
|
||||
<KeyWord>_inpw</KeyWord>
|
||||
<ErrorID>4002</ErrorID>
|
||||
</Exception>
|
||||
<Exception>
|
||||
<KeyWord>_inpd</KeyWord>
|
||||
<ErrorID>4002</ErrorID>
|
||||
</Exception>
|
||||
<Exception>
|
||||
<KeyWord>_outp</KeyWord>
|
||||
<ErrorID>4002</ErrorID>
|
||||
</Exception>
|
||||
<Exception>
|
||||
<KeyWord>_outpw</KeyWord>
|
||||
<ErrorID>4002</ErrorID>
|
||||
</Exception>
|
||||
<Exception>
|
||||
<KeyWord>_outpd</KeyWord>
|
||||
<ErrorID>4002</ErrorID>
|
||||
</Exception>
|
||||
<Exception>
|
||||
<KeyWord>_ReadWriteBarrier</KeyWord>
|
||||
<ErrorID>4002</ErrorID>
|
||||
</Exception>
|
||||
<Exception>
|
||||
<KeyWord>InternalX86DisablePaging32</KeyWord>
|
||||
<ErrorID>4002</ErrorID>
|
||||
</Exception>
|
||||
<Exception>
|
||||
<KeyWord>InternalX86EnablePaging32</KeyWord>
|
||||
<ErrorID>4002</ErrorID>
|
||||
</Exception>
|
||||
<Exception>
|
||||
<KeyWord>InternalLongJump</KeyWord>
|
||||
<ErrorID>4002</ErrorID>
|
||||
</Exception>
|
||||
<Exception>
|
||||
<KeyWord>SetJump</KeyWord>
|
||||
<ErrorID>4002</ErrorID>
|
||||
</Exception>
|
||||
<Exception>
|
||||
<KeyWord>__debugbreak</KeyWord>
|
||||
<ErrorID>5001</ErrorID>
|
||||
</Exception>
|
||||
<Exception>
|
||||
<KeyWord>__readmsr</KeyWord>
|
||||
<ErrorID>5001</ErrorID>
|
||||
</Exception>
|
||||
<Exception>
|
||||
<KeyWord>__writemsr</KeyWord>
|
||||
<ErrorID>5001</ErrorID>
|
||||
</Exception>
|
||||
<Exception>
|
||||
<KeyWord>_InterlockedCompareExchange</KeyWord>
|
||||
<ErrorID>5001</ErrorID>
|
||||
</Exception>
|
||||
<Exception>
|
||||
<KeyWord>_InterlockedCompareExchange64</KeyWord>
|
||||
<ErrorID>5001</ErrorID>
|
||||
</Exception>
|
||||
<Exception>
|
||||
<KeyWord>_InterlockedDecrement</KeyWord>
|
||||
<ErrorID>5001</ErrorID>
|
||||
</Exception>
|
||||
<Exception>
|
||||
<KeyWord>_InterlockedIncrement</KeyWord>
|
||||
<ErrorID>5001</ErrorID>
|
||||
</Exception>
|
||||
<Exception>
|
||||
<KeyWord>_inp</KeyWord>
|
||||
<ErrorID>5001</ErrorID>
|
||||
</Exception>
|
||||
<Exception>
|
||||
<KeyWord>_inpw</KeyWord>
|
||||
<ErrorID>5001</ErrorID>
|
||||
</Exception>
|
||||
<Exception>
|
||||
<KeyWord>_inpd</KeyWord>
|
||||
<ErrorID>5001</ErrorID>
|
||||
</Exception>
|
||||
<Exception>
|
||||
<KeyWord>_outp</KeyWord>
|
||||
<ErrorID>5001</ErrorID>
|
||||
</Exception>
|
||||
<Exception>
|
||||
<KeyWord>_outpw</KeyWord>
|
||||
<ErrorID>5001</ErrorID>
|
||||
</Exception>
|
||||
<Exception>
|
||||
<KeyWord>_outpd</KeyWord>
|
||||
<ErrorID>5001</ErrorID>
|
||||
</Exception>
|
||||
<Exception>
|
||||
<KeyWord>_ReadWriteBarrier</KeyWord>
|
||||
<ErrorID>5001</ErrorID>
|
||||
</Exception>
|
||||
<Exception>
|
||||
<KeyWord>IoRead8</KeyWord>
|
||||
<ErrorID>5001</ErrorID>
|
||||
</Exception>
|
||||
<Exception>
|
||||
<KeyWord>IoWrite8</KeyWord>
|
||||
<ErrorID>5001</ErrorID>
|
||||
</Exception>
|
||||
<Exception>
|
||||
<KeyWord>IoRead16</KeyWord>
|
||||
<ErrorID>5001</ErrorID>
|
||||
</Exception>
|
||||
<Exception>
|
||||
<KeyWord>IoWrite16</KeyWord>
|
||||
<ErrorID>5001</ErrorID>
|
||||
</Exception>
|
||||
<Exception>
|
||||
<KeyWord>IoRead32</KeyWord>
|
||||
<ErrorID>5001</ErrorID>
|
||||
</Exception>
|
||||
<Exception>
|
||||
<KeyWord>IoWrite32</KeyWord>
|
||||
<ErrorID>5001</ErrorID>
|
||||
</Exception>
|
||||
<Exception>
|
||||
<KeyWord>__debugbreak</KeyWord>
|
||||
<ErrorID>5003</ErrorID>
|
||||
</Exception>
|
||||
<Exception>
|
||||
<KeyWord>__readmsr</KeyWord>
|
||||
<ErrorID>5003</ErrorID>
|
||||
</Exception>
|
||||
<Exception>
|
||||
<KeyWord>__writemsr</KeyWord>
|
||||
<ErrorID>5003</ErrorID>
|
||||
</Exception>
|
||||
<Exception>
|
||||
<KeyWord>_InterlockedCompareExchange</KeyWord>
|
||||
<ErrorID>5003</ErrorID>
|
||||
</Exception>
|
||||
<Exception>
|
||||
<KeyWord>_InterlockedCompareExchange64</KeyWord>
|
||||
<ErrorID>5003</ErrorID>
|
||||
</Exception>
|
||||
<Exception>
|
||||
<KeyWord>_InterlockedDecrement</KeyWord>
|
||||
<ErrorID>5003</ErrorID>
|
||||
</Exception>
|
||||
<Exception>
|
||||
<KeyWord>_InterlockedIncrement</KeyWord>
|
||||
<ErrorID>5003</ErrorID>
|
||||
</Exception>
|
||||
<Exception>
|
||||
<KeyWord>_inp</KeyWord>
|
||||
<ErrorID>5003</ErrorID>
|
||||
</Exception>
|
||||
<Exception>
|
||||
<KeyWord>_inpw</KeyWord>
|
||||
<ErrorID>5003</ErrorID>
|
||||
</Exception>
|
||||
<Exception>
|
||||
<KeyWord>_inpd</KeyWord>
|
||||
<ErrorID>5003</ErrorID>
|
||||
</Exception>
|
||||
<Exception>
|
||||
<KeyWord>_outp</KeyWord>
|
||||
<ErrorID>5003</ErrorID>
|
||||
</Exception>
|
||||
<Exception>
|
||||
<KeyWord>_outpw</KeyWord>
|
||||
<ErrorID>5003</ErrorID>
|
||||
</Exception>
|
||||
<Exception>
|
||||
<KeyWord>_outpd</KeyWord>
|
||||
<ErrorID>5003</ErrorID>
|
||||
</Exception>
|
||||
<Exception>
|
||||
<KeyWord>_ReadWriteBarrier</KeyWord>
|
||||
<ErrorID>5003</ErrorID>
|
||||
</Exception>
|
||||
<Exception>
|
||||
<KeyWord>__debugbreak</KeyWord>
|
||||
<ErrorID>7001</ErrorID>
|
||||
</Exception>
|
||||
<Exception>
|
||||
<KeyWord>__readmsr</KeyWord>
|
||||
<ErrorID>7001</ErrorID>
|
||||
</Exception>
|
||||
<Exception>
|
||||
<KeyWord>__writemsr</KeyWord>
|
||||
<ErrorID>7001</ErrorID>
|
||||
</Exception>
|
||||
<Exception>
|
||||
<KeyWord>_InterlockedCompareExchange</KeyWord>
|
||||
<ErrorID>7001</ErrorID>
|
||||
</Exception>
|
||||
<Exception>
|
||||
<KeyWord>_InterlockedCompareExchange64</KeyWord>
|
||||
<ErrorID>7001</ErrorID>
|
||||
</Exception>
|
||||
<Exception>
|
||||
<KeyWord>_InterlockedDecrement</KeyWord>
|
||||
<ErrorID>7001</ErrorID>
|
||||
</Exception>
|
||||
<Exception>
|
||||
<KeyWord>_InterlockedIncrement</KeyWord>
|
||||
<ErrorID>7001</ErrorID>
|
||||
</Exception>
|
||||
<Exception>
|
||||
<KeyWord>_inp</KeyWord>
|
||||
<ErrorID>7001</ErrorID>
|
||||
</Exception>
|
||||
<Exception>
|
||||
<KeyWord>_inpw</KeyWord>
|
||||
<ErrorID>7001</ErrorID>
|
||||
</Exception>
|
||||
<Exception>
|
||||
<KeyWord>_inpd</KeyWord>
|
||||
<ErrorID>7001</ErrorID>
|
||||
</Exception>
|
||||
<Exception>
|
||||
<KeyWord>_outp</KeyWord>
|
||||
<ErrorID>7001</ErrorID>
|
||||
</Exception>
|
||||
<Exception>
|
||||
<KeyWord>_outpw</KeyWord>
|
||||
<ErrorID>7001</ErrorID>
|
||||
</Exception>
|
||||
<Exception>
|
||||
<KeyWord>_outpd</KeyWord>
|
||||
<ErrorID>7001</ErrorID>
|
||||
</Exception>
|
||||
<Exception>
|
||||
<KeyWord>_ReadWriteBarrier</KeyWord>
|
||||
<ErrorID>7001</ErrorID>
|
||||
</Exception>
|
||||
<Exception>
|
||||
<KeyWord>@</KeyWord>
|
||||
<ErrorID>9005</ErrorID>
|
||||
</Exception>
|
||||
<Exception>
|
||||
<KeyWord>@R1</KeyWord>
|
||||
<ErrorID>9005</ErrorID>
|
||||
</Exception>
|
||||
<Exception>
|
||||
<KeyWord>@R2</KeyWord>
|
||||
<ErrorID>9005</ErrorID>
|
||||
</Exception>
|
||||
<Exception>
|
||||
<KeyWord>@Rx</KeyWord>
|
||||
<ErrorID>9005</ErrorID>
|
||||
</Exception>
|
||||
<Exception>
|
||||
<KeyWord>@R2.</KeyWord>
|
||||
<ErrorID>9005</ErrorID>
|
||||
</Exception>
|
||||
<Exception>
|
||||
<KeyWord>_DriverUnloadHandler</KeyWord>
|
||||
<ErrorID>8006</ErrorID>
|
||||
</Exception>
|
||||
<Exception>
|
||||
<KeyWord>ASSERT</KeyWord>
|
||||
<ErrorID>10015</ErrorID>
|
||||
</Exception>
|
||||
<Exception>
|
||||
<KeyWord>REPORT_STATUS_CODE</KeyWord>
|
||||
<ErrorID>10015</ErrorID>
|
||||
</Exception>
|
||||
<Exception>
|
||||
<KeyWord>REPORT_STATUS_CODE_WITH_EXTENDED_DATA</KeyWord>
|
||||
<ErrorID>10015</ErrorID>
|
||||
</Exception>
|
||||
<Exception>
|
||||
<KeyWord>REPORT_STATUS_CODE_WITH_DEVICE_PATH</KeyWord>
|
||||
<ErrorID>10015</ErrorID>
|
||||
</Exception>
|
||||
</ExceptionList>
|
Reference in New Issue
Block a user