001package org.unix4j.unix.sed;
002
003import org.unix4j.processor.LineProcessor;
004import org.unix4j.util.StringUtil;
005
006abstract class AbstractTextProcessor extends AbstractRegexpProcessor {
007        
008        protected final String text;
009
010        public AbstractTextProcessor(Command command, SedArguments args, LineProcessor output) {
011                super(command, args, output);
012                this.text = args.getString2();
013        }
014        
015        public AbstractTextProcessor(Command command, String script, SedArguments args, LineProcessor output) {
016                this(command, deriveArgs(command, script, args), output);
017        }
018
019        private static SedArguments deriveArgs(Command command, String script, SedArguments args) {
020                final int start = StringUtil.findStartTrimWhitespace(script);
021                final int end = indexOfNextDelimiter(script, start);
022                if (end < 0) {
023                        throw new IllegalArgumentException("invalid script for sed " + command + " command: " + script);
024                }
025                args = parsePatternFlags(command, args, script, end + 1);
026                args.setString1(script.substring(start + 1, end));
027                final int commandStart = findCommand(command, script, end + 1);
028                final int backslashStart = findBackslash(command, script, commandStart + 1);
029                final int textStart = StringUtil.findStartTrimNewlineChars(script, backslashStart + 1);
030                final int textEnd = StringUtil.findEndTrimNewlineChars(script);
031                args.setString2(script.substring(textStart, textEnd));
032                return args;
033        }
034
035        private static int findCommand(Command command, String script, int start) {
036                final char cmd = command.commandChar;
037                final int len = script.length();
038                boolean isPatternFlags = true;
039                for (int i = start; i < len; i++) {
040                        final char ch = script.charAt(i);
041                        if (cmd == ch) {
042                                return i;
043                        }
044                        if (Character.isWhitespace(ch)) {
045                                isPatternFlags = false;
046                        } else {
047                                if (!isPatternFlags) {
048                                        //should not get there as the script syntax has been checked before
049                                        throw new IllegalArgumentException("illegal character '" + ch + "' found instead of command character '" + cmd + "' in sed script: " + script);
050                                }
051                        }
052                }
053                //should not get there as the script syntax has been checked before
054                throw new IllegalArgumentException("command character '" + cmd + "' expected in sed script: " + script);
055        }
056        
057        private static int findBackslash(Command command, String script, int start) {
058                final int index = StringUtil.findStartTrimWhitespace(script, start);
059                if (index < script.length()) {
060                        final int ch = script.charAt(index); 
061                        if (ch == '\\') {
062                                return index;
063                        }
064                        throw new IllegalArgumentException("illegal character '" + ch + "' found instead of backslash character '\\' in sed script: " + script);
065                }
066                throw new IllegalArgumentException("backslash character '\\' expected in sed script: " + script);
067        }
068
069}