Search in sources :

Example 1 with Statement

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);
    }
}
Also used : Program(org.apache.felix.gogo.runtime.Parser.Program) Statement(org.apache.felix.gogo.runtime.Parser.Statement) Token(org.apache.felix.gogo.runtime.Token) AttributedStringBuilder(org.jline.utils.AttributedStringBuilder) AttributedString(org.jline.utils.AttributedString) Function(org.apache.felix.service.command.Function) RegionType(org.jline.reader.LineReader.RegionType) SyntaxError(org.apache.felix.gogo.runtime.SyntaxError) EOFError(org.apache.felix.gogo.runtime.EOFError)

Example 2 with Statement

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;
}
Also used : Operator(org.apache.felix.gogo.runtime.Parser.Operator) Statement(org.apache.felix.gogo.runtime.Parser.Statement) Channel(java.nio.channels.Channel) ArrayList(java.util.ArrayList) PipedOutputStream(java.io.PipedOutputStream) PipedInputStream(java.io.PipedInputStream) Result(org.apache.felix.gogo.runtime.Pipe.Result) Pipeline(org.apache.felix.gogo.runtime.Parser.Pipeline) ArrayList(java.util.ArrayList) List(java.util.List) Executable(org.apache.felix.gogo.runtime.Parser.Executable)

Example 3 with Statement

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());
}
Also used : Program(org.apache.felix.gogo.runtime.Parser.Program) Statement(org.apache.felix.gogo.runtime.Parser.Statement) Pipeline(org.apache.felix.gogo.runtime.Parser.Pipeline) Test(org.junit.Test)

Example 4 with Statement

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());
}
Also used : Program(org.apache.felix.gogo.runtime.Parser.Program) Statement(org.apache.felix.gogo.runtime.Parser.Statement) Test(org.junit.Test)

Example 5 with Statement

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());
}
Also used : Program(org.apache.felix.gogo.runtime.Parser.Program) Statement(org.apache.felix.gogo.runtime.Parser.Statement) Pipeline(org.apache.felix.gogo.runtime.Parser.Pipeline) Test(org.junit.Test)

Aggregations

Statement (org.apache.felix.gogo.runtime.Parser.Statement)13 Program (org.apache.felix.gogo.runtime.Parser.Program)12 Test (org.junit.Test)8 Pipeline (org.apache.felix.gogo.runtime.Parser.Pipeline)6 ArrayList (java.util.ArrayList)2 ParsedLineImpl (org.apache.felix.gogo.jline.ParsedLineImpl)2 EOFError (org.apache.felix.gogo.runtime.EOFError)2 Token (org.apache.felix.gogo.runtime.Token)2 Command (org.apache.karaf.shell.api.console.Command)2 CommandLine (org.apache.karaf.shell.api.console.CommandLine)2 Parser (org.apache.karaf.shell.api.console.Parser)2 ParsedLine (org.jline.reader.ParsedLine)2 PipedInputStream (java.io.PipedInputStream)1 PipedOutputStream (java.io.PipedOutputStream)1 Channel (java.nio.channels.Channel)1 List (java.util.List)1 Executable (org.apache.felix.gogo.runtime.Parser.Executable)1 Operator (org.apache.felix.gogo.runtime.Parser.Operator)1 Sequence (org.apache.felix.gogo.runtime.Parser.Sequence)1 Result (org.apache.felix.gogo.runtime.Pipe.Result)1