OpenCores
URL https://opencores.org/ocsvn/w11/w11/trunk

Subversion Repositories w11

[/] [w11/] [tags/] [w11a_V0.74/] [tools/] [src/] [librtcltools/] [RtclProxyBase.cpp] - Blame information for rev 10

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 10 wfjm
// $Id: RtclProxyBase.cpp 374 2011-03-27 17:02:47Z mueller $
2
//
3
// Copyright 2011- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
4
//
5
// This program is free software; you may redistribute and/or modify it under
6
// the terms of the GNU General Public License as published by the Free
7
// Software Foundation, either version 2, or at your option any later version.
8
//
9
// This program is distributed in the hope that it will be useful, but
10
// WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY
11
// or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12
// for complete details.
13
// 
14
// Revision History: 
15
// Date         Rev Version  Comment
16
// 2011-03-05   366   1.0.1  use AppendResultNewLines() in exception catcher
17
// 2011-02-20   363   1.0    Initial version
18
// 2011-02-11   360   0.1    First draft
19
// ---------------------------------------------------------------------------
20
 
21
/*!
22
  \file
23
  \version $Id: RtclProxyBase.cpp 374 2011-03-27 17:02:47Z mueller $
24
  \brief   Implemenation of RtclProxyBase.
25
*/
26
 
27
#include <stdexcept>
28
 
29
#include "RtclProxyBase.hpp"
30
#include "RtclContext.hpp"
31
#include "Rtcl.hpp"
32
 
33
using namespace std;
34
using namespace Retro;
35
 
36
/*!
37
  \class Retro::RtclProxyBase
38
  \brief FIXME_docs
39
*/
40
 
41
typedef std::pair<Retro::RtclProxyBase::mmap_it_t, bool>  mmap_ins_t;
42
 
43
//------------------------------------------+-----------------------------------
44
//! FIXME_docs
45
 
46
RtclProxyBase::RtclProxyBase(const std::string& type)
47
  : fType(type),
48
    fMapMeth(),
49
    fInterp(0)
50
{}
51
 
52
//------------------------------------------+-----------------------------------
53
//! Destructor
54
 
55
RtclProxyBase::~RtclProxyBase()
56
{
57
  if (fInterp) RtclContext::Find(fInterp).UnRegisterProxy(this);
58
  for (mmap_it_t it=fMapMeth.begin(); it!=fMapMeth.end(); it++) {
59
    delete it->second;
60
  }
61
}
62
 
63
//------------------------------------------+-----------------------------------
64
//! FIXME_docs
65
 
66
int RtclProxyBase::ClassCmdConfig(Tcl_Interp* interp, int objc,
67
                                  Tcl_Obj* const objv[])
68
{
69
  if (objc > 2) {
70
    Tcl_AppendResult(interp, "-E: no configuration args supported", NULL);
71
    return TCL_ERROR;
72
  }
73
  return TCL_OK;
74
}
75
 
76
//------------------------------------------+-----------------------------------
77
//! FIXME_docs
78
 
79
void RtclProxyBase::AddMeth(const std::string& name,
80
                            RmethDscBase<RtclArgs>* pmeth)
81
{
82
  mmap_ins_t ret = fMapMeth.insert(mmap_val_t(name, pmeth));
83
  if (ret.second == false)                  // or use !(ret.second)
84
    throw logic_error(string("RtclProxyBase::AddMeth: duplicate name: ") +
85
                      name);
86
  return;
87
}
88
 
89
//------------------------------------------+-----------------------------------
90
//! FIXME_docs
91
 
92
void RtclProxyBase::CreateObjectCmd(Tcl_Interp* interp, const char* name)
93
{
94
  fInterp = interp;
95
  fCmdToken =
96
    Tcl_CreateObjCommand(interp, name, ThunkTclObjectCmd, (ClientData) this,
97
                         (Tcl_CmdDeleteProc *) ThunkTclCmdDeleteProc);
98
  RtclContext::Find(interp).RegisterProxy(this);
99
  Tcl_CreateExitHandler((Tcl_ExitProc*) ThunkTclExitProc, (ClientData) this);
100
  return;
101
}
102
 
103
//------------------------------------------+-----------------------------------
104
//! FIXME_docs
105
 
