This file is indexed.

/usr/share/pyshared/pygccxml/parser/patcher.py is in python-pygccxml 1.0.0-4.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
# Copyright 2004-2008 Roman Yakovenko.
# Distributed under the Boost Software License, Version 1.0. (See
# accompanying file LICENSE_1_0.txt or copy at
# http://www.boost.org/LICENSE_1_0.txt)

from pygccxml import utils
from pygccxml import declarations


class default_argument_patcher_t( object ):
    def __init__( self, enums ):
        object.__init__( self )
        self.__enums = enums
        
    def __call__(self, decl):
        for arg in decl.arguments:
            if not arg.default_value:
                continue
            fixer = self.__find_fixer( decl, arg )
            if fixer:
                arg.default_value = fixer( decl, arg )

    def __find_fixer(self, func, arg):
        if not arg.default_value:
            return False
        elif self.__is_unqualified_enum( func, arg ):
            return self.__fix_unqualified_enum
        elif self.__is_double_call( func, arg ):
            return self.__fix_double_call       
        elif self.__is_invalid_integral( func, arg ):
            return self.__fix_invalid_integral
        elif self.__is_constructor_call( func, arg ):
            return self.__fix_constructor_call
        else:
            return None

    def __join_names( self, prefix, suffix ):
        if prefix == '::':
            return '::' + suffix
        else:
            return prefix + '::' + suffix
  
    def __is_unqualified_enum(self, func, arg):
        type_ = declarations.remove_reference( declarations.remove_cv( arg.type ) )        
        if not declarations.is_enum( type_ ):
            return False
        enum_type = declarations.enum_declaration( type_ )
        return enum_type.has_value_name( arg.default_value )

    def __fix_unqualified_enum( self, func, arg):
        type_ = declarations.remove_reference( declarations.remove_cv( arg.type ) )
        enum_type = declarations.enum_declaration( type_ )
        return self.__join_names( enum_type.parent.decl_string, arg.default_value )

    def __is_invalid_integral(self, func, arg):
        type_ = declarations.remove_reference( declarations.remove_cv( arg.type ) )        
        if not declarations.is_integral( type_ ):
            return False
        try:
            int( arg.default_value )
            return False
        except:
            return True

    def __fix_invalid_integral(self, func, arg):
        try:
            int( arg.default_value )
            return arg.default_value
        except:
            pass
                
        try:
            int( arg.default_value, 16 )
            if 64 == utils.get_architecture():
                #on 64 bit architecture, gccxml reports 0fffff, which is valid number
                #the problem is that in this case it is so buggy so pygccxml can not fix it
                #users will have to fix the default value manually
                return arg.default_value
            default_value = arg.default_value.lower()
            found_hex = filter( lambda ch: ch in 'abcdef', default_value )
            if found_hex and not default_value.startswith( '0x' ):
                int( '0x' + default_value, 16 )
                return '0x' + default_value
        except:
            pass
        
        #may be we deal with enum
        parent = func.parent
        while parent:
            found = self.__find_enum( parent, arg.default_value )
            if found:
                if declarations.is_fundamental( arg.type ) and ' ' in arg.type.decl_string:
                    template = '(%s)(%s)'
                else:
                    template = '%s(%s)'
                return template % ( arg.type.decl_string
                                    , self.__join_names( found.parent.decl_string, arg.default_value ) )
            else:
                parent = parent.parent
        return arg.default_value

    def __find_enum( self, scope, default_value ):
        #this algorithm could be improved: it could take into account
        #1. unnamed namespaced
        #2. location within files
        
        for enum in self.__enums:
            if enum.parent is scope and enum.has_value_name( default_value ):
                return enum
        return None

    def __is_double_call( self, func, arg ):
        call_invocation = declarations.call_invocation
        dv = arg.default_value
        found1 = call_invocation.find_args( dv )
        if found1 == call_invocation.NOT_FOUND:
            return False
        found2 = call_invocation.find_args( dv, found1[1] + 1 )
        if found2 == call_invocation.NOT_FOUND:
            return False
        args1 = call_invocation.args( dv[ found1[0] : found1[1] + 1 ] )
        args2 = call_invocation.args( dv[ found2[0] : found2[1] + 1 ] )
        return len(args1) == len(args2)
    
    def __fix_double_call( self, func, arg ):
        call_invocation = declarations.call_invocation
        dv = arg.default_value
        found1 = call_invocation.find_args( dv )
        found2 = call_invocation.find_args( dv, found1[1] + 1 )
        #args1 = call_invocation.args( dv[ found1[0] : found1[1] + 1 ] )
        args2 = call_invocation.args( dv[ found2[0] : found2[1] + 1 ] )
        return call_invocation.join( dv[:found1[0]], args2 )

    def __is_constructor_call( self, func, arg ):
        #if '0.9' in func.compiler:
        #    return False
        call_invocation = declarations.call_invocation
        dv = arg.default_value
        if not call_invocation.is_call_invocation( dv ):
            return False
        name = call_invocation.name( dv )
        base_type = declarations.base_type( arg.type )
        if not isinstance( base_type, declarations.declarated_t ):
            return False
        decl = base_type.declaration
        return decl.name == name \
               or ( isinstance( decl, declarations.class_t ) \
                    and name in map( lambda typedef: typedef.name, decl.aliases ) )

    def __fix_constructor_call( self, func, arg ):
        call_invocation = declarations.call_invocation
        dv = arg.default_value
        if not call_invocation.is_call_invocation( dv ):
            return False
        base_type = declarations.base_type( arg.type )
        decl = base_type.declaration
        name, args = call_invocation.split( dv )
        if decl.name != name:
            #we have some alias to the class
            relevant_typedefs = filter( lambda typedef: typedef.name == name
                                        , decl.aliases )
            if 1 == len( relevant_typedefs ):
                f_q_name = self.__join_names( declarations.full_name( relevant_typedefs[0].parent )
                                              , name )
            else:#in this case we can not say which typedef user uses:
                f_q_name = self.__join_names( declarations.full_name( decl.parent )
                                              , decl.name )
        else:
            f_q_name = self.__join_names( declarations.full_name( decl.parent ), name )
            
        return call_invocation.join( f_q_name, args )

class casting_operator_patcher_t( object ):
    def __init__( self ):
        object.__init__( self )

    def __call__(self, decl):
        decl.name = 'operator ' + decl.return_type.decl_string

_casting_oper_patcher_ = casting_operator_patcher_t()

def fix_calldef_decls(decls, enums):
    default_arg_patcher = default_argument_patcher_t(enums)
    #decls should be flat list of all declarations, you want to apply patch on
    for decl in decls:
        default_arg_patcher( decl )
        if isinstance( decl, declarations.casting_operator_t):
            _casting_oper_patcher_( decl )