[ooo-build-commit] .: 2 commits - bin/parse-scp2.py

Kohei Yoshida kohei at kemper.freedesktop.org
Thu Jul 15 18:17:49 PDT 2010


 bin/parse-scp2.py |  247 ++++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 240 insertions(+), 7 deletions(-)

New commits:
commit c155b5d92cda35b703afd3c29491fb8b035231f6
Author: Kohei Yoshida <kyoshida at novell.com>
Date:   Thu Jul 15 21:16:28 2010 -0400

    Print structured installation info for all top modules.
    
    Top modules are defined in setup_native/source/packinfo/packinfo_office.txt.
    
    * bin/parse-scp2.py:

diff --git a/bin/parse-scp2.py b/bin/parse-scp2.py
index 78b9e29..aad491d 100755
--- a/bin/parse-scp2.py
+++ b/bin/parse-scp2.py
@@ -7,6 +7,73 @@ arg_desc = ""
 desc = """
 Run this script at the root of OOo source tree."""
 
+top_modules = [
+    'gid_Module_Optional_Gnome',
+    'gid_Module_Optional_Kde',
+    'gid_Module_Root',
+    'gid_Module_Prg_Wrt_Bin',
+    'gid_Module_Prg_Calc_Bin',
+    'gid_Module_Prg_Draw_Bin',
+    'gid_Module_Prg_Impress_Bin',
+    'gid_Module_Prg_Base_Bin',
+    'gid_Module_Prg_Math_Bin',
+    'gid_Module_Optional_Binfilter',
+    'gid_Module_Optional_Grfflt',
+    'gid_Module_Oooimprovement',
+    'gid_Module_Optional_Testtool',
+    'gid_Module_Optional_Oo_English',
+    'gid_Module_Optional_Xsltfiltersamples',
+    'gid_Module_Optional_Javafilter',
+    'gid_Module_Optional_Activexcontrol',
+    'gid_Module_Optional_Onlineupdate',
+    'gid_Module_Optional_Pyuno',
+    'gid_Module_Optional_Pymailmerge',
+    'gid_Module_Optional_Headless',
+    'gid_Module_Root_Files_Images',
+    'gid_Module_Root_Fonts_OOo_Hidden',
+    'gid_Module_Oo_Linguistic',
+    'gid_Module_Root_Files_2',
+    'gid_Module_Root_Files_3',
+    'gid_Module_Root_Files_4',
+    'gid_Module_Root_Files_5',
+    'gid_Module_Root_Files_6',
+    'gid_Module_Root_Files_7',
+    'gid_Module_Root_Extension_Oooimprovement',
+    'gid_Module_Root_Extension_Dictionary_Af',
+    'gid_Module_Root_Extension_Dictionary_Ca',
+    'gid_Module_Root_Extension_Dictionary_Cs',
+    'gid_Module_Root_Extension_Dictionary_Da',
+    'gid_Module_Root_Extension_Dictionary_De_AT',
+    'gid_Module_Root_Extension_Dictionary_De_CH',
+    'gid_Module_Root_Extension_Dictionary_De_DE',
+    'gid_Module_Root_Extension_Dictionary_En',
+    'gid_Module_Root_Extension_Dictionary_Es',
+    'gid_Module_Root_Extension_Dictionary_Et',
+    'gid_Module_Root_Extension_Dictionary_Fr',
+    'gid_Module_Root_Extension_Dictionary_Gl',
+    'gid_Module_Root_Extension_Dictionary_He',
+    'gid_Module_Root_Extension_Dictionary_Hu',
+    'gid_Module_Root_Extension_Dictionary_It',
+    'gid_Module_Root_Extension_Dictionary_Ku_Tr',
+    'gid_Module_Root_Extension_Dictionary_Lt',
+    'gid_Module_Root_Extension_Dictionary_Ne',
+    'gid_Module_Root_Extension_Dictionary_Nl',
+    'gid_Module_Root_Extension_Dictionary_No',
+    'gid_Module_Root_Extension_Dictionary_Pl',
+    'gid_Module_Root_Extension_Dictionary_Pt',
+    'gid_Module_Root_Extension_Dictionary_Ro',
+    'gid_Module_Root_Extension_Dictionary_Ru',
+    'gid_Module_Root_Extension_Dictionary_Sk',
+    'gid_Module_Root_Extension_Dictionary_Sl',
+    'gid_Module_Root_Extension_Dictionary_Sr',
+    'gid_Module_Root_Extension_Dictionary_Sv',
+    'gid_Module_Root_Extension_Dictionary_Sw',
+    'gid_Module_Root_Extension_Dictionary_Th',
+    'gid_Module_Root_Extension_Dictionary_Vi',
+    'gid_Module_Root_Extension_Dictionary_Zu',
+    'gid_Module_Optional_OGLTrans'
+]
+
 def error (msg):
     sys.stderr.write(msg + "\n")
 
