// -*- mode:C++; tab-width:2; c-basic-offset:2; indent-tabs-mode:nil -*-
//
// Copyright (C) 2000-2005 by Roger Rene Kommer / artefaktur, Kassel, Germany.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public License (LGPL).
//
//
// 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
// License ACDK-FreeLicense document enclosed in the distribution
// for more for more details.
// This file is part of the Artefaktur Component Development Kit:
// ACDK
//
// Please refer to
// - http://www.acdk.de
// - http://www.artefaktur.com
// - http://acdk.sourceforge.net
// for more information.
//
// $Header: /cvsroot/acdk/acdk/acdk_core/src/acdk/lang/CmdLineParser.cpp,v 1.18 2005/02/11 10:12:00 kommer Exp $
#include <acdk/lang/CmdLineParser.h>
#include <acdk/lang/CmdLineParseException.h>
#include <acdk/io/PrintWriter.h>
#include <acdk/io/CharArrayWriter.h>
#include <acdk/util/HashMap.h>
#include <acdk/util/Properties.h>
#include <acdk/lang/System.h>
namespace acdk {
namespace lang {
CmdLineParser::CmdLineParser()
: acdk::lang::Object()
, _map(new ::acdk::util::HashMap())
{
}
void
CmdLineParser::addOption(IN(RCmdLineOption) opt)
{
_map->put((acdk::lang::Object)opt->_option, (acdk::lang::Object)opt);
if (opt->_shortOption != Nil && opt->_shortOption->length() > 0)
_map->put((acdk::lang::Object)opt->_shortOption, (acdk::lang::Object)opt);
}
void
CmdLineParser::printHelp(IN(::acdk::io::RPrintWriter) out)
{
if (_helpHeader != Nil)
out->print(_helpHeader);
acdk::util::RIterator it = _map->iterator();
while (it->hasNext() == true) {
RCmdLineOption opt = RCmdLineOption(::acdk::util::RBucketNode(it->next())->getValue());
out->print("\t");
opt->printOn(out);
out->print("\n");
}
if (_helpDetail != Nil)
out->print(_helpDetail);
out->flush();
}
::acdk::util::RProperties
CmdLineParser::parse(IN(RStringArray) args,
bool ignoreUnknown/* = false*/,
bool stripDetected/* = false*/)
{
return parse(new ::acdk::util::Properties(), args, ignoreUnknown, stripDetected);
}
::acdk::util::RProperties
CmdLineParser::parse(IN(::acdk::util::RProperties) props,
IN(RStringArray) args,
bool ignoreUnknown/* = false*/,
bool stripDetected/* = false*/)
{
for (int i = 1; i < args.length(); i++)
{
RString key = args[i];
int pos = key->indexOf('=');
RString value;
if (pos != -1)
{
value = key->substr(pos + 1);
key = key->substr(0, pos);
}
RCmdLineOption opt = (RCmdLineOption)_map->get((acdk::lang::Object)key);
if (opt == Nil)
{
if (ignoreUnknown == true || (key->startsWith("-") == false && key->startsWith("/") == false))
continue;
THROW3(CmdLineParseException, "unknown option", args, this);
}
if (opt->_expectArg == true)
{
if (value != Nil)
{
props->setProperty((opt->_alias != Nil ? opt->_alias : key), value);
}
else
{
if (i + 1 >= args.length())
THROW3(CmdLineParseException, RString("option expexts value: ") + opt->toString(), args, this);
value = args[i + 1];
if (stripDetected == true)
args->remove(i + 1);
else
++i;
props->setProperty((opt->_alias != Nil ? opt->_alias : key), value);
}
}
else
props->setProperty((opt->_alias != Nil ? opt->_alias : key), String::emptyString());
opt->_parsed = true;
if (stripDetected == true)
{
args->remove(i);
i--;
}
}
acdk::util::RIterator it = _map->entrySet()->iterator();
while (it->hasNext() == true)
{
RCmdLineOption opt(acdk::util::RBasicMapEntry(it->next())->getValue());
if (opt->_required == true && opt->_parsed == false)
{
THROW3(CmdLineParseException, RString("option is required: ") + opt->toString(), args, this);
}
}
return props;
}
//virtual
RString
CmdLineParseException::getMessage()
{
acdk::io::RCharArrayWriter cout = new acdk::io::CharArrayWriter();
acdk::io::RPrintWriter pout = new acdk::io::PrintWriter((acdk::io::RCharWriter)&cout);
_parser->printHelp(pout);
return _what + ": command line '" + _cmdline->toString() + "'\n"
+ cout->toString() + "\n" + System::getSystemCmdLineOps();
}
} // lang
} // acdk
|