1
0
mirror of https://github.com/wfjm/w11.git synced 2026-02-09 10:01:33 +00:00
Files
wfjm.w11/tools/src/librtcltools/RtclNameSet.cpp
2018-11-16 18:26:00 +01:00

137 lines
3.8 KiB
C++

// $Id: RtclNameSet.cpp 1066 2018-11-10 11:21:53Z mueller $
//
// Copyright 2011-2018 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
//
// 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
// Software Foundation, either version 3, or (at your option) any later version.
//
// This program 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 General Public License
// for complete details.
//
// Revision History:
// Date Rev Version Comment
// 2018-11-09 1066 1.1.2 use auto
// 2014-08-22 584 1.1.1 use nullptr
// 2013-05-19 521 1.1 add CheckMatch()
// 2013-02-03 481 1.0.1 use Rexception
// 2011-02-20 363 1.0 Initial version
// ---------------------------------------------------------------------------
/*!
\file
\brief Implemenation of RtclNameSet.
*/
// debug
#include <iostream>
#include "RtclNameSet.hpp"
#include "librtools/Rexception.hpp"
using namespace std;
/*!
\class Retro::RtclNameSet
\brief FIXME_docs
*/
// all method definitions in namespace Retro
namespace Retro {
//------------------------------------------+-----------------------------------
//! Default constructor
RtclNameSet::RtclNameSet()
: fSet()
{}
//------------------------------------------+-----------------------------------
//! FIXME_docs
RtclNameSet::RtclNameSet(const std::string& nset)
: fSet()
{
size_t ibeg=0;
while (true) {
size_t iend = nset.find_first_of('|', ibeg);
if (iend-ibeg > 0) {
string name(nset, ibeg, iend-ibeg);
auto ret = fSet.insert(name);
if (ret.second == false) // or use !(ret.second)
throw Rexception("RtclNameSet::<ctor>", "Bad args: " +
string("duplicate name '") + name +
"' in set '" + nset + "'");
}
if (iend == string::npos) break;
ibeg = iend+1;
}
}
//------------------------------------------+-----------------------------------
//! Destructor
RtclNameSet::~RtclNameSet()
{}
//------------------------------------------+-----------------------------------
//! FIXME_docs
bool RtclNameSet::Check(Tcl_Interp* interp, std::string& rval,
const std::string& tval) const
{
return CheckMatch(interp, rval, tval, true) > 0;
}
//------------------------------------------+-----------------------------------
//! FIXME_docs
// irc = 1 -> match
// 0 -> ambiguous match --> tcl err
// -1 -> no match --> tcl err if misserr
int RtclNameSet::CheckMatch(Tcl_Interp* interp, std::string& rval,
const std::string& tval, bool misserr) const
{
rval.clear();
auto it = fSet.lower_bound(tval);
// no leading substring match
if (it==fSet.end() || tval!=it->substr(0,tval.length())) {
if (misserr) {
Tcl_AppendResult(interp, "-E: bad option '", tval.c_str(),
"': must be ", nullptr);
const char* delim = "";
for (auto it1=fSet.begin(); it1!=fSet.end(); it1++) {
Tcl_AppendResult(interp, delim, it1->c_str(), nullptr);
delim = ",";
}
}
return -1;
}
// check for ambiguous substring match
if (tval != *it) {
auto it1 = it;
it1++;
if (it1!=fSet.end() && tval==it1->substr(0,tval.length())) {
Tcl_AppendResult(interp, "-E: ambiguous option '", tval.c_str(),
"': must be ", nullptr);
const char* delim = "";
for (it1=it; it1!=fSet.end() &&
tval==it1->substr(0,tval.length()); it1++) {
Tcl_AppendResult(interp, delim, it1->c_str(), nullptr);
delim = ",";
}
return 0;
}
}
rval = *it;
return 1;
}
} // end namespace Retro