1# Face.py - module for reading and parsing Scintilla.iface file
2# Implemented 2000 by Neil Hodgson neilh@scintilla.org
3# Released to the public domain.
4# Requires Python 2.5 or later
5
6def sanitiseLine(line):
7	if line[-1:] == '\n': line = line[:-1]
8	if line.find("##") != -1:
9		line = line[:line.find("##")]
10	line = line.strip()
11	return line
12
13def decodeFunction(featureVal):
14	retType, rest = featureVal.split(" ", 1)
15	nameIdent, params = rest.split("(")
16	name, value = nameIdent.split("=")
17	params, rest = params.split(")")
18	param1, param2 = params.split(",")
19	return retType, name, value, param1, param2
20
21def decodeEvent(featureVal):
22	retType, rest = featureVal.split(" ", 1)
23	nameIdent, params = rest.split("(")
24	name, value = nameIdent.split("=")
25	return retType, name, value
26
27def decodeParam(p):
28	param = p.strip()
29	type = ""
30	name = ""
31	value = ""
32	if " " in param:
33		type, nv = param.split(" ")
34		if "=" in nv:
35			name, value = nv.split("=")
36		else:
37			name = nv
38	return type, name, value
39
40def IsEnumeration(t):
41	return t[:1].isupper()
42
43class Face:
44
45	def __init__(self):
46		self.order = []
47		self.features = {}
48		self.values = {}
49		self.events = {}
50		self.aliases = {}
51
52	def ReadFromFile(self, name):
53		currentCategory = ""
54		currentComment = []
55		currentCommentFinished = 0
56		file = open(name)
57		for line in file.readlines():
58			line = sanitiseLine(line)
59			if line:
60				if line[0] == "#":
61					if line[1] == " ":
62						if currentCommentFinished:
63							currentComment = []
64							currentCommentFinished = 0
65						currentComment.append(line[2:])
66				else:
67					currentCommentFinished = 1
68					featureType, featureVal = line.split(" ", 1)
69					if featureType in ["fun", "get", "set"]:
70						try:
71							retType, name, value, param1, param2 = decodeFunction(featureVal)
72						except ValueError:
73							print("Failed to decode %s" % line)
74							raise
75						p1 = decodeParam(param1)
76						p2 = decodeParam(param2)
77						self.features[name] = {
78							"FeatureType": featureType,
79							"ReturnType": retType,
80							"Value": value,
81							"Param1Type": p1[0], "Param1Name": p1[1], "Param1Value": p1[2],
82							"Param2Type": p2[0], "Param2Name": p2[1], "Param2Value": p2[2],
83							"Category": currentCategory, "Comment": currentComment
84						}
85						if value in self.values:
86							raise Exception("Duplicate value " + value + " " + name)
87						self.values[value] = 1
88						self.order.append(name)
89						currentComment = []
90					elif featureType == "evt":
91						retType, name, value = decodeEvent(featureVal)
92						self.features[name] = {
93							"FeatureType": featureType,
94							"ReturnType": retType,
95							"Value": value,
96							"Category": currentCategory, "Comment": currentComment
97						}
98						if value in self.events:
99							raise Exception("Duplicate event " + value + " " + name)
100						self.events[value] = 1
101						self.order.append(name)
102					elif featureType == "cat":
103						currentCategory = featureVal
104					elif featureType == "val":
105						try:
106							name, value = featureVal.split("=", 1)
107						except ValueError:
108							print("Failure %s" % featureVal)
109							raise Exception()
110						self.features[name] = {
111							"FeatureType": featureType,
112							"Category": currentCategory,
113							"Value": value }
114						self.order.append(name)
115					elif featureType == "enu" or featureType == "lex":
116						name, value = featureVal.split("=", 1)
117						self.features[name] = {
118							"FeatureType": featureType,
119							"Category": currentCategory,
120							"Value": value,
121							"Comment": currentComment }
122						self.order.append(name)
123						currentComment = []
124					elif featureType == "ali":
125						# Enumeration alias
126						name, value = featureVal.split("=", 1)
127						self.aliases[name] = value
128						currentComment = []
129
130