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

Subversion Repositories w11

[/] [w11/] [tags/] [w11a_V0.7/] [tools/] [src/] [librutiltpp/] [RtclBvi.cpp] - Blame information for rev 33

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 29 wfjm
// $Id: RtclBvi.cpp 632 2015-01-11 12:30:03Z mueller $
2 10 wfjm
//
3 27 wfjm
// Copyright 2011-2014 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
4 10 wfjm
//
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 27 wfjm
// 2014-08-22   584   1.0.2  use nullptr
17 15 wfjm
// 2011-11-28   434   1.0.1  DoCmd(): use intptr_t cast for lp64 compatibility
18 10 wfjm
// 2011-03-27   374   1.0    Initial version
19
// 2011-02-13   361   0.1    First draft
20
// ---------------------------------------------------------------------------
21
 
22
/*!
23
  \file
24 29 wfjm
  \version $Id: RtclBvi.cpp 632 2015-01-11 12:30:03Z mueller $
25 10 wfjm
  \brief   Implemenation of RtclBvi.
26
*/
27
 
28
#include <ctype.h>
29
#include <stdlib.h>
30
#include <string.h>
31
 
32
#include <iostream>
33
 
34
#include "RtclBvi.hpp"
35
#include "librtcltools/RtclOPtr.hpp"
36
 
37
using namespace std;
38
 
39
/*!
40
  \class Retro::RtclBvi
41 19 wfjm
  \brief FIXME_docs
42 10 wfjm
*/
43
 
