#!/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])

    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.updateFiles()

    sys.exit(0)
