• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

polserver / polserver / 13378462461

17 Feb 2025 08:59PM UTC coverage: 58.754% (+0.3%) from 58.475%
13378462461

push

github

web-flow
Add support for sequence and index bindings (#760)

* update grammar

* add ast nodes; ast building

* Rename to unpacking

* semantic analysis

* executor work part 1, unpacking indices

* renamings; implement index binding

* small cleanup

* use multi_index; more tests

* use multi_index only for rest, otherwise list

* initial formatting

* add missing token decoding

* address self-review comments

* formatting tweaks

* add test for var binding in classes

* add StringIterator

* fix spread tests

* add cfgfile iterator; add cfgelem opersubscript; tests

* add iterator for SQLResultSet and SQLRow; tests

* Copy value in take global/local

* Allow any iterable can index rest unpacking
Always use dictionary as rest object in index unpacking

* add docs, core-changes, doc tests

* formatting changes...

* address self-review comments

* update formatter, format all binding test srcs

* address review comments
- unset var scope

* add cfgfile/cfgelem docs

* reformat objref svg

501 of 550 new or added lines in 19 files covered. (91.09%)

14 existing lines in 3 files now uncovered.

42235 of 71885 relevant lines covered (58.75%)

377989.47 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

48.2
/pol-core/pol/module/cfgmod.cpp
1
/** @file
2
 *
3
 * @par History
4
 * - 2005/07/04 Shinigami: mf_AppendConfigFileElem will reload file
5
 * - 2006/09/26 Shinigami: GCC 3.4.x fix - added "template<>" to TmplExecutorModule
6
 */
7

8

9
#include "cfgmod.h"
10
#include <ctype.h>
11
#include <fstream>
12
#include <string>
13
#include <utility>
14

15
#include "../../bscript/berror.h"
16
#include "../../bscript/bobject.h"
17
#include "../../bscript/bstruct.h"
18
#include "../../bscript/contiter.h"
19
#include "../../bscript/dict.h"
20
#include "../../bscript/execmodl.h"
21
#include "../../bscript/executor.h"
22
#include "../../bscript/impstr.h"
23
#include "../../bscript/objmembers.h"
24
#include "../../clib/rawtypes.h"
25
#include "../../clib/refptr.h"
26
#include "../../clib/strutil.h"
27
#include "../../plib/pkg.h"
28
#include "../cfgrepos.h"
29

30
#include <module_defs/cfgfile.h>
31

32
namespace Pol
33
{
34
namespace Module
35
{
36
}
37
namespace Module
38
{
39
Bscript::BApplicObjType cfgfile_type;
40
Bscript::BApplicObjType cfgelem_type;
41

42

43
EConfigFileRefObjImp::EConfigFileRefObjImp( ref_ptr<Core::StoredConfigFile> rcfile )
20✔
44
    : EConfigFileRefObjImpBase( &cfgfile_type, rcfile )
20✔
45
{
46
}
20✔
47

48
class ConfigFileIterator final : public Bscript::ContIterator
49
{
50
public:
51
  ConfigFileIterator( EConfigFileRefObjImp* node, Bscript::BObject* pIter );
52
  virtual Bscript::BObject* step() override;
53

54
private:
55
  Bscript::BObject m_ConfigObj;
56
  EConfigFileRefObjImp* node;
57
  Bscript::BObjectRef m_IterVal;
58
  Core::StoredConfigFile::ElementsByName::const_iterator name_itr;
59
};
60

61
ConfigFileIterator::ConfigFileIterator( EConfigFileRefObjImp* node, Bscript::BObject* pIter )
4✔
62
    : ContIterator(),
63
      m_ConfigObj( node ),
4✔
64
      node( node ),
4✔
65
      m_IterVal( pIter ),
4✔
66
      name_itr( node->obj_->elements_byname_.begin() )
8✔
67
{
68
}
4✔
69

70
Bscript::BObject* ConfigFileIterator::step()
24✔
71
{
72
  if ( name_itr == node->obj_->byname_end() )
24✔
73
    return nullptr;
4✔
74

75
  m_IterVal->setimp( new Bscript::String( name_itr->first ) );
20✔
76
  auto res = std::make_unique<Bscript::BObject>( new EConfigElemRefObjImp( name_itr->second ) );
20✔
77
  ++name_itr;
20✔
78
  return res.release();
20✔
79
}
20✔
80

81
Bscript::ContIterator* EConfigFileRefObjImp::createIterator( Bscript::BObject* pIterVal )
4✔
82
{
83
  return new ConfigFileIterator( this, pIterVal );
4✔
84
}
85

86
Bscript::BObjectRef EConfigFileRefObjImp::OperSubscript( const Bscript::BObject& obj )
4✔
87
{
88
  const Bscript::BObjectImp& imp = obj.impref();
4✔
89
  ref_ptr<Core::StoredConfigElem> celem;
4✔
90

91
  if ( imp.isa( OTString ) )
4✔
92
  {
93
    const char* strval = static_cast<const Bscript::String*>( &imp )->data();
2✔
94
    celem = obj_->findelem( strval );
2✔
95
  }
96
  else if ( imp.isa( OTLong ) )
2✔
97
  {
98
    int key = static_cast<const Bscript::BLong*>( &imp )->value();
2✔
99
    celem = obj_->findelem( key );
2✔
100
  }
101

102
  if ( celem.get() != nullptr )
4✔
103
  {
104
    return Bscript::BObjectRef( new EConfigElemRefObjImp( celem ) );
8✔
105
  }
106
  else
107
  {
108
    return Bscript::BObjectRef( new Bscript::BError( "Element not found" ) );
×
109
  }
110
}
4✔
111

112
const char* EConfigFileRefObjImp::typeOf() const
8✔
113
{
114
  return "ConfigFileRef";
8✔
115
}
116
u8 EConfigFileRefObjImp::typeOfInt() const
×
117
{
118
  return OTConfigFileRef;
×
119
}
120
Bscript::BObjectImp* EConfigFileRefObjImp::copy() const
6✔
121
{
122
  return new EConfigFileRefObjImp( obj_ );
6✔
123
}
124

125
EConfigElemRefObjImp::EConfigElemRefObjImp( ref_ptr<Core::StoredConfigElem> rcelem )
34✔
126
    : EConfigElemRefObjImpBase( &cfgelem_type, rcelem )
34✔
127
{
128
}
34✔
129

130
const char* EConfigElemRefObjImp::typeOf() const
10✔
131
{
132
  return "ConfigElemRef";
10✔
133
}
134
u8 EConfigElemRefObjImp::typeOfInt() const
×
135
{
136
  return OTConfigElemRef;
×
137
}
138
Bscript::BObjectImp* EConfigElemRefObjImp::copy() const
×
139
{
140
  return new EConfigElemRefObjImp( obj_ );
×
141
}
142

143
Bscript::BObjectRef EConfigElemRefObjImp::get_member_id( const int id )  // id test
×
144
{
145
  Bscript::ObjMember* memb = Bscript::getObjMember( id );
×
146

147
  return get_member( memb->code );
×
148
}
149
Bscript::BObjectRef EConfigElemRefObjImp::get_member( const char* membername )
26✔
150
{
151
  Bscript::BObjectImp* imp = obj_->getimp( membername );
26✔
152
  if ( imp != nullptr )
26✔
153
    return Bscript::BObjectRef( imp );
22✔
154

155
  return Bscript::BObjectRef( new Bscript::UninitObject );
4✔
156
}
157

158
Bscript::BObjectRef EConfigElemRefObjImp::OperSubscript( const Bscript::BObject& obj )
22✔
159
{
160
  const Bscript::BObjectImp& imp = obj.impref();
22✔
161
  ref_ptr<Core::StoredConfigElem> celem;
22✔
162

163
  if ( imp.isa( OTString ) )
22✔
164
  {
165
    const char* strval = static_cast<const Bscript::String*>( &imp )->data();
22✔
166
    return get_member( strval );
22✔
167
  }
NEW
168
  else if ( imp.isa( OTLong ) )
×
169
  {
NEW
170
    int key = static_cast<const Bscript::BLong*>( &imp )->value();
×
NEW
171
    return get_member( std::to_string( key ).c_str() );
×
172
  }
NEW
173
  return Bscript::BObjectRef( new Bscript::BError( "Element not found" ) );
×
174
}
22✔
175

176
ConfigFileExecutorModule::ConfigFileExecutorModule( Bscript::Executor& exec )
1,491✔
177
    : TmplExecutorModule<ConfigFileExecutorModule, Bscript::ExecutorModule>( exec )
1,491✔
178
{
179
}
1,491✔
180

181
bool ConfigFileExecutorModule::get_cfgfilename( const std::string& cfgdesc, std::string* cfgfile,
18✔
182
                                                std::string* errmsg, std::string* allpkgbase )
183
{
184
  if ( allpkgbase )
18✔
185
    *allpkgbase = "";
14✔
186
  const Plib::Package* pkg = exec.prog()->pkg;
18✔
187

188
  if ( cfgdesc[0] == ':' )
18✔
189
  {
190
    if ( cfgdesc[1] == ':' )
18✔
191
    {
192
      // Austin 2005-11-15
193
      // This is a bit of a kludge to make /regions/ config files readable.
194
      // Will go away when the paths here work like they do for file.em.
195
      // Looks for ::regions/filename
196
      if ( cfgdesc.substr( 2, 8 ) == "regions/" )
×
197
      {
198
        *cfgfile = cfgdesc.substr( 2, std::string::npos ) + ".cfg";
×
199
        return true;
×
200
      }
201
      else
202
      {
203
        // "::cfgfile" - core config file
204
        *cfgfile = "config/" + cfgdesc.substr( 2, std::string::npos ) + ".cfg";
×
205
        return true;
×
206
      }
207
    }
208
    else  // ":pkgname:configfile" - config file in some package
209
    {
210
      std::string::size_type second_colon = cfgdesc.find( ':', 2 );
18✔
211
      if ( second_colon != std::string::npos )
18✔
212
      {
213
        std::string pkgname = cfgdesc.substr( 1, second_colon - 1 );
18✔
214
        std::string cfgbase = cfgdesc.substr( second_colon + 1, std::string::npos );
18✔
215

216
        if ( pkgname == "*" )
18✔
217
        {
218
          if ( allpkgbase )
×
219
          {
220
            *cfgfile = cfgdesc;
×
221
            *allpkgbase = cfgbase;
×
222
            return true;
×
223
          }
224
          else
225
          {
226
            return false;
×
227
          }
228
        }
229

230
        Plib::Package* dstpkg = Plib::find_package( pkgname );
18✔
231
        if ( dstpkg != nullptr )
18✔
232
        {
233
          *cfgfile = GetPackageCfgPath( dstpkg, cfgbase + ".cfg" );
18✔
234
          return true;
18✔
235
        }
236
        else
237
        {
238
          *errmsg = "Unable to find package " + pkgname;
×
239
          return false;
×
240
        }
241
      }
18✔
242
      else
243
      {
244
        *errmsg = "Poorly formed config file descriptor: " + cfgdesc;
×
245
        return false;
×
246
      }
247
    }
248
  }
249
  else
250
  {
251
    if ( pkg != nullptr )
×
252
    {
253
      *cfgfile = GetPackageCfgPath( const_cast<Plib::Package*>( pkg ), cfgdesc + ".cfg" );
×
254
      return true;
×
255
    }
256
    else
257
    {
258
      *cfgfile = "config/" + cfgdesc + ".cfg";
×
259
      return true;
×
260
    }
261
  }
262
}
263

264

265
Bscript::BObjectImp* ConfigFileExecutorModule::mf_ReadConfigFile()
14✔
266
{
267
  const Bscript::String* cfgdesc_str;
268
  if ( exec.getStringParam( 0, cfgdesc_str ) )
14✔
269
  {
270
    const std::string& cfgdesc = cfgdesc_str->value();
14✔
271
    std::string cfgfile;
14✔
272
    std::string errmsg;
14✔
273
    std::string allpkgbase;
14✔
274
    if ( !get_cfgfilename( cfgdesc, &cfgfile, &errmsg, &allpkgbase ) )
14✔
275
    {
276
      return new Bscript::BError( errmsg );
×
277
    }
278

279
    ref_ptr<Core::StoredConfigFile> cfile = Core::FindConfigFile( cfgfile, allpkgbase );
14✔
280

281
    if ( cfile.get() != nullptr )
14✔
282
    {
283
      return new EConfigFileRefObjImp( cfile );
14✔
284
    }
285
    else
286
    {
287
      return new Bscript::BError( "Config file not found" );
×
288
    }
289
  }
14✔
290
  else
291
  {
292
    return new Bscript::BError( "Invalid parameter type" );
×
293
  }
294
}
295

296
bool legal_scp_filename( const char* filename )
×
297
{
298
  while ( filename && *filename )
×
299
  {
300
    if ( !isalnum( *filename ) )
×
301
      return false;
×
302
    ++filename;
×
303
  }
304
  return true;
×
305
}
306

307
Bscript::BObjectImp* ConfigFileExecutorModule::mf_LoadTusScpFile()
×
308
{
309
  const Bscript::String* filename_str;
310
  if ( !exec.getStringParam( 0, filename_str ) )
×
311
  {
312
    return new Bscript::BError( "Invalid parameter type" );
×
313
  }
314

315
  if ( !legal_scp_filename( filename_str->data() ) )
×
316
  {
317
    return new Bscript::BError( "Filename cannot include path information or special characters" );
×
318
  }
319

320
  ref_ptr<Core::StoredConfigFile> cfile =
321
      Core::LoadTusScpFile( "import/tus/" + filename_str->value() + ".scp" );
×
322

323
  if ( cfile.get() == nullptr )
×
324
  {
325
    return new Bscript::BError( "File not found" );
×
326
  }
327

328
  return new EConfigFileRefObjImp( cfile );
×
329
}
×
330

331
Bscript::BObjectImp* ConfigFileExecutorModule::mf_GetConfigMaxIntKey()
×
332
{
333
  Core::StoredConfigFile* cfile;
334

335
  if ( getStoredConfigFileParam( *this, 0, cfile ) )
×
336
  {
337
    return new Bscript::BLong( cfile->maxintkey() );
×
338
  }
339
  else
340
  {
341
    return new Bscript::BError( "Parameter 0 must be a Config File" );
×
342
  }
343
}
344

345
Bscript::BObjectImp* ConfigFileExecutorModule::mf_GetConfigStringKeys()
6✔
346
{
347
  Core::StoredConfigFile* cfile;
348
  if ( getStoredConfigFileParam( *this, 0, cfile ) )
6✔
349
  {
350
    std::unique_ptr<Bscript::ObjArray> arr( new Bscript::ObjArray );
6✔
351
    Core::StoredConfigFile::ElementsByName::const_iterator itr = cfile->byname_begin(),
6✔
352
                                                           end = cfile->byname_end();
6✔
353
    for ( ; itr != end; ++itr )
16✔
354
    {
355
      arr->addElement( new Bscript::String( ( *itr ).first.c_str() ) );
10✔
356
    }
357
    return arr.release();
6✔
358
  }
6✔
359
  else
360
  {
361
    return new Bscript::BError( "GetConfigStringKeys param 0 must be a Config File" );
×
362
  }
363
}
364

365
Bscript::BObjectImp* ConfigFileExecutorModule::mf_GetConfigIntKeys()
×
366
{
367
  Core::StoredConfigFile* cfile;
368
  if ( getStoredConfigFileParam( *this, 0, cfile ) )
×
369
  {
370
    std::unique_ptr<Bscript::ObjArray> arr( new Bscript::ObjArray );
×
371
    Core::StoredConfigFile::ElementsByNum::const_iterator itr = cfile->bynum_begin(),
×
372
                                                          end = cfile->bynum_end();
×
373
    for ( ; itr != end; ++itr )
×
374
    {
375
      arr->addElement( new Bscript::BLong( ( *itr ).first ) );
×
376
    }
377
    return arr.release();
×
378
  }
×
379
  else
380
  {
381
    return new Bscript::BError( "GetConfigIntKeys param 0 must be a Config File" );
×
382
  }
383
}
384

385
Bscript::BObjectImp* ConfigFileExecutorModule::mf_FindConfigElem()
10✔
386
{
387
  Core::StoredConfigFile* cfile;
388

389
  if ( getStoredConfigFileParam( *this, 0, cfile ) )
10✔
390
  {
391
    Bscript::BObjectImp* keyimp = exec.getParamImp( 1 );
10✔
392

393
    ref_ptr<Core::StoredConfigElem> celem;
10✔
394

395
    if ( keyimp->isa( Bscript::BObjectImp::OTLong ) )
10✔
396
    {
397
      int key = static_cast<Bscript::BLong*>( keyimp )->value();
×
398
      celem = cfile->findelem( key );
×
399
    }
400
    else if ( keyimp->isa( Bscript::BObjectImp::OTString ) )
10✔
401
    {
402
      const char* strval = static_cast<Bscript::String*>( keyimp )->data();
10✔
403
      celem = cfile->findelem( strval );
10✔
404
    }
405
    else
406
    {
407
      return new Bscript::BError( "Param 1 must be an Integer or a String" );
×
408
    }
409

410
    if ( celem.get() != nullptr )
10✔
411
    {
412
      return new EConfigElemRefObjImp( celem );
10✔
413
    }
414
    else
415
    {
416
      return new Bscript::BError( "Element not found" );
×
417
    }
418
  }
10✔
419
  else
420
  {
421
    return new Bscript::BError( "Parameter 0 must be a Config File" );
×
422
  }
423
}
424

425
Bscript::BObjectImp* ConfigFileExecutorModule::mf_GetElemProperty()
×
426
{
427
  return mf_GetConfigString();
×
428
}
429

430
Bscript::BObjectImp* ConfigFileExecutorModule::mf_GetConfigString()
60✔
431
{
432
  Core::StoredConfigElem* celem;
433
  const Bscript::String* propname_str;
434

435
  if ( getStoredConfigElemParam( *this, 0, celem ) && getStringParam( 1, propname_str ) )
60✔
436
  {
437
    Bscript::BObjectImp* imp = celem->getimp( propname_str->value() );
60✔
438
    if ( imp != nullptr )
60✔
439
    {
440
      return new Bscript::String( imp->getStringRep() );
60✔
441
    }
442
    else
443
    {
444
      return new Bscript::BError( "Property not found" );
×
445
    }
446
  }
447
  else
448
  {
449
    return new Bscript::BError( "Invalid parameter type" );
×
450
  }
451
}
452

453
Bscript::BObjectImp* ConfigFileExecutorModule::mf_GetConfigStringArray()
×
454
{
455
  Core::StoredConfigElem* celem;
456
  const Bscript::String* propname_str;
457

458
  if ( getStoredConfigElemParam( *this, 0, celem ) && getStringParam( 1, propname_str ) )
×
459
  {
460
    std::pair<Core::StoredConfigElem::const_iterator, Core::StoredConfigElem::const_iterator> pr =
461
        celem->equal_range( propname_str->data() );
×
462
    Core::StoredConfigElem::const_iterator itr = pr.first;
×
463
    Core::StoredConfigElem::const_iterator end = pr.second;
×
464

465
    std::unique_ptr<Bscript::ObjArray> ar( new Bscript::ObjArray );
×
466
    for ( ; itr != end; ++itr )
×
467
    {
468
      Bscript::BObjectImp* imp = ( *itr ).second.get();
×
469
      // Added 9-03-2005  Austin
470
      // Will no longer place the string right into the array.
471
      // Instead a check is done to make sure something is there.
472
      if ( imp->getStringRep().length() >= 1 )
×
473
        ar->addElement( new Bscript::String( imp->getStringRep() ) );
×
474
    }
475
    return ar.release();
×
476
  }
×
477
  else
478
  {
479
    return new Bscript::BError( "Invalid parameter type" );
×
480
  }
481
}
482

483
Bscript::BObjectImp* ConfigFileExecutorModule::mf_GetConfigStringDictionary()
×
484
{
485
  Core::StoredConfigElem* celem;
486
  const Bscript::String* propname_str;
487

488
  if ( getStoredConfigElemParam( *this, 0, celem ) && getStringParam( 1, propname_str ) )
×
489
  {
490
    std::pair<Core::StoredConfigElem::const_iterator, Core::StoredConfigElem::const_iterator> pr =
491
        celem->equal_range( propname_str->data() );
×
492
    Core::StoredConfigElem::const_iterator itr = pr.first;
×
493
    Core::StoredConfigElem::const_iterator end = pr.second;
×
494

495
    std::unique_ptr<Bscript::BDictionary> dict( new Bscript::BDictionary );
×
496
    for ( ; itr != end; ++itr )
×
497
    {
498
      Bscript::BObjectImp* line = ( *itr ).second.get();
×
499

500
      std::string line_str = line->getStringRep();
×
501
      if ( line_str.length() < 1 )
×
502
        continue;
×
503

504
      /* Example:
505
       * Elem
506
       * {
507
       *     PropName data moredata more data
508
       *     PropName stuff morestuff stuffity stuff
509
       * }
510
       * dict "data"->"moredata more data", "stuff"->"morestuff stuffity stuff!"
511
       */
512
      std::string prop_name, prop_value;
×
513
      Clib::splitnamevalue( line_str, prop_name, prop_value );
×
514

515
      dict->addMember( new Bscript::String( prop_name ), new Bscript::String( prop_value ) );
×
516
    }
×
517

518
    return dict.release();
×
519
  }
×
520
  else
521
  {
522
    return new Bscript::BError( "Invalid parameter type" );
×
523
  }
524
}
525

526

527
Bscript::BObjectImp* ConfigFileExecutorModule::mf_GetConfigInt()
×
528
{
529
  Core::StoredConfigElem* celem;
530
  const Bscript::String* propname_str;
531

532
  if ( getStoredConfigElemParam( *this, 0, celem ) && getStringParam( 1, propname_str ) )
×
533
  {
534
    Bscript::BObjectImp* imp = celem->getimp( propname_str->value() );
×
535
    if ( imp != nullptr )
×
536
    {
537
      if ( imp->isa( Bscript::BObjectImp::OTLong ) )
×
538
      {
539
        return imp;
×
540
      }
541
      else if ( imp->isa( Bscript::BObjectImp::OTDouble ) )
×
542
      {
543
        Bscript::Double* dbl = static_cast<Bscript::Double*>( imp );
×
544
        return new Bscript::BLong( static_cast<int>( dbl->value() ) );
×
545
      }
546
      else if ( imp->isa( Bscript::BObjectImp::OTString ) )
×
547
      {
548
        Bscript::String* str = static_cast<Bscript::String*>( imp );
×
549
        return new Bscript::BLong( strtoul( str->data(), nullptr, 0 ) );
×
550
      }
551
      else
552
      {
553
        return new Bscript::BError( "Invalid type in config file! (internal error)" );
×
554
      }
555
    }
556
    else
557
    {
558
      return new Bscript::BError( "Property not found" );
×
559
    }
560
  }
561
  else
562
  {
563
    return new Bscript::BError( "Invalid parameter type" );
×
564
  }
565
}
566

567
Bscript::BObjectImp* ConfigFileExecutorModule::mf_GetConfigIntArray()
×
568
{
569
  Core::StoredConfigElem* celem;
570
  const Bscript::String* propname_str;
571

572
  if ( getStoredConfigElemParam( *this, 0, celem ) && getStringParam( 1, propname_str ) )
×
573
  {
574
    auto pr = celem->equal_range( propname_str->data() );
×
575
    Core::StoredConfigElem::const_iterator itr = pr.first;
×
576
    Core::StoredConfigElem::const_iterator end = pr.second;
×
577

578
    std::unique_ptr<Bscript::ObjArray> ar( new Bscript::ObjArray );
×
579
    for ( ; itr != end; ++itr )
×
580
    {
581
      Bscript::BObjectImp* imp = ( *itr ).second.get();
×
582
      // Will no longer place the string right into the array.
583
      // Instead a check is done to make sure something is there.
584

585
      if ( imp->getStringRep().length() >= 1 )
×
586
      {
587
        if ( imp->isa( Bscript::BObjectImp::OTLong ) )
×
588
        {
589
          ar->addElement( imp );
×
590
        }
591
        else if ( imp->isa( Bscript::BObjectImp::OTDouble ) )
×
592
        {
593
          Bscript::Double* dbl = static_cast<Bscript::Double*>( imp );
×
594
          ar->addElement( new Bscript::BLong( static_cast<int>( dbl->value() ) ) );
×
595
        }
596
        else if ( imp->isa( Bscript::BObjectImp::OTString ) )
×
597
        {
598
          Bscript::String* str = static_cast<Bscript::String*>( imp );
×
599
          ar->addElement( new Bscript::BLong( strtoul( str->data(), nullptr, 0 ) ) );
×
600
        }
601
      }
602
    }
603
    return ar.release();
×
604
  }
×
605
  else
606
  {
607
    return new Bscript::BError( "Invalid parameter type" );
×
608
  }
609
}
610

611
Bscript::BObjectImp* ConfigFileExecutorModule::mf_GetConfigReal()
×
612
{
613
  Core::StoredConfigElem* celem;
614
  const Bscript::String* propname_str;
615

616
  if ( getStoredConfigElemParam( *this, 0, celem ) && getStringParam( 1, propname_str ) )
×
617
  {
618
    Bscript::BObjectImp* imp = celem->getimp( propname_str->value() );
×
619
    if ( imp != nullptr )
×
620
    {
621
      if ( imp->isa( Bscript::BObjectImp::OTDouble ) )
×
622
      {
623
        return imp;
×
624
      }
625
      else if ( imp->isa( Bscript::BObjectImp::OTLong ) )
×
626
      {
627
        Bscript::BLong* blong = static_cast<Bscript::BLong*>( imp );
×
628
        return new Bscript::Double( blong->value() );
×
629
      }
630
      else if ( imp->isa( Bscript::BObjectImp::OTString ) )
×
631
      {
632
        Bscript::String* str = static_cast<Bscript::String*>( imp );
×
633
        return new Bscript::Double( strtod( str->data(), nullptr ) );
×
634
      }
635
      else
636
      {
637
        return new Bscript::BError( "Invalid type in config file! (internal error)" );
×
638
      }
639
    }
640
    else
641
    {
642
      return new Bscript::BError( "Property not found" );
×
643
    }
644
  }
645
  else
646
  {
647
    return new Bscript::BError( "Invalid parameter type" );
×
648
  }
649
}
650

651
Bscript::BObjectImp* ConfigFileExecutorModule::mf_ListConfigElemProps()
30✔
652
{
653
  Core::StoredConfigElem* celem;
654
  if ( getStoredConfigElemParam( *this, 0, celem ) )
30✔
655
  {
656
    // should return an array or prop-names
657
    return celem->listprops();
30✔
658
  }
659
  else
660
  {
661
    return new Bscript::BError( "Invalid parameter type" );
×
662
  }
663
}
664

665
/* The elements in the array passed should each be a structure (name, value) */
666
Bscript::BObjectImp* ConfigFileExecutorModule::mf_AppendConfigFileElem()
4✔
667
{
668
  const Bscript::String* filename;
669
  const Bscript::String* elemtype;
670
  Bscript::ObjArray* objarr;
671
  if ( !exec.getStringParam( 0, filename ) || !exec.getStringParam( 1, elemtype ) ||
8✔
672
       !exec.getObjArrayParam( 3, objarr ) )
4✔
673
  {
674
    return new Bscript::BError( "Invalid parameter type" );
×
675
  }
676
  std::string elemkey = getParamImp( 2 )->getStringRep();
4✔
677

678
  std::string pathname, errmsg;
4✔
679
  const std::string& cfgdesc = filename->value();
4✔
680
  if ( !get_cfgfilename( cfgdesc, &pathname, &errmsg ) )
4✔
681
  {
682
    return new Bscript::BError( errmsg );
×
683
  }
684

685
  std::ofstream ofs( pathname.c_str(), std::ios::app );
4✔
686
  if ( !ofs.is_open() )
4✔
687
    return new Bscript::BError( "Failed to open file" );
2✔
688
  ofs << std::endl << elemtype->value() << " " << elemkey << std::endl << "{" << std::endl;
2✔
689
  for ( Bscript::ObjArray::const_iterator itr = objarr->ref_arr.begin(),
2✔
690
                                          end = objarr->ref_arr.end();
2✔
691
        itr != end; ++itr )
6✔
692
  {
693
    Bscript::BObject* bo = itr->get();
4✔
694
    if ( bo != nullptr )
4✔
695
    {
696
      if ( bo->isa( Bscript::BObjectImp::OTArray ) )
4✔
697
      {
698
        Bscript::ObjArray* inarr = (Bscript::ObjArray*)( bo->impptr() );
2✔
699
        if ( inarr->ref_arr.size() == 2 )
2✔
700
        {
701
          Bscript::BObject* nobj = inarr->ref_arr[0].get();
2✔
702
          Bscript::BObject* vobj = inarr->ref_arr[1].get();
2✔
703
          if ( nobj != nullptr && nobj->isa( Bscript::BObjectImp::OTString ) && vobj != nullptr )
2✔
704
          {
705
            Bscript::String* namestr = nobj->impptr<Bscript::String>();
2✔
706
            std::string value = vobj->impptr()->getStringRep();
2✔
707

708
            ofs << "\t" << namestr->value() << "\t" << value << std::endl;
2✔
709
          }
2✔
710
        }
711
      }
712
      else if ( bo->isa( Bscript::BObjectImp::OTStruct ) )
2✔
713
      {
714
        Bscript::BStruct* instruct = bo->impptr<Bscript::BStruct>();
2✔
715
        const Bscript::BObjectImp* name_imp = instruct->FindMember( "name" );
2✔
716
        const Bscript::BObjectImp* value_imp = instruct->FindMember( "value" );
2✔
717
        if ( name_imp && name_imp->isa( Bscript::BObjectImp::OTString ) && value_imp )
2✔
718
        {
719
          const Bscript::String* namestr = static_cast<const Bscript::String*>( name_imp );
2✔
720
          std::string value = value_imp->getStringRep();
2✔
721

722
          ofs << "\t" << namestr->value() << "\t" << value << std::endl;
2✔
723
        }
2✔
724
      }
725
    }
726
  }
727
  ofs << "}" << std::endl;
2✔
728

729
  Core::UnloadConfigFile( pathname );
2✔
730

731
  return new Bscript::BLong( 1 );
2✔
732
}
4✔
733

734
Bscript::BObjectImp* ConfigFileExecutorModule::mf_UnloadConfigFile()
×
735
{
736
  const Bscript::String* filename;
737
  if ( getStringParam( 0, filename ) )
×
738
  {
739
    const std::string& cfgdesc = filename->value();
×
740
    std::string cfgfile;
×
741
    std::string errmsg;
×
742
    std::string allpkgbase;
×
743
    if ( !get_cfgfilename( cfgdesc, &cfgfile, &errmsg, &allpkgbase ) )
×
744
    {
745
      return new Bscript::BError( errmsg );
×
746
    }
747

748
    return new Bscript::BLong( Core::UnloadConfigFile( cfgfile ) );
×
749
  }
×
750
  else
751
  {
752
    return new Bscript::BError( "Invalid parameter" );
×
753
  }
754
}
755

756
bool getStoredConfigFileParam( Bscript::ExecutorModule& exmod, unsigned param,
16✔
757
                               Core::StoredConfigFile*& cfile )
758
{
759
  Bscript::BApplicObjBase* ao_cfile_base = exmod.exec.getApplicObjParam( param, &cfgfile_type );
16✔
760
  if ( ao_cfile_base != nullptr )
16✔
761
  {
762
    EConfigFileRefObjImp* ao_cfile = static_cast<EConfigFileRefObjImp*>( ao_cfile_base );
16✔
763

764
    cfile = ao_cfile->value().get();
16✔
765

766
    return true;
16✔
767
  }
768
  else
769
  {
770
    return false;
×
771
  }
772
}
773

774
bool getStoredConfigElemParam( Bscript::ExecutorModule& exmod, unsigned param,
90✔
775
                               Core::StoredConfigElem*& celem )
776
{
777
  Bscript::BApplicObjBase* ao_celem_base = exmod.exec.getApplicObjParam( param, &cfgelem_type );
90✔
778
  if ( ao_celem_base != nullptr )
90✔
779
  {
780
    EConfigElemRefObjImp* ao_celem = static_cast<EConfigElemRefObjImp*>( ao_celem_base );
90✔
781

782
    celem = ao_celem->value().get();
90✔
783

784
    return true;
90✔
785
  }
786
  else
787
  {
788
    return false;
×
789
  }
790
}
791
}  // namespace Module
792
}  // namespace Pol
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc