Beispiel #1
0
  def parse_rcs_tree(self):
    while 1:
      revision = self.ts.get()

      # End of RCS tree description ?
      if revision == 'desc':
        self.ts.unget(revision)
        return

      # Parse date
      semi, date, sym = self.ts.mget(3)
      if sym != 'date':
        raise RCSExpected(sym, 'date')
      if semi != ';':
        raise RCSExpected(semi, ';')

      # Convert date into timestamp
      date_fields = string.split(date, '.') + ['0', '0', '0']
      date_fields = map(string.atoi, date_fields)
      # need to make the date four digits for timegm
      EPOCH = 1970
      if date_fields[0] < EPOCH:
          if date_fields[0] < 70:
              date_fields[0] = date_fields[0] + 2000
          else:
              date_fields[0] = date_fields[0] + 1900
          if date_fields[0] < EPOCH:
              raise ValueError, 'invalid year'

      timestamp = compat.timegm(tuple(date_fields))

      # Parse author
      ### NOTE: authors containing whitespace are violations of the
      ### RCS specification.  We are making an allowance here because
      ### CVSNT is known to produce these sorts of authors.
      self.ts.match('author')
      author = ''
      while 1:
        token = self.ts.get()
        if token == ';':
          break
        author = author + token + ' '
      author = author[:-1]  # toss the trailing space

      # Parse state
      self.ts.match('state')
      state = ''
      while 1:
        token = self.ts.get()
        if token == ';':
          break
        state = state + token + ' '
      state = state[:-1]  # toss the trailing space

      # Parse branches
      self.ts.match('branches')
      branches = [ ]
      while 1:
        token = self.ts.get()
        if token == ';':
          break
        branches.append(token)

      # Parse revision of next delta in chain
      next, sym = self.ts.mget(2)
      if sym != 'next':
        raise RCSExpected(sym, 'next')
      if next == ';':
        next = None
      else:
        self.ts.match(';')

      # there are some files with extra tags in them. for example:
      #    owner	640;
      #    group	15;
      #    permissions	644;
      #    hardlinks	@configure.in@;
      # this is "newphrase" in RCSFILE(5). we just want to skip over these.
      while 1:
        token = self.ts.get()
        if token == 'desc' or token[0] in string.digits:
          self.ts.unget(token)
          break
        # consume everything up to the semicolon
        while self.ts.get() != ';':
          pass

      self.sink.define_revision(revision, timestamp, author, state, branches,
                                next)
Beispiel #2
0
def _parse_log_entry(fp):
  """Parse a single log entry.

  On entry, fp should point to the first line of the entry (the "revision"
  line).
  On exit, fp will have consumed the log separator line (dashes) or the
  end-of-file marker (equals).

  Returns: Revision object and eof flag (see _EOF_*)
  """
  rev = None
  line = fp.readline()
  if not line:
    return None, _EOF_LOG
  if line == LOG_END_MARKER:
    # Needed because some versions of RCS precede LOG_END_MARKER
    # with ENTRY_END_MARKER
    return None, _EOF_FILE
  if line[:8] == 'revision':
    match = _re_rev.match(line)
    if not match:
      return None, _EOF_LOG
    rev = match.group(1)

    line = fp.readline()
    if not line:
      return None, _EOF_LOG
    match = _re_log_info.match(line)

  eof = None
  log = ''
  while 1:
    line = fp.readline()
    if not line:
      # true end-of-file
      eof = _EOF_LOG
      break
    if line[:9] == 'branches:':
      continue
    if line == ENTRY_END_MARKER:
      break
    if line == LOG_END_MARKER:
      # end of this file's log information
      eof = _EOF_FILE
      break

    log = log + line

  if not rev or not match:
    # there was a parsing error
    return None, eof

  # parse out a time tuple for the local time
  tm = compat.cvs_strptime(match.group(1))

  # rlog seems to assume that two-digit years are 1900-based (so, "04"
  # comes out as "1904", not "2004").
  EPOCH = 1970
  if tm[0] < EPOCH:
    tm = list(tm)
    if (tm[0] - 1900) < 70:
      tm[0] = tm[0] + 100
    if tm[0] < EPOCH:
      raise ValueError, 'invalid year'
  date = compat.timegm(tm)

  return Revision(rev, date,
                  # author, state, lines changed
                  match.group(2), match.group(3) == "dead", match.group(5),
                  log), eof