#!/usr/bin/env python3
#
# Copyright (c) 2017 Intel Corporation
#
# SPDX-License-Identifier: Apache-2.0

"""
gperf C file post-processor

We use gperf to build up a perfect hashtable of pointer values. The way gperf
does this is to create a table 'wordlist' indexed by a string representation
of a pointer address, and then doing memcmp() on a string passed in for
comparison

We are exclusively working with 4-byte pointer values. This script adjusts
the generated code so that we work with pointers directly and not strings.
This saves a considerable amount of space.
"""

import argparse
import os
import re
import sys

from packaging import version

# --- debug stuff ---


def debug(text):
    if not args.verbose:
        return
    sys.stdout.write(os.path.basename(sys.argv[0]) + ": " + text + "\n")


def error(text):
    sys.exit(os.path.basename(sys.argv[0]) + " ERROR: " + text)


def warn(text):
    sys.stdout.write(os.path.basename(sys.argv[0]) + " WARNING: " + text + "\n")


def reformat_str(match_obj):
    addr_str = match_obj.group(0)

    # Nip quotes
    addr_str = addr_str[1:-1]
    addr_vals = [0, 0, 0, 0, 0, 0, 0, 0]
    ctr = 7
    i = 0

    while True:
        if i >= len(addr_str):
            break

        if addr_str[i] == "\\":
            if addr_str[i + 1].isdigit():
                # Octal escape sequence
                val_str = addr_str[i + 1 : i + 4]
                addr_vals[ctr] = int(val_str, 8)
                i += 4
            else:
                # Char value that had to be escaped by C string rules
                addr_vals[ctr] = ord(addr_str[i + 1])
                i += 2

        else:
            addr_vals[ctr] = ord(addr_str[i])
            i += 1

        ctr -= 1

    return f"(char *)0x{bytes(addr_vals).hex()}"


def process_line(line, fp):
    if line.startswith("#"):
        fp.write(line)
        return

    # Set the lookup function to static inline so it gets rolled into
    # k_object_find(), nothing else will use it
    if re.search(args.pattern + " [*]$", line):
        fp.write("static inline " + line)
        return

    m = re.search("gperf version (.*) [*][/]$", line)
    if m:
        v = version.parse(m.groups()[0])
        v_lo = version.parse("3.0")
        v_hi = version.parse("3.1")
        if v < v_lo or v > v_hi:
            warn(f"gperf {v} is not tested, versions {v_lo} through {v_hi} supported")

    # Replace length lookups with constant len since we're always
    # looking at pointers
    line = re.sub(r'lengthtable\[key\]', r'sizeof(void *)', line)

    # Empty wordlist entries to have NULLs instead of ""
    line = re.sub(r'[{]["]["][}]', r'{}', line)

    # Suppress a compiler warning since this table is no longer necessary
    line = re.sub(
        r'static unsigned char lengthtable', r'static unsigned char __unused lengthtable', line
    )

    # drop all use of register keyword, let compiler figure that out,
    # we have to do this since we change stuff to take the address of some
    # parameters
    line = re.sub(r'register', r'', line)

    # Hashing the address of the string
    line = re.sub(r"hash [(]str, len[)]", r"hash((const char *)&str, len)", line)

    # Just compare pointers directly instead of using memcmp
    if re.search("if [(][*]str", line):
        fp.write("            if (str == s)\n")
        return

    # Take the strings with the binary information for the pointer values,
    # and just turn them into pointers
    line = re.sub(r'["].*["]', reformat_str, line)

    # Use a bigger data type for the asso_values table to provide some margin
    line = re.sub(r'char asso_values', r'short asso_values', line)

    fp.write(line)


def parse_args():
    global args

    parser = argparse.ArgumentParser(
        description=__doc__,
        formatter_class=argparse.RawDescriptionHelpFormatter,
        allow_abbrev=False,
    )

    parser.add_argument("-i", "--input", required=True, help="Input C file from gperf")
    parser.add_argument("-o", "--output", required=True, help="Output C file with processing done")
    parser.add_argument("-p", "--pattern", required=True, help="Search pattern for objects")
    parser.add_argument(
        "-v", "--verbose", action="store_true", help="Print extra debugging information"
    )
    args = parser.parse_args()
    if "VERBOSE" in os.environ:
        args.verbose = 1


def main():
    parse_args()

    with open(args.input) as in_fp, open(args.output, "w") as out_fp:
        for line in in_fp.readlines():
            process_line(line, out_fp)


if __name__ == "__main__":
    main()