106
int RtclProxyBase::TclObjectCmd(Tcl_Interp* interp, int objc,
107
                                Tcl_Obj* const objv[])
108
{
109
  mdsc_t* pmdsc = 0;
110
 
111
  if (objc == 1) {                             // no args
112
    mmap_cit_t it = fMapMeth.find("$default"); // default method registered ?
113
    if (it == fMapMeth.end()) {                // if not, complain
114
      Tcl_WrongNumArgs(interp, 1, objv, "option ?args?");
115
      return TCL_ERROR;
116
    }
117
    pmdsc = it->second;
118
 
119
  } else {                                     // at least method name given 
120
    string name(Tcl_GetString(objv[1]));
121
    mmap_cit_t it = fMapMeth.lower_bound(name);
122
 
123
    // no leading substring match
124
    if (it==fMapMeth.end() || name!=it->first.substr(0,name.length())) {
125
      Tcl_AppendResult(interp, "-E: bad option \"", Tcl_GetString(objv[1]),
126
                       "\": must be ", NULL);
127
      const char* delim = "";
128
      for (mmap_cit_t it1=fMapMeth.begin(); it1!=fMapMeth.end(); it1++) {
129
        if (it1->first.c_str()[0] != '$') {
130
          Tcl_AppendResult(interp, delim, it1->first.c_str(), NULL);
131
          delim = ",";
132
        }
133
      }
134
      return TCL_ERROR;
135
    }
136
 
137
    pmdsc = it->second;
138
 
139
    // check for ambiguous substring match
140
    if (name != it->first) {
141
      mmap_cit_t it1 = it;
142
      it1++;
143
      if (it1!=fMapMeth.end() && name==it1->first.substr(0,name.length())) {
144
        Tcl_AppendResult(interp, "-E: ambiguous option \"",
145
                         Tcl_GetString(objv[1]), "\": must be ", NULL);
146
        const char* delim = "";
147
        for (it1=it; it1!=fMapMeth.end() &&
148
               name==it1->first.substr(0,name.length()); it1++) {
149
          Tcl_AppendResult(interp, delim, it1->first.c_str(), NULL);
150
          delim = ",";
151
        }
152
        return TCL_ERROR;
153
      }
154
    }
155
  }
156
 
157
  RtclArgs  args(interp, objc, objv, 2);
158
  return (*pmdsc)(args);
159
}
160
 
161
//------------------------------------------+-----------------------------------
162
//! FIXME_docs
163
 
164
int RtclProxyBase::ThunkTclObjectCmd(ClientData cdata, Tcl_Interp* interp,
165
                                     int objc, Tcl_Obj* const objv[])
166
{
167
  if (!cdata) {
168
    Tcl_AppendResult(interp, "-E: BUG! ThunkTclObjectCmd called with cdata==0",
169
                     NULL);
170
    return TCL_ERROR;
171
  }
172
 
173
  try {
174
    return ((RtclProxyBase*) cdata)->TclObjectCmd(interp, objc, objv);
175
  } catch (exception& e) {
176
    Rtcl::AppendResultNewLines(interp);
177
    Tcl_AppendResult(interp, "-E: exception caught \"", e.what(), "\"", NULL);
178
  }
179
  return TCL_ERROR;
180
}
181
 
182
//------------------------------------------+-----------------------------------
183
//! FIXME_docs
184
 
185
void RtclProxyBase::ThunkTclCmdDeleteProc(ClientData cdata)
186
{
187
  Tcl_DeleteExitHandler((Tcl_ExitProc*) ThunkTclExitProc, cdata);
188
  delete ((RtclProxyBase*) cdata);
189
  return;
190
}
191
 
192
//------------------------------------------+-----------------------------------
193
//! FIXME_docs
194
 
195
void RtclProxyBase::ThunkTclExitProc(ClientData cdata)
196
{
197
  delete ((RtclProxyBase*) cdata);
198
  return;
199
}
200
 
201
//------------------------------------------+-----------------------------------
202
#if (defined(Retro_NoInline) || defined(Retro_RtclProxyBase_NoInline))
203
#define inline
204
#include "RtclProxyBase.ipp"
205
#undef  inline
206
#endif

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.