timeline-object: Add TrackObject to the Track after the TimelineObject
[platform/upstream/gstreamer.git] / bindings / python / codegen / scmexpr.py
1 #!/usr/bin/env python
2 # -*- Mode: Python; py-indent-offset: 4 -*-
3 from __future__ import generators
4
5 import string
6 from cStringIO import StringIO
7
8 class error(Exception):
9     def __init__(self, filename, lineno, msg):
10         Exception.__init__(self, msg)
11         self.filename = filename
12         self.lineno = lineno
13         self.msg = msg
14     def __str__(self):
15         return '%s:%d: error: %s' % (self.filename, self.lineno, self.msg)
16
17 trans = [' '] * 256
18 for i in range(256):
19     if chr(i) in string.letters + string.digits + '_':
20         trans[i] = chr(i)
21     else:
22         trans[i] = '_'
23 trans = string.join(trans, '')
24
25 def parse(filename):
26     if isinstance(filename, str):
27         fp = open(filename, 'r')
28     else: # if not string, assume it is some kind of iterator
29         fp = filename
30         filename = getattr(fp, 'name', '<unknown>')
31     whitespace = ' \t\n\r\x0b\x0c'
32     nonsymbol = whitespace + '();\'"'
33     stack = []
34     openlines = []
35     lineno = 0
36     for line in fp:
37         pos = 0
38         lineno += 1
39         while pos < len(line):
40             if line[pos] in whitespace: # ignore whitespace
41                 pass
42             elif line[pos] == ';': # comment
43                 break
44             elif line[pos:pos+2] == "'(":
45                 pass # the open parenthesis will be handled next iteration
46             elif line[pos] == '(':
47                 stack.append(())
48                 openlines.append(lineno)
49             elif line[pos] == ')':
50                 if len(stack) == 0:
51                     raise error(filename, lineno, 'close parenthesis found when none open')
52                 closed = stack[-1]
53                 del stack[-1]
54                 del openlines[-1]
55                 if stack:
56                     stack[-1] += (closed,)
57                 else:
58                     yield closed
59             elif line[pos] == '"': # quoted string
60                 if not stack:
61                     raise error(filename, lineno,
62                                 'string found outside of s-expression')
63                 endpos = pos + 1
64                 chars = []
65                 while endpos < len(line):
66                     if endpos+1 < len(line) and line[endpos] == '\\':
67                         endpos += 1
68                         if line[endpos] == 'n':
69                             chars.append('\n')
70                         elif line[endpos] == 'r':
71                             chars.append('\r')
72                         elif line[endpos] == 't':
73                             chars.append('\t')
74                         else:
75                             chars.append('\\')
76                             chars.append(line[endpos])
77                     elif line[endpos] == '"':
78                         break
79                     else:
80                         chars.append(line[endpos])
81                     endpos += 1
82                 if endpos >= len(line):
83                     raise error(filename, lineno, "unclosed quoted string")
84                 pos = endpos
85                 stack[-1] += (''.join(chars),)
86             else: # symbol/number
87                 if not stack:
88                     raise error(filename, lineno,
89                                 'identifier found outside of s-expression')
90                 endpos = pos
91                 while endpos < len(line) and line[endpos] not in nonsymbol:
92                     endpos += 1
93                 symbol = line[pos:endpos]
94                 pos = max(pos, endpos-1)
95                 try: symbol = int(symbol)
96                 except ValueError:
97                     try: symbol = float(symbol)
98                     except ValueError: pass
99                 stack[-1] += (symbol,)
100             pos += 1
101     if len(stack) != 0:
102         msg = '%d unclosed parentheses found at end of ' \
103               'file (opened on line(s) %s)' % (len(stack),
104                                                ', '.join(map(str, openlines)))
105         raise error(filename, lineno, msg)
106
107 class Parser:
108     def __init__(self, filename):
109         """Argument is either a string, a parse tree, or file object"""
110         self.filename = filename
111     def startParsing(self, filename=None):
112         statements = parse(filename or self.filename)
113         for statement in statements:
114             self.handle(statement)
115     def handle(self, tup):
116         cmd = string.translate(tup[0], trans)
117         if hasattr(self, cmd):
118             getattr(self, cmd)(*tup[1:])
119         else:
120             self.unknown(tup)
121     def unknown(self, tup):
122         pass
123
124 _testString = """; a scheme file
125 (define-func gdk_font_load    ; a comment at end of line
126   GdkFont
127   ((string name)))
128
129 (define-boxed GdkEvent
130   gdk_event_copy
131   gdk_event_free
132   "sizeof(GdkEvent)")
133 """
134
135 if __name__ == '__main__':
136     import sys
137     if sys.argv[1:]:
138         fp = open(sys.argv[1])
139     else:
140         fp = StringIO(_testString)
141     statements = parse(fp)
142     for s in statements:
143         print `s`