# this file contains definitions related to the Linux kernel itself
#

# list here the macros that you know are always defined/undefined when including
# the kernel headers
#
import sys, cpp, re, os.path, string, time
from defaults import *

verboseSearch = 0
verboseFind   = 0

########################################################################
########################################################################
#####                                                              #####
#####           H E A D E R   S C A N N E R                        #####
#####                                                              #####
########################################################################
########################################################################


class HeaderScanner:
    """a class used to non-recursively detect which Linux kernel headers are
       used by a given set of input source files"""

    # to use the HeaderScanner, do the following:
    #
    #    scanner = HeaderScanner()
    #    for path in <your list of files>:
    #        scanner.parseFile(path)
    #
    #    # get the set of Linux headers included by your files
    #    headers = scanner.getHeaders()
    #
    #    # get the set of of input files that do include Linux headers
    #    files   = scanner.getFiles()
    #
    #    note that the result of getHeaders() is a set of strings, each one
    #    corresponding to a non-bracketed path name, e.g.:
    #
    #        set("linux/types","asm/types.h")
    #

    # the default algorithm is pretty smart and will analyze the input
    # files with a custom C pre-processor in order to optimize out macros,
    # get rid of comments, empty lines, etc..
    #
    # this avoids many annoying false positives... !!
    #

    # this regular expression is used to detect include paths that relate to
    # the kernel, by default, it selects one of:
    #    <linux/*>
    #    <asm/*>
    #    <asm-generic/*>
    #    <mtd/*>
    #
    re_combined_str=\
       r"^.*<((%s)/[\d\w_\+\.\-/]*)>.*$" % string.join(kernel_dirs,"|")

    re_combined = re.compile(re_combined_str)

    # some kernel files choose to include files with relative paths (x86 32/64
    # dispatch for instance)
    re_rel_dir = re.compile(r'^.*"([\d\w_\+\.\-/]+)".*$')

    def __init__(self,config={}):
        """initialize a HeaderScanner"""
        self.reset()
        self.config = config

    def reset(self,config={}):
        self.files    = set()  # set of files being parsed for headers
        self.headers  = {}     # maps headers to set of users
        self.config   = config

    def checkInclude(self, line, from_file, kernel_root=None):
        relative = False
        m = HeaderScanner.re_combined.match(line)
        if kernel_root and not m:
            m = HeaderScanner.re_rel_dir.match(line)
            relative = True
        if not m: return

        header = m.group(1)
        if from_file:
            self.files.add(from_file)
            if kernel_root and relative:
                hdr_dir = os.path.realpath(os.path.dirname(from_file))
                hdr_dir = hdr_dir.replace("%s/" % os.path.realpath(kernel_root),
                                          "")
                if hdr_dir:
                    _prefix = "%s/" % hdr_dir
                else:
                    _prefix = ""
                header = "%s%s" % (_prefix, header)

        if not header in self.headers:
            self.headers[header] = set()

        if from_file:
            if verboseFind:
                print "=== %s uses %s" % (from_file, header)
            self.headers[header].add(from_file)

    def parseFile(self, path, arch=None, kernel_root=None):
        """parse a given file for Linux headers"""
        if not os.path.exists(path):
            return

        # since tokenizing the file is very slow, we first try a quick grep
        # to see if this returns any meaningful results. only if this is true
        # do we do the tokenization"""
        try:
            f = open(path, "rt")
        except:
            print "!!! can't read '%s'" % path
            return

        hasIncludes = False
        for line in f:
            if (HeaderScanner.re_combined.match(line) or
                (kernel_root and HeaderScanner.re_rel_dir.match(line))):
                hasIncludes = True
                break

        if not hasIncludes:
            if verboseSearch: print "::: " + path
            return

        if verboseSearch: print "*** " + path

        list = cpp.BlockParser().parseFile(path)
        if list:
            #list.removePrefixed("CONFIG_",self.config)
            macros = kernel_known_macros.copy()
            if kernel_root:
                macros.update(self.config)
                if arch and arch in kernel_default_arch_macros:
                    macros.update(kernel_default_arch_macros[arch])
            list.optimizeMacros(macros)
            list.optimizeIf01()
            includes = list.findIncludes()
            for inc in includes:
                self.checkInclude(inc, path, kernel_root)

    def getHeaders(self):
        """return the set of all needed kernel headers"""
        return set(self.headers.keys())

    def getHeaderUsers(self,header):
        """return the set of all users for a given header"""
        return set(self.headers.get(header))

    def getAllUsers(self):
        """return a dictionary mapping heaaders to their user set"""
        return self.headers.copy()

    def getFiles(self):
        """returns the set of files that do include kernel headers"""
        return self.files.copy()


##########################################################################
##########################################################################
#####                                                                #####
#####           H E A D E R   F I N D E R                            #####
#####                                                                #####
##########################################################################
##########################################################################


