32
32
#include < algorithm>
33
33
#include < cctype>
34
34
#include < ctime>
35
+ #include < sstream>
35
36
36
37
37
38
namespace {
@@ -420,16 +421,13 @@ u8 const inp_header::MAGIC[inp_header::OFFS_BASETIME - inp_header::OFFS_MAGIC] =
420
421
// to the current list
421
422
// -------------------------------------------------
422
423
423
- void ioport_list::append (device_t &device, std::string &errorbuf)
424
+ void ioport_list::append (device_t &device, std::ostream &errorbuf)
424
425
{
425
426
// no constructor, no list
426
427
ioport_constructor constructor = device.input_ports ();
427
- if (constructor == nullptr )
428
+ if (! constructor)
428
429
return ;
429
430
430
- // reset error buffer
431
- errorbuf.clear ();
432
-
433
431
// detokenize into the list
434
432
(*constructor)(device, *this , errorbuf);
435
433
@@ -692,7 +690,7 @@ ioport_setting::ioport_setting(ioport_field &field, ioport_value _value, const c
692
690
// ioport_diplocation - constructor
693
691
// -------------------------------------------------
694
692
695
- ioport_diplocation::ioport_diplocation (const char * name, u8 swnum, bool invert) :
693
+ ioport_diplocation::ioport_diplocation (std::string_view name, u8 swnum, bool invert) :
696
694
m_name(name),
697
695
m_number(swnum),
698
696
m_invert(invert)
@@ -1359,7 +1357,7 @@ float ioport_field::crosshair_read() const
1359
1357
// descriptions
1360
1358
// -------------------------------------------------
1361
1359
1362
- void ioport_field::expand_diplocation (const char *location, std::string &errorbuf)
1360
+ void ioport_field::expand_diplocation (const char *location, std::ostream &errorbuf)
1363
1361
{
1364
1362
// if nothing present, bail
1365
1363
if (!location)
@@ -1368,70 +1366,76 @@ void ioport_field::expand_diplocation(const char *location, std::string &errorbu
1368
1366
m_diploclist.clear ();
1369
1367
1370
1368
// parse the string
1371
- std::string name; // Don't move this variable inside the loop, lastname's lifetime depends on it being outside
1372
- const char *lastname = nullptr ;
1369
+ std::string_view lastname;
1373
1370
const char *curentry = location;
1374
1371
int entries = 0 ;
1375
- while (*curentry != 0 )
1372
+ while (*curentry)
1376
1373
{
1377
1374
// find the end of this entry
1378
1375
const char *comma = strchr (curentry, ' ,' );
1379
- if (comma == nullptr )
1376
+ if (! comma)
1380
1377
comma = curentry + strlen (curentry);
1381
1378
1382
1379
// extract it to tempbuf
1383
- std::string tempstr (curentry, comma - curentry);
1380
+ std::string_view tempstr (curentry, comma - curentry);
1384
1381
1385
1382
// first extract the switch name if present
1386
- const char * number = tempstr. c_str () ;
1387
- const char * colon = strchr ( tempstr.c_str (), ' :' );
1383
+ std::string_view::size_type number = 0 ;
1384
+ std::string_view::size_type const colon = tempstr.find ( ' :' );
1388
1385
1389
- if (colon != nullptr )
1386
+ std::string_view name;
1387
+ if (colon != std::string_view::npos)
1390
1388
{
1391
1389
// allocate and copy the name if it is present
1392
- lastname = name. assign (number , colon - number). c_str ( );
1390
+ lastname = tempstr. substr ( 0 , colon);
1393
1391
number = colon + 1 ;
1392
+ if (lastname.empty ())
1393
+ {
1394
+ util::stream_format (errorbuf, " Switch location '%s' has empty switch name!\n " , location);
1395
+ lastname = " UNK" ;
1396
+ }
1397
+ name = lastname;
1394
1398
}
1395
1399
else
1396
1400
{
1397
1401
// otherwise, just copy the last name
1398
- if (lastname == nullptr )
1402
+ if (lastname. empty () )
1399
1403
{
1400
- errorbuf. append ( string_format ( " Switch location '%s' missing switch name!\n " , location) );
1401
- lastname = ( char *) " UNK" ;
1404
+ util::stream_format (errorbuf, " Switch location '%s' missing switch name!\n " , location);
1405
+ lastname = " UNK" ;
1402
1406
}
1403
- name. assign ( lastname) ;
1407
+ name = lastname;
1404
1408
}
1405
1409
1406
1410
// if the number is preceded by a '!' it's active high
1407
- bool invert = false ;
1408
- if (*number == ' !' )
1409
- {
1410
- invert = true ;
1411
- number++;
1412
- }
1411
+ bool const invert = tempstr[number] == ' !' ;
1412
+ if (invert)
1413
+ ++number;
1413
1414
1414
1415
// now scan the switch number
1415
1416
int swnum = -1 ;
1416
- if (sscanf (number, " %d" , &swnum) != 1 )
1417
- errorbuf.append (string_format (" Switch location '%s' has invalid format!\n " , location));
1417
+ if (sscanf (&tempstr[number], " %d" , &swnum) != 1 )
1418
+ util::stream_format (errorbuf, " Switch location '%s' has invalid format!\n " , location);
1419
+ else if (0 >= swnum)
1420
+ util::stream_format (errorbuf, " Switch location '%s' has switch number that is not positive!\n " , location);
1418
1421
1419
1422
// allocate a new entry
1420
- m_diploclist.emplace_back (name.c_str (), swnum, invert);
1423
+ if (0 < swnum)
1424
+ m_diploclist.emplace_back (name, swnum, invert);
1421
1425
entries++;
1422
1426
1423
1427
// advance to the next item
1424
1428
curentry = comma;
1425
- if (*curentry != 0 )
1429
+ if (*curentry)
1426
1430
curentry++;
1427
1431
}
1428
1432
1429
1433
// then verify the number of bits in the mask matches
1430
1434
int const bits = population_count_32 (m_mask);
1431
1435
if (bits > entries)
1432
- errorbuf. append ( string_format ( " Switch location '%s' does not describe enough bits for mask %X\n " , location, m_mask) );
1436
+ util::stream_format (errorbuf, " Switch location '%s' does not describe enough bits for mask %X\n " , location, m_mask);
1433
1437
else if (bits < entries)
1434
- errorbuf. append ( string_format ( " Switch location '%s' describes too many bits for mask %X\n " , location, m_mask) );
1438
+ util::stream_format (errorbuf, " Switch location '%s' describes too many bits for mask %X\n " , location, m_mask);
1435
1439
}
1436
1440
1437
1441
@@ -1638,7 +1642,7 @@ void ioport_port::frame_update()
1638
1642
// wholly overlapped by other fields
1639
1643
// -------------------------------------------------
1640
1644
1641
- void ioport_port::collapse_fields (std::string &errorbuf)
1645
+ void ioport_port::collapse_fields (std::ostream &errorbuf)
1642
1646
{
1643
1647
ioport_value maskbits = 0 ;
1644
1648
int lastmodcount = -1 ;
@@ -1667,13 +1671,13 @@ void ioport_port::collapse_fields(std::string &errorbuf)
1667
1671
// for errors
1668
1672
// -------------------------------------------------
1669
1673
1670
- void ioport_port::insert_field (ioport_field &newfield, ioport_value &disallowedbits, std::string &errorbuf)
1674
+ void ioport_port::insert_field (ioport_field &newfield, ioport_value &disallowedbits, std::ostream &errorbuf)
1671
1675
{
1672
1676
// verify against the disallowed bits, but only if we are condition-free
1673
1677
if (newfield.condition ().none ())
1674
1678
{
1675
1679
if ((newfield.mask () & disallowedbits) != 0 )
1676
- errorbuf. append ( string_format ( " INPUT_TOKEN_FIELD specifies duplicate port bits (port=%s mask=%X)\n " , tag (), newfield.mask () ));
1680
+ util::stream_format (errorbuf, " INPUT_TOKEN_FIELD specifies duplicate port bits (port=%s mask=%X)\n " , tag (), newfield.mask ());
1677
1681
disallowedbits |= newfield.mask ();
1678
1682
}
1679
1683
@@ -1812,12 +1816,17 @@ time_t ioport_manager::initialize()
1812
1816
1813
1817
// if we have a token list, proceed
1814
1818
device_enumerator iter (machine ().root_device ());
1815
- for (device_t &device : iter)
1816
1819
{
1817
- std::string errors;
1818
- m_portlist.append (device, errors);
1819
- if (!errors.empty ())
1820
- osd_printf_error (" Input port errors:\n %s" , errors);
1820
+ std::ostringstream errors;
1821
+ for (device_t &device : iter)
1822
+ {
1823
+ m_portlist.append (device, errors);
1824
+ if (errors.tellp ())
1825
+ {
1826
+ osd_printf_error (" Input port errors:\n %s" , std::move (errors).str ());
1827
+ errors.str (" " );
1828
+ }
1829
+ }
1821
1830
}
1822
1831
1823
1832
// renumber player numbers for controller ports
@@ -3274,7 +3283,7 @@ void ioport_manager::record_port(ioport_port &port)
3274
3283
// ioport_configurer - constructor
3275
3284
// -------------------------------------------------
3276
3285
3277
- ioport_configurer::ioport_configurer (device_t &owner, ioport_list &portlist, std::string &errorbuf) :
3286
+ ioport_configurer::ioport_configurer (device_t &owner, ioport_list &portlist, std::ostream &errorbuf) :
3278
3287
m_owner(owner),
3279
3288
m_portlist(portlist),
3280
3289
m_errorbuf(errorbuf),
0 commit comments