def test_scope_in_const_definition(self): code = """ #include "cryptopp/cryptopp/pch.h" #include "cryptopp/cryptopp/cast.h" namespace CryptoPP{ // CAST S-boxes int CAST::x = 1; int CAST::y; int z; const word32 CAST::S[8][256] = { { 0x30FB40D4UL, 0x9FA0FF0BUL, 0x6BECCD2FUL, 0x3F258C7AUL, 0x1E213F2FUL, 0x9C004DD3UL, 0x6003E540UL, 0xCF9FC949UL, 0xBFD4AF27UL, 0x88BBBDB5UL, 0xE2034090UL, 0x98D09675UL, 0x6E63A0E0UL, 0x15C361D2UL, 0xC2E7661DUL, 0x22D4FF8EUL }} """ parser = DRLCPPParser() parser.parse(code) expected = set([ CPPItem(type_=CPPItem.VAR, name='S', scope='CryptoPP::CAST'), CPPItem(type_=CPPItem.VAR, name='x', scope='CryptoPP::CAST'), CPPItem(type_=CPPItem.VAR, name='y', scope='CryptoPP::CAST'), CPPItem(type_=CPPItem.VAR, name='z', scope='CryptoPP') ]) self.assertItemsEqual(expected, parser.definitions)
def handle_statement(self, statement, scope, declarations, definitions): tokens = self.tokenize_code(statement[0]) if not tokens: return if '(' in tokens: name, scop = self._extract_scope_and_name(tokens, '(') scope = CPPItem.extend_scope(scope, scop) if statement[1] is None: declarations.add(CPPItem(CPPItem.METHOD, name, scope)) else: definitions.add(CPPItem(CPPItem.METHOD, name, scope)) return if 'namespace' in tokens: if statement[1] is not None: try: name = tokens[tokens.index('namespace') + 1] scope = CPPItem.extend_scope(scope, name) self.recursive_parser(statement[1], scope, declarations, definitions) except: pass # Anonimous namespace return if 'class' in tokens: if statement[1] is not None: class_index = -1 # Inheritance case if ':' in tokens: class_index = tokens.index(':') - 1 name = tokens[class_index] # If class or struct, the class name is the last one declarations.add(CPPItem(CPPItem.CLASS, name, scope)) return if 'struct' in tokens and statement[1] is not None and tokens[-1] != '=': name = tokens[-1] # If class or struct, the class name is the last one declarations.add(CPPItem(CPPItem.STRUCT, name, scope)) return if 'using' in tokens: return if 'extern' in tokens and statement[1] is not None: # for extern "C" { constructs self.recursive_parser(statement[1], scope, declarations, definitions) if '[' in tokens: # declaring array name, scop = self._extract_scope_and_name(tokens, '[') scope = CPPItem.extend_scope(scope, scop) elif '=' in tokens: name, scop = self._extract_scope_and_name(tokens, '=') scope = CPPItem.extend_scope(scope, scop) else: name, scop = self._extract_scope_and_name(tokens) scope = CPPItem.extend_scope(scope, scop) if 'extern' in tokens: declarations.add(CPPItem(CPPItem.VAR, name, scope)) return definitions.add(CPPItem(CPPItem.VAR, name, scope))
def test_multiline_define(self): text = r'''#if !defined(_WIN32) && !defined(WIN32) && !defined(_WRS_KERNEL) \ && !defined(__minux) void kk(int a); # else void pun(int a); # endif''' parser = FileParser() includes, refs, declarations, definitions, comments = parser.parse(text) self.assertIn(CPPItem(CPPItem.METHOD, 'pun', ''), declarations) self.assertIn(CPPItem(CPPItem.METHOD, 'kk', ''), declarations)
def test_destructor(self): text = r""" namespace Poco { LexicalHandler::~LexicalHandler() { } }""" parser = DRLCPPParser() parser.parse(text) self.assertEqual( CPPItem(CPPItem.METHOD, '~LexicalHandler', 'Poco::LexicalHandler'), parser.definitions.pop())
def check_declarations(self, cell, content, defs_dict, implicits): for declaration in content.parser.declarations: try: if declaration.type in [CPPItem.CLASS, CPPItem.STRUCT]: scope = CPPItem.extend_scope(declaration.scope, declaration.name) ds = defs_dict[cell.name.block_name][scope].values() for d in ds: d.discard(cell.name) #logger.debug('Adding class/struct as implicit %s because %s in defs dict' # % (cell.name, str(d))) implicits.update(d) else: ds = defs_dict[cell.name.block_name][declaration.scope][declaration.name] ds.discard(cell.name) #logger.debug('Adding implicit %s: %s because %s is in defs dict' # % (cell.name, str(ds), str(declaration.name))) implicits.update(ds) except KeyError: # Declaration not found in definitions pass
def test_namespace(self): text = r''' namespace Geom { float intersect(); float other(){ return 0.0f; } class Line{ }; namespace NS{ float foo(); class Bar{ }; } } float Geom::intersect(){ return 0; } float Geom::NS::intersect2(){ return 0; } ''' parser = DRLCPPParser() parser.parse(text) expected = set([ CPPItem(CPPItem.CLASS, 'Line', 'Geom'), CPPItem(CPPItem.METHOD, 'intersect', 'Geom'), CPPItem(CPPItem.CLASS, 'Bar', 'Geom::NS'), CPPItem(CPPItem.METHOD, 'foo', 'Geom::NS'), ]) self.assertEqual(expected, parser.declarations) expected = set([ CPPItem(CPPItem.METHOD, 'other', 'Geom'), CPPItem(CPPItem.METHOD, 'intersect', 'Geom'), CPPItem(CPPItem.METHOD, 'intersect2', 'Geom::NS'), ]) self.assertEqual(expected, parser.definitions)
def test_declaration_defintions(self): text = r''' int a; float b = 0.0f; extern double c; float suma(float a, float b) //comment { //suma return a+b; } class PreDecl //My predc ; float multiply(float a, float b); class Sphere : public Polygon//MyClass comment { protected: float radius; public: Sphere(float r):radius(r){ /*Inline coment*/}; float volume(){ return radius*radius*radius; } float methodDecl(); }; ''' parser = DRLCPPParser() parser.parse(text) expected = set([ CPPItem(CPPItem.CLASS, 'Sphere'), CPPItem(CPPItem.VAR, 'c'), CPPItem(CPPItem.METHOD, 'multiply'), ]) #print parser.declarations self.assertEqual(expected, parser.declarations) expected = set([ CPPItem(CPPItem.VAR, 'a'), CPPItem(CPPItem.VAR, 'b'), CPPItem(CPPItem.METHOD, 'suma'), ]) self.assertEqual(expected, parser.definitions)
def test_escape_single_character(self): text = r"""int a=3; char b='\''; char c='c'; char d='\''; char e='e'; int main(){ } """ parser = FileParser() includes, refs, declarations, definitions, comments = parser.parse(text) #print parser.declarations #print parser.definitions self.assertIn(CPPItem(CPPItem.METHOD, 'main', ''), definitions) self.assertIn(CPPItem(CPPItem.VAR, 'a', ''), definitions) self.assertIn(CPPItem(CPPItem.VAR, 'b', ''), definitions) self.assertIn(CPPItem(CPPItem.VAR, 'c', ''), definitions) self.assertIn(CPPItem(CPPItem.VAR, 'd', ''), definitions) self.assertIn(CPPItem(CPPItem.VAR, 'e', ''), definitions)
def handle_statement(self, statement, scope, declarations, definitions): tokens = self.tokenize_code(statement[0]) if not tokens: return if '(' in tokens: name, scop = self._extract_scope_and_name(tokens, '(') scope = CPPItem.extend_scope(scope, scop) if statement[1] is None: declarations.add(CPPItem(CPPItem.METHOD, name, scope)) else: definitions.add(CPPItem(CPPItem.METHOD, name, scope)) return if 'namespace' in tokens: if statement[1] is not None: try: name = tokens[tokens.index('namespace') + 1] scope = CPPItem.extend_scope(scope, name) self.recursive_parser(statement[1], scope, declarations, definitions) except: pass # Anonimous namespace return if 'class' in tokens: if statement[1] is not None: class_index = -1 # Inheritance case if ':' in tokens: class_index = tokens.index(':') - 1 name = tokens[ class_index] # If class or struct, the class name is the last one declarations.add(CPPItem(CPPItem.CLASS, name, scope)) return if 'struct' in tokens and statement[ 1] is not None and tokens[-1] != '=': name = tokens[ -1] # If class or struct, the class name is the last one declarations.add(CPPItem(CPPItem.STRUCT, name, scope)) return if 'using' in tokens: return if 'extern' in tokens and statement[ 1] is not None: # for extern "C" { constructs self.recursive_parser(statement[1], scope, declarations, definitions) if '[' in tokens: # declaring array name, scop = self._extract_scope_and_name(tokens, '[') scope = CPPItem.extend_scope(scope, scop) elif '=' in tokens: name, scop = self._extract_scope_and_name(tokens, '=') scope = CPPItem.extend_scope(scope, scop) else: name, scop = self._extract_scope_and_name(tokens) scope = CPPItem.extend_scope(scope, scop) if 'extern' in tokens: declarations.add(CPPItem(CPPItem.VAR, name, scope)) return definitions.add(CPPItem(CPPItem.VAR, name, scope))