#===- gen-msvc-exports.py - Generate C API export file -------*- python -*--===#
#
# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
# See https://llvm.org/LICENSE.txt for license information.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
#
#===------------------------------------------------------------------------===#
#
# Generate an export file from a list of given LIB files. This only exports symbols
# that start with LLVM, so it only exports the LLVM C API.
#
# To have CMake run this, set LLVM_BUILD_LLVM_C_DYLIB to on while
# building on Windows.
#
# To run manually, build LLVM with Visual Studio, use a Command prompt
# to navigate to the directory with the .lib files (Debug\lib etc). Then run
#     python C:\Path\To\gen-msvc-exports.py --nm ..\bin\llvm-nm.exe LLVM*.lib
#
# If you're generating a 32 bit DLL, use the `--underscore` flag.
# If you want to use a different `llvm-nm` executable, pass the path
# with the `--nm` flag.
#
# You can use the --output flag to set the name of the export file.
#
#===------------------------------------------------------------------------===#
from tempfile import mkstemp
from contextlib import contextmanager
from subprocess import check_call
import argparse
import os
import re


_UNDERSCORE_REGEX = {
    False: re.compile(r"^\w+\s+T\s+(LLVM.*)$"),
    True:  re.compile(r"^\w+\s+T\s+_(LLVM.*)$")
}


@contextmanager
def removing(path):
    try:
        yield path
    finally:
        os.unlink(path)


def touch_tempfile(*args, **kwargs):
    fd, name = mkstemp(*args, **kwargs)
    os.close(fd)
    return name


def gen_llvm_c_export(output, underscore, libs, nm):
    """Generate the export file for the LLVM-C DLL.

    Run `nm` for each lib in `libs`, and output an export file
    to `output`. If `underscore` is true, symbols will
    be assumed to be prefixed with an underscore.
    """
    with removing(touch_tempfile(prefix='dumpout', suffix='.txt')) as dumpout:

        # Get the right regex.
        p = _UNDERSCORE_REGEX[underscore]

        with open(output, 'w+t') as output_f:

            # For each lib get the LLVM* functions it exports.
            for lib in libs:
                # Call dumpbin.
                with open(dumpout, 'w+t') as dumpout_f:
                    check_call([nm, '-g', lib], stdout=dumpout_f)

                # Get the matching lines.
                with open(dumpout) as dumpbin:
                    for line in dumpbin:
                        m = p.match(line)
                        if m is not None:
                            output_f.write(m.group(1) + '\n')


def main():
    parser = argparse.ArgumentParser('gen-msvc-exports')

    parser.add_argument(
        '-i', '--libsfile', help='file with list of libs, new line separated',
        action='store', default=None
    )
    parser.add_argument(
        '-o', '--output', help='output filename', default='LLVM-C.exports'
    )
    parser.add_argument('-u', '--underscore',
        help='labels are prefixed with an underscore (use for 32 bit DLLs)',
        action='store_true'
    )
    parser.add_argument(
        '--nm', help='path to the llvm-nm executable', default='llvm-nm'
    )
    parser.add_argument(
        'libs', metavar='LIBS', nargs='*', help='list of libraries to generate export from'
    )

    ns = parser.parse_args()

    libs = ns.libs

    # Add if we where given a libsfile add it to the libs.
    if ns.libsfile:
        with open(ns.libsfile) as f:
            libs.extend(f.read().splitlines())

    gen_llvm_c_export(ns.output, ns.underscore, libs, ns.nm)


if __name__ == '__main__':
    main()
