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