in freemarker-core/src/main/java/freemarker/core/JSONParser.java [511:589]
private static String createSourceCodeErrorMessage(String message, String srcCode, int position) {
int ln = srcCode.length();
if (position < 0) {
position = 0;
}
if (position >= ln) {
return message + "\n"
+ "Error location: At the end of text.";
}
int i;
char c;
int rowBegin = 0;
int rowEnd;
int row = 1;
char lastChar = 0;
for (i = 0; i <= position; i++) {
c = srcCode.charAt(i);
if (lastChar == 0xA) {
rowBegin = i;
row++;
} else if (lastChar == 0xD && c != 0xA) {
rowBegin = i;
row++;
}
lastChar = c;
}
for (i = position; i < ln; i++) {
c = srcCode.charAt(i);
if (c == 0xA || c == 0xD) {
if (c == 0xA && i > 0 && srcCode.charAt(i - 1) == 0xD) {
i--;
}
break;
}
}
rowEnd = i - 1;
if (position > rowEnd + 1) {
position = rowEnd + 1;
}
int col = position - rowBegin + 1;
if (rowBegin > rowEnd) {
return message + "\n"
+ "Error location: line "
+ row + ", column " + col + ":\n"
+ "(Can't show the line because it is empty.)";
}
String s1 = srcCode.substring(rowBegin, position);
String s2 = srcCode.substring(position, rowEnd + 1);
s1 = expandTabs(s1, 8);
int ln1 = s1.length();
s2 = expandTabs(s2, 8, ln1);
int ln2 = s2.length();
if (ln1 + ln2 > MAX_QUOTATION_LENGTH) {
int newLn2 = ln2 - ((ln1 + ln2) - MAX_QUOTATION_LENGTH);
if (newLn2 < 6) {
newLn2 = 6;
}
if (newLn2 < ln2) {
s2 = s2.substring(0, newLn2 - 3) + "...";
ln2 = newLn2;
}
if (ln1 + ln2 > MAX_QUOTATION_LENGTH) {
s1 = "..." + s1.substring((ln1 + ln2) - MAX_QUOTATION_LENGTH + 3);
}
}
StringBuilder res = new StringBuilder(message.length() + 80);
res.append(message);
res.append("\nError location: line ").append(row).append(", column ").append(col).append(":\n");
res.append(s1).append(s2).append("\n");
int x = s1.length();
while (x != 0) {
res.append(' ');
x--;
}
res.append('^');
return res.toString();
}