"Fossies" - the Fresh Open Source Software Archive

Member "cheetah3-3.2.6.post2/Cheetah/SourceReader.py" (20 Apr 2021, 7774 Bytes) of package /linux/www/cheetah3-3.2.6.post2.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Python source code syntax highlighting (style: standard) with prefixed line numbers. Alternatively you can here view or download the uninterpreted source code file. For more information about "SourceReader.py" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 3-3.1.0_vs_3-3.2.0.

    1 """SourceReader class for Cheetah's Parser and CodeGenerator
    2 """
    3 import re
    4 from Cheetah.compat import unicode
    5 
    6 EOLre = re.compile(r'[ \f\t]*(?:\r\n|\r|\n)')
    7 EOLZre = re.compile(r'(?:\r\n|\r|\n|\Z)')
    8 ENCODINGsearch = re.compile("coding[=:]\s*([-\w.]+)").search
    9 
   10 
   11 class Error(Exception):
   12     pass
   13 
   14 
   15 class SourceReader(object):
   16     def __init__(self, src, filename=None, breakPoint=None, encoding=None):
   17         self._src = src
   18         self._filename = filename
   19         self._srcLen = len(src)
   20         if breakPoint is None:
   21             self._breakPoint = self._srcLen
   22         else:
   23             self.setBreakPoint(breakPoint)
   24         self._pos = 0
   25         self._bookmarks = {}
   26         self._posTobookmarkMap = {}
   27 
   28         # collect some meta-information
   29         self._EOLs = []
   30         pos = 0
   31         while pos < len(self):
   32             EOLmatch = EOLZre.search(src, pos)
   33             self._EOLs.append(EOLmatch.start())
   34             pos = EOLmatch.end()
   35 
   36         self._BOLs = []
   37         for pos in self._EOLs:
   38             BOLpos = self.findBOL(pos)
   39             self._BOLs.append(BOLpos)
   40 
   41     def src(self):
   42         return self._src
   43 
   44     def filename(self):
   45         return self._filename
   46 
   47     def __len__(self):
   48         return self._breakPoint
   49 
   50     def __getitem__(self, i):
   51         if not isinstance(i, int):
   52             self.checkPos(i.stop)
   53         else:
   54             self.checkPos(i)
   55         return self._src[i]
   56 
   57     def __getslice__(self, i, j):
   58         i = max(i, 0)
   59         j = max(j, 0)
   60         return self._src[i:j]
   61 
   62     def splitlines(self):
   63         if not hasattr(self, '_srcLines'):
   64             self._srcLines = self._src.splitlines()
   65         return self._srcLines
   66 
   67     def lineNum(self, pos=None):
   68         if pos is None:
   69             pos = self._pos
   70 
   71         for i in range(len(self._BOLs)):
   72             if pos >= self._BOLs[i] and pos <= self._EOLs[i]:
   73                 return i
   74 
   75     def getRowCol(self, pos=None):
   76         if pos is None:
   77             pos = self._pos
   78         lineNum = self.lineNum(pos)
   79         BOL = self._BOLs[lineNum]
   80         return lineNum + 1, pos - BOL + 1
   81 
   82     def getRowColLine(self, pos=None):
   83         if pos is None:
   84             pos = self._pos
   85         row, col = self.getRowCol(pos)
   86         return row, col, self.splitlines()[row - 1]
   87 
   88     def getLine(self, pos):
   89         if pos is None:
   90             pos = self._pos
   91         lineNum = self.lineNum(pos)
   92         return self.splitlines()[lineNum]
   93 
   94     def pos(self):
   95         return self._pos
   96 
   97     def setPos(self, pos):
   98         self.checkPos(pos)
   99         self._pos = pos
  100 
  101     def validPos(self, pos):
  102         return pos <= self._breakPoint and pos >= 0
  103 
  104     def checkPos(self, pos):
  105         if not pos <= self._breakPoint:
  106             raise Error(
  107                 "pos (" + str(pos) + ") is invalid: beyond the stream's end ("
  108                 + str(self._breakPoint - 1) + ")")
  109         elif not pos >= 0:
  110             raise Error("pos (" + str(pos) + ") is invalid: less than 0")
  111 
  112     def breakPoint(self):
  113         return self._breakPoint
  114 
  115     def setBreakPoint(self, pos):
  116         if pos > self._srcLen:
  117             raise Error(
  118                 "New breakpoint (" + str(pos)
  119                 + ") is invalid: beyond the end of stream's source string ("
  120                 + str(self._srcLen) + ")")
  121         elif not pos >= 0:
  122             raise Error(
  123                 "New breakpoint (" + str(pos) + ") is invalid: less than 0")
  124 
  125         self._breakPoint = pos
  126 
  127     def setBookmark(self, name):
  128         self._bookmarks[name] = self._pos
  129         self._posTobookmarkMap[self._pos] = name
  130 
  131     def hasBookmark(self, name):
  132         return name in self._bookmarks
  133 
  134     def gotoBookmark(self, name):
  135         if not self.hasBookmark(name):
  136             raise Error(
  137                 "Invalid bookmark (" + name + ") is invalid: does not exist")
  138         pos = self._bookmarks[name]
  139         if not self.validPos(pos):
  140             raise Error("Invalid bookmark (" + name + ', '
  141                         + str(pos) + ") is invalid: pos is out of range")
  142         self._pos = pos
  143 
  144     def atEnd(self):
  145         return self._pos >= self._breakPoint
  146 
  147     def atStart(self):
  148         return self._pos == 0
  149 
  150     def peek(self, offset=0):
  151         self.checkPos(self._pos + offset)
  152         pos = self._pos + offset
  153         return self._src[pos]
  154 
  155     def getc(self):
  156         pos = self._pos
  157         if self.validPos(pos + 1):
  158             self._pos += 1
  159         return self._src[pos]
  160 
  161     def ungetc(self, c=None):
  162         if not self.atStart():
  163             raise Error('Already at beginning of stream')
  164 
  165         self._pos -= 1
  166         if c is not None:
  167             self._src[self._pos] = c
  168 
  169     def advance(self, offset=1):
  170         self.checkPos(self._pos + offset)
  171         self._pos += offset
  172 
  173     def rev(self, offset=1):
  174         self.checkPos(self._pos - offset)
  175         self._pos -= offset
  176 
  177     def read(self, offset):
  178         self.checkPos(self._pos + offset)
  179         start = self._pos
  180         self._pos += offset
  181         return self._src[start:self._pos]
  182 
  183     def readTo(self, to, start=None):
  184         self.checkPos(to)
  185         if start is None:
  186             start = self._pos
  187         self._pos = to
  188         return self._src[start:to]
  189 
  190     def readToEOL(self, start=None, gobble=True):
  191         EOLmatch = EOLZre.search(self.src(), self.pos())
  192         if gobble:
  193             pos = EOLmatch.end()
  194         else:
  195             pos = EOLmatch.start()
  196         return self.readTo(to=pos, start=start)
  197 
  198     def find(self, it, pos=None):
  199         if pos is None:
  200             pos = self._pos
  201         return self._src.find(it, pos)
  202 
  203     def startswith(self, it, pos=None):
  204         if self.find(it, pos) == self.pos():
  205             return True
  206         else:
  207             return False
  208 
  209     def rfind(self, it, pos):
  210         if pos is None:
  211             pos = self._pos
  212         return self._src.rfind(it, pos)
  213 
  214     def findBOL(self, pos=None):
  215         if pos is None:
  216             pos = self._pos
  217         src = self.src()
  218         return max(src.rfind('\n', 0, pos) + 1, src.rfind('\r', 0, pos) + 1, 0)
  219 
  220     def findEOL(self, pos=None, gobble=False):
  221         if pos is None:
  222             pos = self._pos
  223 
  224         match = EOLZre.search(self.src(), pos)
  225         if gobble:
  226             return match.end()
  227         else:
  228             return match.start()
  229 
  230     def isLineClearToPos(self, pos=None):
  231         if pos is None:
  232             pos = self.pos()
  233         self.checkPos(pos)
  234         src = self.src()
  235         BOL = self.findBOL()
  236         return BOL == pos or src[BOL:pos].isspace()
  237 
  238     def matches(self, strOrRE):
  239         if isinstance(strOrRE, (str, unicode)):
  240             return self.startswith(strOrRE, pos=self.pos())
  241         else:  # assume an re object
  242             return strOrRE.match(self.src(), self.pos())
  243 
  244     def matchWhiteSpace(self, WSchars=' \f\t'):
  245         return (not self.atEnd()) and self.peek() in WSchars
  246 
  247     def getWhiteSpace(self, max=None, WSchars=' \f\t'):
  248         if not self.matchWhiteSpace(WSchars):
  249             return ''
  250         start = self.pos()
  251         breakPoint = self.breakPoint()
  252         if max is not None:
  253             breakPoint = min(breakPoint, self.pos() + max)
  254         while self.pos() < breakPoint:
  255             self.advance()
  256             if not self.matchWhiteSpace(WSchars):
  257                 break
  258         return self.src()[start:self.pos()]
  259 
  260     def matchNonWhiteSpace(self, WSchars=' \f\t\n\r'):
  261         return self.atEnd() or not self.peek() in WSchars
  262 
  263     def getNonWhiteSpace(self, WSchars=' \f\t\n\r'):
  264         if not self.matchNonWhiteSpace(WSchars):
  265             return ''
  266         start = self.pos()
  267         while self.pos() < self.breakPoint():
  268             self.advance()
  269             if not self.matchNonWhiteSpace(WSchars):
  270                 break
  271         return self.src()[start:self.pos()]