Exemplo n.º 1
0
    def writeOperaSetup(self, sourceRoot, outputRoot):
        """
        Writes a small header file with the current time to
        {outputRoot}/modules/hardcore/base/operasetup.h
        That file's sole purpose is to help dependency resolving. If
        the platform needs it, it should be included from a
        platform-specific header file.

        If outputRoot equals sourceRoot, then modules/hardcore/module.generated
        is updated with the name of the generated file: "base/operasetup.h".
        """
        if outputRoot is None:
            outputRoot = sourceRoot
        opera_setup_h = os.path.join(outputRoot, 'modules', 'hardcore', 'base', 'operasetup.h')
        util.makedirs(os.path.dirname(opera_setup_h))
        f = None
        try:
            f = open(opera_setup_h, "w")
            print >>f, "#ifndef MODULES_HARDCORE_OPERA_OPERASETUP_H"
            print >>f, "#define MODULES_HARDCORE_OPERA_OPERASETUP_H"
            print >>f, "// Modified by operasetup.py %s" % time.ctime()
            print >>f, "#endif // !MODULES_HARDCORE_OPERA_OPERASETUP_H"
        finally:
            if f: f.close()
        if outputRoot == sourceRoot:
            util.updateModuleGenerated(os.path.join(sourceRoot, 'modules', 'hardcore'),
                                       ["base/operasetup.h"])
Exemplo n.º 2
0
    def writeOutputFiles(self, sourceRoot, outputRoot=None):
        import util
        hardcoreDir = os.path.join(sourceRoot, 'modules', 'hardcore')
        actionsDir = os.path.join(hardcoreDir, 'actions')
        if outputRoot is None: targetDir = actionsDir
        else:
            targetDir = os.path.join(outputRoot, 'modules', 'hardcore', 'actions')
            util.makedirs(targetDir)
        changed = util.readTemplate(os.path.join(actionsDir, 'actions_template.h'),
                                    os.path.join(targetDir, 'generated_actions.h'),
                                    HandleTemplateAction(self))

        changed = util.readTemplate(os.path.join(actionsDir, 'actions_enum_template.h'),
                                    os.path.join(targetDir, 'generated_actions_enum.h'),
                                    HandleTemplateAction(self)) or changed
        changed = util.readTemplate(os.path.join(actionsDir, 'actions_strings_template.h'),
                                    os.path.join(targetDir, 'generated_actions_strings.h'),
                                    HandleTemplateAction(self)) or changed
        # Ignore changes in this; this is just a template for a
        # platforms' actions.h and not used when building Opera:
        util.readTemplate(os.path.join(actionsDir, 'actions_template_template.h'),
                          os.path.join(targetDir, 'generated_actions_template.h'),
                          HandleTemplateAction(self))
        if targetDir == actionsDir:
            util.updateModuleGenerated(
                hardcoreDir,
                ['actions/generated_actions.h',
                 'actions/generated_actions_enum.h',
                 'actions/generated_actions_strings.h',
                 'actions/generated_actions_template.h'])
        return changed
Exemplo n.º 3
0
    def __call__(self, sourceRoot, outputRoot=None, quiet=True, show_all=False):
        """
        Calling this instance will generate the source files from the
        modules/viewers/module.viewers file.

        @param sourceRoot is the root directory of the source tree
          that was parsed. Some of the output files are always
          generated relative to the sourceRoot.
        @param outputRoot root of the tree for generated files,
          defaults to sourceRoot
        @param quiet if False, print a message if no files were changed.
        @param show_all controls whether to show only modified files or all
          files which are inspected. Default is False.

        @return The convention of the "system-functions" are that the
          return value should be
          - 0 to indicate success
          - 1 to indicate an error
          - 2 to indicate that output files have changed.
        """
        self.startTiming()
        import viewers

        if outputRoot == None:
            outputRoot = sourceRoot

        modulepath = os.path.join(sourceRoot, "modules", "viewers")
        viewersfile = os.path.join(modulepath, "module.viewers")
        destpath = os.path.join(outputRoot, "modules", "viewers", "src")
        enumfile = os.path.join(destpath, "generated_viewers_enum.h")
        datafile = os.path.join(destpath, "generated_viewers_data.inc")
        result = 0
        util.fileTracker.addInput(viewersfile)
        if not os.path.exists(enumfile) or not os.path.exists(datafile) or \
            max(os.path.getmtime(viewersfile), os.path.getmtime(viewers.__file__)) > min(os.path.getmtime(enumfile), os.path.getmtime(datafile)):
            util.makedirs(destpath)
            viewers.BuildViewers(viewersfile, enumfile, datafile)
            result = 2

            # List the generated files in module.generated
            if outputRoot == sourceRoot:
                util.updateModuleGenerated(modulepath,
                                           [enumfile[len(modulepath) + 1:],
                                            datafile[len(modulepath) + 1:]])

        return self.endTiming(result, quiet=quiet)
Exemplo n.º 4
0
    def __call__(self, sourceRoot, outputRoot=None, quiet=True, show_all=False):
        """
        Calling this instance will generate the source files from the
        modules/viewers/module.viewers file.

        @param sourceRoot is the root directory of the source tree
          that was parsed. Some of the output files are always
          generated relative to the sourceRoot.
        @param outputRoot root of the tree for generated files,
          defaults to sourceRoot
        @param quiet if False, print a message if no files were changed.
        @param show_all controls whether to show only modified files or all
          files which are inspected. Default is False.

        @return The convention of the "system-functions" are that the
          return value should be
          - 0 to indicate success
          - 1 to indicate an error
          - 2 to indicate that output files have changed.
        """
        self.startTiming()
        import viewers

        if outputRoot == None:
            outputRoot = sourceRoot

        modulepath = os.path.join(sourceRoot, "modules", "viewers")
        viewersfile = os.path.join(modulepath, "module.viewers")
        destpath = os.path.join(outputRoot, "modules", "viewers", "src")
        enumfile = os.path.join(destpath, "generated_viewers_enum.h")
        datafile = os.path.join(destpath, "generated_viewers_data.inc")
        result = 0
        util.fileTracker.addInput(viewersfile)
        if not os.path.exists(enumfile) or not os.path.exists(datafile) or \
            max(os.path.getmtime(viewersfile), os.path.getmtime(viewers.__file__)) > min(os.path.getmtime(enumfile), os.path.getmtime(datafile)):
            util.makedirs(destpath)
            viewers.BuildViewers(viewersfile, enumfile, datafile)
            result = 2

            # List the generated files in module.generated
            if outputRoot == sourceRoot:
                util.updateModuleGenerated(modulepath,
                                           [enumfile[len(modulepath) + 1:],
                                            datafile[len(modulepath) + 1:]])

        return self.endTiming(result, quiet=quiet)
Exemplo n.º 5
0
    def create_opera_h(self, sourceRoot, outputRoot=None):
        """
        Creates modules/hardcore/opera/opera.h from the corresponding template
        file modules/hardcore/opera/opera_template.h. The file is generate
        relative to the specified outputRoot. If the outputRoot is not
        specified, sourceRoot is used. If outputRoot == sourceRoot then
        hardcore's module.generated is updated with the line "opera/opera.h".

        Returns true if the generated file was changed.
        """
        if outputRoot is None: outputRoot = sourceRoot
        hardcoreDir = os.path.join(sourceRoot, "modules", "hardcore")
        template = os.path.join(hardcoreDir, "opera", "opera_template.h")
        opera_h = os.path.join(outputRoot, "modules", "hardcore", "opera", "opera.h")
        changed = util.readTemplate(template, opera_h,
                                    self.getTemplateActionHandler(sourceRoot))
        if sourceRoot == outputRoot:
            util.updateModuleGenerated(hardcoreDir, ["opera/opera.h"])
        return changed
Exemplo n.º 6
0
    def create_opera_h(self, sourceRoot, outputRoot=None):
        """
        Creates modules/hardcore/opera/opera.h from the corresponding template
        file modules/hardcore/opera/opera_template.h. The file is generate
        relative to the specified outputRoot. If the outputRoot is not
        specified, sourceRoot is used. If outputRoot == sourceRoot then
        hardcore's module.generated is updated with the line "opera/opera.h".

        Returns true if the generated file was changed.
        """
        if outputRoot is None: outputRoot = sourceRoot
        hardcoreDir = os.path.join(sourceRoot, "modules", "hardcore")
        template = os.path.join(hardcoreDir, "opera", "opera_template.h")
        opera_h = os.path.join(outputRoot, "modules", "hardcore", "opera",
                               "opera.h")
        changed = util.readTemplate(template, opera_h,
                                    self.getTemplateActionHandler(sourceRoot))
        if sourceRoot == outputRoot:
            util.updateModuleGenerated(hardcoreDir, ["opera/opera.h"])
        return changed
Exemplo n.º 7
0
    def create_components_h(self, sourceRoot, outputRoot=None):
        """
        Creates modules/hardcore/opera/components.h from the template file
        modules/hardcore/opera/components_template.h and the module.components
        file from all modules. The file is generated relative to the specified
        outputRoot. If the outputRoot is not specified, sourceRoot is used. If
        outputRoot == sourceRoot then hardcore's module.generated is updated
        with the line 'opera/components.h'.

        Returns true if the generated file was changed.
        """
        if outputRoot is None: outputRoot = sourceRoot
        hardcoreDir = os.path.join(sourceRoot, 'modules', 'hardcore')
        operaDir = os.path.join(hardcoreDir, 'opera')
        changed = util.readTemplate(os.path.join(operaDir, 'components_template.h'),
                                    os.path.join(outputRoot, 'modules', 'hardcore', 'opera', 'components.h'),
                                    ComponentTemplateActionHandler(self.components()))
        if sourceRoot == outputRoot:
            util.updateModuleGenerated(hardcoreDir, ["opera/components.h"])
        return changed
Exemplo n.º 8
0
    def writeOutputFiles(self, sourceRoot, outputRoot):
        hardcoreDir = os.path.join(sourceRoot, 'modules', 'hardcore')

        mhDir = os.path.join(hardcoreDir, 'mh')
        if outputRoot is None:
            targetDir = mhDir
        else:
            targetDir = os.path.join(outputRoot, 'modules', 'hardcore', 'mh')
            util.makedirs(targetDir)
        changed = util.readTemplate(os.path.join(mhDir, 'messages_template.h'),
                                    os.path.join(targetDir, 'generated_messages.h'),
                                    HandleTemplateAction(self))
        changed = util.readTemplate(os.path.join(mhDir, 'message_strings_template.inc'),
                                    os.path.join(targetDir, 'generated_message_strings.inc'),
                                    HandleTemplateAction(self)) or changed
        if targetDir == mhDir:
            util.updateModuleGenerated(hardcoreDir,
                                       ['mh/generated_messages.h',
                                        'mh/generated_message_strings.inc'])
        return changed