@@ -28,6 +95,10 @@ class DirError(ErrorBase):
     def __init__ (self, msg):
         ErrorBase.__init__(self, "DirError", msg, 0)
 
+class ModuleError(ErrorBase):
+    def __init__ (self, msg):
+        ErrorBase.__init__(self, "ModuleError", msg, 0)
+
 class LinkedNode(object):
     def __init__ (self, name):
         self.name = name
@@ -283,9 +354,10 @@ class Scp2Processor(object):
         'scp2/source/ooo/starregistry_ooo.scp': True
     }
 
-    def __init__ (self, cur_dir, mod_output_dir):
+    def __init__ (self, cur_dir, mod_output_dir, vars):
         self.cur_dir = cur_dir
         self.mod_output_dir = mod_output_dir
+        self.vars = vars
         self.scp_files = []
         self.nodedata = {}
         self.nodetree = {}
@@ -360,12 +432,15 @@ class Scp2Processor(object):
             attr_names.sort()
             for attr_name in attr_names:
                 if attr_name in ['__node_type__', '__node_location__', '__node_values__']:
-                    # Skip special attribute.
+                    # Skip special attributes.
                     continue
                 print ("  %s = %s"%(attr_name, attrs[attr_name]))
 
-    def print_summary_tree (self):
-        root = 'gid_Module_Root'
+    def print_summary_tree (self, root):
+
+        if not self.nodetree.has_key(root):
+            raise ModuleError("module %s not found."%root)
+
         node = self.nodetree[root]
         self.__print_summary_tree_node(node, 0)
 
@@ -411,6 +486,23 @@ class Scp2Processor(object):
 
         return filename
 
+    def __resolve_vars (self, s):
+
+        while True:
+            start = s.find('${')
+            if start == -1:
+                break
+    
+            end = s.find('}', start+2)
+            if end == -1:
+                break
+    
+            key = s[start+2:end]
+            if self.vars.has_key(key):
+                s = s[:start] + self.vars[key] + s[end+1:]
+    
+        return s
+
     def __print_summary_tree_node (self, node, level):
 
         indent = '    '*level
@@ -433,6 +525,7 @@ class Scp2Processor(object):
         if node_type in ['File', 'Unixlink', 'Shortcut']:
             try:
                 name = self.__get_fullpath(node.name)
+                name = self.__resolve_vars(name)
             except DirError as e:
                 error(e.value)
                 return
@@ -441,7 +534,9 @@ class Scp2Processor(object):
         if len(name) > 0:
             s += " name=\"%s\""%name
         if node_type == 'Unixlink':
-            s += " target=\"%s\""%nodedata['Target']
+            target = nodedata['Target']
+            target = self.__resolve_vars(target)
+            s += " target=\"%s\""%target
 
         if len(node.children) > 0:
             s += ">"
@@ -491,6 +586,13 @@ class OOLstParser(object):
 
         return s
 
+    def get_vars (self, scopes):
+        vars = {}
+        for scope in scopes:
+            for key in self.vars[scope].keys():
+                vars[key] = self.vars[scope][key]
+        return vars
+
     def parse_openoffice_lst (self, lines):
     
         class _Error(ParseError):
@@ -595,13 +697,23 @@ if __name__ == '__main__':
         if e.sev > 0:
             sys.exit(1)
 
-    vars = oolst_parser.vars
+    # For now, just pull variables from these two namespaces.
+    scopes_to_use = ['Globals::Settings::variables', 'OpenOffice::Settings::variables']
+    vars = oolst_parser.get_vars(scopes_to_use)
+    if vars.has_key('PRODUCTNAME'):
+        # Special variable
+        vars['UNIXPRODUCTNAME'] = vars['PRODUCTNAME'].lower()
 
     try:
-        processor = Scp2Processor(cur_dir, options.mod_output_dir)
+        processor = Scp2Processor(cur_dir, options.mod_output_dir, vars)
         processor.run()
         if options.mode == 'tree':
-            processor.print_summary_tree()
+            for module in top_modules:
+                try:
+                    processor.print_summary_tree(module)
+                except ModuleError as e:
+                    error(e.value)
+
         elif options.mode == 'flat':
             processor.print_summary_flat()
         else:
commit 68e9bc23f8142e06997929a5dd53b525f970a386
Author: Kohei Yoshida <kyoshida at novell.com>
Date:   Thu Jul 15 15:05:59 2010 -0400

    Parse openoffice.lst and build a list of variables used in scp files.
    
    * bin/parse-scp2.py:

diff --git a/bin/parse-scp2.py b/bin/parse-scp2.py
index 0632c10..78b9e29 100755
--- a/bin/parse-scp2.py
+++ b/bin/parse-scp2.py
@@ -34,6 +34,8 @@ class LinkedNode(object):
         self.parent = None
         self.children = []
 
+# ----------------------------------------------------------------------------
+
 class Scp2Tokenizer(object):
 
     def __init__ (self, content):
