/*************************************************************************
 *
 *  $RCSfile: cmdparse.hxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: fs $ $Date: 2001/02/02 10:22:18 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  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
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser 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
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _SVTOOLS_CMDPARSE_HXX
#define _SVTOOLS_CMDPARSE_HXX

#ifndef _STRING_HXX
#include <tools/string.hxx>
#endif

#ifndef _LIST_HXX //autogen
#include <tools/list.hxx>
#endif

namespace svt
{

#ifndef STRING_LIST
#define STRING_LIST
DECLARE_LIST( StringList, String * )
#endif

class CommandParser
{
	// Trennzeichen fuer Optionen
	const char aDelimiterChar;
	const char aAssignChar;
	const char aQuoteChar;

	// Sollen nur Optionen (keine Parameter) geparst werden?
	// In diesem Fall werden Blanks in Optionen nicht als Ende des Optionswertes
	// angesehen und das Delimiter-Zeichen zu Beginn der ersten Option kann fehlen
	// (z. B. zum Parsen von ODBC-Connection-Strings: "DSN=sample;UID=admin;PWD=xxx")
	const BOOL bOptionsOnly;

	BOOL bAnyOptionAllowed;

	// Liste der Parameter
	StringList aParameterStringList;

	// Liste der Options-Namen und -Werte
	StringList aOptionNameList;
	StringList aOptionStringList;

	// Die beim letzten Parsen aufgetretene Fehlermeldung
	// (leer = kein Fehler)
	String aInvalidOptions;

	static const String aEmptyString;

	void AddParameter(const String & rParameterString);

  public:
	// Optional kann bei der Konstruktion bereits ein String geparsed werden.
	CommandParser(const String & rString = String(),
				  const char aNewDelimiterChar = '/',
				  const char aNewAssignChar = ':',
				  const BOOL bNewOptionsOnly = FALSE,
				  const char aNewQuoteChar = '"');
	CommandParser(const CommandParser & rCommandParser);
	~CommandParser();

	const CommandParser & operator=(const CommandParser &rCommandParser);

	BOOL operator==(const CommandParser &rCommandParser) const;
	BOOL operator!=(const CommandParser &rCommandParser) const;

	// Wert zum angegebenen Keyword ersetzen:
	// Gross-/Kleinschreibung bei Keyword wird ignoriert.
	void SetOption(const UINT32 nOptionNumber, const String & rOptionString);
	void SetOption(const String & rOptionName, const String & rOptionString);

	// Alle Parameter und Optionen loeschen:
	void Clear();

	// String parsen:
	// String-Format: "ParameterString ParameterString/optionname:OptionString /optionname:OptionString" ...
	// (hier mit dem Default-Delimiter '/' und dem Default-Assign-Zeichen ':')

	// Wenn ':' und Wert fehlen, wird als Wert "-1" (!= 0, also TRUE) eingesetzt,
	// wenn nur der Wert fehlt, ein Leerstring.
	// Parameter duerfen alle Zeichen ausser aDelimiterChar und Blank/Tab enthalten.
	// Optionsnamen sollten nur Buchstaben und ggf. Ziffern enthalten, Werte koennen
	// alle Zeichen ausser aDelimiterChar und Blank/Tab beinhalten.
	// Zwischen dem Optionsnamen, dem Zuweisungszeichen und dem Optionswert
	// duerfen keine Leerzeichen und Tabs auftreten.
	// Bei jedem Parse werden die Werte mit SetValue gesetzt, d. h. die schon vorher
	// gesetzten Werte anderer Optionsnamen bleiben erhalten. Bei jedem weiteren Parsen,
	// d. h. wenn bereits Parameter und/oder Optionen vorhanden sind, koennen nur noch
	// Optionsnamen vorkommen, die bereits im Konstruktor (ggf. mit einem Initialisierungswert)
	//  mit angegeben worden sind. Mit Clear kann wieder der Ausgangszustand hergestellt
	// werden, d. h. der naechste Parse-Vorgang erlaubt beliebige Optionen.
	void Parse(const String & rString);

	// String wird aus Kommandozeilenargumenten zusammengesetzt (Blanks zwischen argv ...)
	void Parse(int argc, char * * argv);

	// Wert zu der angegebenen Option (nach Name oder Nummer)
	// Gross-/Kleinschreibung beim Namen wird ignoriert.
	// Leerstring, falls nicht gefunden oder falls als Wert ein Leerstring gesetzt worden ist.
	// Bool: alles ausser Leerstring, "0" und "FALSE" gilt als TRUE
	const UINT32	OptionCount() const { return aOptionStringList.Count(); };
	const String &	OptionName(const UINT32 nOptionNumber) const;
	String			OptionString(const UINT32 nOptionNumber) const;
	String			OptionString(const String & rOptionName) const;
	const BOOL		OptionBool(const UINT32 nOptionNumber) const;
	const BOOL		OptionBool(const String & rOptionName) const;
	const INT32		OptionInt(const UINT32 nOptionNumber) const;
	const INT32		OptionInt(const String & rOptionName) const;
	const UINT32	OptionUInt(const UINT32 nOptionNumber) const;
	const UINT32	OptionUInt(const String & rOptionName) const;

	BOOL		   Exists(const String & rOptionName) const;

	// Parameter:
	const UINT32 ParameterCount() const { return aParameterStringList.Count(); };
	const String & ParameterString(const UINT32 nParameterNumber) const;
	const BOOL     ParameterBool(const UINT32 nParameterNumber) const;
	const INT32    ParameterInt(const UINT32 nParameterNumber) const;
	const UINT32   ParameterUInt(const UINT32 nParameterNumber) const;

	// Fehlerabfrage nach Konstruktion und nach Parse:
	const BOOL IsInvalid() const { return aInvalidOptions.Len() != 0; }
	// Die Option(en), die nicht zulaessig waren (mit Blank getrennt):
	const String & InvalidOptions() const { return aInvalidOptions; }

	// Das Gegenteil vom Parsen: alle Parameter und Optionen wieder zu einem String
	// zusammensetzen (unter Benutzung des Delimiter- und Assign-Zeichens).
	// Gegebenenfalls werden die angegebenen Optionen (nur Optionsnamen mit Delimiter
	// getrennt!) weggelassen.
	// Optionen mit dem Wert "-1" werden OHNE Wert und ohne Assign-Zeichen ausgegeben
	// (also als reine "Flags" ohne Wert)!
	void Compose(String & rString, const String & rLeaveOutOptions) const;

};

inline BOOL CommandParser::operator!=(const CommandParser &rCommandParser) const
{
	return ! (*this == rCommandParser);
}

}	// namespace svt

#endif