Exemplo n.º 9
0
    def generateSourcesSetup(self, verify_sources=True):
        """
        Generates the files sources.all, sources.nopch, sources.pch,
        sources.pch_system_includes and sources.pch_jumbo in both
        modules/hardcore/setup/plain/sources and
        modules/hardcore/setup/jumbo/sources. It also generates the
        jumbo compile units of all modules.
        @return True if any of the generated files has changed and
          False if none has changed.
        """
        changed = False
        self.__plain_sources = module_sources.SourcesSet()
        self.__jumbo_sources = module_sources.SourcesSet()
        for module in self.__modules:
            if util.fileTracker.addInput(module.getSourcesFile()):
                sources = module.getModuleSources()
                changed = sources.generateJumboCompileUnits(self.__sourceRoot, self.__outputRoot) or changed
                self.__plain_sources.extend(sources.plain_sources(),
                                            module.type(), module.name())
                self.__jumbo_sources.extend(sources.jumbo_sources(),
                                            module.type(), module.name())

        # verify that all files exist:
        if verify_sources:
            for filename in set(self.__plain_sources.all()) | set(self.__jumbo_sources.all()):
                if not os.path.exists(os.path.join(self.__sourceRoot, filename)) and not os.path.exists(os.path.join(self.__outputRoot, filename)):
                    self.addError(util.Line("", 0), "file '%s' not found" % filename)

        hardcoreDir = os.path.join(self.__outputRoot, 'modules', 'hardcore')
        plainDir = os.path.join(hardcoreDir, 'setup', 'plain', 'sources')
        jumboDir = os.path.join(hardcoreDir, 'setup', 'jumbo', 'sources')
        sources = ['all', 'nocph', 'pch', 'pch_system_includes', 'pch_jumbo']
        changed = self.__plain_sources.generateSourcesListFiles(plainDir) or changed
        util.updateModuleGenerated(hardcoreDir,
                                   map(lambda s: '/'.join(['setup', 'plain', 'sources', "sources.%s" % s]), sources))
        changed = self.__jumbo_sources.generateSourcesListFiles(jumboDir) or changed
        util.updateModuleGenerated(hardcoreDir,
                                   map(lambda s: '/'.join(['setup', 'jumbo', 'sources', "sources.%s" % s]), sources))

        return changed
Exemplo n.º 10
0
    def generateSourcesSetup(self, verify_sources=True):
        """
        Generates the files sources.all, sources.nopch, sources.pch,
        sources.pch_system_includes and sources.pch_jumbo in both
        modules/hardcore/setup/plain/sources and
        modules/hardcore/setup/jumbo/sources. It also generates the
        jumbo compile units of all modules.
        @return True if any of the generated files has changed and
          False if none has changed.
        """
        changed = False
        self.__plain_sources = module_sources.SourcesSet()
        self.__jumbo_sources = module_sources.SourcesSet()
        for module in self.__modules:
            if util.fileTracker.addInput(module.getSourcesFile()):
                sources = module.getModuleSources()
                changed = sources.generateJumboCompileUnits(self.__sourceRoot, self.__outputRoot) or changed
                self.__plain_sources.extend(sources.plain_sources(),
                                            module.type(), module.name())
                self.__jumbo_sources.extend(sources.jumbo_sources(),
                                            module.type(), module.name())

        # verify that all files exist:
        if verify_sources:
            for filename in set(self.__plain_sources.all()) | set(self.__jumbo_sources.all()):
                if not os.path.exists(os.path.join(self.__sourceRoot, filename)) and not os.path.exists(os.path.join(self.__outputRoot, filename)):
                    self.addError(util.Line("", 0), "file '%s' not found" % filename)

        hardcoreDir = os.path.join(self.__outputRoot, 'modules', 'hardcore')
        plainDir = os.path.join(hardcoreDir, 'setup', 'plain', 'sources')
        jumboDir = os.path.join(hardcoreDir, 'setup', 'jumbo', 'sources')
        sources = ['all', 'nocph', 'pch', 'pch_system_includes', 'pch_jumbo']
        changed = self.__plain_sources.generateSourcesListFiles(plainDir) or changed
        util.updateModuleGenerated(hardcoreDir,
                                   map(lambda s: '/'.join(['setup', 'plain', 'sources', "sources.%s" % s]), sources))
        changed = self.__jumbo_sources.generateSourcesListFiles(jumboDir) or changed
        util.updateModuleGenerated(hardcoreDir,
                                   map(lambda s: '/'.join(['setup', 'jumbo', 'sources', "sources.%s" % s]), sources))

        return changed
Exemplo n.º 11
0
    def create_components_h(self, sourceRoot, outputRoot=None):
        """
        Creates modules/hardcore/opera/components.h from the template file
        modules/hardcore/opera/components_template.h and the module.components
        file from all modules. The file is generated relative to the specified
        outputRoot. If the outputRoot is not specified, sourceRoot is used. If
        outputRoot == sourceRoot then hardcore's module.generated is updated
        with the line 'opera/components.h'.

        Returns true if the generated file was changed.
        """
        if outputRoot is None: outputRoot = sourceRoot
        hardcoreDir = os.path.join(sourceRoot, 'modules', 'hardcore')
        operaDir = os.path.join(hardcoreDir, 'opera')
        changed = util.readTemplate(
            os.path.join(operaDir, 'components_template.h'),
            os.path.join(outputRoot, 'modules', 'hardcore', 'opera',
                         'components.h'),
            ComponentTemplateActionHandler(self.components()))
        if sourceRoot == outputRoot:
            util.updateModuleGenerated(hardcoreDir, ["opera/components.h"])
        return changed
Exemplo n.º 12
0
    def writeOutputFiles(self, sourceRoot, outputRoot=None):
        import util
        hardcoreDir = os.path.join(sourceRoot, 'modules', 'hardcore')
        actionsDir = os.path.join(hardcoreDir, 'actions')
        if outputRoot is None: targetDir = actionsDir
        else:
            targetDir = os.path.join(outputRoot, 'modules', 'hardcore',
                                     'actions')
            util.makedirs(targetDir)
        changed = util.readTemplate(
            os.path.join(actionsDir, 'actions_template.h'),
            os.path.join(targetDir, 'generated_actions.h'),
            HandleTemplateAction(self))

        changed = util.readTemplate(
            os.path.join(actionsDir, 'actions_enum_template.h'),
            os.path.join(targetDir, 'generated_actions_enum.h'),
            HandleTemplateAction(self)) or changed
        changed = util.readTemplate(
            os.path.join(actionsDir, 'actions_strings_template.h'),
            os.path.join(targetDir, 'generated_actions_strings.h'),
            HandleTemplateAction(self)) or changed
        # Ignore changes in this; this is just a template for a
        # platforms' actions.h and not used when building Opera:
        util.readTemplate(
            os.path.join(actionsDir, 'actions_template_template.h'),
            os.path.join(targetDir, 'generated_actions_template.h'),
            HandleTemplateAction(self))
        if targetDir == actionsDir:
            util.updateModuleGenerated(hardcoreDir, [
                'actions/generated_actions.h',
                'actions/generated_actions_enum.h',
                'actions/generated_actions_strings.h',
                'actions/generated_actions_template.h'
            ])
        return changed
Exemplo n.º 13
0
    def __call__(self, sourceRoot, outputRoot=None, quiet=True, show_all=False):
        """
        Calling this instance will generate the source files from all prefs .txt
        files.

        @param sourceRoot is the root directory of the source tree
          that was parsed. Some of the output files are always
          generated relative to the sourceRoot.
        @param outputRoot root of the tree for generated files,
          defaults to sourceRoot
        @param quiet if False, print some log messages about executing the perl
          script.
        @param show_all controls whether to show only modified files or all
          files which are inspected. Default is False.

        @return The convention of the "system-functions" are that the
          return value should be
          - 0 to indicate success
          - 1 to indicate an error
          - 2 to indicate that output files have changed.
        """
        self.startTiming()

        if outputRoot == None:
            outputRoot = sourceRoot

        perl = self.findPerl(quiet)
        if perl is None: return self.endTiming(1, quiet=quiet)
        # Now perl should be the path to a perl executable

        # Scan for modules and prefs files and build the structure
        allfiles = []
        changed = False
        for module, files in find_prefs_files(sourceRoot):
            modfiles = []
            for filename in files:
                self.logmessage(quiet, "Creating prefs enum for %s" % (filename))

                parser = PrefsCollectionParser()
                parser.parse("%s.txt" % filename)
                if not quiet: parser.printParserWarnings()
                if parser.printParserErrors():
                    return self.endTiming(1, quiet=quiet)

                handler = PrefsCollectionTemplateActionHandler(
                    parser.header(), parser.items())

                stem = os.path.relpath(filename, sourceRoot)

                outdir = os.path.dirname(os.path.join(outputRoot, stem))
                basename = os.path.basename(filename)
                prefs_collection_dir = os.path.join("modules", "prefs", "prefsmanager", "collections")
                pc_template_h = os.path.join(sourceRoot, prefs_collection_dir,
                                             "pc_template.h")
                output_h = os.path.join(outdir, "%s_h.inl" % basename)
                changed = util.readTemplate(pc_template_h, output_h, handler) or changed

                pc_template_c = os.path.join(sourceRoot, prefs_collection_dir,
                                             "pc_template.cpp")
                output_c = os.path.join(outdir, "%s_c.inl" % basename)
                changed = util.readTemplate(pc_template_c, output_c, handler) or changed
                modfiles += [output_c, output_h]

                allfiles.append(stem)
                util.fileTracker.addInput(stem + ".cpp") # Will be used by extract-documentation.pl

            # List the generated files in module.generated
            if outputRoot == sourceRoot:
                util.updateModuleGenerated(module.fullPath(), modfiles)

        # Update documentation
        for f in ('modules/prefs/prefsmanager/opprefscollection.cpp',
                  'modules/prefs/prefsmanager/opprefscollection.h',
                  'modules/prefs/module.tweaks',
                  'modules/prefs/prefsmanager/collections/erasettings.h',
                  'modules/pi/OpSystemInfo.h'):
            util.fileTracker.addInput(f) # Will be used by extract-documentation.pl
        if changed:
            documentation_dir = os.path.join(sourceRoot, "modules", "prefs")
            documentation_output_dir = os.path.join(outputRoot, "modules", "prefs")
            documentation_path = os.path.join(documentation_dir, "extract-documentation.pl")
            util.makedirs(os.path.join(documentation_output_dir, "documentation"))
            self.logmessage(quiet, "calling script %s" % (documentation_path))
            subprocess.call([perl, documentation_path, "-o", outputRoot] + allfiles, cwd=sourceRoot)
            if outputRoot == sourceRoot:
                util.updateModuleGenerated(documentation_output_dir, ["documentation/settings.html"])

        if changed: result = 2
        else: result = 0
        return self.endTiming(result, quiet=quiet)
