bin/synchb.py
changeset 0 16d8024aca5e
child 3 11d3954df52a
equal deleted inserted replaced
-1:000000000000 0:16d8024aca5e
       
     1 #!/usr/bin/env python
       
     2 # -*- coding: utf-8 -*-
       
     3 #
       
     4 #############################################################################
       
     5 ##
       
     6 ## Copyright (C) 2008-2010 Nokia Corporation and/or its subsidiary(-ies).
       
     7 ## All rights reserved.
       
     8 ## Contact: Nokia Corporation (developer.feedback@nokia.com)
       
     9 ##
       
    10 ## This file is part of the UI Extensions for Mobile.
       
    11 ##
       
    12 ## GNU Lesser General Public License Usage
       
    13 ## This file may be used under the terms of the GNU Lesser General Public
       
    14 ## License version 2.1 as published by the Free Software Foundation and
       
    15 ## appearing in the file LICENSE.LGPL included in the packaging of this file.
       
    16 ## Please review the following information to ensure the GNU Lesser General
       
    17 ## Public License version 2.1 requirements will be met:
       
    18 ## http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    19 ##
       
    20 ## In addition, as a special exception, Nokia gives you certain additional
       
    21 ## rights.  These rights are described in the Nokia Qt LGPL Exception
       
    22 ## version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    23 ##
       
    24 ## If you have questions regarding the use of this file, please contact
       
    25 ## Nokia at developer.feedback@nokia.com.
       
    26 ##
       
    27 #############################################################################
       
    28 
       
    29 import os
       
    30 import re
       
    31 import sys
       
    32 import shutil
       
    33 import optparse
       
    34 
       
    35 # ============================================================================
       
    36 # Globals
       
    37 # ============================================================================
       
    38 VERBOSE = False
       
    39 EXCLUDE = ["hbplugins", "hbservers", "3rdparty", "internal", "tsrc", "debug", "release"]
       
    40 COLLECTIONS = {"hbcore": "HbCore",
       
    41                "hbfeedback": "HbFeedback",
       
    42                "hbinput": "HbInput",
       
    43                "hbutils": "HbUtils",
       
    44                "hbwidgets": "HbWidgets"}
       
    45 
       
    46 # ============================================================================
       
    47 # OptionParser
       
    48 # ============================================================================
       
    49 class OptionParser(optparse.OptionParser):
       
    50     def __init__(self):
       
    51         optparse.OptionParser.__init__(self)
       
    52         self.add_option("-v", "--verbose", action="store_true", dest="verbose",
       
    53                         help="print verbose information about each step of the sync process")
       
    54 
       
    55         group = optparse.OptionGroup(self, "Input/output options")
       
    56         self.add_option("-i", "--input", dest="inputdir", metavar="dir",
       
    57                         help="specify the input <dir>")
       
    58         self.add_option("-o", "--output", dest="outputdir", metavar="dir",
       
    59                         help="specify the output <dir>")
       
    60         self.add_option_group(group)
       
    61 
       
    62         self.set_defaults(verbose=VERBOSE)
       
    63 
       
    64 # ============================================================================
       
    65 # Utils
       
    66 # ============================================================================
       
    67 if not hasattr(os.path, "relpath"):
       
    68     def relpath(path, start=os.curdir):
       
    69         return path
       
    70     os.path.relpath = relpath
       
    71 
       
    72 def read_file(filepath):
       
    73     content = ""
       
    74     try:
       
    75         file = open(filepath, "r")
       
    76         content = file.read()
       
    77         file.close()
       
    78     except IOError, e:
       
    79         print(e)
       
    80     return content
       
    81 
       
    82 def write_file(filepath, content):
       
    83     try:
       
    84         file = open(filepath, "w")
       
    85         file.write(content)
       
    86         file.close()
       
    87     except IOError, e:
       
    88         print(e)
       
    89 
       
    90 def write_header(filepath, include):
       
    91     write_file(filepath, "#include \"%s\"\n" % include)
       
    92 
       
    93 # ============================================================================
       
    94 # Component
       
    95 # ============================================================================
       
    96 class Component:
       
    97     def __init__(self, name):
       
    98         self.name = name
       
    99         self.headers = list()
       
   100         self.privates = list()
       
   101 
       
   102     def read(self, path):
       
   103         entries = os.listdir(path)
       
   104         for entry in entries:
       
   105             entrypath = os.path.join(path, entry)
       
   106             if os.path.isdir(entrypath):
       
   107                 self.read(entrypath)
       
   108             elif os.path.isfile(entrypath):
       
   109                 if entry.endswith("_p_p.h"):
       
   110                     continue
       
   111                 elif entry.endswith("_p.h"):
       
   112                     self.privates.append(entrypath)
       
   113                 elif entry.endswith(".h"):
       
   114                     self.headers.append(entrypath)
       
   115 
       
   116     def write(self, path):
       
   117         if len(self.headers) > 0:
       
   118             self._makedirs(path)
       
   119             self._write(path, self.headers, True)
       
   120 
       
   121         if len(self.privates) > 0:
       
   122             privpath = os.path.join(path, "private")
       
   123             self._makedirs(privpath)
       
   124             self._write(privpath, self.privates, False)
       
   125 
       
   126     def _write(self, path, headers, convenience):
       
   127         global VERBOSE
       
   128         if VERBOSE:
       
   129             print("INFO: Writing headers to '%s'" % path)
       
   130         for header in headers:
       
   131             filename = os.path.basename(header)
       
   132             filepath = os.path.join(path, filename)
       
   133             relpath = os.path.relpath(header, path)
       
   134             if VERBOSE:
       
   135                 print("INFO:\t ==> %s" % os.path.basename(filepath))
       
   136             write_header(filepath, relpath.replace("\\", "/"))
       
   137             if convenience:
       
   138                 classes = list()
       
   139                 content = read_file(header)
       
   140                 for match in re.finditer("(?:class|namespace)\s+(?:HB_[^_]+_EXPORT\s+)?(Hb\w*)(\s*;)?", content):
       
   141                     if not match.group(2):
       
   142                         classes.append(match.group(1))
       
   143                 for match in re.finditer("#pragma hb_header\((\w+)\)", content):
       
   144                     classes.append(match.group(1))
       
   145                 for cls in classes:
       
   146                     filepath = os.path.join(path, cls)
       
   147                     write_header(filepath, filename)
       
   148 
       
   149     def _makedirs(self, path):
       
   150         global VERBOSE
       
   151         if not os.path.exists(path):
       
   152             if VERBOSE:
       
   153                 print("INFO: Creating include dir '%s'" % path)
       
   154             os.makedirs(path)
       
   155 
       
   156 # ============================================================================
       
   157 # Collection
       
   158 # ============================================================================
       
   159 class Collection:
       
   160     def __init__(self, name):
       
   161         self.name = name
       
   162         self.components = []
       
   163 
       
   164     def read(self, path):
       
   165         global EXCLUDE
       
   166         for entry in os.listdir(path):
       
   167             entrypath = os.path.join(path, entry)
       
   168             if not entry in EXCLUDE and os.path.isdir(entrypath):
       
   169                 component = Component(entry)
       
   170                 component.read(entrypath)
       
   171                 self.components.append(component)
       
   172 
       
   173     def write(self, path):
       
   174         global COLLECTIONS
       
   175         # include/hbcore
       
   176         includes = list()
       
   177         path = os.path.join(path, self.name)
       
   178         for component in self.components:
       
   179             component.write(path)
       
   180             for header in component.headers:
       
   181                 includes.append("#include \"%s\"\n" % os.path.basename(header))
       
   182         if self.name in COLLECTIONS:
       
   183             write_file(os.path.join(path, self.name + ".h"), "".join(includes))
       
   184             write_header(os.path.join(path, COLLECTIONS[self.name]), self.name + ".h")
       
   185 
       
   186 # ============================================================================
       
   187 # Package
       
   188 # ============================================================================
       
   189 class Package:
       
   190     def __init__(self, name):
       
   191         self.path = name
       
   192         self.collections = list()
       
   193 
       
   194     def read(self, path):
       
   195         global EXCLUDE
       
   196         for entry in os.listdir(path):
       
   197             # hbcore, hbwidgets, hbutils...
       
   198             entrypath = os.path.join(path, entry)
       
   199             if not entry in EXCLUDE and os.path.isdir(entrypath):
       
   200                 collection = Collection(entry)
       
   201                 collection.read(entrypath)
       
   202                 self.collections.append(collection)
       
   203 
       
   204     def write(self, path):
       
   205         for collection in self.collections:
       
   206             collection.write(path)
       
   207 
       
   208 # ============================================================================
       
   209 # main()
       
   210 # ============================================================================
       
   211 def main():
       
   212     global VERBOSE
       
   213 
       
   214     parser = OptionParser()
       
   215     (options, args) = parser.parse_args()
       
   216 
       
   217     VERBOSE = options.verbose
       
   218 
       
   219     if not options.inputdir:
       
   220         options.inputdir = os.path.abspath(sys.path[0])
       
   221     if os.path.basename(os.path.normpath(options.inputdir)) == "bin":
       
   222         options.inputdir = os.path.normpath(os.path.join(options.inputdir, os.pardir))
       
   223     if not os.path.basename(os.path.normpath(options.inputdir)) == "src":
       
   224         options.inputdir = os.path.join(options.inputdir, "src")
       
   225 
       
   226     if not options.outputdir:
       
   227         options.outputdir = os.getcwd()
       
   228     if not os.path.basename(os.path.normpath(options.outputdir)) == "include":
       
   229         options.outputdir = os.path.join(options.outputdir, "include")
       
   230 
       
   231     if os.path.exists(options.outputdir):
       
   232         if VERBOSE:
       
   233             print("INFO: Removing include dir '%s'" % options.outputdir)
       
   234         shutil.rmtree(options.outputdir, ignore_errors=True)
       
   235 
       
   236     package = Package("hb")
       
   237     package.read(options.inputdir)
       
   238     package.write(options.outputdir)
       
   239 
       
   240 if __name__ == "__main__":
       
   241     main()