[ooo-build-commit] .: bin/parse-scp2.py
Kohei Yoshida
kohei at kemper.freedesktop.org
Wed Jul 14 12:51:18 PDT 2010
bin/parse-scp2.py | 202 ++++++++++++++++++++++++++++++++++++++++++++++++------
1 file changed, 183 insertions(+), 19 deletions(-)
New commits:
commit 4aaca1ff085c9b491b1bf28f17b52ab80c9f9d95
Author: Kohei Yoshida <kyoshida at novell.com>
Date: Wed Jul 14 15:49:55 2010 -0400
Print module structure and list of contained files in XML format.
* bin/parse-scp2.py:
diff --git a/bin/parse-scp2.py b/bin/parse-scp2.py
index 6a34f96..4ec7651 100755
--- a/bin/parse-scp2.py
+++ b/bin/parse-scp2.py
@@ -24,6 +24,16 @@ class ParseError(ErrorBase):
def __init__ (self, msg, sev = 0):
ErrorBase.__init__(self, "ParseError", msg, sev)
+class DirError(ErrorBase):
+ def __init__ (self, msg):
+ ErrorBase.__init__(self, "DirError", msg, 0)
+
+class LinkedNode(object):
+ def __init__ (self, name):
+ self.name = name
+ self.parent = None
+ self.children = []
+
# Parse each .scp file.
class Scp2Parser(object):
@@ -53,7 +63,7 @@ class Scp2Parser(object):
def __init__ (self, content, filename):
self.content = content
self.filename = filename
- self.nodes = {}
+ self.nodedata = {}
def tokenize (self):
self.tokens = []
@@ -67,6 +77,9 @@ class Scp2Parser(object):
if c in ' ;':
if len(token) > 0:
+ if token[0] == '"' and token[-1] == '"':
+ # remove quotes.
+ token = token[1:-1]
self.tokens.append(token)
token = ''
if c == ';':
@@ -88,20 +101,64 @@ class Scp2Parser(object):
name, attrs, values = self.__parseEntity()
attrs['__node_type__'] = t # type of node
attrs['__node_location__'] = self.filename # file where the node is defined
- attrs['__node_values__'] = values
- if self.nodes.has_key(name):
+ attrs['__node_values__'] = values # list of values that are not attributes (i.e. not associated with names)
+ if self.nodedata.has_key(name):
raise ParseError("node named %s already exists"%name, 1)
- self.nodes[name] = attrs
+ self.nodedata[name] = attrs
else:
raise ParseError("Unknown node type: %s"%t)
self.next()
- def append_nodes (self, nodes):
- for key in self.nodes.keys():
- if nodes.has_key(key):
+ def append_nodes (self, nodedata, nodetree):
+
+ for key in self.nodedata.keys():
+
+ if nodedata.has_key(key):
raise ParseError("node named %s already exists"%key, 1)
- nodes[key] = self.nodes[key]
+
+ # Transfer all the node attributes to the caller instance.
+ nodedata[key] = self.nodedata[key]
+
+ # Now, add linkage data to the parent tree instance.
+
+ if not nodetree.has_key(key):
+ # Create a new linked node instance.
+ nodetree[key] = LinkedNode(key)
+
+ attrs = self.nodedata[key]
+
+ node_type = attrs['__node_type__']
+ if node_type == 'Module':
+ self.__link_module_node(key, attrs, nodetree)
+
+
+ def __link_module_node (self, name, attrs, nodetree):
+
+ if attrs.has_key('ParentID'):
+ parentID = attrs['ParentID']
+
+ if not nodetree.has_key(parentID):
+ nodetree[parentID] = LinkedNode(parentID)
+
+ nodetree[parentID].children.append(nodetree[name])
+ if nodetree[name].parent != None:
+ raise ParseError("parent node instance already exists for '%s'"%parentID, 1)
+ nodetree[name].parent = nodetree[parentID]
+
+ if attrs.has_key('Files'):
+ # file list strings are formatted '(file1,file2,file3,....)'
+ files = attrs['Files']
+ if files[0] != '(' or files[-1] != ')':
+ raise ParseError("file list string is not formatted correctly: %s"%files)
+ files = files[1:-1]
+ list = files.split(',')
+ for file in list:
+
+ if not nodetree.has_key(file):
+ nodetree[file] = LinkedNode(file)
+ nodetree[name].children.append(nodetree[file])
+
def next (self):
self.i += 1
@@ -112,6 +169,8 @@ class Scp2Parser(object):
def __parseEntity (self):
self.next()
name = self.token()
+ if len(name) == 0:
+ raise ParseError("empty name", 1)
left = True
attr_name = ''
attr_value = ''
@@ -130,7 +189,7 @@ class Scp2Parser(object):
elif left:
if self.token() == ';':
- # Not a valid attribute. Ignore this for now.
+ # Not a valid attribute. Store it as a 'value'.
values.append(attr_name)
attr_name = ''
else:
@@ -150,7 +209,6 @@ class Scp2Parser(object):
return name, attrs, values
-
# Collect all .scp files in scp2 directory, and run preprocessor.
class Scp2Processor(object):
@@ -167,7 +225,8 @@ class Scp2Processor(object):
self.cur_dir = cur_dir
self.mod_output_dir = mod_output_dir
self.scp_files = []
- self.nodes = {}
+ self.nodedata = {}
+ self.nodetree = {}
# Check file paths first.
if not os.path.isfile("%s/scp2/inc/macros.inc"%self.cur_dir):
@@ -200,7 +259,7 @@ class Scp2Processor(object):
if ret > 0:
raise ParseError("failed to copy scp file to a temporary location.")
- subprocess.call("gcc -E -I./scp2/inc -I%s -DUNX %s 2>/dev/null | grep -v -E \"^\#\" > %s"%
+ subprocess.call("gcc -E -I./scp2/inc -I./scp2/%s/inc -DUNX %s 2>/dev/null | grep -v -E \"^\#\" > %s"%
(self.mod_output_dir, Scp2Processor.tmpin, Scp2Processor.tmpout), shell=True)
file = open(Scp2Processor.tmpout, 'r')
@@ -210,7 +269,7 @@ class Scp2Processor(object):
parser.tokenize()
try:
parser.parse()
- parser.append_nodes(self.nodes)
+ parser.append_nodes(self.nodedata, self.nodetree)
except ParseError as e:
# Skip mal-formed files, instead of exit with error.
error (e.value)
@@ -219,11 +278,11 @@ class Scp2Processor(object):
# This is a severe error. Exit right away.
sys.exit(1)
- def print_summary (self):
- names = self.nodes.keys()
+ def print_summary_flat (self):
+ names = self.nodedata.keys()
names.sort()
for name in names:
- attrs = self.nodes[name]
+ attrs = self.nodedata[name]
node_type = attrs['__node_type__']
print ('-'*70)
print ("%s (%s)"%(name, node_type))
@@ -243,6 +302,98 @@ class Scp2Processor(object):
continue
print (" %s = %s"%(attr_name, attrs[attr_name]))
+ def print_summary_tree (self):
+ root = 'gid_Module_Root'
+ node = self.nodetree[root]
+ self.__print_summary_tree_node(node, 0)
+
+ def __get_fullpath (self, fileID):
+ nodedata = self.nodedata[fileID]
+ filename = None
+ if nodedata.has_key('Name'):
+ filename = nodedata['Name']
+ elif nodedata.has_key('Name(en-US)'):
+ filename = nodedata['Name(en-US)']
+ else:
+ raise DirError("%s doesn't have a name attribute."%fileID)
+
+ if not nodedata.has_key('Dir'):
+ raise DirError("file %s doesn't have Dir attribute."%fileID)
+
+ parent_dir_name = nodedata['Dir']
+
+ while parent_dir_name != None:
+
+ if parent_dir_name == 'PREDEFINED_PROGDIR':
+ # special directory name
+ return parent_dir_name + '/' + filename
+
+ if not self.nodedata.has_key(parent_dir_name):
+ # directory is referenced but not defined. Skip it for now.
+ raise DirError("directory '%s' is referenced but not defined."%parent_dir_name)
+
+ nodedata = self.nodedata[parent_dir_name]
+ if nodedata.has_key('DosName'):
+ filename = nodedata['DosName'] + "/" + filename
+ elif nodedata.has_key('DosName(en-US)'):
+ filename = nodedata['DosName(en-US)'] + "/" + filename
+ elif nodedata.has_key('HostName'):
+ filename = nodedata['HostName'] + "/" + filename
+ else:
+ raise DirError("directory '%s' does not have either DosName or HostName attribute."%parent_dir_name)
+
+ if nodedata.has_key('ParentID'):
+ parent_dir_name = nodedata['ParentID']
+ else:
+ parent_dir_name = None
+
+ return filename
+
+ def __print_summary_tree_node (self, node, level):
+
+ indent = ' '*level
+
+ if node == None:
+ return
+
+ if not self.nodedata.has_key(node.name):
+ # This node is referenced but is not defined. Skip it.
+ #error("Node '%s' is referenced but not defined."%node.name)
+ return
+
+ nodedata = self.nodedata[node.name]
+ if not self.nodedata.has_key(node.name):
+ raise ParseError("there is no associated node data for '%s'"%node.name)
+
+ node_type = nodedata['__node_type__']
+
+ name = ''
+ if node_type == 'File':
+ try:
+ name = self.__get_fullpath(node.name)
+ except DirError as e:
+ name = e.value
+ elif node_type == 'Directory':
+ name = ndoedata['DosName']
+
+ s = indent + "<%s id=\"%s\""%(node_type, node.name)
+ if len(name) > 0:
+ s += " name=\"%s\""%name
+
+ if len(node.children) > 0:
+ s += ">"
+ print (s)
+
+ children = node.children
+ children.sort()
+ for child in children:
+ self.__print_summary_tree_node(child, level+1)
+
+ print (indent + "</%s>"%node_type)
+ else:
+ s += "/>"
+ print (s)
+
@staticmethod
def visit (arg, dirname, names):
instance = arg
@@ -251,19 +402,32 @@ class Scp2Processor(object):
if os.path.splitext(filepath)[1] == '.scp':
instance.scp_files.append(filepath)
-
if __name__ == '__main__':
parser = optparse.OptionParser()
parser.usage += " " + arg_desc + "\n" + desc
parser.add_option("", "--module-output-dir", dest="mod_output_dir", default="unxlngi6.pro", metavar="DIR",
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'.")
options, args = parser.parse_args()
+
+ if not options.mode in ['tree', 'flat']:
+ error("unknown output mode '%s'"%options.mode)
+ sys.exit(1)
+
cur_dir = os.getcwd()
try:
processor = Scp2Processor(cur_dir, options.mod_output_dir)
processor.run()
- processor.print_summary()
+ if options.mode == 'tree':
+ processor.print_summary_tree()
+ elif options.mode == 'flat':
+ processor.print_summary_flat()
+ else:
+ raise ParseError("unknown output mode '%s'"%options.mode)
+
except ParseError as e:
- print (e.value)
+ error (e.value)
+ sys.exit(1)
More information about the ooo-build-commit
mailing list