From 494e672ece6f52b1d3446c67f53da4f3e0cd7d36 Mon Sep 17 00:00:00 2001
From: Andreas Kloeckner <inform@tiker.net>
Date: Sun, 28 Jun 2015 19:10:34 -0500
Subject: [PATCH] Preserve line numbers in floopy transform code, for
 debuggability

---
 loopy/frontend/fortran/__init__.py | 10 +++++-
 loopy/tools.py                     | 49 ++++++++++++++++++++++--------
 2 files changed, 45 insertions(+), 14 deletions(-)

diff --git a/loopy/frontend/fortran/__init__.py b/loopy/frontend/fortran/__init__.py
index efdd07e8a..ed228ebc1 100644
--- a/loopy/frontend/fortran/__init__.py
+++ b/loopy/frontend/fortran/__init__.py
@@ -95,11 +95,17 @@ def _extract_loopy_lines(source):
                 raise LoopyError("can't enter loopy block twice")
             in_loopy_code = True
 
+            # Preserves line numbers in loopy code, for debuggability
+            loopy_lines.append("# "+l)
+
         elif cmt_stripped == "$loopy end":
             if not in_loopy_code:
                 raise LoopyError("can't leave loopy block twice")
             in_loopy_code = False
 
+            # Preserves line numbers in loopy code, for debuggability
+            loopy_lines.append("# "+l)
+
         elif in_loopy_code:
             loopy_lines.append(cmt)
 
@@ -169,7 +175,9 @@ def parse_transformed_fortran(source, free_form=True, strict=True,
     from loopy.tools import remove_common_indentation
     transform_code = remove_common_indentation(
             transform_code,
-            require_leading_newline=False)
+            require_leading_newline=False,
+            ignore_lines_starting_with="#")
+    print(transform_code)
 
     if transform_code_context is None:
         proc_dict = {}
diff --git a/loopy/tools.py b/loopy/tools.py
index b3c610dcb..e734417d6 100644
--- a/loopy/tools.py
+++ b/loopy/tools.py
@@ -164,7 +164,8 @@ class PicklableDtype(object):
 
 # {{{ remove common indentation
 
-def remove_common_indentation(code, require_leading_newline=True):
+def remove_common_indentation(code, require_leading_newline=True,
+        ignore_lines_starting_with=None, strip_empty_lines=True):
     if "\n" not in code:
         return code
 
@@ -175,21 +176,43 @@ def remove_common_indentation(code, require_leading_newline=True):
         return code
 
     lines = code.split("\n")
-    while lines[0].strip() == "":
-        lines.pop(0)
-    while lines[-1].strip() == "":
-        lines.pop(-1)
-
-    if lines:
-        base_indent = 0
-        while lines[0][base_indent] in " \t":
+
+    if strip_empty_lines:
+        while lines[0].strip() == "":
+            lines.pop(0)
+        while lines[-1].strip() == "":
+            lines.pop(-1)
+
+    test_line = None
+    if ignore_lines_starting_with:
+        for l in lines:
+            strip_l = l.lstrip()
+            if (strip_l
+                    and not strip_l.startswith(ignore_lines_starting_with)):
+                test_line = l
+                break
+
+    else:
+        test_line = lines[0]
+
+    base_indent = 0
+    if test_line:
+        while test_line[base_indent] in " \t":
             base_indent += 1
 
-        for line in lines[1:]:
-            if line[:base_indent].strip():
-                raise ValueError("inconsistent indentation")
+    new_lines = []
+    for line in lines:
+        if (ignore_lines_starting_with
+                and line.lstrip().startswith(ignore_lines_starting_with)):
+            new_lines.append(line)
+            continue
+
+        if line[:base_indent].strip():
+            raise ValueError("inconsistent indentation: '%s'" % line)
+
+        new_lines.append(line[base_indent:])
 
-    return "\n".join(line[base_indent:] for line in lines)
+    return "\n".join(new_lines)
 
 # }}}
 
-- 
GitLab