Skip to content

calldef_matcher matches on structure too #62

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
teto opened this issue Jul 26, 2016 · 5 comments
Closed

calldef_matcher matches on structure too #62

teto opened this issue Jul 26, 2016 · 5 comments

Comments

@teto
Copy link

teto commented Jul 26, 2016

I am looking for the declaration of the "sigaction" function defined in <signal.h> with the following code. Problem is pygccxml returns the declaration of the "struct sigaction".

I've reduced my code to an autonomeous example:

#!/usr/bin/env python3
# Example taken out of http://pygccxml.readthedocs.io/en/develop/examples/searching1/example.html
from pygccxml import utils
from pygccxml import declarations
from pygccxml import parser
from pygccxml.declarations import declaration_utils
import os
import argparse
import csv
import subprocess
import logging
import sys


"""
Must be able to generate:
    - 

todo do same for dl/pthread/rt
"""

log = logging.getLogger("dce")
# log.setLevel(logging.DEBUG)
log.addHandler(logging.StreamHandler())

class Generator:
    def __init__(self):
        pass

    def parse(self, filename):
        """
        cache parsing
        """
        utils.loggers.set_level(logging.DEBUG)

        # Find the location of the xml generator (castxml or gccxml)
        generator_path, generator_name = utils.find_xml_generator()

        # Configure the xml generator
        xml_generator_config = parser.xml_generator_configuration_t(
            xml_generator_path=generator_path,
            xml_generator=generator_name,
            cflags=" -nostdinc -I/usr/include",

            # asked on tracker to generate va_list but not ok
            # flags= ["f1"]
            )
        # config.flags = 
        # The c++ file we want to parse
        # printf is declared in stdio.h
        # filename = "/home/teto/glibc/libio/stdio.h"
        filename = "test.h"
        code = """
#include <signal.h>
        """

        self.project_reader = parser.project_reader_t(xml_generator_config)
        self.decls = self.project_reader.read_string(code)


    def generate_wrappers(self, input_filename, out_filename):
        """
        Generate wrappers + headers
        """

        # input_filename = "natives.h.txt"
        # out_filename = 
        global_namespace = declarations.get_global_namespace(self.decls)

        locations = {}

        # look for a match
        criteria = declarations.calldef_matcher(name="sigaction")
        results = declarations.matcher.find(criteria, global_namespace) 

        # print("decl", results)
        decl = results[0]
        # print( "islist ? len",len(func1))
        name = declaration_utils.full_name(decl)
        if name[:2] == "::":
            name = name[2:]
        log.info("Parsing function %s" % name)
        extern="extern" if decl.has_extern else ""
        rtype = "%s" % (decl.return_type if decl.return_type is not None else "void")

        temp = []
        for arg in decl.arguments:
            s = str(arg.decl_type)
            if s.startswith("?unknown?"):
                print("UNKNOWN")
                s = "va_list"
            elif "(" in s:
                print ("TOTO")
                s= s.rstrip("*")
            temp.append(s)

        for arg in temp:
            print("arg=%s"% arg)

        # temp = ["va_list" else str(a.decl_type) for a in decl.arguments]
        fullargs = ",".join(temp)
        res = """
            {extern} {ret} {name} ({fullargs});

        """.format(
                extern=extern,
                ret=rtype,
                fullargs=fullargs,
                name=name,
                retstmt="return" if rtype is not "void" else "",
                arg_names=",".join([arg.name for arg in decl.arguments]),
        )
        print(res)



def main():
    parser  = argparse.ArgumentParser()
    g = Generator()
    g.parse("toto")
    g.generate_wrappers("temp", "model/libc.generated.cc")

if __name__ == "__main__":
    main()

@iMichka iMichka added the bug label Jul 26, 2016
@iMichka iMichka added this to the 1.8.0 milestone Jul 26, 2016
@teto
Copy link
Author

teto commented Jul 27, 2016

some more intel

castxml --version                                                                     
castxml version 0.1-g1489405

CastXML project maintained and supported by Kitware (kitware.com).

Ubuntu clang version 3.7.1-1ubuntu4 (tags/RELEASE_371/final) (based on LLVM 3.7.1)

with pygccxml "develop" commit f9f0deb

@iMichka
Copy link
Collaborator

iMichka commented Aug 31, 2016

Hi

coming back to your problem. I still have trouble to understand what you are trying to do.

  1. The results variable contains 3 elements. 2 constructors and 1 function. You should not take element 0 without checking it's type. For me the free_function_t object is the third element in the list. Using it, it will print the following arguments:

Parsing function sigaction
arg=int
arg=sigaction const *
arg=sigaction *

This does correspond to the definition of this function in signal.h.

I do not know why you are talking about structs. If you are confused by the fact that the calldef_matcher returns 2 constructors, remember that in c++ these are juste methods of the class. You need to filter your result list with an isinstance check.

  1. If the above does not help, on which Ubuntu are you ? From which PPA did your get your clang compiler. It seems to me that it is not a common version on Ubuntu (and least not a standard one). I'll need to test with the same setup (I'm on OS X with llvm 3.8.1 here).

@teto
Copy link
Author

teto commented Aug 31, 2016

Your remarks for both of my issues look spot on, let me go back to you later though as it's my turn to go on holyday. I should be able to give you a definite answer around mid september.

@iMichka
Copy link
Collaborator

iMichka commented Sep 1, 2016

Ok. I will move your two bugs off the 1.8.0 milestone, I do not want to delay the release too much. If there are still fixes to be applied, this can get in the next minor release. Have a nice holiday.

@iMichka iMichka removed this from the 1.8.0 milestone Sep 1, 2016
@iMichka iMichka removed the bug label Sep 1, 2016
@teto
Copy link
Author

teto commented Sep 10, 2016

I've added an additionnal criteria decl_type=declarations.free_function_t) to only match free functions so it solves my problem .

@teto teto closed this as completed Sep 10, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants