#   Copyright 2013 David Malcolm <dmalcolm@redhat.com>
#   Copyright 2013 Red Hat, Inc.
#
#   This 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/>.

import glob
import sys

from xmltypes import ApiRegistry, Api

COPYRIGHT_HEADER = '''
   Copyright 2013 David Malcolm <dmalcolm@redhat.com>
   Copyright 2013 Red Hat, Inc.

   This 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/>.
'''

def write_header(out):
    out.write('/* This file is autogenerated: do not edit */\n')
    out.write('/*%s*/\n' % COPYRIGHT_HEADER)
    out.write('\n')

def write_footer(out):
    out.write('''
/*
  PEP-7
Local variables:
c-basic-offset: 4
indent-tabs-mode: nil
End:
*/
''')

def main(c_filename, xmldir):
    registry = ApiRegistry()
    for xmlfile in sorted(glob.glob(xmldir + '*.xml')):
        api = Api(registry, xmlfile)

    with open(c_filename, 'w') as c_out:
        write_header(c_out)

        c_out.write('#include "gcc-common.h"\n')
        c_out.write('#include "gcc-tree.h"\n')
        c_out.write('#include "ggc.h"\n')
        c_out.write('#include "gcc-internal.h"\n')
        c_out.write('#include <assert.h>\n')
        c_out.write('#include "tree.h"\n')

        # Ensure that we use the headers, so that the generated
        # casts pick up on the 'extern "C"' and don't get name-mangled:
        for api in registry.apis:
            c_out.write('#include "%s"\n' % api.get_header_filename())

        for type_ in registry.iter_types():
            for subclass in type_.get_subclasses(recursive=True):
                c_out.write('IMPLEMENT_CAST(%s, %s)\n'
                            % (type_.get_c_name(),
                               subclass.get_c_name()))
                c_out.write('IMPLEMENT_CAST(%s, %s)\n'
                            % (subclass.get_c_name(),
                               type_.get_c_name()))

        write_footer(c_out)

main(c_filename=sys.argv[1],
     xmldir=sys.argv[2])