Exemplo n.º 14
0
    def __call__(self,
                 sourceRoot,
                 outputRoot=None,
                 quiet=True,
                 show_all=False):
        """
        Calling this instance will generate the source files from all prefs .txt
        files.

        @param sourceRoot is the root directory of the source tree
          that was parsed. Some of the output files are always
          generated relative to the sourceRoot.
        @param outputRoot root of the tree for generated files,
          defaults to sourceRoot
        @param quiet if False, print some log messages about executing the perl
          script.
        @param show_all controls whether to show only modified files or all
          files which are inspected. Default is False.

        @return The convention of the "system-functions" are that the
          return value should be
          - 0 to indicate success
          - 1 to indicate an error
          - 2 to indicate that output files have changed.
        """
        self.startTiming()

        if outputRoot == None:
            outputRoot = sourceRoot

        perl = self.findPerl(quiet)
        if perl is None: return self.endTiming(1, quiet=quiet)
        # Now perl should be the path to a perl executable

        # Scan for modules and prefs files and build the structure
        allfiles = []
        changed = False
        for module, files in find_prefs_files(sourceRoot):
            modfiles = []
            for filename in files:
                self.logmessage(quiet,
                                "Creating prefs enum for %s" % (filename))

                parser = PrefsCollectionParser()
                parser.parse("%s.txt" % filename)
                if not quiet: parser.printParserWarnings()
                if parser.printParserErrors():
                    return self.endTiming(1, quiet=quiet)

                handler = PrefsCollectionTemplateActionHandler(
                    parser.header(), parser.items())

                stem = os.path.relpath(filename, sourceRoot)

                outdir = os.path.dirname(os.path.join(outputRoot, stem))
                basename = os.path.basename(filename)
                prefs_collection_dir = os.path.join("modules", "prefs",
                                                    "prefsmanager",
                                                    "collections")
                pc_template_h = os.path.join(sourceRoot, prefs_collection_dir,
                                             "pc_template.h")
                output_h = os.path.join(outdir, "%s_h.inl" % basename)
                changed = util.readTemplate(pc_template_h, output_h,
                                            handler) or changed

                pc_template_c = os.path.join(sourceRoot, prefs_collection_dir,
                                             "pc_template.cpp")
                output_c = os.path.join(outdir, "%s_c.inl" % basename)
                changed = util.readTemplate(pc_template_c, output_c,
                                            handler) or changed
                modfiles += [output_c, output_h]

                allfiles.append(stem)
                util.fileTracker.addInput(
                    stem + ".cpp")  # Will be used by extract-documentation.pl

            # List the generated files in module.generated
            if outputRoot == sourceRoot:
                util.updateModuleGenerated(module.fullPath(), modfiles)

        # Update documentation
        for f in ('modules/prefs/prefsmanager/opprefscollection.cpp',
                  'modules/prefs/prefsmanager/opprefscollection.h',
                  'modules/prefs/module.tweaks',
                  'modules/prefs/prefsmanager/collections/erasettings.h',
                  'modules/pi/OpSystemInfo.h'):
            util.fileTracker.addInput(
                f)  # Will be used by extract-documentation.pl
        if changed:
            documentation_dir = os.path.join(sourceRoot, "modules", "prefs")
            documentation_output_dir = os.path.join(outputRoot, "modules",
                                                    "prefs")
            documentation_path = os.path.join(documentation_dir,
                                              "extract-documentation.pl")
            util.makedirs(
                os.path.join(documentation_output_dir, "documentation"))
            self.logmessage(quiet, "calling script %s" % (documentation_path))
            subprocess.call([perl, documentation_path, "-o", outputRoot] +
                            allfiles,
                            cwd=sourceRoot)
            if outputRoot == sourceRoot:
                util.updateModuleGenerated(documentation_output_dir,
                                           ["documentation/settings.html"])

        if changed: result = 2
        else: result = 0
        return self.endTiming(result, quiet=quiet)
