コード例 #1
0
def get_all_PyMethodDef_initializers():
    """
    Locate all initializers for PyMethodDef, returning a list
    of StructInitializer instances
    """
    log('get_all_PyMethodDef_initializers')

    result = []
    vars = gcc.get_variables()
    for var in vars:
        if isinstance(var.decl, gcc.VarDecl):
            if isinstance(var.decl.type, gcc.ArrayType):
                if str(var.decl.type.type) == 'struct PyMethodDef':
                    if var.decl.initial:
                        table = []
                        for idx, ctor in var.decl.initial.elements:
                            #print idx, ctor
                            si = PyMethodDefInitializer(ctor)
                            table.append(si)
                        # Warn about missing sentinel entry with
                        #   ml->ml_name == NULL
                        ml_name = table[-1].char_ptr_field('ml_name')
                        if 0:
                            print('final ml_name: %r' % ml_name)
                        if ml_name is not None:
                            gcc.warning(table[-1].get_location(),
                                        'missing NULL sentinel value at end of PyMethodDef table')
                        result += table
    return result
コード例 #2
0
def get_all_PyMethodDef_initializers():
    """
    Locate all initializers for PyMethodDef, returning a list
    of StructInitializer instances
    """
    log('get_all_PyMethodDef_initializers')

    result = []
    vars = gcc.get_variables()
    for var in vars:
        if isinstance(var.decl, gcc.VarDecl):
            if isinstance(var.decl.type, gcc.ArrayType):
                if str(var.decl.type.type) == 'struct PyMethodDef':
                    if var.decl.initial:
                        table = []
                        for idx, ctor in var.decl.initial.elements:
                            #print idx, ctor
                            si = PyMethodDefInitializer(ctor)
                            table.append(si)
                        # Warn about missing sentinel entry with
                        #   ml->ml_name == NULL
                        ml_name = table[-1].char_ptr_field('ml_name')
                        if 0:
                            print('final ml_name: %r' % ml_name)
                        if ml_name is not None:
                            gcc.warning(
                                table[-1].get_location(),
                                'missing NULL sentinel value at end of PyMethodDef table'
                            )
                        result += table
    return result
コード例 #3
0
def verify_any_PyMethodDef_flags():
    """
    Check all initializers for PyMethodDef arrays.
    Verify that the flags used match the real signature of the callback
    function (albeit usually cast to a PyCFunction):
      http://docs.python.org/c-api/structures.html#PyMethodDef
    """
    methods = get_all_PyMethodDef_initializers()
    #from pprint import pprint
    #pprint(methods)

    for si in methods:
        if 0:
            print(si)
        ml_meth = si.function_ptr_field('ml_meth')
        ml_flags = si.int_field('ml_flags')
        if 0:
            print('  ml_meth: %r' % ml_meth)
            print('  ml_flags: %r' % ml_flags)
        check_isinstance(ml_flags, int)

        if ml_meth is not None:
            check_isinstance(ml_meth, gcc.FunctionDecl)
            if ml_flags & METH_KEYWORDS:
                expargs = 3
                exptypemsg = 'expected ml_meth callback of type "PyObject (fn)(someobject *, PyObject *args, PyObject *kwargs)" due to METH_KEYWORDS flag'
            else:
                expargs = 2
                exptypemsg = 'expected ml_meth callback of type "PyObject (fn)(someobject *, PyObject *)"'
            actualargs = len(ml_meth.type.argument_types)
            if expargs != actualargs:
                gcc.warning(
                    si.get_location(),
                    'flags do not match callback signature for %r'
                    ' within PyMethodDef table' % ml_meth.name)
                gcc.inform(si.get_location(),
                           exptypemsg + ' (%s arguments)' % expargs)
                gcc.inform(
                    si.get_location(),
                    'actual type of underlying callback: %s' % ml_meth.type +
                    ' (%s arguments)' % actualargs)
                gcc.inform(
                    si.get_location(),
                    'see http://docs.python.org/c-api/structures.html#PyMethodDef'
                )
コード例 #4
0
def verify_any_PyMethodDef_flags():
    """
    Check all initializers for PyMethodDef arrays.
    Verify that the flags used match the real signature of the callback
    function (albeit usually cast to a PyCFunction):
      http://docs.python.org/c-api/structures.html#PyMethodDef
    """
    methods = get_all_PyMethodDef_initializers()
    #from pprint import pprint
    #pprint(methods)

    for si in methods:
        if 0:
            print(si)
        ml_meth = si.function_ptr_field('ml_meth')
        ml_flags = si.int_field('ml_flags')
        if 0:
            print('  ml_meth: %r' % ml_meth)
            print('  ml_flags: %r' % ml_flags)
        check_isinstance(ml_flags, int)

        if ml_meth is not None:
            check_isinstance(ml_meth, gcc.FunctionDecl)
            if ml_flags & METH_KEYWORDS:
                expargs = 3
                exptypemsg = 'expected ml_meth callback of type "PyObject (fn)(someobject *, PyObject *args, PyObject *kwargs)" due to METH_KEYWORDS flag'
            else:
                expargs = 2
                exptypemsg = 'expected ml_meth callback of type "PyObject (fn)(someobject *, PyObject *)"'
            actualargs = len(ml_meth.type.argument_types)
            if expargs != actualargs:
                gcc.warning(si.get_location(),
                            'flags do not match callback signature for %r'
                            ' within PyMethodDef table'
                            % ml_meth.name)
                gcc.inform(si.get_location(),
                           exptypemsg + ' (%s arguments)' % expargs)
                gcc.inform(si.get_location(),
                           'actual type of underlying callback: %s' % ml_meth.type
                            + ' (%s arguments)' % actualargs)
                gcc.inform(si.get_location(),
                           'see http://docs.python.org/c-api/structures.html#PyMethodDef')
