Документ взят из кэша поисковой машины. Адрес оригинального документа : http://www.stsci.edu/spst/UnixTransition/doc/rcsinfo.py
Дата изменения: Fri Feb 28 14:46:11 2014
Дата индексирования: Sat Mar 1 13:55:49 2014
Кодировка:

Поисковые слова: п п п п п п п п
"""RCS rlog interface module.

Defines the class rlog, which represents the rlog information of an rcs
element.

"""

import string
import re

_rlog_comment_sep = '----------------------------\n'
_rlog_end_sep = '=============================================================================\n'
_re_symbolic_name = re.compile("\s+([^:]+):\s+(.+)$")
_re_revision = re.compile("^revision\s+([0-9.]+).*")
_re_data_line = re.compile(
"^date:\s+(\d+)/(\d+)/(\d+)\s+(\d+):(\d+):(\d+);\s+"\
"author:\s+([^;]+);\s+"\
"state:\s+([^;]+);\s+"\
"lines:\s+\+(\d+)\s+\-(\d+)$")
_re_data_line_add = re.compile(
"^date:\s+(\d+)/(\d+)/(\d+)\s+(\d+):(\d+):(\d+);\s+"\
"author:\s+([^;]+);\s+"\
"state:\s+([^;]+);$")
Month_name = ["", "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", \
"Aug", "Sep", "Oct", "Nov", "Dec"]

class RCS_info:

def __init__(self, info_list):
"""Constructor."""
self.info_dict = self.info (info_list)
pass

def __del__(self):
"""Destructor."""
pass

def element_name(self):
"""Return the element name."""
return self.info_dict['Working file']

def head(self):
"""Return the head revision for this element."""
return self.info_dict['head']

def tag_to_rev (self, tag):
"""Return the revision id for a symbolic ."""
if self.info_dict['symbolic names'].has_key(tag):
return self.info_dict['symbolic names'][tag]
else:
return None

def state(self, tag):
"""Return the state for revision ."""
if self.info_dict['revisions'].has_key(tag):
return self.info_dict['revisions'][tag]['state']
else:
# Translate the to a revision number and get the state.
rev = self.tag_to_rev (tag)
if (rev != None) and (self.info_dict['revisions'].has_key(rev)):
return self.info_dict['revisions'][rev]['state']
else:
return None

def descript (self, tag):
"""Return the description for the element if is <> or
returns the description of the specific revision of
the element.
"""
if tag == "":
# Return the main description for this element.
return self.info_dict['description']
elif self.info_dict['revisions'].has_key(tag):
# If is a revision number return the description for this
# revision.
return self.info_dict['revisions'][tag]['description']
else:
# Translate the to a revision number and get the description.
rev = self.tag_to_rev (tag)
if (rev != None) and (self.info_dict['revisions'].has_key(rev)):
return self.info_dict['revisions'][rev]['description']
else:
return None

def print_info (self, name_rev):
"""Print a listing of the rlog contents for element NAME_REV"""
keys = self.info_dict.keys()
keys.sort ()
for key in keys:
if key == 'symbolic names':
print key, ": "
skeys = self.info_dict[key].keys()
skeys.sort ()
for skey in skeys:
print " ", skey, ": ", self.info_dict[key][skey]
elif key == 'revisions':
print key, ": "
rkeys = self.info_dict[key].keys()
for rkey in rkeys:
print " ", rkey, " = "
r2keys = self.info_dict[key][rkey].keys()
r2keys.sort ()
for r2key in r2keys:
print " ", r2key, ": ", self.info_dict[key][rkey][r2key]
else:
print key, ": ", self.info_dict[key]

def info(self, info_list):
"""Return a dictionary of info (from rlog) for NAME_REV

The dictionary's keys are the keywords that rlog prints
(e.g. 'head' and its values are the corresponding data
(e.g. '1.3').

XXX locks are not returned

"""
info_list_size = len(info_list)
dict = {}
i = 0
while i < info_list_size:
line = info_list[i]
i += 1
if i >= info_list_size: break
if line[0] == '\t':
# XXX could be a lock or symbolic name
# Anything else?
continue
j = string.find(line, ':')
if j > 0:
key, value = line[:j], string.strip(line[j+1:])
# Handle symbolic name list.
if key == 'symbolic names':
dict[key], offset = self.parse_symbolic_names(info_list[i:])
#Increment the counter by the number of lines read.
i += offset
elif key == 'total revisions':
# From this point out need to individually process lines.
break
else:
dict[key] = value

dict["description"], offset = self.parse_description (info_list[i:])
i += offset
dict["revisions"] = self.parse_revision_entries (info_list[i:])

return dict

# --- Internal methods ---

def parse_symbolic_names(self, info_list):
""" Parse all the symbolic tag names.
Return the last unmatched line and a list of tags.
"""

