--- /dev/null
+package org.simantics.scl.compiler.errors;
+
+import gnu.trove.list.array.TIntArrayList;
+
+import java.io.IOException;
+import java.io.Reader;
+import java.io.StringReader;
+
+public class CompilationErrorFormatter {
+
+ public static int[] rows(Reader reader) throws IOException {
+ TIntArrayList rows = new TIntArrayList();
+ rows.add(0);
+
+ int i=0;
+ while(true) {
+ ++i;
+ int c = reader.read();
+ if(c < 0)
+ break;
+ if(c == '\n')
+ rows.add(i);
+ }
+ reader.close();
+ return rows.toArray();
+ }
+
+ public static int lineNumber(int[] rows, int location) {
+ if(location < 0)
+ return 1;
+ if(location >= rows[rows.length-1])
+ return rows.length;
+ int a = 0;
+ int b = rows.length-1;
+ while(b-a > 1) {
+ int c = (a+b)/2;
+ if(rows[c] <= location)
+ a = c;
+ else
+ b = c;
+ }
+ return a+1;
+ }
+
+ private static String locationToString(int[] rows, int location) {
+ if(location == -1)
+ return "?";
+ if(location >= rows[rows.length-1])
+ return rows.length + ":" + (location - rows[rows.length-1] + 1);
+ int a = 0;
+ int b = rows.length-1;
+ while(b-a > 1) {
+ int c = (a+b)/2;
+ if(rows[c] <= location)
+ a = c;
+ else
+ b = c;
+ }
+ return (a+1) + ":" + (location - rows[a] + 1);
+ }
+
+ public static String toString(String source, CompilationError[] errors) {
+ return toString(new StringReader(source), errors);
+ }
+
+ public static String toString(Reader source, CompilationError[] errors) {
+ int[] rows;
+ try {
+ if(source != null)
+ rows = rows(source);
+ else
+ rows = new int[] {0};
+ } catch(IOException e) {
+ rows = new int[] {0};
+ }
+ StringBuilder b = new StringBuilder();
+ boolean first = true;
+ for(CompilationError error : errors) {
+ if(first)
+ first = false;
+ else
+ b.append('\n');
+ b.append(locationToString(rows, Locations.beginOf(error.location)) + "-" +
+ locationToString(rows, Locations.endOf(error.location)) + ": " +
+ error.description);
+ }
+ return b.toString();
+ }
+
+ public static String toString(CompilationError[] errors) {
+ return toString((Reader)null, errors);
+ }
+}