3232#include < algorithm>
3333#include < cctype>
3434#include < ctime>
35+ #include < sstream>
3536
3637
3738namespace {
@@ -420,16 +421,13 @@ u8 const inp_header::MAGIC[inp_header::OFFS_BASETIME - inp_header::OFFS_MAGIC] =
420421// to the current list
421422// -------------------------------------------------
422423
423- void ioport_list::append (device_t &device, std::string &errorbuf)
424+ void ioport_list::append (device_t &device, std::ostream &errorbuf)
424425{
425426 // no constructor, no list
426427 ioport_constructor constructor = device.input_ports ();
427- if (constructor == nullptr )
428+ if (! constructor)
428429 return ;
429430
430- // reset error buffer
431- errorbuf.clear ();
432-
433431 // detokenize into the list
434432 (*constructor)(device, *this , errorbuf);
435433
@@ -692,7 +690,7 @@ ioport_setting::ioport_setting(ioport_field &field, ioport_value _value, const c
692690// ioport_diplocation - constructor
693691// -------------------------------------------------
694692
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) :
696694 m_name(name),
697695 m_number(swnum),
698696 m_invert(invert)
@@ -1359,7 +1357,7 @@ float ioport_field::crosshair_read() const
13591357// descriptions
13601358// -------------------------------------------------
13611359
1362- void ioport_field::expand_diplocation (const char *location, std::string &errorbuf)
1360+ void ioport_field::expand_diplocation (const char *location, std::ostream &errorbuf)
13631361{
13641362 // if nothing present, bail
13651363 if (!location)
@@ -1368,70 +1366,76 @@ void ioport_field::expand_diplocation(const char *location, std::string &errorbu
13681366 m_diploclist.clear ();
13691367
13701368 // 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;
13731370 const char *curentry = location;
13741371 int entries = 0 ;
1375- while (*curentry != 0 )
1372+ while (*curentry)
13761373 {
13771374 // find the end of this entry
13781375 const char *comma = strchr (curentry, ' ,' );
1379- if (comma == nullptr )
1376+ if (! comma)
13801377 comma = curentry + strlen (curentry);
13811378
13821379 // extract it to tempbuf
1383- std::string tempstr (curentry, comma - curentry);
1380+ std::string_view tempstr (curentry, comma - curentry);
13841381
13851382 // 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 ( ' :' );
13881385
1389- if (colon != nullptr )
1386+ std::string_view name;
1387+ if (colon != std::string_view::npos)
13901388 {
13911389 // allocate and copy the name if it is present
1392- lastname = name. assign (number , colon - number). c_str ( );
1390+ lastname = tempstr. substr ( 0 , colon);
13931391 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;
13941398 }
13951399 else
13961400 {
13971401 // otherwise, just copy the last name
1398- if (lastname == nullptr )
1402+ if (lastname. empty () )
13991403 {
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" ;
14021406 }
1403- name. assign ( lastname) ;
1407+ name = lastname;
14041408 }
14051409
14061410 // 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;
14131414
14141415 // now scan the switch number
14151416 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);
14181421
14191422 // 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);
14211425 entries++;
14221426
14231427 // advance to the next item
14241428 curentry = comma;
1425- if (*curentry != 0 )
1429+ if (*curentry)
14261430 curentry++;
14271431 }
14281432
14291433 // then verify the number of bits in the mask matches
14301434 int const bits = population_count_32 (m_mask);
14311435 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);
14331437 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);
14351439}
14361440
14371441
@@ -1638,7 +1642,7 @@ void ioport_port::frame_update()
16381642// wholly overlapped by other fields
16391643// -------------------------------------------------
16401644
1641- void ioport_port::collapse_fields (std::string &errorbuf)
1645+ void ioport_port::collapse_fields (std::ostream &errorbuf)
16421646{
16431647 ioport_value maskbits = 0 ;
16441648 int lastmodcount = -1 ;
@@ -1667,13 +1671,13 @@ void ioport_port::collapse_fields(std::string &errorbuf)
16671671// for errors
16681672// -------------------------------------------------
16691673
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)
16711675{
16721676 // verify against the disallowed bits, but only if we are condition-free
16731677 if (newfield.condition ().none ())
16741678 {
16751679 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 ());
16771681 disallowedbits |= newfield.mask ();
16781682 }
16791683
@@ -1812,12 +1816,17 @@ time_t ioport_manager::initialize()
18121816
18131817 // if we have a token list, proceed
18141818 device_enumerator iter (machine ().root_device ());
1815- for (device_t &device : iter)
18161819 {
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+ }
18211830 }
18221831
18231832 // renumber player numbers for controller ports
@@ -3274,7 +3283,7 @@ void ioport_manager::record_port(ioport_port &port)
32743283// ioport_configurer - constructor
32753284// -------------------------------------------------
32763285
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) :
32783287 m_owner(owner),
32793288 m_portlist(portlist),
32803289 m_errorbuf(errorbuf),
0 commit comments