symbolic_name_dict = {}
i2 = 0
info_list_size = len(info_list)
while i2 < info_list_size:
line = info_list[i2]
i2 += 1
match = _re_symbolic_name.match(line)
if not match:
return symbolic_name_dict, i2 -1
break

(tag, revision) = match.groups()

## check if the tag represents a branch, in RCS this means
## the second-to-last number is a zero
index = string.rfind(revision, '.')
if revision[index-2:index] == '.0':
revision = revision[:index-2] + revision[index:]

symbolic_name_dict[tag] = revision

return symbolic_name_dict, i2

def parse_description(self, info_list):
"""Returns a description line."""

description_line = []
i2 = 0
info_list_size = len(info_list)
while i2 < info_list_size:
line = info_list[i2]
i2 += 1
if line[:12] == 'description:':
break

# Record the description.
while i2 < info_list_size:
line = info_list[i2]
i2 += 1
# The last line printed out by rlog is '===='...
# or '------'... between entries.
if line == _rlog_comment_sep or line == _rlog_end_sep:
break

# Append line to the descripton list
description_line.append(string.rstrip(line))
if description_line == []:
return "", i2
else:
return string.join(description_line, '\n'), i2

def parse_revision_entries(self, info_list):
"""Parse the contents of all the revision entries for an element. """
revision_list = {}
i2 = 0
info_list_size = len(info_list)
while i2 < info_list_size:
revision_entry, offset = self.parse_one_revision_entry(info_list[i2:])
i2 += offset
if not revision_entry:
break
revision_list[revision_entry["revision"]] = revision_entry
return revision_list

def parse_one_revision_entry(self, info_list):
"""Parse the contents of a single revision entry."""
import time

i2 = 0
info_list_size = len(info_list)
# Parse the revision information on this line.
line = info_list[i2]
i2 += 1
# Since FreeBSD's rlog outputs extra "---...---\n" before
# "===...===\n", _rlog_end may be occured here.
if (i2 >= info_list_size) or line == _rlog_end_sep:
return None, i2

## revision
match = _re_revision.match(line)
(revision,) = match.groups()

## data line
line = info_list[i2]
i2 += 1
match = _re_data_line.match(line)
if not match:
match = _re_data_line_add.match(line)

if not match:
raise error, "bad rlog parser, no cookie!"

## retrieve the matched grops as a tuple in hopes
## this will be faster (ala profiler)
groups = match.groups()

year = string.atoi(groups[0])
month = string.atoi(groups[1])
day = string.atoi(groups[2])
hour = string.atoi(groups[3])
minute = string.atoi(groups[4])
second = string.atoi(groups[5])

date = groups[2] + "-" + Month_name[month] + "-" + groups[0] + " "\
+ groups[3] + ":" + groups[4] + ":" + groups[5]

## compute time using time routines in seconds from epoc GMT
## NOTE: mktime's arguments are in local time, and we have
## them in GMT from RCS; therefore, we have to manually
## subtract out the timezone correction
##
## XXX: Linux glib2.0.7 bug: it looks like mktime doesn't honor
## the '0' flag to force no timezone correction, so we look
## at the correction ourself and do the right thing after
## mktime mangles the date
gmt_time = \
time.mktime((year, month, day, hour, minute, second, 0, 0, -1))

if time.localtime(gmt_time)[8] == 1:
# dst time active?
# XXX: This is still wrong in those both nights,
# where the switch between DST and normal time occurs.
gmt_time = gmt_time - time.altzone
else:
gmt_time = gmt_time - time.timezone

author = groups[6]
state = groups[7]

## very strange; here's the deal: if this is a newly added file,
## then there is no plus/minus count count of lines; if there
## is, then this could be a "CHANGE" or "REMOVE", you can tell
## if the file has been removed by looking if state == 'dead'
try:
pluscount = groups[8]
minuscount = groups[9]
except IndexError:
pluscount = ''
minuscount = ''

## branch line: pretty much ignored if it's there
desc_line_list = []

line = info_list[i2]
i2 += 1
if not line[:10] == 'branches: ':
desc_line_list.append(string.rstrip(line))

## suck up description
while i2 <= info_list_size:
line = info_list[i2]
i2 += 1
## the last line printed out by rlog is '===='...
## or '------'... between entries
if line == _rlog_comment_sep or line == _rlog_end_sep:
break

## append line to the descripton list
desc_line_list.append(string.rstrip(line))

# Now create the final dictionary for storing the revision info.
revision_entry = {}
revision_entry["revision"] = revision
revision_entry["date"] = date
revision_entry["gmt-time"] = gmt_time
revision_entry["author"] = author
revision_entry["state"] = state
revision_entry["pluscount"] = pluscount
revision_entry["minuscount"] = minuscount
revision_entry["description"] = string.join(desc_line_list, '\n')

return revision_entry, i2