From 518fe1094fa417ae2b1b5def7063c07ebfe89a9e Mon Sep 17 00:00:00 2001 From: simiyutin Date: Sat, 4 Mar 2017 20:07:21 +0300 Subject: [PATCH 01/10] task 1 done --- shell/src/main/java/commands/Cat.java | 47 ++++++ shell/src/main/java/commands/Echo.java | 28 ++++ shell/src/main/java/commands/Eq.java | 22 +++ shell/src/main/java/commands/Exit.java | 22 +++ shell/src/main/java/commands/OutSource.java | 55 +++++++ shell/src/main/java/commands/Pwd.java | 27 +++ shell/src/main/java/commands/Wc.java | 84 ++++++++++ shell/src/main/java/shell/Command.java | 29 ++++ .../src/main/java/shell/CommandExecutor.java | 25 +++ shell/src/main/java/shell/CommandFactory.java | 66 ++++++++ shell/src/main/java/shell/Environment.java | 40 +++++ shell/src/main/java/shell/Main.java | 8 + shell/src/main/java/shell/Parser.java | 121 ++++++++++++++ shell/src/main/java/shell/Preprocessor.java | 64 ++++++++ shell/src/main/java/shell/Shell.java | 41 +++++ shell/src/main/java/shell/Stream.java | 55 +++++++ shell/src/main/java/shell/Token.java | 154 ++++++++++++++++++ shell/src/main/java/shell/Tokenizer.java | 73 +++++++++ shell/src/test/java/ParserTests.java | 90 ++++++++++ shell/src/test/java/PreprocessorTests.java | 71 ++++++++ shell/src/test/java/TokenizerTests.java | 65 ++++++++ 21 files changed, 1187 insertions(+) create mode 100644 shell/src/main/java/commands/Cat.java create mode 100644 shell/src/main/java/commands/Echo.java create mode 100644 shell/src/main/java/commands/Eq.java create mode 100644 shell/src/main/java/commands/Exit.java create mode 100644 shell/src/main/java/commands/OutSource.java create mode 100644 shell/src/main/java/commands/Pwd.java create mode 100644 shell/src/main/java/commands/Wc.java create mode 100644 shell/src/main/java/shell/Command.java create mode 100644 shell/src/main/java/shell/CommandExecutor.java create mode 100644 shell/src/main/java/shell/CommandFactory.java create mode 100644 shell/src/main/java/shell/Environment.java create mode 100644 shell/src/main/java/shell/Main.java create mode 100644 shell/src/main/java/shell/Parser.java create mode 100644 shell/src/main/java/shell/Preprocessor.java create mode 100644 shell/src/main/java/shell/Shell.java create mode 100644 shell/src/main/java/shell/Stream.java create mode 100644 shell/src/main/java/shell/Token.java create mode 100644 shell/src/main/java/shell/Tokenizer.java create mode 100644 shell/src/test/java/ParserTests.java create mode 100644 shell/src/test/java/PreprocessorTests.java create mode 100644 shell/src/test/java/TokenizerTests.java diff --git a/shell/src/main/java/commands/Cat.java b/shell/src/main/java/commands/Cat.java new file mode 100644 index 0000000..6e36cd9 --- /dev/null +++ b/shell/src/main/java/commands/Cat.java @@ -0,0 +1,47 @@ +package commands; + +import shell.Command; +import shell.Environment; +import shell.Stream; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.List; +import java.util.Scanner; + +public class Cat extends Command { + + public static final String NAME = "cat"; + + public Cat(List args, Environment env) { + super(args, env); + } + + @Override + public Stream run(Stream stream) { + + if (stream.hasNext()) { + return stream; + } + + Stream res = new Stream(); + if (args.isEmpty()) { + Scanner sc = new Scanner(System.in); + while (true) { + System.out.println(sc.nextLine()); + } + } else { + String filename = args.get(0); + Path file = Paths.get(filename); + try { + List lines = Files.readAllLines(file); + lines.forEach(res::write); + } catch (IOException e) { + e.printStackTrace(); + } + } + return res; + } +} diff --git a/shell/src/main/java/commands/Echo.java b/shell/src/main/java/commands/Echo.java new file mode 100644 index 0000000..d786511 --- /dev/null +++ b/shell/src/main/java/commands/Echo.java @@ -0,0 +1,28 @@ +package commands; + +import shell.Command; +import shell.Environment; +import shell.Stream; + +import java.util.List; +import java.util.stream.Collectors; + +public class Echo extends Command { + + public static final String NAME = "echo"; + + public Echo(List args, Environment env) { + super(args, env); + } + + @Override + public Stream run(Stream ignored) { + + String toPrint = args.stream().collect(Collectors.joining()); + + Stream stream = new Stream(); + stream.write(toPrint); + return stream; + } + +} diff --git a/shell/src/main/java/commands/Eq.java b/shell/src/main/java/commands/Eq.java new file mode 100644 index 0000000..641333d --- /dev/null +++ b/shell/src/main/java/commands/Eq.java @@ -0,0 +1,22 @@ +package commands; + +import shell.Command; +import shell.Environment; +import shell.Stream; + +import java.util.List; + +public class Eq extends Command { + + public Eq(List args, Environment env) { + super(args, env); + } + + @Override + public Stream run(Stream ignored) { + String var = args.get(0); + String val = args.get(1); + env.put(var, val); + return new Stream(); + } +} diff --git a/shell/src/main/java/commands/Exit.java b/shell/src/main/java/commands/Exit.java new file mode 100644 index 0000000..2a1fa60 --- /dev/null +++ b/shell/src/main/java/commands/Exit.java @@ -0,0 +1,22 @@ +package commands; + +import shell.Command; +import shell.Environment; +import shell.Stream; + +import java.util.List; + +public class Exit extends Command { + + public static final String NAME = "exit"; + + public Exit(List args, Environment env) { + super(args, env); + } + + @Override + public Stream run(Stream stream) { + System.exit(0); + return null; + } +} diff --git a/shell/src/main/java/commands/OutSource.java b/shell/src/main/java/commands/OutSource.java new file mode 100644 index 0000000..556d10c --- /dev/null +++ b/shell/src/main/java/commands/OutSource.java @@ -0,0 +1,55 @@ +package commands; + +import shell.Command; +import shell.Environment; +import shell.Stream; + +import java.io.*; +import java.util.List; +import java.util.stream.Collectors; + +public class OutSource extends Command { + + private String commandName; + + public OutSource(String commandName, List args, Environment env) { + super(args, env); + this.commandName = commandName; + } + + @Override + public Stream run(Stream stream) { + String command = commandName + " " + args.stream().collect(Collectors.joining(" ")); + Stream output = new Stream(); + try { + Process process = Runtime.getRuntime().exec(command); + write(process, stream); + output = read(process); + } catch (IOException | InterruptedException e) { + e.printStackTrace(); + } + return output; + } + + private void write(Process process, Stream stream) throws IOException { + Writer handle = new PrintWriter(process.getOutputStream()); + final int LINE_FEED = 10; + while (stream.hasNext()) { + handle.write(stream.read()); + handle.write(LINE_FEED); + } + handle.close(); + } + + private Stream read(Process process) throws IOException, InterruptedException { + Stream output = new Stream(); + BufferedReader reader = + new BufferedReader(new InputStreamReader(process.getInputStream())); + String line; + while ((line = reader.readLine()) != null) { + output.write(line); + } + process.waitFor(); + return output; + } +} diff --git a/shell/src/main/java/commands/Pwd.java b/shell/src/main/java/commands/Pwd.java new file mode 100644 index 0000000..a3985a7 --- /dev/null +++ b/shell/src/main/java/commands/Pwd.java @@ -0,0 +1,27 @@ +package commands; + +import shell.Command; +import shell.Environment; +import shell.Stream; + +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.List; + +public class Pwd extends Command { + + public static final String NAME = "pwd"; + + public Pwd(List args, Environment env) { + super(args, env); + } + + @Override + public Stream run(Stream ignored) { + Path currentRelativePath = Paths.get(""); + String currentDir = currentRelativePath.toAbsolutePath().toString(); + Stream stream = new Stream(); + stream.write(currentDir); + return stream; + } +} diff --git a/shell/src/main/java/commands/Wc.java b/shell/src/main/java/commands/Wc.java new file mode 100644 index 0000000..0eef945 --- /dev/null +++ b/shell/src/main/java/commands/Wc.java @@ -0,0 +1,84 @@ +package commands; + +import shell.Command; +import shell.Environment; +import shell.Stream; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Scanner; +import java.util.stream.Collectors; + +public class Wc extends Command { + + public static final String NAME = "wc"; + + public Wc(List args, Environment env) { + super(args, env); + } + + @Override + public Stream run(Stream stream) { + if (!args.isEmpty()) { + return handleFile(); + } else if (stream.hasNext()) { + return handleInputStream(stream); + } else { + handleStdIn(); + return new Stream(); + } + } + + private Stream handleFile() { + String fileName = args.get(0); + Path file = Paths.get(fileName); + try { + List lines = Files.readAllLines(file); + return parseLines(lines); + } catch (IOException e) { + e.printStackTrace(); + return new Stream(); + } + } + + private Stream handleInputStream(Stream stream) { + List lines = new ArrayList<>(); + while (stream.hasNext()) { + lines.add(stream.read()); + } + return parseLines(lines); + } + + private void handleStdIn() { + Scanner sc = new Scanner(System.in); + while (true) { + List lines = Collections.singletonList(sc.nextLine()); + Stream result = parseLines(lines); + System.out.println(result.read()); + } + } + + private Stream parseLines(List lines) { + int linesCount = lines.size(); + char[] concatenated = lines.stream().collect(Collectors.joining(" ")).toCharArray(); + long wordCount = 0; + for (char c : concatenated) { + if (c == ' ') { + wordCount++; + } + } + wordCount++; + + long byteCount = concatenated.length; + + String result = String.format(" %d %d %d", linesCount, wordCount, byteCount); + Stream stream = new Stream(); + stream.write(result); + return stream; + } +} diff --git a/shell/src/main/java/shell/Command.java b/shell/src/main/java/shell/Command.java new file mode 100644 index 0000000..b87bbc6 --- /dev/null +++ b/shell/src/main/java/shell/Command.java @@ -0,0 +1,29 @@ +package shell; + +import java.util.List; + +/** + * Abstract class which impersonates Command entity. + * Command can be run with Stream as an argument and can modify environment of a shell. + */ +public abstract class Command { + + protected List args; + protected Environment env; + + + /** + * @param args arguments of a command as a List + * @param env environment of current running shell + */ + public Command(List args, Environment env) { + this.args = args; + this.env = env; + } + + /** + * @param stream + * @return result data as a Stream object + */ + public abstract Stream run(Stream stream); +} diff --git a/shell/src/main/java/shell/CommandExecutor.java b/shell/src/main/java/shell/CommandExecutor.java new file mode 100644 index 0000000..0526c70 --- /dev/null +++ b/shell/src/main/java/shell/CommandExecutor.java @@ -0,0 +1,25 @@ +package shell; + +import java.util.List; + + +/** + * Entity to implement chained computations. + * Every computation is processed one after another + * and result of current one is passed to the next one. + */ +public class CommandExecutor { + private CommandExecutor() {} + + /** + * @param commands List of Command objects + * @return Stream object which contain result of a chain of computations + */ + public static Stream run(List commands) { + Stream stream = new Stream(); + for (Command command : commands) { + stream = command.run(stream); + } + return stream; + } +} diff --git a/shell/src/main/java/shell/CommandFactory.java b/shell/src/main/java/shell/CommandFactory.java new file mode 100644 index 0000000..c96c5ad --- /dev/null +++ b/shell/src/main/java/shell/CommandFactory.java @@ -0,0 +1,66 @@ +package shell; + +import commands.*; + +import java.util.List; +import java.util.stream.Collectors; + + +/** + * Factory which is used to construct Command objects relying on command token + */ +public class CommandFactory { + + + /** + * @param commandToken token, which contains command name as a String + * @param args arguments of a command + * @param env Environment object + * @return generated runnable Command object + */ + public static Command produce(Token commandToken, List args, Environment env) { + Command command; + switch (commandToken.getType()) { + case EQ: + command = new Eq(args, env); + return command; + case WORD: + command = getCommand(commandToken.toString(), args, env); + return command; + default: + return null; + } + } + + private static Command getCommand(String commandName, List args, Environment env) { + + Command command = null; + switch (commandName) { + case Echo.NAME: + command = new Echo(args, env); + break; + case Cat.NAME: + command = new Cat(args, env); + break; + case Wc.NAME: + command = new Wc(args, env); + break; + case Pwd.NAME: + command = new Pwd(args, env); + break; + case Exit.NAME: + command = new Exit(args, env); + break; + default: + command = new OutSource(commandName, args, env); + break; + + } + return command; + } + + private static String concat(List args) { + + return args.stream().collect(Collectors.joining()); + } +} diff --git a/shell/src/main/java/shell/Environment.java b/shell/src/main/java/shell/Environment.java new file mode 100644 index 0000000..e38a6e3 --- /dev/null +++ b/shell/src/main/java/shell/Environment.java @@ -0,0 +1,40 @@ +package shell; + +import java.util.HashMap; +import java.util.Map; + +/** + * Entity which represents a concept of environment which handles state of a running shell. + * It can be asked to give variable by its name and to accept new variable by name and value + */ +public class Environment { + private Map map; + + public Environment() { + this.map = new HashMap<>(); + } + + /** + * @param var name of requested variable + * @return value of a requested variable or empty string if such does not exist in environment + */ + public String get(String var) { + + String res = map.get(var); + + if (res == null) { + return ""; + } else { + return res; + } + } + + + /** + * @param var name of inserted variable + * @param val value of inserted variable + */ + public void put(String var, String val) { + map.put(var, val); + } +} diff --git a/shell/src/main/java/shell/Main.java b/shell/src/main/java/shell/Main.java new file mode 100644 index 0000000..56e8108 --- /dev/null +++ b/shell/src/main/java/shell/Main.java @@ -0,0 +1,8 @@ +package shell; + +public class Main { + public static void main(String[] args) { + Shell shell = new Shell(); + shell.run(); + } +} diff --git a/shell/src/main/java/shell/Parser.java b/shell/src/main/java/shell/Parser.java new file mode 100644 index 0000000..f19716e --- /dev/null +++ b/shell/src/main/java/shell/Parser.java @@ -0,0 +1,121 @@ +package shell; + +import java.util.ArrayDeque; +import java.util.ArrayList; +import java.util.List; +import java.util.Queue; + +/** + * A DFA which accepts a list of tokens and evaluates + * corresponding shell command or a sequence of them + */ +public class Parser { + + private Queue queue; + private Environment env; + private List commands = new ArrayList<>(); + + private Parser(List tokens, Environment env) { + this.queue = new ArrayDeque<>(tokens); + this.env = env; + } + + + /** + * @param tokens List of tokens to parse as a chain of shell commands + * @param env Environment object + * @return List of generated commands + */ + public static List run(List tokens, Environment env) { + + Parser parser = new Parser(tokens, env); + parser.start(); + return parser.commands; + + } + + private void start() { + Token token = queue.poll(); + if (token.getType() == Token.Type.WORD) { + parseCommand(token); + } else { + error(); + } + + } + + private void parseCommand(Token firstWord) { + Token token = queue.poll(); + switch (token.getType()) { + case EQ: + parseEQ(firstWord); + break; + case WORD: + List args = new ArrayList<>(); + args.add(token.toString()); + parseArg(firstWord, args); + break; + case PIPE: + createCommand(firstWord, new ArrayList<>()); + start(); + break; + case EOF: + createCommand(firstWord, new ArrayList<>()); + break; + default: + error(); + break; + } + } + + private void createCommand(Token commandToken, List args) { + Command command = CommandFactory.produce(commandToken, args, env); + commands.add(command); + } + + private void parseEQ(Token var) { + Token val = queue.poll(); + switch (val.getType()) { + case WORD: + checkEQSyntax(); + List args = new ArrayList<>(); + args.add(var.toString()); + args.add(val.toString()); + createCommand(Token.eq(), args); + break; + default: + error(); + break; + } + } + + private void checkEQSyntax() { + Token token = queue.poll(); + if (token.getType() != Token.Type.EOF) { + error(); + } + } + + private void parseArg(Token command, List args) { + Token token = queue.poll(); + switch (token.getType()) { + case WORD: + args.add(token.toString()); + parseArg(command, args); + break; + case PIPE: + createCommand(command, args); + start(); + break; + case EOF: + createCommand(command, args); + break; + default: + error(); + break; + } + } + + private void error() {} + +} diff --git a/shell/src/main/java/shell/Preprocessor.java b/shell/src/main/java/shell/Preprocessor.java new file mode 100644 index 0000000..f8d103d --- /dev/null +++ b/shell/src/main/java/shell/Preprocessor.java @@ -0,0 +1,64 @@ +package shell; + +/** + * Takes care of substitution variable values in requested places + */ +public class Preprocessor { + + /** + * @param unprocessed unprocessed input String + * @param env Environment object + * @return String with substituted variables from environment + */ + public static String run(String unprocessed, Environment env) { + + char[] chars = unprocessed.toCharArray(); + + StringBuilder varName = new StringBuilder(); + StringBuilder processed = new StringBuilder(); + boolean varReading = false; + boolean isInsideDoubleQuotes = false; + boolean isInsideSingleQuotes = false; + + for (int i = 0; i < chars.length; i++) { + + if (!isInsideSingleQuotes && chars[i] == '$') { + varReading = true; + continue; + } + + if (varReading) { + varName.append(chars[i]); + if (isEndOfVarName(chars, i)) { + processed.append(env.get(varName.toString())); + varName.delete(0, chars.length); + varReading = false; + } + continue; + } + + if (chars[i] == '"' && !isInsideSingleQuotes) { + isInsideDoubleQuotes = !isInsideDoubleQuotes; + } + + if (chars[i] == '\'' && !isInsideDoubleQuotes) { + isInsideSingleQuotes = !isInsideSingleQuotes; + } + + processed.append(chars[i]); + } + + return processed.toString(); + } + + private static boolean isEndOfVarName(char[] chars, int index) { + + if (index == chars.length - 1) { + return true; + } + + char c = chars[index + 1]; + return c == ' ' || c == '"' || c == '\'' || c == '$'; + } + +} diff --git a/shell/src/main/java/shell/Shell.java b/shell/src/main/java/shell/Shell.java new file mode 100644 index 0000000..c4202c8 --- /dev/null +++ b/shell/src/main/java/shell/Shell.java @@ -0,0 +1,41 @@ +package shell; + +import java.util.List; +import java.util.Scanner; + +//todo возвращать код возврата +//todo исключения парсера +//прохождения нового теста токенайзера + +/** + * Main entity. Reads from stdin in an infinite loop and executes commands + */ +public class Shell { + + private Environment env; + + /** + * constructs Shell with empty environment + */ + Shell() { + env = new Environment(); + } + + /** + * runs Shell + */ + public void run() { + Scanner sc = new Scanner(System.in); + + while (true) { + String input = sc.nextLine(); + input = Preprocessor.run(input, env); + List tokens = Tokenizer.run(input); + List commands = Parser.run(tokens, env); + Stream stream = CommandExecutor.run(commands); + while (stream.hasNext()) { + System.out.println(stream.read()); + } + } + } +} diff --git a/shell/src/main/java/shell/Stream.java b/shell/src/main/java/shell/Stream.java new file mode 100644 index 0000000..1e7b2b3 --- /dev/null +++ b/shell/src/main/java/shell/Stream.java @@ -0,0 +1,55 @@ +package shell; + +import java.util.ArrayDeque; +import java.util.Queue; + +/** + * Entity to handle input and output of commands. + */ +public class Stream { + + private Queue vals; + + public Stream() { + this.vals = new ArrayDeque<>(); + } + + /** + * @return next line in stream or null if stream is empty + */ + public String read() { + return vals.poll(); + } + + /** + * @param val line to add to stream + */ + public void write(String val) { + vals.offer(val); + } + + /** + * @return true if stream has at least one line to read + */ + public boolean hasNext() { + return vals.peek() != null; + } + + /** + * @return concatenated lines in stream + */ + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + Queue replacement = new ArrayDeque<>(); + while (hasNext()) { + String line = read(); + sb.append('\n'); + sb.append(line); + replacement.add(line); + } + vals = replacement; + sb.delete(0, 1); + return sb.toString(); + } +} diff --git a/shell/src/main/java/shell/Token.java b/shell/src/main/java/shell/Token.java new file mode 100644 index 0000000..0092ba4 --- /dev/null +++ b/shell/src/main/java/shell/Token.java @@ -0,0 +1,154 @@ +package shell; + +import java.util.ArrayList; + +/** + * Describes possible lexems + */ +public class Token { + + /** + * describes possible token types + */ + public enum Type { + SINGLE_QUOTE, + DOUBLE_QUOTE, + WHITESPACE, + PIPE, + WORD, + EQ, + EOF + } + + private String value; + private Type type; + + private static final String SINGLE_QUOTE = "'"; + private static final String DOUBLE_QUOTE = "\""; + private static final String EQUALITY_OPERATOR = "="; + private static final String WHITESPACE = " "; + private static final String PIPE = "|"; + private static final String EOF = "\0"; + + private Token(Token.Type type, String value) { + this.type = type; + this.value = value; + } + + /** + * @return new single quote token + */ + public static Token singleQuote() { + return new Token(Type.SINGLE_QUOTE, SINGLE_QUOTE); + } + + /** + * @return new double quote token + */ + public static Token doubleQuote() { + return new Token(Type.DOUBLE_QUOTE, DOUBLE_QUOTE); + } + + /** + * @return new '=' token + */ + public static Token eq() { + return new Token(Type.EQ, EQUALITY_OPERATOR); + } + + /** + * @return new whitespace token + */ + public static Token whitespace() { + return new Token(Type.WHITESPACE, WHITESPACE); + } + + /** + * @return new pipe token + */ + public static Token pipe() { + return new Token(Type.PIPE, PIPE); + } + + /** + * @param word + * @return new word token + */ + public static Token word(String word) { + return new Token(Type.WORD, word); + } + + /** + * @return new end of line token + */ + public static Token eof() { + return new Token(Type.EOF, EOF); + } + + + /** + * @param c + * @return tests if passed char can be a delimiter between words + */ + public static boolean isDelimiter(char c) { + ArrayList test = new ArrayList<>(); + test.add(SINGLE_QUOTE); + test.add(DOUBLE_QUOTE); + test.add(WHITESPACE); + test.add(EQUALITY_OPERATOR); + test.add(PIPE); + return test.contains(String.valueOf(c)); + } + + /** + * @param c + * @return generate corresponding token to passed char + */ + public static Token valueOf(char c) { + switch (String.valueOf(c)) { + case SINGLE_QUOTE: + return singleQuote(); + case DOUBLE_QUOTE: + return doubleQuote(); + case WHITESPACE: + return whitespace(); + case EQUALITY_OPERATOR: + return eq(); + case PIPE: + return pipe(); + default: + return word(String.valueOf(c)); + } + } + + public Type getType() { + return type; + } + + public String getValue() { + return value; + } + + @Override + public String toString() { + return value; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + Token token = (Token) o; + + if (value != null ? !value.equals(token.value) : token.value != null) return false; + return type == token.type; + } + + @Override + public int hashCode() { + int result = value != null ? value.hashCode() : 0; + result = 31 * result + (type != null ? type.hashCode() : 0); + return result; + } +} diff --git a/shell/src/main/java/shell/Tokenizer.java b/shell/src/main/java/shell/Tokenizer.java new file mode 100644 index 0000000..52d5179 --- /dev/null +++ b/shell/src/main/java/shell/Tokenizer.java @@ -0,0 +1,73 @@ +package shell; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.Predicate; + +/** + * Takes care of translating given char string to list of lexemes. + */ +public class Tokenizer { + + /** + * @param input processed string corresponding to some shell command + * @return list of words and operators obtained from passed string + */ + public static List run(String input) { + + List tokens = new ArrayList<>(); + + char[] chars = input.toCharArray(); + for (int i = 0; i < chars.length;) { + char c = chars[i]; + if (!Token.isDelimiter(c)) { + String word = readWord(chars, i); + i += word.length(); + tokens.add(Token.word(word)); + continue; + } + Token.Type type = Token.valueOf(c).getType(); + switch (type) { + case SINGLE_QUOTE: + case DOUBLE_QUOTE: + i++; + String word = readWordInsideQuotes(chars, i, c); + i += word.length() + 1; + tokens.add(Token.word(word)); + break; + case EQ: + tokens.add(Token.eq()); + i++; + break; + case WHITESPACE: + i++; + break; + case PIPE: + tokens.add(Token.pipe()); + i++; + break; + } + } + + tokens.add(Token.eof()); + + return tokens; + } + + private static String readWordInsideQuotes(char[] chars, int i, char matcher) { + return readWordUntil(c -> c.equals(matcher), chars, i); + } + + private static String readWord(char[] chars, int i) { + return readWordUntil(Token::isDelimiter, chars, i); + } + + private static String readWordUntil(Predicate breaker, char[] chars, int i) { + StringBuilder sb = new StringBuilder(); + while (i < chars.length && !breaker.test(chars[i])) { + sb.append(chars[i++]); + } + return sb.toString(); + } + +} diff --git a/shell/src/test/java/ParserTests.java b/shell/src/test/java/ParserTests.java new file mode 100644 index 0000000..6e438af --- /dev/null +++ b/shell/src/test/java/ParserTests.java @@ -0,0 +1,90 @@ +import org.junit.Test; +import shell.*; + +import java.util.List; + +import static org.junit.Assert.assertEquals; + +public class ParserTests { + + @Test + public void smokeTest() { + Environment env = getEnv(); + String input = "hello=hacked"; + List tokens = Tokenizer.run(input); + List commands = Parser.run(tokens, env); + commands.get(0).run(new Stream()); + assertEquals("hacked", Preprocessor.run("$hello", env)); + } + + @Test + public void reduceTest() { + Environment env = getEnv(); + String input = "hello='hacked = | azazazazaa'"; + List tokens = Tokenizer.run(input); + List commands = Parser.run(tokens, env); + commands.get(0).run(new Stream()); + assertEquals("hacked = | azazazazaa", Preprocessor.run("$hello", env)); + } + + @Test + public void reduceWithSubstitutionTest() { + Environment env = getEnv(); + String input = "hello=\"hacked $vladimir\""; + input = Preprocessor.run(input, env); + List tokens = Tokenizer.run(input); + List commands = Parser.run(tokens, env); + commands.get(0).run(new Stream()); + assertEquals("hacked putin", Preprocessor.run("$hello", env)); + } + + @Test + public void recursiveReduceWithSubstitutionTest() { + Environment env = getEnv(); + String input = "hello=\"hacked $hello\""; + input = Preprocessor.run(input, env); + List tokens = Tokenizer.run(input); + List commands = Parser.run(tokens, env); + commands.get(0).run(new Stream()); + assertEquals("hacked world", Preprocessor.run("$hello", env)); + } + + @Test + public void echoTest() { + Environment env = getEnv(); + String input = "echo hello"; + List tokens = Tokenizer.run(input); + List commands = Parser.run(tokens, env); + Stream output = CommandExecutor.run(commands); + assertEquals("hello", output.toString()); + } + + @Test + public void echoToPipeToCatTest() { + Environment env = getEnv(); + String input = "echo hello | cat"; + List tokens = Tokenizer.run(input); + List commands = Parser.run(tokens, env); + Stream output = CommandExecutor.run(commands); + assertEquals("hello", output.toString()); + } + + @Test + public void echoToSedAsOutSourceTest() { + + Environment env = getEnv(); + String input = "echo \"hello_world\" | sed 's/hello/goodbye/'"; + List tokens = Tokenizer.run(input); + List commands = Parser.run(tokens, env); + Stream output = CommandExecutor.run(commands); + assertEquals("goodbye_world", output.toString()); + } + + private Environment getEnv() { + Environment env = new Environment(); + env.put("hello", "world"); + env.put("vladimir", "putin"); + + return env; + } +} diff --git a/shell/src/test/java/PreprocessorTests.java b/shell/src/test/java/PreprocessorTests.java new file mode 100644 index 0000000..3ee580c --- /dev/null +++ b/shell/src/test/java/PreprocessorTests.java @@ -0,0 +1,71 @@ +import org.junit.Test; +import shell.Environment; +import shell.Preprocessor; + +import static org.junit.Assert.assertEquals; + +public class PreprocessorTests { + + @Test + public void smokeTest() { + + Environment env = getEnv(); + + assertEquals("cat world | echo putin azazaza", + Preprocessor.run("cat $hello | echo $vladimir azazaza", env)); + } + + @Test + public void emptySubstitutionTest() { + + Environment env = getEnv(); + + assertEquals("", Preprocessor.run("$not_in_env", env)); + } + + @Test + public void lastSub() { + Environment env = getEnv(); + + assertEquals("world", Preprocessor.run("$hello", env)); + } + + @Test + public void varNameBreakers() { + Environment env = getEnv(); + + assertEquals("world'hidden' \"world\" worldputin putin", + Preprocessor.run("$hello'hidden' \"$hello\" $hello$vladimir $vladimir", env)); + } + + @Test + public void hidesInSingleQuotes() { + Environment env = getEnv(); + + assertEquals("'$hello' world", Preprocessor.run("'$hello' $hello", env)); + } + + @Test + public void handlesIncorrectInput() { + Environment env = getEnv(); + + assertEquals("'$hello", Preprocessor.run("'$hello", env)); + } + + @Test + public void nestedQuotes() { + Environment env = getEnv(); + + assertEquals("\"'hello'\" world", Preprocessor.run("\"'$test'\" world", env)); + } + + private Environment getEnv() { + Environment env = new Environment(); + env.put("hello", "world"); + env.put("vladimir", "putin"); + env.put("test", "hello"); + + return env; + } + +} diff --git a/shell/src/test/java/TokenizerTests.java b/shell/src/test/java/TokenizerTests.java new file mode 100644 index 0000000..34d6d22 --- /dev/null +++ b/shell/src/test/java/TokenizerTests.java @@ -0,0 +1,65 @@ +import org.junit.Test; +import shell.Token; +import shell.Tokenizer; + +import java.util.ArrayList; +import java.util.List; + +import static org.junit.Assert.assertEquals; + +public class TokenizerTests { + + @Test + public void smokeTest() { + List expected = new ArrayList<>(); + expected.add(Token.word("hello world")); + expected.add(Token.eof()); + + List actual = Tokenizer.run("'hello world'"); + + assertEquals(expected, actual); + } + + @Test + public void emptyTest() { + List expected = new ArrayList<>(); + expected.add(Token.eof()); + + List actual = Tokenizer.run(""); + + assertEquals(expected, actual); + } + + @Test + public void assignmentTest() { + List expected = new ArrayList<>(); + expected.add(Token.word("hello")); + expected.add(Token.eq()); + expected.add(Token.word("world")); + expected.add(Token.eof()); + + List actual = Tokenizer.run("hello=world"); + + assertEquals(expected, actual); + } + + @Test + public void mixedTest() { + List expected = new ArrayList<>(); + expected.add(Token.word("cat")); + expected.add(Token.word("input.txt")); + expected.add(Token.pipe()); + expected.add(Token.word("cat")); + expected.add(Token.pipe()); + expected.add(Token.word("grep")); + expected.add(Token.word("-v")); + expected.add(Token.word("azazaazz")); + expected.add(Token.word("long \"string\" constant")); + expected.add(Token.eof()); + + + List actual = Tokenizer.run("cat input.txt | cat | grep -v azazaazz 'long \"string\" constant' "); + + assertEquals(expected, actual); + } +} From 14c5beb67208f6b2e65df70137fcf589af21e48b Mon Sep 17 00:00:00 2001 From: simiyutin Date: Mon, 6 Mar 2017 15:53:08 +0300 Subject: [PATCH 02/10] more comments --- shell/src/main/java/commands/Cat.java | 3 +++ shell/src/main/java/commands/Echo.java | 4 ++++ shell/src/main/java/commands/Eq.java | 3 +++ shell/src/main/java/commands/Exit.java | 3 +++ shell/src/main/java/commands/OutSource.java | 3 +++ shell/src/main/java/commands/Pwd.java | 3 +++ shell/src/main/java/commands/Wc.java | 3 +++ shell/src/main/java/shell/Command.java | 2 ++ shell/src/main/java/shell/CommandExecutor.java | 1 + shell/src/main/java/shell/CommandFactory.java | 1 + shell/src/main/java/shell/Environment.java | 2 ++ shell/src/main/java/shell/Parser.java | 1 + shell/src/main/java/shell/Preprocessor.java | 1 + shell/src/main/java/shell/Shell.java | 3 --- shell/src/main/java/shell/Stream.java | 4 ++++ shell/src/main/java/shell/Token.java | 9 +++++++++ shell/src/main/java/shell/Tokenizer.java | 1 + 17 files changed, 44 insertions(+), 3 deletions(-) diff --git a/shell/src/main/java/commands/Cat.java b/shell/src/main/java/commands/Cat.java index 6e36cd9..d8c8e34 100644 --- a/shell/src/main/java/commands/Cat.java +++ b/shell/src/main/java/commands/Cat.java @@ -11,6 +11,9 @@ import java.util.List; import java.util.Scanner; +/** + * Reads file from parameter to stdout or reflects stdin to stdout + */ public class Cat extends Command { public static final String NAME = "cat"; diff --git a/shell/src/main/java/commands/Echo.java b/shell/src/main/java/commands/Echo.java index d786511..8c82e75 100644 --- a/shell/src/main/java/commands/Echo.java +++ b/shell/src/main/java/commands/Echo.java @@ -7,6 +7,10 @@ import java.util.List; import java.util.stream.Collectors; + +/** + * Prints arguments to output stream + */ public class Echo extends Command { public static final String NAME = "echo"; diff --git a/shell/src/main/java/commands/Eq.java b/shell/src/main/java/commands/Eq.java index 641333d..0661da5 100644 --- a/shell/src/main/java/commands/Eq.java +++ b/shell/src/main/java/commands/Eq.java @@ -6,6 +6,9 @@ import java.util.List; +/** + * Puts new variable in context or changes variable value + */ public class Eq extends Command { public Eq(List args, Environment env) { diff --git a/shell/src/main/java/commands/Exit.java b/shell/src/main/java/commands/Exit.java index 2a1fa60..31aa230 100644 --- a/shell/src/main/java/commands/Exit.java +++ b/shell/src/main/java/commands/Exit.java @@ -6,6 +6,9 @@ import java.util.List; +/** + * Exits shell + */ public class Exit extends Command { public static final String NAME = "exit"; diff --git a/shell/src/main/java/commands/OutSource.java b/shell/src/main/java/commands/OutSource.java index 556d10c..193e2fa 100644 --- a/shell/src/main/java/commands/OutSource.java +++ b/shell/src/main/java/commands/OutSource.java @@ -8,6 +8,9 @@ import java.util.List; import java.util.stream.Collectors; +/** + * Passes input arguments and stream to external shell and reads result from its stdout + */ public class OutSource extends Command { private String commandName; diff --git a/shell/src/main/java/commands/Pwd.java b/shell/src/main/java/commands/Pwd.java index a3985a7..4d66b04 100644 --- a/shell/src/main/java/commands/Pwd.java +++ b/shell/src/main/java/commands/Pwd.java @@ -8,6 +8,9 @@ import java.nio.file.Paths; import java.util.List; +/** + * Prints current directory + */ public class Pwd extends Command { public static final String NAME = "pwd"; diff --git a/shell/src/main/java/commands/Wc.java b/shell/src/main/java/commands/Wc.java index 0eef945..5c6d2f5 100644 --- a/shell/src/main/java/commands/Wc.java +++ b/shell/src/main/java/commands/Wc.java @@ -14,6 +14,9 @@ import java.util.Scanner; import java.util.stream.Collectors; +/** + * Counts lines, words and bytes in given file or input stream + */ public class Wc extends Command { public static final String NAME = "wc"; diff --git a/shell/src/main/java/shell/Command.java b/shell/src/main/java/shell/Command.java index b87bbc6..07c30b1 100644 --- a/shell/src/main/java/shell/Command.java +++ b/shell/src/main/java/shell/Command.java @@ -13,6 +13,7 @@ public abstract class Command { /** + * Public constructor * @param args arguments of a command as a List * @param env environment of current running shell */ @@ -22,6 +23,7 @@ public Command(List args, Environment env) { } /** + * Used as interface to command object. Takes input stream and returns result as output stream. * @param stream * @return result data as a Stream object */ diff --git a/shell/src/main/java/shell/CommandExecutor.java b/shell/src/main/java/shell/CommandExecutor.java index 0526c70..bf9dcf3 100644 --- a/shell/src/main/java/shell/CommandExecutor.java +++ b/shell/src/main/java/shell/CommandExecutor.java @@ -12,6 +12,7 @@ public class CommandExecutor { private CommandExecutor() {} /** + * Sequentially executes chained list of commands. * @param commands List of Command objects * @return Stream object which contain result of a chain of computations */ diff --git a/shell/src/main/java/shell/CommandFactory.java b/shell/src/main/java/shell/CommandFactory.java index c96c5ad..3e75950 100644 --- a/shell/src/main/java/shell/CommandFactory.java +++ b/shell/src/main/java/shell/CommandFactory.java @@ -13,6 +13,7 @@ public class CommandFactory { /** + * Factory method to generate commands from tokens. * @param commandToken token, which contains command name as a String * @param args arguments of a command * @param env Environment object diff --git a/shell/src/main/java/shell/Environment.java b/shell/src/main/java/shell/Environment.java index e38a6e3..7562aa4 100644 --- a/shell/src/main/java/shell/Environment.java +++ b/shell/src/main/java/shell/Environment.java @@ -15,6 +15,7 @@ public Environment() { } /** + * Get value of variable * @param var name of requested variable * @return value of a requested variable or empty string if such does not exist in environment */ @@ -31,6 +32,7 @@ public String get(String var) { /** + * Put variable value * @param var name of inserted variable * @param val value of inserted variable */ diff --git a/shell/src/main/java/shell/Parser.java b/shell/src/main/java/shell/Parser.java index f19716e..c8ab817 100644 --- a/shell/src/main/java/shell/Parser.java +++ b/shell/src/main/java/shell/Parser.java @@ -22,6 +22,7 @@ private Parser(List tokens, Environment env) { /** + * Parses list of tokens into list of commands * @param tokens List of tokens to parse as a chain of shell commands * @param env Environment object * @return List of generated commands diff --git a/shell/src/main/java/shell/Preprocessor.java b/shell/src/main/java/shell/Preprocessor.java index f8d103d..e19b9c8 100644 --- a/shell/src/main/java/shell/Preprocessor.java +++ b/shell/src/main/java/shell/Preprocessor.java @@ -6,6 +6,7 @@ public class Preprocessor { /** + * Substitutes variables in unprocessed string * @param unprocessed unprocessed input String * @param env Environment object * @return String with substituted variables from environment diff --git a/shell/src/main/java/shell/Shell.java b/shell/src/main/java/shell/Shell.java index c4202c8..739d030 100644 --- a/shell/src/main/java/shell/Shell.java +++ b/shell/src/main/java/shell/Shell.java @@ -3,9 +3,6 @@ import java.util.List; import java.util.Scanner; -//todo возвращать код возврата -//todo исключения парсера -//прохождения нового теста токенайзера /** * Main entity. Reads from stdin in an infinite loop and executes commands diff --git a/shell/src/main/java/shell/Stream.java b/shell/src/main/java/shell/Stream.java index 1e7b2b3..5a6a3f4 100644 --- a/shell/src/main/java/shell/Stream.java +++ b/shell/src/main/java/shell/Stream.java @@ -15,6 +15,7 @@ public Stream() { } /** + * Read one line from stream * @return next line in stream or null if stream is empty */ public String read() { @@ -22,6 +23,7 @@ public String read() { } /** + * Write one line to stream * @param val line to add to stream */ public void write(String val) { @@ -29,6 +31,7 @@ public void write(String val) { } /** + * Check if stream has more lines to read * @return true if stream has at least one line to read */ public boolean hasNext() { @@ -36,6 +39,7 @@ public boolean hasNext() { } /** + * String representation of a stream object * @return concatenated lines in stream */ @Override diff --git a/shell/src/main/java/shell/Token.java b/shell/src/main/java/shell/Token.java index 0092ba4..c4583c4 100644 --- a/shell/src/main/java/shell/Token.java +++ b/shell/src/main/java/shell/Token.java @@ -36,6 +36,7 @@ private Token(Token.Type type, String value) { } /** + * Static factory method * @return new single quote token */ public static Token singleQuote() { @@ -43,6 +44,7 @@ public static Token singleQuote() { } /** + * Static factory method * @return new double quote token */ public static Token doubleQuote() { @@ -50,6 +52,7 @@ public static Token doubleQuote() { } /** + * Static factory method * @return new '=' token */ public static Token eq() { @@ -57,6 +60,7 @@ public static Token eq() { } /** + * Static factory method * @return new whitespace token */ public static Token whitespace() { @@ -64,6 +68,7 @@ public static Token whitespace() { } /** + * Static factory method * @return new pipe token */ public static Token pipe() { @@ -71,6 +76,7 @@ public static Token pipe() { } /** + * Static factory method * @param word * @return new word token */ @@ -79,6 +85,7 @@ public static Token word(String word) { } /** + * Static factory method * @return new end of line token */ public static Token eof() { @@ -87,6 +94,7 @@ public static Token eof() { /** + * Test if given char corresponds to somme delimiter token * @param c * @return tests if passed char can be a delimiter between words */ @@ -101,6 +109,7 @@ public static boolean isDelimiter(char c) { } /** + * Static factory method * @param c * @return generate corresponding token to passed char */ diff --git a/shell/src/main/java/shell/Tokenizer.java b/shell/src/main/java/shell/Tokenizer.java index 52d5179..00f158c 100644 --- a/shell/src/main/java/shell/Tokenizer.java +++ b/shell/src/main/java/shell/Tokenizer.java @@ -10,6 +10,7 @@ public class Tokenizer { /** + * Start tokenizer on preprocessed string * @param input processed string corresponding to some shell command * @return list of words and operators obtained from passed string */ From 436381a683855bf0d9e63fb18468cd555505679d Mon Sep 17 00:00:00 2001 From: simiyutin Date: Mon, 6 Mar 2017 16:24:44 +0300 Subject: [PATCH 03/10] Create README.md --- README.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..5f43aa7 --- /dev/null +++ b/README.md @@ -0,0 +1,16 @@ +# au_software_design + +##1. Shell + +###Command line utility similar to Unix shell. + +Supported features: + +* echo command +* cat command +* wc command +* exit command +* pwd command +* environment variables +* unknown commands are passed to system shell as separate process through Java.Process library. + From 12f41aa71be5dab9b8e24841ce8b46ebc85788c9 Mon Sep 17 00:00:00 2001 From: simiyutin Date: Tue, 7 Mar 2017 13:23:23 +0300 Subject: [PATCH 04/10] Update README.md --- README.md | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 5f43aa7..266fc9b 100644 --- a/README.md +++ b/README.md @@ -13,4 +13,15 @@ Supported features: * pwd command * environment variables * unknown commands are passed to system shell as separate process through Java.Process library. - + +###Class diagram +![shell class diagram](https://www.gliffy.com/go/share/image/smx5dub0j39jxied850w.png?utm_medium=live-embed&utm_source=custom) + + Data flow: + * Main: run Shell object. + * Shell: Read line from System.in. +   * Preprocessor: Substitute environment variables in input string. E. g. "Hello, $name" -> "Hello, Alex" + * Tokeniser: Split string into a list of tokens: words and operators. + * Parser: Parse list of tokens as sequence of commands divided by pipes. + * Command Executor: Perform chained computation passing output of one comand as input to the next one. + * Pass result to System.in and loop again. From ac8f8cbbacea430a27e0044c4fe54078fb54ed8c Mon Sep 17 00:00:00 2001 From: simiyutin Date: Tue, 7 Mar 2017 14:13:37 +0300 Subject: [PATCH 05/10] exceptions --- .../2.10/taskArtifacts/cache.properties.lock | Bin 17 -> 55 bytes .../.gradle/2.10/taskArtifacts/fileHashes.bin | Bin 22067 -> 22739 bytes .../2.10/taskArtifacts/fileSnapshots.bin | Bin 30333 -> 47470 bytes .../2.10/taskArtifacts/taskArtifacts.bin | Bin 22269 -> 31965 bytes shell/build.gradle | 6 +++ shell/src/main/java/commands/Cat.java | 8 +++- shell/src/main/java/commands/Echo.java | 3 +- shell/src/main/java/commands/Eq.java | 3 +- shell/src/main/java/commands/Exit.java | 3 +- shell/src/main/java/commands/OutSource.java | 9 ++-- shell/src/main/java/commands/Pwd.java | 3 +- shell/src/main/java/commands/Wc.java | 3 +- .../exceptions/CommandExecutionException.java | 10 +++++ .../main/java/exceptions/ParserException.java | 11 +++++ .../main/java/exceptions/ShellException.java | 17 ++++++++ shell/src/main/java/shell/Command.java | 4 +- .../src/main/java/shell/CommandExecutor.java | 13 ++++-- shell/src/main/java/shell/Parser.java | 41 ++++++++++-------- shell/src/test/java/ParserTests.java | 25 +++++++++-- 19 files changed, 123 insertions(+), 36 deletions(-) create mode 100644 shell/src/main/java/exceptions/CommandExecutionException.java create mode 100644 shell/src/main/java/exceptions/ParserException.java create mode 100644 shell/src/main/java/exceptions/ShellException.java diff --git a/shell/.gradle/2.10/taskArtifacts/cache.properties.lock b/shell/.gradle/2.10/taskArtifacts/cache.properties.lock index 7a2565a4de4e1f5ee642cb703aa0609349b5624c..9b611430cdcf69ab3bef76113d5390143f06dff1 100644 GIT binary patch literal 55 zcmZQ}IWh$jrcSEoIe;?C$@bE3PuIm{^#bGYI!!nQ!zDN zBTk7zHuoO9n-6UdUzzQ~mD$T*$!s@*MZC{+neAFDvzM#LZ0Aau?ZKAW+WdR68=jlY zrsNlMHfw_EtUyc{2I5&v%r^mKv79hpHPBAnxq=b=PGkb?w3wLC0*JICG0_^(sMUuF zkAq6>e9ZR>2-S(igl(W*2lpESM!IR3D7&OoS8Bq}Z!3#P@?X4T{$;Q?#V;qGLZPmZ zasn6P8Q@L91cbY5%;qpc<;0tk(-=BgJ&T7_two&(D}orU9`+P2xaRDL<3?^F_eYOi ztTr3II5UvD&-V!p&TqSsmxiC8nD0f&FtoSof<(A4YIFNOQ4N!gFbdG_?-T zg#})?sLSCGo57fikhQ);Lt{9kzBDW1roW&hCI6G_`sI3F9LAzTg}|s3hG=@Teow%` z&DCi5H562^8BfFfwgqk);}?gx7#=GJqq&N0>FWl{53i0k_!s&Gse`uV0$kSU^(=pB2hr1?la$CS2 z^6mO5{HfPAv-r#WV z^|Pzh8(YmrdfcS}UnKSMsC3l?V%~f< z)t;B~54|weZnTfFeS_6+2sDA9{1iZSXR#Zft)D9XBO_i)W z##fj7-R=9cK%1`@$6;(~RkM5FJXtbjfd1pEa_(c&=d4;7dQr5}#%nMef2@yR9L6+Z z*A;I6#+FMrH|)wg_NETST7zOW!v1SN{i&3FMQaBAy6(;yu=q<}yZ$u z(l`D1Hv;A7r%KN1L>SKw@P0amuV!)v-Jv7(`L_bv&RSL17<+K8FuA6x&oin9`DsF4 zQDfW>bh}?bK{KIBe>;?Xw7Q|>G998C!i>bsjkw#SC#> zlVn!ffotBxDvJf1HFRHUD8Hj+o_TcaKoarFpXolBSeL_aSr;(vX8xk2sf4IKPD;G{jo9D`&5F;kUBAV+|2kj#qPNREQf zBe7ZAIT}AdA`xUI#?!T0KywumF@hL|mJ_~N>-j8WIUDpBEjgp;GJ@p>`wjNqN3bQ> z;WLA6da2>>$BE&m?41NLBlgvOg-zQw%iv_LS54HwnP(6! zONXd$F6<{LK}yw~+vkGTjfEJBy9%VLx`ZRXmxMqEx;?Qt*u^$iE}z(QC)he?@e38h z8Z89bLkK%XLN8jI)x?8wFQ*zG4LYRqkvvFnB{77khe;?eHJ!C+#jV7J7V?&@#RfE_ zWQ&wMN$BaQGI!94Qn0Q};;^EJvkO7QDS!J1SFJt=}1roxX^AIYRq_q{egdBWKJxU(*qL9 z^a%c8j@`Yaa~`U$wKKvy5wrk8io*nC^fu#Awxs{0hea#zf@9u?B_zbGL`M!r{Gt%e F{C^PWwPpYS delta 1549 zcmZ9MX;4#F6vvYn3Zx}KElD0A5JLbfvUCIjC`heP9tmM-ScM72GEziYgh(tMD}@4T zEpU}0SX4mN78oMRQkH~J%Dz+>%Rp-ZaRG|0S`n#W-*Wpw&zC#*o!|YRbM86!jVb93 zHS_{DlLn2WR36|KssS)ZV-U$r@CC|2Fb7bA`XGT}U>e`~s=*4r6ZHZwV-Dgk2I0nX zL@WfO#t)Hzd7w6_M*Q?ayr~=s(^+n{KZk!(yA>>U#j3MA4=7JGlXG{Lu zw7=DhgIi0nEs5E`dpL}&W01|ESR|ihJuz4G*Y@0axxvJHmfx?AXm&3#AQ%EpVNQB@ z3TLPj^Z_CTa1S%m!asfv*0E4Ds`#Q)rDY#Gq4lf)`73$?9*qErer7}t<$*_}O_oJQ z6V@$TxLWzUp#LH)%ALpoeTNEx1B5rpQ!l%JFkd73uKR0svV9l4x9 zzgk)q^#4MMuv|zHVUK&V4O8_z9n~mmR%lHSx&)4iEYLky-?zOeNa|SftQl5$*Va?c z2o`7-g`p>_-*Wa(9+KT3RE!PV3U5H?CSW5DIp=~)Pwfgv%E*Vs4UXfO?zApxfzCH51%@7>z>76F zQgWgEq{J1ua&S&K&LttkvIqz*0=0+>_V^2VcBk_uKDlT3uWOfp-F7J97zrBH2T-6^ zBA^Gb`S_i6>_25?U#K7VsCRo^mK@tha@s!a6o-IK5)OFj&($i_N#_F-3E8Y3W)HUG z@YB7>OVnr9WM3b7Mo>0Lona}-3H(F+L>_ZfuhaN4zg5ff5Y-IBG7p&PSrQumuw^-= zPdikz7E&=9@A4^BI!!@32vIYbk&t6rwR<3`=-CTJT-AJr;_>Y?$l}6;=^h{jhpzps zZLL3wZF}%Q{8OF%aR@b2kX}3qHEtjNYNzLN`PV8N@1$$rEf7#iTagz9(JM))Jcaqf zymCwQ(Wv{IZF=~TP)SWey2E5@D*=~yZi&+D+I0`s!{Gd>)Z5*;q?)QVhyoGvritlX zO7G5-@9@(Ui`@u z#@a-7yCEo>At*Zs+=HF)^*TricE;BW;A(Ie5w=)i7gf*TUP~@zpWhJvY(E*+J{I z+U5D&0fKfQGsJ?&m$6QIvCjlxGC}c)$`0B8PD+LG0h!2Xh^sAL{c?eG!IVjJ%PNCW U*EKu3m16%~q1do8YNa{;2X~wV2mk;8 diff --git a/shell/.gradle/2.10/taskArtifacts/fileSnapshots.bin b/shell/.gradle/2.10/taskArtifacts/fileSnapshots.bin index b6a62f2d51d515332c21471b5c7a0317459b20d3..c057143ed6e8db321cbe969015a9dd1bca8f26e1 100644 GIT binary patch delta 4741 zcmeHKc~nzp7Egi@mH^)iAV~=*$XaEo5iJT55Hu`-fXJ{zSR`SSu%n`;Ajmja_0s_r z5h$n?iXd2u3tfZ(R06!eXQV zcwJefGE9yNyE3o|sc&xEr6I5MHrWZ9u){?a5Z7?>ACqee zSmQ%rbG-H6A(FCS(mLH$6M4TjV#I$yykwa9jr;|LLDhf2K5zW&L{}{;La1AL{#?cG zFC%SA?C+_Ww9$WlxQ?Z>&?1JH#*+gcEn)I23Pd02q?)}Q(m%nJd4M}fcT)kGfv0+R zRxqFLA@bgL8El>}^#T_VxB>L6{&7{yk+p>Cm?n`^zytj}D2~Nk!9|+gR5TF6z255@ zfg{@=B4%a0VzpOCKc2cv1$R#bP<;o^TS^jo8av|iD$Ac-`8Nwk+%XH41$$|B0he=Z znexke>x|_-n+o`$yE+wk!0NuYbPD;Y27Zxwek=FO0?~wa910capQg31S3SO0ne(qT z5{_?n>y&n)D;Wj{k?Ht_AcXu&UtT@UiA9Au z33}JW1eW