コード例 #5
0
 def spellcheck_node(self, node, loc):
     # Spellcheck any textual constants found within the node:
     if isinstance(node, gcc.StringCst):
         words = node.constant.split()
         for word in words:
             if not spellingdict.check(word):
                 # Warn about the spelling error (controlling the warning
                 # with the -Wall command-line option):
                 if gcc.warning(loc,
                                'Possibly misspelt word in string constant: %r' % word,
                                gcc.Option('-Wall')):
                     # and, if the warning was not suppressed at the command line, emit
                     # suggested respellings:
                     suggestions = spellingdict.suggest(word)
                     if suggestions:
                         gcc.inform(loc, 'Suggested respellings: %r' % ', '.join(suggestions))
コード例 #6
0
def on_pass_execution(p, fn):
    if p.name == '*warn_function_return':
        gcc.error(fn.start, 'this is an error (with positional args)')
        gcc.error(location=fn.start,
                  message='this is an error (with keyword args)')
        gcc.warning(fn.end, 'this is a warning (with positional args)',
                    gcc.Option('-Wdiv-by-zero'))
        gcc.warning(location=fn.end,
                    message='this is a warning (with keyword args)',
                    option=gcc.Option('-Wdiv-by-zero'))
        gcc.error(
            fn.start,
            # These should be passed through, without triggering errors:
            'a warning with some embedded format strings %s and %i')

        # Verify that -Wno-format was honored
        # The behavior of these flags changed in 4.8, so skip this part
        # on gcc 4.8 onwards:
        if gcc.GCCPLUGINS_API_VERSION <= 4007:
            gcc.warning(fn.end, 'this warning ought not to appear',
                        gcc.Option('-Wformat'))

        # Verify that we can issue an unconditional warning, with no option
        # (as per https://fedorahosted.org/gcc-python-plugin/ticket/8 ):
        gcc.warning(fn.end, 'this is an unconditional warning')
        gcc.warning(fn.end, 'this is another unconditional warning', None)

        # Verify that gcc.warning handles an object of the wrong type by
        # raising a TypeError
        try:
            gcc.warning(
                fn.end, 'this is another unconditional warning',
                'this should have been a gcc.Option instance, or None')
        except TypeError:
            err = sys.exc_info()[1]
            sys.stderr.write('expected error was found: %s\n' % err)
        else:
            raise RuntimeError('expected exception was not raised')

        # Exercise gcc.inform:
        gcc.inform(fn.start, 'This is the start of the function')
        gcc.inform(fn.end, 'This is the end of the function')
コード例 #7
0
 def flush(self):
     gcc.warning(self.loc, self.msg)
コード例 #8
0
 def flush(self):
     gcc.warning(self.loc, self.msg)
コード例 #9
0
ファイル: script.py プロジェクト: bganne/gcc-python-plugin
def on_pass_execution(p, fn):
    if p.name == '*warn_function_return':
        gcc.error(fn.start, 'this is an error (with positional args)')
        gcc.error(location=fn.start,
                  message='this is an error (with keyword args)')
        gcc.warning(fn.end, 'this is a warning (with positional args)',
                    gcc.Option('-Wdiv-by-zero'))
        gcc.warning(location=fn.end,
                    message='this is a warning (with keyword args)',
                    option=gcc.Option('-Wdiv-by-zero'))
        gcc.error(fn.start,
                  # These should be passed through, without triggering errors:
                  'a warning with some embedded format strings %s and %i')

        # Verify that -Wno-format was honored
        # The behavior of these flags changed in 4.8, so skip this part
        # on gcc 4.8 onwards:
        if gcc.GCCPLUGINS_API_VERSION <= 4007:
            gcc.warning(fn.end,
                        'this warning ought not to appear',
                        gcc.Option('-Wformat'))

        # Verify that we can issue an unconditional warning, with no option
        # (as per https://fedorahosted.org/gcc-python-plugin/ticket/8 ):
        gcc.warning(fn.end, 'this is an unconditional warning')
        gcc.warning(fn.end, 'this is another unconditional warning', None)

        # Verify that gcc.warning handles an object of the wrong type by
        # raising a TypeError
        try:
            gcc.warning(fn.end, 'this is another unconditional warning',
                        'this should have been a gcc.Option instance, or None')
        except TypeError:
            err = sys.exc_info()[1]
            sys.stderr.write('expected error was found: %s\n' % err)
        else:
            raise RuntimeError('expected exception was not raised')

        # Exercise gcc.inform:
        gcc.inform(fn.start, 'This is the start of the function')
        gcc.inform(fn.end, 'This is the end of the function')