Exemplo n.º 15
0
def generate(sourceRoot, outputRoot):
    class File:
        def __init__(self, path, root=outputRoot):
            self.__path = os.path.join(root, *path.split("/"))
            self.__file = StringIO()
            self.__updated = False

        def __getattr__(self, name):
            return getattr(self.__file, name)

        def close(self):
            written = self.__file.getvalue()

            try: existing = open(self.__path).read()
            except: existing = None

            if written != existing:
                self.__updated = True
                util.makedirs(os.path.dirname(self.__path))
                open(self.__path, "w").write(written)

        def updated(self):
            return self.__updated

        def __str__(self):
            return self.__path

    atoms_txt_path = os.path.join(sourceRoot, "modules/dom/src/atoms.txt")

    opatom_h_path = "modules/dom/src/opatom.h"
    opatom_cpp_path = "modules/dom/src/opatom.cpp.inc"
    opatom_ot_path = "modules/dom/selftest/opatom.ot"

    errors = []
    warnings = []
    informational = []

    util.fileTracker.addInput(atoms_txt_path)
    atoms_txt = open(atoms_txt_path, "r")
    atoms = {}

    def addAtom(name, css_property, html_attribute, svg_attribute, condition):
        atom = atoms.get(name)
        if atom:
            errors.append("modules/dom/src/atoms.txt:%d: atom defined twice, previously defined at line %d" % (line_nr, atom['line_nr']))
        else:
            atoms[name] = dict(line_nr=line_nr, name=name, css_property=css_property, html_attribute=html_attribute, svg_attribute=svg_attribute, condition=condition)

    re_comment = re.compile(r"^\s*#.*$")
    re_condition = r"(?:{(.*)})?"
    re_simple_atom = re.compile(r"^\s*([a-zA-Z0-9_]+)\s*" + re_condition + "\s*$")
    re_complex_atom = re.compile(r"^\s*([a-zA-Z0-9_]+)\s*=\s\[(.*)\]\s*" + re_condition + "\s*$")

    line_nr = 0

    in_header = True
    atoms_txt_header = []

    for line in atoms_txt:
        line_nr += 1

        line = line.strip()

        if in_header:
            if line.startswith("#"):
                atoms_txt_header.append(line)
            else:
                in_header = False

        if not line: continue

        match = re_comment.match(line)
        if match:
            continue

        match = re_simple_atom.match(line)
        if match:
            condition = match.group(2)
            if condition:
                condition = condition.strip();
            addAtom(match.group(1), None, None, None, condition)
            continue

        def is_html(d):
            return d.startswith("ATTR_") or d.startswith("Markup::HA_")

        def is_svg(d):
            return d.startswith("SVG_SA_") or d.startswith("Markup::SVGA_")

        match = re_complex_atom.match(line)
        if match:
            data = match.group(2).split(",")
            css_property = [datum.strip() for datum in data if datum.strip().startswith("CSS_PROPERTY_")]
            html_attribute = [datum.strip() for datum in data if is_html(datum.strip())]
            svg_attribute = [datum.strip() for datum in data if is_svg(datum.strip())]
            unknown = [datum.strip() for datum in data if not datum.strip().startswith("CSS_PROPERTY_") and not is_html(datum.strip()) and not is_svg(datum.strip())]
            if css_property: css_property = css_property[0]
            else: css_property = None
            if html_attribute: html_attribute = html_attribute[0]
            else: html_attribute = None
            if svg_attribute: svg_attribute = svg_attribute[0]
            else: svg_attribute = None
            if unknown: errors.append("modules/dom/src/atoms.txt:%d: unknown token(s): %s" % (line_nr, ", ".join(unknown)))
            condition = match.group(3);
            if condition:
                condition = condition.strip();
            addAtom(match.group(1), css_property, html_attribute, svg_attribute, condition)
            continue

        errors.append("modules/dom/src/atoms.txt:%d: parse error" % line_nr)

    atoms_txt.close()

    atom_names = atoms.keys()
    atom_names.sort()

    if errors:
        print >>sys.stderr, "Errors:"
        for error in errors: print >>sys.stderr, error
        return 1

    if "--grep-for-uses" in sys.argv:
        for atom_name in atom_names:
            atom = atoms[atom_name]
            if not atom["css_property"]:
                result = os.system("grep -R OP_ATOM_%s `find modules/dom/src -name '*.cpp' -print` >/dev/null" % atom_name)
                if os.WIFEXITED(result) and os.WEXITSTATUS(result) == 1:
                    warnings.append("%s:%d: OP_ATOM_%s appears to be unused." % (atoms_txt_path, atom["line_nr"], atom_name))

    if warnings:
        print >>sys.stderr, "Warnings:"
        for warning in warnings: print >>sys.stderr, warning

    last_atom_name = None
    last_line_nr = 0
    reorder = False

    for atom_name in atom_names:
        if atoms[atom_name]["line_nr"] < last_line_nr:
            reorder = True
            break
        last_atom_name = atom_name
        last_line_nr = atoms[atom_name]["line_nr"]

    if reorder:
        print >>sys.stderr, """
WARNING: Reordering atoms in modules/dom/src/atoms.txt.

This file is tracked by Git!  You should commit the updated (reordered)
version of the file, or everyone will get this message when building.
"""

        atoms_txt = open(atoms_txt_path, "w")

        for line in atoms_txt_header:
            print >>atoms_txt, line

        print >>atoms_txt

        for atom_name in atom_names:
            atom = atoms[atom_name]
            data = []
            condition = ""

            if atom["svg_attribute"]: data.append(atom["svg_attribute"])
            if atom["html_attribute"]: data.append(atom["html_attribute"])
            if atom["css_property"]: data.append(atom["css_property"])
            if atom["condition"]: condition = " {%s}" % atom["condition"]

            if data: print >>atoms_txt, "%s = [%s]%s" % (atom_name, ", ".join(data), condition)
            else: print >>atoms_txt, "%s%s" % (atom_name, condition)

        atoms_txt.close()

    opatom_h = File(opatom_h_path)

    print >>opatom_h, "/* -*- mode: c++; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */"
    print >>opatom_h
    print >>opatom_h, "#ifndef DOM_OPATOM_H"
    print >>opatom_h, "#define DOM_OPATOM_H"
    print >>opatom_h
    print >>opatom_h, "#include \"modules/dom/src/domdefines.h\""
    print >>opatom_h
    print >>opatom_h, "enum OpAtom"
    print >>opatom_h, "{"
    print >>opatom_h, "\tOP_ATOM_UNASSIGNED = -1,"
    print >>opatom_h

    re_exclude_from_format = re.compile(r"ifdef|ifndef|if|\(|\)|defined")
    re_whitespace = re.compile(r"\s+")

    def formatCondition(condition):
        condition = re_exclude_from_format.sub("", condition)
        condition = re_whitespace.sub(" ", condition)
        return condition.strip()

    last_condition = None

    for index in range(len(atom_names)):
        atom_name = atom_names[index]
        atom = atoms[atom_name]

        if atom["condition"]:
            if atom["condition"] != last_condition:
                print >>opatom_h, "#%s" % atom["condition"]
                last_condition = atom["condition"]

        print >>opatom_h, "\tOP_ATOM_%s," % atom_name

        if atom["condition"]:
            if index < len(atom_names) - 1:
                next_condition = atoms[atom_names[index + 1]]["condition"]
            else:
                next_condition = None
            if next_condition != atom["condition"]:
                print >>opatom_h, "#endif // %s" % formatCondition(atom["condition"])
                last_condition = None

    print >>opatom_h
    print >>opatom_h, "\tOP_ATOM_ABSOLUTELY_LAST_ENUM"
    print >>opatom_h, "};"
    print >>opatom_h
    print >>opatom_h, "extern const unsigned g_DOM_atomData[OP_ATOM_ABSOLUTELY_LAST_ENUM];"
    print >>opatom_h, "extern const unsigned short g_DOM_SVG_atomData[OP_ATOM_ABSOLUTELY_LAST_ENUM];"
    print >>opatom_h
    print >>opatom_h, "OpAtom DOM_StringToAtom(const uni_char *string);"
    print >>opatom_h, "const char *DOM_AtomToString(OpAtom atom);"
    print >>opatom_h
    print >>opatom_h, "Markup::AttrType DOM_AtomToHtmlAttribute(OpAtom atom);"
    print >>opatom_h, "int DOM_AtomToCssProperty(OpAtom atom);"
    print >>opatom_h, "Markup::AttrType DOM_AtomToSvgAttribute(OpAtom atom);"
    print >>opatom_h
    print >>opatom_h, "#endif // DOM_OPATOM_H"

    opatom_h.close()

    opatom_cpp = File(opatom_cpp_path)

    print >>opatom_cpp, "/* -*- mode: c++; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */"
    print >>opatom_cpp
    print >>opatom_cpp, "#ifdef DOM_NO_COMPLEX_GLOBALS"
    print >>opatom_cpp, "# define DOM_ATOM_NAMES_START() void DOM_atomNames_Init(DOM_GlobalData *global_data) { const char **names = global_data->atomNames;"
    print >>opatom_cpp, "# define DOM_ATOM_NAMES_ITEM(name) *names = name; ++names;"
    print >>opatom_cpp, "# define DOM_ATOM_NAMES_ITEM_LAST(name) *names = name;"
    print >>opatom_cpp, "# define DOM_ATOM_NAMES_END() }"
    print >>opatom_cpp, "#else // DOM_NO_COMPLEX_GLOBALS"
    print >>opatom_cpp, "# define DOM_ATOM_NAMES_START() const char *const g_DOM_atomNames[] = {"
    print >>opatom_cpp, "# define DOM_ATOM_NAMES_ITEM(name) name,"
    print >>opatom_cpp, "# define DOM_ATOM_NAMES_ITEM_LAST(name) name"
    print >>opatom_cpp, "# define DOM_ATOM_NAMES_END() };"
    print >>opatom_cpp, "#endif // DOM_NO_COMPLEX_GLOBALS"
    print >>opatom_cpp
    print >>opatom_cpp, "DOM_ATOM_NAMES_START()"

    last_atom_name = atom_names[-1]
    comma = ""
    last_condition = None

    for index in range(len(atom_names)):
        atom_name = atom_names[index]
        atom = atoms[atom_name]

        if atom_name == last_atom_name: comma = "_LAST"

        if atom["condition"]:
            if atom["condition"] != last_condition:
                print >>opatom_cpp, "#%s" % atom["condition"]
                last_condition = atom["condition"]

        print >>opatom_cpp, "\tDOM_ATOM_NAMES_ITEM%s(\"%s\")" % (comma, atom_name)

        if atom["condition"]:
            if index < len(atom_names) - 1:
                next_condition = atoms[atom_names[index + 1]]["condition"]
            else:
                next_condition = None
            if next_condition != atom["condition"]:
                print >>opatom_cpp, "#endif // %s" % formatCondition(atom["condition"])
                last_condition = None

    print >>opatom_cpp, "DOM_ATOM_NAMES_END()"
    print >>opatom_cpp
    print >>opatom_cpp, "const unsigned g_DOM_atomData[] ="
    print >>opatom_cpp, "{"

    comma = ","
    last_condition = None

    for index in range(len(atom_names)):
        atom_name = atom_names[index]
        atom = atoms[atom_name]

        if atom_name == last_atom_name: comma = ""

        if atom["condition"]:
            if atom["condition"] != last_condition:
                print >>opatom_cpp, "#%s" % atom["condition"]
                last_condition = atom["condition"]

        html_attribute = atom["html_attribute"]
        css_property = atom["css_property"]
        if html_attribute is None and css_property is None:
            print >>opatom_cpp, "\tUINT_MAX%s // %s" % (comma, atom_name)
        else:
            if html_attribute is None: html_attribute = "USHRT_MAX"
            if css_property is None: css_property = "USHRT_MAX"
            print >>opatom_cpp, "\tstatic_cast<unsigned>(%s << 16 | %s)%s // %s" % (html_attribute, css_property, comma, atom_name)

        if atom["condition"]:
            if index < len(atom_names) - 1:
                next_condition = atoms[atom_names[index + 1]]["condition"]
            else:
                next_condition = None
            if next_condition != atom["condition"]:
                print >>opatom_cpp, "#endif // %s" % formatCondition(atom["condition"])
                last_condition = None

    print >>opatom_cpp, "};"
    print >>opatom_cpp
    print >>opatom_cpp, "#ifdef SVG_DOM"
    print >>opatom_cpp, "const unsigned short g_DOM_SVG_atomData[] ="
    print >>opatom_cpp, "{"

    comma = ","
    last_condition = None

    for index in range(len(atom_names)):
        atom_name = atom_names[index]
        atom = atoms[atom_name]

        if atom_name == last_atom_name: comma = ""

        if atom["condition"]:
            if atom["condition"] != last_condition:
                print >>opatom_cpp, "#%s" % atom["condition"]
                last_condition = atom["condition"]

        svg_attribute = atom["svg_attribute"]
        if svg_attribute is None:
            print >>opatom_cpp, "\tUSHRT_MAX%s // %s" % (comma, atom_name)
        else:
            print >>opatom_cpp, "\t%s%s // %s" % (svg_attribute, comma, atom_name)

        if atom["condition"]:
            if index < len(atom_names) - 1:
                next_condition = atoms[atom_names[index + 1]]["condition"]
            else:
                next_condition = None
            if next_condition != atom["condition"]:
                print >>opatom_cpp, "#endif // %s" % formatCondition(atom["condition"])
                last_condition = None

    print >>opatom_cpp, "};"
    print >>opatom_cpp
    print >>opatom_cpp, "#endif // SVG_DOM"

    opatom_cpp.close()

    opatom_ot = File(opatom_ot_path)

    print >>opatom_ot, "/* -*- mode: c++; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */"
    print >>opatom_ot
    print >>opatom_ot, "group \"DOM.OpAtom.simple\";"
    print >>opatom_ot
    print >>opatom_ot, "include \"modules/dom/src/opatomdata.h\";"
    print >>opatom_ot, "include \"modules/util/tempbuf.h\";"
    print >>opatom_ot, "include \"modules/doc/frm_doc.h\";"
    print >>opatom_ot
    print >>opatom_ot, "test(\"Sequenciality\")"
    print >>opatom_ot, "{"
    print >>opatom_ot, "  /* If this test fails, chances are someone has modified the OpAtom"
    print >>opatom_ot, "     declaration manually and not updated this file correctly. */"
    print >>opatom_ot
    print >>opatom_ot, "  int index = -1;"
    print >>opatom_ot
    print >>opatom_ot, "  verify(OP_ATOM_UNASSIGNED == index++);"

    last_condition = None

    for index in range(len(atom_names)):
        atom_name = atom_names[index]
        atom = atoms[atom_name]

        if atom["condition"]:
            if atom["condition"] != last_condition:
                print >>opatom_ot, "#%s" % atom["condition"]
                last_condition = atom["condition"]

        print >>opatom_ot, "  verify(OP_ATOM_%s == index++);" % atom_names[index]

        if atom["condition"]:
            if index < len(atom_names) - 1:
                next_condition = atoms[atom_names[index + 1]]["condition"]
            else:
                next_condition = None
            if next_condition != atom["condition"]:
                print >>opatom_ot, "#endif // %s" % formatCondition(atom["condition"])
                last_condition = None

    print >>opatom_ot, "  verify(OP_ATOM_ABSOLUTELY_LAST_ENUM == index);"
    print >>opatom_ot, "}"
    print >>opatom_ot
    print >>opatom_ot, "test(\"Atom to string conversion\")"
    print >>opatom_ot, "{"

    last_condition = None

    for index in range(len(atom_names)):
        atom_name = atom_names[index]
        atom = atoms[atom_name]

        if atom["condition"]:
            if atom["condition"] != last_condition:
                print >>opatom_ot, "#%s" % atom["condition"]
                last_condition = atom["condition"]

        print >>opatom_ot, "  verify(op_strcmp(DOM_AtomToString(OP_ATOM_%s), \"%s\") == 0);" % (atom_name, atom_name)

        if atom["condition"] or last_condition:
            if index < len(atom_names) - 1:
                next_condition = atoms[atom_names[index + 1]]["condition"]
            else:
                next_condition = None
            if next_condition != atom["condition"]:
                print >>opatom_ot, "#endif // %s" % formatCondition(atom["condition"])
                last_condition = None

    print >>opatom_ot, "}"
    print >>opatom_ot
    print >>opatom_ot, "test(\"String to atom conversion\")"
    print >>opatom_ot, "{"
    print >>opatom_ot, "  verify(DOM_StringToAtom(UNI_L(\"aaaaaa\")) == OP_ATOM_UNASSIGNED);"

    last_condition = None

    for index in range(len(atom_names)):
        atom_name = atom_names[index]
        atom = atoms[atom_name]

        if atom["condition"]:
            if atom["condition"] != last_condition:
                print >>opatom_ot, "#%s" % atom["condition"]
                last_condition = atom["condition"]

        print >>opatom_ot, "  verify(DOM_StringToAtom(UNI_L(\"%s\")) == OP_ATOM_%s);" % (atom_name, atom_name)
        print >>opatom_ot, "  verify(DOM_StringToAtom(UNI_L(\"%sA\")) == OP_ATOM_UNASSIGNED);" % atom_name

        if atom["condition"] or last_condition:
            if index < len(atom_names) - 1:
                next_condition = atoms[atom_names[index + 1]]["condition"]
            else:
                next_condition = None
            if next_condition != atom["condition"]:
                print >>opatom_ot, "#endif // %s" % formatCondition(atom["condition"])
                last_condition = None

    print >>opatom_ot, "  verify(DOM_StringToAtom(UNI_L(\"zzzzzz\")) == OP_ATOM_UNASSIGNED);"
    print >>opatom_ot, "}"
    print >>opatom_ot
    print >>opatom_ot, "test(\"Atom to HTML attribute conversion\")"
    print >>opatom_ot, "{"

    last_condition = None

    html_atom_names = [atom_name for atom_name in atom_names if atoms[atom_name]["html_attribute"]]

    for index in range(len(html_atom_names)):
        atom_name = html_atom_names[index]
        atom = atoms[atom_name]

        html_attribute = atoms[atom_name]["html_attribute"]

        if atom["condition"]:
            if atom["condition"] != last_condition:
                print >>opatom_ot, "#%s" % atom["condition"]
                last_condition = atom["condition"]

        print >>opatom_ot, "  verify(DOM_AtomToHtmlAttribute(OP_ATOM_%s) == %s || %s == USHRT_MAX);" % (atom_name, html_attribute, html_attribute)

        if atom["condition"] or last_condition:
            if index < len(html_atom_names) - 1:
                next_condition = atoms[html_atom_names[index + 1]]["condition"]
            else:
                next_condition = None
            if next_condition != atom["condition"]:
                print >>opatom_ot, "#endif // %s" % formatCondition(atom["condition"])
                last_condition = None

    print >>opatom_ot, "}"
    print >>opatom_ot
    print >>opatom_ot, "test(\"Atom to SVG attribute conversion\")"
    print >>opatom_ot, "\trequire SVG_SUPPORT;"
    print >>opatom_ot, "\trequire SVG_DOM;"
    print >>opatom_ot, "{"

    last_condition = None

    svg_atom_names = [atom_name for atom_name in atom_names if atoms[atom_name]["svg_attribute"]]

    for index in range(len(svg_atom_names)):
        atom_name = svg_atom_names[index]
        atom = atoms[atom_name]

        svg_attribute = atoms[atom_name]["svg_attribute"]

        if atom["condition"]:
            if atom["condition"] != last_condition:
                print >>opatom_ot, "#%s" % atom["condition"]
                last_condition = atom["condition"]

        print >>opatom_ot, "  verify(DOM_AtomToSvgAttribute(OP_ATOM_%s) == %s || %s == USHRT_MAX);" % (atom_name, svg_attribute, svg_attribute)

        if atom["condition"] or last_condition:
            if index < len(svg_atom_names) - 1:
                next_condition = atoms[svg_atom_names[index + 1]]["condition"]
            else:
                next_condition = None
            if next_condition != atom["condition"]:
                print >>opatom_ot, "#endif // %s" % formatCondition(atom["condition"])
                last_condition = None

    print >>opatom_ot, "}"
    print >>opatom_ot
    print >>opatom_ot, "test(\"Atom to CSS property conversion\")"
    print >>opatom_ot, "{"

    last_condition = None

    css_atom_names = [atom_name for atom_name in atom_names if atoms[atom_name]["css_property"]]

    for index in range(len(css_atom_names)):
        atom_name = css_atom_names[index]
        atom = atoms[atom_name]

        css_property = atoms[atom_name]["css_property"]
        if css_property is not None:
            if atom["condition"]:
                if atom["condition"] != last_condition:
                    print >>opatom_ot, "#%s" % atom["condition"]
                    last_condition = atom["condition"]

            print >>opatom_ot, "  verify(DOM_AtomToCssProperty(OP_ATOM_%s) == %s);" % (atom_name, css_property)

            if atom["condition"] or last_condition:
                if index < len(css_atom_names) - 1:
                    next_condition = atoms[css_atom_names[index + 1]]["condition"]
                else:
                    next_condition = None
                if next_condition != atom["condition"]:
                    print >>opatom_ot, "#endif // %s" % formatCondition(atom["condition"])
                    last_condition = None

    print >>opatom_ot, "}"
    print >>opatom_ot
    print >>opatom_ot, "group \"DOM.OpAtom.complicated\";"
    print >>opatom_ot, "require init;"
    print >>opatom_ot
    print >>opatom_ot, "include \"modules/dom/src/domenvironmentimpl.h\";"
    print >>opatom_ot, "include \"modules/dom/src/domobj.h\";"
    print >>opatom_ot
    print >>opatom_ot, "global"
    print >>opatom_ot, "{"
    print >>opatom_ot, "  class AtomsTester : public DOM_Object"
    print >>opatom_ot, "  {"
    print >>opatom_ot, "  private:"
    print >>opatom_ot, "    OpAtom expected, got;"
    print >>opatom_ot, "    BOOL result, called;"
    print >>opatom_ot
    print >>opatom_ot, "  public:"
    print >>opatom_ot, "    AtomsTester()"
    print >>opatom_ot, "      : expected(OP_ATOM_UNASSIGNED), got(OP_ATOM_UNASSIGNED), result(FALSE), called(FALSE)"
    print >>opatom_ot, "    {"
    print >>opatom_ot, "    }"
    print >>opatom_ot
    print >>opatom_ot, "    virtual ES_GetState GetIndex(int property_index, ES_Value *value, ES_Runtime *)"
    print >>opatom_ot, "    {"
    print >>opatom_ot, "      expected = (OpAtom) property_index;"
    print >>opatom_ot, "      DOMSetUndefined(value);"
    print >>opatom_ot, "      return GET_SUCCESS;"
    print >>opatom_ot, "    }"
    print >>opatom_ot
    print >>opatom_ot, "    virtual ES_GetState GetName(OpAtom property_name, ES_Value *value, ES_Runtime *)"
    print >>opatom_ot, "    {"
    print >>opatom_ot, "      result = (got = property_name) == expected;"
    print >>opatom_ot, "      called = TRUE;"
    print >>opatom_ot, "      DOMSetUndefined(value);"
    print >>opatom_ot, "      return GET_SUCCESS;"
    print >>opatom_ot, "    }"
    print >>opatom_ot
    print >>opatom_ot, "    virtual ES_PutState PutName(OpAtom property_name, ES_Value *, ES_Runtime *)"
    print >>opatom_ot, "    {"
    print >>opatom_ot, "      result = property_name == expected;"
    print >>opatom_ot, "      called = TRUE;"
    print >>opatom_ot, "      return PUT_SUCCESS;"
    print >>opatom_ot, "    }"
    print >>opatom_ot
    print >>opatom_ot, "    virtual int Call(ES_Object *, ES_Value *, int, ES_Value *return_value, ES_Runtime *)"
    print >>opatom_ot, "    {"
    print >>opatom_ot, "      if (result)"
    print >>opatom_ot, "        DOMSetBoolean(return_value, TRUE);"
    print >>opatom_ot, "      else"
    print >>opatom_ot, "      {"
    print >>opatom_ot, "        TempBuffer *buffer = GetEmptyTempBuf();"
    print >>opatom_ot, "        char expected_int[14]; /* ARRAY OK 2009-04-24 jl */"
    print >>opatom_ot, "        char got_int[14]; /* ARRAY OK 2009-04-24 jl */"
    print >>opatom_ot, "        const char *expected_string, *got_string;"
    print >>opatom_ot
    print >>opatom_ot, "        op_sprintf(expected_int, \"%d\", (int) expected);"
    print >>opatom_ot, "        op_sprintf(got_int, \"%d\", (int) got);"
    print >>opatom_ot
    print >>opatom_ot, "        expected_string = (expected > OP_ATOM_UNASSIGNED && expected < OP_ATOM_ABSOLUTELY_LAST_ENUM) ? DOM_AtomToString(expected) : \"<invalid>\";"
    print >>opatom_ot, "        got_string = (got > OP_ATOM_UNASSIGNED && got < OP_ATOM_ABSOLUTELY_LAST_ENUM) ? DOM_AtomToString(got) : \"<invalid>\";"
    print >>opatom_ot
    print >>opatom_ot, "        CALL_FAILED_IF_ERROR(buffer->Append(\"Expected \"));"
    print >>opatom_ot, "        CALL_FAILED_IF_ERROR(buffer->Append(expected_int));"
    print >>opatom_ot, "        CALL_FAILED_IF_ERROR(buffer->Append(\" (\"));"
    print >>opatom_ot, "        CALL_FAILED_IF_ERROR(buffer->Append(expected_string));"
    print >>opatom_ot, "        if (called)"
    print >>opatom_ot, "        {"
    print >>opatom_ot, "          CALL_FAILED_IF_ERROR(buffer->Append(\"), got \"));"
    print >>opatom_ot, "          CALL_FAILED_IF_ERROR(buffer->Append(got_int));"
    print >>opatom_ot, "          CALL_FAILED_IF_ERROR(buffer->Append(\" (\"));"
    print >>opatom_ot, "          CALL_FAILED_IF_ERROR(buffer->Append(got_string));"
    print >>opatom_ot, "          CALL_FAILED_IF_ERROR(buffer->Append(\")\"));"
    print >>opatom_ot, "        }"
    print >>opatom_ot, "        else"
    print >>opatom_ot, "          CALL_FAILED_IF_ERROR(buffer->Append(\"), got nothing\"));"
    print >>opatom_ot
    print >>opatom_ot, "        DOMSetString(return_value, buffer->GetStorage());"
    print >>opatom_ot, "      }"
    print >>opatom_ot
    print >>opatom_ot, "      result = FALSE;"
    print >>opatom_ot, "      called = FALSE;"
    print >>opatom_ot
    print >>opatom_ot, "      return ES_VALUE;"
    print >>opatom_ot, "    }"
    print >>opatom_ot, "  };"
    print >>opatom_ot, "}"
    print >>opatom_ot
    print >>opatom_ot, "html \"\";"
    print >>opatom_ot
    print >>opatom_ot, "test(\"Setup (c++)\")"
    print >>opatom_ot, "{"
    print >>opatom_ot, "  verify(state.doc);"
    print >>opatom_ot, "  verify(state.doc->ConstructDOMEnvironment() == OpStatus::OK);"
    print >>opatom_ot, "  verify(state.doc->GetDOMEnvironment());"
    print >>opatom_ot, "  verify(state.doc->GetDOMEnvironment()->IsEnabled());"
    print >>opatom_ot
    print >>opatom_ot, "  DOM_Environment *env = state.doc->GetDOMEnvironment();"
    print >>opatom_ot
    print >>opatom_ot, "  DOM_Object *atomstester = OP_NEW(AtomsTester, ());"
    print >>opatom_ot, "  verify(atomstester != NULL);"
    print >>opatom_ot, "  verify(atomstester->SetFunctionRuntime(env->GetRuntime(), UNI_L(\"atomsTester\"), NULL, NULL) == OpStatus::OK);"
    print >>opatom_ot, "  verify(env->GetWindow()->Put(UNI_L(\"atomsTester\"), *atomstester) == OpStatus::OK);"
    print >>opatom_ot, "}"
    print >>opatom_ot
    print >>opatom_ot, "language ecmascript;"
    print >>opatom_ot
    print >>opatom_ot, "test(\"Setup (ecmascript)\")"
    print >>opatom_ot, "  disabled;"
    print >>opatom_ot, "{"
    print >>opatom_ot, "  atoms = ["

    for atom_name in atom_names:
        print >>opatom_ot, "    \"%s\"," % atom_name

    print >>opatom_ot, "    null"
    print >>opatom_ot, "  ];"
    print >>opatom_ot, "}"
    print >>opatom_ot
    print >>opatom_ot, "test(\"GetName conversion\")"
    print >>opatom_ot, "  disabled;"
    print >>opatom_ot, "{"
    print >>opatom_ot, "  var index = 0;"
    print >>opatom_ot, "  while (atoms[index])"
    print >>opatom_ot, "  {"
    print >>opatom_ot, "    var x = atomsTester[index];"
    print >>opatom_ot, "    var y = atomsTester[atoms[index]];"
    print >>opatom_ot, "    var result = atomsTester();"
    print >>opatom_ot, "    if (result != true)"
    print >>opatom_ot, "      throw result;"
    print >>opatom_ot, "    ++index;"
    print >>opatom_ot, "  }"
    print >>opatom_ot, "}"
    print >>opatom_ot
    print >>opatom_ot, "test(\"PutName conversion\")"
    print >>opatom_ot, "  disabled;"
    print >>opatom_ot, "{"
    print >>opatom_ot, "  var index = 0;"
    print >>opatom_ot, "  while (atoms[index])"
    print >>opatom_ot, "  {"
    print >>opatom_ot, "    var x = atomsTester[index];"
    print >>opatom_ot, "    atomsTester[atoms[index]] = true;"
    print >>opatom_ot, "    var result = atomsTester();"
    print >>opatom_ot, "    if (result != true)"
    print >>opatom_ot, "      throw result;"
    print >>opatom_ot, "    ++index;"
    print >>opatom_ot, "  }"
    print >>opatom_ot, "}"

    opatom_ot.close()

    if outputRoot == sourceRoot:
        util.updateModuleGenerated(os.path.join(sourceRoot, "modules", "dom"),
                                   ["src/opatom.h",
                                    "src/opatom.cpp.inc",
                                    "selftest/opatom.ot"])

    if reorder:
        return 1
    elif opatom_h.updated() or opatom_cpp.updated() or opatom_ot.updated():
        return 2
    else:
        return 0
