def str_as_atr(s):
if s == '_':
return []
atr = []
i = 0
while i < len(s):
v = s[i]
if i + 1 < len(s) and s[i+1].isdigit():
n = 0
i = i + 1
while i < len(s) and s[i].isdigit():
n = n * 10 + int(s[i])
i += 1
else:
i += 1
n = 1
for j in range(n):
atr.append(v)
return atr
def atr_as_str(atr):
if not atr:
return '_'
prefl = []
prestr = ''.join([str(x) for x in atr])
i = 0
while i < len(prestr):
c = prestr[i]
j = i+1
while j < len(prestr) and prestr[j] == c:
j += 1
if j - i > 2:
prefl.append(c)
prefl.append(str(j-i))
else:
while i < j:
prefl.append(c)
i += 1
i = j
return ''.join(prefl)
def str_as_ixl(s):
return [ord(ch)-ord('a') for ch in str_as_atr(s)]
def ixl_as_str(ixl):
return atr_as_str([chr(ix + ord('a')) for ix in ixl])
class Paths:
def __init__(self, mod, rp, key, extended=True, andsets=(), variant=2):
self.mod = mod
self._hiding_tag_ = mod._hiding_tag_
self.key = key
self.rp = rp
self.extended = extended
self.srcrow = rp.get_row(self.key)
self.variant = variant
self.andsetbyname = {}
row = self.srcrow
while row is not None:
self.andsetbyname[row.ixlstr] = mod.Use.Anything
row = row.parent
if isinstance(andsets, dict):
self.andsetbyname.update(andsets)
elif isinstance(andsets, (tuple, list)):
row = self.srcrow
for i, s in enumerate(andsets):
if row is None:
raise ValueError('andsets argument is too long')
if s is not None:
self.andsetbyname[row.ixlstr] = s
row = row.parent
else:
raise TypeError('andsets argument must be dict, tuple, or list')
mod.OutputHandling.setup_printing(
self,
stop_only_when_told=variant >= 2)
def get_str_of_path_component_singleton(self, set):
return set.brief.lstrip('<1 ').rstrip('>')
def source_to_target_info(self):
src = 'Source'
tgt = 'Target'
via = 'Via'
row = self.srcrow
indent = 0
while row is not None:
if row.parent is None:
a = tgt
elif row is srcrow:
a = src
else:
a = via
a = ' '*indent + a
name = row.ixlstr
a = a + ' ' + ' '*(8+srcrow.depth*indinc -
len(name)-len(a)) + name + ': '
yield a+row.getsummary(mod.line_length-len(a))
row = row.parent
indent += indinc
def _oh_get_label(self):
return 'Paths from source %r to target %r.' % (self.srcrow.ixlstr, '_')
def _oh_get_line_iter(self):
return getattr(self, 'get_line_iter_%s' % (self.variant,))()
def _oh_get_more_state_msg(self, startindex, lastindex):
return ''
def get_line_iter_1(self):
# Original variant indenting from left to right
mod = self.mod
srcrow = self.srcrow
srcset = srcrow.set
indinc = 2
if srcrow.depth >= 10:
indinc = 1
def genlines(row, ks, indent=0):
par = row.parent
for key, i, set in ks:
sidx = '%s[%d]' % (row.ixlstr, i)
if self.extended:
strsing = self.get_str_of_path_component_singleton(set)
else:
strsing = ''
vline = '%s %s %s %s' % (
key,
' '*(40-len(key) - len(sidx)),
sidx,
strsing
)
yield vline
if par is None:
continue
def get_nks(key, set):
parset = set.referents & par.set
for i, p in enumerate(parset.byid.parts):
rels = mod.Path.relations(set.theone, p.theone)
for rel in rels:
if rel is mod.Path.identity:
continue
if rel is mod.Path.norelation:
k = '??'
else:
k = str(rel) % ''
k = ' '*(indent+indinc)+k
yield k, i, p
for line in genlines(par, get_nks(key, set), indent+indinc):
yield line
def get_ks():
for i, s in enumerate(srcset.byid.parts):
k = '[%d] ' % i
k = k + (' -'*20)[:36-len(k)-srcrow.depth]
yield k, i, s
for line in genlines(srcrow, get_ks()):
yield line
return
def get_line_iter_2(self):
# Newer variant
mod = self.mod
srcrow = self.srcrow
indinc = 1
if srcrow.depth >= 10:
indinc = 1
lno = [0]
seen = {}
indir = 1
if indir == 1:
max_ixlstr_len = 0
max_str_len_set = 0
row = srcrow
while row:
if len(row.ixlstr) > max_ixlstr_len:
max_ixlstr_len = len(row.ixlstr)
if len(str(len(row.set.nodes))) > max_str_len_set:
max_str_len_set = len(str(len(row.set.nodes)))
row = row.parent
def genlines(row, part, idx):
seen[part.nodes, row.depth] = lno[0]
sidx = row.ixlstr
idxs = '[%d]' % idx
if indir < 0:
indent = (row.depth)*indinc
sidx = '%s%s%s' % (
sidx, ' '*(6+indent-len(sidx)-len(idxs)), idxs)
if row.parent is None:
sidx += ' == %s' % part.brief
else:
#idxs = ('[%.'+str(max_str_len_set)+'d]')%idx
sidx = '%s%s%s' % (sidx,
' '*(3+max_str_len_set +
max_ixlstr_len-len(sidx)-len(idxs)),
idxs)
sidx += ' ' * (srcrow.depth + 1 - row.depth)
if row.parent is not None:
sidx += '@'
else:
sidx += '= %s' % part.brief
if row.parent is None:
#vline += ' == %s'%self.get_str_of_path_component_singleton(part)
vline = '%2s: %s' % (lno[0], sidx)
lno[0] += 1
yield ('STOP_AFTER', vline)
return
referents = part.referents & row.parent.set & self.andsetbyname[row.parent.ixlstr]
relations = mod.Path.relations
iso = mod.Use.iso
s = part.theone
t = [(relations(s, p.theone), p.by(referents.er), i)
for (i, p) in enumerate(referents.byid.parts)]
for (rels, p, i) in t:
relstrings = []
for rel in rels:
if rel is mod.Path.identity:
continue
if rel is mod.Path.norelation:
k = '??'
else:
k = str(rel) % ''
relstrings.append(k)
relsstr = ' / '.join(relstrings)
seenlno = seen.get((p.nodes, row.parent.depth))
vline = '%2s: %s' % (lno[0], sidx)
lno[0] += 1
if seenlno is not None:
relsstr += ' -> #%d' % seenlno
yield ('STOP_AFTER', vline + ' ' + relsstr)
else:
yield vline + ' ' + relsstr
for line in genlines(row.parent, p, i):
yield line
for i, p in enumerate((srcrow.set & self.andsetbyname[srcrow.ixlstr]).byid.parts):
for line in genlines(srcrow, p, i):
yield line
class RefPatIter:
def __init__(self, rp, start=0):
self.rp = rp
self._hiding_tag_ = rp._hiding_tag_
self.ix = start
def __iter__(self):
return self
def __next__(self):
try:
x = self.rp[self.ix]
except IndexError:
raise StopIteration
self.ix += 1
return x
class RefPatRow:
def __init__(self, rp, kindset, seenline, ixl, parent):
self.rp = rp
self._hiding_tag_ = rp._hiding_tag_
self.kindset = kindset
self.kind, self.set = kindset
assert self.set <= self.kind
self.seenline = seenline
self.ixl = ixl[:]
self.parent = parent
if parent is not None:
self.depth = parent.depth + 1
else:
self.depth = 0
self.index = 0
self.maxdepth = rp.depth
self.max_str_len = rp.mod.line_length
self.ixlstr = ixl_as_str(ixl)
self.isready = 0
self.children = []
def __str__(self):
prestr = '%2d: %s ' % (self.index, self.ixlstr)
if self.index & 1:
fillpat = ' ' * 100
else:
fillpat = '-'*100
lps = len(prestr)
fill = fillpat[lps:9+self.depth]
if self.seenline:
ref = '[^ %s]' % self.seenline.index
elif self.isroot:
ref = '[R]'
elif self.depth > 0 and self.set <= self.rp.stopkind:
ref = '[S]'
elif self.depth < self.maxdepth:
ref = '[-]'
else:
ref = '[+]'
prefix = '%s%s %s ' % (prestr, fill, ref)
return '%s%s' % (prefix, self.getsummary(self.max_str_len-len(prefix)))
def getchild(self, ix):
while ix >= len(self.children) and not self.isready:
self.rp.generate(len(self.rp.lines))
return self.children[ix]
def getsummary(self, max_len):
kind, set = self.kind, self.set
summary = set.fam.get_str_refpat(set, kind, max_len)
return summary
class ReferencePattern:
__doc__ = '