FileDocCategorySizeDatePackage
Grep2.javaAPI DocExample4222Thu Mar 25 20:49:22 GMT 2004None

Grep2.java

import java.io.*;
import java.util.*;
import java.util.regex.*;

import com.darwinsys.lang.GetOpt;

/** A command-line grep-like program. Accepts some command-line options,
 * and takes a pattern and a list of text files.
 */
public class Grep2 {
	/** The pattern we're looking for */
	protected Pattern pattern;
	/** The matcher for this pattern */
	protected Matcher matcher;
	/** The Reader for the current file */
    protected BufferedReader d;
	/** Are we to only count lines, instead of printing? */
	protected boolean countOnly = false;
	/** Are we to ignore case? */
	protected boolean ignoreCase = false;
	/** Are we to suppress printing of filenames? */
	protected boolean dontPrintFileName = false;
	/** Are we to only list names of files that match? */
	protected boolean listOnly = false;
	/** are we to print line numbers? */
	protected boolean numbered = false;
	/** Are we to be silent about errors? */
	protected boolean silent = false;
	/** are we to print only lines that DONT match? */
	protected boolean inVert = false;

	/** Construct a Grep2 object for each pattern, and run it
	 * on all input files listed in argv.
	 * Be aware that a few of the command-line options are not
	 * acted upon in this version - this is an exercise for the reader!
	 */
	public static void main(String[] argv) {

		if (argv.length < 1) {
		    System.err.println(
			"Usage: Grep2 pattern [-chilsnv][-f pattfile][filename...]");
		    System.exit(1);
		}
		String patt = null;

		GetOpt go = new GetOpt("cf:hilnsv");
		BitSet args = new BitSet();

		char c;
		while ((c = go.getopt(argv)) != 0) {
			switch(c) {
				case 'c':
					args.set('C');
					break;
				case 'f':
					try {
						BufferedReader b = new BufferedReader(new FileReader(go.optarg()));
						patt = b.readLine();
						b.close();
					} catch (IOException e) {
						System.err.println("Can't read pattern file " + go.optarg());
						System.exit(1);
					}
					break;
				case 'h':
					args.set('H');
					break;
				case 'i':
					args.set('I');
					break;
				case 'l':
					args.set('L');
					break;
				case 'n':
					args.set('N');
					break;
				case 's':
					args.set('S');
					break;
				case 'v':
					args.set('V');
					break;
			}
		}

		int ix = go.getOptInd();

		if (patt == null)
			patt = argv[ix];

		Grep2 pg = null;
		try {
			pg = new Grep2(patt, args);
		} catch (PatternSyntaxException ex) {
			System.err.println("RE Syntax error in " + patt);
			return;
		}

		if (argv.length == ix)
			pg.process(new InputStreamReader(System.in), "(standard input)");
		else
			for (int i=ix; i<argv.length; i++) {
				try {
					pg.process(new FileReader(argv[i]), argv[i]);
				} catch(Exception e) {
					System.err.println(e);
				}
			}
	}

	/** Construct a Grep2 object.
	 * @param patt The pattern to look for
	 * @param args the command-line options.
	 */
	public Grep2(String patt, BitSet args) throws PatternSyntaxException {
		// compile the regular expression
		if (args.get('C'))
			countOnly = true;
		if (args.get('H'))
			dontPrintFileName = true;
		if (args.get('I'))
			ignoreCase = true;
		if (args.get('L'))
			listOnly = true;
		if (args.get('N'))
			numbered = true;
		if (args.get('S'))
			silent = true;
		if (args.get('V'))
			inVert = true;
		int caseMode = ignoreCase ?
			Pattern.UNICODE_CASE | Pattern.CASE_INSENSITIVE :
			0;
		pattern = Pattern.compile(patt, caseMode);
		matcher = pattern.matcher("");
	}
        
	/** Do the work of scanning one file
	 * @param	ifile	Reader	Reader object already open
	 * @param	fileName String	Name of the input file
	 */
	public void process(Reader ifile, String fileName) {

		String inputLine;
		int matches = 0;

		try {
			d = new BufferedReader(ifile);
		    
			while ((inputLine = d.readLine()) != null) {
				matcher.reset(inputLine);
				if (matcher.lookingAt()) {
					if (countOnly)
						matches++;
					else {
					if (!dontPrintFileName)
						System.out.print(fileName + ": ");
					System.out.println(inputLine);
					}
				} else if (inVert) {
					System.out.println(inputLine);
				}
			}
			if (countOnly)
				System.out.println(matches + " matches in " + fileName);
			d.close();
		} catch (IOException e) { System.err.println(e); }
	}
}