#===========================================================================nix
# @file   ClassExtract.py
# @author <NAME>
# @brief  This program takes two parameters. The first is the path to the
#         directory which contains all the XML files used by paraview. Second
#         is the *Init.cxx initilization files which will be produced. This
#         initilization file will be used to initialize only the components
#         that are used by paraview. This may help in reducing the entire
#         footprint of a statically linked paraview.
#===========================================================================nix

import os
import os.path
import sys
import xml.sax.handler
import xml.sax
import pprint

#---------------------------------------------------------------------------nix
# This class is essentially a callback. It is used to parse the xml files.
# It searches for "class" attribute and collects it in a 'classes' array
class ClassExtractor(xml.sax.handler.ContentHandler):
    # Constructor
    def __init__(self):
        self.classes = []

    # Callback each time a new element is parsed
    def startElement(self, name, attributes):
        if attributes.has_key("class"):
            self.classes.append(attributes["class"])

#---------------------------------------------------------------------------nix
# Simply outputs the extern declarations that will be used by the function.
#
# @param f The file to write into.
# @param initObjs The list of the classes collected.
def outputExternDefinitions(f, initObjs):
    for obj in initObjs:
        f.write(
            "extern void "+obj+"_Init(vtkClientServerInterpreter* csi);\n"
            );
    f.write("\n")

#---------------------------------------------------------------------------nix
# outputs the initialization function into the provided file. The initi
# funtion  calls all the other *_Init routines.
#
# @param f The file to write into.
# @param initObjs The list of the classes collected.
# @param outputFile The cxx file that will be genrated.
def outputInitializeFunction(f, initObjs, outputFile):
    # Split all the /in/path/ and extract only source file
    temp = outputFile.split("/")
    # Extract only the classname
    funName = temp[len(temp)-1].split(".")[0].split("Init")[0]+"_Initialize"
    f.write(
        "//-------------------------------------------------------------------------auto\n"
        "/*\n"
        " * This function initializes. The classes and method to be used by the\n"
        " * interpreter.\n"
        " *\n"
        " * @param csi client server interpreter reference\n"
        " */\n"
        "extern \"C\" void VTK_WRAP_CS_EXPORT "+funName+"(\n"
        "  vtkClientServerInterpreter *csi)\n"
        "{\n"
        );
    for obj in initObjs:
        f.write("  "+obj+"_Init(csi);\n");

    f.write("}\n")

#---------------------------------------------------------------------------nix
# Ouputs the header and all the other contents to a cxx output file. This
# generated file can is used to initialize all the classes in the interpreter
#
# @param initObjs The list of the classes collected.
# @param outputFile The cxx file that will be genrated.
def outputParaviewInit_cxx(initObjs,outputFile):
    f = open(outputFile, 'w')
    f.write(
        "//-------------------------------------------------------------------------auto\n"
        "/*\n"
        "* @file   "+outputFile+"\n"
        "*\n"
        "* @brief  This file is autogenerated form ClassExtract.py.\n"
        "*         It is used to initialize all the Classs used in *.xml.\n"
        "*/\n"
        "//-------------------------------------------------------------------------auto\n"
        "\n"                                
        "#include \"vtkClientServerInterpreter.h\"\n"
        "\n"
        "#ifndef PARAVIEW_BUILD_SHARED_LIBS\n"
        "/* #undef PARAVIEW_BUILD_SHARED_LIBS */\n"
        "#endif\n"
        "#if defined(PARAVIEW_BUILD_SHARED_LIBS) && defined(_WIN32)\n"
        "# define VTK_WRAP_CS_EXPORT __declspec(dllexport)\n"
        "#else\n"
        "# define VTK_WRAP_CS_EXPORT\n"
        "#endif\n\n"
        );
    outputExternDefinitions(f,initObjs)
    outputInitializeFunction(f,initObjs,outputFile)

