Package libxyz :: Package parser :: Module sourcedata |
[hide private]
[frames] | no frames]

# Source Code for Module libxyz.parser.sourcedata

      1  #-*- coding: utf8 -*
      2  #
      3  # Max E. Kuznecov ~syhpoon <syhpoon@syhpoon.name> 2008
      4  #
      5  # This file is part of XYZCommander.
      6  # XYZCommander is free software: you can redistribute it and/or modify
      7  # it under the terms of the GNU Lesser Public License as published by
      8  # the Free Software Foundation, either version 3 of the License, or
      9  # (at your option) any later version.
     10  # XYZCommander is distributed in the hope that it will be useful,
     11  # but WITHOUT ANY WARRANTY; without even the implied warranty of
     12  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
     13  # GNU Lesser Public License for more details.
     14  # You should have received a copy of the GNU Lesser Public License
     15  # along with XYZCommander. If not, see <http://www.gnu.org/licenses/>.
     16
     17  import libxyz
     18
     19 -class SourceData(object):
     20      """
     21      Source data iterator class
     22      """
     23
     24      FILE = 0
     25      STRING = 1
     26
     27 -    def __init__(self, source, bytes=True):
     28          """
     29          @param source: Source
     30          @type source: String or file-like object
     31          @param bytes: If True then object will produce single byte on iteration
     32                        Otherwise it will be single line.
     33          """
     34
     35          self.lineno = 1
     36
     37          self._bytes = bytes
     38          self._source = None
     39          self._index = 0
     40          self._next_me = None
     41          self._len = 0
     42          self._buffer = []
     43
     44          self._source = source
     45          self._intern = u""
     46
     47          if isinstance(source, basestring):
     48              self._intern = _(u"Source string")
     49              self._type = self.STRING
     50              self._next_me = self._next_string
     51              self._len = len(self._source)
     52          # Open file-like object supposed
     53          else:
     54              self._intern = libxyz.core.utils.ustring(source.name)
     55              self._type = self.FILE
     56              self._next_me = self._next_file
     57
     58      #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     59
     60 -    def __iter__(self):
     61          return self
     62
     63      #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     64
     65 -    def next(self):
     66          _res = None
     67
     68          if self._buffer:
     69              _res = self._buffer.pop()
     70          else:
     71              _res = self._next_me()
     72
     73          _res = libxyz.core.utils.ustring(_res)
     74
     75          if _res == u"\n":
     76              self.lineno += 1
     77
     78          return _res
     79
     80      #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     81
     82 -    def _next_file(self):
     83          if self._bytes:
     84              _data = self._source.read(1)
     85          else:
     86              _data = self._source.readline()
     87
     88          # EOF
     89          if not _data:
     90              raise StopIteration()
     91          else:
     92              return _data
     93
     94      #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     95
     96 -    def _next_string(self):
     97          if self._index >= self._len:
     98              raise StopIteration()
     99
    100          if not self._bytes:
    101              _nl = self._source.find(u"\n")
    102
    103              if _nl == -1:
    104                  _data = self._source[self._index:]
    105                  self._index = len(_data)
    106              else:
    107                  _data = self._source[self._index:_nl]
    108                  self._index = _nl
    109          else:
    110              _data = self._source[self._index]
    111              self._index += 1
    112
    113          return _data
    114
    115      #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    116
    117 -    def unget(self, string):
    118          """
    119          Put token back onto input stream
    120          """
    121
    122          self._buffer.extend(reversed(string))
    123
    124          # Decrease lineno if needed
    125          self.lineno -= string.count(u"\n")
    126
    127      #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    128
    129 -    def desc(self):
    130          """
    131          Get source data description
    132          """
    133
    134          return self._intern
    135