#!/usr/bin/python
#
# C++ header to SIP file converter.
#
import sys
import re

curclass = None

fixclasses = ["ref_counted", "ref_counted", "association_kind", "Package", "Language", "ElementDefinition", "Property", "Slot", "Element", "AbstractElementDefinition", "EnumerationDefinition", "DatatypeDefinition", "Atom"]

def wr_line(l):
    global curclass
    global fixclasses
    for i in fixclasses:
        if re.search("class\s+" + i + "\W", l):
            continue
        if re.search("enum " + i, l):
            continue
        s = "([^~a-zA-Z\s])" + i + "([\s&\*])"
        l = re.sub(s, "\\1coral::" + i + "\\2", l)
        s = "(\S+)\s+" + i + "\s"
        l = re.sub(s, "\\1 coral::" + i + " ", l)
        s = "^(\s*) " + i + "([^\(])"
        l = re.sub(s, "\\1coral::" + i + "\\2", l)
        s = "const " + i
        l = re.sub(s, "const coral::" + i, l)
        s = ",\s+" + i
        l = re.sub(s, ", coral::" + i, l)
    l = re.sub("std::size_t", "int", l)
    l = re.sub("size_t", "int", l)
    sys.stdout.write(l)

def find_includes(filename):
    includes = []
    f = file(filename, "rt")
    while 1:
        l = f.readline()
        if not l: break
        if re.search("#\s*include", l):
            includes.append(l)
    f.close()
    return includes

def gensip(filename):
    global curclass
    global fixclasses
    includes = find_includes(filename)
    f = file(filename, "rt")
    #print "%Module smw"
    print
    print "%HeaderCode"
    for i in includes:
        sys.stdout.write(i)
    print "#include <" + filename + ">"
    print "%End"

    print
    print "%Import stdstring.sip"

    while 1:
        l = f.readline()
        if not l: break
        find_var_names = "\((.+)\s+[^()\s&*]+\)" 
        # Finds variables in functions, and removes them...
        l = re.sub(find_var_names, "(\\1)", l)
        if re.search("^\s+enum\s+", l):
            wr_line(l)
            continue
        l = re.sub("/\*.*?\*/", "", l)
        l = re.sub("throw \(\);\s*$", ";\n", l)
        l = re.sub("public\s+", "", l)
        l = re.sub("const enum", "const", l) # weird...
        l = re.sub("^(\s+)static", "\\1", l)
        l = re.sub("^\s*private:\s*$", "", l)
        l = re.sub("coral_uuid_t", "std::string", l)
        l = re.sub("EXPORT_coral\s+", "", l)
        l = re.sub("EXPORT_MM\s+", "", l)
        l = re.sub(".*CTOR_ASSIGNMENT.*", "", l)
        l = re.sub(".*CTOR_INITIALIZATION.*", "", l)
        l = re.sub(".*EXTERN_MUTEX.*", "", l)
        l = re.sub(".*extern.*", "", l)
        l = re.sub("^\s*mutable\s+.*", "", l) # No variables
        l = re.sub("^\s*int\s+\S+\s*;\s*$", "", l)
        l = re.sub("inline\s+", "", l)
        l = re.sub("\(void\)", "()", l)
        l = re.sub("#\s*ifndef\s+.*", "", l)
        l = re.sub("#\s*ifdef\s+.*", "", l)
        l = re.sub("#\s*undef\s+.*", "", l)
        l = re.sub("#\s*define\s+.*", "", l)
        l = re.sub("#\s*include\s+.*", "", l)
        l = re.sub("#\s*endif\s+.*", "", l)
        if re.search("namespace", l):
            pass
        elif re.search("class\s+(\S+)", l):
            matcher = re.search("class\s+([a-zA-Z0-9_]+)", l)
            curclass = matcher.group(1)
            pass
        elif re.search("{.*}", l):
            l = re.sub("{.*}", ";", l)
        elif re.search("{", l):
            l = re.sub("{.*", ";", l)
            wr_line(l)
            while 1:
                l = f.readline()
                if not l: break
                if re.search("}", l): break
            continue
        # Skip variables in function defs...
        l = re.sub("\S+\s*=.*?([,\)])" , "\\1", l)
        l = re.sub("([,\(])\s*([^,\(\)]+)\s+(\*?&?)[a-zA-Z0-9]+\s*([,\)])" , "\\1\\2\\3\\4", l)
        #l = re.sub(".*~.*", "", l)
        l = re.sub("^\s*\S[^(){}]+\s+[^()\s]+\s*;\s*$", "", l) # Forget variables...
        l = re.sub("^}\s*$", "};", l) # For namespace end
        # AAAAAARGH sip doesn't seem to obey namespaces
        wr_line(l)
    f.close()

gensip(sys.argv[1])


