#!/usr/bin/env python3

#------------------------------------------------------------------------------
# Description of the header clean process
#------------------------------------------------------------------------------
# Here is the list of actions performed by this script to clean the original
# kernel headers.
#
# 1. Optimize well-known macros (e.g. __KERNEL__, __KERNEL_STRICT_NAMES)
#
#     This pass gets rid of everything that is guarded by a well-known macro
#     definition. This means that a block like:
#
#        #ifdef __KERNEL__
#        ....
#        #endif
#
#     Will be totally omitted from the output. The optimizer is smart enough to
#     handle all complex C-preprocessor conditional expression appropriately.
#     This means that, for example:
#
#        #if defined(__KERNEL__) || defined(FOO)
#        ...
#        #endif
#
#     Will be transformed into:
#
#        #ifdef FOO
#        ...
#        #endif
#
#     See tools/defaults.py for the list of well-known macros used in this pass,
#     in case you need to update it in the future.
#
#     Note that this also removes any reference to a kernel-specific
#     configuration macro like CONFIG_FOO from the clean headers.
#
#
# 2. Remove variable and function declarations:
#
#   This pass scans non-directive text and only keeps things that look like a
#   typedef/struct/union/enum declaration. This allows us to get rid of any
#   variables or function declarations that should only be used within the
#   kernel anyway (and which normally *should* be guarded by an #ifdef
#   __KERNEL__ ...  #endif block, if the kernel writers were not so messy).
#
#   There are, however, a few exceptions: it is seldom useful to keep the
#   definition of some static inline functions performing very simple
#   operations. A good example is the optimized 32-bit byte-swap function
#   found in:
#
#     arch-arm/asm/byteorder.h
#
#   The list of exceptions is in tools/defaults.py in case you need to update
#   it in the future.
#
#   Note that we do *not* remove macro definitions, including these macro that
#   perform a call to one of these kernel-header functions, or even define other
#   functions. We consider it safe since userland applications have no business
#   using them anyway.
#
#
# 3. Add a standard disclaimer:
#
#   The message:
#
#   /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
#
#   Is prepended to each generated header.
#------------------------------------------------------------------------------

import sys, cpp, kernel, glob, os, re, getopt
from defaults import *
from utils import *

def print_error(no_update, msg):
    if no_update:
        panic(msg)
    sys.stderr.write("warning: " + msg)


def cleanupFile(dst_file, src_file, rel_path, no_update = True):
    """reads an original header and perform the cleanup operation on it
       this functions returns the destination path and the clean header
       as a single string"""
    # Check the header path
    if not os.path.exists(src_file):
        print_error(no_update, "'%s' does not exist\n" % src_file)
        return None

    if not os.path.isfile(src_file):
        print_error(no_update, "'%s' is not a file\n" % src_file)
        return None

    # Extract the architecture if found.
    arch = None
    m = re.search(r"(^|/)asm-([\w\d_\+\.\-]+)/.*", rel_path)
    if m and m.group(2) != 'generic':
        arch = m.group(2)

    # Now, let's parse the file.
    parser = cpp.BlockParser()
    blocks = parser.parseFile(src_file)
    if not parser.parsed:
        print_error(no_update, "Can't parse '%s'" % src_file)
        return None

    macros = kernel_known_macros.copy()
    if arch and arch in kernel_default_arch_macros:
        macros.update(kernel_default_arch_macros[arch])

    if arch and arch in kernel_arch_token_replacements:
        blocks.replaceTokens(kernel_arch_token_replacements[arch])

    blocks.removeStructs(kernel_structs_to_remove)
    blocks.optimizeMacros(macros)
    blocks.optimizeIf01()
    blocks.removeVarsAndFuncs(kernel_known_generic_statics)
    blocks.replaceTokens(kernel_token_replacements)

    out = StringOutput()
    out.write(kernel_disclaimer)
    blocks.write(out)
    return out.get()


if __name__ == "__main__":

    def usage():
        print """\
    usage:  %s [options] <header_path>

        options:
            -v    enable verbose mode

            -u    enabled update mode
                this will try to update the corresponding 'clean header'
                if the content has changed. with this, you can pass more
                than one file on the command-line

            -k<path>  specify path of original kernel headers
            -d<path>  specify path of cleaned kernel headers

        <header_path> must be in a subdirectory of 'original'
    """ % os.path.basename(sys.argv[0])
        sys.exit(1)

    try:
        optlist, args = getopt.getopt(sys.argv[1:], 'uvk:d:')
    except:
        # unrecognized option
        sys.stderr.write("error: unrecognized option\n")
        usage()

    no_update = True
    dst_dir = None
    src_dir = None
    for opt, arg in optlist:
        if opt == '-u':
            no_update = False
        elif opt == '-v':
            logging.basicConfig(level=logging.DEBUG)
        elif opt == '-k':
            src_dir = arg
        elif opt == '-d':
            dst_dir = arg
    # get_kernel_dir() and get_kernel_headers_original_dir() require the current
    # working directory to be a direct or indirect subdirectory of
    # ANDROID_BUILD_TOP.  Otherwise, these functions print an error message and
    # exit.  Let's allow the user to run this program from an unrelated
    # directory, if they specify src_dir and dst_dir on the command line.
    if dst_dir is None:
      dst_dir = get_kernel_dir()
    if src_dir is None:
      src_dir = get_kernel_headers_original_dir()

    if len(args) == 0:
        usage()

    if no_update:
        for path in args:
            dst_file = os.path.join(dst_dir, path)
            src_file = os.path.join(src_dir, path)
            new_data = cleanupFile(dst_file, src_file, path)
            # Use sys.stdout.write instead of a simple print statement to avoid
            # sending an extra new line character to stdout.  Running this
            # program in non-update mode and redirecting stdout to a file should
            # yield the same result as using update mode, where new_data is
            # written directly to a file.
            sys.stdout.write(new_data)

        sys.exit(0)

    # Now let's update our files.

    b = BatchFileUpdater()

    for path in args:
        dst_file = os.path.join(dst_dir, path)
        src_file = os.path.join(src_dir, path)
        new_data = cleanupFile(dst_file, src_file, path, no_update)
        if not new_data:
            continue

        b.readFile(dst_file)
        r = b.editFile(dst_file, new_data)
        if r == 0:
            r = "unchanged"
        elif r == 1:
            r = "edited"
        else:
            r = "added"

        print "cleaning: %-*s -> %-*s (%s)" % (35, path, 35, path, r)


    b.updateGitFiles()

    sys.exit(0)