Exemplo n.º 16
0
    def __call__(self, sourceRoot, feature_def, outputRoot=None, quiet=True):
        """
        Generates the following files in the specified output root:
        - modules/hardcore/features/features.h
        - modules/hardcore/features/features-thirdparty_attributions.inl
        - modules/hardcore/features/profile_{profile}.h for all profiles
        Generates the following files in the specified source root:
        - modules/hardcore/opera/setupinfo_features.cpp
        - modules/hardcore/documentation/features.{core_version}.xml for
          the core_version as given by the specified feature_def.

        @param sourceRoot is the path to the Opera source tree

        @param feature_def specifies a loaded instance of the class
          util.FeatureDefinition

        @param outputRoot is the path in which to generate the output files
          modules/hardcore/features/features.h
          modules/hardcore/features/profile_{profile}.h
          If this argument is None, then
          {sourceRoot}/modules/hardcore/features/ is used.
        """
        self.startTiming()
        if feature_def is None or not feature_def.isLoaded():
            error(
                "the argument feature_def must be a loaded util.FeatureDefinition instance"
            )
            result = 1
        else:
            hardcoreDir = os.path.join(sourceRoot, 'modules', 'hardcore')
            featuresDir = os.path.join(hardcoreDir, 'features')
            if outputRoot is None:
                targetDir = featuresDir
            else:
                targetDir = os.path.join(outputRoot, 'modules', 'hardcore',
                                         'features')

            changed = util.makedirs(targetDir)

            # TODO: instead of creating a copy of "features.h" for each
            # profile in
            # opera/profiles/{profile}.[next]/include/modules/hardcore/features/
            # with the same content, try to find a place for that include file
            # which only depends on "current" or "next" mainline-configuration:
            changed = util.readTemplate(
                os.path.join(featuresDir, 'features_template.h'),
                os.path.join(targetDir, 'features.h'),
                HandleTemplateAction(feature_def)) or changed

            changed = util.readTemplate(
                os.path.join(featuresDir,
                             'features-thirdparty_attributions_template.inl'),
                os.path.join(targetDir,
                             'features-thirdparty_attributions.inl'),
                LegalTemplateActionHandler(feature_def)) or changed

            # TODO: instead of creating profile_XXX.h for all profiles XXX in
            # opera/profile/{profile}.[next]/include/modules/hardcore/features/,
            # only create profile_{profile}.h for the one profile that is
            # needed:
            for profile in util.PROFILES:
                changed = util.readTemplate(
                    os.path.join(featuresDir, 'profile_template.h'),
                    os.path.join(targetDir, 'profile_%s.h' % profile),
                    ProfileTemplateActionHandler(
                        profile, feature_def.featuresWithDefault())) or changed
            if targetDir == featuresDir:
                util.updateModuleGenerated(hardcoreDir, [
                    'features/features.h',
                    'features/features-thirdparty_attributions.inl'
                ] + [
                    'features/profile_%s.h' % profile
                    for profile in util.PROFILES
                ])

            # Ignore changes in setupinfo_features.cpp and documentation files:
            setupinfoDir = os.path.join(hardcoreDir, 'opera')
            documentationDir = os.path.join(hardcoreDir, 'documentation')
            if outputRoot is None:
                setupinfoOutputDir = setupInfoDir
                documentationOutputDir = documentationDir
            else:
                setupinfoOutputDir = os.path.join(outputRoot, 'modules',
                                                  'hardcore', 'opera')
                documentationOutputDir = os.path.join(outputRoot, 'modules',
                                                      'hardcore',
                                                      'documentation')
            # TODO: create a different output file
            # setupinfo_features.{core_version}.cpp for different
            # core-versions - note: this is only required if new features are
            # added or the documentation of a feature is changed.
            util.readTemplate(
                os.path.join(setupinfoDir, 'setupinfo_features_template.cpp'),
                os.path.join(setupinfoOutputDir,
                             'setupinfo_features_generated.inl'),
                HandleTemplateAction(feature_def),
                hardcoreDir if setupinfoDir == setupinfoOutputDir else None,
                'opera/setupinfo_features.cpp')
            if feature_def.coreVersion() is None:
                features_xml = 'features.xml'
            else:
                features_xml = 'features.%s.xml' % feature_def.coreVersion()
            util.readTemplate(
                os.path.join(featuresDir, 'features_template.xml'),
                os.path.join(documentationOutputDir, features_xml),
                HandleTemplateAction(feature_def), hardcoreDir
                if documentationDir == documentationOutputDir else None,
                'documentation/%s' % features_xml)

            if changed: result = 2
            else: result = 0
        return self.endTiming(result,
                              sourceRoot=sourceRoot,
                              outputRoot=outputRoot,
                              quiet=quiet)
