• 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

78.16
/pol-core/bscript/bstruct.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:    BStruct::unpack() will accept zero length Structs
6
 * - 2009/09/05 Turley:    Added struct .? and .- as shortcut for .exists() and .erase()
7
 * - 2009/12/21 Turley:    ._method() call fix
8
 */
9

10

11
#include "bstruct.h"
12

13
#include <stddef.h>
14

15
#include "../clib/passert.h"
16
#include "../clib/stlutil.h"
17
#include "berror.h"
18
#include "bobject.h"
19
#include "contiter.h"
20
#include "executor.h"
21
#include "impstr.h"
22
#include "objmethods.h"
23

24

25
namespace Pol::Bscript
26
{
27
BStruct::BStruct() : BObjectImp( OTStruct ), contents_() {}
3,057✔
28

29
BStruct::BStruct( BObjectType type ) : BObjectImp( type ), contents_() {}
6,155✔
30

31
BStruct::BStruct( const BStruct& other, BObjectType type ) : BObjectImp( type ), contents_()
2,676✔
32
{
33
  for ( const auto& elem : other.contents_ )
9,664✔
34
  {
35
    const std::string& key = elem.first;
6,988✔
36
    const BObjectRef& bvalref = elem.second;
6,988✔
37

38
    contents_[key] = BObjectRef( new BObject( bvalref->impref().copy() ) );
6,988✔
39
  }
40
}
2,676✔
41

42
BStruct::BStruct( std::istream& is, unsigned size, BObjectType type )
3✔
43
    : BObjectImp( type ), contents_()
3✔
44
{
45
  for ( unsigned i = 0; i < size; ++i )
6✔
46
  {
47
    BObjectImp* keyimp = BObjectImp::unpack( is );
3✔
48
    BObjectImp* valimp = BObjectImp::unpack( is );
3✔
49
    if ( auto* key = impptrIf<String>( keyimp ); valimp && key )
3✔
50
    {
51
      contents_[key->value()].set( new BObject( valimp ) );
3✔
52

53
      BObject cleaner( key );
3✔
54
    }
3✔
55
    else
56
    {
57
      if ( keyimp )
×
58
        BObject objk( keyimp );
×
59
      if ( valimp )
×
60
        BObject objv( valimp );
×
61
    }
62
  }
63
}
3✔
64

65
BObjectImp* BStruct::copy() const
2,570✔
66
{
67
  passert( isa( OTStruct ) );
2,570✔
68
  return new BStruct( *this, OTStruct );
2,570✔
69
}
70
char BStruct::packtype() const
6✔
71
{
72
  return 't';
6✔
73
}
74

75
const char* BStruct::typetag() const
1,613✔
76
{
77
  return "struct";
1,613✔
78
}
79

80
const char* BStruct::typeOf() const
13✔
81
{
82
  return "Struct";
13✔
83
}
84
u8 BStruct::typeOfInt() const
6✔
85
{
86
  return OTStruct;
6✔
87
}
88

89

90
BObjectImp* BStruct::unpack( std::istream& is )
×
91
{
92
  unsigned size;
93
  char colon;
94
  if ( !( is >> size >> colon ) )
×
95
  {
96
    return new BError( "Unable to unpack struct elemcount" );
×
97
  }
98
  if ( (int)size < 0 )
×
99
  {
100
    return new BError(
101
        "Unable to unpack struct elemcount. Length given must be positive integer!" );
×
102
  }
103
  if ( colon != ':' )
×
104
  {
105
    return new BError( "Unable to unpack struct elemcount. Bad format. Colon not found!" );
×
106
  }
107
  return new BStruct( is, size, OTStruct );
×
108
}
109

110
void BStruct::FormatForStringRep( std::ostream& os, const std::string& key,
3,092✔
111
                                  const BObjectRef& bvalref ) const
112
{
113
  os << key << " = " << bvalref->impref().getFormattedStringRep();
3,092✔
114
}
3,092✔
115

116
class BStructIterator final : public ContIterator
117
{
118
public:
119
  BStructIterator( BStruct* pDict, BObject* pIterVal );
120
  BObject* step() override;
121

122
private:
123
  BObject m_StructObj;
124
  BStruct* m_pStruct;
125
  BObjectRef m_IterVal;
126
  std::string key;
127
  bool m_First;
128
};
129
BStructIterator::BStructIterator( BStruct* pStruct, BObject* pIterVal )
61✔
130
    : m_StructObj( pStruct ),
61✔
131
      m_pStruct( pStruct ),
61✔
132
      m_IterVal( pIterVal ),
61✔
133
      key( "" ),
61✔
134
      m_First( true )
61✔
135
{
136
}
61✔
137

138
BObject* BStructIterator::step()
221✔
139
{
140
  if ( m_First )
221✔
141
  {
142
    auto itr = m_pStruct->contents_.begin();
61✔
143
    if ( itr == m_pStruct->contents_.end() )
61✔
144
      return nullptr;
×
145

146
    m_First = false;
61✔
147
    key = ( *itr ).first;
61✔
148
    m_IterVal->setimp( new String( key ) );
61✔
149

150
    BObjectRef& oref = ( *itr ).second;
61✔
151
    return oref.get();
61✔
152
  }
153

154
  auto itr = m_pStruct->contents_.find( key );
160✔
155
  if ( itr == m_pStruct->contents_.end() )
160✔
NEW
156
    return nullptr;
×
157
  ++itr;
160✔
158
  if ( itr == m_pStruct->contents_.end() )
160✔
159
    return nullptr;
61✔
160

161
  key = ( *itr ).first;
99✔
162
  m_IterVal->setimp( new String( key ) );
99✔
163

164
  BObjectRef& oref = ( *itr ).second;
99✔
165
  return oref.get();
99✔
166
}
167

168
ContIterator* BStruct::createIterator( BObject* pIterVal )
61✔
169
{
170
  return new BStructIterator( this, pIterVal );
61✔
171
}
172

173
size_t BStruct::sizeEstimate() const
198✔
174
{
175
  return sizeof( BStruct ) +
176
         Clib::memsize( contents_, []( const auto& v ) { return v.sizeEstimate(); } );
474✔
177
}
178

179
size_t BStruct::mapcount() const
3✔
180
{
181
  return contents_.size();
3✔
182
}
183

184

185
BObjectRef BStruct::set_member( const char* membername, BObjectImp* value, bool copy )
608✔
186
{
187
  BObjectImp* target = copy ? value->copy() : value;
608✔
188
  auto itr = contents_.find( membername );
608✔
189
  if ( itr != contents_.end() )
608✔
190
  {
191
    BObjectRef& oref = ( *itr ).second;
187✔
192
    oref->setimp( target );
187✔
193
    return oref;
187✔
194
  }
195
  BObjectRef ref( new BObject( target ) );
421✔
196
  contents_.emplace( membername, ref );
421✔
197
  return ref;
421✔
198
}
421✔
199

200
// used programmatically
201
const BObjectImp* BStruct::FindMember( const char* name )
50✔
202
{
203
  auto itr = contents_.find( name );
50✔
204
  if ( itr != contents_.end() )
50✔
205
    return ( *itr ).second->impptr();
13✔
206
  return nullptr;
37✔
207
}
208

209
BObjectRef BStruct::get_member( const char* membername )
11,776✔
210
{
211
  auto itr = contents_.find( membername );
11,776✔
212
  if ( itr != contents_.end() )
11,776✔
213
    return ( *itr ).second;
11,720✔
214
  return BObjectRef( UninitObject::create() );
56✔
215
}
216

217
BObjectRef BStruct::OperSubscript( const BObject& obj )
276✔
218
{
219
  if ( obj->isa( OTString ) )
276✔
220
  {
221
    const String* keystr = obj.impptr<String>();
273✔
222

223
    auto itr = contents_.find( keystr->value() );
273✔
224
    if ( itr != contents_.end() )
273✔
225
    {
226
      BObjectRef& oref = ( *itr ).second;
270✔
227
      return oref;
270✔
228
    }
229
    return BObjectRef( UninitObject::create() );
3✔
230
  }
231
  return BObjectRef( new BError( "Struct members can only be accessed by name" ) );
3✔
232
}
233

234
BObjectImp* BStruct::array_assign( BObjectImp* idx, BObjectImp* target, bool copy )
38✔
235
{
236
  if ( auto* key = impptrIf<String>( idx ) )
38✔
237
  {
238
    BObjectImp* new_target = copy ? target->copy() : target;
35✔
239

240
    auto itr = contents_.find( key->value() );
35✔
241
    if ( itr != contents_.end() )
35✔
242
    {
243
      BObjectRef& oref = ( *itr ).second;
15✔
244
      oref->setimp( new_target );
15✔
245
      return new_target;
15✔
246
    }
247
    contents_[key->value()].set( new BObject( new_target ) );
20✔
248
    return new_target;
20✔
249
  }
250
  return new BError( "Struct members can only be accessed by name" );
3✔
251
}
252

253
void BStruct::addMember( const char* name, BObjectRef val )
×
254
{
255
  contents_[name] = val;
×
256
}
×
257

258
void BStruct::addMember( const char* name, BObjectImp* imp )
9,243✔
259
{
260
  contents_[name] = BObjectRef( imp );
9,243✔
261
}
9,243✔
262

263
BObjectImp* BStruct::call_method_id( const int id, Executor& ex, bool /*forcebuiltin*/ )
670✔
264
{
265
  BObject* keyobj;
266
  BObject* valobj;
267
  switch ( id )
670✔
268
  {
269
  case MTH_SIZE:
27✔
270
    if ( ex.numParams() == 0 )
27✔
271
      return new BLong( static_cast<int>( contents_.size() ) );
27✔
272
    return new BError( "struct.size() doesn't take parameters." );
×
273

274
  case MTH_ERASE:
×
275
    if ( ex.numParams() == 1 && ( keyobj = ex.getParamObj( 0 ) ) != nullptr )
×
276
    {
277
      if ( !keyobj->isa( OTString ) )
×
278
        return new BError( "Struct keys must be strings" );
×
279
      String* strkey = keyobj->impptr<String>();
×
280
      int nremove = static_cast<int>( contents_.erase( strkey->value() ) );
×
281
      return new BLong( nremove );
×
282
    }
283
    return new BError( "struct.erase(key) requires a parameter." );
×
284
    break;
285
  case MTH_INSERT:
15✔
286
    if ( ex.numParams() == 2 && ( keyobj = ex.getParamObj( 0 ) ) != nullptr &&
21✔
287
         ( valobj = ex.getParamObj( 1 ) ) != nullptr )
6✔
288
    {
289
      if ( !keyobj->isa( OTString ) )
6✔
290
        return new BError( "Struct keys must be strings" );
×
291
      String* strkey = keyobj->impptr<String>();
6✔
292
      contents_[strkey->value()] = BObjectRef( new BObject( valobj->impptr()->copy() ) );
6✔
293
      return new BLong( static_cast<int>( contents_.size() ) );
6✔
294
    }
295
    return new BError( "struct.insert(key,value) requires two parameters." );
9✔
296
    break;
297
  case MTH_EXISTS:
625✔
298
    if ( ex.numParams() == 1 && ( keyobj = ex.getParamObj( 0 ) ) != nullptr )
625✔
299
    {
300
      if ( !keyobj->isa( OTString ) )
625✔
301
        return new BError( "Struct keys must be strings" );
×
302
      String* strkey = keyobj->impptr<String>();
625✔
303
      int count = static_cast<int>( contents_.count( strkey->value() ) );
625✔
304
      return new BLong( count );
625✔
305
    }
306
    return new BError( "struct.exists(key) requires a parameter." );
×
307

308
  case MTH_KEYS:
×
309
    if ( ex.numParams() == 0 )
×
310
    {
311
      std::unique_ptr<ObjArray> arr( new ObjArray );
×
312
      for ( const auto& content : contents_ )
×
313
      {
314
        arr->addElement( new String( content.first ) );
×
315
      }
316
      return arr.release();
×
317
    }
×
318
    return new BError( "struct.keys() doesn't take parameters." );
×
319
    break;
320
  default:
3✔
321
    return nullptr;
3✔
322
  }
323
}
324

325
BObjectImp* BStruct::call_method( const char* methodname, Executor& ex )
×
326
{
327
  ObjMethod* objmethod = getKnownObjMethod( methodname );
×
328
  if ( objmethod != nullptr )
×
329
    return this->call_method_id( objmethod->id, ex );
×
330
  return nullptr;
×
331
}
332

333
void BStruct::packonto( std::ostream& os ) const
9✔
334
{
335
  os << packtype() << contents_.size() << ":";
9✔
336
  for ( const auto& content : contents_ )
24✔
337
  {
338
    const std::string& key = content.first;
15✔
339
    const BObjectRef& bvalref = content.second;
15✔
340

341
    String::packonto( os, key );
15✔
342
    bvalref->impref().packonto( os );
15✔
343
  }
344
}
9✔
345

346
std::string BStruct::getStringRep() const
2,248✔
347
{
348
  OSTRINGSTREAM os;
2,248✔
349
  os << typetag() << "{ ";
2,248✔
350
  bool any = false;
2,248✔
351

352
  for ( const auto& content : contents_ )
5,340✔
353
  {
354
    const std::string& key = content.first;
3,092✔
355
    const BObjectRef& bvalref = content.second;
3,092✔
356

357
    if ( any )
3,092✔
358
      os << ", ";
1,294✔
359
    else
360
      any = true;
1,798✔
361

362
    FormatForStringRep( os, key, bvalref );
3,092✔
363
  }
364

365
  os << " }";
2,248✔
366

367
  return OSTRINGSTREAM_STR( os );
4,496✔
368
}
2,248✔
369

370

371
BObjectRef BStruct::operDotPlus( const char* name )
1,945✔
372
{
373
  if ( contents_.count( name ) == 0 )
1,945✔
374
  {
375
    auto pnewobj = new BObject( new UninitObject );
1,939✔
376
    contents_[name] = BObjectRef( pnewobj );
1,939✔
377
    return BObjectRef( pnewobj );
1,939✔
378
  }
379
  return BObjectRef( new BError( "Member already exists" ) );
6✔
380
}
381

382
BObjectRef BStruct::operDotMinus( const char* name )
×
383
{
384
  contents_.erase( name );
×
385
  return BObjectRef( new BLong( 1 ) );
×
386
}
387

388
BObjectRef BStruct::operDotQMark( const char* name )
1,609✔
389
{
390
  int count = static_cast<int>( contents_.count( name ) );
1,609✔
391
  return BObjectRef( new BLong( count ) );
3,218✔
392
}
393

394
const BStruct::Contents& BStruct::contents() const
1,746✔
395
{
396
  return contents_;
1,746✔
397
}
398
}  // 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