added a check for non-DOS line endings

Mon, 24 Jun 2019 19:08:24 +0300

author
Teemu Piippo <teemu@hecknology.net>
date
Mon, 24 Jun 2019 19:08:24 +0300
changeset 94
109fb7cf658f
parent 93
ffe05d369412
child 95
a3536e51f6bc

added a check for non-DOS line endings

filecache.py file | annotate | diff | comparison | revisions
ldcheck.py file | annotate | diff | comparison | revisions
parse.py file | annotate | diff | comparison | revisions
tests/misc.py file | annotate | diff | comparison | revisions
--- a/filecache.py	Mon Jun 24 17:34:30 2019 +0300
+++ b/filecache.py	Mon Jun 24 19:08:24 2019 +0300
@@ -89,7 +89,7 @@
         self.cache[filename] = subfile
         try:
             path = self.find_file(filename)
-            with path.open() as file:
+            with path.open('rb') as file:
                 model = parse.read_ldraw(
                     file,
                     ldraw_directories = self.ldraw_directories,
--- a/ldcheck.py	Mon Jun 24 17:34:30 2019 +0300
+++ b/ldcheck.py	Mon Jun 24 19:08:24 2019 +0300
@@ -119,7 +119,7 @@
             print('Description:', repr(subfile.description))
             print('Contains studs:', repr(subfile.has_studs))
     else:
-        with open(args.filename) as file:
+        with open(args.filename, 'rb') as file:
             from os.path import basename
             model = parse.read_ldraw(
                 file,
--- a/parse.py	Mon Jun 24 17:34:30 2019 +0300
+++ b/parse.py	Mon Jun 24 19:08:24 2019 +0300
@@ -8,11 +8,15 @@
     pass
 
 class Model:
-    def __init__(self, header, body, *, ldraw_directories, header_size = 0):
+    def __init__(
+        self, header, body, *, ldraw_directories, \
+        header_size = 0, line_ending_errors = None
+    ):
         self.header = header
         self.body = body
         self.header_size = header_size
         self.ldraw_directories = ldraw_directories
+        self.line_ending_errors = line_ending_errors
     def filter_by_type(self, type):
         yield from [
             element
@@ -62,10 +66,20 @@
                 yield point @ transformation_matrix
 
 def read_ldraw(file, *, ldraw_directories, name = ''):
-    model_body = [
-        parse_ldraw_code(line)
-        for line in file
-    ]
+    line_ending_errors = {
+        'count': 0,
+        'first-at': None,
+    }
+    model_body = []
+    for i, line in enumerate(file.readlines()):
+        # check line endings
+        if not line.endswith(b'\r\n'):
+            if line_ending_errors['first-at'] is None:
+                line_ending_errors['first-at'] = i
+            line_ending_errors['count'] += 1
+        model_body.append(parse_ldraw_code(line))
+    if line_ending_errors['count'] == 0:
+        line_ending_errors = None
     headerparser = header.HeaderParser()
     try:
         header_parse_result = headerparser.parse(model_body)
@@ -78,7 +92,9 @@
         header = header_object,
         body = model_body,
         header_size = end,
-        ldraw_directories = ldraw_directories)
+        ldraw_directories = ldraw_directories,
+        line_ending_errors = line_ending_errors,
+    )
     model.name = name
     return model
 
--- a/tests/misc.py	Mon Jun 24 17:34:30 2019 +0300
+++ b/tests/misc.py	Mon Jun 24 19:08:24 2019 +0300
@@ -229,6 +229,23 @@
                     command_text = element.text,
                 )
 
+@problem_type('bad-line-endings',
+    severity = 'hold',
+    message = lambda count: str.format(
+        'file contains non-DOS line endings ({count} total)',
+        count = count,
+    ),
+)
+def line_endings_test(model):
+    # Line endings are already checked during parse. This function
+    # only serves to report them.
+    if model.line_ending_errors != None:
+        yield report_problem(
+            'bad-line-endings',
+            bad_object = model.body[model.line_ending_errors['first-at']],
+            count = model.line_ending_errors['count'],
+        )
+
 manifest = {
     'tests': [
         colours_test,
@@ -243,5 +260,6 @@
         moved_to_with_extension_test,
         bfc_invertnext_not_on_subfile_test,
         metacommands_test,
+        line_endings_test,
     ],
 }

mercurial