--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/bin/synchb.py Mon Apr 19 14:02:13 2010 +0300
@@ -0,0 +1,241 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+#############################################################################
+##
+## Copyright (C) 2008-2010 Nokia Corporation and/or its subsidiary(-ies).
+## All rights reserved.
+## Contact: Nokia Corporation (developer.feedback@nokia.com)
+##
+## This file is part of the UI Extensions for Mobile.
+##
+## GNU Lesser General Public License Usage
+## This file may be used under the terms of the GNU Lesser General Public
+## License version 2.1 as published by the Free Software Foundation and
+## appearing in the file LICENSE.LGPL included in the packaging of this file.
+## Please review the following information to ensure the GNU Lesser General
+## Public License version 2.1 requirements will be met:
+## http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+##
+## In addition, as a special exception, Nokia gives you certain additional
+## rights. These rights are described in the Nokia Qt LGPL Exception
+## version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+##
+## If you have questions regarding the use of this file, please contact
+## Nokia at developer.feedback@nokia.com.
+##
+#############################################################################
+
+import os
+import re
+import sys
+import shutil
+import optparse
+
+# ============================================================================
+# Globals
+# ============================================================================
+VERBOSE = False
+EXCLUDE = ["hbplugins", "hbservers", "3rdparty", "internal", "tsrc", "debug", "release"]
+COLLECTIONS = {"hbcore": "HbCore",
+ "hbfeedback": "HbFeedback",
+ "hbinput": "HbInput",
+ "hbutils": "HbUtils",
+ "hbwidgets": "HbWidgets"}
+
+# ============================================================================
+# OptionParser
+# ============================================================================
+class OptionParser(optparse.OptionParser):
+ def __init__(self):
+ optparse.OptionParser.__init__(self)
+ self.add_option("-v", "--verbose", action="store_true", dest="verbose",
+ help="print verbose information about each step of the sync process")
+
+ group = optparse.OptionGroup(self, "Input/output options")
+ self.add_option("-i", "--input", dest="inputdir", metavar="dir",
+ help="specify the input <dir>")
+ self.add_option("-o", "--output", dest="outputdir", metavar="dir",
+ help="specify the output <dir>")
+ self.add_option_group(group)
+
+ self.set_defaults(verbose=VERBOSE)
+
+# ============================================================================
+# Utils
+# ============================================================================
+if not hasattr(os.path, "relpath"):
+ def relpath(path, start=os.curdir):
+ return path
+ os.path.relpath = relpath
+
+def read_file(filepath):
+ content = ""
+ try:
+ file = open(filepath, "r")
+ content = file.read()
+ file.close()
+ except IOError, e:
+ print(e)
+ return content
+
+def write_file(filepath, content):
+ try:
+ file = open(filepath, "w")
+ file.write(content)
+ file.close()
+ except IOError, e:
+ print(e)
+
+def write_header(filepath, include):
+ write_file(filepath, "#include \"%s\"\n" % include)
+
+# ============================================================================
+# Component
+# ============================================================================
+class Component:
+ def __init__(self, name):
+ self.name = name
+ self.headers = list()
+ self.privates = list()
+
+ def read(self, path):
+ entries = os.listdir(path)
+ for entry in entries:
+ entrypath = os.path.join(path, entry)
+ if os.path.isdir(entrypath):
+ self.read(entrypath)
+ elif os.path.isfile(entrypath):
+ if entry.endswith("_p_p.h"):
+ continue
+ elif entry.endswith("_p.h"):
+ self.privates.append(entrypath)
+ elif entry.endswith(".h"):
+ self.headers.append(entrypath)
+
+ def write(self, path):
+ if len(self.headers) > 0:
+ self._makedirs(path)
+ self._write(path, self.headers, True)
+
+ if len(self.privates) > 0:
+ privpath = os.path.join(path, "private")
+ self._makedirs(privpath)
+ self._write(privpath, self.privates, False)
+
+ def _write(self, path, headers, convenience):
+ global VERBOSE
+ if VERBOSE:
+ print("INFO: Writing headers to '%s'" % path)
+ for header in headers:
+ filename = os.path.basename(header)
+ filepath = os.path.join(path, filename)
+ relpath = os.path.relpath(header, path)
+ if VERBOSE:
+ print("INFO:\t ==> %s" % os.path.basename(filepath))
+ write_header(filepath, relpath.replace("\\", "/"))
+ if convenience:
+ classes = list()
+ content = read_file(header)
+ for match in re.finditer("(?:class|namespace)\s+(?:HB_[^_]+_EXPORT\s+)?(Hb\w*)(\s*;)?", content):
+ if not match.group(2):
+ classes.append(match.group(1))
+ for match in re.finditer("#pragma hb_header\((\w+)\)", content):
+ classes.append(match.group(1))
+ for cls in classes:
+ filepath = os.path.join(path, cls)
+ write_header(filepath, filename)
+
+ def _makedirs(self, path):
+ global VERBOSE
+ if not os.path.exists(path):
+ if VERBOSE:
+ print("INFO: Creating include dir '%s'" % path)
+ os.makedirs(path)
+
+# ============================================================================
+# Collection
+# ============================================================================
+class Collection:
+ def __init__(self, name):
+ self.name = name
+ self.components = []
+
+ def read(self, path):
+ global EXCLUDE
+ for entry in os.listdir(path):
+ entrypath = os.path.join(path, entry)
+ if not entry in EXCLUDE and os.path.isdir(entrypath):
+ component = Component(entry)
+ component.read(entrypath)
+ self.components.append(component)
+
+ def write(self, path):
+ global COLLECTIONS
+ # include/hbcore
+ includes = list()
+ path = os.path.join(path, self.name)
+ for component in self.components:
+ component.write(path)
+ for header in component.headers:
+ includes.append("#include \"%s\"\n" % os.path.basename(header))
+ if self.name in COLLECTIONS:
+ write_file(os.path.join(path, self.name + ".h"), "".join(includes))
+ write_header(os.path.join(path, COLLECTIONS[self.name]), self.name + ".h")
+
+# ============================================================================
+# Package
+# ============================================================================
+class Package:
+ def __init__(self, name):
+ self.path = name
+ self.collections = list()
+
+ def read(self, path):
+ global EXCLUDE
+ for entry in os.listdir(path):
+ # hbcore, hbwidgets, hbutils...
+ entrypath = os.path.join(path, entry)
+ if not entry in EXCLUDE and os.path.isdir(entrypath):
+ collection = Collection(entry)
+ collection.read(entrypath)
+ self.collections.append(collection)
+
+ def write(self, path):
+ for collection in self.collections:
+ collection.write(path)
+
+# ============================================================================
+# main()
+# ============================================================================
+def main():
+ global VERBOSE
+
+ parser = OptionParser()
+ (options, args) = parser.parse_args()
+
+ VERBOSE = options.verbose
+
+ if not options.inputdir:
+ options.inputdir = os.path.abspath(sys.path[0])
+ if os.path.basename(os.path.normpath(options.inputdir)) == "bin":
+ options.inputdir = os.path.normpath(os.path.join(options.inputdir, os.pardir))
+ if not os.path.basename(os.path.normpath(options.inputdir)) == "src":
+ options.inputdir = os.path.join(options.inputdir, "src")
+
+ if not options.outputdir:
+ options.outputdir = os.getcwd()
+ if not os.path.basename(os.path.normpath(options.outputdir)) == "include":
+ options.outputdir = os.path.join(options.outputdir, "include")
+
+ if os.path.exists(options.outputdir):
+ if VERBOSE:
+ print("INFO: Removing include dir '%s'" % options.outputdir)
+ shutil.rmtree(options.outputdir, ignore_errors=True)
+
+ package = Package("hb")
+ package.read(options.inputdir)
+ package.write(options.outputdir)
+
+if __name__ == "__main__":
+ main()