From 4d2d2d42d61b09bda8d07f81c37a7bdcf84129ab Mon Sep 17 00:00:00 2001
From: Johannes Mey <johannes.mey@tu-dresden.de>
Date: Wed, 8 Feb 2017 12:47:41 +0100
Subject: [PATCH] add improved output (including long line breaks)

---
 Parser/spec/PrintingCore.jadd | 122 +++++++++++++++++++++++++++++++++-
 1 file changed, 120 insertions(+), 2 deletions(-)

diff --git a/Parser/spec/PrintingCore.jadd b/Parser/spec/PrintingCore.jadd
index a0babb0..c125a3f 100644
--- a/Parser/spec/PrintingCore.jadd
+++ b/Parser/spec/PrintingCore.jadd
@@ -1,3 +1,14 @@
+aspect SimplePrinting {
+    String ASTNode.prettyPrint() {
+        return this.prettyPrint("  ", false);
+    }
+    String ASTNode.prettyPrint(String indenter, boolean uppercase) {
+        PrettyPrinter pp = new PrettyPrinter(indenter, uppercase);
+        this.prettyPrint(pp);
+        return pp.toString();
+    }
+}
+
 public class PrettyPrinter {
     private StringBuilder s;
 
@@ -6,6 +17,8 @@ public class PrettyPrinter {
     private int indent;
     private boolean newline;
     private boolean bof;
+    private boolean useColons;
+    private int lineLength;
 
     public PrettyPrinter(String indenter, boolean uppercase) {
 
@@ -16,6 +29,12 @@ public class PrettyPrinter {
         this.indent = 0;
         this.newline = false;
         this.bof = true;
+        this.useColons = false;
+        this.lineLength = 84;
+    }
+
+    public boolean useColons() {
+        return useColons;
     }
 
     public PrettyPrinter append(String s){
@@ -81,7 +100,106 @@ public class PrettyPrinter {
 
     public String toString() {
         flushNewline();
-        return s.toString();
+        return linebreak(s.toString());
+    }
+
+    /**
+     * Adds linebreaks to fortran sources with long line
+     * Default fortran allows 132 chars on a line
+     * If more - you have to break it with an ampersand
+     */
+    public String linebreak(String source) {
+        StringBuilder sb = new StringBuilder();
+        int index = source.indexOf("\n");
+        int builderIndex = 0;
+        while (index > 0)
+        {
+            // TODO long strings must be done here with everything else in an else-block
+            int nextIndex = source.indexOf("\n", index+1);
+            int nextComment = source.indexOf("!", index+1);
+            // when the line is too long but contains a comment, we substract the comment
+            if (nextComment < 0 || nextComment > nextIndex) {
+                nextComment = 0;
+            }
+            if (nextIndex - nextComment - index > lineLength) {
+                // append all previously found stuff to sb
+                sb.append(source.substring(builderIndex, index));
+                String longLine = source.substring(index+1, nextIndex);
+                String nextIndent = getNextIndent(longLine);
+                convertLongLine(sb, longLine, nextIndent);
+                builderIndex = nextIndex;
+            }
+            index = nextIndex;
+        }
+        sb.append(source.substring(builderIndex, source.length()));
+        return sb.toString();
+    }
+
+    /**
+     * detect the amount of indent for "line" by the "indenter" string
+     * returns the indent for the next line (amount+1)
+     */
+    private String getNextIndent(String line) {
+        // first detect the indent-depth
+        int indentDepth = 0;
+        String followingIndents = "";
+        while (line.substring(indentDepth * indenter.length(), indentDepth*indenter.length() + indenter.length()).equals(indenter)) {
+            indentDepth++;
+            followingIndents += indenter;
+        }
+        followingIndents += indenter;
+        return followingIndents;
+    }
+
+    /**
+     * converts a long line (longer than "length") to multiple ampersand-split lines
+     * "nextIndent" is the amount of indention all following lines should get
+     * appends to the StringBuilder
+     */
+    private void convertLongLine(StringBuilder sb, String line, String nextIndent) {
+        int length = lineLength;
+        String comment = "";
+        char[] splitChars = {' ', '\t', '(', ',', '+', '-', '*', '/', ')'};
+        Boolean isFirst = true;
+        // remove comment so we do not needlessly try to break this
+        if (line.indexOf("!")>0) {
+            comment = line.substring(line.indexOf("!"), line.length());
+            line = line.substring(0, line.indexOf("!"));
+        }
+        sb.append("\n");
+        while (line.length() > length) {
+            int breakPoint = 0;
+            for (char c: splitChars) {
+                breakPoint = line.lastIndexOf(c, length-1);
+                if (breakPoint > 0)
+                    break;
+            }
+            if (breakPoint <= 0) {
+                sb.append("! ERROR your code can not be split in mulitple lines\n");
+                sb.append(nextIndent);
+                sb.append("! Try adding some whitespaces\n");
+                sb.append(nextIndent);
+                break;
+            }
+            // System.err.printf("Bla (%d, %d)\n", line.length(), breakPoint);
+            sb.append(line.substring(0, breakPoint));
+            for (int i=breakPoint; i<length-1; i++) {
+                sb.append(" ");
+            }
+            sb.append("&\n");
+            sb.append(nextIndent);
+            if (isFirst) {
+                isFirst = false;
+                length -= nextIndent.length();
+            }
+            line = line.substring(breakPoint, line.length()).replaceAll("^\\s*", "");
+        }
+        sb.append(line);
+        if (!comment.isEmpty()) {
+            sb.append("\n");
+            sb.append(nextIndent);
+            sb.append(comment);
+        }
     }
 
-}
\ No newline at end of file
+}
-- 
GitLab