• 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

57.84
/pol-core/pol/storage.cpp
1
/** @file
2
 *
3
 * @par History
4
 * - 2005/11/26 Shinigami: changed "strcmp" into "stricmp" to suppress Script Errors
5
 */
6

7

8
#include "storage.h"
9

10
#include <exception>
11
#include <string>
12
#include <time.h>
13

14
#include "../bscript/berror.h"
15
#include "../bscript/bobject.h"
16
#include "../bscript/contiter.h"
17
#include "../bscript/impstr.h"
18
#include "../clib/cfgelem.h"
19
#include "../clib/cfgfile.h"
20
#include "../clib/clib.h"
21
#include "../clib/logfacility.h"
22
#include "../clib/rawtypes.h"
23
#include "../clib/stlutil.h"
24
#include "../clib/streamsaver.h"
25
#include "../plib/poltype.h"
26
#include "../plib/systemstate.h"
27
#include "containr.h"
28
#include "fnsearch.h"
29
#include "globals/object_storage.h"
30
#include "globals/uvars.h"
31
#include "item/item.h"
32
#include "loaddata.h"
33
#include "mkscrobj.h"
34
#include "ufunc.h"
35

36

37
namespace Pol::Core
38
{
39
using namespace Bscript;
40

41
StorageArea::StorageArea( std::string name ) : _name( name ) {}
6✔
42

43
StorageArea::~StorageArea()
6✔
44
{
45
  while ( !_items.empty() )
10✔
46
  {
47
    Cont::iterator itr = _items.begin();
4✔
48
    Items::Item* item = ( *itr ).second;
4✔
49
    item->destroy();
4✔
50
    _items.erase( itr );
4✔
51
  }
52
}
6✔
53

54
size_t StorageArea::estimateSize() const
×
55
{
56
  size_t size = _name.capacity() + Clib::memsize( _items );
×
57
  return size;
×
58
}
59

60

61
Items::Item* StorageArea::find_root_item( const std::string& name )
6✔
62
{
63
  // LINEAR_SEARCH
64
  Cont::iterator itr = _items.find( name );
6✔
65
  if ( itr != _items.end() )
6✔
66
  {
67
    return ( *itr ).second;
6✔
68
  }
69
  return nullptr;
×
70
}
71

72
bool StorageArea::delete_root_item( const std::string& name )
1✔
73
{
74
  Cont::iterator itr = _items.find( name );
1✔
75
  if ( itr != _items.end() )
1✔
76
  {
77
    Items::Item* item = ( *itr ).second;
1✔
78
    item->destroy();
1✔
79
    _items.erase( itr );
1✔
80
    return true;
1✔
81
  }
82
  return false;
×
83
}
84

85
void StorageArea::insert_root_item( Items::Item* item )
5✔
86
{
87
  item->inuse( true );
5✔
88

89
  _items.insert( make_pair( item->name(), item ) );
5✔
90
}
5✔
91

92
extern Items::Item* read_item( Clib::ConfigElem& elem );  // from UIMPORT.CPP
93

94
void StorageArea::load_item( Clib::ConfigElem& elem )
6✔
95
{
96
  u32 container_serial = 0;                                  // defaults to item at storage root,
6✔
97
  (void)elem.remove_prop( "CONTAINER", &container_serial );  // so the return value can be ignored
6✔
98

99
  Items::Item* item = read_item( elem );
6✔
100
  // Austin added 8/10/2006, protect against further crash if item is null. Should throw instead?
101
  if ( item == nullptr )
6✔
102
  {
103
    elem.warn_with_line( "Error reading item SERIAL or OBJTYPE." );
×
104
    return;
×
105
  }
106
  if ( container_serial == 0 )
6✔
107
  {
108
    insert_root_item( item );
2✔
109
  }
110
  else
111
  {
112
    Items::Item* cont_item = Core::system_find_item( container_serial );
4✔
113

114
    if ( cont_item )
4✔
115
    {
116
      add_loaded_item( cont_item, item );
4✔
117
    }
118
    else
119
    {
120
      defer_item_insertion( item, container_serial );
×
121
    }
122
  }
123
}
124
StorageArea* Storage::find_area( const std::string& name )
3✔
125
{
126
  AreaCont::iterator itr = areas.find( name );
3✔
127
  if ( itr == areas.end() )
3✔
128
    return nullptr;
×
129
  return ( *itr ).second;
3✔
130
}
131

132
StorageArea* Storage::create_area( const std::string& name )
6✔
133
{
134
  AreaCont::iterator itr = areas.find( name );
6✔
135
  if ( itr == areas.end() )
6✔
136
  {
137
    StorageArea* area = new StorageArea( name );
6✔
138
    areas[name] = area;
6✔
139
    return area;
6✔
140
  }
141

NEW
142
  return ( *itr ).second;
×
143
}
144

145
StorageArea* Storage::create_area( Clib::ConfigElem& elem )
3✔
146
{
147
  const char* rest = elem.rest();
3✔
148
  if ( rest != nullptr && rest[0] )
3✔
149
  {
150
    return create_area( rest );
×
151
  }
152

153
  std::string name = elem.remove_string( "NAME" );
3✔
154
  return create_area( name );
3✔
155
}
3✔
156

157

158
void StorageArea::print( Clib::StreamWriter& sw ) const
6✔
159
{
160
  for ( const auto& cont_item : _items )
10✔
161
  {
162
    const Items::Item* item = cont_item.second;
4✔
163
    if ( item->saveonexit() )
4✔
164
      item->printOn( sw );
4✔
165
  }
166
}
6✔
167

168
void StorageArea::on_delete_realm( Realms::Realm* realm )
×
169
{
170
  for ( Cont::const_iterator itr = _items.begin(), itrend = _items.end(); itr != itrend; ++itr )
×
171
  {
172
    Items::Item* item = ( *itr ).second;
×
173
    if ( item )
×
174
    {
175
      setrealmif( item, (void*)realm );
×
176
      if ( item->isa( UOBJ_CLASS::CLASS_CONTAINER ) )
×
177
      {
178
        UContainer* cont = static_cast<UContainer*>( item );
×
179
        cont->for_each_item( setrealmif, (void*)realm );
×
180
      }
181
    }
182
  }
183
}
×
184

185
void Storage::on_delete_realm( Realms::Realm* realm )
4✔
186
{
187
  for ( AreaCont::const_iterator itr = areas.begin(), itrend = areas.end(); itr != itrend; ++itr )
4✔
188
  {
189
    itr->second->on_delete_realm( realm );
×
190
  }
191
}
4✔
192

193
void Storage::read( Clib::ConfigFile& cf )
1✔
194
{
195
  static int num_until_dot = 1000;
196
  unsigned int nobjects = 0;
1✔
197

198
  StorageArea* area = nullptr;
1✔
199
  Clib::ConfigElem elem;
1✔
200

201
  clock_t start = clock();
1✔
202

203
  while ( cf.read( elem ) )
10✔
204
  {
205
    if ( --num_until_dot == 0 )
9✔
206
    {
207
      INFO_PRINT( "." );
×
208
      num_until_dot = 1000;
×
209
    }
210
    if ( elem.type_is( "StorageArea" ) )
9✔
211
    {
212
      area = create_area( elem );
3✔
213
    }
214
    else if ( elem.type_is( "Item" ) )
6✔
215
    {
216
      if ( area != nullptr )
6✔
217
      {
218
        try
219
        {
220
          area->load_item( elem );
6✔
221
        }
222
        catch ( std::exception& )
×
223
        {
224
          if ( !Plib::systemstate.config.ignore_load_errors )
×
225
            throw;
×
226
        }
×
227
      }
228
      else
229
      {
230
        ERROR_PRINTLN( "Storage: Got an ITEM element, but don't have a StorageArea to put it." );
×
231
        throw std::runtime_error( "Data file integrity error" );
×
232
      }
233
    }
234
    else
235
    {
236
      ERROR_PRINTLN( "Unexpected element type {} in storage file.", elem.type() );
×
237
      throw std::runtime_error( "Data file integrity error" );
×
238
    }
239
    ++nobjects;
9✔
240
  }
241

242
  clock_t end = clock();
1✔
243
  int ms = static_cast<int>( ( end - start ) * 1000.0 / CLOCKS_PER_SEC );
1✔
244

245
  INFO_PRINTLN( " {} elements in {} ms.", nobjects, ms );
1✔
246
}
1✔
247

248
void Storage::print( Clib::StreamWriter& sw ) const
4✔
249
{
250
  for ( const auto& area : areas )
10✔
251
  {
252
    sw.begin( "StorageArea" );
6✔
253
    sw.add( "Name", area.first );
6✔
254
    sw.end();
6✔
255
    area.second->print( sw );
6✔
256
  }
257
}
4✔
258

259
void Storage::clear()
3✔
260
{
261
  while ( !areas.empty() )
9✔
262
  {
263
    delete ( ( *areas.begin() ).second );
6✔
264
    areas.erase( areas.begin() );
6✔
265
  }
266
}
3✔
267

268
size_t Storage::estimateSize() const
1✔
269
{
270
  size_t size = Clib::memsize( areas );
1✔
271
  for ( const auto& area : areas )
1✔
272
  {
273
    if ( area.second != nullptr )
×
274
      size += area.second->estimateSize();
×
275
  }
276
  return size;
1✔
277
}
278

279
class StorageAreaIterator final : public ContIterator
280
{
281
public:
282
  StorageAreaIterator( StorageArea* area, BObject* pIter );
283
  BObject* step() override;
284

285
private:
286
  BObject* m_pIterVal;
287
  std::string key;
288
  StorageArea* _area;
289
};
290

291
StorageAreaIterator::StorageAreaIterator( StorageArea* area, BObject* pIter )
×
292
    : ContIterator(), m_pIterVal( pIter ), key( "" ), _area( area )
×
293
{
294
}
×
295

296
BObject* StorageAreaIterator::step()
×
297
{
298
  StorageArea::Cont::iterator itr = _area->_items.lower_bound( key );
×
299
  if ( !key.empty() && itr != _area->_items.end() )
×
300
  {
301
    ++itr;
×
302
  }
303

304
  if ( itr == _area->_items.end() )
×
305
    return nullptr;
×
306

307
  key = ( *itr ).first;
×
308
  m_pIterVal->setimp( new String( key ) );
×
309
  BObject* result = new BObject( make_itemref( ( *itr ).second ) );
×
310
  return result;
×
311
}
312

313
ContIterator* StorageAreaImp::createIterator( BObject* pIterVal )
×
314
{
315
  return new StorageAreaIterator( _area, pIterVal );
×
316
}
317

318
BObjectRef StorageAreaImp::get_member( const char* membername )
8✔
319
{
320
  if ( stricmp( membername, "count" ) == 0 )
8✔
321
  {
322
    return BObjectRef( new BLong( static_cast<int>( _area->_items.size() ) ) );
2✔
323
  }
324
  if ( stricmp( membername, "totalcount" ) == 0 )
6✔
325
  {
326
    unsigned int total = 0;
6✔
327
    for ( StorageArea::Cont::iterator itr = _area->_items.begin(); itr != _area->_items.end();
12✔
328
          ++itr )
6✔
329
    {
330
      Items::Item* item = ( *itr ).second;
6✔
331
      total += item->item_count();
6✔
332
    }
333
    return BObjectRef( new BLong( total ) );
6✔
334
  }
335
  return BObjectRef( UninitObject::create() );
×
336
}
337

338

339
class StorageAreasIterator final : public ContIterator
340
{
341
public:
342
  StorageAreasIterator( BObject* pIter );
343
  BObject* step() override;
344

345
private:
346
  BObject* m_pIterVal;
347
  std::string key;
348
};
349

350
StorageAreasIterator::StorageAreasIterator( BObject* pIter )
×
351
    : ContIterator(), m_pIterVal( pIter ), key( "" )
×
352
{
353
}
×
354

355
BObject* StorageAreasIterator::step()
×
356
{
357
  Storage::AreaCont::iterator itr = gamestate.storage.areas.lower_bound( key );
×
358
  if ( !key.empty() && itr != gamestate.storage.areas.end() )
×
359
  {
360
    ++itr;
×
361
  }
362

363
  if ( itr == gamestate.storage.areas.end() )
×
364
    return nullptr;
×
365

366
  key = ( *itr ).first;
×
367
  m_pIterVal->setimp( new String( key ) );
×
368
  BObject* result = new BObject( new StorageAreaImp( ( *itr ).second ) );
×
369
  return result;
×
370
}
371

372
class StorageAreasImp final : public BObjectImp
373
{
374
public:
375
  StorageAreasImp() : BObjectImp( BObjectImp::OTUnknown ) {}
1✔
376
  BObjectImp* copy() const override { return new StorageAreasImp(); }
×
377
  std::string getStringRep() const override { return "<StorageAreas>"; }
×
378
  size_t sizeEstimate() const override { return sizeof( *this ); }
×
379
  ContIterator* createIterator( BObject* pIterVal ) override
×
380
  {
381
    return new StorageAreasIterator( pIterVal );
×
382
  }
383

384
  BObjectRef get_member( const char* membername ) override;
385

386
  BObjectRef OperSubscript( const BObject& obj ) override;
387
};
388

389
BObjectImp* CreateStorageAreasImp()
1✔
390
{
391
  return new StorageAreasImp();
1✔
392
}
393

394
BObjectRef StorageAreasImp::get_member( const char* membername )
1✔
395
{
396
  if ( stricmp( membername, "count" ) == 0 )
1✔
397
  {
398
    return BObjectRef( new BLong( static_cast<int>( gamestate.storage.areas.size() ) ) );
1✔
399
  }
400
  return BObjectRef( UninitObject::create() );
×
401
}
402
BObjectRef StorageAreasImp::OperSubscript( const BObject& obj )
×
403
{
404
  if ( obj.isa( OTString ) )
×
405
  {
406
    String& rtstr = (String&)obj.impref();
×
407
    std::string key = rtstr.value();
×
408

409
    Storage::AreaCont::iterator itr = gamestate.storage.areas.find( key );
×
410
    if ( itr != gamestate.storage.areas.end() )
×
411
    {
412
      return BObjectRef( new BObject( new StorageAreaImp( ( *itr ).second ) ) );
×
413
    }
414

NEW
415
    return BObjectRef( new BObject( new BError( "Storage Area not found" ) ) );
×
416
  }
×
417
  return BObjectRef( new BObject( new BError( "Invalid parameter type" ) ) );
×
418
}
419
}  // namespace Pol::Core
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