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

polserver / polserver / 21108840797

18 Jan 2026 08:35AM UTC coverage: 60.508% (+0.02%) from 60.492%
21108840797

push

github

web-flow
ClangTidy readability-else-after-return (#857)

* trigger tidy

* Automated clang-tidy change: readability-else-after-return

* compile test

* rerun

* Automated clang-tidy change: readability-else-after-return

* trigger..

* Automated clang-tidy change: readability-else-after-return

* manually removed a few

* Automated clang-tidy change: readability-else-after-return

* removed duplicate code

* fix remaining warnings

* fixed scope

---------

Co-authored-by: Clang Tidy <clang-tidy@users.noreply.github.com>

837 of 1874 new or added lines in 151 files covered. (44.66%)

46 existing lines in 25 files now uncovered.

44448 of 73458 relevant lines covered (60.51%)

525066.38 hits per line

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

76.64
/pol-core/bscript/dict.cpp
1
/** @file
2
 *
3
 * @par History
4
 * - 2005/11/26 Shinigami: changed "strcmp" into "stricmp" to suppress Script Errors
5
 * - 2008/02/11 Turley:    BDictionary::unpack() will accept zero length Dictionarys
6
 * - 2009/12/21 Turley:    ._method() call fix
7
 */
8

9

10
#include "dict.h"
11

12
#include <stddef.h>
13

14
#include "../clib/stlutil.h"
15
#include "berror.h"
16
#include "contiter.h"
17
#include "executor.h"
18
#include "impstr.h"
19
#include "objmethods.h"
20

21

22
namespace Pol::Bscript
23
{
24
BDictionary::BDictionary() : BObjectImp( OTDictionary ), contents_() {}
232✔
25

26
BDictionary::BDictionary( BObjectType type ) : BObjectImp( type ), contents_() {}
×
27

28
BDictionary::BDictionary( const BDictionary& dict, BObjectType type )
634✔
29
    : BObjectImp( type ), contents_()
634✔
30
{
31
  for ( const auto& elem : dict.contents_ )
791✔
32
  {
33
    const BObject& bkeyobj = elem.first;
157✔
34
    const BObjectRef& bvalref = elem.second;
157✔
35

36
    contents_[bkeyobj] = BObjectRef( new BObject( bvalref->impref().copy() ) );
157✔
37
  }
38
}
634✔
39

40
BDictionary::BDictionary( std::istream& is, unsigned size, BObjectType type )
9✔
41
    : BObjectImp( type ), contents_()
9✔
42
{
43
  for ( unsigned i = 0; i < size; ++i )
213✔
44
  {
45
    BObjectImp* keyimp = BObjectImp::unpack( is );
204✔
46
    BObjectImp* valimp = BObjectImp::unpack( is );
204✔
47
    if ( keyimp != nullptr && valimp != nullptr )
204✔
48
    {
49
      BObject keyobj( keyimp );
204✔
50
      contents_[keyobj].set( new BObject( valimp ) );
204✔
51
    }
204✔
52
    else
53
    {
54
      if ( keyimp )
×
55
        BObject objk( keyimp );
×
56
      if ( valimp )
×
57
        BObject objv( valimp );
×
58
    }
59
  }
60
}
9✔
61

62
class BDictionaryIterator final : public ContIterator
63
{
64
public:
65
  BDictionaryIterator( BDictionary* pDict, BObject* pIterVal );
66
  BObject* step() override;
67

68
private:
69
  BObject m_DictObj;
70
  BDictionary* m_pDict;
71
  BObjectRef m_IterVal;
72
  BObject m_Key;
73
  bool m_First;
74
};
75
BDictionaryIterator::BDictionaryIterator( BDictionary* pDict, BObject* pIterVal )
24✔
76
    : ContIterator(),
77
      m_DictObj( pDict ),
24✔
78
      m_pDict( pDict ),
24✔
79
      m_IterVal( pIterVal ),
24✔
80
      m_Key( UninitObject::create() ),
24✔
81
      m_First( true )
24✔
82
{
83
}
24✔
84

85
BObject* BDictionaryIterator::step()
93✔
86
{
87
  if ( m_First )
93✔
88
  {
89
    auto itr = m_pDict->contents_.begin();
24✔
90
    if ( itr == m_pDict->contents_.end() )
24✔
91
      return nullptr;
×
92

93
    m_First = false;
24✔
94
    const BObject& okey = ( *itr ).first;
24✔
95
    m_Key.setimp( okey.impptr()->copy() );
24✔
96
    m_IterVal->setimp( m_Key.impptr() );
24✔
97

98
    BObjectRef& oref = ( *itr ).second;
24✔
99
    return oref.get();
24✔
100
  }
101

102
  auto itr = m_pDict->contents_.find( m_Key );
69✔
103
  if ( itr == m_pDict->contents_.end() )
69✔
NEW
104
    return nullptr;
×
105
  ++itr;
69✔
106
  if ( itr == m_pDict->contents_.end() )
69✔
107
    return nullptr;
24✔
108

109
  const BObject& okey = ( *itr ).first;
45✔
110
  m_Key.setimp( okey.impptr()->copy() );
45✔
111
  m_IterVal->setimp( m_Key.impptr() );
45✔
112

113
  BObjectRef& oref = ( *itr ).second;
45✔
114
  return oref.get();
45✔
115
}
116

117
ContIterator* BDictionary::createIterator( BObject* pIterVal )
24✔
118
{
119
  return new BDictionaryIterator( this, pIterVal );
24✔
120
}
121

122
BObjectImp* BDictionary::copy() const
634✔
123
{
124
  return new BDictionary( *this );
634✔
125
}
126

127
size_t BDictionary::sizeEstimate() const
120✔
128
{
129
  return sizeof( BDictionary ) +
130
         Clib::memsize_keyvalue( contents_, []( const auto& v ) { return v.sizeEstimate(); } );
618✔
131
}
132

133
size_t BDictionary::mapcount() const
×
134
{
135
  return contents_.size();
×
136
}
137

138
BObjectRef BDictionary::set_member( const char* membername, BObjectImp* value, bool copy )
24✔
139
{
140
  BObject key( new String( membername ) );
24✔
141
  BObjectImp* target = copy ? value->copy() : value;
24✔
142

143
  auto itr = contents_.find( key );
24✔
144
  if ( itr != contents_.end() )
24✔
145
  {
146
    BObjectRef& oref = ( *itr ).second;
15✔
147
    oref->setimp( target );
15✔
148
    return oref;
15✔
149
  }
150

151
  BObjectRef ref( new BObject( target ) );
9✔
152
  contents_[key] = ref;
9✔
153
  return ref;
9✔
154
}
24✔
155

156
BObjectRef BDictionary::get_member( const char* membername )
67✔
157
{
158
  BObject key( new String( membername ) );
67✔
159

160
  auto itr = contents_.find( key );
67✔
161
  if ( itr != contents_.end() )
67✔
162
  {
163
    return ( *itr ).second;
61✔
164
  }
165

166
  return BObjectRef( UninitObject::create() );
6✔
167
}
67✔
168

169

170
BObjectRef BDictionary::OperSubscript( const BObject& obj )
137✔
171
{
172
  if ( obj->isa( OTString ) || obj->isa( OTLong ) || obj->isa( OTDouble ) ||
140✔
173
       obj->isa( OTApplicObj ) )
3✔
174
  {
175
    auto itr = contents_.find( obj );
134✔
176
    if ( itr != contents_.end() )
134✔
177
    {
178
      BObjectRef& oref = ( *itr ).second;
128✔
179
      return oref;
128✔
180
    }
181

182
    return BObjectRef( UninitObject::create() );
6✔
183
  }
184

185
  return BObjectRef( new BError( "Dictionary keys must be integer, real, or string" ) );
3✔
186
}
187

188
BObjectImp* BDictionary::array_assign( BObjectImp* idx, BObjectImp* target, bool copy )
190✔
189
{
190
  if ( idx->isa( OTString ) || idx->isa( OTLong ) || idx->isa( OTDouble ) ||
190✔
191
       idx->isa( OTApplicObj ) )
×
192
  {
193
    BObjectImp* new_target = copy ? target->copy() : target;
190✔
194

195
    BObject obj( idx );
190✔
196
    auto itr = contents_.find( obj );
190✔
197
    if ( itr != contents_.end() )
190✔
198
    {
199
      BObjectRef& oref = ( *itr ).second;
18✔
200
      oref->setimp( new_target );
18✔
201
      return new_target;
18✔
202
    }
203

204
    contents_[BObject( obj->copy() )].set( new BObject( new_target ) );
172✔
205
    return new_target;
172✔
206
  }
190✔
207

NEW
208
  return new BError( "Dictionary keys must be integer, real, or string" );
×
209
}
210

211
void BDictionary::addMember( const char* name, BObjectRef val )
×
212
{
213
  BObject key( new String( name ) );
×
214
  contents_[key] = val;
×
215
}
×
216

217
void BDictionary::addMember( const char* name, BObjectImp* imp )
×
218
{
219
  BObject key( new String( name ) );
×
220
  contents_[key] = BObjectRef( imp );
×
221
}
×
222

223
void BDictionary::addMember( BObjectImp* keyimp, BObjectImp* valimp )
182✔
224
{
225
  BObject key( keyimp );
182✔
226
  contents_[key] = BObjectRef( valimp );
182✔
227
}
182✔
228

229
BObjectImp* BDictionary::call_method_id( const int id, Executor& ex, bool /*forcebuiltin*/ )
241✔
230
{
231
  BObject* keyobj;
232
  BObject* valobj;
233
  switch ( id )
241✔
234
  {
235
  case MTH_SIZE:
27✔
236
    if ( ex.numParams() == 0 )
27✔
237
      return new BLong( static_cast<int>( contents_.size() ) );
27✔
238
    else
239
      return new BError( "dictionary.size() doesn't take parameters." );
×
240
    break;
241
  case MTH_ERASE:
49✔
242
    if ( ex.numParams() == 1 && ( keyobj = ex.getParamObj( 0 ) ) != nullptr )
49✔
243
    {
244
      if ( !( keyobj->isa( OTLong ) || keyobj->isa( OTString ) || keyobj->isa( OTDouble ) ||
49✔
245
              keyobj->isa( OTApplicObj ) ) )
×
246
        return new BError( "Dictionary keys must be integer, real, or string" );
×
247
      int nremove = static_cast<int>( contents_.erase( *keyobj ) );
49✔
248
      return new BLong( nremove );
49✔
249
    }
250
    else
251
    {
252
      return new BError( "dictionary.erase(key) requires a parameter." );
×
253
    }
254
    break;
255
  case MTH_INSERT:
51✔
256
    if ( ex.numParams() == 2 && ( keyobj = ex.getParamObj( 0 ) ) != nullptr &&
102✔
257
         ( valobj = ex.getParamObj( 1 ) ) != nullptr )
51✔
258
    {
259
      if ( !( keyobj->isa( OTLong ) || keyobj->isa( OTString ) || keyobj->isa( OTDouble ) ||
51✔
260
              keyobj->isa( OTApplicObj ) ) )
×
261
        return new BError( "Dictionary keys must be integer, real, or string" );
×
262
      BObject key( keyobj->impptr()->copy() );
51✔
263
      contents_[key] = BObjectRef( new BObject( valobj->impptr()->copy() ) );
51✔
264
      return new BLong( static_cast<int>( contents_.size() ) );
51✔
265
    }
51✔
266
    else
267
    {
268
      return new BError( "dictionary.insert(key,value) requires two parameters." );
×
269
    }
270
    break;
271
  case MTH_EXISTS:
111✔
272
    if ( ex.numParams() == 1 && ( keyobj = ex.getParamObj( 0 ) ) != nullptr )
111✔
273
    {
274
      if ( !( keyobj->isa( OTLong ) || keyobj->isa( OTString ) || keyobj->isa( OTDouble ) ||
111✔
275
              keyobj->isa( OTApplicObj ) ) )
×
276
        return new BError( "Dictionary keys must be integer, real, or string" );
×
277
      int count = static_cast<int>( contents_.count( *keyobj ) );
111✔
278
      return new BLong( count );
111✔
279
    }
280
    else
281
    {
282
      return new BError( "dictionary.exists(key) requires a parameter." );
×
283
    }
284
    break;
285
  case MTH_KEYS:
3✔
286
    if ( ex.numParams() == 0 )
3✔
287
    {
288
      auto arr = new ObjArray;
3✔
289
      for ( const auto& content : contents_ )
9✔
290
      {
291
        const BObject& bkeyobj = content.first;
6✔
292

293
        arr->addElement( bkeyobj.impref().copy() );
6✔
294
      }
295
      return arr;
3✔
296
    }
297
    else
298
      return new BError( "dictionary.keys() doesn't take parameters." );
×
299
    break;
300
  default:
×
301
    return nullptr;
×
302
  }
303
}
304

305
BObjectImp* BDictionary::call_method( const char* methodname, Executor& ex )
×
306
{
307
  ObjMethod* objmethod = getKnownObjMethod( methodname );
×
308
  if ( objmethod != nullptr )
×
309
    return this->call_method_id( objmethod->id, ex );
×
NEW
310
  return nullptr;
×
311
}
312

313
char BDictionary::packtype() const
9✔
314
{
315
  return 'd';
9✔
316
}
317

318
const char* BDictionary::typetag() const
861✔
319
{
320
  return "dict";
861✔
321
}
322

323
const char* BDictionary::typeOf() const
×
324
{
325
  return "Dictionary";
×
326
}
327
u8 BDictionary::typeOfInt() const
3✔
328
{
329
  return OTDictionary;
3✔
330
}
331

332
void BDictionary::packonto( std::ostream& os ) const
9✔
333
{
334
  os << packtype() << contents_.size() << ":";
9✔
335
  for ( const auto& content : contents_ )
36✔
336
  {
337
    const BObject& bkeyobj = content.first;
27✔
338
    const BObjectRef& bvalref = content.second;
27✔
339

340
    bkeyobj.impref().packonto( os );
27✔
341
    bvalref->impref().packonto( os );
27✔
342
  }
343
}
9✔
344

345

346
BObjectImp* BDictionary::unpack( std::istream& is )
9✔
347
{
348
  unsigned size;
349
  char colon;
350
  if ( !( is >> size >> colon ) )
9✔
351
  {
352
    return new BError( "Unable to unpack dictionary elemcount" );
×
353
  }
354
  if ( (int)size < 0 )
9✔
355
  {
356
    return new BError(
357
        "Unable to unpack dictionary elemcount. Length given must be positive integer!" );
×
358
  }
359
  if ( colon != ':' )
9✔
360
  {
361
    return new BError( "Unable to unpack dictionary elemcount. Bad format. Colon not found!" );
×
362
  }
363
  return new BDictionary( is, size );
9✔
364
}
365

366
std::string BDictionary::getStringRep() const
861✔
367
{
368
  OSTRINGSTREAM os;
861✔
369
  os << typetag() << "{ ";
861✔
370
  bool any = false;
861✔
371

372
  for ( const auto& content : contents_ )
1,707✔
373
  {
374
    const BObject& bkeyobj = content.first;
846✔
375
    const BObjectRef& bvalref = content.second;
846✔
376

377
    if ( any )
846✔
378
      os << ", ";
414✔
379
    else
380
      any = true;
432✔
381

382
    FormatForStringRep( os, bkeyobj, bvalref );
846✔
383
  }
384

385
  os << " }";
861✔
386

387
  return OSTRINGSTREAM_STR( os );
1,722✔
388
}
861✔
389

390
void BDictionary::FormatForStringRep( std::ostream& os, const BObject& bkeyobj,
846✔
391
                                      const BObjectRef& bvalref ) const
392
{
393
  os << bkeyobj.impref().getFormattedStringRep() << " -> "
846✔
394
     << bvalref->impref().getFormattedStringRep();
846✔
395
}
846✔
396

397

398
BObjectRef BDictionary::operDotPlus( const char* name )
×
399
{
400
  BObject key( new String( name ) );
×
401
  if ( contents_.count( key ) == 0 )
×
402
  {
403
    auto pnewobj = new BObject( new UninitObject );
×
404
    contents_[key] = BObjectRef( pnewobj );
×
405
    return BObjectRef( pnewobj );
×
406
  }
407

NEW
408
  return BObjectRef( new BError( "Member already exists" ) );
×
UNCOV
409
}
×
410

411
const BDictionary::Contents& BDictionary::contents() const
34✔
412
{
413
  return contents_;
34✔
414
}
415
}  // namespace Pol::Bscript
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