#---------------------------------------------------------------------------nix
# Parses all the XML files in a directory and gets all the respective classes.
#
# @param inputDir This directory hold all the XML files.
def parseAndGetUniqueClasses(filesList):
    # Init the parser and register callbacks
    parser = xml.sax.make_parser()
    handler= ClassExtractor()
    parser.setContentHandler(handler)
    # Collect everything in a dictionary
    unique = {}
    for item in filesList:
        parser.parse(item)
        for obj in handler.classes:
            if(len(obj) ):
                if(obj != "not-used"):
                    unique[obj]=obj
    # Return all the values on the dictionary in a list
    return unique.values()

#---------------------------------------------------------------------------nix
# MAIN. This is where it all starts
def main(argv=None):
    # Collect command line args
    if argv is None:
        argv = sys.argv
    # Check if the right parameters are passed
    if(len(argv) < 3):
        print(
            "Usage:"
            " python ClassExtract.py <Output-File-Name> <List-Of-XML-Files>\n")
        sys.exit(1)
    # parse and generate the output file
    outputParaviewInit_cxx (parseAndGetUniqueClasses(argv[2:]),argv[1])

#---------------------------------------------------------------------------nix
# This is where is actually starts. main() is called by default
if __name__ == "__main__":
    sys.exit(main())

#===========================================================================nix
# @file   ClassExtract.py
# @author <NAME>
# @brief  This program takes two parameters. The first is the path to the
#         directory which contains all the XML files used by paraview. Second
#         is the *Init.cxx initilization files which will be produced. This
#         initilization file will be used to initialize only the components
#         that are used by paraview. This may help in reducing the entire
#         footprint of a statically linked paraview.
#===========================================================================nix

import os
import os.path
import sys
import xml.sax.handler
import xml.sax
import pprint

#---------------------------------------------------------------------------nix
# This class is essentially a callback. It is used to parse the xml files.
# It searches for "class" attribute and collects it in a 'classes' array
class ClassExtractor(xml.sax.handler.ContentHandler):
    # Constructor
    def __init__(self):
        self.classes = []

    # Callback each time a new element is parsed
    def startElement(self, name, attributes):
        if attributes.has_key("class"):
            self.classes.append(attributes["class"])

#---------------------------------------------------------------------------nix
# Simply outputs the extern declarations that will be used by the function.
#
# @param f The file to write into.
# @param initObjs The list of the classes collected.
def outputExternDefinitions(f, initObjs):
    for obj in initObjs:
        f.write(
            "extern void "+obj+"_Init(vtkClientServerInterpreter* csi);\n"
            );
    f.write("\n")

#---------------------------------------------------------------------------nix
# outputs the initialization function into the provided file. The initi
# funtion  calls all the other *_Init routines.
#
# @param f The file to write into.
# @param initObjs The list of the classes collected.
# @param outputFile The cxx file that will be genrated.
def outputInitializeFunction(f, initObjs, outputFile):
    # Split all the /in/path/ and extract only source file
    temp = outputFile.split("/")
    # Extract only the classname
    funName = temp[len(temp)-1].split(".")[0].split("Init")[0]+"_Initialize"
    f.write(
        "//-------------------------------------------------------------------------auto\n"
        "/*\n"
        " * This function initializes. The classes and method to be used by the\n"
        " * interpreter.\n"
        " *\n"
        " * @param csi client server interpreter reference\n"
        " */\n"
        "extern \"C\" void VTK_WRAP_CS_EXPORT "+funName+"(\n"
        "  vtkClientServerInterpreter *csi)\n"
        "{\n"
        );
    for obj in initObjs:
        f.write("  "+obj+"_Init(csi);\n");

    f.write("}\n")

