001package org.unix4j.unix.sed;
002
003import java.util.Collections;
004import java.util.EnumSet;
005import java.util.Iterator;
006
007import org.unix4j.option.Option;
008import org.unix4j.unix.Sed;
009
010/**
011 * Options for the {@link Sed sed} command.
012 * <p>
013 * For most applications, it may be more convenient to use {@link Sed#Options} 
014 * instead of the option constants defined here.
015 * <p>
016 * <table>
017 * <tr valign="top"><td width="10px"></td><td nowrap="nowrap">{@code -n}</td><td>&nbsp;&nbsp;</td><td nowrap="nowrap">{@code --quiet}</td><td>&nbsp;</td><td>Suppress the default output (in which each line, after it is 
018                        examined for editing, is written to standard output). Only lines 
019                        explicitly selected for output are written.</td></tr>
020 * <tr valign="top"><td width="10px"></td><td nowrap="nowrap">{@code -g}</td><td>&nbsp;&nbsp;</td><td nowrap="nowrap">{@code --global}</td><td>&nbsp;</td><td>Globally substitute for all non-overlapping instances of the regexp 
021                        rather than just the first one. 
022                        <p>
023                        (This option is ignored if the occurrence operand is specified).</td></tr>
024 * <tr valign="top"><td width="10px"></td><td nowrap="nowrap">{@code -p}</td><td>&nbsp;&nbsp;</td><td nowrap="nowrap">{@code --print}</td><td>&nbsp;</td><td>Write the matched line to standard output.</td></tr>
025 * <tr valign="top"><td width="10px"></td><td nowrap="nowrap">{@code -l}</td><td>&nbsp;&nbsp;</td><td nowrap="nowrap">{@code --lineNumber}</td><td>&nbsp;</td><td>Writes the current line number on a separate line to the standard 
026                        output.</td></tr>
027 * <tr valign="top"><td width="10px"></td><td nowrap="nowrap">{@code -I}</td><td>&nbsp;&nbsp;</td><td nowrap="nowrap">{@code --ignoreCase}</td><td>&nbsp;</td><td>Use case insensitive pattern matching.</td></tr>
028 * <tr valign="top"><td width="10px"></td><td nowrap="nowrap">{@code -s}</td><td>&nbsp;&nbsp;</td><td nowrap="nowrap">{@code --substitute}</td><td>&nbsp;</td><td>Substitutes the replacement string for instances of the regexp in 
029                        the matched line.
030<p>
031                        The characters "$0" appearing in the replacement are replaced
032                        by the line matching the regexp.  The characters "$n", where n is a
033                        digit other than zero, are replaced by the text matched by the
034                        corresponding backreference expression (aka group).  The special
035                        meaning of "$n" in this context can be suppressed by preceding it
036                        by a backslash.
037<p>
038                        A line can be split by substituting a newline ('\n') into it. 
039                        <p>
040                        A substitution is considered to have been performed even if the 
041                        replacement string is identical to the string that it replaces.</td></tr>
042 * <tr valign="top"><td width="10px"></td><td nowrap="nowrap">{@code -a}</td><td>&nbsp;&nbsp;</td><td nowrap="nowrap">{@code --append}</td><td>&nbsp;</td><td>Append string2 as a separate line after the matched line.</td></tr>
043 * <tr valign="top"><td width="10px"></td><td nowrap="nowrap">{@code -i}</td><td>&nbsp;&nbsp;</td><td nowrap="nowrap">{@code --insert}</td><td>&nbsp;</td><td>Insert string2 as a separate line before the matched line.</td></tr>
044 * <tr valign="top"><td width="10px"></td><td nowrap="nowrap">{@code -c}</td><td>&nbsp;&nbsp;</td><td nowrap="nowrap">{@code --change}</td><td>&nbsp;</td><td>Write string2 as a separate line instead of the matched line.</td></tr>
045 * <tr valign="top"><td width="10px"></td><td nowrap="nowrap">{@code -d}</td><td>&nbsp;&nbsp;</td><td nowrap="nowrap">{@code --delete}</td><td>&nbsp;</td><td>Delete the matched line.</td></tr>
046 * <tr valign="top"><td width="10px"></td><td nowrap="nowrap">{@code -y}</td><td>&nbsp;&nbsp;</td><td nowrap="nowrap">{@code --translate}</td><td>&nbsp;</td><td>Replace all occurrences of characters in string1 with the 
047                        corresponding characters in string2. If the number of characters in 
048                        the two strings are not equal, or if any of the characters in 
049                        string1 appear more than once, the results are undefined.</td></tr>
050 * </table>
051 */
052public enum SedOption implements Option, SedOptions {
053        /**
054         * Option <b>{@code --quiet}</b>, <b>{@code -n}</b>: 
055         * Suppress the default output (in which each line, after it is 
056                        examined for editing, is written to standard output). Only lines 
057                        explicitly selected for output are written.
058         */
059        quiet('n'),
060        /**
061         * Option <b>{@code --global}</b>, <b>{@code -g}</b>: 
062         * Globally substitute for all non-overlapping instances of the regexp 
063                        rather than just the first one. 
064                        <p>
065                        (This option is ignored if the occurrence operand is specified).
066         */
067        global('g'),
068        /**
069         * Option <b>{@code --print}</b>, <b>{@code -p}</b>: 
070         * Write the matched line to standard output.
071         */
072        print('p'),
073        /**
074         * Option <b>{@code --lineNumber}</b>, <b>{@code -l}</b>: 
075         * Writes the current line number on a separate line to the standard 
076                        output.
077         */
078        lineNumber('l'),
079        /**
080         * Option <b>{@code --ignoreCase}</b>, <b>{@code -I}</b>: 
081         * Use case insensitive pattern matching.
082         */
083        ignoreCase('I'),
084        /**
085         * Option <b>{@code --substitute}</b>, <b>{@code -s}</b>: 
086         * Substitutes the replacement string for instances of the regexp in 
087                        the matched line.
088<p>
089                        The characters "$0" appearing in the replacement are replaced
090                        by the line matching the regexp.  The characters "$n", where n is a
091                        digit other than zero, are replaced by the text matched by the
092                        corresponding backreference expression (aka group).  The special
093                        meaning of "$n" in this context can be suppressed by preceding it
094                        by a backslash.
095<p>
096                        A line can be split by substituting a newline ('\n') into it. 
097                        <p>
098                        A substitution is considered to have been performed even if the 
099                        replacement string is identical to the string that it replaces.
100         */
101        substitute('s'),
102        /**
103         * Option <b>{@code --append}</b>, <b>{@code -a}</b>: 
104         * Append string2 as a separate line after the matched line.
105         */
106        append('a'),
107        /**
108         * Option <b>{@code --insert}</b>, <b>{@code -i}</b>: 
109         * Insert string2 as a separate line before the matched line.
110         */
111        insert('i'),
112        /**
113         * Option <b>{@code --change}</b>, <b>{@code -c}</b>: 
114         * Write string2 as a separate line instead of the matched line.
115         */
116        change('c'),
117        /**
118         * Option <b>{@code --delete}</b>, <b>{@code -d}</b>: 
119         * Delete the matched line.
120         */
121        delete('d'),
122        /**
123         * Option <b>{@code --translate}</b>, <b>{@code -y}</b>: 
124         * Replace all occurrences of characters in string1 with the 
125                        corresponding characters in string2. If the number of characters in 
126                        the two strings are not equal, or if any of the characters in 
127                        string1 appear more than once, the results are undefined.
128         */
129        translate('y');
130        
131        private final char acronym;
132        private SedOption(char acronym) {
133                this.acronym = acronym;
134        }
135        @Override
136        public Class<SedOption> optionType() {
137                return SedOption.class;
138        }
139        /**
140         * Returns the option with the given {@code acronym}, or {@code null} if no
141         * such option is found.
142         * 
143         * @param acronym the option {@link #acronym() acronym}
144         * @return      the option with the given {@code acronym} or {@code null} if it
145         *                      is not found
146         */
147        public static SedOption findByAcronym(char acronym) {
148                for (final SedOption opt : values()) {
149                        if (opt.acronym() == acronym) return opt;
150                }
151                return null;
152        }
153        @Override
154        public char acronym() {
155                return acronym;
156        }
157        @Override
158        public boolean isSet(SedOption option) {
159                return equals(option);
160        }
161        /**
162         * Returns a new set with {@code this} active option.
163         * 
164         * @return a new set containing this option
165         */
166        @Override
167        public EnumSet<SedOption> asSet() {
168                return EnumSet.of(this);
169        }
170        
171        /**
172         * Returns an immutable iterator returning o single element: {@code this} 
173         * option.
174         * 
175         * @return an immutable iterator with {@code this} active option.
176         */
177        @Override
178        public Iterator<SedOption> iterator() {
179                return Collections.singleton(this).iterator();
180        }
181        
182        /**
183         * Returns 1 as this is a set with a single element: {@code this} option
184         * 
185         * @return one
186         */
187        @Override
188        public int size() {
189                return 1;
190        }
191
192        /**
193         * Returns true if the {@link Option#acronym() acronym} should be used for
194         * the specified {@code option} in string representations. 
195         * <p>
196         * This method returns always true for all options.
197         *  
198         * @param option
199         *            the option of interest
200         * @return always true indicating that option acronyms should be used in
201         *                      string representations for all options
202         */
203        @Override
204        public boolean useAcronymFor(SedOption option) {
205                return true;
206        }
207}