/* VisAD system for interactive analysis and visualization of numerical data. Copyright (C) 1996 - 2017 Bill Hibbard, Curtis Rueden, Tom Rink, Dave Glowacki, Steve Emmerson, Tom Whittaker, Don Murray, and Tommy Jasmin. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ package visad.util; import java.util.ArrayList; /** * Parse command-line arguments passed to the initial main() method * of an application.<br> * <br> * To use this, a class would implement <tt>CmdlineConsumer</tt>, * then add the following code snippet to the constructor * (assuming the constructor is supplied a list of arguments * named <tt>'args'</tt>):<br> * <pre> * <code> * CmdlineParser cmdline = new CmdlineParser(this); * if (!cmdline.processArgs(args)) { * </code> * <i> * complain about errors, exit, etc. * </i> * <code> * } * </code> * */ public class CmdlineParser { private String mainName; private ArrayList list; /** * Create a command-line parser. * * @param mainClass The class in which the main() method lives. */ public CmdlineParser(Object mainClass) { String className = mainClass.getClass().getName(); int pt = className.lastIndexOf('.'); final int ds = className.lastIndexOf('$'); if (ds > pt) { pt = ds; } mainName = className.substring(pt == -1 ? 0 : pt + 1); list = null; if (mainClass instanceof CmdlineConsumer) { addConsumer((CmdlineConsumer )mainClass); } } /** * Add a command-line argument/keyword consumer. * * consumer Class which implements <tt>CmdlineConsumer</tt>. */ public void addConsumer(CmdlineConsumer consumer) { if (list == null) { list = new ArrayList(); } list.add(consumer); } /** * Get the name of the main class. * * @return main class name */ public String getMainClassName() { return mainName; } /** * Pass all options/keywords on to all * {@link CmdlineConsumer CmdlineConsumer}s. * * @param args Array of command-line arguments passed to main() method. */ public boolean processArgs(String[] args) { boolean usage = false; // if the are no consumers or arguments, we're done if (list == null || args == null) { return true; } // add consumers from newest to oldest CmdlineConsumer[] consumers = new CmdlineConsumer[list.size()]; for (int c = 0; c < consumers.length; c++) { consumers[c] = (CmdlineConsumer )list.get(consumers.length - (c + 1)); } for (int c = 0; c < consumers.length; c++) { consumers[c].initializeArgs(); } for (int i = 0; !usage && i < args.length; i++) { if (args[i].length() > 0 && args[i].charAt(0) == '-') { char ch = args[i].charAt(1); String str, result; boolean strInOption = false; if (args[i].length() > 2) { str = args[i].substring(2); strInOption = true; } else if ((i + 1) < args.length) { str = args[i+1]; } else { str = null; } int handled; for (int c = 0; c < consumers.length; c++) { handled = consumers[c].checkOption(mainName, ch, str); if (handled > 0) { if (handled > 1) { if (strInOption) { handled = 1; } else { handled = 2; } } i += (handled - 1); break; } else { if (handled == 0) { System.err.println(mainName + ": Unknown option \"-" + ch + "\""); } usage = true; } } } else { int handled; for (int c = 0; c < consumers.length; c++) { handled = consumers[c].checkKeyword(mainName, i, args); if (handled > 0) { i += (handled - 1); break; } else { if (handled == 0) { System.err.println(mainName + ": Unknown keyword \"" + args[i] + "\""); } usage = true; } } } } for (int c = 0; !usage && c < consumers.length; c++) { usage |= !consumers[c].finalizeArgs(mainName); } if (usage) { StringBuffer buf = new StringBuffer("Usage: " + mainName); for (int c = 0; c < consumers.length; c++) { buf.append(consumers[c].optionUsage()); } for (int c = 0; c < consumers.length; c++) { buf.append(consumers[c].keywordUsage()); } System.err.println(buf.toString()); } return !usage; } }