Exemplo n.º 17
0
def generatePchFiles(sourceRoot, outputRoot, platform_product_config=None, pch_template=None):
    """
    Generates from modules/hardcore/base/pch_template.h the header
    files core/pch.h, core/pch_jumbo.h, core/pch_system_includes.h
    @param sourceRoot is the path to the Opera source tree.
    @param outputRoot is the output directory in which to generate the
      header files. If outputRoot is None, the header files are
      generated relative to the specified sourceRoot.
    @param platform_product_config is the platform's config file
      that #defines the PRODUCT_* macros. That file is included by the
      generated pch header files. If no config file is specified, an
      #error statement is generated to indicate that these macros are
      needed on compiling the sources.
    @param pch_template is the template file
      that should be used when generating pch files
    @return True if any of the generated files was updated and False
      if none of the files were changed.
    """

    class CreatePchFromTemplate:
        """
        Creates a core/pch...h file frome the template file
        modules/hardcore/base/pch_template.h.
        """
        def __init__(self, filename, platform_product_config=None):
            """
            @param filename is the name of the header file to
              create. This name is used to generate the
              #ifndef...#define...#endif statements.
            @param platform_product_config is the path to the
              platform's config file which #defines the PRODUCT_*
              macros. If no config file is specified, an #error
              statement is generated to indicate that these macros are
              needed on compiling the sources.
            """
            self.__define = "_CORE_%s_" % filename.replace('.', '_').upper()
            self.__platform_product_config = platform_product_config
            if filename == "pch_system_includes.h":
                # only core/pch_system_includes.h should add a
                # #define ALLOW_SYSTEM_INCLUDES
                self.__allow_system_includes = True
            else:
                self.__allow_system_includes = False

        def __call__(self, action, output):
            if action == "ifndef file_h":
                output.write("#ifndef %s\n" % self.__define)
                return True

            elif action == "define file_h":
                output.write("#define %s\n" % self.__define)
                return True

            elif action == "define ALLOW_SYSTEM_INCLUDES":
                if self.__allow_system_includes:
                    # enclose in ifndef, because sometimes it's defined globally
                    # (in Opera.vcxproj generated by vcxproj_update.py)
                    # and in this case redefinition gives a lot of compilation warnings
                    output.write("#ifndef ALLOW_SYSTEM_INCLUDES\n")
                    output.write("#define ALLOW_SYSTEM_INCLUDES\n")
                    output.write("#endif // ALLOW_SYSTEM_INCLUDES\n\n")
                return True

            elif action == "endif file_h":
                output.write("#endif // %s\n" % self.__define)
                return True

            elif action == "include platform config":
                if self.__platform_product_config:
                    output.write("#include \"%s\"\n" % self.__platform_product_config)
                else:
                    output.write("#ifdef PRODUCT_CONFIG_FILE\n")
                    output.write("// The platform may define a command line define PRODUCT_CONFIG_FILE:\n")
                    output.write("// 'PRODUCT_CONFIG_FILE=\"platforms/my_platform/product_config.h\"' which\n")
                    output.write("// defines a header file that is included here. The header file has the\n")
                    output.write("// possibility to define the PRODUCT_*_FILE macros e.g. like\n")
                    output.write("// #define PRODUCT_FEATURE_FILE \"platforms/my_platform/features.h\"\n")
                    output.write("// #define PRODUCT_SYSTEM_FILE \"platforms/my_platform/system.h\"\n")
                    output.write("// #define PRODUCT_OPKEY_FILE \"platforms/my_platform/opkey.h\"\n")
                    output.write("// #define PRODUCT_ACTIONS_FILE \"platforms/my_platform/actions.h\"\n")
                    output.write("// #define PRODUCT_TWEAKS_FILE \"platforms/my_platform/tweaks.h\"\n")
                    output.write("# include PRODUCT_CONFIG_FILE\n")
                    output.write("#endif // PRODUCT_CONFIG_FILE\n")
                return True

    changed = False
    hardcoreDir = os.path.join(sourceRoot, 'modules', 'hardcore')
    if not pch_template:
        baseDir = os.path.join(hardcoreDir, 'base')
        pch_template = os.path.join(baseDir, 'pch_template.h')
    elif not os.path.isabs(pch_template):
        pch_template = os.path.join(sourceRoot, pch_template)
    if not os.path.exists(pch_template):
        raise IOError(errno.ENOENT, "Template file '%s' (passed with --pch_template) not found" % pch_template)
    for pch in ('pch.h', 'pch_jumbo.h', 'pch_system_includes.h'):
        changed = util.readTemplate(
            pch_template, os.path.join(outputRoot, 'core', pch),
            CreatePchFromTemplate(pch, platform_product_config)) or changed

    # if the pch files are generated relative to the modules/hardcore
    # dir, update hardcore's module.generated:
    match = re.match("^%s(.*)$" % re.escape(hardcoreDir+os.sep), outputRoot)
    if match:
        base = match.group(1).replace(os.sep, '/')
        util.updateModuleGenerated(os.path.join(sourceRoot, 'modules', 'hardcore'),
                                   map(lambda h: '/'.join([base, 'core', h]),
                                       ['pch.h', 'pch_jumbo.h',
                                        'pch_system_includes.h']))
    return changed
