#!/usr/bin/env python3
# Copyright (C) 1996-2024 Free Software Foundation, Inc.
#
# This file is part of the GNU simulators.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

"""Helper to generate target-newlib-* files.

target-newlib-* are files that describe various newlib/libgloss values used
by the host/target interface.  This needs to be rerun whenever the newlib source
changes.  Developers manually run it.

If the path to newlib is not specified, it will be searched for in:
- the root of this source tree
- alongside this source tree
"""

import argparse
from pathlib import Path
import re
import subprocess
import sys
from typing import Iterable, List, TextIO


PROG = Path(__file__).name

# Unfortunately, many newlib/libgloss ports have seen fit to define their own
# syscall.h file.  This means that system call numbers can vary for each port.
# Support for all this crud is kept here, rather than trying to get too fancy.
# If you want to try to improve this, please do, but don't break anything.
#
# If a target isn't listed here, it gets the standard syscall.h file (see
# libgloss/syscall.h) which hopefully new targets will use.
#
# NB: New ports should use libgloss, not newlib.
TARGET_DIRS = {
    'cr16': 'libgloss/cr16/sys',
    'd10v': 'newlib/libc/sys/d10v/sys',
    # Port removed from the tree years ago.
    #'i960': 'libgloss/i960',
    'mcore': 'libgloss/mcore',
    'riscv': 'libgloss/riscv/machine',
    'sh': 'newlib/libc/sys/sh/sys',
    'v850': 'libgloss/v850/sys',
}


# The header for the generated def file.
FILE_HEADER = f"""\
/* Newlib/libgloss macro values needed by remote target support.  */
/* This file is machine generated by {PROG}.  */\
"""

# Used to update sections of files.
START_MARKER = 'gennltvals: START'
END_MARKER = 'gennltvals: END'


def extract_syms(cpp: str, srcdir: Path,
                 headers: Iterable[str],
                 pattern: str,
                 filter: str = r'^$') -> dict:
    """Extract all the symbols from |headers| matching |pattern| using |cpp|."""
    srcfile = ''.join(f'#include <{x}>\n' for x in headers)
    syms = set()
    define_pattern = re.compile(r'^#\s*define\s+(' + pattern + ')')
    filter_pattern = re.compile(filter)
    for header in headers:
        with open(srcdir / header, 'r', encoding='utf-8') as fp:
            data = fp.read()
        for line in data.splitlines():
            m = define_pattern.match(line)
            if m and not filter_pattern.search(line):
                syms.add(m.group(1))
    for sym in syms:
        srcfile += f'#ifdef {sym}\nDEFVAL "{sym}" {sym}\n#endif\n'

    result = subprocess.run(
        f'{cpp} -E -I"{srcdir}" -', shell=True, check=True, encoding='utf-8',
        input=srcfile, capture_output=True)
    ret = {}
    for line in result.stdout.splitlines():
        if line.startswith('DEFVAL '):
            _, sym, val = line.split()
            ret[sym.strip('"')] = val
    return ret


def gentvals(output_dir: Path,
             cpp: str, srctype: str, srcdir: Path,
             headers: Iterable[str],
             pattern: str,
             filter: str = r'^$',
             target: str = None):
    """Extract constants from the specified files using a regular expression.

    We'll run things through the preprocessor.
    """
    headers = tuple(headers)

    # Require all files exist in order to regenerate properly.
    for header in headers:
        fullpath = srcdir / header
        assert fullpath.exists(), f'{fullpath} does not exist'

    syms = extract_syms(cpp, srcdir, headers, pattern, filter)

    target_map = output_dir / f'target-newlib-{srctype}.c'
    assert target_map.exists(), f'{target_map}: Missing skeleton'
    old_lines = target_map.read_text().splitlines()
    start_i = end_i = None
    for i, line in enumerate(old_lines):
        if START_MARKER in line:
            start_i = i
        if END_MARKER in line:
            end_i = i
    assert start_i and end_i
    new_lines = old_lines[0:start_i + 1]
    new_lines.extend(
        f'#ifdef {sym}\n'
        f'  {{ "{sym}", {sym}, {val} }},\n'
        f'#endif' for sym, val in sorted(syms.items()))
    new_lines.extend(old_lines[end_i:])
    target_map.write_text('\n'.join(new_lines) + '\n')


def gen_common(output_dir: Path, newlib: Path, cpp: str):
    """Generate the common C library constants.

    No arch should override these.
    """
    # Enable Linux errno extensions since the newlib values are designed to
    # not conflict with each other.
    gentvals(output_dir,
             cpp + ' -D__LINUX_ERRNO_EXTENSIONS__',
             'errno', newlib / 'newlib/libc/include',
             ('errno.h', 'sys/errno.h'), 'E[A-Z0-9]*')

    gentvals(output_dir, cpp, 'signal', newlib / 'newlib/libc/include',
             ('signal.h', 'sys/signal.h'), r'SIG[A-Z0-9]*', filter=r'SIGSTKSZ')

    gentvals(output_dir, cpp, 'open', newlib / 'newlib/libc/include',
             ('fcntl.h', 'sys/fcntl.h', 'sys/_default_fcntl.h'), r'O_[A-Z0-9]*')


