xref: /AOO41X/main/toolkit/src2xml/source/srclexer.py (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1*cdf0e10cSrcweirimport sys, os.path
2*cdf0e10cSrcweirfrom globals import *
3*cdf0e10cSrcweirimport macroparser
4*cdf0e10cSrcweir
5*cdf0e10cSrcweirclass EOF(Exception):
6*cdf0e10cSrcweir    def __init__ (self):
7*cdf0e10cSrcweir        pass
8*cdf0e10cSrcweir
9*cdf0e10cSrcweir    def str (self):
10*cdf0e10cSrcweir        return "end of file"
11*cdf0e10cSrcweir
12*cdf0e10cSrcweirclass BOF(Exception):
13*cdf0e10cSrcweir    def __init__ (self):
14*cdf0e10cSrcweir        pass
15*cdf0e10cSrcweir
16*cdf0e10cSrcweir    def str (self):
17*cdf0e10cSrcweir        return "beginning of file"
18*cdf0e10cSrcweir
19*cdf0e10cSrcweir
20*cdf0e10cSrcweirdef removeHeaderQuotes (orig):
21*cdf0e10cSrcweir    if len(orig) <= 2:
22*cdf0e10cSrcweir        return orig
23*cdf0e10cSrcweir    elif orig[0] == orig[-1] == '"':
24*cdf0e10cSrcweir        return orig[1:-1]
25*cdf0e10cSrcweir    elif orig[0] == '<' and orig[-1] == '>':
26*cdf0e10cSrcweir        return orig[1:-1]
27*cdf0e10cSrcweir
28*cdf0e10cSrcweir    return orig
29*cdf0e10cSrcweir
30*cdf0e10cSrcweir
31*cdf0e10cSrcweirdef dumpTokens (tokens, toError=False):
32*cdf0e10cSrcweir
33*cdf0e10cSrcweir    scope = 0
34*cdf0e10cSrcweir    indent = "    "
35*cdf0e10cSrcweir    line = ''
36*cdf0e10cSrcweir    chars = ''
37*cdf0e10cSrcweir
38*cdf0e10cSrcweir    for token in tokens:
39*cdf0e10cSrcweir        if token in '{<':
40*cdf0e10cSrcweir            if len(line) > 0:
41*cdf0e10cSrcweir                chars += indent*scope + line + "\n"
42*cdf0e10cSrcweir                line = ''
43*cdf0e10cSrcweir            chars += indent*scope + token + "\n"
44*cdf0e10cSrcweir            scope += 1
45*cdf0e10cSrcweir
46*cdf0e10cSrcweir        elif token in '}>':
47*cdf0e10cSrcweir            if len(line) > 0:
48*cdf0e10cSrcweir                chars += indent*scope + line + "\n"
49*cdf0e10cSrcweir                line = ''
50*cdf0e10cSrcweir            scope -= 1
51*cdf0e10cSrcweir            chars += indent*scope + token
52*cdf0e10cSrcweir
53*cdf0e10cSrcweir        elif token == ';':
54*cdf0e10cSrcweir            if len(line) > 0:
55*cdf0e10cSrcweir                chars += indent*scope + line + ";\n"
56*cdf0e10cSrcweir                line = ''
57*cdf0e10cSrcweir            else:
58*cdf0e10cSrcweir                chars += ";\n"
59*cdf0e10cSrcweir        elif len(token) > 0:
60*cdf0e10cSrcweir            line += token + ' '
61*cdf0e10cSrcweir
62*cdf0e10cSrcweir    if len(line) > 0:
63*cdf0e10cSrcweir        chars += line
64*cdf0e10cSrcweir    chars += "\n"
65*cdf0e10cSrcweir    if toError:
66*cdf0e10cSrcweir        sys.stderr.write(chars)
67*cdf0e10cSrcweir    else:
68*cdf0e10cSrcweir        sys.stdout.write(chars)
69*cdf0e10cSrcweir
70*cdf0e10cSrcweir
71*cdf0e10cSrcweirclass HeaderData(object):
72*cdf0e10cSrcweir    def __init__ (self):
73*cdf0e10cSrcweir        self.defines = {}
74*cdf0e10cSrcweir        self.tokens = []
75*cdf0e10cSrcweir
76*cdf0e10cSrcweir
77*cdf0e10cSrcweirclass SrcLexer(object):
78*cdf0e10cSrcweir    """Lexicographical analyzer for .src format.
79*cdf0e10cSrcweir
80*cdf0e10cSrcweirThe role of a lexer is to parse the source file and break it into
81*cdf0e10cSrcweirappropriate tokens.  Such tokens are later passed to a parser to
82*cdf0e10cSrcweirbuild the syntax tree.
83*cdf0e10cSrcweir"""
84*cdf0e10cSrcweir    headerCache = {}
85*cdf0e10cSrcweir
86*cdf0e10cSrcweir    VISIBLE = 0
87*cdf0e10cSrcweir    INVISIBLE_PRE = 1
88*cdf0e10cSrcweir    INVISIBLE_POST = 2
89*cdf0e10cSrcweir
90*cdf0e10cSrcweir    def __init__ (self, chars, filepath = None):
91*cdf0e10cSrcweir        self.filepath = filepath
92*cdf0e10cSrcweir        self.parentLexer = None
93*cdf0e10cSrcweir        self.chars = chars
94*cdf0e10cSrcweir        self.bufsize = len(self.chars)
95*cdf0e10cSrcweir
96*cdf0e10cSrcweir        # TODO: use parameters for this
97*cdf0e10cSrcweir        # Properties that can be copied.
98*cdf0e10cSrcweir        self.headerDict = dict ()
99*cdf0e10cSrcweir        self.debug = False
100*cdf0e10cSrcweir        self.debugMacro = False
101*cdf0e10cSrcweir        self.includeDirs = list ()
102*cdf0e10cSrcweir        self.expandHeaders = True
103*cdf0e10cSrcweir        self.inMacroDefine = False
104*cdf0e10cSrcweir        self.stopOnHeader = False
105*cdf0e10cSrcweir
106*cdf0e10cSrcweir    def copyProperties (self, other):
107*cdf0e10cSrcweir        """Copy properties from another instance of SrcLexer."""
108*cdf0e10cSrcweir
109*cdf0e10cSrcweir        # TODO: use parameters for this
110*cdf0e10cSrcweir        self.headerDict = other.headerDict
111*cdf0e10cSrcweir        self.debug = other.debug
112*cdf0e10cSrcweir        self.debugMacro = other.debugMacro
113*cdf0e10cSrcweir        self.includeDirs = other.includeDirs[:]
114*cdf0e10cSrcweir        self.expandHeaders = other.expandHeaders
115*cdf0e10cSrcweir        self.inMacroDefine = other.inMacroDefine
116*cdf0e10cSrcweir        self.stopOnHeader = other.stopOnHeader
117*cdf0e10cSrcweir
118*cdf0e10cSrcweir    def init (self):
119*cdf0e10cSrcweir        self.firstNonBlank = ''
120*cdf0e10cSrcweir        self.token = ''
121*cdf0e10cSrcweir        self.tokens = []
122*cdf0e10cSrcweir        self.defines = {}
123*cdf0e10cSrcweir        self.visibilityStack = []
124*cdf0e10cSrcweir
125*cdf0e10cSrcweir    def getTokens (self):
126*cdf0e10cSrcweir        return self.tokens
127*cdf0e10cSrcweir
128*cdf0e10cSrcweir    def getDefines (self):
129*cdf0e10cSrcweir        return self.defines
130*cdf0e10cSrcweir
131*cdf0e10cSrcweir    def nextPos (self, i):
132*cdf0e10cSrcweir        while True:
133*cdf0e10cSrcweir            i += 1
134*cdf0e10cSrcweir            try:
135*cdf0e10cSrcweir                c = self.chars[i]
136*cdf0e10cSrcweir            except IndexError:
137*cdf0e10cSrcweir                raise EOF
138*cdf0e10cSrcweir
139*cdf0e10cSrcweir            if ord(c) in [0x0D]:
140*cdf0e10cSrcweir                continue
141*cdf0e10cSrcweir            break
142*cdf0e10cSrcweir        return i
143*cdf0e10cSrcweir
144*cdf0e10cSrcweir    def prevPos (self, i):
145*cdf0e10cSrcweir        while True:
146*cdf0e10cSrcweir            i -= 1
147*cdf0e10cSrcweir            try:
148*cdf0e10cSrcweir                c = self.chars[i]
149*cdf0e10cSrcweir            except IndexError:
150*cdf0e10cSrcweir                raise BOF
151*cdf0e10cSrcweir
152*cdf0e10cSrcweir            if ord(c) in [0x0D]:
153*cdf0e10cSrcweir                continue
154*cdf0e10cSrcweir            break
155*cdf0e10cSrcweir        return i
156*cdf0e10cSrcweir
157*cdf0e10cSrcweir    def isCodeVisible (self):
158*cdf0e10cSrcweir        if len(self.visibilityStack) == 0:
159*cdf0e10cSrcweir            return True
160*cdf0e10cSrcweir        for item in self.visibilityStack:
161*cdf0e10cSrcweir            if item != SrcLexer.VISIBLE:
162*cdf0e10cSrcweir                return False
163*cdf0e10cSrcweir        return True
164*cdf0e10cSrcweir
165*cdf0e10cSrcweir    def tokenize (self):
166*cdf0e10cSrcweir        self.init()
167*cdf0e10cSrcweir
168*cdf0e10cSrcweir        i = 0
169*cdf0e10cSrcweir        while True:
170*cdf0e10cSrcweir            c = self.chars[i]
171*cdf0e10cSrcweir
172*cdf0e10cSrcweir            if self.firstNonBlank == '' and not c in [' ', "\n", "\t"]:
173*cdf0e10cSrcweir                # Store the first non-blank in a line.
174*cdf0e10cSrcweir                self.firstNonBlank = c
175*cdf0e10cSrcweir            elif c == "\n":
176*cdf0e10cSrcweir                self.firstNonBlank = ''
177*cdf0e10cSrcweir
178*cdf0e10cSrcweir            if c == '#':
179*cdf0e10cSrcweir                i = self.pound(i)
180*cdf0e10cSrcweir            elif c == '/':
181*cdf0e10cSrcweir                i = self.slash(i)
182*cdf0e10cSrcweir            elif c == "\n":
183*cdf0e10cSrcweir                i = self.lineBreak(i)
184*cdf0e10cSrcweir            elif c == '"':
185*cdf0e10cSrcweir                i = self.doubleQuote(i)
186*cdf0e10cSrcweir            elif c in [' ', "\t"]:
187*cdf0e10cSrcweir                i = self.blank(i)
188*cdf0e10cSrcweir            elif c in ";()[]{}<>,=+-*":
189*cdf0e10cSrcweir                # Any outstanding single-character token.
190*cdf0e10cSrcweir                i = self.anyToken(i, c)
191*cdf0e10cSrcweir            elif self.isCodeVisible():
192*cdf0e10cSrcweir                self.token += c
193*cdf0e10cSrcweir
194*cdf0e10cSrcweir            try:
195*cdf0e10cSrcweir                i = self.nextPos(i)
196*cdf0e10cSrcweir            except EOF:
197*cdf0e10cSrcweir                break
198*cdf0e10cSrcweir
199*cdf0e10cSrcweir        if len(self.token):
200*cdf0e10cSrcweir            self.tokens.append(self.token)
201*cdf0e10cSrcweir
202*cdf0e10cSrcweir        if not self.parentLexer and self.debug:
203*cdf0e10cSrcweir            progress ("-"*68 + "\n")
204*cdf0e10cSrcweir            progress ("All defines found in this translation unit:\n")
205*cdf0e10cSrcweir            keys = self.defines.keys()
206*cdf0e10cSrcweir            keys.sort()
207*cdf0e10cSrcweir            for key in keys:
208*cdf0e10cSrcweir                progress ("@ %s\n"%key)
209*cdf0e10cSrcweir
210*cdf0e10cSrcweir    def dumpTokens (self, toError=False):
211*cdf0e10cSrcweir        dumpTokens(self.tokens, toError)
212*cdf0e10cSrcweir
213*cdf0e10cSrcweir
214*cdf0e10cSrcweir    def maybeAddToken (self):
215*cdf0e10cSrcweir        if len(self.token) > 0:
216*cdf0e10cSrcweir            self.tokens.append(self.token)
217*cdf0e10cSrcweir            self.token = ''
218*cdf0e10cSrcweir
219*cdf0e10cSrcweir
220*cdf0e10cSrcweir    #--------------------------------------------------------------------
221*cdf0e10cSrcweir    # character handlers
222*cdf0e10cSrcweir
223*cdf0e10cSrcweir    def blank (self, i):
224*cdf0e10cSrcweir        if not self.isCodeVisible():
225*cdf0e10cSrcweir            return i
226*cdf0e10cSrcweir
227*cdf0e10cSrcweir        self.maybeAddToken()
228*cdf0e10cSrcweir        return i
229*cdf0e10cSrcweir
230*cdf0e10cSrcweir
231*cdf0e10cSrcweir    def pound (self, i):
232*cdf0e10cSrcweir
233*cdf0e10cSrcweir        if self.inMacroDefine:
234*cdf0e10cSrcweir            return i
235*cdf0e10cSrcweir
236*cdf0e10cSrcweir        if not self.firstNonBlank == '#':
237*cdf0e10cSrcweir            return i
238*cdf0e10cSrcweir
239*cdf0e10cSrcweir        self.maybeAddToken()
240*cdf0e10cSrcweir        # We are in preprocessing mode.
241*cdf0e10cSrcweir
242*cdf0e10cSrcweir        # Get the macro command name '#<command> .....'
243*cdf0e10cSrcweir
244*cdf0e10cSrcweir        command, define, buf = '', '', ''
245*cdf0e10cSrcweir        firstNonBlank = False
246*cdf0e10cSrcweir        while True:
247*cdf0e10cSrcweir            try:
248*cdf0e10cSrcweir                i = self.nextPos(i)
249*cdf0e10cSrcweir                c = self.chars[i]
250*cdf0e10cSrcweir                if c == '\\' and self.chars[self.nextPos(i)] == "\n":
251*cdf0e10cSrcweir                    i = self.nextPos(i)
252*cdf0e10cSrcweir                    continue
253*cdf0e10cSrcweir            except EOF:
254*cdf0e10cSrcweir                break
255*cdf0e10cSrcweir
256*cdf0e10cSrcweir            if c == "\n":
257*cdf0e10cSrcweir                if len(buf) > 0 and len(command) == 0:
258*cdf0e10cSrcweir                    command = buf
259*cdf0e10cSrcweir                i = self.prevPos(i)
260*cdf0e10cSrcweir                break
261*cdf0e10cSrcweir            elif c in [' ', "\t"]:
262*cdf0e10cSrcweir                if not firstNonBlank:
263*cdf0e10cSrcweir                    # Ignore any leading blanks after the '#'.
264*cdf0e10cSrcweir                    continue
265*cdf0e10cSrcweir
266*cdf0e10cSrcweir                if len(command) == 0:
267*cdf0e10cSrcweir                    command = buf
268*cdf0e10cSrcweir                    buf = ''
269*cdf0e10cSrcweir                else:
270*cdf0e10cSrcweir                    buf += ' '
271*cdf0e10cSrcweir            elif c == '(':
272*cdf0e10cSrcweir                if len(buf) > 0 and len(command) == 0:
273*cdf0e10cSrcweir                    command = buf
274*cdf0e10cSrcweir                buf += c
275*cdf0e10cSrcweir            else:
276*cdf0e10cSrcweir                if not firstNonBlank:
277*cdf0e10cSrcweir                    firstNonBlank = True
278*cdf0e10cSrcweir                buf += c
279*cdf0e10cSrcweir
280*cdf0e10cSrcweir        if command == 'define':
281*cdf0e10cSrcweir            self.handleMacroDefine(buf)
282*cdf0e10cSrcweir        elif command == 'include':
283*cdf0e10cSrcweir            self.handleMacroInclude(buf)
284*cdf0e10cSrcweir        elif command == 'ifdef':
285*cdf0e10cSrcweir            defineName = buf.strip()
286*cdf0e10cSrcweir            if self.defines.has_key(defineName):
287*cdf0e10cSrcweir                self.visibilityStack.append(SrcLexer.VISIBLE)
288*cdf0e10cSrcweir            else:
289*cdf0e10cSrcweir                self.visibilityStack.append(SrcLexer.INVISIBLE_PRE)
290*cdf0e10cSrcweir
291*cdf0e10cSrcweir        elif command == 'ifndef':
292*cdf0e10cSrcweir            defineName = buf.strip()
293*cdf0e10cSrcweir            if self.defines.has_key(defineName):
294*cdf0e10cSrcweir                self.visibilityStack.append(SrcLexer.INVISIBLE_PRE)
295*cdf0e10cSrcweir            else:
296*cdf0e10cSrcweir                self.visibilityStack.append(SrcLexer.VISIBLE)
297*cdf0e10cSrcweir
298*cdf0e10cSrcweir        elif command == 'if':
299*cdf0e10cSrcweir            if self.evalCodeVisibility(buf):
300*cdf0e10cSrcweir                self.visibilityStack.append(SrcLexer.VISIBLE)
301*cdf0e10cSrcweir            else:
302*cdf0e10cSrcweir                self.visibilityStack.append(SrcLexer.INVISIBLE_PRE)
303*cdf0e10cSrcweir
304*cdf0e10cSrcweir        elif command == 'elif':
305*cdf0e10cSrcweir            if len(self.visibilityStack) == 0:
306*cdf0e10cSrcweir                raise ParseError ('')
307*cdf0e10cSrcweir
308*cdf0e10cSrcweir            if self.visibilityStack[-1] == SrcLexer.VISIBLE:
309*cdf0e10cSrcweir                self.visibilityStack[-1] = SrcLexer.INVISIBLE_POST
310*cdf0e10cSrcweir            elif self.visibilityStack[-1] == SrcLexer.INVISIBLE_PRE:
311*cdf0e10cSrcweir                # Evaluate only if the current visibility is false.
312*cdf0e10cSrcweir                if self.evalCodeVisibility(buf):
313*cdf0e10cSrcweir                    self.visibilityStack[-1] = SrcLexer.VISIBLE
314*cdf0e10cSrcweir
315*cdf0e10cSrcweir        elif command == 'else':
316*cdf0e10cSrcweir            if len(self.visibilityStack) == 0:
317*cdf0e10cSrcweir                raise ParseError ('')
318*cdf0e10cSrcweir
319*cdf0e10cSrcweir            if self.visibilityStack[-1] == SrcLexer.VISIBLE:
320*cdf0e10cSrcweir                self.visibilityStack[-1] = SrcLexer.INVISIBLE_POST
321*cdf0e10cSrcweir            if self.visibilityStack[-1] == SrcLexer.INVISIBLE_PRE:
322*cdf0e10cSrcweir                self.visibilityStack[-1] = SrcLexer.VISIBLE
323*cdf0e10cSrcweir
324*cdf0e10cSrcweir        elif command == 'endif':
325*cdf0e10cSrcweir            if len(self.visibilityStack) == 0:
326*cdf0e10cSrcweir                raise ParseError ('')
327*cdf0e10cSrcweir            self.visibilityStack.pop()
328*cdf0e10cSrcweir
329*cdf0e10cSrcweir        elif command == 'undef':
330*cdf0e10cSrcweir            pass
331*cdf0e10cSrcweir        elif command in ['error', 'pragma']:
332*cdf0e10cSrcweir            pass
333*cdf0e10cSrcweir        else:
334*cdf0e10cSrcweir            print "'%s' '%s'"%(command, buf)
335*cdf0e10cSrcweir            print self.filepath
336*cdf0e10cSrcweir            sys.exit(0)
337*cdf0e10cSrcweir
338*cdf0e10cSrcweir        return i
339*cdf0e10cSrcweir
340*cdf0e10cSrcweir
341*cdf0e10cSrcweir    def evalCodeVisibility (self, buf):
342*cdf0e10cSrcweir        try:
343*cdf0e10cSrcweir            return eval(buf)
344*cdf0e10cSrcweir        except:
345*cdf0e10cSrcweir            return True
346*cdf0e10cSrcweir
347*cdf0e10cSrcweir    def handleMacroDefine (self, buf):
348*cdf0e10cSrcweir
349*cdf0e10cSrcweir        mparser = macroparser.MacroParser(buf)
350*cdf0e10cSrcweir        mparser.debug = self.debugMacro
351*cdf0e10cSrcweir        mparser.parse()
352*cdf0e10cSrcweir        macro = mparser.getMacro()
353*cdf0e10cSrcweir        if macro:
354*cdf0e10cSrcweir            self.defines[macro.name] = macro
355*cdf0e10cSrcweir
356*cdf0e10cSrcweir    def handleMacroInclude (self, buf):
357*cdf0e10cSrcweir
358*cdf0e10cSrcweir        # Strip excess string if any.
359*cdf0e10cSrcweir        pos = buf.find(' ')
360*cdf0e10cSrcweir        if pos >= 0:
361*cdf0e10cSrcweir            buf = buf[:pos]
362*cdf0e10cSrcweir        headerSub = removeHeaderQuotes(buf)
363*cdf0e10cSrcweir
364*cdf0e10cSrcweir        if not self.expandHeaders:
365*cdf0e10cSrcweir            # We don't want to expand headers.  Bail out.
366*cdf0e10cSrcweir            if self.debug:
367*cdf0e10cSrcweir                progress ("%s ignored\n"%headerSub)
368*cdf0e10cSrcweir            return
369*cdf0e10cSrcweir
370*cdf0e10cSrcweir        defines = {}
371*cdf0e10cSrcweir        headerPath = None
372*cdf0e10cSrcweir        for includeDir in self.includeDirs:
373*cdf0e10cSrcweir            hpath = includeDir + '/' + headerSub
374*cdf0e10cSrcweir            if os.path.isfile(hpath) and hpath != self.filepath:
375*cdf0e10cSrcweir                headerPath = hpath
376*cdf0e10cSrcweir                break
377*cdf0e10cSrcweir
378*cdf0e10cSrcweir        if not headerPath:
379*cdf0e10cSrcweir            error("included header file " + headerSub + " not found\n", self.stopOnHeader)
380*cdf0e10cSrcweir            return
381*cdf0e10cSrcweir
382*cdf0e10cSrcweir        if self.debug:
383*cdf0e10cSrcweir            progress ("%s found\n"%headerPath)
384*cdf0e10cSrcweir
385*cdf0e10cSrcweir        if headerPath in self.headerDict:
386*cdf0e10cSrcweir            if self.debug:
387*cdf0e10cSrcweir                progress ("%s already included\n"%headerPath)
388*cdf0e10cSrcweir            return
389*cdf0e10cSrcweir
390*cdf0e10cSrcweir        if SrcLexer.headerCache.has_key(headerPath):
391*cdf0e10cSrcweir            if self.debug:
392*cdf0e10cSrcweir                progress ("%s in cache\n"%headerPath)
393*cdf0e10cSrcweir            for key in SrcLexer.headerCache[headerPath].defines.keys():
394*cdf0e10cSrcweir                self.defines[key] = SrcLexer.headerCache[headerPath].defines[key]
395*cdf0e10cSrcweir            return
396*cdf0e10cSrcweir
397*cdf0e10cSrcweir        chars = open(headerPath, 'r').read()
398*cdf0e10cSrcweir        mclexer = SrcLexer(chars, headerPath)
399*cdf0e10cSrcweir        mclexer.copyProperties(self)
400*cdf0e10cSrcweir        mclexer.parentLexer = self
401*cdf0e10cSrcweir        mclexer.tokenize()
402*cdf0e10cSrcweir        hdrData = HeaderData()
403*cdf0e10cSrcweir        hdrData.tokens = mclexer.getTokens()
404*cdf0e10cSrcweir        headerDefines = mclexer.getDefines()
405*cdf0e10cSrcweir        for key in headerDefines.keys():
406*cdf0e10cSrcweir            defines[key] = headerDefines[key]
407*cdf0e10cSrcweir            hdrData.defines[key] = headerDefines[key]
408*cdf0e10cSrcweir
409*cdf0e10cSrcweir        self.headerDict[headerPath] = True
410*cdf0e10cSrcweir        SrcLexer.headerCache[headerPath] = hdrData
411*cdf0e10cSrcweir
412*cdf0e10cSrcweir        # Update the list of headers that have already been expaneded.
413*cdf0e10cSrcweir        for key in mclexer.headerDict.keys():
414*cdf0e10cSrcweir            self.headerDict[key] = True
415*cdf0e10cSrcweir
416*cdf0e10cSrcweir        if self.debug:
417*cdf0e10cSrcweir            progress ("defines found in header %s:\n"%headerSub)
418*cdf0e10cSrcweir            for key in defines.keys():
419*cdf0e10cSrcweir                progress ("  '%s'\n"%key)
420*cdf0e10cSrcweir
421*cdf0e10cSrcweir        for key in defines.keys():
422*cdf0e10cSrcweir            self.defines[key] = defines[key]
423*cdf0e10cSrcweir
424*cdf0e10cSrcweir
425*cdf0e10cSrcweir    def slash (self, i):
426*cdf0e10cSrcweir        if not self.isCodeVisible():
427*cdf0e10cSrcweir            return i
428*cdf0e10cSrcweir
429*cdf0e10cSrcweir        if i < self.bufsize - 1 and self.chars[i+1] == '/':
430*cdf0e10cSrcweir            # Parse line comment.
431*cdf0e10cSrcweir            line = ''
432*cdf0e10cSrcweir            i += 2
433*cdf0e10cSrcweir            while i < self.bufsize:
434*cdf0e10cSrcweir                c = self.chars[i]
435*cdf0e10cSrcweir                if ord(c) in [0x0A, 0x0D]:
436*cdf0e10cSrcweir                    return i - 1
437*cdf0e10cSrcweir                line += c
438*cdf0e10cSrcweir                i += 1
439*cdf0e10cSrcweir            self.token = ''
440*cdf0e10cSrcweir        elif i < self.bufsize - 1 and self.chars[i+1] == '*':
441*cdf0e10cSrcweir            comment = ''
442*cdf0e10cSrcweir            i += 2
443*cdf0e10cSrcweir            while i < self.bufsize:
444*cdf0e10cSrcweir                c = self.chars[i]
445*cdf0e10cSrcweir                if c == '/' and self.chars[i-1] == '*':
446*cdf0e10cSrcweir                    return i
447*cdf0e10cSrcweir                comment += c
448*cdf0e10cSrcweir                i += 1
449*cdf0e10cSrcweir        else:
450*cdf0e10cSrcweir            return self.anyToken(i, '/')
451*cdf0e10cSrcweir
452*cdf0e10cSrcweir        return i
453*cdf0e10cSrcweir
454*cdf0e10cSrcweir
455*cdf0e10cSrcweir    def lineBreak (self, i):
456*cdf0e10cSrcweir        if not self.isCodeVisible():
457*cdf0e10cSrcweir            return i
458*cdf0e10cSrcweir
459*cdf0e10cSrcweir        self.maybeAddToken()
460*cdf0e10cSrcweir
461*cdf0e10cSrcweir        return i
462*cdf0e10cSrcweir
463*cdf0e10cSrcweir
464*cdf0e10cSrcweir    def doubleQuote (self, i):
465*cdf0e10cSrcweir        if not self.isCodeVisible():
466*cdf0e10cSrcweir            return i
467*cdf0e10cSrcweir
468*cdf0e10cSrcweir        literal = ''
469*cdf0e10cSrcweir        i += 1
470*cdf0e10cSrcweir        while i < self.bufsize:
471*cdf0e10cSrcweir            c = self.chars[i]
472*cdf0e10cSrcweir            if c == '"':
473*cdf0e10cSrcweir                self.tokens.append('"'+literal+'"')
474*cdf0e10cSrcweir                break
475*cdf0e10cSrcweir            literal += c
476*cdf0e10cSrcweir            i += 1
477*cdf0e10cSrcweir
478*cdf0e10cSrcweir        return i
479*cdf0e10cSrcweir
480*cdf0e10cSrcweir
481*cdf0e10cSrcweir    def anyToken (self, i, token):
482*cdf0e10cSrcweir        if not self.isCodeVisible():
483*cdf0e10cSrcweir            return i
484*cdf0e10cSrcweir
485*cdf0e10cSrcweir        self.maybeAddToken()
486*cdf0e10cSrcweir        self.token = token
487*cdf0e10cSrcweir        self.maybeAddToken()
488*cdf0e10cSrcweir        return i
489