Exemplo n.º 18
0
def generate(sourceRoot, outputRoot):
    all_prototypes = {}
    groups = []

    re_exclude_from_format = re.compile(r"ifdef|ifndef|if|\(|\)|defined")
    re_whitespace = re.compile(r"\s+")

    def formatCondition(condition):
        condition = re_exclude_from_format.sub("", condition)
        condition = re_whitespace.sub(" ", condition)
        return condition.strip()

    class File:
        def __init__(self, path, root=outputRoot):
            self.__path = os.path.join(root, *path.split("/"))
            self.__file = StringIO()
            self.__updated = False

        def __getattr__(self, name):
            return getattr(self.__file, name)

        def close(self):
            written = self.__file.getvalue()

            try: existing = open(self.__path).read()
            except: existing = None

            if written != existing:
                self.__updated = True
                util.makedirs(os.path.dirname(self.__path))
                open(self.__path, "w").write(written)

        def updated(self):
            return self.__updated

        def __str__(self):
            return self.__path

    class Group:
        def __init__(self, title, condition):
            self.__title = title
            self.__condition = condition
            self.__prototypes = []

        def addPrototype(self, prototype):
            self.__prototypes.append(prototype)

        def getTitle(self): return self.__title

        def getLines(self, for_file):
            lines = ["\t/* %s */\n" % self.__title]

            if self.__condition: lines.append("#%s\n" % self.__condition)

            actual_lines = 0

            current_condition = None
            for index, prototype in enumerate(self.__prototypes):
                prototype_lines = prototype.getLines(for_file)
                if prototype_lines:
                    if prototype.getCondition() != current_condition:
                        if current_condition: lines.append("#endif // %s\n" % formatCondition(current_condition))
                        current_condition = prototype.getCondition()
                        if current_condition: lines.append("#%s\n" % current_condition)

                    lines.extend(prototype_lines)
                    actual_lines += len(prototype_lines)

            if actual_lines == 0: return []

            if current_condition: lines.append("#endif // %s\n" % formatCondition(current_condition))

            if self.__condition: lines.append("#endif // %s\n" % formatCondition(self.__condition))

            lines.append("\n")
            return lines

    class Prototype:
        def __init__(self, name, classname, displayname, functions, functions_with_data, prepare_prototype_function, baseprototype, condition):
            self.__displayname = displayname
            self.__name = name
            self.__classname = classname
            self.__functions = functions
            self.__functions_with_data = functions_with_data
            self.__prepare_prototype_function = prepare_prototype_function
            self.__condition = condition

            if baseprototype:
                if baseprototype == "(ERROR)": self.__baseprototype = -2
                else: self.__baseprototype = "DOM_Runtime::%s_PROTOTYPE" % baseprototype
            else: self.__baseprototype = -1

        def getCondition(self): return self.__condition

        def getLines(self, for_file):
            if self.__name.startswith("(") and self.__name.endswith(")") and for_file in ("domruntime.h", "domruntime.cpp", "domruntime.cpp-constructor-name", "domprototypes.cpp"):
                return None

            if for_file == "domruntime.h":
                return ["\t%s_PROTOTYPE,\n" % self.__name]
            elif for_file == "domruntime.cpp":
                return ["\tDOM_PROTOTYPE_CLASSNAMES_ITEM(\"%s\")\n" % (self.__displayname)];
            elif for_file == "domruntime.cpp-constructor-name":
                return ["\tDOM_CONSTRUCTOR_NAMES_ITEM(\"%s\")\n" % (self.__displayname)];
            elif for_file == "domprototypes.cpp":
                if self.__functions and self.__functions_with_data:
                    return ["\tDOM_PROTOTYPES_ITEM3(%s_PROTOTYPE, %s_functions, %s_functions_with_data, %s)\n" % (self.__name, self.__classname, self.__classname, self.__baseprototype)]
                elif self.__functions:
                    return ["\tDOM_PROTOTYPES_ITEM1(%s_PROTOTYPE, %s_functions, %s)\n" % (self.__name, self.__classname, self.__baseprototype)]
                elif self.__functions_with_data:
                    return ["\tDOM_PROTOTYPES_ITEM2(%s_PROTOTYPE, %s_functions_with_data, %s)\n" % (self.__name, self.__classname, self.__baseprototype)]
                else:
                    return ["\tDOM_PROTOTYPES_ITEM0(%s_PROTOTYPE, %s)\n" % (self.__name, self.__baseprototype)]
            elif for_file == "domprototypes.cpp-prepare-prototype":
                if self.__prepare_prototype_function:
                    return ["\tcase %s_PROTOTYPE:\n" % self.__name, "\t\t%s::%s(object, this);\n" % (self.__classname, self.__prepare_prototype_function), "\t\treturn;\n"]
                else:
                    return None
            else:
                if self.__functions and self.__functions_with_data:
                    return ["\tDOM_FUNCTIONS3(%s)\n" % self.__classname]
                elif self.__functions:
                    return ["\tDOM_FUNCTIONS1(%s)\n" % self.__classname]
                elif self.__functions_with_data:
                    return ["\tDOM_FUNCTIONS2(%s)\n" % self.__classname]

    group_decl = re.compile("^group\\s+\"([^)]+)\"(\\s+{([^}]*)})?$")
    group_start = re.compile("^{$")
    prototype_decl = re.compile("^(\\(?[A-Z0-9_]+\\)?):\\s+([A-Za-z0-9_]+)\\((\S+(?:,\s*\S+)*)?\\)(?:\\s+base=([A-Z0-9_]+|\([A-Z0-9_]+\)))?(?:\\s+{([^}]*)})?$")
    group_end = re.compile(r"^}$")

    pending_group = None
    current_group = None

    def fatal(message):
        print >>sys.stderr, message
        return 1

    prototypes_txt_path = os.path.join(sourceRoot, "modules/dom/src/prototypes.txt")
    util.fileTracker.addInput(prototypes_txt_path)
    for line in open(prototypes_txt_path):
        line = line.strip()

        if not line or line[0] == "#": continue

        match = group_decl.match(line)
        if match:
            title = match.group(1)
            condition = match.group(3)

            if current_group: return fatal("Nested group (\"%s\" inside \"%s\")" % (title, current_group.getTitle()))
            if pending_group: return fatal("Parse error: %s" % line)

            pending_group = Group(title, condition)
            continue

        match = group_start.match(line)
        if match:
            if not pending_group: return fatal("Unexpected {")
            current_group = pending_group
            pending_group = None
            continue

        match = prototype_decl.match(line)
        if match:
            name = match.group(1)
            classname = match.group(2)
            functions_decl = match.group(3)
            baseprototype = match.group(4)
            condition = match.group(5)

            if all_prototypes.has_key(name): return fatal("Duplicate prototype: %s" % name)
            if current_group is None: return fatal("Prototype outside group: %s" % name)


            displayname = None
            functions = False
            functions_with_data = False
            prepare_prototype_function = None

            if functions_decl is not None:
                items = [item.strip() for item in functions_decl.split(",")]
                for item in items:
                    if displayname is None:
                        displayname = item
                    elif item == "functions_with_data":
                        functions_with_data = True
                    elif item == "functions":
                        functions = True
                    elif prepare_prototype_function is None:
                        prepare_prototype_function = item
                    else:
                        return fatal("Failed to grok functions declaration for prototype: %s" % name)

            if not displayname:
                return fatal("Missing display name for prototype: %s" % name)

            current_group.addPrototype(Prototype(name, classname, displayname, functions, functions_with_data, prepare_prototype_function, baseprototype, condition))
            continue

        match = group_end.match(line)
        if match:
            groups.append(current_group)
            current_group = None
            continue

        return fatal("Parse error: %s" % line)

    domruntime_h = File("modules/dom/src/domruntime.h.inc")
    domruntime_h.write("""/* -*- Mode: c++; indent-tabs-mode: t; tab-width: 4 -*- */

enum Prototype
{
""")

    for group in groups:
        domruntime_h.writelines(group.getLines("domruntime.h"))

    domruntime_h.write("""\tPROTOTYPES_COUNT
};
""")

    domruntime_h.close()

    domruntime_cpp = File("modules/dom/src/domruntime.cpp.inc")
    domruntime_cpp.write("""/* -*- Mode: c++; indent-tabs-mode: t; tab-width: 4 -*- */

DOM_PROTOTYPE_CLASSNAMES_START()

""")

    for group in groups:
        domruntime_cpp.writelines(group.getLines("domruntime.cpp"))

    domruntime_cpp.write("\tDOM_PROTOTYPE_CLASSNAMES_ITEM_LAST(\"\")\n\nDOM_PROTOTYPE_CLASSNAMES_END()\n\nDOM_CONSTRUCTOR_NAMES_START()\n\n")

    for group in groups:
        domruntime_cpp.writelines(group.getLines("domruntime.cpp-constructor-name"))

    domruntime_cpp.write("\tDOM_CONSTRUCTOR_NAMES_ITEM_LAST(\"\")\n\nDOM_CONSTRUCTOR_NAMES_END()\n")
    domruntime_cpp.close()

    domprototypes_cpp = File("modules/dom/src/domprototypes.cpp.inc")
    domprototypes_cpp.write("""/* -*- Mode: c++; indent-tabs-mode: t; tab-width: 4 -*- */

DOM_PROTOTYPES_START()

""")

    for group in groups:
        domprototypes_cpp.writelines(group.getLines("domprototypes.cpp"))

    domprototypes_cpp.write("""DOM_PROTOTYPES_END()

void
DOM_Runtime::PreparePrototypeL(ES_Object *object, Prototype type)
{
\tswitch (type)
\t{
""")

    for group in groups:
        domprototypes_cpp.writelines(group.getLines("domprototypes.cpp-prepare-prototype"))

    domprototypes_cpp.write("""\tdefault:
\t\tstatic_cast<void>(object);
\t\t/* No preparation necessary. */
\t\treturn;
\t}
}
""")

    domprototypes_cpp.close()

    domglobaldata = File("modules/dom/src/domglobaldata.inc")
    domglobaldata.write("""/* -*- Mode: c++; indent-tabs-mode: t; tab-width: 4 -*- */

    """)

    written = set()
    for group in groups:
        for line in group.getLines("domglobaldata"):
            if line not in written:
                domglobaldata.write(line)
                if line.strip() and not line.startswith("#"):
                    written.add(line)

    domglobaldata.close()

    if outputRoot == sourceRoot:
        util.updateModuleGenerated(os.path.join(sourceRoot, "modules", "dom"),
                                   ["src/domruntime.h.inc",
                                    "src/domruntime.cpp.inc",
                                    "src/domprototypes.cpp.inc",
                                    "src/domglobaldata.inc"])

    if domruntime_h.updated() or domruntime_cpp.updated() or domprototypes_cpp.updated() or domglobaldata.updated():
        return 2
    else:
        return 0
