changeset 169:7b76125fe80c

Parsing the timestamp database is fully implemented now
author Franz Glasner <hg@dom66.de>
date Fri, 31 Aug 2018 19:35:24 +0200
parents 940b805a5afa
children 0f34be604716
files extensions/timestamps.py
diffstat 1 files changed, 65 insertions(+), 11 deletions(-) [+]
line wrap: on
line diff
--- a/extensions/timestamps.py	Fri Aug 31 09:39:34 2018 +0200
+++ b/extensions/timestamps.py	Fri Aug 31 19:35:24 2018 +0200
@@ -144,13 +144,13 @@
                     db.write("%s %s\n" % (db_escape(fn),
                                           to_isoformat(st.st_mtime)))
 
-
 def restore_timestamps(ui, repo, ctx,
                        tsconfig=None):
     if not repo.local():
         raise error.Abort(_("repository is not local"))
     cmdutil.bailifchanged(repo)
     matcher = gen_matcher(repo, ctx, tsconfig=tsconfig)
+    print list(read_posix_db(os.path.join(repo.root, TIMESTAMPS_DATABASE)))
 
 
 def gen_matcher(repo, ctx, tsconfig=None):
@@ -198,36 +198,90 @@
 
 
 def db_escape(fn):
-    if " " in fn or "@" in fn:
+    if " " in fn or '@' in fn or '#' in fn:
         return "@%s@" % fn.replace("@", "@@")
     else:
         return fn
 
 
 def read_posix_db(filename):
-    with util.posixfile(filename, "rb") as db:
+    with io.open(filename, "rb") as db:
         for f in read_db(db):
             yield f
 
-            
+
 def read_db(db):
     """`db` is a binary file"""
-    db = il.BufferedReader(db)
-    c = db.read()
+    db = io.BufferedReader(db)
+    c = db.read(1)
+    record = []
+    field = []
     while c:
         if c in '\r\n':
             # record separator
-            pass
+            f = ''.join(field)
+            if f or record:
+                record.append(''.join(field))
+            # an empty line is an empty record
+            yield record
+            record = []
+            field = []
         elif c == ' ':
-            # field
-            pass
+            # field separator
+            record.append(''.join(field))
+            field = []
         elif c == '@':
             sf = []
             # field with special chars
-            c2 = db.read()
+            c2 = db.read(1)
             while c2:
                 if c2 == '@':
-                    pass # XXX TBD
+                    c3 = db.peek(1)
+                    if c3 and c3[0] == '@':
+                        # a quoted (i.e. duplicated) `@'
+                        sf.append('@')
+                        # and consume it
+                        db.read(1)
+                        c2 = db.read(1)
+                    else:
+                        # end of quoted string
+                        c2 = ''
+                        #
+                        # the next character will be read below:
+                        # just stay at the trailing `@'
+                        #
+                else:
+                    sf.append(c2)
+                    c2 = db.read(1)
+            field = sf
+        elif not field and c == '#':
+            # comment: `#' at the beginning of a line
+            comment = ['#']
+            while True:
+                c3 = db.peek(1)
+                if c3 and c3[0] in '\r\n':
+                    # end of comment
+                    break
+                    #
+                    # the next character will be read below:
+                    # just stay at the eol char
+                    #
+                else:
+                    c2 = db.read(1)
+                    comment.append(c2)
+            field = comment
+        else:
+            field.append(c)
+        c = db.read(1)
+    #
+    # EOF
+    # Check whether the last line contained data but no CR or LF
+    #
+    f = ''.join(field)
+    if f or record:
+        record.append(f)
+        # an empty line is an empty record: do not yield trailing empty lines
+        yield record
 
 
 def to_isoformat(t):