44 19 wfjm
// all method definitions in namespace Retro
45
namespace Retro {
46
 
47 10 wfjm
static const int kOK  = TCL_OK;
48
static const int kERR = TCL_ERROR;
49
 
50
//------------------------------------------+-----------------------------------
51 19 wfjm
//! FIXME_docs
52 10 wfjm
 
53
void RtclBvi::CreateCmds(Tcl_Interp* interp)
54
{
55 27 wfjm
  Tcl_CreateObjCommand(interp,  "bvi", DoCmd, (ClientData) kStr2Int, nullptr);
56
  Tcl_CreateObjCommand(interp, "pbvi", DoCmd, (ClientData) kInt2Str, nullptr);
57 10 wfjm
  return;
58
}
59
 
60
//------------------------------------------+-----------------------------------
61 19 wfjm
//! FIXME_docs
62 10 wfjm
 
63
int RtclBvi::DoCmd(ClientData cdata, Tcl_Interp* interp, int objc,
64
                   Tcl_Obj* const objv[])
65
{
66
  bool list = false;
67
  char form = 0;
68
  int nbit  = 0;
69
  if (!CheckFormat(interp, objc, objv, list, form, nbit)) return kERR;
70
 
71 15 wfjm
  //ConvMode mode = (ConvMode)((int) cdata);
72
  ConvMode mode = (ConvMode)((intptr_t) cdata);
73 10 wfjm
 
74
  if (list) {
75
    int lobjc = 0;
76 29 wfjm
    Tcl_Obj** lobjv = nullptr;
77 10 wfjm
    if (Tcl_ListObjGetElements(interp, objv[2], &lobjc, &lobjv) != kOK) {
78
      return kERR;
79
    }
80
 
81 27 wfjm
    RtclOPtr rlist(Tcl_NewListObj(0, nullptr));
82 10 wfjm
 
83
    for (int i=0; i<lobjc; i++) {
84
      RtclOPtr rval(DoConv(interp, mode, lobjv[i], form, nbit));
85
      if (!rval) return kERR;
86
      if (Tcl_ListObjAppendElement(interp, rlist, rval) != kOK) return kERR;
87
    }
88
 
89
    Tcl_SetObjResult(interp, rlist);
90
 
91
  } else {
92
    Tcl_Obj* rval = DoConv(interp, mode, objv[2], form, nbit);
93
    if (rval==0) return kERR;
94
    Tcl_SetObjResult(interp, rval);
95
  }
96
 
97
  return kOK;
98
}
99
 
100
//------------------------------------------+-----------------------------------
101 19 wfjm
//! FIXME_docs
102 10 wfjm
 
103
Tcl_Obj* RtclBvi::DoConv(Tcl_Interp* interp, ConvMode mode, Tcl_Obj* val,
104
                         char form, int nbit)
105
{
106
  if (mode == kStr2Int) {
107
    const char* pval = Tcl_GetString(val);
108
    int lval = strlen(pval);
109
 
110
    // strip leading blanks
111 22 wfjm
    while (pval[0]!=0 && ::isblank(pval[0])) {
112 10 wfjm
      pval++;
113
      lval--;
114
    }
115
    // strip trailing blanks
116 22 wfjm
    while (lval>0 && ::isblank(pval[lval-1])) {
117 10 wfjm
      lval--;
118
    }
119
 
120
    // check for c"ddd" format
121
    if (lval>3 && pval[1]=='"' && pval[lval-1]=='"') {
122
      if (strchr("bBoOdDxX", pval[0]) == 0) {
123 19 wfjm
        Tcl_AppendResult(interp, "-E: bad prefix in c'dddd' format string",
124 27 wfjm
                         nullptr);
125 10 wfjm
        return 0;
126
      }
127
      form = pval[0];
128
      pval += 2;
129
      lval -= 3;
130
    // check for 0xddd format
131
    } else if (lval>2 && pval[0]=='0' && (pval[1]=='x' || pval[1]=='X')) {
132
      form = 'x';
133
      pval += 2;
134
      lval -= 2;
135
    }
136
 
137
    int base = 0;
138
    switch (form) {
139
      case 'b': case 'B':  base =  2; break;
140
      case 'o': case 'O':  base =  8; break;
141
      case 'd': case 'D':  base = 10; break;
142
      case 'x': case 'X':  base = 16; break;
143
    }
144
 
145
    unsigned long lres=0;
146
    char* eptr=0;
147
 
148
    if (base==10 && pval[0]=='-') {
149 22 wfjm
      lres = (unsigned long) ::strtol(pval, &eptr, base);
150 10 wfjm
      if (nbit<32) lres &= (1ul<<nbit)-1;
151
    } else {
152 22 wfjm
      lres = ::strtoul(pval, &eptr, base);
153 10 wfjm
    }
154
 
155
    if (eptr != pval+lval) {
156
      Tcl_AppendResult(interp, "-E: conversion error in '",
157 27 wfjm
                       Tcl_GetString(val), "'", nullptr);
158 10 wfjm
      return 0;
159
    }
160
 
161
    if (lres > (1ul<<nbit)-1) {
162
      Tcl_AppendResult(interp, "-E: too many bits defined in '",
163 27 wfjm
                       Tcl_GetString(val), "'", nullptr);
164 10 wfjm
      return 0;
165
    }
166
 
167
    return Tcl_NewIntObj((int)lres);
168
 
169
  } else if (mode == kInt2Str) {
170
    int val_int;
171
    if (Tcl_GetIntFromObj(interp, val, &val_int)  != kOK) return 0;
172
    int val_uint = (unsigned int) val_int;
173
 
174
    int nwidth = 1;
175
    if (form=='o' || form=='O') nwidth = 3;
176
    if (form=='x' || form=='X') nwidth = 4;
177
    unsigned int nmask = (1<<nwidth)-1;
178
 
179
    char buf[64];
180
    char* pbuf = buf;
181
    if (form=='B' || form=='O' || form=='X') {
182
      *pbuf++ = tolower(form);
183
      *pbuf++ = '"';
184
    }
185
 
186
    int ndig = (nbit+nwidth-1)/nwidth;
187
    for (int i=ndig-1; i>=0; i--) {
188
      unsigned int nibble = ((val_uint)>>(i*nwidth)) & nmask;
189
      nibble += (nibble <= 9) ? '0' : ('a'-10);
190
      *pbuf++ = (char) nibble;
191
    }
192
 
193
    if (form=='B' || form=='O' || form=='X') {
194
      *pbuf++ = '"';
195
    }
196
 
197
    return Tcl_NewStringObj(buf, pbuf-buf);
198
 
199
  } else {
200
    Tcl_AppendResult(interp, "-E: BUG! bad cdata in RtclBvi::DoConv() call",
201 27 wfjm
                     nullptr);
202 10 wfjm
  }
203
  return 0;
204
}
205
 
206
//------------------------------------------+-----------------------------------
207 19 wfjm
//! FIXME_docs
208 10 wfjm
 
209
bool RtclBvi::CheckFormat(Tcl_Interp* interp, int objc, Tcl_Obj* const objv[],
210
                          bool& list, char& form, int& nbit)
211
{
212
  list = false;
213
  form = 'b';
214
  nbit = 0;
215
 
216
  if (objc != 3) {
217
    Tcl_WrongNumArgs(interp, 1, objv, "form arg");
218
    return false;
219
  }
220
 
221
  const char* opt = Tcl_GetString(objv[1]);
222
 
223
  while(*opt != 0) {
224
    switch (*opt) {
225
    case 'b':
226
    case 'B':
227
    case 'o':
228
    case 'O':
229
    case 'x':
230
    case 'X':
231
      form = *opt;
232
      break;
233
 
234
    case 'l':
235
      list = true;
236
      break;
237
 
238
    default:
239
      if (*opt>='0' && *opt<='9') {
240
        nbit = 10*nbit + ((*opt) - '0');
241
        if (nbit > 32) {
242 19 wfjm
          Tcl_AppendResult(interp, "-E: invalid bvi format '", opt, "'",
243 27 wfjm
                           " bit count > 32", nullptr);
244 10 wfjm
          return false;
245
        }
246
      } else {
247 19 wfjm
        Tcl_AppendResult(interp, "-E: invalid bvi format '", opt, "'",
248 27 wfjm
                         " allowed: [bBoOxXl][0-9]*", nullptr);
249 10 wfjm
        return false;
250
      }
251
      break;
252
    }
253
    opt++;
254
  }
255
 
256
  if (nbit==0) nbit=8;
257
 
258
  return true;
259
}
260
 
261 19 wfjm
} // end namespace Retro

powered by: WebSVN 2.1.0

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