Exemplo n.º 19
0
def generatePchFiles(sourceRoot, outputRoot, platform_product_config=None, pch_template=None):
    """
    Generates from modules/hardcore/base/pch_template.h the header
    files core/pch.h, core/pch_jumbo.h, core/pch_system_includes.h
    @param sourceRoot is the path to the Opera source tree.
    @param outputRoot is the output directory in which to generate the
      header files. If outputRoot is None, the header files are
      generated relative to the specified sourceRoot.
    @param platform_product_config is the platform's config file
      that #defines the PRODUCT_* macros. That file is included by the
      generated pch header files. If no config file is specified, an
      #error statement is generated to indicate that these macros are
      needed on compiling the sources.
    @param pch_template is the template file
      that should be used when generating pch files
    @return True if any of the generated files was updated and False
      if none of the files were changed.
    """

    class CreatePchFromTemplate:
        """
        Creates a core/pch...h file frome the template file
        modules/hardcore/base/pch_template.h.
        """
        def __init__(self, filename, platform_product_config=None):
            """
            @param filename is the name of the header file to
              create. This name is used to generate the
              #ifndef...#define...#endif statements.
            @param platform_product_config is the path to the
              platform's config file which #defines the PRODUCT_*
              macros. If no config file is specified, an #error
              statement is generated to indicate that these macros are
              needed on compiling the sources.
            """
            self.__define = "_CORE_%s_" % filename.replace('.', '_').upper()
            self.__platform_product_config = platform_product_config
            if filename == "pch_system_includes.h":
                # only core/pch_system_includes.h should add a
                # #define ALLOW_SYSTEM_INCLUDES
                self.__allow_system_includes = True
            else:
                self.__allow_system_includes = False

        def __call__(self, action, output):
            if action == "ifndef file_h":
                output.write("#ifndef %s\n" % self.__define)
                return True

            elif action == "define file_h":
                output.write("#define %s\n" % self.__define)
                return True

            elif action == "define ALLOW_SYSTEM_INCLUDES":
                if self.__allow_system_includes:
                    # enclose in ifndef, because sometimes it's defined globally
                    # (in Opera.vcxproj generated by vcxproj_update.py)
                    # and in this case redefinition gives a lot of compilation warnings
                    output.write("#ifndef ALLOW_SYSTEM_INCLUDES\n")
                    output.write("#define ALLOW_SYSTEM_INCLUDES\n")
                    output.write("#endif // ALLOW_SYSTEM_INCLUDES\n\n")
                return True

            elif action == "endif file_h":
                output.write("#endif // %s\n" % self.__define)
                return True

            elif action == "include platform config":
                if self.__platform_product_config:
                    output.write("#include \"%s\"\n" % self.__platform_product_config)
                else:
                    output.write("#ifdef PRODUCT_CONFIG_FILE\n")
                    output.write("// The platform may define a command line define PRODUCT_CONFIG_FILE:\n")
                    output.write("// 'PRODUCT_CONFIG_FILE=\"platforms/my_platform/product_config.h\"' which\n")
                    output.write("// defines a header file that is included here. The header file has the\n")
                    output.write("// possibility to define the PRODUCT_*_FILE macros e.g. like\n")
                    output.write("// #define PRODUCT_FEATURE_FILE \"platforms/my_platform/features.h\"\n")
                    output.write("// #define PRODUCT_SYSTEM_FILE \"platforms/my_platform/system.h\"\n")
                    output.write("// #define PRODUCT_OPKEY_FILE \"platforms/my_platform/opkey.h\"\n")
                    output.write("// #define PRODUCT_ACTIONS_FILE \"platforms/my_platform/actions.h\"\n")
                    output.write("// #define PRODUCT_TWEAKS_FILE \"platforms/my_platform/tweaks.h\"\n")
                    output.write("# include PRODUCT_CONFIG_FILE\n")
                    output.write("#endif // PRODUCT_CONFIG_FILE\n")
                return True

    changed = False
    hardcoreDir = os.path.join(sourceRoot, 'modules', 'hardcore')
    if not pch_template:
        baseDir = os.path.join(hardcoreDir, 'base')
        pch_template = os.path.join(baseDir, 'pch_template.h')
    elif not os.path.isabs(pch_template):
        pch_template = os.path.join(sourceRoot, pch_template)
    if not os.path.exists(pch_template):
        raise IOError(errno.ENOENT, "Template file '%s' (passed with --pch_template) not found" % pch_template)
    for pch in ('pch.h', 'pch_jumbo.h', 'pch_system_includes.h'):
        changed = util.readTemplate(
            pch_template, os.path.join(outputRoot, 'core', pch),
            CreatePchFromTemplate(pch, platform_product_config)) or changed

    # if the pch files are generated relative to the modules/hardcore
    # dir, update hardcore's module.generated:
    match = re.match("^%s(.*)$" % re.escape(hardcoreDir+os.sep), outputRoot)
    if match:
        base = match.group(1).replace(os.sep, '/')
        util.updateModuleGenerated(os.path.join(sourceRoot, 'modules', 'hardcore'),
                                   map(lambda h: '/'.join([base, 'core', h]),
                                       ['pch.h', 'pch_jumbo.h',
                                        'pch_system_includes.h']))
    return changed
Exemplo n.º 20
0
    def __call__(self, sourceRoot, feature_def, outputRoot=None, quiet=True):
        """
        Generates the following files in the specified output root:
        - modules/hardcore/features/features.h
        - modules/hardcore/features/features-thirdparty_attributions.inl
        - modules/hardcore/features/profile_{profile}.h for all profiles
        Generates the following files in the specified source root:
        - modules/hardcore/opera/setupinfo_features.cpp
        - modules/hardcore/documentation/features.{core_version}.xml for
          the core_version as given by the specified feature_def.

        @param sourceRoot is the path to the Opera source tree

        @param feature_def specifies a loaded instance of the class
          util.FeatureDefinition

        @param outputRoot is the path in which to generate the output files
          modules/hardcore/features/features.h
          modules/hardcore/features/profile_{profile}.h
          If this argument is None, then
          {sourceRoot}/modules/hardcore/features/ is used.
        """
        self.startTiming()
        if feature_def is None or not feature_def.isLoaded():
            error("the argument feature_def must be a loaded util.FeatureDefinition instance")
            result = 1
        else:
            hardcoreDir = os.path.join(sourceRoot, 'modules', 'hardcore')
            featuresDir = os.path.join(hardcoreDir, 'features')
            if outputRoot is None:
                targetDir = featuresDir
            else:
                targetDir = os.path.join(outputRoot, 'modules', 'hardcore', 'features')

            changed = util.makedirs(targetDir)

            # TODO: instead of creating a copy of "features.h" for each
            # profile in
            # opera/profiles/{profile}.[next]/include/modules/hardcore/features/
            # with the same content, try to find a place for that include file
            # which only depends on "current" or "next" mainline-configuration:
            changed = util.readTemplate(
                os.path.join(featuresDir, 'features_template.h'),
                os.path.join(targetDir, 'features.h'),
                HandleTemplateAction(feature_def)) or changed

            changed = util.readTemplate(os.path.join(featuresDir, 'features-thirdparty_attributions_template.inl'),
                                        os.path.join(targetDir, 'features-thirdparty_attributions.inl'),
                                        LegalTemplateActionHandler(feature_def)) or changed

            # TODO: instead of creating profile_XXX.h for all profiles XXX in
            # opera/profile/{profile}.[next]/include/modules/hardcore/features/,
            # only create profile_{profile}.h for the one profile that is
            # needed:
            for profile in util.PROFILES:
                changed = util.readTemplate(
                    os.path.join(featuresDir, 'profile_template.h'),
                    os.path.join(targetDir, 'profile_%s.h' % profile),
                    ProfileTemplateActionHandler(profile, feature_def.featuresWithDefault())) or changed
            if targetDir == featuresDir:
                util.updateModuleGenerated(hardcoreDir,
                                           ['features/features.h',
                                            'features/features-thirdparty_attributions.inl'] +
                                           ['features/profile_%s.h' % profile for profile in util.PROFILES])

            # Ignore changes in setupinfo_features.cpp and documentation files:
            setupinfoDir = os.path.join(hardcoreDir, 'opera')
            documentationDir = os.path.join(hardcoreDir, 'documentation')
            if outputRoot is None:
                setupinfoOutputDir = setupInfoDir
                documentationOutputDir = documentationDir
            else:
                setupinfoOutputDir = os.path.join(outputRoot, 'modules', 'hardcore', 'opera')
                documentationOutputDir = os.path.join(outputRoot, 'modules', 'hardcore', 'documentation')
            # TODO: create a different output file
            # setupinfo_features.{core_version}.cpp for different
            # core-versions - note: this is only required if new features are
            # added or the documentation of a feature is changed.
            util.readTemplate(
                os.path.join(setupinfoDir, 'setupinfo_features_template.cpp'),
                os.path.join(setupinfoOutputDir, 'setupinfo_features_generated.inl'),
                HandleTemplateAction(feature_def),
                hardcoreDir if setupinfoDir == setupinfoOutputDir else None,
                'opera/setupinfo_features.cpp')
            if feature_def.coreVersion() is None:
                features_xml = 'features.xml'
            else: features_xml = 'features.%s.xml' % feature_def.coreVersion()
            util.readTemplate(
                os.path.join(featuresDir, 'features_template.xml'),
                os.path.join(documentationOutputDir, features_xml),
                HandleTemplateAction(feature_def),
                hardcoreDir if documentationDir == documentationOutputDir else None,
                'documentation/%s' % features_xml)

            if changed: result = 2
            else: result = 0
        return self.endTiming(result, sourceRoot=sourceRoot, outputRoot=outputRoot, quiet=quiet)