// $Id: RtclNameSet.cpp 521 2013-05-20 22:16:45Z mueller $
|
// $Id: RtclNameSet.cpp 521 2013-05-20 22:16:45Z mueller $
|
//
|
//
|
// Copyright 2011-2013 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
// Copyright 2011-2013 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
//
|
//
|
// This program is free software; you may redistribute and/or modify it under
|
// This program is free software; you may redistribute and/or modify it under
|
// the terms of the GNU General Public License as published by the Free
|
// the terms of the GNU General Public License as published by the Free
|
// Software Foundation, either version 2, or at your option any later version.
|
// Software Foundation, either version 2, or at your option any later version.
|
//
|
//
|
// This program is distributed in the hope that it will be useful, but
|
// This program is distributed in the hope that it will be useful, but
|
// WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY
|
// WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY
|
// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
// for complete details.
|
// for complete details.
|
//
|
//
|
// Revision History:
|
// Revision History:
|
// Date Rev Version Comment
|
// Date Rev Version Comment
|
// 2013-05-19 521 1.1 add CheckMatch()
|
// 2013-05-19 521 1.1 add CheckMatch()
|
// 2013-02-03 481 1.0.1 use Rexception
|
// 2013-02-03 481 1.0.1 use Rexception
|
// 2011-02-20 363 1.0 Initial version
|
// 2011-02-20 363 1.0 Initial version
|
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
|
|
/*!
|
/*!
|
\file
|
\file
|
\version $Id: RtclNameSet.cpp 521 2013-05-20 22:16:45Z mueller $
|
\version $Id: RtclNameSet.cpp 521 2013-05-20 22:16:45Z mueller $
|
\brief Implemenation of RtclNameSet.
|
\brief Implemenation of RtclNameSet.
|
*/
|
*/
|
|
|
// debug
|
// debug
|
#include <iostream>
|
#include <iostream>
|
|
|
#include "RtclNameSet.hpp"
|
#include "RtclNameSet.hpp"
|
|
|
#include "librtools/Rexception.hpp"
|
#include "librtools/Rexception.hpp"
|
|
|
using namespace std;
|
using namespace std;
|
|
|
/*!
|
/*!
|
\class Retro::RtclNameSet
|
\class Retro::RtclNameSet
|
\brief FIXME_docs
|
\brief FIXME_docs
|
*/
|
*/
|
|
|
// all method definitions in namespace Retro
|
// all method definitions in namespace Retro
|
namespace Retro {
|
namespace Retro {
|
|
|
typedef std::pair<RtclNameSet::nset_it_t, bool> nset_ins_t;
|
typedef std::pair<RtclNameSet::nset_it_t, bool> nset_ins_t;
|
|
|
//------------------------------------------+-----------------------------------
|
//------------------------------------------+-----------------------------------
|
//! Default constructor
|
//! Default constructor
|
|
|
RtclNameSet::RtclNameSet()
|
RtclNameSet::RtclNameSet()
|
: fSet()
|
: fSet()
|
{}
|
{}
|
|
|
//------------------------------------------+-----------------------------------
|
//------------------------------------------+-----------------------------------
|
//! FIXME_docs
|
//! FIXME_docs
|
|
|
RtclNameSet::RtclNameSet(const std::string& nset)
|
RtclNameSet::RtclNameSet(const std::string& nset)
|
: fSet()
|
: fSet()
|
{
|
{
|
size_t ibeg=0;
|
size_t ibeg=0;
|
while (true) {
|
while (true) {
|
size_t iend = nset.find_first_of('|', ibeg);
|
size_t iend = nset.find_first_of('|', ibeg);
|
if (iend-ibeg > 0) {
|
if (iend-ibeg > 0) {
|
string name(nset, ibeg, iend-ibeg);
|
string name(nset, ibeg, iend-ibeg);
|
nset_ins_t ret = fSet.insert(name);
|
nset_ins_t ret = fSet.insert(name);
|
if (ret.second == false) // or use !(ret.second)
|
if (ret.second == false) // or use !(ret.second)
|
throw Rexception("RtclNameSet::<ctor>", "Bad args: " +
|
throw Rexception("RtclNameSet::<ctor>", "Bad args: " +
|
string("duplicate name '") + name +
|
string("duplicate name '") + name +
|
"' in set '" + nset + "'");
|
"' in set '" + nset + "'");
|
}
|
}
|
if (iend == string::npos) break;
|
if (iend == string::npos) break;
|
ibeg = iend+1;
|
ibeg = iend+1;
|
}
|
}
|
}
|
}
|
|
|
//------------------------------------------+-----------------------------------
|
//------------------------------------------+-----------------------------------
|
//! Destructor
|
//! Destructor
|
|
|
RtclNameSet::~RtclNameSet()
|
RtclNameSet::~RtclNameSet()
|
{}
|
{}
|
|
|
//------------------------------------------+-----------------------------------
|
//------------------------------------------+-----------------------------------
|
//! FIXME_docs
|
//! FIXME_docs
|
|
|
bool RtclNameSet::Check(Tcl_Interp* interp, std::string& rval,
|
bool RtclNameSet::Check(Tcl_Interp* interp, std::string& rval,
|
const std::string& tval) const
|
const std::string& tval) const
|
{
|
{
|
return CheckMatch(interp, rval, tval, true) > 0;
|
return CheckMatch(interp, rval, tval, true) > 0;
|
}
|
}
|
|
|
//------------------------------------------+-----------------------------------
|
//------------------------------------------+-----------------------------------
|
//! FIXME_docs
|
//! FIXME_docs
|
// irc = 1 -> match
|
// irc = 1 -> match
|
// 0 -> ambiguous match --> tcl err
|
// 0 -> ambiguous match --> tcl err
|
// -1 -> no match --> tcl err if misserr
|
// -1 -> no match --> tcl err if misserr
|
|
|
int RtclNameSet::CheckMatch(Tcl_Interp* interp, std::string& rval,
|
int RtclNameSet::CheckMatch(Tcl_Interp* interp, std::string& rval,
|
const std::string& tval, bool misserr) const
|
const std::string& tval, bool misserr) const
|
{
|
{
|
rval.clear();
|
rval.clear();
|
nset_cit_t it = fSet.lower_bound(tval);
|
nset_cit_t it = fSet.lower_bound(tval);
|
|
|
// no leading substring match
|
// no leading substring match
|
if (it==fSet.end() || tval!=it->substr(0,tval.length())) {
|
if (it==fSet.end() || tval!=it->substr(0,tval.length())) {
|
if (misserr) {
|
if (misserr) {
|
Tcl_AppendResult(interp, "-E: bad option '", tval.c_str(),
|
Tcl_AppendResult(interp, "-E: bad option '", tval.c_str(),
|
"': must be ", NULL);
|
"': must be ", NULL);
|
const char* delim = "";
|
const char* delim = "";
|
for (nset_cit_t it1=fSet.begin(); it1!=fSet.end(); it1++) {
|
for (nset_cit_t it1=fSet.begin(); it1!=fSet.end(); it1++) {
|
Tcl_AppendResult(interp, delim, it1->c_str(), NULL);
|
Tcl_AppendResult(interp, delim, it1->c_str(), NULL);
|
delim = ",";
|
delim = ",";
|
}
|
}
|
}
|
}
|
return -1;
|
return -1;
|
}
|
}
|
|
|
// check for ambiguous substring match
|
// check for ambiguous substring match
|
if (tval != *it) {
|
if (tval != *it) {
|
nset_cit_t it1 = it;
|
nset_cit_t it1 = it;
|
it1++;
|
it1++;
|
if (it1!=fSet.end() && tval==it1->substr(0,tval.length())) {
|
if (it1!=fSet.end() && tval==it1->substr(0,tval.length())) {
|
Tcl_AppendResult(interp, "-E: ambiguous option '", tval.c_str(),
|
Tcl_AppendResult(interp, "-E: ambiguous option '", tval.c_str(),
|
"': must be ", NULL);
|
"': must be ", NULL);
|
const char* delim = "";
|
const char* delim = "";
|
for (it1=it; it1!=fSet.end() &&
|
for (it1=it; it1!=fSet.end() &&
|
tval==it1->substr(0,tval.length()); it1++) {
|
tval==it1->substr(0,tval.length()); it1++) {
|
Tcl_AppendResult(interp, delim, it1->c_str(), NULL);
|
Tcl_AppendResult(interp, delim, it1->c_str(), NULL);
|
delim = ",";
|
delim = ",";
|
}
|
}
|
return 0;
|
return 0;
|
}
|
}
|
}
|
}
|
|
|
rval = *it;
|
rval = *it;
|
return 1;
|
return 1;
|
}
|
}
|
|
|
} // end namespace Retro
|
} // end namespace Retro
|
|
|