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

Subversion Repositories w11

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

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

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