OpenCores
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

powered by: WebSVN 2.1.0

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