mirror of
https://github.com/wfjm/w11.git
synced 2026-01-22 11:00:49 +00:00
tcl command handling update
- support now sub-command handling - support dynamically created commands (like 'virt') - support command info (via '?' option)
This commit is contained in:
parent
81b6d6854d
commit
823c03ba3b
@ -17,6 +17,10 @@ software or firmware builds or that the documentation is consistent.
|
||||
The full set of tests is only run for tagged releases._
|
||||
|
||||
### Summary
|
||||
- move to Ubuntu 16.04 as development platform
|
||||
- document urjtag build (jtag in Ubuntu 16.04 is broken)
|
||||
- add environment sanity wrappers for acroread,awk,firefox to ensure
|
||||
proper operation of vivado under Ubuntu 16.04
|
||||
- use Rtime; drop Rtools::TimeOfDayAsDouble()
|
||||
- probe/setup auxilliary devices: kw11l,kw11p,iist
|
||||
- librw11/Rw11Cpu: add ModLalh()
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
// $Id: RtclCmdBase.cpp 584 2014-08-22 19:38:12Z mueller $
|
||||
// $Id: RtclCmdBase.cpp 863 2017-04-02 11:43:15Z mueller $
|
||||
//
|
||||
// Copyright 2011-2014 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
||||
// Copyright 2011-2017 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
|
||||
@ -13,6 +13,9 @@
|
||||
//
|
||||
// Revision History:
|
||||
// Date Rev Version Comment
|
||||
// 2017-04-02 863 1.1 add DelMeth(),TstMeth(); add M_info() and '?'
|
||||
// rename fMapMeth -> fMethMap
|
||||
// 2017-03-11 859 1.1 support now sub-command handling
|
||||
// 2014-08-22 584 1.0.3 use nullptr
|
||||
// 2013-02-10 485 1.0.2 add static const defs
|
||||
// 2013-02-05 483 1.0.1 remove 'unknown specified, full match only' logic
|
||||
@ -21,7 +24,7 @@
|
||||
|
||||
/*!
|
||||
\file
|
||||
\version $Id: RtclCmdBase.cpp 584 2014-08-22 19:38:12Z mueller $
|
||||
\version $Id: RtclCmdBase.cpp 863 2017-04-02 11:43:15Z mueller $
|
||||
\brief Implemenation of RtclCmdBase.
|
||||
*/
|
||||
|
||||
@ -29,6 +32,7 @@
|
||||
|
||||
#include "librtools/Rexception.hpp"
|
||||
#include "Rtcl.hpp"
|
||||
#include "RtclOPtr.hpp"
|
||||
|
||||
using namespace std;
|
||||
|
||||
@ -40,8 +44,6 @@ using namespace std;
|
||||
// all method definitions in namespace Retro
|
||||
namespace Retro {
|
||||
|
||||
typedef std::pair<RtclCmdBase::mmap_it_t, bool> mmap_ins_t;
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
// constants definitions
|
||||
|
||||
@ -52,7 +54,7 @@ const int RtclCmdBase::kERR;
|
||||
//! FIXME_docs
|
||||
|
||||
RtclCmdBase::RtclCmdBase()
|
||||
: fMapMeth()
|
||||
: fMethMap()
|
||||
{}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
@ -70,36 +72,38 @@ int RtclCmdBase::DispatchCmd(RtclArgs& args)
|
||||
|
||||
Tcl_Interp* interp = args.Interp();
|
||||
|
||||
// no method name given
|
||||
if (args.Objc() <= 1) { // no args
|
||||
it_match = fMapMeth.find("$default"); // default method registered ?
|
||||
if (it_match != fMapMeth.end()) {
|
||||
if (size_t(args.Objc()) == args.NDone()) {// no args left -> no method name
|
||||
it_match = fMethMap.find("$default"); // default method registered ?
|
||||
if (it_match != fMethMap.end()) {
|
||||
return (it_match->second)(args);
|
||||
}
|
||||
Tcl_WrongNumArgs(interp, 1, args.Objv(), "option ?args?"); // or fail
|
||||
// or fail
|
||||
Tcl_WrongNumArgs(interp, args.NDone(), args.Objv(), "option ?args?");
|
||||
return kERR;
|
||||
}
|
||||
|
||||
// here if at least method name given
|
||||
string name(Tcl_GetString(args[1]));
|
||||
string name;
|
||||
args.GetArg("cmd", name); // will always succeed
|
||||
it_match = fMethMap.lower_bound(name);
|
||||
|
||||
it_match = fMapMeth.lower_bound(name);
|
||||
// handle '?'
|
||||
if (name == "?") return M_info(args);
|
||||
|
||||
// no leading substring match
|
||||
if (it_match==fMapMeth.end() ||
|
||||
if (it_match==fMethMap.end() ||
|
||||
name!=it_match->first.substr(0,name.length())) {
|
||||
|
||||
mmap_cit_t it_un = fMapMeth.find("$unknown"); // unknown method registered ?
|
||||
if (it_un!=fMapMeth.end()) {
|
||||
mmap_cit_t it_un = fMethMap.find("$unknown"); // unknown method registered ?
|
||||
if (it_un!=fMethMap.end()) {
|
||||
return (it_un->second)(args);
|
||||
}
|
||||
|
||||
Tcl_AppendResult(interp, "-E: bad option '", name.c_str(),
|
||||
"': must be ", nullptr);
|
||||
const char* delim = "";
|
||||
for (mmap_cit_t it1=fMapMeth.begin(); it1!=fMapMeth.end(); it1++) {
|
||||
if (it1->first.c_str()[0] != '$') {
|
||||
Tcl_AppendResult(interp, delim, it1->first.c_str(), nullptr);
|
||||
for (const auto& kv : fMethMap) {
|
||||
if (kv.first.c_str()[0] != '$') {
|
||||
Tcl_AppendResult(interp, delim, kv.first.c_str(), nullptr);
|
||||
delim = ",";
|
||||
}
|
||||
}
|
||||
@ -110,11 +114,11 @@ int RtclCmdBase::DispatchCmd(RtclArgs& args)
|
||||
if (name != it_match->first) {
|
||||
mmap_cit_t it1 = it_match;
|
||||
it1++;
|
||||
if (it1!=fMapMeth.end() && name==it1->first.substr(0,name.length())) {
|
||||
if (it1!=fMethMap.end() && name==it1->first.substr(0,name.length())) {
|
||||
Tcl_AppendResult(interp, "-E: ambiguous option '",
|
||||
name.c_str(), "': must be ", nullptr);
|
||||
const char* delim = "";
|
||||
for (it1=it_match; it1!=fMapMeth.end() &&
|
||||
for (it1=it_match; it1!=fMethMap.end() &&
|
||||
name==it1->first.substr(0,name.length()); it1++) {
|
||||
Tcl_AppendResult(interp, delim, it1->first.c_str(), nullptr);
|
||||
delim = ",";
|
||||
@ -131,11 +135,61 @@ int RtclCmdBase::DispatchCmd(RtclArgs& args)
|
||||
|
||||
void RtclCmdBase::AddMeth(const std::string& name, const methfo_t& methfo)
|
||||
{
|
||||
mmap_ins_t ret = fMapMeth.insert(mmap_val_t(name, methfo));
|
||||
auto ret = fMethMap.emplace(name, methfo);
|
||||
if (ret.second == false) // or use !(ret.second)
|
||||
throw Rexception("RtclCmdBase::AddMeth:",
|
||||
string("Bad args: duplicate name: '") + name + "'");
|
||||
return;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
void RtclCmdBase::DelMeth(const std::string& name)
|
||||
{
|
||||
if (fMethMap.erase(name) == 0) // balk if not existing
|
||||
throw Rexception("RtclCmdBase::DelMeth:",
|
||||
string("Bad args: non-existing name: '") + name + "'");
|
||||
return;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
bool RtclCmdBase::TstMeth(const std::string& name)
|
||||
{
|
||||
return fMethMap.find(name) != fMethMap.end();
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
int RtclCmdBase::M_info(RtclArgs& args)
|
||||
{
|
||||
Tcl_Interp* interp = args.Interp();
|
||||
string cname("");
|
||||
if (!args.GetArg("??cname", cname)) return TCL_ERROR;
|
||||
if (!args.AllDone()) return TCL_ERROR;
|
||||
|
||||
RtclOPtr rlist(Tcl_NewListObj(0,nullptr));
|
||||
if (cname == "") { // no name --> return all
|
||||
for (const auto& kv : fMethMap) {
|
||||
if (kv.first[0] == '$') continue; // skip $nnn internals
|
||||
RtclOPtr pele(Tcl_NewStringObj(kv.first.c_str(), -1));
|
||||
Tcl_ListObjAppendElement(nullptr, rlist, pele);
|
||||
}
|
||||
|
||||
} else { // name seen --> return matches
|
||||
auto it_match = fMethMap.lower_bound(cname);
|
||||
for (auto it=it_match; it!=fMethMap.end() &&
|
||||
cname==it->first.substr(0,cname.length()); it++) {
|
||||
RtclOPtr pele(Tcl_NewStringObj(it->first.c_str(), -1));
|
||||
Tcl_ListObjAppendElement(nullptr, rlist, pele);
|
||||
}
|
||||
}
|
||||
|
||||
Tcl_SetObjResult(interp, rlist);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
} // end namespace Retro
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
// $Id: RtclCmdBase.hpp 511 2013-04-27 13:51:46Z mueller $
|
||||
// $Id: RtclCmdBase.hpp 863 2017-04-02 11:43:15Z mueller $
|
||||
//
|
||||
// Copyright 2013- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
||||
// Copyright 2013-2017 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
|
||||
@ -13,13 +13,15 @@
|
||||
//
|
||||
// Revision History:
|
||||
// Date Rev Version Comment
|
||||
// 2017-04-02 863 1.1 add DelMeth(),TstMeth(); add M_info() and '?'
|
||||
// rename fMapMeth -> fMethMap
|
||||
// 2013-04-26 511 1.0.1 AddMeth() now public
|
||||
// 2013-02-02 480 1.0 Initial version (refactored out from ProxyBase)
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
/*!
|
||||
\file
|
||||
\version $Id: RtclCmdBase.hpp 511 2013-04-27 13:51:46Z mueller $
|
||||
\version $Id: RtclCmdBase.hpp 863 2017-04-02 11:43:15Z mueller $
|
||||
\brief Declaration of class RtclCmdBase.
|
||||
*/
|
||||
|
||||
@ -52,15 +54,18 @@ namespace Retro {
|
||||
|
||||
int DispatchCmd(RtclArgs& args);
|
||||
void AddMeth(const std::string& name, const methfo_t& methfo);
|
||||
void DelMeth(const std::string& name);
|
||||
bool TstMeth(const std::string& name);
|
||||
|
||||
// some constants (also defined in cpp)
|
||||
static const int kOK = TCL_OK; //<!
|
||||
static const int kERR = TCL_ERROR; //<!
|
||||
|
||||
protected:
|
||||
|
||||
int M_info(RtclArgs& args);
|
||||
|
||||
protected:
|
||||
mmap_t fMapMeth; //!< map for named methods
|
||||
mmap_t fMethMap; //!< map for named methods
|
||||
};
|
||||
|
||||
} // end namespace Retro
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
// $Id: RtclProxyBase.cpp 584 2014-08-22 19:38:12Z mueller $
|
||||
// $Id: RtclProxyBase.cpp 859 2017-03-11 22:36:45Z mueller $
|
||||
//
|
||||
// Copyright 2011-2014 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
||||
// Copyright 2011-2017 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
|
||||
@ -13,6 +13,7 @@
|
||||
//
|
||||
// Revision History:
|
||||
// Date Rev Version Comment
|
||||
// 2017-03-11 859 1.5 adopt new DispatchCmd() logic
|
||||
// 2014-08-22 584 1.4.3 use nullptr
|
||||
// 2013-02-09 485 1.4.2 add CommandName()
|
||||
// 2013-02-05 483 1.4.1 ClassCmdConfig: use RtclArgs
|
||||
@ -27,7 +28,7 @@
|
||||
|
||||
/*!
|
||||
\file
|
||||
\version $Id: RtclProxyBase.cpp 584 2014-08-22 19:38:12Z mueller $
|
||||
\version $Id: RtclProxyBase.cpp 859 2017-03-11 22:36:45Z mueller $
|
||||
\brief Implemenation of RtclProxyBase.
|
||||
*/
|
||||
|
||||
@ -114,7 +115,7 @@ void RtclProxyBase::CreateObjectCmd(Tcl_Interp* interp, const char* name)
|
||||
int RtclProxyBase::TclObjectCmd(Tcl_Interp* interp, int objc,
|
||||
Tcl_Obj* const objv[])
|
||||
{
|
||||
RtclArgs args(interp, objc, objv, 2);
|
||||
RtclArgs args(interp, objc, objv, 1);
|
||||
return DispatchCmd(args);
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user