#---------------------------------------------------------------------------nix
# Ouputs the header and all the other contents to a cxx output file. This
# generated file can is used to initialize all the classes in the interpreter
#
# @param initObjs The list of the classes collected.
# @param outputFile The cxx file that will be genrated.
def outputParaviewInit_cxx(initObjs,outputFile):
    f = open(outputFile, 'w')
    f.write(
        "//-------------------------------------------------------------------------auto\n"
        "/*\n"
        "* @file   "+outputFile+"\n"
        "*\n"
        "* @brief  This file is autogenerated form ClassExtract.py.\n"
        "*         It is used to initialize all the Classs used in *.xml.\n"
        "*/\n"
        "//-------------------------------------------------------------------------auto\n"
        "\n"                                
        "#include \"vtkClientServerInterpreter.h\"\n"
        "\n"
        "#ifndef PARAVIEW_BUILD_SHARED_LIBS\n"
        "/* #undef PARAVIEW_BUILD_SHARED_LIBS */\n"
        "#endif\n"
        "#if defined(PARAVIEW_BUILD_SHARED_LIBS) && defined(_WIN32)\n"
        "# define VTK_WRAP_CS_EXPORT __declspec(dllexport)\n"
        "#else\n"
        "# define VTK_WRAP_CS_EXPORT\n"
        "#endif\n\n"
        );
    outputExternDefinitions(f,initObjs)
    outputInitializeFunction(f,initObjs,outputFile)

#---------------------------------------------------------------------------nix
# Parses all the XML files in a directory and gets all the respective classes.
#
# @param inputDir This directory hold all the XML files.
def parseAndGetUniqueClasses(filesList):
    # Init the parser and register callbacks
    parser = xml.sax.make_parser()
    handler= ClassExtractor()
    parser.setContentHandler(handler)
    # Collect everything in a dictionary
    unique = {}
    for item in filesList:
        parser.parse(item)
        for obj in handler.classes:
            if(len(obj) ):
                if(obj != "not-used"):
                    unique[obj]=obj
    # Return all the values on the dictionary in a list
    return unique.values()

#---------------------------------------------------------------------------nix
# MAIN. This is where it all starts
def main(argv=None):
    # Collect command line args
    if argv is None:
        argv = sys.argv
    # Check if the right parameters are passed
    if(len(argv) < 3):
        print(
            "Usage:"
            " python ClassExtract.py <Output-File-Name> <List-Of-XML-Files>\n")
        sys.exit(1)
    # parse and generate the output file
    outputParaviewInit_cxx (parseAndGetUniqueClasses(argv[2:]),argv[1])

#---------------------------------------------------------------------------nix
# This is where is actually starts. main() is called by default
if __name__ == "__main__":
    sys.exit(main())

#===========================================================================nix # @file   ClassExtract.py # @author <NAME> # @brief  This program takes two parameters. The first is the path to the #         directory which contains all the XML files used by paraview. Second #         is the *Init.cxx initilization files which will be produced. This #         initilization file will be used to initialize only the components #         that are used by paraview. This may help in reducing the entire #         footprint of a statically linked paraview. #===========================================================================nix #---------------------------------------------------------------------------nix # This class is essentially a callback. It is used to parse the xml files. # It searches for "class" attribute and collects it in a 'classes' array # Constructor # Callback each time a new element is parsed #---------------------------------------------------------------------------nix # Simply outputs the extern declarations that will be used by the function. # # @param f The file to write into. # @param initObjs The list of the classes collected. #---------------------------------------------------------------------------nix # outputs the initialization function into the provided file. The initi # funtion  calls all the other *_Init routines. # # @param f The file to write into. # @param initObjs The list of the classes collected. # @param outputFile The cxx file that will be genrated. # Split all the /in/path/ and extract only source file # Extract only the classname #---------------------------------------------------------------------------nix # Ouputs the header and all the other contents to a cxx output file. This # generated file can is used to initialize all the classes in the interpreter # # @param initObjs The list of the classes collected. # @param outputFile The cxx file that will be genrated. #undef PARAVIEW_BUILD_SHARED_LIBS */\n" #---------------------------------------------------------------------------nix # Parses all the XML files in a directory and gets all the respective classes. # # @param inputDir This directory hold all the XML files. # Init the parser and register callbacks # Collect everything in a dictionary # Return all the values on the dictionary in a list #---------------------------------------------------------------------------nix # MAIN. This is where it all starts # Collect command line args # Check if the right parameters are passed # parse and generate the output file #---------------------------------------------------------------------------nix # This is where is actually starts. main() is called by default