def gen_target_syscall(output_dir: Path, newlib: Path, cpp: str):
    """Generate the target-specific syscall lists."""
    target_map_c = output_dir / 'target-newlib-syscall.c'
    old_lines_c = target_map_c.read_text().splitlines()
    start_i = end_i = None
    for i, line in enumerate(old_lines_c):
        if START_MARKER in line:
            start_i = i
        if END_MARKER in line:
            end_i = i
    assert start_i and end_i, f'{target_map_c}: Unable to find markers'
    new_lines_c = old_lines_c[0:start_i + 1]
    new_lines_c_end = old_lines_c[end_i:]

    target_map_h = output_dir / 'target-newlib-syscall.h'
    old_lines_h = target_map_h.read_text().splitlines()
    start_i = end_i = None
    for i, line in enumerate(old_lines_h):
        if START_MARKER in line:
            start_i = i
        if END_MARKER in line:
            end_i = i
    assert start_i and end_i, f'{target_map_h}: Unable to find markers'
    new_lines_h = old_lines_h[0:start_i + 1]
    new_lines_h_end = old_lines_h[end_i:]

    headers = ('syscall.h',)
    pattern = r'SYS_[_a-zA-Z0-9]*'

    # Output the target-specific syscalls.
    for target, subdir in sorted(TARGET_DIRS.items()):
        syms = extract_syms(cpp, newlib / subdir, headers, pattern)
        new_lines_c.append(f'CB_TARGET_DEFS_MAP cb_{target}_syscall_map[] = {{')
        new_lines_c.extend(
            f'#ifdef CB_{sym}\n'
            '  { '
            f'"{sym[4:]}", CB_{sym}, TARGET_NEWLIB_{target.upper()}_{sym}'
            ' },\n'
            '#endif' for sym in sorted(syms))
        new_lines_c.append('  {NULL, -1, -1},')
        new_lines_c.append('};\n')

        new_lines_h.append(
            f'extern CB_TARGET_DEFS_MAP cb_{target}_syscall_map[];')
        new_lines_h.extend(
            f'#define TARGET_NEWLIB_{target.upper()}_{sym} {val}'
            for sym, val in sorted(syms.items()))
        new_lines_h.append('')

    # Then output the common syscall targets.
    syms = extract_syms(cpp, newlib / 'libgloss', headers, pattern)
    new_lines_c.append(f'CB_TARGET_DEFS_MAP cb_init_syscall_map[] = {{')
    new_lines_c.extend(
        f'#ifdef CB_{sym}\n'
        f'  {{ "{sym[4:]}", CB_{sym}, TARGET_NEWLIB_{sym} }},\n'
        f'#endif' for sym in sorted(syms))
    new_lines_c.append('  {NULL, -1, -1},')
    new_lines_c.append('};')

    new_lines_h.append('extern CB_TARGET_DEFS_MAP cb_init_syscall_map[];')
    new_lines_h.extend(
        f'#define TARGET_NEWLIB_{sym} {val}'
        for sym, val in sorted(syms.items()))

    new_lines_c.extend(new_lines_c_end)
    target_map_c.write_text('\n'.join(new_lines_c) + '\n')

    new_lines_h.extend(new_lines_h_end)
    target_map_h.write_text('\n'.join(new_lines_h) + '\n')


def gen_targets(output_dir: Path, newlib: Path, cpp: str):
    """Generate the target-specific lists."""
    gen_target_syscall(output_dir, newlib, cpp)


def gen(output_dir: Path, newlib: Path, cpp: str):
    """Generate all the things!"""
    gen_common(output_dir, newlib, cpp)
    gen_targets(output_dir, newlib, cpp)


def get_parser() -> argparse.ArgumentParser:
    """Get CLI parser."""
    parser = argparse.ArgumentParser(
        description=__doc__,
        formatter_class=argparse.RawDescriptionHelpFormatter)
    parser.add_argument(
        '-o', '--output', type=Path,
        help='write to the specified directory')
    parser.add_argument(
        '--cpp', type=str, default='cpp',
        help='the preprocessor to use')
    parser.add_argument(
        '--srcroot', type=Path,
        help='the root of this source tree')
    parser.add_argument(
        'newlib', nargs='?', type=Path,
        help='path to the newlib+libgloss source tree')
    return parser


def parse_args(argv: List[str]) -> argparse.Namespace:
    """Process the command line & default options."""
    parser = get_parser()
    opts = parser.parse_args(argv)

    if opts.output is None:
        # Default to where the script lives.
        opts.output = Path(__file__).resolve().parent

    if opts.srcroot is None:
        opts.srcroot = Path(__file__).resolve().parent.parent.parent
    else:
        opts.srcroot = opts.srcroot.resolve()

    if opts.newlib is None:
        # Try to find newlib relative to our source tree.
        if (opts.srcroot / 'newlib').is_dir():
            # If newlib is manually in the same source tree, use it.
            if (opts.srcroot / 'libgloss').is_dir():
                opts.newlib = opts.srcroot
            else:
                opts.newlib = opts.srcroot / 'newlib'
        elif (opts.srcroot.parent / 'newlib').is_dir():
            # Or see if it's alongside the gdb/binutils repo.
            opts.newlib = opts.srcroot.parent / 'newlib'
    if opts.newlib is None or not opts.newlib.is_dir():
        parser.error('unable to find newlib')

    return opts


def main(argv: List[str]) -> int:
    """The main entry point for scripts."""
    opts = parse_args(argv)

    gen(opts.output, opts.newlib, opts.cpp)
    return 0


if __name__ == '__main__':
    sys.exit(main(sys.argv[1:]))
