/*******************************************************************************
* Copyright (c) 2008, 2017 xored software, Inc. and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* xored software, Inc. - initial API and Implementation (Andrei Sobolev)
*******************************************************************************/
package org.eclipse.dltk.tcl.parser.tests;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import org.eclipse.core.runtime.Path;
import org.eclipse.dltk.tcl.parser.ITclErrorConstants;
import org.eclipse.dltk.tcl.parser.TclErrorCollector;
import org.eclipse.dltk.tcl.parser.TclParser;
import org.eclipse.dltk.tcl.parser.internal.tests.TestTclParser;
public class TestUtils {
public static class CodeModel {
private int[] codeLineLengths;
private int[] codeStarts;
private int[] codeEnds;
public CodeModel(String code) {
String[] codeLines = code.split("\n");
int count = codeLines.length;
this.codeLineLengths = new int[count];
this.codeStarts = new int[count];
this.codeEnds = new int[count];
int sum = 0;
for (int i = 0; i < count; ++i) {
this.codeLineLengths[i] = sum;
String trim = codeLines[i].trim();
int off = codeLines[i].indexOf(trim);
this.codeStarts[i] = sum + off;
this.codeEnds[i] = trim.length();
sum += codeLines[i].length() + 1;
}
}
public int[] getBounds(int lineNumber) {
if (lineNumber < this.codeLineLengths.length) {
int start = this.codeStarts[lineNumber];
int end = this.codeEnds[lineNumber];
return new int[] { start, start + end };
}
return new int[] { 0, 0 };
}
public int getLineNumber(int start, int end) {
int len = codeLineLengths.length;
for (int i = 0; i < len - 1; ++i) {
int s = this.codeLineLengths[i];
int e = start + this.codeLineLengths[i + 1] - 1;
if (start <= s && end <= e) {
return i + 1;
}
}
return this.codeLineLengths.length;
}
}
public static void outErrors(final String source,
TclErrorCollector errors) {
System.out.println("-----------------ERRORS----------------------\n");
final CodeModel model = new CodeModel(source);
errors.reportAll((code, message, extraMessage, start, end, kind) -> {
System.out.println((kind == ITclErrorConstants.ERROR ? "Error:"
: "Warning/Info:") + code + " (" + start + "," + end
+ ") message:" + message);
int line = model.getLineNumber(start, end);
int[] bounds = model.getBounds(line - 1);
String prefix = source.substring(bounds[0], bounds[1]);
System.out.println(prefix);
outBlock(start - bounds[0], end - bounds[0]);
});
System.out.println("=============================================");
}
public static void outCode(String source, int startPos, int endPos) {
System.out.println("------------------code-----------------------\n"
+ source.replace('\t', ' '));
outBlock(startPos, endPos);
// System.out.println("=============================================");
}
private static void outBlock(int startPos, int endPos) {
for (int i = 0; i < startPos; i++)
System.out.print(" ");
System.out.print("^");
for (int i = 0; i < (endPos - startPos - 2); i++)
System.out.print(" ");
System.out.println("^");
}
public static String getContents(URL url) throws IOException {
InputStream input = url.openStream();
return getContents(input);
}
public static String getContents(InputStream input) throws IOException {
StringBuffer result = new StringBuffer();
input = new BufferedInputStream(input, 4096);
try {
// Simple copy
int ch = -1;
while ((ch = input.read()) != -1) {
result.append((char) ch);
}
} finally {
if (input != null) {
input.close();
}
}
return result.toString();
}
public static void exractZipInto(String location, URL entry,
String[] skipFiles) throws IOException {
try (InputStream openStream = entry.openStream();
ZipInputStream zis = new ZipInputStream(
new BufferedInputStream(openStream, 4096))) {
File root = new File(location);
root.mkdirs();
while (true) {
ZipEntry nextEntry = zis.getNextEntry();
if (nextEntry != null) {
String name = nextEntry.getName();
if (!nextEntry.isDirectory()) {
boolean skip = false;
for (int i = 0; i < skipFiles.length; i++) {
if (name.equals(skipFiles[i])) {
skip = true;
break;
}
}
if (skip) {
zis.closeEntry();
continue;
}
try (FileOutputStream fileOutput = new FileOutputStream(
new File(new Path(location).append(name)
.toOSString()))) {
byte[] buf = new byte[1024];
int len;
try (OutputStream arrayOut = new BufferedOutputStream(
fileOutput, 4096)) {
while ((len = zis.read(buf)) > 0) {
arrayOut.write(buf, 0, len);
}
}
}
}
zis.closeEntry();
} else {
break;
}
}
}
}
public static void exractFilesInto(String location, URL entry,
String[] skipFiles) throws IOException {
try (InputStream openStream = entry.openStream();
ZipInputStream zis = new ZipInputStream(
new BufferedInputStream(openStream, 4096))) {
File root = new File(location);
root.mkdirs();
while (true) {
ZipEntry nextEntry = zis.getNextEntry();
if (nextEntry != null) {
String name = nextEntry.getName();
if (!nextEntry.isDirectory()) {
boolean found = false;
for (int i = 0; i < skipFiles.length; i++) {
if (name.equals(skipFiles[i])) {
found = true;
}
}
if (!found) {
zis.closeEntry();
continue;
}
byte[] buf = new byte[1024];
int len;
try (FileOutputStream fileOutput = new FileOutputStream(
new File(new Path(location).append(name)
.toOSString()));
OutputStream arrayOut = new BufferedOutputStream(
fileOutput, 4096)) {
while ((len = zis.read(buf)) > 0) {
arrayOut.write(buf, 0, len);
}
}
}
zis.closeEntry();
} else {
break;
}
}
}
}
public static TclParser createParser() {
return new TestTclParser();
}
public static TclParser createParser(String version) {
return new TestTclParser(version);
}
}