@@ -73,6 +75,8 @@ class Scp2Tokenizer(object):
                 self.buf += c
             i += 1
 
+# ----------------------------------------------------------------------------
+
 # Parse each .scp file.
 class Scp2Parser(object):
 
@@ -265,6 +269,7 @@ class Scp2Parser(object):
 
         return name, attrs, values
 
+# ----------------------------------------------------------------------------
 
 # Collect all .scp files in scp2 directory, and run preprocessor.
 class Scp2Processor(object):
@@ -460,6 +465,103 @@ class Scp2Processor(object):
             if os.path.splitext(filepath)[1] == '.scp':
                 instance.scp_files.append(filepath)
 
+# ----------------------------------------------------------------------------
+
+class OOLstParser(object):
+
+    def __init__ (self):
+        self.vars = {}
+
+    def __repr__ (self):
+        s = ''
+        scope_names = self.vars.keys()
+        scope_names.sort()
+        for scope in scope_names:
+            s += "%s\n"%scope
+            attrs = self.vars[scope]
+            keys = attrs.keys()
+            keys.sort()
+            for key in keys:
+                s += "    %s"%key
+                if attrs[key] != None:
+                    s += " = %s"%attrs[key]
+                else:
+                    s += " ="
+                s += "\n"
+
+        return s
+
+    def parse_openoffice_lst (self, lines):
+    
+        class _Error(ParseError):
+            def __init__ (self, msg, sev=0):
+                ParseError.__init__(self, "(openoffice.lst) " + msg, sev)
+    
+        self.ns = [] # namespace stack
+        n = len(lines)
+        self.last = None
+        for i in xrange(0, n):
+            words = lines[i].split()
+            if len(words) == 0:
+                # empty line
+                continue
+    
+            if words[0] == '{':
+                # new scope begins
+                if len(words) != 1:
+                    raise _Error("{ is followed by a token.", 1)
+                if self.last == None:
+                    raise _Error("fail to find a namespace token in the previous line.", 1)
+                if len(self.last) != 1:
+                    raise _Error("line contains multiple tokens when only one token is expected.", 1)
+                t = self.last[0]
+                self.ns.append(t)
+    
+            elif words[0] == '}':
+                # current scope ends
+                self.__check_last_line()
+
+                if len(words) != 1:
+                    raise _Error("} is followed by a token.", 1)
+                self.ns.pop()
+    
+            else:
+                # check the last line
+                self.__check_last_line()
+    
+            self.last = words
+
+    def __check_last_line (self):
+        if self.last == None or len(self.last) == 0:
+            return
+
+        if self.last[0] in '{}':
+            return
+
+        key = self.last[0]
+        val = None
+        if len(self.last) > 1:
+            sep = ' '
+            val = sep.join(self.last[1:])
+        self.__insert_attr(self.ns, key, val)
+
+
+    def __insert_attr (self, ns, key, val):
+        ns_str = '' # aggregate namespaces, separated by '::'s.
+        for name in ns:
+            if len(ns_str) == 0:
+                ns_str = name
+            else:
+                ns_str += '::' + name
+
+        if not self.vars.has_key(ns_str):
+            # Create this namespace entry.
+            self.vars[ns_str] = {}
+        self.vars[ns_str][key] = val
+
+
+# ----------------------------------------------------------------------------
+
 if __name__ == '__main__':
 
     parser = optparse.OptionParser()
@@ -468,6 +570,8 @@ if __name__ == '__main__':
         help="Specify the name of module output directory.  The default value is 'unxlngi6.pro'.")
     parser.add_option("-m", "--output-mode", dest="mode", default='tree', metavar="MODE",
         help="Specify output mode.  Allowed values are 'tree' and 'flat.  The default mode is 'tree'.")
+    parser.add_option("", "--openoffice-lst", dest="openoffice_lst", default="instsetoo_native/util/openoffice.lst", metavar="FILE",
+        help="Specify the location of openoffice.lst file which contains variables used by the scp files.  The default value is 'instsetoo_native/util/openoffice.lst'.")
 
     options, args = parser.parse_args()
 
@@ -476,6 +580,23 @@ if __name__ == '__main__':
         sys.exit(1)
 
     cur_dir = os.getcwd()
+    oo_lst_path = cur_dir + '/' + options.openoffice_lst
+    if not os.path.isfile(oo_lst_path):
+        error("failed to find the openoffice.lst file at (%s)."%oo_lst_path)
+        sys.exit(1)
+
+    oolst_parser = OOLstParser()
+    try:
+        file = open(oo_lst_path, 'r')
+        oolst_parser.parse_openoffice_lst(file.readlines())
+        file.close()
+    except ParseError as e:
+        error(e.value)
+        if e.sev > 0:
+            sys.exit(1)
+
+    vars = oolst_parser.vars
+
     try:
         processor = Scp2Processor(cur_dir, options.mod_output_dir)
         processor.run()


More information about the ooo-build-commit mailing list