Mercurial > hg > python
changeset 65:5e5feacb730d
abandon regexp, work with lisparser output
author | Henry S. Thompson <ht@inf.ed.ac.uk> |
---|---|
date | Thu, 14 Dec 2023 16:43:54 +0000 |
parents | fff2fa031ed7 |
children | 53c37a02d471 |
files | repair.py |
diffstat | 1 files changed, 80 insertions(+), 54 deletions(-) [+] |
line wrap: on
line diff
--- a/repair.py Thu Dec 14 11:43:44 2023 +0000 +++ b/repair.py Thu Dec 14 16:43:54 2023 +0000 @@ -1,31 +1,49 @@ +#!/usr/bin/python3 +import sys + import lisparser def readAlist(fn): with open(fn,'r') as f: sline = f.readline() - alines = [l for l in f if (L:=l).startswith("(")] - return sline, alist(alines), L + alines = (l for l in f if (L:=l).startswith("(")) + return sline, alist(alines), L +# alist fields are: group, rank, read, [marks, [method, [params]]] +# string int [list] [plist] expr plist def alist(lines): res = {} for l in lines: ll = lisparser.get_ast(lisparser.normalize_str(l))[0] k = ll.pop(0) - n = ll.pop(0) - t = ll.pop(0) - if ll: - pp = ll.pop(0) - if pp[0] == '(': - pp = dict((a[0],a[1:]) for a in pp) - # Otherwise only "nil", I think, so pass through - else: - pp = None - res[eval(k)]=(n, t, pp, ll) + n = int(ll.pop(0)) + res[eval(k)]=[n]+al2p(ll) return res -# alist fields are: group, rank, read, marks, method, params - -def p2l(pl, f, top = False): +def al2p(ll): + '''handle read (list or nil), maybe marks (plist or nil), usually method, + maybe params (plist)''' + res=[ll.pop(0)] # read + if ll: + marks = ll.pop(0) + if marks != 'nil': + marks = dict((e[0],e[1:]) for e in marks) + res.append(marks) + else: + return res + if ll: + res.append(ll.pop(0)) # method + else: + return res + if ll: + res.append(dict((e[0],e[1:]) for e in ll.pop(0))) # params + else: + return res + if ll: + raise ValueError("too many args: %s"%ll) + return res + +def p2l(pl, f): if isinstance(pl,list) or isinstance(pl,tuple): if len(pl) == 0: f.write('nil') @@ -41,49 +59,33 @@ space = True f.write(')') elif isinstance(pl,dict): - if top: - f.write("(setq gnus-newsrc-alist '(\n") + f.write('(') space = False for k, v in pl.items(): if space: - f.write('%s('%('\n' if top else ' ')) - else: - f.write('(' if top else '((') - space = True - if top: - f.write('"%s"'%k) - for e in v[:3]: # v is [n, t, pp, ll], pp may be None - if e: - f.write(' ') - p2l(e,f) - # ll may be empty - for e in v[3]: - if e: - f.write(' ') - p2l(e,f) + f.write(' (') else: - f.write(k) - for e in v: - f.write(' ') - p2l(e,f) - f.write(')') - if top: - f.write('\n))\n') - else: + f.write('(') + space = True + f.write(k) + for e in v: + f.write(' ') + p2l(e,f) f.write(')') - elif isinstance(pl,str): - if pl in ['.','nil']: - f.write(pl) - else: - try: - int(pl) - f.write(pl) - except ValueError: - f.write(pl) + f.write(')') +# elif isinstance(pl,str): +# if pl in ['.','nil']: +# f.write(pl) +# else: +# try: +# int(pl) +# f.write(pl) +# except ValueError: +# f.write(pl) else: f.write(pl) -def merge(gnus, mail): +def merge(gnus, mail, out): ''' rank, read, marks, method, params @@ -96,12 +98,32 @@ if mail is nil, use gnus otherwise use mail marks: merge unseen keys, unequal values for same key prefer gnus - EXCEPT bogus, w3c-ac-forum, handle by hand + EXCEPT bogus, w3c-ac-forum, handle by hand DONE method: change "ht" to "nnml+ht", flag anything else - FIX group-2002-07 in gnus by hand - params: TBD + FIX group-2002-07 in gnus by hand DONE + params: merge by keys +''' # ' + global g, m + g1, g, g2 = readAlist(gnus) + _, m, _ = readAlist(mail) + with open(out, "w") as outf: + outf.write(g1) + for k, v in g.items(): + if k in m: + return + res = mergeOne(v, m[k]) + else: + res = v + outf.write('("%s" '%k) + outf.write(str(res[0])) # rank + for v in res[1:]: + outf.write(' ') + p2l(v,outf) + outf.write(')\n') + outf.write(g2) - +def stale(): + ''' Comparison tool: @@ -116,3 +138,7 @@ fgrep -hf shared {gnus,mail}/alist.fixed | sed 's/ \([0-9]\) '"$P1 $P2 / \1 \2 \5 /;s/\(.*${T}.*${T}.*${T}\)$MA $P2/\1\2${T}\4/" paste <(cat shared) <(fgrep -f shared mail/alist.fixed | sed 's/ \([0-9]\) '"$P $P/ \1 \2 \5 /g" | cut -f 3) <(fgrep -f shared gnus/alist.fixed | sed 's/ \([0-9]\) '"$P $P/ \1 \2 \5 /g" | cut -f 3) | { IFS=' ' ; while read gn g m; do if [ "$g" != "$m" ]; then printf "=----%s------\n%s\n%s\n" "$gn" "$g" "$m"; fi; done ; } | less ''' + +if __name__ == '__main__': + merge(*sys.argv[1:]) +