class KernelHeaderFinder:
    """a class used to scan the kernel headers themselves."""

    # this is different
    #  from a HeaderScanner because we need to translate the path returned by
    #  HeaderScanner.getHeaders() into possibly architecture-specific ones.
    #
    # for example, <asm/XXXX.h> needs to be translated in <asm-ARCH/XXXX.h>
    # where ARCH is appropriately chosen

    # here's how to use this:
    #
    #    scanner = HeaderScanner()
    #    for path in <your list of user sources>:
    #        scanner.parseFile(path)
    #
    #    used_headers = scanner.getHeaders()
    #    finder       = KernelHeaderFinder(used_headers, [ "arm", "x86" ],
    #                                      "<kernel_include_path>")
    #    all_headers  = finder.scanForAllArchs()
    #
    #   not that the result of scanForAllArchs() is a list of relative
    #   header paths that are not bracketed
    #

    def __init__(self,headers,archs,kernel_root,kernel_config):
        """init a KernelHeaderScanner,

            'headers' is a list or set of headers,
            'archs' is a list of architectures
            'kernel_root' is the path to the 'include' directory
             of your original kernel sources
        """

        if len(kernel_root) > 0 and kernel_root[-1] != "/":
            kernel_root += "/"
        #print "using kernel_root %s" % kernel_root
        self.archs         = archs
        self.searched      = set(headers)
        self.kernel_root   = kernel_root
        self.kernel_config = kernel_config
        self.needed        = {}
        self.setArch(arch=None)

    def setArch(self,arch=None):
        self.curr_arch = arch
        self.arch_headers = set()
        if arch:
            self.prefix = "asm-%s/" % arch
        else:
            self.prefix = None

    def pathFromHeader(self,header):
        path = header
        if self.prefix and path.startswith("asm/"):
            path = "%s%s" % (self.prefix, path[4:])
        return path

    def pathToHeader(self,path):
        if self.prefix and path.startswith(self.prefix):
            path = "asm/%s" % path[len(self.prefix):]
        return "%s" % path

    def setSearchedHeaders(self,headers):
        self.searched = set(headers)

    def scanForArch(self):
        fparser   = HeaderScanner(config=self.kernel_config)
        workqueue = []
        needed    = {}
        for h in self.searched:
            path = self.pathFromHeader(h)
            if not path in needed:
                needed[path] = set()
            workqueue.append(path)

        i = 0
        while i < len(workqueue):
            path = workqueue[i]
            i   += 1
            fparser.parseFile(self.kernel_root + path,
                              arch=self.curr_arch, kernel_root=self.kernel_root)
            for used in fparser.getHeaders():
                path  = self.pathFromHeader(used)
                if not path in needed:
                    needed[path] = set()
                    workqueue.append(path)
                for user in fparser.getHeaderUsers(used):
                    needed[path].add(user)

        # now copy the arch-specific headers into the global list
        for header in needed.keys():
            users = needed[header]
            if not header in self.needed:
                self.needed[header] = set()

            for user in users:
                self.needed[header].add(user)

    def scanForAllArchs(self):
        """scan for all architectures and return the set of all needed kernel headers"""
        for arch in self.archs:
            self.setArch(arch)
            self.scanForArch()

        return set(self.needed.keys())

    def getHeaderUsers(self,header):
        """return the set of all users for a given header"""
        return set(self.needed[header])

    def getArchHeaders(self,arch):
        """return the set of all <asm/...> headers required by a given architecture"""
        return set()  # XXX: TODO

#####################################################################################
#####################################################################################
#####                                                                           #####
#####           C O N F I G   P A R S E R                                       #####
#####                                                                           #####
#####################################################################################
#####################################################################################

class ConfigParser:
    """a class used to parse the Linux kernel .config file"""
    re_CONFIG_ = re.compile(r"^(CONFIG_\w+)=(.*)$")

    def __init__(self):
        self.items = {}
        self.duplicates = False

    def parseLine(self,line):
        line = string.strip(line)

        # skip empty and comment lines
        if len(line) == 0 or line[0] == "#":
            return

        m = ConfigParser.re_CONFIG_.match(line)
        if not m: return

        name  = m.group(1)
        value = m.group(2)

        if name in self.items:  # aarg, duplicate value
            self.duplicates = True

        self.items[name] = value

    def parseFile(self,path):
        f = file(path, "r")
        for line in f:
            if len(line) > 0:
                if line[-1] == "\n":
                    line = line[:-1]
                    if len(line) > 0 and line[-1] == "\r":
                        line = line[:-1]
                self.parseLine(line)
        f.close()

    def getDefinitions(self):
        """retrieve a dictionary containing definitions for CONFIG_XXX"""
        return self.items.copy()

    def __repr__(self):
        return repr(self.items)

    def __str__(self):
        return str(self.items)
