use of org.apache.felix.gogo.runtime.Parser.Statement in project felix by apache.
the class Highlighter method highlight.
public AttributedString highlight(LineReader reader, String buffer) {
try {
Program program = null;
List<Token> tokens = null;
List<Statement> statements = null;
String repaired = buffer;
while (program == null) {
try {
org.apache.felix.gogo.runtime.Parser parser = new org.apache.felix.gogo.runtime.Parser(repaired);
program = parser.program();
tokens = parser.tokens();
statements = parser.statements();
} catch (EOFError e) {
repaired = repaired + " " + e.repair();
// Make sure we don't loop forever
if (repaired.length() > buffer.length() + 1024) {
return new AttributedStringBuilder().append(buffer).toAttributedString();
}
}
}
Map<String, String> colors = Posix.getColorMap(session, "HIGHLIGHTER", DEFAULT_HIGHLIGHTER_COLORS);
int underlineStart = -1;
int underlineEnd = -1;
int negativeStart = -1;
int negativeEnd = -1;
String search = reader.getSearchTerm();
if (search != null && search.length() > 0) {
underlineStart = buffer.indexOf(search);
if (underlineStart >= 0) {
underlineEnd = underlineStart + search.length() - 1;
}
}
if (reader.getRegionActive() != RegionType.NONE) {
negativeStart = reader.getRegionMark();
negativeEnd = reader.getBuffer().cursor();
if (negativeStart > negativeEnd) {
int x = negativeEnd;
negativeEnd = negativeStart;
negativeStart = x;
}
if (reader.getRegionActive() == RegionType.LINE) {
while (negativeStart > 0 && reader.getBuffer().atChar(negativeStart - 1) != '\n') {
negativeStart--;
}
while (negativeEnd < reader.getBuffer().length() - 1 && reader.getBuffer().atChar(negativeEnd + 1) != '\n') {
negativeEnd++;
}
}
}
Type[] types = new Type[repaired.length()];
Arrays.fill(types, Type.Unknown);
int cur = 0;
for (Token token : tokens) {
// We're on the repair side, so exit now
if (token.start() >= buffer.length()) {
break;
}
if (token.start() > cur) {
cur = token.start();
}
// Find corresponding statement
Statement statement = null;
for (int i = statements.size() - 1; i >= 0; i--) {
Statement s = statements.get(i);
if (s.start() <= cur && cur < s.start() + s.length()) {
statement = s;
break;
}
}
// Reserved tokens
Type type = Type.Unknown;
if (Token.eq(token, "{") || Token.eq(token, "}") || Token.eq(token, "(") || Token.eq(token, ")") || Token.eq(token, "[") || Token.eq(token, "]") || Token.eq(token, "|") || Token.eq(token, ";") || Token.eq(token, "=")) {
type = Type.Reserved;
} else if (token.charAt(0) == '\'' || token.charAt(0) == '"') {
type = Type.String;
} else if (token.toString().matches("^[-+]?[0-9]*\\.?[0-9]+([eE][-+]?[0-9]+)?$")) {
type = Type.Number;
} else if (token.charAt(0) == '$') {
type = Type.Variable;
} else if (((Set) session.get(CommandSessionImpl.CONSTANTS)).contains(token.toString()) || Token.eq(token, "null") || Token.eq(token, "false") || Token.eq(token, "true")) {
type = Type.Constant;
} else {
boolean isFirst = statement != null && statement.tokens().size() > 0 && token == statement.tokens().get(0);
boolean isThirdWithNext = statement != null && statement.tokens().size() > 3 && token == statement.tokens().get(2);
boolean isAssign = statement != null && statement.tokens().size() > 1 && Token.eq(statement.tokens().get(1), "=");
if (isFirst && isAssign) {
type = Type.VariableName;
}
if (isFirst && !isAssign || isAssign && isThirdWithNext) {
Object v = session.get(Shell.resolve(session, token.toString()));
type = (v instanceof Function) ? Type.Function : Type.BadFunction;
}
}
Arrays.fill(types, token.start(), Math.min(token.start() + token.length(), types.length), type);
cur = Math.min(token.start() + token.length(), buffer.length());
}
if (buffer.length() < repaired.length()) {
Arrays.fill(types, buffer.length(), repaired.length(), Type.Repair);
}
AttributedStringBuilder sb = new AttributedStringBuilder();
for (int i = 0; i < repaired.length(); i++) {
sb.style(AttributedStyle.DEFAULT);
applyStyle(sb, colors, types[i]);
if (i >= underlineStart && i <= underlineEnd) {
sb.style(sb.style().underline());
}
if (i >= negativeStart && i <= negativeEnd) {
sb.style(sb.style().inverse());
}
char c = repaired.charAt(i);
if (c == '\t' || c == '\n') {
sb.append(c);
} else if (c < 32) {
sb.style(sb.style().inverseNeg()).append('^').append((char) (c + '@')).style(sb.style().inverseNeg());
} else {
int w = WCWidth.wcwidth(c);
if (w > 0) {
sb.append(c);
}
}
}
return sb.toAttributedString();
} catch (SyntaxError e) {
return super.highlight(reader, buffer);
}
}
use of org.apache.felix.gogo.runtime.Parser.Statement in project felix by apache.
the class Closure method execute.
@SuppressWarnings("unchecked")
private Object execute(List<Object> values, Channel capturingOutput) throws Exception {
if (null != values) {
parmv = new ArrayList<>(values);
parms = new ArgList(parmv);
} else if (null != parent) {
// inherit parent closure parameters
parmv = parent.parmv != null ? new ArrayList<>(parent.parmv) : null;
parms = parmv != null ? new ArgList(parmv) : null;
} else {
// inherit session parameters
Object args = session.get("args");
if (null != args && args instanceof List<?>) {
parmv = new ArrayList<>((List<Object>) args);
parms = new ArgList(parmv);
}
}
Result last = null;
Operator operator = null;
for (Iterator<Executable> iterator = program.tokens().iterator(); iterator.hasNext(); ) {
Operator prevOperator = operator;
Executable executable = iterator.next();
if (iterator.hasNext()) {
operator = (Operator) iterator.next();
} else {
operator = null;
}
if (prevOperator != null) {
if (Token.eq("&&", prevOperator)) {
if (!last.isSuccess()) {
continue;
}
} else if (Token.eq("||", prevOperator)) {
if (last.isSuccess()) {
continue;
}
}
}
Channel[] streams;
boolean[] toclose = new boolean[10];
if (Pipe.getCurrentPipe() != null) {
streams = Pipe.getCurrentPipe().streams.clone();
} else {
streams = new Channel[10];
System.arraycopy(session.channels, 0, streams, 0, 3);
}
if (capturingOutput != null) {
streams[1] = capturingOutput;
toclose[1] = true;
}
CommandSessionImpl.JobImpl job;
if (executable instanceof Pipeline) {
Pipeline pipeline = (Pipeline) executable;
List<Executable> exec = pipeline.tokens();
Token s = exec.get(0);
Token e = exec.get(exec.size() - 1);
Token t = program.subSequence(s.start - program.start, e.start + e.length - program.start);
job = session().createJob(t);
for (int i = 0; i < exec.size(); i++) {
Statement ex = (Statement) exec.get(i);
Operator op = i < exec.size() - 1 ? (Operator) exec.get(++i) : null;
Channel[] nstreams;
boolean[] ntoclose;
boolean endOfPipe;
if (i == exec.size() - 1) {
nstreams = streams;
ntoclose = toclose;
endOfPipe = true;
} else if (Token.eq("|", op)) {
PipedInputStream pis = new PipedInputStream();
PipedOutputStream pos = new PipedOutputStream(pis);
nstreams = streams.clone();
nstreams[1] = Channels.newChannel(pos);
ntoclose = toclose.clone();
ntoclose[1] = true;
streams[0] = Channels.newChannel(pis);
toclose[0] = true;
endOfPipe = false;
} else if (Token.eq("|&", op)) {
PipedInputStream pis = new PipedInputStream();
PipedOutputStream pos = new PipedOutputStream(pis);
nstreams = streams.clone();
nstreams[1] = nstreams[2] = Channels.newChannel(pos);
ntoclose = toclose.clone();
ntoclose[1] = ntoclose[2] = true;
streams[0] = Channels.newChannel(pis);
toclose[0] = true;
endOfPipe = false;
} else {
throw new IllegalStateException("Unrecognized pipe operator: '" + op + "'");
}
Pipe pipe = new Pipe(this, job, ex, nstreams, ntoclose, endOfPipe);
job.addPipe(pipe);
}
} else {
job = session().createJob(executable);
Pipe pipe = new Pipe(this, job, (Statement) executable, streams, toclose, true);
job.addPipe(pipe);
}
// Start pipe in background
if (operator != null && Token.eq("&", operator)) {
job.start(Status.Background);
last = new Result((Object) null);
} else // Start in foreground and wait for results
{
last = job.start(Status.Foreground);
if (last == null) {
last = new Result((Object) null);
} else if (last.exception != null) {
throw last.exception;
}
}
}
return last == null ? null : last.result;
}
use of org.apache.felix.gogo.runtime.Parser.Statement in project felix by apache.
the class TestParser method testPipeRedir.
@Test
public void testPipeRedir() {
Program x = new Parser("abc def|&ghi").program();
Pipeline p0 = (Pipeline) x.tokens().get(0);
Statement s00 = (Statement) p0.tokens().get(0);
assertEquals("|&", p0.tokens().get(1).toString());
Statement s01 = (Statement) p0.tokens().get(2);
assertEquals("abc", s00.tokens().get(0).toString());
assertEquals("def", s00.tokens().get(1).toString());
assertEquals("ghi", s01.tokens().get(0).toString());
}
use of org.apache.felix.gogo.runtime.Parser.Statement in project felix by apache.
the class TestParser method testBackground.
@Test
public void testBackground() {
Program x = new Parser("echo foo&echo bar").program();
Statement s0 = (Statement) x.tokens().get(0);
assertEquals("&", x.tokens().get(1).toString());
Statement s1 = (Statement) x.tokens().get(2);
assertEquals("echo", s0.tokens().get(0).toString());
assertEquals("foo", s0.tokens().get(1).toString());
assertEquals("echo", s1.tokens().get(0).toString());
assertEquals("bar", s1.tokens().get(1).toString());
}
use of org.apache.felix.gogo.runtime.Parser.Statement in project felix by apache.
the class TestParser method testProgram.
@Test
public void testProgram() {
Program x = new Parser("abc def|ghi jkl;mno pqr|stu vwx").program();
Pipeline p0 = (Pipeline) x.tokens().get(0);
Statement s00 = (Statement) p0.tokens().get(0);
assertEquals("|", p0.tokens().get(1).toString());
Statement s01 = (Statement) p0.tokens().get(2);
assertEquals(";", x.tokens().get(1).toString());
Pipeline p1 = (Pipeline) x.tokens().get(2);
Statement s10 = (Statement) p1.tokens().get(0);
assertEquals("|", p1.tokens().get(1).toString());
Statement s11 = (Statement) p1.tokens().get(2);
assertEquals("abc", s00.tokens().get(0).toString());
assertEquals("def", s00.tokens().get(1).toString());
assertEquals("ghi", s01.tokens().get(0).toString());
assertEquals("jkl", s01.tokens().get(1).toString());
assertEquals("mno", s10.tokens().get(0).toString());
assertEquals("pqr", s10.tokens().get(1).toString());
assertEquals("stu", s11.tokens().get(0).toString());
assertEquals("vwx", s11.tokens().get(1).toString());
}
Aggregations