d-RR*^0TcL&(1Civ$VD7ocslX$?$Q43g|myB{J9c43jK@jLP19eWSE%^H{LakjWWGo6q%8 zQ%)$m0_YDLIEuNVu8BRbK5f!Kr6=8GaML3#BI0<-$#MuGcYNDe=H>(bKDSeA-qT(} zfDS&csBU#hTl!K(=u|!o>azreeAMK-dh7X7adA_c$8R;I?hLlyy5b!CTfTqE4w-pq z!Ba*p6mlb1FJb+2=V`9GTl)gxT{Hk&oe2IWsXmZDXiq7fe>ZEJICa+tt?8H1gu2mz zU5!FmdOq;eyKe9x4?{oGy__K!rraz3?Kr2P3?p)~neDYDb zMU|V(f)vGMtjZ87P%6d+tP=tzQa*PI0Z#)hN`j?fuL-Q z5lQzqgB3EppnNK=r}Lm)gfgrON|{+*@Ggo8sKB6L!EaedW{27zQVZ%!c@*L=!5iYf z2)(9E>U6Ail3>{eOE?zMfW|SSO#ULo%~qR~U7@q<9brDr+$!E&LMzX1CJ?iu4fO=*1hWk$YB3&asgB7NR^2Q=uoJQbUr|BQ z7NOHFrM$|{Ay{G55L0+lAcV3EioEs_j-D;_=rey zg3IjXG&onjaKPp=>^ODEh^++Xja}bcz31M4~!ct#v7H7LhlL j$mII@W)b<%i^$A*>%VOq=zE;LZOl2}{<#+s5u5fC)hx&% delta 69 zcmaF&iRtef#trrojQo=eBqSy;kVu$pASp39K{8?T4Ir%`B{4Ze%0u8k6fl4RW7S5* Qzv3GWW{YhO@X*x*0NaNfp#T5? diff --git a/shell/.gradle/2.10/taskArtifacts/taskArtifacts.bin b/shell/.gradle/2.10/taskArtifacts/taskArtifacts.bin index 04bc858e1d8a35eb4367280e2950e944b62d5f9c..1318f3477d5fa7e82a326890e5dc812c139d9a73 100644 GIT binary patch delta 482 zcmeynmhtXS#tEX9EDT@}76+u}L)bp~3=GU0A?yGJ1_m}e2s`XA0|UD^gw5c#QSpNK zWH|{BsW^}SP{5S%_|wdG7FLLo!XJ|xB*dgV_Q9kB0%qlKcRk(CJu3j8ETm{$1AxN`Y%8I|hqRo*fo7IXA42iBW#?em}9z zYkVu1HW&MJacP_}2D-@>h)qG5sp_ux+;)%W{kz&iJ}fFp7O(rB#S@wNAYe1tlr=uS zn>{?`nKz&HSir2s?u@4S|4Z)c;@{6)lF3V7F3r@nB&_fNGoQI~8(8z^H9k4ao9lew z8hOGQ7dmk`rJ@mElGmsn7Hl& E0A~cQd;kCd delta 114 zcmccnlkx9b#tEXF3{W7pG4QPT#02BXauOa=KKcKlfGOeerCnE4p7*EZ$aHIFO< diff --git a/shell/build.gradle b/shell/build.gradle index afbf593..1620193 100644 --- a/shell/build.gradle +++ b/shell/build.gradle @@ -2,6 +2,8 @@ group 'simiyutin' version '1.0-SNAPSHOT' apply plugin: 'java' +apply plugin: 'application' +mainClassName = "shell.Main" sourceCompatibility = 1.8 @@ -9,6 +11,10 @@ repositories { mavenCentral() } +run{ + standardInput = System.in +} + dependencies { testCompile group: 'junit', name: 'junit', version: '4.11' } diff --git a/shell/src/main/java/commands/Cat.java b/shell/src/main/java/commands/Cat.java index d8c8e34..3bb7021 100644 --- a/shell/src/main/java/commands/Cat.java +++ b/shell/src/main/java/commands/Cat.java @@ -1,10 +1,12 @@ package commands; +import exceptions.CommandExecutionException; import shell.Command; import shell.Environment; import shell.Stream; import java.io.IOException; +import java.nio.charset.MalformedInputException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; @@ -23,7 +25,7 @@ public Cat(List args, Environment env) { } @Override - public Stream run(Stream stream) { + public Stream run(Stream stream) throws CommandExecutionException { if (stream.hasNext()) { return stream; @@ -41,8 +43,10 @@ public Stream run(Stream stream) { try { List lines = Files.readAllLines(file); lines.forEach(res::write); + } catch (MalformedInputException e) { + throw new CommandExecutionException("Cannot determine file encoding"); } catch (IOException e) { - e.printStackTrace(); + throw new CommandExecutionException("Error while reading file: " + e.toString()); } } return res; diff --git a/shell/src/main/java/commands/Echo.java b/shell/src/main/java/commands/Echo.java index 8c82e75..1ff5827 100644 --- a/shell/src/main/java/commands/Echo.java +++ b/shell/src/main/java/commands/Echo.java @@ -1,5 +1,6 @@ package commands; +import exceptions.CommandExecutionException; import shell.Command; import shell.Environment; import shell.Stream; @@ -20,7 +21,7 @@ public Echo(List args, Environment env) { } @Override - public Stream run(Stream ignored) { + public Stream run(Stream ignored) throws CommandExecutionException { String toPrint = args.stream().collect(Collectors.joining()); diff --git a/shell/src/main/java/commands/Eq.java b/shell/src/main/java/commands/Eq.java index 0661da5..c2d3127 100644 --- a/shell/src/main/java/commands/Eq.java +++ b/shell/src/main/java/commands/Eq.java @@ -1,5 +1,6 @@ package commands; +import exceptions.CommandExecutionException; import shell.Command; import shell.Environment; import shell.Stream; @@ -16,7 +17,7 @@ public Eq(List args, Environment env) { } @Override - public Stream run(Stream ignored) { + public Stream run(Stream ignored) throws CommandExecutionException { String var = args.get(0); String val = args.get(1); env.put(var, val); diff --git a/shell/src/main/java/commands/Exit.java b/shell/src/main/java/commands/Exit.java index 31aa230..0123e00 100644 --- a/shell/src/main/java/commands/Exit.java +++ b/shell/src/main/java/commands/Exit.java @@ -1,5 +1,6 @@ package commands; +import exceptions.CommandExecutionException; import shell.Command; import shell.Environment; import shell.Stream; @@ -18,7 +19,7 @@ public Exit(List args, Environment env) { } @Override - public Stream run(Stream stream) { + public Stream run(Stream stream) throws CommandExecutionException { System.exit(0); return null; } diff --git a/shell/src/main/java/commands/OutSource.java b/shell/src/main/java/commands/OutSource.java index 193e2fa..6e30db1 100644 --- a/shell/src/main/java/commands/OutSource.java +++ b/shell/src/main/java/commands/OutSource.java @@ -1,5 +1,6 @@ package commands; +import exceptions.CommandExecutionException; import shell.Command; import shell.Environment; import shell.Stream; @@ -21,7 +22,7 @@ public OutSource(String commandName, List args, Environment env) { } @Override - public Stream run(Stream stream) { + public Stream run(Stream stream) throws CommandExecutionException { String command = commandName + " " + args.stream().collect(Collectors.joining(" ")); Stream output = new Stream(); try { @@ -29,17 +30,17 @@ public Stream run(Stream stream) { write(process, stream); output = read(process); } catch (IOException | InterruptedException e) { - e.printStackTrace(); + throw new CommandExecutionException("System error: " + e.toString()); } return output; } private void write(Process process, Stream stream) throws IOException { Writer handle = new PrintWriter(process.getOutputStream()); - final int LINE_FEED = 10; + final int lineFeed = 10; while (stream.hasNext()) { handle.write(stream.read()); - handle.write(LINE_FEED); + handle.write(lineFeed); } handle.close(); } diff --git a/shell/src/main/java/commands/Pwd.java b/shell/src/main/java/commands/Pwd.java index 4d66b04..6f940ad 100644 --- a/shell/src/main/java/commands/Pwd.java +++ b/shell/src/main/java/commands/Pwd.java @@ -1,5 +1,6 @@ package commands; +import exceptions.CommandExecutionException; import shell.Command; import shell.Environment; import shell.Stream; @@ -20,7 +21,7 @@ public Pwd(List args, Environment env) { } @Override - public Stream run(Stream ignored) { + public Stream run(Stream ignored) throws CommandExecutionException { Path currentRelativePath = Paths.get(""); String currentDir = currentRelativePath.toAbsolutePath().toString(); Stream stream = new Stream(); diff --git a/shell/src/main/java/commands/Wc.java b/shell/src/main/java/commands/Wc.java index 5c6d2f5..ba545a8 100644 --- a/shell/src/main/java/commands/Wc.java +++ b/shell/src/main/java/commands/Wc.java @@ -1,5 +1,6 @@ package commands; +import exceptions.CommandExecutionException; import shell.Command; import shell.Environment; import shell.Stream; @@ -26,7 +27,7 @@ public Wc(List args, Environment env) { } @Override - public Stream run(Stream stream) { + public Stream run(Stream stream) throws CommandExecutionException { if (!args.isEmpty()) { return handleFile(); } else if (stream.hasNext()) { diff --git a/shell/src/main/java/exceptions/CommandExecutionException.java b/shell/src/main/java/exceptions/CommandExecutionException.java new file mode 100644 index 0000000..fc1e1e7 --- /dev/null +++ b/shell/src/main/java/exceptions/CommandExecutionException.java @@ -0,0 +1,10 @@ +package exceptions; + +/** + * This is used when errors while commands execution encountered + */ +public class CommandExecutionException extends ShellException { + public CommandExecutionException(String what) { + super(what); + } +} diff --git a/shell/src/main/java/exceptions/ParserException.java b/shell/src/main/java/exceptions/ParserException.java new file mode 100644 index 0000000..8905ef8 --- /dev/null +++ b/shell/src/main/java/exceptions/ParserException.java @@ -0,0 +1,11 @@ +package exceptions; + + +/** + * This is thrown when command has incorrect syntax + */ +public class ParserException extends ShellException { + public ParserException(String what) { + super(what); + } +} diff --git a/shell/src/main/java/exceptions/ShellException.java b/shell/src/main/java/exceptions/ShellException.java new file mode 100644 index 0000000..ccf8203 --- /dev/null +++ b/shell/src/main/java/exceptions/ShellException.java @@ -0,0 +1,17 @@ +package exceptions; + + +/** + * Base class for shell exceptions + */ +public class ShellException extends Exception { + private String what = ""; + public ShellException(String what) { + this.what = what; + } + + @Override + public String toString() { + return what; + } +} diff --git a/shell/src/main/java/shell/Command.java b/shell/src/main/java/shell/Command.java index 07c30b1..cf0c8f9 100644 --- a/shell/src/main/java/shell/Command.java +++ b/shell/src/main/java/shell/Command.java @@ -1,5 +1,7 @@ package shell; +import exceptions.CommandExecutionException; + import java.util.List; /** @@ -27,5 +29,5 @@ public Command(List args, Environment env) { * @param stream * @return result data as a Stream object */ - public abstract Stream run(Stream stream); + public abstract Stream run(Stream stream) throws CommandExecutionException; } diff --git a/shell/src/main/java/shell/CommandExecutor.java b/shell/src/main/java/shell/CommandExecutor.java index bf9dcf3..ed14ae6 100644 --- a/shell/src/main/java/shell/CommandExecutor.java +++ b/shell/src/main/java/shell/CommandExecutor.java @@ -1,5 +1,7 @@ package shell; +import exceptions.CommandExecutionException; + import java.util.List; @@ -18,9 +20,14 @@ private CommandExecutor() {} */ public static Stream run(List commands) { Stream stream = new Stream(); - for (Command command : commands) { - stream = command.run(stream); - } + try { + for (Command command : commands) { + stream = command.run(stream); + } + } catch (CommandExecutionException e) { + System.out.println(e.toString()); + return new Stream(); + } return stream; } } diff --git a/shell/src/main/java/shell/Parser.java b/shell/src/main/java/shell/Parser.java index c8ab817..57ad608 100644 --- a/shell/src/main/java/shell/Parser.java +++ b/shell/src/main/java/shell/Parser.java @@ -1,5 +1,7 @@ package shell; +import exceptions.ParserException; + import java.util.ArrayDeque; import java.util.ArrayList; import java.util.List; @@ -28,24 +30,27 @@ private Parser(List tokens, Environment env) { * @return List of generated commands */ public static List run(List tokens, Environment env) { - - Parser parser = new Parser(tokens, env); - parser.start(); - return parser.commands; - + try { + Parser parser = new Parser(tokens, env); + parser.start(); + return parser.commands; + } catch (ParserException e) { + System.out.println(e.toString()); + return new ArrayList<>(); + } } - private void start() { + private void start() throws ParserException { Token token = queue.poll(); if (token.getType() == Token.Type.WORD) { parseCommand(token); } else { - error(); + error("Expression must start with a command"); } } - private void parseCommand(Token firstWord) { + private void parseCommand(Token firstWord) throws ParserException { Token token = queue.poll(); switch (token.getType()) { case EQ: @@ -64,17 +69,17 @@ private void parseCommand(Token firstWord) { createCommand(firstWord, new ArrayList<>()); break; default: - error(); + error("Unexpected token"); break; } } - private void createCommand(Token commandToken, List args) { + private void createCommand(Token commandToken, List args) throws ParserException { Command command = CommandFactory.produce(commandToken, args, env); commands.add(command); } - private void parseEQ(Token var) { + private void parseEQ(Token var) throws ParserException { Token val = queue.poll(); switch (val.getType()) { case WORD: @@ -85,19 +90,19 @@ private void parseEQ(Token var) { createCommand(Token.eq(), args); break; default: - error(); + error("Violated syntax of assignment operator"); break; } } - private void checkEQSyntax() { + private void checkEQSyntax() throws ParserException { Token token = queue.poll(); if (token.getType() != Token.Type.EOF) { - error(); + error("Violated syntax of assignment operator"); } } - private void parseArg(Token command, List args) { + private void parseArg(Token command, List args) throws ParserException { Token token = queue.poll(); switch (token.getType()) { case WORD: @@ -112,11 +117,13 @@ private void parseArg(Token command, List args) { createCommand(command, args); break; default: - error(); + error("Violated syntax of argument list"); break; } } - private void error() {} + private void error(String what) throws ParserException { + throw new ParserException(what); + } } diff --git a/shell/src/test/java/ParserTests.java b/shell/src/test/java/ParserTests.java index 6e438af..617658d 100644 --- a/shell/src/test/java/ParserTests.java +++ b/shell/src/test/java/ParserTests.java @@ -1,3 +1,4 @@ +import exceptions.CommandExecutionException; import org.junit.Test; import shell.*; @@ -13,7 +14,11 @@ public void smokeTest() { String input = "hello=hacked"; List tokens = Tokenizer.run(input); List commands = Parser.run(tokens, env); - commands.get(0).run(new Stream()); + try { + commands.get(0).run(new Stream()); + } catch (CommandExecutionException e) { + e.printStackTrace(); + } assertEquals("hacked", Preprocessor.run("$hello", env)); } @@ -23,7 +28,11 @@ public void reduceTest() { String input = "hello='hacked = | azazazazaa'"; List tokens = Tokenizer.run(input); List commands = Parser.run(tokens, env); - commands.get(0).run(new Stream()); + try { + commands.get(0).run(new Stream()); + } catch (CommandExecutionException e) { + e.printStackTrace(); + } assertEquals("hacked = | azazazazaa", Preprocessor.run("$hello", env)); } @@ -34,7 +43,11 @@ public void reduceWithSubstitutionTest() { input = Preprocessor.run(input, env); List tokens = Tokenizer.run(input); List commands = Parser.run(tokens, env); - commands.get(0).run(new Stream()); + try { + commands.get(0).run(new Stream()); + } catch (CommandExecutionException e) { + e.printStackTrace(); + } assertEquals("hacked putin", Preprocessor.run("$hello", env)); } @@ -45,7 +58,11 @@ public void recursiveReduceWithSubstitutionTest() { input = Preprocessor.run(input, env); List tokens = Tokenizer.run(input); List commands = Parser.run(tokens, env); - commands.get(0).run(new Stream()); + try { + commands.get(0).run(new Stream()); + } catch (CommandExecutionException e) { + e.printStackTrace(); + } assertEquals("hacked world", Preprocessor.run("$hello", env)); } From bae7b44e1c2a976ce8ce4197f04ad7dc20a9c446 Mon Sep 17 00:00:00 2001 From: simiyutin Date: Tue, 7 Mar 2017 14:17:57 +0300 Subject: [PATCH 06/10] Update README.md --- README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 266fc9b..eff4d63 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ ###Command line utility similar to Unix shell. -Supported features: +####Supported features: * echo command * cat command @@ -14,13 +14,14 @@ Supported features: * environment variables * unknown commands are passed to system shell as separate process through Java.Process library. -###Class diagram +####Class diagram ![shell class diagram](https://www.gliffy.com/go/share/image/smx5dub0j39jxied850w.png?utm_medium=live-embed&utm_source=custom) - Data flow: +####Data flow: * Main: run Shell object. * Shell: Read line from System.in. -   * Preprocessor: Substitute environment variables in input string. E. g. "Hello, $name" -> "Hello, Alex" +   + * Preprocessor: Substitute environment variables in input string. E. g. "Hello, $name" -> "Hello, Alex" * Tokeniser: Split string into a list of tokens: words and operators. * Parser: Parse list of tokens as sequence of commands divided by pipes. * Command Executor: Perform chained computation passing output of one comand as input to the next one. From cf1f13b0d1e496216bcac3b13549205433b3a23e Mon Sep 17 00:00:00 2001 From: simiyutin Date: Tue, 7 Mar 2017 14:18:20 +0300 Subject: [PATCH 07/10] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index eff4d63..d02f125 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ * environment variables * unknown commands are passed to system shell as separate process through Java.Process library. -####Class diagram +####Class diagram: ![shell class diagram](https://www.gliffy.com/go/share/image/smx5dub0j39jxied850w.png?utm_medium=live-embed&utm_source=custom) ####Data flow: From 26a50788a5fb37c2d1cc1565bbed275ea03da1ef Mon Sep 17 00:00:00 2001 From: simiyutin Date: Sat, 11 Mar 2017 22:57:22 +0300 Subject: [PATCH 08/10] fixes --- shell/src/main/java/shell/Command.java | 4 +-- shell/src/main/java/shell/CommandFactory.java | 5 --- shell/src/main/java/shell/Shell.java | 2 +- shell/src/main/java/shell/Token.java | 11 +++---- shell/src/test/java/ParserTests.java | 32 +++++-------------- 5 files changed, 16 insertions(+), 38 deletions(-) diff --git a/shell/src/main/java/shell/Command.java b/shell/src/main/java/shell/Command.java index cf0c8f9..983fc2e 100644 --- a/shell/src/main/java/shell/Command.java +++ b/shell/src/main/java/shell/Command.java @@ -26,8 +26,8 @@ public Command(List args, Environment env) { /** * Used as interface to command object. Takes input stream and returns result as output stream. - * @param stream - * @return result data as a Stream object + * @param stream input data as a Stream object + * @return output data as a Stream object */ public abstract Stream run(Stream stream) throws CommandExecutionException; } diff --git a/shell/src/main/java/shell/CommandFactory.java b/shell/src/main/java/shell/CommandFactory.java index 3e75950..553b6dc 100644 --- a/shell/src/main/java/shell/CommandFactory.java +++ b/shell/src/main/java/shell/CommandFactory.java @@ -59,9 +59,4 @@ private static Command getCommand(String commandName, List args, Environ } return command; } - - private static String concat(List args) { - - return args.stream().collect(Collectors.joining()); - } } diff --git a/shell/src/main/java/shell/Shell.java b/shell/src/main/java/shell/Shell.java index 739d030..ef681d2 100644 --- a/shell/src/main/java/shell/Shell.java +++ b/shell/src/main/java/shell/Shell.java @@ -14,7 +14,7 @@ public class Shell { /** * constructs Shell with empty environment */ - Shell() { + public Shell() { env = new Environment(); } diff --git a/shell/src/main/java/shell/Token.java b/shell/src/main/java/shell/Token.java index c4583c4..1ddd76f 100644 --- a/shell/src/main/java/shell/Token.java +++ b/shell/src/main/java/shell/Token.java @@ -3,7 +3,7 @@ import java.util.ArrayList; /** - * Describes possible lexems + * Describes possible lexemes */ public class Token { @@ -77,7 +77,7 @@ public static Token pipe() { /** * Static factory method - * @param word + * @param word string to encapsulate in newly created token * @return new word token */ public static Token word(String word) { @@ -94,9 +94,8 @@ public static Token eof() { /** - * Test if given char corresponds to somme delimiter token - * @param c - * @return tests if passed char can be a delimiter between words + * Tests if given char corresponds to any delimiter token + * @param c character to test */ public static boolean isDelimiter(char c) { ArrayList test = new ArrayList<>(); @@ -110,7 +109,7 @@ public static boolean isDelimiter(char c) { /** * Static factory method - * @param c + * @param c character to get corresponding token * @return generate corresponding token to passed char */ public static Token valueOf(char c) { diff --git a/shell/src/test/java/ParserTests.java b/shell/src/test/java/ParserTests.java index 617658d..5ebf524 100644 --- a/shell/src/test/java/ParserTests.java +++ b/shell/src/test/java/ParserTests.java @@ -9,60 +9,44 @@ public class ParserTests { @Test - public void smokeTest() { + public void smokeTest() throws Exception { Environment env = getEnv(); String input = "hello=hacked"; List tokens = Tokenizer.run(input); List commands = Parser.run(tokens, env); - try { - commands.get(0).run(new Stream()); - } catch (CommandExecutionException e) { - e.printStackTrace(); - } + commands.get(0).run(new Stream()); assertEquals("hacked", Preprocessor.run("$hello", env)); } @Test - public void reduceTest() { + public void reduceTest() throws Exception { Environment env = getEnv(); String input = "hello='hacked = | azazazazaa'"; List tokens = Tokenizer.run(input); List commands = Parser.run(tokens, env); - try { - commands.get(0).run(new Stream()); - } catch (CommandExecutionException e) { - e.printStackTrace(); - } + commands.get(0).run(new Stream()); assertEquals("hacked = | azazazazaa", Preprocessor.run("$hello", env)); } @Test - public void reduceWithSubstitutionTest() { + public void reduceWithSubstitutionTest() throws Exception { Environment env = getEnv(); String input = "hello=\"hacked $vladimir\""; input = Preprocessor.run(input, env); List tokens = Tokenizer.run(input); List commands = Parser.run(tokens, env); - try { - commands.get(0).run(new Stream()); - } catch (CommandExecutionException e) { - e.printStackTrace(); - } + commands.get(0).run(new Stream()); assertEquals("hacked putin", Preprocessor.run("$hello", env)); } @Test - public void recursiveReduceWithSubstitutionTest() { + public void recursiveReduceWithSubstitutionTest() throws Exception { Environment env = getEnv(); String input = "hello=\"hacked $hello\""; input = Preprocessor.run(input, env); List tokens = Tokenizer.run(input); List commands = Parser.run(tokens, env); - try { - commands.get(0).run(new Stream()); - } catch (CommandExecutionException e) { - e.printStackTrace(); - } + commands.get(0).run(new Stream()); assertEquals("hacked world", Preprocessor.run("$hello", env)); } From 1879ced96c0c26b3caba1b9060e42f494b1ff3fa Mon Sep 17 00:00:00 2001 From: simiyutin Date: Sat, 11 Mar 2017 23:18:40 +0300 Subject: [PATCH 09/10] reversed domain name packages --- shell/build.gradle | 2 +- .../{ => com/simiyutin/au/shell}/commands/Cat.java | 10 +++++----- .../{ => com/simiyutin/au/shell}/commands/Echo.java | 10 +++++----- .../java/{ => com/simiyutin/au/shell}/commands/Eq.java | 10 +++++----- .../{ => com/simiyutin/au/shell}/commands/Exit.java | 10 +++++----- .../simiyutin/au/shell}/commands/OutSource.java | 10 +++++----- .../{ => com/simiyutin/au/shell}/commands/Pwd.java | 10 +++++----- .../java/{ => com/simiyutin/au/shell}/commands/Wc.java | 10 +++++----- .../simiyutin/au/shell/core}/Command.java | 4 ++-- .../simiyutin/au/shell/core}/CommandExecutor.java | 4 ++-- .../simiyutin/au/shell/core}/CommandFactory.java | 5 ++--- .../simiyutin/au/shell/core}/Environment.java | 2 +- .../{shell => com/simiyutin/au/shell/core}/Main.java | 2 +- .../{shell => com/simiyutin/au/shell/core}/Parser.java | 4 ++-- .../simiyutin/au/shell/core}/Preprocessor.java | 2 +- .../{shell => com/simiyutin/au/shell/core}/Shell.java | 2 +- .../{shell => com/simiyutin/au/shell/core}/Stream.java | 2 +- .../{shell => com/simiyutin/au/shell/core}/Token.java | 2 +- .../simiyutin/au/shell/core}/Tokenizer.java | 2 +- .../core}/exceptions/CommandExecutionException.java | 2 +- .../au/shell/core}/exceptions/ParserException.java | 2 +- .../au/shell/core}/exceptions/ShellException.java | 2 +- .../java/{ => com/simiyutin/au/shell}/ParserTests.java | 5 +++-- .../simiyutin/au/shell}/PreprocessorTests.java | 6 ++++-- .../{ => com/simiyutin/au/shell}/TokenizerTests.java | 6 ++++-- 25 files changed, 65 insertions(+), 61 deletions(-) rename shell/src/main/java/{ => com/simiyutin/au/shell}/commands/Cat.java (84%) rename shell/src/main/java/{ => com/simiyutin/au/shell}/commands/Echo.java (68%) rename shell/src/main/java/{ => com/simiyutin/au/shell}/commands/Eq.java (63%) rename shell/src/main/java/{ => com/simiyutin/au/shell}/commands/Exit.java (59%) rename shell/src/main/java/{ => com/simiyutin/au/shell}/commands/OutSource.java (87%) rename shell/src/main/java/{ => com/simiyutin/au/shell}/commands/Pwd.java (70%) rename shell/src/main/java/{ => com/simiyutin/au/shell}/commands/Wc.java (90%) rename shell/src/main/java/{shell => com/simiyutin/au/shell/core}/Command.java (88%) rename shell/src/main/java/{shell => com/simiyutin/au/shell/core}/CommandExecutor.java (88%) rename shell/src/main/java/{shell => com/simiyutin/au/shell/core}/CommandFactory.java (95%) rename shell/src/main/java/{shell => com/simiyutin/au/shell/core}/Environment.java (96%) rename shell/src/main/java/{shell => com/simiyutin/au/shell/core}/Main.java (77%) rename shell/src/main/java/{shell => com/simiyutin/au/shell/core}/Parser.java (97%) rename shell/src/main/java/{shell => com/simiyutin/au/shell/core}/Preprocessor.java (98%) rename shell/src/main/java/{shell => com/simiyutin/au/shell/core}/Shell.java (95%) rename shell/src/main/java/{shell => com/simiyutin/au/shell/core}/Stream.java (97%) rename shell/src/main/java/{shell => com/simiyutin/au/shell/core}/Token.java (99%) rename shell/src/main/java/{shell => com/simiyutin/au/shell/core}/Tokenizer.java (98%) rename shell/src/main/java/{ => com/simiyutin/au/shell/core}/exceptions/CommandExecutionException.java (82%) rename shell/src/main/java/{ => com/simiyutin/au/shell/core}/exceptions/ParserException.java (79%) rename shell/src/main/java/{ => com/simiyutin/au/shell/core}/exceptions/ShellException.java (84%) rename shell/src/test/java/{ => com/simiyutin/au/shell}/ParserTests.java (97%) rename shell/src/test/java/{ => com/simiyutin/au/shell}/PreprocessorTests.java (92%) rename shell/src/test/java/{ => com/simiyutin/au/shell}/TokenizerTests.java (93%) diff --git a/shell/build.gradle b/shell/build.gradle index 1620193..5247b51 100644 --- a/shell/build.gradle +++ b/shell/build.gradle @@ -3,7 +3,7 @@ version '1.0-SNAPSHOT' apply plugin: 'java' apply plugin: 'application' -mainClassName = "shell.Main" +mainClassName = "com.simiyutin.au.shell.core.Main" sourceCompatibility = 1.8 diff --git a/shell/src/main/java/commands/Cat.java b/shell/src/main/java/com/simiyutin/au/shell/commands/Cat.java similarity index 84% rename from shell/src/main/java/commands/Cat.java rename to shell/src/main/java/com/simiyutin/au/shell/commands/Cat.java index 3bb7021..6198516 100644 --- a/shell/src/main/java/commands/Cat.java +++ b/shell/src/main/java/com/simiyutin/au/shell/commands/Cat.java @@ -1,9 +1,9 @@ -package commands; +package com.simiyutin.au.shell.commands; -import exceptions.CommandExecutionException; -import shell.Command; -import shell.Environment; -import shell.Stream; +import com.simiyutin.au.shell.core.exceptions.CommandExecutionException; +import com.simiyutin.au.shell.core.Command; +import com.simiyutin.au.shell.core.Environment; +import com.simiyutin.au.shell.core.Stream; import java.io.IOException; import java.nio.charset.MalformedInputException; diff --git a/shell/src/main/java/commands/Echo.java b/shell/src/main/java/com/simiyutin/au/shell/commands/Echo.java similarity index 68% rename from shell/src/main/java/commands/Echo.java rename to shell/src/main/java/com/simiyutin/au/shell/commands/Echo.java index 1ff5827..80487d5 100644 --- a/shell/src/main/java/commands/Echo.java +++ b/shell/src/main/java/com/simiyutin/au/shell/commands/Echo.java @@ -1,9 +1,9 @@ -package commands; +package com.simiyutin.au.shell.commands; -import exceptions.CommandExecutionException; -import shell.Command; -import shell.Environment; -import shell.Stream; +import com.simiyutin.au.shell.core.exceptions.CommandExecutionException; +import com.simiyutin.au.shell.core.Command; +import com.simiyutin.au.shell.core.Environment; +import com.simiyutin.au.shell.core.Stream; import java.util.List; import java.util.stream.Collectors; diff --git a/shell/src/main/java/commands/Eq.java b/shell/src/main/java/com/simiyutin/au/shell/commands/Eq.java similarity index 63% rename from shell/src/main/java/commands/Eq.java rename to shell/src/main/java/com/simiyutin/au/shell/commands/Eq.java index c2d3127..e088b7d 100644 --- a/shell/src/main/java/commands/Eq.java +++ b/shell/src/main/java/com/simiyutin/au/shell/commands/Eq.java @@ -1,9 +1,9 @@ -package commands; +package com.simiyutin.au.shell.commands; -import exceptions.CommandExecutionException; -import shell.Command; -import shell.Environment; -import shell.Stream; +import com.simiyutin.au.shell.core.exceptions.CommandExecutionException; +import com.simiyutin.au.shell.core.Command; +import com.simiyutin.au.shell.core.Environment; +import com.simiyutin.au.shell.core.Stream; import java.util.List; diff --git a/shell/src/main/java/commands/Exit.java b/shell/src/main/java/com/simiyutin/au/shell/commands/Exit.java similarity index 59% rename from shell/src/main/java/commands/Exit.java rename to shell/src/main/java/com/simiyutin/au/shell/commands/Exit.java index 0123e00..8a9d4e9 100644 --- a/shell/src/main/java/commands/Exit.java +++ b/shell/src/main/java/com/simiyutin/au/shell/commands/Exit.java @@ -1,9 +1,9 @@ -package commands; +package com.simiyutin.au.shell.commands; -import exceptions.CommandExecutionException; -import shell.Command; -import shell.Environment; -import shell.Stream; +import com.simiyutin.au.shell.core.exceptions.CommandExecutionException; +import com.simiyutin.au.shell.core.Command; +import com.simiyutin.au.shell.core.Environment; +import com.simiyutin.au.shell.core.Stream; import java.util.List; diff --git a/shell/src/main/java/commands/OutSource.java b/shell/src/main/java/com/simiyutin/au/shell/commands/OutSource.java similarity index 87% rename from shell/src/main/java/commands/OutSource.java rename to shell/src/main/java/com/simiyutin/au/shell/commands/OutSource.java index 6e30db1..2e369ef 100644 --- a/shell/src/main/java/commands/OutSource.java +++ b/shell/src/main/java/com/simiyutin/au/shell/commands/OutSource.java @@ -1,9 +1,9 @@ -package commands; +package com.simiyutin.au.shell.commands; -import exceptions.CommandExecutionException; -import shell.Command; -import shell.Environment; -import shell.Stream; +import com.simiyutin.au.shell.core.exceptions.CommandExecutionException; +import com.simiyutin.au.shell.core.Command; +import com.simiyutin.au.shell.core.Environment; +import com.simiyutin.au.shell.core.Stream; import java.io.*; import java.util.List; diff --git a/shell/src/main/java/commands/Pwd.java b/shell/src/main/java/com/simiyutin/au/shell/commands/Pwd.java similarity index 70% rename from shell/src/main/java/commands/Pwd.java rename to shell/src/main/java/com/simiyutin/au/shell/commands/Pwd.java index 6f940ad..d802de4 100644 --- a/shell/src/main/java/commands/Pwd.java +++ b/shell/src/main/java/com/simiyutin/au/shell/commands/Pwd.java @@ -1,9 +1,9 @@ -package commands; +package com.simiyutin.au.shell.commands; -import exceptions.CommandExecutionException; -import shell.Command; -import shell.Environment; -import shell.Stream; +import com.simiyutin.au.shell.core.exceptions.CommandExecutionException; +import com.simiyutin.au.shell.core.Command; +import com.simiyutin.au.shell.core.Environment; +import com.simiyutin.au.shell.core.Stream; import java.nio.file.Path; import java.nio.file.Paths; diff --git a/shell/src/main/java/commands/Wc.java b/shell/src/main/java/com/simiyutin/au/shell/commands/Wc.java similarity index 90% rename from shell/src/main/java/commands/Wc.java rename to shell/src/main/java/com/simiyutin/au/shell/commands/Wc.java index ba545a8..f2e9222 100644 --- a/shell/src/main/java/commands/Wc.java +++ b/shell/src/main/java/com/simiyutin/au/shell/commands/Wc.java @@ -1,9 +1,9 @@ -package commands; +package com.simiyutin.au.shell.commands; -import exceptions.CommandExecutionException; -import shell.Command; -import shell.Environment; -import shell.Stream; +import com.simiyutin.au.shell.core.exceptions.CommandExecutionException; +import com.simiyutin.au.shell.core.Command; +import com.simiyutin.au.shell.core.Environment; +import com.simiyutin.au.shell.core.Stream; import java.io.IOException; import java.nio.file.Files; diff --git a/shell/src/main/java/shell/Command.java b/shell/src/main/java/com/simiyutin/au/shell/core/Command.java similarity index 88% rename from shell/src/main/java/shell/Command.java rename to shell/src/main/java/com/simiyutin/au/shell/core/Command.java index 983fc2e..76190ac 100644 --- a/shell/src/main/java/shell/Command.java +++ b/shell/src/main/java/com/simiyutin/au/shell/core/Command.java @@ -1,6 +1,6 @@ -package shell; +package com.simiyutin.au.shell.core; -import exceptions.CommandExecutionException; +import com.simiyutin.au.shell.core.exceptions.CommandExecutionException; import java.util.List; diff --git a/shell/src/main/java/shell/CommandExecutor.java b/shell/src/main/java/com/simiyutin/au/shell/core/CommandExecutor.java similarity index 88% rename from shell/src/main/java/shell/CommandExecutor.java rename to shell/src/main/java/com/simiyutin/au/shell/core/CommandExecutor.java index ed14ae6..d6d7d73 100644 --- a/shell/src/main/java/shell/CommandExecutor.java +++ b/shell/src/main/java/com/simiyutin/au/shell/core/CommandExecutor.java @@ -1,6 +1,6 @@ -package shell; +package com.simiyutin.au.shell.core; -import exceptions.CommandExecutionException; +import com.simiyutin.au.shell.core.exceptions.CommandExecutionException; import java.util.List; diff --git a/shell/src/main/java/shell/CommandFactory.java b/shell/src/main/java/com/simiyutin/au/shell/core/CommandFactory.java similarity index 95% rename from shell/src/main/java/shell/CommandFactory.java rename to shell/src/main/java/com/simiyutin/au/shell/core/CommandFactory.java index 553b6dc..0f70efa 100644 --- a/shell/src/main/java/shell/CommandFactory.java +++ b/shell/src/main/java/com/simiyutin/au/shell/core/CommandFactory.java @@ -1,9 +1,8 @@ -package shell; +package com.simiyutin.au.shell.core; -import commands.*; +import com.simiyutin.au.shell.commands.*; import java.util.List; -import java.util.stream.Collectors; /** diff --git a/shell/src/main/java/shell/Environment.java b/shell/src/main/java/com/simiyutin/au/shell/core/Environment.java similarity index 96% rename from shell/src/main/java/shell/Environment.java rename to shell/src/main/java/com/simiyutin/au/shell/core/Environment.java index 7562aa4..37dcc9c 100644 --- a/shell/src/main/java/shell/Environment.java +++ b/shell/src/main/java/com/simiyutin/au/shell/core/Environment.java @@ -1,4 +1,4 @@ -package shell; +package com.simiyutin.au.shell.core; import java.util.HashMap; import java.util.Map; diff --git a/shell/src/main/java/shell/Main.java b/shell/src/main/java/com/simiyutin/au/shell/core/Main.java similarity index 77% rename from shell/src/main/java/shell/Main.java rename to shell/src/main/java/com/simiyutin/au/shell/core/Main.java index 56e8108..b22e91e 100644 --- a/shell/src/main/java/shell/Main.java +++ b/shell/src/main/java/com/simiyutin/au/shell/core/Main.java @@ -1,4 +1,4 @@ -package shell; +package com.simiyutin.au.shell.core; public class Main { public static void main(String[] args) { diff --git a/shell/src/main/java/shell/Parser.java b/shell/src/main/java/com/simiyutin/au/shell/core/Parser.java similarity index 97% rename from shell/src/main/java/shell/Parser.java rename to shell/src/main/java/com/simiyutin/au/shell/core/Parser.java index 57ad608..1adc5ef 100644 --- a/shell/src/main/java/shell/Parser.java +++ b/shell/src/main/java/com/simiyutin/au/shell/core/Parser.java @@ -1,6 +1,6 @@ -package shell; +package com.simiyutin.au.shell.core; -import exceptions.ParserException; +import com.simiyutin.au.shell.core.exceptions.ParserException; import java.util.ArrayDeque; import java.util.ArrayList; diff --git a/shell/src/main/java/shell/Preprocessor.java b/shell/src/main/java/com/simiyutin/au/shell/core/Preprocessor.java similarity index 98% rename from shell/src/main/java/shell/Preprocessor.java rename to shell/src/main/java/com/simiyutin/au/shell/core/Preprocessor.java index e19b9c8..154e4d1 100644 --- a/shell/src/main/java/shell/Preprocessor.java +++ b/shell/src/main/java/com/simiyutin/au/shell/core/Preprocessor.java @@ -1,4 +1,4 @@ -package shell; +package com.simiyutin.au.shell.core; /** * Takes care of substitution variable values in requested places diff --git a/shell/src/main/java/shell/Shell.java b/shell/src/main/java/com/simiyutin/au/shell/core/Shell.java similarity index 95% rename from shell/src/main/java/shell/Shell.java rename to shell/src/main/java/com/simiyutin/au/shell/core/Shell.java index ef681d2..dab43d4 100644 --- a/shell/src/main/java/shell/Shell.java +++ b/shell/src/main/java/com/simiyutin/au/shell/core/Shell.java @@ -1,4 +1,4 @@ -package shell; +package com.simiyutin.au.shell.core; import java.util.List; import java.util.Scanner; diff --git a/shell/src/main/java/shell/Stream.java b/shell/src/main/java/com/simiyutin/au/shell/core/Stream.java similarity index 97% rename from shell/src/main/java/shell/Stream.java rename to shell/src/main/java/com/simiyutin/au/shell/core/Stream.java index 5a6a3f4..2873004 100644 --- a/shell/src/main/java/shell/Stream.java +++ b/shell/src/main/java/com/simiyutin/au/shell/core/Stream.java @@ -1,4 +1,4 @@ -package shell; +package com.simiyutin.au.shell.core; import java.util.ArrayDeque; import java.util.Queue; diff --git a/shell/src/main/java/shell/Token.java b/shell/src/main/java/com/simiyutin/au/shell/core/Token.java similarity index 99% rename from shell/src/main/java/shell/Token.java rename to shell/src/main/java/com/simiyutin/au/shell/core/Token.java index 1ddd76f..70defcd 100644 --- a/shell/src/main/java/shell/Token.java +++ b/shell/src/main/java/com/simiyutin/au/shell/core/Token.java @@ -1,4 +1,4 @@ -package shell; +package com.simiyutin.au.shell.core; import java.util.ArrayList; diff --git a/shell/src/main/java/shell/Tokenizer.java b/shell/src/main/java/com/simiyutin/au/shell/core/Tokenizer.java similarity index 98% rename from shell/src/main/java/shell/Tokenizer.java rename to shell/src/main/java/com/simiyutin/au/shell/core/Tokenizer.java index 00f158c..d902e0f 100644 --- a/shell/src/main/java/shell/Tokenizer.java +++ b/shell/src/main/java/com/simiyutin/au/shell/core/Tokenizer.java @@ -1,4 +1,4 @@ -package shell; +package com.simiyutin.au.shell.core; import java.util.ArrayList; import java.util.List; diff --git a/shell/src/main/java/exceptions/CommandExecutionException.java b/shell/src/main/java/com/simiyutin/au/shell/core/exceptions/CommandExecutionException.java similarity index 82% rename from shell/src/main/java/exceptions/CommandExecutionException.java rename to shell/src/main/java/com/simiyutin/au/shell/core/exceptions/CommandExecutionException.java index fc1e1e7..b34eda5 100644 --- a/shell/src/main/java/exceptions/CommandExecutionException.java +++ b/shell/src/main/java/com/simiyutin/au/shell/core/exceptions/CommandExecutionException.java @@ -1,4 +1,4 @@ -package exceptions; +package com.simiyutin.au.shell.core.exceptions; /** * This is used when errors while commands execution encountered diff --git a/shell/src/main/java/exceptions/ParserException.java b/shell/src/main/java/com/simiyutin/au/shell/core/exceptions/ParserException.java similarity index 79% rename from shell/src/main/java/exceptions/ParserException.java rename to shell/src/main/java/com/simiyutin/au/shell/core/exceptions/ParserException.java index 8905ef8..c7d68a1 100644 --- a/shell/src/main/java/exceptions/ParserException.java +++ b/shell/src/main/java/com/simiyutin/au/shell/core/exceptions/ParserException.java @@ -1,4 +1,4 @@ -package exceptions; +package com.simiyutin.au.shell.core.exceptions; /** diff --git a/shell/src/main/java/exceptions/ShellException.java b/shell/src/main/java/com/simiyutin/au/shell/core/exceptions/ShellException.java similarity index 84% rename from shell/src/main/java/exceptions/ShellException.java rename to shell/src/main/java/com/simiyutin/au/shell/core/exceptions/ShellException.java index ccf8203..77003e3 100644 --- a/shell/src/main/java/exceptions/ShellException.java +++ b/shell/src/main/java/com/simiyutin/au/shell/core/exceptions/ShellException.java @@ -1,4 +1,4 @@ -package exceptions; +package com.simiyutin.au.shell.core.exceptions; /** diff --git a/shell/src/test/java/ParserTests.java b/shell/src/test/java/com/simiyutin/au/shell/ParserTests.java similarity index 97% rename from shell/src/test/java/ParserTests.java rename to shell/src/test/java/com/simiyutin/au/shell/ParserTests.java index 5ebf524..4429e8e 100644 --- a/shell/src/test/java/ParserTests.java +++ b/shell/src/test/java/com/simiyutin/au/shell/ParserTests.java @@ -1,6 +1,7 @@ -import exceptions.CommandExecutionException; +package com.simiyutin.au.shell; + import org.junit.Test; -import shell.*; +import com.simiyutin.au.shell.core.*; import java.util.List; diff --git a/shell/src/test/java/PreprocessorTests.java b/shell/src/test/java/com/simiyutin/au/shell/PreprocessorTests.java similarity index 92% rename from shell/src/test/java/PreprocessorTests.java rename to shell/src/test/java/com/simiyutin/au/shell/PreprocessorTests.java index 3ee580c..38a3f52 100644 --- a/shell/src/test/java/PreprocessorTests.java +++ b/shell/src/test/java/com/simiyutin/au/shell/PreprocessorTests.java @@ -1,6 +1,8 @@ +package com.simiyutin.au.shell; + import org.junit.Test; -import shell.Environment; -import shell.Preprocessor; +import com.simiyutin.au.shell.core.Environment; +import com.simiyutin.au.shell.core.Preprocessor; import static org.junit.Assert.assertEquals; diff --git a/shell/src/test/java/TokenizerTests.java b/shell/src/test/java/com/simiyutin/au/shell/TokenizerTests.java similarity index 93% rename from shell/src/test/java/TokenizerTests.java rename to shell/src/test/java/com/simiyutin/au/shell/TokenizerTests.java index 34d6d22..f524f10 100644 --- a/shell/src/test/java/TokenizerTests.java +++ b/shell/src/test/java/com/simiyutin/au/shell/TokenizerTests.java @@ -1,6 +1,8 @@ +package com.simiyutin.au.shell; + import org.junit.Test; -import shell.Token; -import shell.Tokenizer; +import com.simiyutin.au.shell.core.Token; +import com.simiyutin.au.shell.core.Tokenizer; import java.util.ArrayList; import java.util.List; From 954103907c9d04cc331c6887096a2d5017aa5ce4 Mon Sep 17 00:00:00 2001 From: simiyutin Date: Sat, 11 Mar 2017 23:20:15 +0300 Subject: [PATCH 10/10] .gradle folder removed --- .../.gradle/2.10/taskArtifacts/cache.properties | 1 - .../2.10/taskArtifacts/cache.properties.lock | Bin 55 -> 0 bytes shell/.gradle/2.10/taskArtifacts/fileHashes.bin | Bin 22739 -> 0 bytes .../2.10/taskArtifacts/fileSnapshots.bin | Bin 47470 -> 0 bytes .../2.10/taskArtifacts/outputFileStates.bin | Bin 18722 -> 0 bytes .../2.10/taskArtifacts/taskArtifacts.bin | Bin 31965 -> 0 bytes .../.gradle/3.1/taskArtifacts/cache.properties | 1 - .../3.1/taskArtifacts/cache.properties.lock | Bin 17 -> 0 bytes shell/.gradle/3.1/taskArtifacts/fileHashes.bin | Bin 18697 -> 0 bytes .../.gradle/3.1/taskArtifacts/fileSnapshots.bin | Bin 19105 -> 0 bytes .../.gradle/3.1/taskArtifacts/taskArtifacts.bin | Bin 19472 -> 0 bytes 11 files changed, 2 deletions(-) delete mode 100644 shell/.gradle/2.10/taskArtifacts/cache.properties delete mode 100644 shell/.gradle/2.10/taskArtifacts/cache.properties.lock delete mode 100644 shell/.gradle/2.10/taskArtifacts/fileHashes.bin delete mode 100644 shell/.gradle/2.10/taskArtifacts/fileSnapshots.bin delete mode 100644 shell/.gradle/2.10/taskArtifacts/outputFileStates.bin delete mode 100644 shell/.gradle/2.10/taskArtifacts/taskArtifacts.bin delete mode 100644 shell/.gradle/3.1/taskArtifacts/cache.properties delete mode 100644 shell/.gradle/3.1/taskArtifacts/cache.properties.lock delete mode 100644 shell/.gradle/3.1/taskArtifacts/fileHashes.bin delete mode 100644 shell/.gradle/3.1/taskArtifacts/fileSnapshots.bin delete mode 100644 shell/.gradle/3.1/taskArtifacts/taskArtifacts.bin diff --git a/shell/.gradle/2.10/taskArtifacts/cache.properties b/shell/.gradle/2.10/taskArtifacts/cache.properties deleted file mode 100644 index 34e0db3..0000000 --- a/shell/.gradle/2.10/taskArtifacts/cache.properties +++ /dev/null @@ -1 +0,0 @@ -#Sat Mar 04 19:36:05 MSK 2017 diff --git a/shell/.gradle/2.10/taskArtifacts/cache.properties.lock b/shell/.gradle/2.10/taskArtifacts/cache.properties.lock deleted file mode 100644 index 9b611430cdcf69ab3bef76113d5390143f06dff1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 55 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 diff --git a/shell/.gradle/2.10/taskArtifacts/fileSnapshots.bin b/shell/.gradle/2.10/taskArtifacts/fileSnapshots.bin deleted file mode 100644 index c057143ed6e8db321cbe969015a9dd1bca8f26e1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 47470 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 diff --git a/shell/.gradle/2.10/taskArtifacts/outputFileStates.bin b/shell/.gradle/2.10/taskArtifacts/outputFileStates.bin deleted file mode 100644 index 9cea602cf49e1fa2c867ea47e097566963a38fb8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 18722 zcmeI(yGz4R6vy$46cp(D?ouPUcZlRK(C>xI;rtE>oX;9!%?e>?b$NvM=-!qN z0R#|0009ILKmY**5I_I{1Q0*~0R#|0009L4f`GN`Y|-p)VvIDXl{9Nth`|=8Z8U|w zIbK^Ca7WQC^(Eor{X8BIYWp&`Rc=p*Gxglmw#*+@{`orbkW3ez^+5I_I{1Q0*~0R#|0009IL zKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0;9m+@5oc}9xlKPeu&|dK zN*|3$3f()so9XB(joxnfPe1hMrNdIW*MFLPiLSn7i|UtzUvEB$)YjU~<0t=TZ~8-% Tt%=h!|7kFlS&vojvugSc+xL({ diff --git a/shell/.gradle/2.10/taskArtifacts/taskArtifacts.bin b/shell/.gradle/2.10/taskArtifacts/taskArtifacts.bin deleted file mode 100644 index 1318f3477d5fa7e82a326890e5dc812c139d9a73..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 31965 zcmeI4du$X%7{KT5T3)SKGzvyU(3tSL-HL!Didy@y&`M7z_!j1Fr`K)wc9+@N_KL<= zv{g_{E#+BKA`dm;4+;1J@j;0EK?Owxl~k)35wU3eLyV8$%owYJ#CP>uO6neKM( zb{@a)`)0oRX71Vw5E_+pChf00e*l5C8%|00;m9AOHk_01yBI|6u}c^LgWjxeXjO z-S4$Dr>z#D+-&}DX8ppGLpv%;*12yLhrFGHEz37dp4R!(Q8)j-VlUsn=-5wd8Zt87 z{Kda``T3ugl(oEh;`T&2Z+iKm&{{2P>9O5zK56puy{ns#mL{%n0Rlh(2mk>f00e*l z5C8%|00;m9AOHk_01yBIKmZ5;0U!VbfB+Bx0zd!=00AHX1b_e#00KY&2mk>f00e*l z5C8%|00;m9AOHmVK%ng!{-H%Y-64|i*_&DpKfgCJX7dXtfA9QoNKWOXOK8nUo$v27 zXjF<)tY}2SrYbRPRa=sx;;3#|OpRDlInS9(OoK9Ux3GXj42l_1c(KV>g{UpC5h33Q zk^H->w@+Gm;L8zD9U5Aab$I%4d0K0GVaFA>ZSAqPu&pbasz;^Sn06`O_m*5~#E2X= zsA|dBUN}Xz6uGiiwknCH$zfa76j@WlmYWg0TFMR1o0AusS6o&uRbh%|9$a(F*8S^W z{^9lUP5XZ9nE!dr=%`(;Rt$7ITu{Et-y2IG{w)7yAe+BG|W}tX2Z}3)_VrEf?*mZOq7V3 z8df!x)wxXwTrJILPBzW0k^VD&>%8K+@Js9VgtK#_?bsisK{CUHh|i(6NLN*#4IS9p(9U{x#A3n?{dKlKm{77VtBSu>It@y?mS4$9@f z_cvZ7pS5In{<|%&9GE!dmswLL?{9tR+AB|=>VlM5w#FH7IcDCMVIlolVd6Q<6V*#;112Zjg}QQ>>Z+)nk^qS?BCK)y}Z5AR_NG2a!&eYU* zKL912h%}XuyNSznWIauAs+JrfmAMYqstQ%(N+YRyM6(qV!c3@851@*%Rmnl^EO@+m zP6r1_!ULhCV zNJpz3%_>#(YN8~teWD$?tGRvR82**zxaa6OpXwE>FNyW(gox6lT-;5{y%>Jt!8H5l z#>VBFvdc!-M)EiWE-~(W_tOP*zWmzjamI>PC%&$jvIQoeO zO?OsjC}BPRrZ}~M`!@N z(HK^B@J6}%!1586k31yNb>27U?r(gzacbUk`$mr4Tlhuhl*bz~7w7Ky_$#nX2<#*R zR}k1qMaBj^uroNn+f;hyMAng!r`ryV)}zl~>R-BP!Q!_A!>_%vegF(s_}(y;!c?je zh{THMez&OH05C!W#Q*>R diff --git a/shell/.gradle/3.1/taskArtifacts/fileHashes.bin b/shell/.gradle/3.1/taskArtifacts/fileHashes.bin deleted file mode 100644 index 6d05f69772ff4a8c75a80dbb3321adabcbca537c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 18697 zcmeI%K_~=K9LMoTij3?WY;AiJ2U}=L(zQwrexDPY?=13wwxqH z9LSY&*{g%Fw{cU7a-cS=c+<>loA&6Y@2fZO-*5Ugz0Y+2gkU`^!&j z*TKf^O?~5G@#JxD`1|v2B3!&Q-v@&Y@m$|XX>T#7xv*W%Si8pNs~&80q}|3Z-@bSP diff --git a/shell/.gradle/3.1/taskArtifacts/fileSnapshots.bin b/shell/.gradle/3.1/taskArtifacts/fileSnapshots.bin deleted file mode 100644 index 6963709d7a7d660037646f6d361235df84f1382a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 19105 zcmeI(JxJVO9LMqG9%{j>Hj8k$Iti^2r9v$f1P9+hI+VkulJlbHadJoQY(P4RAR@ki zs8HG>Rt2#LMH~dB6w%G4pl%9Iz7<>qp)K}#NP=s?PURc;U!MH)@I1eKZVYMEw3u=0 zAKKkfb~j{%00IagfB*srAbb~0J#^_v=ke)EUxjh7{H-S2M({a4AGtJCw3 z?OwmRE9l3IruXKiUVQi09}D`yS@uV~d;B7R00IagfB*srAb`cb&ajayLrL63x=D~yTJuce*CGab=|^1`pdH#_Q60#|MQ zN!E-ip??dpwdp!mE@wM_lBfPbnouS5#Sp1o m87kB~VYtzsl}8V!#}5bJzONp-G}M+^wPjS6P!&-v&G-w_&mjW< diff --git a/shell/.gradle/3.1/taskArtifacts/taskArtifacts.bin b/shell/.gradle/3.1/taskArtifacts/taskArtifacts.bin deleted file mode 100644 index 395bf7c20f0a96c92fd3a412c05fdcd9173ea066..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 19472 zcmeI%O=uHA7zW@;QxT-qAQU2kUZhxPcB@4X+DmIztEiR4sNf+?He+_`HoMGBvetkn z1;O}t)Pvwbv0(8oqEN6Pda6YbJX;TXP!Aq;*3FXiP|Qt{cVTyD=lA=bnVga(B%S)% zx=8yPXctj}00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafK;VB7DCk5sM9HLwd&0t| zfRK?sT}X`BThH|LKfD(;Pmag`AH;86KNPj$2>}Q|00Izz00bZa0SG_<0uX=z1Rwwb z2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX?}zaTJ5NODo%&%-;> zim10)qRMviw&1>M?0j?X-Pf1fu1-^Nkh^T@{osl*pW1)Z7oN|A;!K9spMw0A=A)sH z*W~X}Vb#FGe14FM-1nl@xc_Q-_=zVfMn%xF%M9vsLs5BN8iAm`p2s*Hy^C39dx9!f zPNbe*Z~Vxv^xZkKyzn_#+It|8nwuJXdv<&JS>`VLHv3`AWgT$uV#0L18D^F|!KF!S z#oeYXn@(U#hqZP1IvagOQipQm*`rpm zkhgNh$*E)3t@G`f=)ex=KCU;T8_=%<@kJ$%(_qn^f2iud}~n9