1
0
mirror of https://github.com/wfjm/w11.git synced 2026-03-27 10:41:30 +00:00
Files
wfjm.w11/tools/src/librtcltools/RtclClassBase.cpp
Walter F.J. Mueller a20f49fcd5 - add sources for C++/Tcl based backend, add directories
- tools/src/...
  - tools/tcl/...
  - tools/dox
  - tools/make
- add rlink test system
  - rtl/sys_gen/tst_rlink/nexys2/...
2011-04-02 11:08:56 +00:00

189 lines
5.5 KiB
C++

// $Id: RtclClassBase.cpp 374 2011-03-27 17:02:47Z mueller $
//
// Copyright 2011- 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 2, 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
// 2011-03-05 366 1.0.1 use AppendResultNewLines() in exception catcher
// 2011-02-20 363 1.0 Initial version
// 2011-02-11 360 0.1 First draft
// ---------------------------------------------------------------------------
/*!
\file
\version $Id: RtclClassBase.cpp 374 2011-03-27 17:02:47Z mueller $
\brief Implemenation of RtclClassBase.
*/
#include <string.h>
#include <stdexcept>
#include "RtclClassBase.hpp"
#include "RtclContext.hpp"
#include "RtclOPtr.hpp"
#include "Rtcl.hpp"
using namespace std;
using namespace Retro;
/*!
\class Retro::RtclClassBase
\brief FIXME_docs
*/
//------------------------------------------+-----------------------------------
//! Default constructor
RtclClassBase::RtclClassBase(const std::string& type)
: fType(type),
fInterp(0)
{}
//------------------------------------------+-----------------------------------
//! Destructor
RtclClassBase::~RtclClassBase()
{
if (fInterp) RtclContext::Find(fInterp).UnRegisterClass(this);
}
//------------------------------------------+-----------------------------------
//! FIXME_docs
void RtclClassBase::CreateClassCmd(Tcl_Interp* interp, const char* name)
{
fInterp = interp;
fCmdToken =
Tcl_CreateObjCommand(interp, name, ThunkTclClassCmd, (ClientData) this,
(Tcl_CmdDeleteProc *) ThunkTclCmdDeleteProc);
RtclContext::Find(interp).RegisterClass(this);
Tcl_CreateExitHandler((Tcl_ExitProc*) ThunkTclExitProc, (ClientData) this);
return;
}
//------------------------------------------+-----------------------------------
//! FIXME_docs
inline int RtclClassBase::TclClassCmd(Tcl_Interp* interp, int objc,
Tcl_Obj* const objv[])
{
if (objc == 1) {
return ClassCmdList(interp);
}
const char* name = Tcl_GetString(objv[1]);
if (objc == 3 && strcmp(Tcl_GetString(objv[2]), "-delete")==0) {
return ClassCmdDelete(interp, name);
}
return ClassCmdCreate(interp, objc, objv);
}
//------------------------------------------+-----------------------------------
//! FIXME_docs
inline int RtclClassBase::ClassCmdList(Tcl_Interp* interp)
{
std::vector<RtclProxyBase*> list;
RtclContext::Find(interp).ListProxy(list, Type());
RtclOPtr rlist(Tcl_NewListObj(0, NULL));
for (size_t i=0; i<list.size(); i++) {
const char* cmdname = Tcl_GetCommandName(interp, list[i]->Token());
RtclOPtr rval(Tcl_NewStringObj(cmdname, -1));
if (Tcl_ListObjAppendElement(interp, rlist, rval) != kOK) return kERR;
}
Tcl_SetObjResult(interp, rlist);
return kOK;
}
//------------------------------------------+-----------------------------------
//! FIXME_docs
inline int RtclClassBase::ClassCmdDelete(Tcl_Interp* interp, const char* name)
{
Tcl_CmdInfo cinfo;
if (Tcl_GetCommandInfo(interp, name, &cinfo) == 0) {
Tcl_AppendResult(interp, "-E: unknown command name \"", name, "\"", NULL);
return kERR;
}
RtclContext& cntx = RtclContext::Find(interp);
if (!cntx.CheckProxy((RtclProxyBase*) cinfo.objClientData)) {
Tcl_AppendResult(interp, "-E: command \"", name, "\" is not a RtclProxy",
NULL);
return kERR;
}
if (!cntx.CheckProxy((RtclProxyBase*) cinfo.objClientData, Type())) {
Tcl_AppendResult(interp, "-E: command \"", name,
"\" is not a RtclProxy of type \"",
Type().c_str(), "\"", NULL);
return kERR;
}
int irc = Tcl_DeleteCommand(interp, name);
if (irc != kOK) Tcl_AppendResult(interp, "-E: failed to delete \"", name,
"\"", NULL);
return irc;
}
//------------------------------------------+-----------------------------------
//! FIXME_docs
int RtclClassBase::ThunkTclClassCmd(ClientData cdata, Tcl_Interp* interp,
int objc, Tcl_Obj* const objv[])
{
if (!cdata) {
Tcl_AppendResult(interp, "-E: BUG! ThunkTclClassCmd called with cdata == 0",
NULL);
return kERR;
}
try {
return ((RtclClassBase*) cdata)->TclClassCmd(interp, objc, objv);
} catch (exception& e) {
Rtcl::AppendResultNewLines(interp);
Tcl_AppendResult(interp, "-E: exception caught in ThunkTclClassCmd: \"",
e.what(), "\"", NULL);
}
return kERR;
}
//------------------------------------------+-----------------------------------
//! FIXME_docs
void RtclClassBase::ThunkTclCmdDeleteProc(ClientData cdata)
{
Tcl_DeleteExitHandler((Tcl_ExitProc*) ThunkTclExitProc, cdata);
delete ((RtclClassBase*) cdata);
return;
}
//------------------------------------------+-----------------------------------
//! FIXME_docs
void RtclClassBase::ThunkTclExitProc(ClientData cdata)
{
delete ((RtclClassBase*) cdata);
return;
}
//------------------------------------------+-----------------------------------
#if (defined(Retro_NoInline) || defined(Retro_RtclClassBase_NoInline))
#define inline
#include "RtclClassBase.ipp"
#undef inline
#endif