1# ************************************************************* 2# 3# Licensed to the Apache Software Foundation (ASF) under one 4# or more contributor license agreements. See the NOTICE file 5# distributed with this work for additional information 6# regarding copyright ownership. The ASF licenses this file 7# to you under the Apache License, Version 2.0 (the 8# "License"); you may not use this file except in compliance 9# with the License. You may obtain a copy of the License at 10# 11# http://www.apache.org/licenses/LICENSE-2.0 12# 13# Unless required by applicable law or agreed to in writing, 14# software distributed under the License is distributed on an 15# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16# KIND, either express or implied. See the License for the 17# specific language governing permissions and limitations 18# under the License. 19# 20# ************************************************************* 21 22import sys 23 24class ParseError (Exception): 25 pass 26 27def error (msg, exit=0): 28 sys.stderr.write (msg) 29 if exit: 30 sys.exit (exit) 31 32def progress (msg): 33 sys.stderr.write(msg) 34 35 36def removeQuote (text): 37 """Remove quotes from a literal. 38""" 39 if len(text) >= 2 and text[0] == text[len(text)-1] == '"': 40 text = text[1:-1] 41 return text 42 43 44class Macro(object): 45 def __init__ (self, name): 46 self.name = name 47 self.tokens = [] 48 self.vars = {} 49 50 51class Node(object): 52 def __init__ (self): 53 self.children = [] 54 55 def appendChild (self, childnode): 56 self.children.append(childnode) 57 childnode.parent = self 58 59 def getChildren (self): 60 return self.children 61 62 63class RootNode(Node): 64 def __init__ (self): 65 Node.__init__(self) 66 67 def dump (self): 68 chars = '' 69 for child in self.getChildren(): 70 chars += child.dump() 71 return chars 72 73 74class Element(Node): 75 76 INDENT = " " 77 78 def __init__ (self, name, rid = None): 79 Node.__init__(self) 80 self.name = name 81 self.parent = None 82# print "name: " + self.name - stats ... 83 84 # The following attributes are copied when 'clone'ed. 85 self.rid = rid 86 self.attrs = {} 87 88 def dump (self, level = 0): 89 chars = '' 90 chars += "\n" + Element.INDENT*level 91 chars += '<%s'%self.name 92 93 if self.rid != None: 94 self.setAttr("rid", self.rid) 95 96 chars += self.__dumpAttrs() 97 98 if len(self.children) == 0: 99 chars += '/>' 100 else: 101 chars += '>' 102 for child in self.getChildren(): 103 chars += child.dump(level+1) 104 105 chars += "\n"+Element.INDENT*level 106 chars += "</%s>"%self.name 107 108 return chars 109 110 def hasAttr (self, name): 111 return name in self.attrs 112 113 def getAttr (self, name): 114 return self.attrs[name] 115 116 def setAttr (self, name, value): 117 if type(value) == type(0): 118 value = "%d"%value 119 self.attrs[name] = removeQuote(value) 120# print "attr: " + self.name + "." + name - stats ... 121 return 122 123 def clone (self, elem): 124 keys = list(elem.attrs.keys()) 125 for key in keys: 126 self.attrs[key] = elem.attrs[key] 127 self.rid = elem.rid 128 129 def __dumpAttrs (self): 130 text = '' 131 keys = sorted(self.attrs.keys()) 132 for key in keys: 133 value = self.attrs[key] 134 text += ' %s="%s"'%(key, value) 135 return text 136