URL
https://opencores.org/ocsvn/w11/w11/trunk
Subversion Repositories w11
Compare Revisions
- This comparison shows the changes necessary to convert path
/w11/tags/w11a_V0.6/tools/src/librutiltpp
- from Rev 22 to Rev 24
- ↔ Reverse comparison
Rev 22 → Rev 24
/RtclSystem.hpp
0,0 → 1,50
// $Id: RtclSystem.hpp 521 2013-05-20 22:16:45Z mueller $ |
// |
// Copyright 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 |
// 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 |
// 2013-05-17 521 1.0 Initial version |
// --------------------------------------------------------------------------- |
|
/*! |
\file |
\version $Id: RtclSystem.hpp 521 2013-05-20 22:16:45Z mueller $ |
\brief Declaration of class RtclSystem. |
*/ |
|
#ifndef included_Retro_RtclSystem |
#define included_Retro_RtclSystem 1 |
|
#include "tcl.h" |
|
namespace Retro { |
|
class RtclSystem { |
public: |
static void CreateCmds(Tcl_Interp* interp); |
|
static int Isatty(ClientData cdata, Tcl_Interp* interp, |
int objc, Tcl_Obj* const objv[]); |
static int SignalAction(ClientData cdata, Tcl_Interp* interp, |
int objc, Tcl_Obj* const objv[]); |
static int WaitPid(ClientData cdata, Tcl_Interp* interp, |
int objc, Tcl_Obj* const objv[]); |
|
private: |
}; |
|
} // end namespace Retro |
|
//#include "RtclSystem.ipp" |
|
#endif |
/RtclSignalAction.cpp
0,0 → 1,260
// $Id: RtclSignalAction.cpp 521 2013-05-20 22:16:45Z mueller $ |
// |
// Copyright 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 |
// 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 |
// 2013-05-17 521 1.0 Initial version |
// --------------------------------------------------------------------------- |
|
/*! |
\file |
\version $Id: RtclSignalAction.cpp 521 2013-05-20 22:16:45Z mueller $ |
\brief Implemenation of class RtclSignalAction. |
*/ |
|
#include <errno.h> |
#include <signal.h> |
#include <string.h> |
|
#include <iostream> |
|
#include "librtools/Rexception.hpp" |
|
#include "RtclSignalAction.hpp" |
|
using namespace std; |
|
/*! |
\class Retro::RtclSignalAction |
\brief FIXME_docs |
*/ |
|
// all method definitions in namespace Retro |
namespace Retro { |
|
RtclSignalAction* RtclSignalAction::fpObj = 0; |
|
//------------------------------------------+----------------------------------- |
//! FIXME_docs |
bool RtclSignalAction::Init(Tcl_Interp* interp, RerrMsg& emsg) |
{ |
if (fpObj) { |
emsg.Init("RtclSignalAction::Init", "already initialized"); |
return false; |
} |
|
try { |
fpObj = new RtclSignalAction(interp); |
} catch (exception& e) { |
emsg.Init("RtclSignalAction::Init", string("exception: ")+e.what()); |
return false; |
} |
|
Tcl_CreateExitHandler((Tcl_ExitProc*) ThunkTclExitProc, (ClientData) fpObj); |
|
return true; |
} |
|
//------------------------------------------+----------------------------------- |
//! FIXME_docs |
|
RtclSignalAction* RtclSignalAction::Obj() |
{ |
return fpObj; |
} |
|
|
//------------------------------------------+----------------------------------- |
//! FIXME_docs |
|
bool RtclSignalAction::SetAction(int signum, Tcl_Obj* pobj, RerrMsg& emsg) |
{ |
if (!ValidSignal(signum, emsg)) return false; |
if (fActionSet[signum] && !ClearAction(signum, emsg)) return false; |
|
struct sigaction sigact; |
::memset(&sigact, 0, sizeof(sigact)); |
sigact.sa_handler = SignalHandler; |
|
if (::sigaction(signum, &sigact, &fOldAction[signum]) != 0) { |
emsg.InitErrno("RtclSignalAction::SetAction", |
"sigaction() failed: ", errno); |
return false; |
} |
|
fpScript[signum] = pobj; |
fActionSet[signum] = true; |
return true; |
} |
|
//------------------------------------------+----------------------------------- |
//! FIXME_docs |
|
bool RtclSignalAction::GetAction(int signum, Tcl_Obj*& pobj, RerrMsg& emsg) |
{ |
if (!ValidSignal(signum, emsg)) return false; |
if (!fActionSet[signum]) { |
emsg.Init("RtclSignalAction::GetAction", "no action for signal"); |
return false; |
} |
|
pobj = fpScript[signum]; |
return true; |
} |
|
//------------------------------------------+----------------------------------- |
//! FIXME_docs |
|
bool RtclSignalAction::ClearAction(int signum, RerrMsg& emsg) |
{ |
if (!ValidSignal(signum, emsg)) return false; |
if (!fActionSet[signum]) { |
emsg.Init("RtclSignalAction::ClearAction", "no action for signal"); |
return false; |
} |
|
if (::sigaction(signum, &fOldAction[signum], NULL) != 0) { |
emsg.InitErrno("RtclSignalAction::ClearAction", |
"sigaction() failed: ", errno); |
return false; |
} |
fpScript[signum] = 0; |
fActionSet[signum] = false; |
return true; |
} |
|
//------------------------------------------+----------------------------------- |
//! FIXME_docs |
|
bool RtclSignalAction::ValidSignal(int signum, RerrMsg& emsg) |
{ |
if (signum > 0 && signum < 32) { |
switch (signum) { |
case SIGHUP: |
case SIGINT: |
case SIGTERM: |
case SIGUSR1: |
case SIGUSR2: |
return true; |
default: |
break; |
} |
} |
emsg.Init("RtclSignalAction::ValidSignal", "unsupported signal"); |
return false; |
} |
|
//------------------------------------------+----------------------------------- |
//! FIXME_docs |
|
void RtclSignalAction::TclChannelHandler(int mask) |
{ |
char signum; |
Tcl_Read(fShuttleChn, (char*) &signum, sizeof(signum)); |
// FIXME_code: handle return code |
|
Tcl_SetVar2Ex(fpInterp, "Rutil_signum", NULL, Tcl_NewIntObj((int)signum), 0); |
// FIXME_code: handle return code |
|
if ((Tcl_Obj*)fpScript[(int)signum]) { |
Tcl_EvalObjEx(fpInterp, fpScript[(int)signum], TCL_EVAL_GLOBAL); |
// FIXME_code: handle return code |
} |
|
return; |
} |
|
//------------------------------------------+----------------------------------- |
//! FIXME_docs |
|
void RtclSignalAction::SignalHandler(int signum) |
{ |
if (fpObj && fpObj->fFdPipeWrite>0) { |
char signum_c = signum; |
int irc = ::write(fpObj->fFdPipeWrite, (void*) &signum_c, sizeof(signum_c)); |
if (irc < 0) |
cerr << "RtclSignalAction::SignalHandler-E: write() failed, errno=" |
<< errno << endl; |
} else { |
cerr << "RtclSignalAction::SignalHandler-E: spurious call" << endl; |
} |
return; |
} |
|
//------------------------------------------+----------------------------------- |
//! FIXME_docs |
|
void RtclSignalAction::ThunkTclChannelHandler(ClientData cdata, int mask) |
{ |
if (fpObj) fpObj->TclChannelHandler(mask); |
return; |
} |
|
//------------------------------------------+----------------------------------- |
//! FIXME_docs |
|
void RtclSignalAction::ThunkTclExitProc(ClientData cdata) |
{ |
delete fpObj; |
fpObj = 0; |
return; |
} |
|
//------------------------------------------+----------------------------------- |
//! constructor |
|
RtclSignalAction::RtclSignalAction(Tcl_Interp* interp) |
: fpInterp(interp), |
fFdPipeRead(-1), |
fFdPipeWrite(-1), |
fShuttleChn(), |
fActionSet(), |
fpScript(), |
fOldAction() |
{ |
for (size_t i=0; i<32; i++) { |
fActionSet[i] = false; |
::memset(&fOldAction[i], 0, sizeof(fOldAction[0])); |
} |
|
int pipefd[2]; |
if (::pipe(pipefd) < 0) |
throw Rexception("RtclSignalAction::<ctor>", "pipe() failed: ", errno); |
|
fFdPipeRead = pipefd[0]; |
fFdPipeWrite = pipefd[1]; |
|
fShuttleChn = Tcl_MakeFileChannel((ClientData)fFdPipeRead, TCL_READABLE); |
|
Tcl_SetChannelOption(NULL, fShuttleChn, "-buffersize", "64"); |
Tcl_SetChannelOption(NULL, fShuttleChn, "-encoding", "binary"); |
Tcl_SetChannelOption(NULL, fShuttleChn, "-translation", "binary"); |
|
Tcl_CreateChannelHandler(fShuttleChn, TCL_READABLE, |
(Tcl_FileProc*) ThunkTclChannelHandler, |
(ClientData) this); |
} |
|
//------------------------------------------+----------------------------------- |
//! Destructor |
|
RtclSignalAction::~RtclSignalAction() |
{ |
for (size_t i=0; i<32; i++) { |
RerrMsg emsg; |
if (fActionSet[i]) ClearAction(i, emsg); |
} |
} |
|
|
} // end namespace Retro |
/RtclBvi.cpp
0,0 → 1,260
// $Id: RtclBvi.cpp 521 2013-05-20 22:16:45Z 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-11-28 434 1.0.1 DoCmd(): use intptr_t cast for lp64 compatibility |
// 2011-03-27 374 1.0 Initial version |
// 2011-02-13 361 0.1 First draft |
// --------------------------------------------------------------------------- |
|
/*! |
\file |
\version $Id: RtclBvi.cpp 521 2013-05-20 22:16:45Z mueller $ |
\brief Implemenation of RtclBvi. |
*/ |
|
#include <ctype.h> |
#include <stdlib.h> |
#include <string.h> |
|
#include <iostream> |
|
#include "RtclBvi.hpp" |
#include "librtcltools/RtclOPtr.hpp" |
|
using namespace std; |
|
/*! |
\class Retro::RtclBvi |
\brief FIXME_docs |
*/ |
|
// all method definitions in namespace Retro |
namespace Retro { |
|
static const int kOK = TCL_OK; |
static const int kERR = TCL_ERROR; |
|
//------------------------------------------+----------------------------------- |
//! FIXME_docs |
|
void RtclBvi::CreateCmds(Tcl_Interp* interp) |
{ |
Tcl_CreateObjCommand(interp, "bvi", DoCmd, (ClientData) kStr2Int, NULL); |
Tcl_CreateObjCommand(interp, "pbvi", DoCmd, (ClientData) kInt2Str, NULL); |
return; |
} |
|
//------------------------------------------+----------------------------------- |
//! FIXME_docs |
|
int RtclBvi::DoCmd(ClientData cdata, Tcl_Interp* interp, int objc, |
Tcl_Obj* const objv[]) |
{ |
bool list = false; |
char form = 0; |
int nbit = 0; |
if (!CheckFormat(interp, objc, objv, list, form, nbit)) return kERR; |
|
//ConvMode mode = (ConvMode)((int) cdata); |
ConvMode mode = (ConvMode)((intptr_t) cdata); |
|
if (list) { |
int lobjc = 0; |
Tcl_Obj** lobjv = 0; |
if (Tcl_ListObjGetElements(interp, objv[2], &lobjc, &lobjv) != kOK) { |
return kERR; |
} |
|
RtclOPtr rlist(Tcl_NewListObj(0, NULL)); |
|
for (int i=0; i<lobjc; i++) { |
RtclOPtr rval(DoConv(interp, mode, lobjv[i], form, nbit)); |
if (!rval) return kERR; |
if (Tcl_ListObjAppendElement(interp, rlist, rval) != kOK) return kERR; |
} |
|
Tcl_SetObjResult(interp, rlist); |
|
} else { |
Tcl_Obj* rval = DoConv(interp, mode, objv[2], form, nbit); |
if (rval==0) return kERR; |
Tcl_SetObjResult(interp, rval); |
} |
|
return kOK; |
} |
|
//------------------------------------------+----------------------------------- |
//! FIXME_docs |
|
Tcl_Obj* RtclBvi::DoConv(Tcl_Interp* interp, ConvMode mode, Tcl_Obj* val, |
char form, int nbit) |
{ |
if (mode == kStr2Int) { |
const char* pval = Tcl_GetString(val); |
int lval = strlen(pval); |
|
// strip leading blanks |
while (pval[0]!=0 && ::isblank(pval[0])) { |
pval++; |
lval--; |
} |
// strip trailing blanks |
while (lval>0 && ::isblank(pval[lval-1])) { |
lval--; |
} |
|
// check for c"ddd" format |
if (lval>3 && pval[1]=='"' && pval[lval-1]=='"') { |
if (strchr("bBoOdDxX", pval[0]) == 0) { |
Tcl_AppendResult(interp, "-E: bad prefix in c'dddd' format string", |
NULL); |
return 0; |
} |
form = pval[0]; |
pval += 2; |
lval -= 3; |
// check for 0xddd format |
} else if (lval>2 && pval[0]=='0' && (pval[1]=='x' || pval[1]=='X')) { |
form = 'x'; |
pval += 2; |
lval -= 2; |
} |
|
int base = 0; |
switch (form) { |
case 'b': case 'B': base = 2; break; |
case 'o': case 'O': base = 8; break; |
case 'd': case 'D': base = 10; break; |
case 'x': case 'X': base = 16; break; |
} |
|
unsigned long lres=0; |
char* eptr=0; |
|
if (base==10 && pval[0]=='-') { |
lres = (unsigned long) ::strtol(pval, &eptr, base); |
if (nbit<32) lres &= (1ul<<nbit)-1; |
} else { |
lres = ::strtoul(pval, &eptr, base); |
} |
|
if (eptr != pval+lval) { |
Tcl_AppendResult(interp, "-E: conversion error in '", |
Tcl_GetString(val), "'", NULL); |
return 0; |
} |
|
if (lres > (1ul<<nbit)-1) { |
Tcl_AppendResult(interp, "-E: too many bits defined in '", |
Tcl_GetString(val), "'", NULL); |
return 0; |
} |
|
return Tcl_NewIntObj((int)lres); |
|
} else if (mode == kInt2Str) { |
int val_int; |
if (Tcl_GetIntFromObj(interp, val, &val_int) != kOK) return 0; |
int val_uint = (unsigned int) val_int; |
|
int nwidth = 1; |
if (form=='o' || form=='O') nwidth = 3; |
if (form=='x' || form=='X') nwidth = 4; |
unsigned int nmask = (1<<nwidth)-1; |
|
char buf[64]; |
char* pbuf = buf; |
if (form=='B' || form=='O' || form=='X') { |
*pbuf++ = tolower(form); |
*pbuf++ = '"'; |
} |
|
int ndig = (nbit+nwidth-1)/nwidth; |
for (int i=ndig-1; i>=0; i--) { |
unsigned int nibble = ((val_uint)>>(i*nwidth)) & nmask; |
nibble += (nibble <= 9) ? '0' : ('a'-10); |
*pbuf++ = (char) nibble; |
} |
|
if (form=='B' || form=='O' || form=='X') { |
*pbuf++ = '"'; |
} |
|
return Tcl_NewStringObj(buf, pbuf-buf); |
|
} else { |
Tcl_AppendResult(interp, "-E: BUG! bad cdata in RtclBvi::DoConv() call", |
NULL); |
} |
return 0; |
} |
|
//------------------------------------------+----------------------------------- |
//! FIXME_docs |
|
bool RtclBvi::CheckFormat(Tcl_Interp* interp, int objc, Tcl_Obj* const objv[], |
bool& list, char& form, int& nbit) |
{ |
list = false; |
form = 'b'; |
nbit = 0; |
|
if (objc != 3) { |
Tcl_WrongNumArgs(interp, 1, objv, "form arg"); |
return false; |
} |
|
const char* opt = Tcl_GetString(objv[1]); |
|
while(*opt != 0) { |
switch (*opt) { |
case 'b': |
case 'B': |
case 'o': |
case 'O': |
case 'x': |
case 'X': |
form = *opt; |
break; |
|
case 'l': |
list = true; |
break; |
|
default: |
if (*opt>='0' && *opt<='9') { |
nbit = 10*nbit + ((*opt) - '0'); |
if (nbit > 32) { |
Tcl_AppendResult(interp, "-E: invalid bvi format '", opt, "'", |
" bit count > 32", NULL); |
return false; |
} |
} else { |
Tcl_AppendResult(interp, "-E: invalid bvi format '", opt, "'", |
" allowed: [bBoOxXl][0-9]*", NULL); |
return false; |
} |
break; |
} |
opt++; |
} |
|
if (nbit==0) nbit=8; |
|
return true; |
} |
|
} // end namespace Retro |
/RtclSignalAction.hpp
0,0 → 1,77
// $Id: RtclSignalAction.hpp 521 2013-05-20 22:16:45Z mueller $ |
// |
// Copyright 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 |
// 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 |
// 2013-05-17 521 1.0 Initial version |
// --------------------------------------------------------------------------- |
|
/*! |
\file |
\version $Id: RtclSignalAction.hpp 521 2013-05-20 22:16:45Z mueller $ |
\brief Declaration of class RtclSignalAction. |
*/ |
|
#ifndef included_Retro_RtclSignalAction |
#define included_Retro_RtclSignalAction 1 |
|
// Note: on cpp environment _POSIX_C_SOURCE is already defined !! |
#include <signal.h> |
|
#include "tcl.h" |
|
#include "librtools/RerrMsg.hpp" |
#include "librtools/Rexception.hpp" |
#include "librtcltools/RtclOPtr.hpp" |
|
namespace Retro { |
|
class RtclSignalAction { |
public: |
|
static bool Init(Tcl_Interp* interp, RerrMsg& emsg); |
static RtclSignalAction* Obj(); |
|
bool SetAction(int signum, Tcl_Obj* pobj, RerrMsg& emsg); |
bool GetAction(int signum, Tcl_Obj*& pobj, RerrMsg& emsg); |
bool ClearAction(int signum, RerrMsg& emsg); |
|
protected: |
bool ValidSignal(int signum, RerrMsg& emsg); |
void TclChannelHandler(int mask); |
static void SignalHandler(int signum); |
static void ThunkTclChannelHandler(ClientData cdata, int mask); |
static void ThunkTclExitProc(ClientData cdata); |
|
private: |
RtclSignalAction(Tcl_Interp* interp); |
~RtclSignalAction(); |
|
protected: |
Tcl_Interp* fpInterp; //!< Tcl interpreter used |
int fFdPipeRead; //!< attn pipe read fd |
int fFdPipeWrite; //!< attn pipe write fd |
Tcl_Channel fShuttleChn; //!< Tcl channel |
bool fActionSet[32]; //!< true if SetAction() done |
RtclOPtr fpScript[32]; //!< action scripts |
struct sigaction fOldAction[32]; //!< original sigaction |
|
private: |
static RtclSignalAction* fpObj; //!< pointer to singleton |
}; |
|
} // end namespace Retro |
|
//#include "RtclSignalAction.ipp" |
|
#endif |
/Rutiltpp_Init.cpp
0,0 → 1,59
// $Id: Rutiltpp_Init.cpp 521 2013-05-20 22:16:45Z mueller $ |
// |
// 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 |
// 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 |
// 2013-05-17 512 1.0.3 add RtclSystem::CreateCmds() |
// 2013-02-10 485 1.0.2 remove Tcl_InitStubs() |
// 2011-03-20 372 1.0.1 renamed ..tcl -> ..tpp |
// 2011-03-19 371 1.0 Initial version |
// --------------------------------------------------------------------------- |
|
/*! |
\file |
\version $Id: Rutiltpp_Init.cpp 521 2013-05-20 22:16:45Z mueller $ |
\brief Implemenation of Rutiltpp_Init . |
*/ |
|
#include "tcl.h" |
|
#include <stdexcept> |
|
#include "RtclSystem.hpp" |
#include "RtclBvi.hpp" |
|
using namespace std; |
using namespace Retro; |
|
//------------------------------------------+----------------------------------- |
extern "C" int Rutiltpp_Init(Tcl_Interp* interp) |
{ |
int irc; |
|
// declare package name and version |
irc = Tcl_PkgProvide(interp, "rutiltpp", "1.0.0"); |
if (irc != TCL_OK) return irc; |
|
try { |
// register general commands |
RtclSystem::CreateCmds(interp); |
RtclBvi::CreateCmds(interp); |
return TCL_OK; |
|
} catch (exception& e) { |
Tcl_AppendResult(interp, "-E: exception caught in Rutiltpp_Init: '", |
e.what(), "'", NULL); |
} |
return TCL_ERROR; |
} |
|
/RtclSystem.cpp
0,0 → 1,231
// $Id: RtclSystem.cpp 521 2013-05-20 22:16:45Z mueller $ |
// |
// Copyright 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 |
// 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 |
// 2013-05-17 521 1.0 Initial version |
// --------------------------------------------------------------------------- |
|
/*! |
\file |
\version $Id: RtclSystem.cpp 521 2013-05-20 22:16:45Z mueller $ |
\brief Implemenation of RtclSystem. |
*/ |
|
#include <unistd.h> |
#include <errno.h> |
#include <string.h> |
#include <sys/types.h> |
#include <sys/wait.h> |
|
#include <iostream> |
#include <string> |
#include <algorithm> |
|
#include "librtools/RerrMsg.hpp" |
#include "librtcltools/RtclArgs.hpp" |
|
#include "RtclSignalAction.hpp" |
|
#include "RtclSystem.hpp" |
|
using namespace std; |
|
/*! |
\class Retro::RtclSystem |
\brief FIXME_docs |
*/ |
|
// all method definitions in namespace Retro |
namespace Retro { |
|
static const int kOK = TCL_OK; |
static const int kERR = TCL_ERROR; |
|
//------------------------------------------+----------------------------------- |
//! FIXME_docs |
|
void RtclSystem::CreateCmds(Tcl_Interp* interp) |
{ |
Tcl_CreateObjCommand(interp, "rutil::isatty", Isatty, |
(ClientData) 0, NULL); |
Tcl_CreateObjCommand(interp, "rutil::sigaction", SignalAction, |
(ClientData) 0, NULL); |
Tcl_CreateObjCommand(interp, "rutil::waitpid", WaitPid, |
(ClientData) 0, NULL); |
return; |
} |
|
//------------------------------------------+----------------------------------- |
//! FIXME_docs |
|
int RtclSystem::Isatty(ClientData cdata, Tcl_Interp* interp, |
int objc, Tcl_Obj* const objv[]) |
{ |
RtclArgs args(interp, objc, objv); |
string file = "stdin"; |
if (!args.GetArg("?file", file)) return kERR; |
if (!args.AllDone()) return kERR; |
|
transform(file.begin(), file.end(), file.begin(), ::tolower); |
int fileno = -1; |
if (file == "stdin") fileno = STDIN_FILENO; |
if (file == "stdout") fileno = STDOUT_FILENO; |
if (file == "stderr") fileno = STDERR_FILENO; |
if (fileno == -1) return args.Quit("file must be stdin, stdout, or stderr"); |
|
args.SetResult(bool(::isatty(fileno))); |
|
return kOK; |
} |
|
//------------------------------------------+----------------------------------- |
|
static int signam2num(const std::string& signam) |
{ |
string sn = signam; |
transform(sn.begin(), sn.end(), sn.begin(), ::toupper); |
if (sn == "SIGHUP") return SIGHUP; |
if (sn == "SIGINT") return SIGINT; |
if (sn == "SIGTERM") return SIGTERM; |
if (sn == "SIGUSR1") return SIGUSR1; |
if (sn == "SIGUSR2") return SIGUSR2; |
return -1; |
} |
|
static const char* signum2nam(int signum) |
{ |
if (signum == SIGHUP) return "SIGHUP"; |
if (signum == SIGINT) return "SIGINT"; |
if (signum == SIGTERM) return "SIGTERM"; |
if (signum == SIGUSR1) return "SIGUSR1"; |
if (signum == SIGUSR2) return "SIGUSR2"; |
return "???"; |
} |
|
//------------------------------------------+----------------------------------- |
//! FIXME_docs |
|
int RtclSystem::SignalAction(ClientData cdata, Tcl_Interp* interp, |
int objc, Tcl_Obj* const objv[]) |
{ |
RtclArgs args(interp, objc, objv); |
RerrMsg emsg; |
|
// check if initialized, if not, do it |
if (!RtclSignalAction::Obj()) { |
RerrMsg emsg; |
if (!RtclSignalAction::Init(interp, emsg)) return args.Quit(emsg); |
} |
RtclSignalAction* pact = RtclSignalAction::Obj(); |
|
// blank 'sigaction' is a noop (initialize as side effect) |
if (objc == 1) return kOK; |
|
// handle cases with only options (no signal name first) |
|
if (args.PeekArgString(0)[0] == '-') { |
static RtclNameSet optset("-init|-info"); |
string opt; |
if (args.NextOpt(opt, optset)) { |
|
if (opt == "-init") { // -init |
if (!args.AllDone()) return kERR; |
return kOK; |
|
} else if (opt == "-info") { // -info |
RtclOPtr pres(Tcl_NewListObj(0,0)); |
int siglist[] = {SIGHUP,SIGINT,SIGTERM,SIGUSR1,SIGUSR2}; |
for (size_t i=0; i<sizeof(siglist)/sizeof(int); i++) { |
Tcl_Obj* pobj; |
if (pact->GetAction(siglist[i], pobj, emsg)) { |
RtclOPtr pele(Tcl_NewListObj(0,0)); |
Tcl_ListObjAppendElement(NULL, pele, |
Tcl_NewStringObj(signum2nam(siglist[i]),-1)); |
if (pobj) { |
Tcl_ListObjAppendElement(NULL, pele, pobj); |
} else { |
Tcl_ListObjAppendElement(NULL, pele, Tcl_NewStringObj("{}",-1)); |
} |
Tcl_ListObjAppendElement(NULL, pres, pele); |
} |
} |
args.SetResult(pres); |
return kOK; |
} |
} |
if (!args.OptValid()) return kERR; |
if (!args.AllDone()) return kERR; |
return kERR; |
} |
|
// handle cases which start with a signal name |
|
string signam; |
if (!args.GetArg("signam", signam)) return kERR; |
int signum = signam2num(signam); |
if (signum < 0) return args.Quit("invalid signal name"); |
|
static RtclNameSet optset("-action|-revert"); |
string opt; |
if (args.NextOpt(opt, optset)) { |
if (opt == "-action") { // signam -action script |
string script; |
if (!args.GetArg("script", script)) return kERR; |
if (!args.AllDone()) return kERR; |
RtclOPtr pobj(Tcl_NewStringObj(script.c_str(), -1)); |
if (!pact->SetAction(signum, pobj, emsg)) |
return args.Quit(emsg); |
|
} else if (opt == "-revert") { // signam -revert |
if (!args.AllDone()) return kERR; |
if (!pact->ClearAction(signum, emsg)) |
return args.Quit(emsg); |
} |
|
} else { // signam |
if (!args.OptValid()) return kERR; |
if (!args.AllDone()) return kERR; |
Tcl_Obj* pobj; |
if (!pact->GetAction(signum, pobj, emsg)) |
return args.Quit("no handler defined"); |
if (pobj == 0) pobj = Tcl_NewStringObj("{}",-1); |
args.SetResult(pobj); |
} |
|
return kOK; |
} |
|
//------------------------------------------+----------------------------------- |
//! FIXME_docs |
|
int RtclSystem::WaitPid(ClientData cdata, Tcl_Interp* interp, |
int objc, Tcl_Obj* const objv[]) |
{ |
RtclArgs args(interp, objc, objv); |
int pid; |
if (!args.GetArg("pid", pid)) return kERR; |
if (!args.AllDone()) return kERR; |
|
int status; |
int irc = ::waitpid(pid, &status, WNOHANG); |
if (irc < 0) { |
RerrMsg emsg("RtclSystem::WaitPid", "waitpid() failed: ", errno); |
return args.Quit(emsg); |
} |
args.SetResult(status); |
return kOK; |
} |
|
|
} // end namespace Retro |
/Makefile
0,0 → 1,64
# $Id: Makefile 529 2013-08-02 17:15:43Z mueller $ |
# |
# Revision History: |
# Date Rev Version Comment |
# 2013-02-01 479 1.1.2 use checkpath_cpp.mk |
# 2012-12-24 464 1.1.1 add TCLINC |
# 2011-07-31 401 1.1 rename realclean->distclean |
# 2011-07-01 386 1.0.2 add BOOSTINC |
# 2011-03-20 372 1.0.1 renamed ..tcl -> ..tpp |
# 2011-03-19 371 1.0 Initial version |
#--- |
# |
# Name of the sharable library |
# |
SONAME = rutiltpp |
SOMAJV = 1 |
SOMINV = 0 |
# |
# Compile and Link search paths |
# |
include ../checkpath_cpp.mk |
# |
INCLFLAGS = -I${RETROBASE}/tools/src -I${TCLINC} -I${BOOSTINC} |
LDLIBS = -lpthread |
LDLIBS += -L${RETROBASE}/tools/lib -lrtcltools |
# |
# Object files to be included |
# |
OBJ_all = Rutiltpp_Init.o RtclBvi.o RtclSystem.o RtclSignalAction.o |
# |
DEP_all = $(OBJ_all:.o=.dep) |
# |
#- generic part ---------------------------------------------------------------- |
# |
SOFILE = lib$(SONAME).so |
SOFILEV = lib$(SONAME).so.$(SOMAJV) |
SOFILEVV = lib$(SONAME).so.$(SOMAJV).$(SOMINV) |
# |
include $(RETROBASE)/tools/make/generic_cpp.mk |
include $(RETROBASE)/tools/make/generic_dep.mk |
include $(RETROBASE)/tools/make/generic_so.mk |
include $(RETROBASE)/tools/make/dontincdep.mk |
# |
# The magic auto-dependency include |
# |
ifndef DONTINCDEP |
include $(DEP_all) |
endif |
# |
# cleanup phonies: |
# |
.PHONY : clean cleandep distclean |
clean : |
@ rm -f $(OBJ_all) |
@ echo "Object files removed" |
# |
cleandep : |
@ rm -f $(DEP_all) |
@ echo "Dependency files removed" |
# |
distclean : clean cleandep |
@ rm -f $(SOPATH)/lib$(SONAME).a $(SOPATH)/lib$(SONAME).so* |
@ echo "Libraries removed" |
# |
/RtclBvi.hpp
0,0 → 1,54
// $Id: RtclBvi.hpp 486 2013-02-10 22:34:43Z 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-27 374 1.0 Initial version |
// 2011-02-18 362 0.1 First draft |
// --------------------------------------------------------------------------- |
|
/*! |
\file |
\version $Id: RtclBvi.hpp 486 2013-02-10 22:34:43Z mueller $ |
\brief Declaration of class RtclBvi. |
*/ |
|
#ifndef included_Retro_RtclBvi |
#define included_Retro_RtclBvi 1 |
|
#include "tcl.h" |
|
namespace Retro { |
|
class RtclBvi { |
public: |
static void CreateCmds(Tcl_Interp* interp); |
|
protected: |
enum ConvMode {kStr2Int = 0, |
kInt2Str}; |
|
static int DoCmd(ClientData cdata, Tcl_Interp* interp, |
int objc, Tcl_Obj* const objv[]); |
static Tcl_Obj* DoConv(Tcl_Interp* interp, ConvMode mode, Tcl_Obj* val, |
char form, int nbit); |
static bool CheckFormat(Tcl_Interp* interp, int objc, |
Tcl_Obj* const objv[], bool& list, |
char& form, int& nbit); |
}; |
|
} // end namespace Retro |
|
//#include "RtclBvi.ipp" |
|
#endif |
/.cvsignore
0,0 → 1,54
*.dep |
.
Property changes :
Added: svn:ignore
## -0,0 +1,33 ##
+*.dep_ghdl
+*.dep_isim
+*.dep_xst
+work-obj93.cf
+*.vcd
+*.ghw
+*.sav
+*.tmp
+*.exe
+ise
+xflow.his
+*.ngc
+*.ncd
+*.pcf
+*.bit
+*.msk
+isim
+isim.log
+isim.wdb
+fuse.log
+*_[sft]sim.vhd
+*_tsim.sdf
+*_xst.log
+*_tra.log
+*_twr.log
+*_map.log
+*_par.log
+*_pad.log
+*_bgn.log
+*_svn.log
+*_sum.log
+*_[dsft]sim.log
+*.dep