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

Subversion Repositories w11

[/] [w11/] [tags/] [w11a_V0.7/] [tools/] [src/] [librtcltools/] [RtclArgs.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: RtclArgs.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-26   373   1.0.4  add GetArg(float/double)
17
// 2011-03-13   369   1.0.3  add GetArg(vector<unit8_t>); NextOpt clear NOptMiss
18
// 2011-03-06   367   1.0.2  add Config() methods;
19
// 2011-03-05   366   1.0.1  fObjc,fNDone now size_t; add NDone(), SetResult();
20
//                           add GetArg(Tcl_Obj), PeekArgString();
21
// 2011-02-26   364   1.0    Initial version
22
// 2011-02-11   360   0.1    First draft
23
// ---------------------------------------------------------------------------
24
 
25
/*!
26
  \file
27
  \version $Id: RtclArgs.cpp 374 2011-03-27 17:02:47Z mueller $
28
  \brief   Implemenation of RtclArgs.
29
*/
30
 
31
//debug
32
#include <iostream>
33
 
34
#include <ctype.h>
35
#include <stdarg.h>
36
 
37
#include <stdexcept>
38
 
39
#include "RtclArgs.hpp"
40
#include "Rtcl.hpp"
41
 
42
using namespace std;
43
using namespace Retro;
44
 
45
/*!
46
  \class Retro::RtclArgs
47
  \brief FIXME_docs
48
*/
49
 
50
//------------------------------------------+-----------------------------------
51
//! Default constructor
52
 
53
RtclArgs::RtclArgs()
54
  : fpInterp(0),
55
    fObjc(0),
56
    fObjv(0),
57
    fNDone(0),
58
    fNOptMiss(0),
59
    fNConfigRead(0),
60
    fOptErr(false),
61
    fArgErr(false)
62
{}
63
 
64
//------------------------------------------+-----------------------------------
65
//! FIXME_docs
66
 
67
RtclArgs::RtclArgs(Tcl_Interp* interp, int objc, Tcl_Obj* const objv[],
68
                   size_t nskip)
69
  : fpInterp(interp),
70
    fObjc((size_t)objc),
71
    fObjv(objv),
72
    fNDone((nskip<=(size_t)objc) ? nskip : (size_t)objc),
73
    fNOptMiss(0),
74
    fNConfigRead(0),
75
    fOptErr(false),
76
    fArgErr(false)
77
{
78
  if (objc < 0)
79
    throw invalid_argument("RtclArgs::ctor: objc must be >= 0");
80
}
81
 
82
//------------------------------------------+-----------------------------------
83
//! FIXME_docs
84
 
85
RtclArgs::RtclArgs(const RtclArgs& rhs)
86
  : fpInterp(rhs.fpInterp),
87
    fObjc(rhs.fObjc),
88
    fObjv(rhs.fObjv),
89
    fNDone(rhs.fNDone),
90
    fNOptMiss(rhs.fNOptMiss),
91
    fOptErr(rhs.fOptErr),
92
    fArgErr(rhs.fArgErr)
93
{}
94
 
95
//------------------------------------------+-----------------------------------
96
//! Destructor
97
 
98
RtclArgs::~RtclArgs()
99
{}
100
 
101
//------------------------------------------+-----------------------------------
102
//! FIXME_docs
103
 
104
Tcl_Obj* RtclArgs::Objv(size_t ind) const
105
{
106
  if (ind >= (size_t)fObjc)
107
    throw out_of_range("RtclArgs::Objv: index out-of-range");
108
  return fObjv[ind];
109
}
110
 
111
//------------------------------------------+-----------------------------------
112
//! FIXME_docs
113
 
114
bool RtclArgs::GetArg(const char* name, Tcl_Obj*& pval)
115
{
116
  Tcl_Obj* pobj;
117
  if (!NextArg(name, pobj)) return false;
118
  if (pobj==0) return true;
119
  pval = pobj;
120
  return true;
121
}
122
 
123
//------------------------------------------+-----------------------------------
124
//! FIXME_docs
125
 
126
bool RtclArgs::GetArg(const char* name, const char*& val)
127
{
128
  Tcl_Obj* pobj;
129
  if (!NextArg(name, pobj)) return false;
130
  if (pobj==0) return true;
131
  val = Tcl_GetString(pobj);
132
  return true;
133
}
134
 
135
//------------------------------------------+-----------------------------------
136
//! FIXME_docs
137
 
138
bool RtclArgs::GetArg(const char* name, std::string& val)
139
{
140
  Tcl_Obj* pobj;
141
  if (!NextArg(name, pobj)) return false;
142
  if (pobj==0) return true;
143
  val = Tcl_GetString(pobj);
144
  return true;
145
}
146
 
147
//------------------------------------------+-----------------------------------
148
//! FIXME_docs
149
 
150
bool RtclArgs::GetArg(const char* name, int8_t& val, int8_t min, int8_t max)
151
{
152
  int32_t val32 = (int32_t)val;
153
  bool ret = GetArg(name, val32, (int32_t)min, (int32_t)max);
154
  val = (int8_t) val32;
155
  return ret;
156
}
157
 
158
//------------------------------------------+-----------------------------------
159
//! FIXME_docs
160
 
161
bool RtclArgs::GetArg(const char* name, uint8_t& val, uint8_t max, uint8_t min)
162
{
163
  uint32_t val32 = (uint32_t)val;
164
  bool ret = GetArg(name, val32, (uint32_t)max, (uint32_t)min);
165
  val = (uint8_t) val32;
166
  return ret;
167
}
168
 
169
//------------------------------------------+-----------------------------------
170
//! FIXME_docs
171
 
172
bool RtclArgs::GetArg(const char* name, int16_t& val, int16_t min, int16_t max)
173
{
174
  int32_t val32 = (int32_t)val;
175
  bool ret = GetArg(name, val32, (int32_t)min, (int32_t)max);
176
  val = (int16_t) val32;
177
  return ret;
178
}
179
 
180
//------------------------------------------+-----------------------------------
181
//! FIXME_docs
182
 
183
bool RtclArgs::GetArg(const char* name, uint16_t& val, uint16_t max,
184
                      uint16_t min)
185
{
186
  uint32_t val32 = (uint32_t)val;
187
  bool ret = GetArg(name, val32, (uint32_t)max, (uint32_t)min);
188
  val = (uint16_t) val32;
189
  return ret;
190
}
191
 
192
//------------------------------------------+-----------------------------------
193
//! FIXME_docs
194
 
195
bool RtclArgs::GetArg(const char* name, int32_t& val, int32_t min, int32_t max)
196
{
197
  Tcl_Obj* pobj;
198
  if (!NextArg(name, pobj)) return false;
199
  if (pobj==0) return true;
200
  int objval;
201
  if (Tcl_GetIntFromObj(fpInterp, pobj, &objval) != TCL_OK) return false;
202
  if (objval < min || objval > max) {
203
    ostringstream sos;
204
    sos << "-E: value '" << objval << "' for '" << name << "' out of range "
205
        << min << "..." << max;
206
    AppendResult(sos);
207
    return false;
208
  }
209
  val = (int32_t) objval;
210
  return true;
211
}
212
 
213
//------------------------------------------+-----------------------------------
214
//! FIXME_docs
215
 
216
bool RtclArgs::GetArg(const char* name, uint32_t& val, uint32_t max,
217
                      uint32_t min)
218
{
219
  Tcl_Obj* pobj;
220
  if (!NextArg(name, pobj)) return false;
221
  if (pobj==0) return true;
222
  int objval;
223
  if (Tcl_GetIntFromObj(fpInterp, pobj, &objval) != TCL_OK) return false;
224
  unsigned int objuval = objval;
225
  if (objuval < min || objuval > max) {
226
    ostringstream sos;
227
    sos << "-E: value '" << objuval << "' for '" << name << "' out of range "
228
        << min << "..." << max;
229
    AppendResult(sos);
230
    return false;
231
  }
232
  val = (uint32_t) objval;
233
  return true;
234
}
235
 
236
//------------------------------------------+-----------------------------------
237
//! FIXME_docs
238
 
239
bool RtclArgs::GetArg(const char* name, float& val, float min, float max)
240
{
241
  double vald = (double)val;
242
  bool ret = GetArg(name, vald, (double)max, (double)min);
243
  val = (float) vald;
244
  return ret;
245
}
246
 
247
//------------------------------------------+-----------------------------------
248
//! FIXME_docs
249
 
250
bool RtclArgs::GetArg(const char* name, double& val, double min, double max)
251
{
252
  Tcl_Obj* pobj;
253
  if (!NextArg(name, pobj)) return false;
254
  if (pobj==0) return true;
255
  double objval;
256
  if (Tcl_GetDoubleFromObj(fpInterp, pobj, &objval) != TCL_OK) return false;
257
  if (objval < min || objval > max) {
258
    ostringstream sos;
259
    sos << "-E: value '" << objval << "' for '" << name << "' out of range "
260
        << min << "..." << max;
261
    AppendResult(sos);
262
    return false;
263
  }
264
  val = objval;
265
  return true;
266
}
267
 
268
//------------------------------------------+-----------------------------------
269
//! FIXME_docs
270
 
271
bool RtclArgs::GetArg(const char* name, std::vector<uint8_t>& val,
272
                      size_t lmin, size_t lmax)
273
{
274
  int objc = 0;
275
  Tcl_Obj** objv = 0;
276
  if (!NextArgList(name, objc, objv, lmin, lmax)) return false;
277
  if (objv==0) return true;
278
 
279
  val.clear();
280
  val.reserve(objc);
281
 
282
  for (int i=0; i<objc; i++) {
283
    int ival;
284
    if (Tcl_GetIntFromObj(fpInterp, objv[i], &ival) != TCL_OK) return false;
285
    int ivalmsb = ival>>8;
286
    if (ivalmsb != 0 && ivalmsb != -1) {
287
      ostringstream sos;
288
      sos << "-E: list element '" << Tcl_GetString(objv[i])
289
          << "' for '" << name
290
          << "' out of range " << "0...0xff";
291
      AppendResult(sos);
292
      return false;
293
    }
294
    val.push_back((uint8_t)ival);
295
  }
296
  return true;
297
}
298
 
299
//------------------------------------------+-----------------------------------
300
//! FIXME_docs
301
 
302
bool RtclArgs::GetArg(const char* name, std::vector<uint16_t>& val,
303
                      size_t lmin, size_t lmax)
304
{
305
  int objc = 0;
306
  Tcl_Obj** objv = 0;
307
  if (!NextArgList(name, objc, objv, lmin, lmax)) return false;
308
  if (objv==0) return true;
309
 
310
  val.clear();
311
  val.reserve(objc);
312
 
313
  for (int i=0; i<objc; i++) {
314
    int ival;
315
    if (Tcl_GetIntFromObj(fpInterp, objv[i], &ival) != TCL_OK) return false;
316
    int ivalmsb = ival>>16;
317
    if (ivalmsb != 0 && ivalmsb != -1) {
318
      ostringstream sos;
319
      sos << "-E: list element '" << Tcl_GetString(objv[i])
320
          << "' for '" << name
321
          << "' out of range " << "0...0xffff";
322
      AppendResult(sos);
323
      return false;
324
    }
325
    val.push_back((uint16_t)ival);
326
  }
327
  return true;
328
}
329
 
330
//------------------------------------------+-----------------------------------
331
//! FIXME_docs
332
 
333
bool RtclArgs::Config(const char* name, std::string& val)
334
{
335
  ConfigNameCheck(name);
336
  string tmp = val;
337
  if (!GetArg(name, tmp)) return false;
338
  if (fNOptMiss == 0) {                     // config write
339
    val = tmp;
340
  } else {                                  // config read
341
    if (!ConfigReadCheck()) return false;
342
    SetResult(Tcl_NewStringObj(val.data(), val.length()));
343
  }
344
  return true;
345
}
346
 
347
//------------------------------------------+-----------------------------------
348
//! FIXME_docs
349
 
350
bool RtclArgs::Config(const char* name, uint32_t& val, uint32_t max,
351
                      uint32_t min)
352
{
353
  ConfigNameCheck(name);
354
  uint32_t tmp = val;
355
  if (!GetArg(name, tmp, max, min)) return false;
356
  if (fNOptMiss == 0) {                     // config write
357
    val = tmp;
358
  } else {                                  // config read
359
    if (!ConfigReadCheck()) return false;
360
    SetResult(Tcl_NewIntObj((int)val));
361
  }
362
  return true;
363
}
364
 
365
//------------------------------------------+-----------------------------------
366
//! FIXME_docs
367
 
368
bool RtclArgs::NextOpt(std::string& val)
369
{
370
  fNOptMiss = 0;
371
  val.clear();
372
  fOptErr = false;
373
 
374
  if (fNDone == fObjc) return false;
375
 
376
  const char* str = PeekArgString(0);
377
 
378
  if (str[0]=='-' && str[1] && !isdigit(str[1])) {
379
    fNDone += 1;
380
    // '--' seen (eat it, and say no Opt's found)
381
    if (str[1]=='-' && str[2]==0) {
382
      return false;
383
    }
384
    val = str;
385
    return true;
386
  }
387
  return false;
388
}
389
 
390
//------------------------------------------+-----------------------------------
391
//! FIXME_docs
392
 
393
bool RtclArgs::NextOpt(std::string& val, RtclNameSet& optset)
394
{
395
  val.clear();
396
  string opt;
397
  if (!NextOpt(opt) || opt.empty()) return false;
398
 
399
  fOptErr = !optset.Check(fpInterp, val, opt);
400
  return !fOptErr;
401
}
402
 
403
//------------------------------------------+-----------------------------------
404
//! FIXME_docs
405
 
406
bool RtclArgs::AllDone()
407
{
408
  if (fArgErr || fOptErr) return false;
409
  if (fNDone < fObjc) {
410
    AppendResult("-E: superfluous arguments, first one \"",
411
                 Tcl_GetString(fObjv[fNDone]), "\"", NULL);
412
    return false;
413
  }
414
  return true;
415
}
416
 
417
//------------------------------------------+-----------------------------------
418
//! FIXME_docs
419
 
420
const char* RtclArgs::PeekArgString(int rind) const
421
{
422
  int ind = fNDone + rind;
423
  if (ind < 0 || ind >= (int)fObjc) return "";
424
  return Tcl_GetString(fObjv[ind]);
425
}
426
 
427
//------------------------------------------+-----------------------------------
428
//! FIXME_docs
429
 
430
void RtclArgs::AppendResult(const char* str, ...)
431
{
432
  Tcl_AppendResult(fpInterp, str, NULL);
433
  va_list ap;
434
  va_start (ap, str);
435
  Tcl_AppendResultVA(fpInterp, ap);
436
  va_end (ap);
437
  return;
438
}
439
 
440
//------------------------------------------+-----------------------------------
441
//! FIXME_docs
442
 
443
void RtclArgs::AppendResultLines(const std::string& str)
444
{
445
  Rtcl::AppendResultNewLines(fpInterp);
446
 
447
  if (str.length()>0 && str[str.length()-1]=='\n') {
448
    Tcl_AppendResult(fpInterp, str.substr(0,str.length()-1).c_str(), NULL);
449
  } else {
450
    Tcl_AppendResult(fpInterp, str.c_str(), NULL);
451
  }
452
  return;
453
}
454
 
455
//------------------------------------------+-----------------------------------
456
//! FIXME_docs
457
 
458
bool RtclArgs::NextArg(const char* name, Tcl_Obj*& pobj)
459
{
460
  pobj = 0;
461
 
462
  bool isopt    = name[0] == '?';
463
  bool isoptopt = isopt && (name[1] == '?');
464
 
465
  if (!isopt) fNOptMiss = 0;
466
 
467
  if (fNDone == fObjc) {
468
    if (!isopt) {
469
      AppendResult("-E: required argument \"", name, "\" missing", NULL);
470
      fArgErr = true;
471
      return false;
472
    }
473
    fNOptMiss += 1;
474
    return true;
475
  }
476
 
477
  // if %% arg peek in next arg and check that it's not an option
478
  if (isoptopt) {
479
    const char* nval = Tcl_GetString(fObjv[fNDone]);
480
    if (nval[0]=='-' && nval[1] && isalpha(nval[1])) {
481
      fNOptMiss += 1;
482
      return true;
483
    }
484
  }
485
 
486
  pobj = fObjv[fNDone++];
487
 
488
  return true;
489
}
490
 
491
//------------------------------------------+-----------------------------------
492
//! FIXME_docs
493
 
494
bool RtclArgs::NextArgList(const char* name, int& objc, Tcl_Obj**& objv,
495
                           size_t lmin, size_t lmax)
496
{
497
  objc = 0;
498
  objv = 0;
499
  Tcl_Obj* pobj = 0;
500
  if (!NextArg(name, pobj)) return false;
501
  if (pobj==0) return true;
502
 
503
  if (Tcl_ListObjGetElements(fpInterp, pobj, &objc, &objv) != TCL_OK) {
504
    return false;
505
  }
506
 
507
  if ((size_t)objc < lmin || (size_t)objc > lmax) {
508
    ostringstream sos;
509
    sos << "-E: list length '" << objc << "' for '" << name << "' out of range "
510
        << lmin << "..." << lmax;
511
    AppendResult(sos);
512
    return false;
513
  }
514
  return true;
515
}
516
 
517
//------------------------------------------+-----------------------------------
518
//! FIXME_docs
519
 
520
void RtclArgs::ConfigNameCheck(const char* name)
521
{
522
  if (name==0 || name[0]!='?' || name[1]!='?')
523
    throw invalid_argument("RtclArgs::Config(): name must start with ??");
524
  return;
525
}
526
 
527
//------------------------------------------+-----------------------------------
528
//! FIXME_docs
529
 
530
bool RtclArgs::ConfigReadCheck()
531
{
532
  if (fNConfigRead != 0) {
533
    SetResult(Tcl_NewObj());
534
    AppendResult("-E: only one config read allowed per command, \"",
535
                 PeekArgString(-1), "\" is second", NULL);
536
    return false;
537
  }
538
  fNConfigRead += 1;
539
  return true;
540
}
541
 
542
//------------------------------------------+-----------------------------------
543
#if (defined(Retro_NoInline) || defined(Retro_RtclArgs_NoInline))
544
#define inline
545
#include "RtclArgs.ipp"
546
#undef  inline
547
#endif

powered by: WebSVN 2.1.0

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