diff --git a/src/misc/CMakeLists.txt b/src/misc/CMakeLists.txt --- a/src/misc/CMakeLists.txt +++ b/src/misc/CMakeLists.txt @@ -11,5 +11,4 @@ add_files( getoptdata.h hashtable.hpp lrucache.hpp - str.hpp ) diff --git a/src/misc/array.hpp b/src/misc/array.hpp --- a/src/misc/array.hpp +++ b/src/misc/array.hpp @@ -11,7 +11,7 @@ #define ARRAY_HPP #include "fixedsizearray.hpp" -#include "str.hpp" +#include "../string_func.h" /** * Flexible array with size limit. Implemented as fixed size @@ -103,14 +103,14 @@ public: */ template void Dump(D &dmp) const { - dmp.WriteLine("capacity = %d", Tcapacity); + dmp.WriteValue("capacity", Tcapacity); uint num_items = Length(); - dmp.WriteLine("num_items = %d", num_items); - CStrA name; + dmp.WriteValue("num_items", num_items); for (uint i = 0; i < num_items; i++) { const T &item = (*this)[i]; - name.Format("item[%d]", i); - dmp.WriteStructT(name.Data(), &item); + char name[32]; + seprintf(name, lastof(name), "item[%d]", i); + dmp.WriteStructT(name, &item); } } }; diff --git a/src/misc/dbg_helpers.cpp b/src/misc/dbg_helpers.cpp --- a/src/misc/dbg_helpers.cpp +++ b/src/misc/dbg_helpers.cpp @@ -10,6 +10,10 @@ #include "../stdafx.h" #include "../rail_map.h" #include "dbg_helpers.h" +#include "blob.hpp" + +#include +#include #include "../safeguards.h" @@ -20,19 +24,15 @@ static const char * const trackdir_names }; /** Return name of given Trackdir. */ -CStrA ValueStr(Trackdir td) +std::string ValueStr(Trackdir td) { - CStrA out; - out.Format("%d (%s)", td, ItemAtT(td, trackdir_names, "UNK", INVALID_TRACKDIR, "INV")); - return out.Transfer(); + return std::to_string(td) + " (" + ItemAtT(td, trackdir_names, "UNK", INVALID_TRACKDIR, "INV") + ")"; } /** Return composed name of given TrackdirBits. */ -CStrA ValueStr(TrackdirBits td_bits) +std::string ValueStr(TrackdirBits td_bits) { - CStrA out; - out.Format("%d (%s)", td_bits, ComposeNameT(td_bits, trackdir_names, "UNK", INVALID_TRACKDIR_BIT, "INV").Data()); - return out.Transfer(); + return std::to_string(td_bits) + " (" + ComposeNameT(td_bits, trackdir_names, "UNK", INVALID_TRACKDIR_BIT, "INV") + ")"; } @@ -42,11 +42,9 @@ static const char * const diagdir_names[ }; /** Return name of given DiagDirection. */ -CStrA ValueStr(DiagDirection dd) +std::string ValueStr(DiagDirection dd) { - CStrA out; - out.Format("%d (%s)", dd, ItemAtT(dd, diagdir_names, "UNK", INVALID_DIAGDIR, "INV")); - return out.Transfer(); + return std::to_string(dd) + " (" + ItemAtT(dd, diagdir_names, "UNK", INVALID_DIAGDIR, "INV") + ")"; } @@ -56,20 +54,19 @@ static const char * const signal_type_na }; /** Return name of given SignalType. */ -CStrA ValueStr(SignalType t) +std::string ValueStr(SignalType t) { - CStrA out; - out.Format("%d (%s)", t, ItemAtT(t, signal_type_names, "UNK")); - return out.Transfer(); + return std::to_string(t) + " (" + ItemAtT(t, signal_type_names, "UNK") + ")"; } /** Translate TileIndex into string. */ -CStrA TileStr(TileIndex tile) +std::string TileStr(TileIndex tile) { - CStrA out; - out.Format("0x%04X (%d, %d)", tile, TileX(tile), TileY(tile)); - return out.Transfer(); + std::stringstream ss; + ss << "0x" << std::setfill('0') << std::setw(4) << std::hex << tile; // 0x%04X + ss << " (" << TileX(tile) << ", " << TileY(tile) << ")"; + return ss.str(); } /** @@ -81,21 +78,21 @@ CStrA TileStr(TileIndex tile) } /** Return structured name of the current class/structure. */ -CStrA DumpTarget::GetCurrentStructName() +std::string DumpTarget::GetCurrentStructName() { - CStrA out; + std::string out; if (!m_cur_struct.empty()) { /* we are inside some named struct, return its name */ out = m_cur_struct.top(); } - return out.Transfer(); + return out; } /** * Find the given instance in our anti-recursion repository. * Return true and set name when object was found. */ -bool DumpTarget::FindKnownName(size_t type_id, const void *ptr, CStrA &name) +bool DumpTarget::FindKnownName(size_t type_id, const void *ptr, std::string &name) { KNOWN_NAMES::const_iterator it = m_known_names.find(KnownStructKey(type_id, ptr)); if (it != m_known_names.end()) { @@ -111,33 +108,29 @@ void DumpTarget::WriteIndent() { int num_spaces = 2 * m_indent; if (num_spaces > 0) { - memset(m_out.GrowSizeNC(num_spaces), ' ', num_spaces); + m_out += std::string(num_spaces, ' '); } } -/** Write a line with indent at the beginning and \ at the end. */ -void DumpTarget::WriteLine(const char *format, ...) +/** Write 'name = value' with indent and new-line. */ +void DumpTarget::WriteValue(const char *name, int value) { WriteIndent(); - va_list args; - va_start(args, format); - m_out.AddFormatL(format, args); - va_end(args); - m_out.AppendStr("\n"); + m_out += std::string(name) + " = " + std::to_string(value) + "\n"; } /** Write 'name = value' with indent and new-line. */ void DumpTarget::WriteValue(const char *name, const char *value_str) { WriteIndent(); - m_out.AddFormat("%s = %s\n", name, value_str); + m_out += std::string(name) + " = " + value_str + "\n"; } /** Write name & TileIndex to the output. */ void DumpTarget::WriteTile(const char *name, TileIndex tile) { WriteIndent(); - m_out.AddFormat("%s = %s\n", name, TileStr(tile).Data()); + m_out += std::string(name) + " = " + TileStr(tile) + "\n"; } /** @@ -146,12 +139,12 @@ void DumpTarget::WriteTile(const char *n void DumpTarget::BeginStruct(size_t type_id, const char *name, const void *ptr) { /* make composite name */ - CStrA cur_name = GetCurrentStructName().Transfer(); - if (cur_name.Size() > 0) { + std::string cur_name = GetCurrentStructName(); + if (cur_name.size() > 0) { /* add name delimiter (we use structured names) */ - cur_name.AppendStr("."); + cur_name += "."; } - cur_name.AppendStr(name); + cur_name += name; /* put the name onto stack (as current struct name) */ m_cur_struct.push(cur_name); @@ -160,7 +153,7 @@ void DumpTarget::BeginStruct(size_t type m_known_names.insert(KNOWN_NAMES::value_type(KnownStructKey(type_id, ptr), cur_name)); WriteIndent(); - m_out.AddFormat("%s = {\n", name); + m_out += std::string(name) + " = {\n"; m_indent++; } @@ -171,7 +164,7 @@ void DumpTarget::EndStruct() { m_indent--; WriteIndent(); - m_out.AddFormat("}\n"); + m_out += "}\n"; /* remove current struct name from the stack */ m_cur_struct.pop(); diff --git a/src/misc/dbg_helpers.h b/src/misc/dbg_helpers.h --- a/src/misc/dbg_helpers.h +++ b/src/misc/dbg_helpers.h @@ -12,8 +12,7 @@ #include #include - -#include "str.hpp" +#include #include "../direction_type.h" #include "../signal_type.h" @@ -67,9 +66,9 @@ inline typename ArrayT::item_t ItemAt * or t_unk when index is out of bounds. */ template -inline CStrA ComposeNameT(E value, T &t, const char *t_unk, E val_inv, const char *name_inv) +inline std::string ComposeNameT(E value, T &t, const char *t_unk, E val_inv, const char *name_inv) { - CStrA out; + std::string out; if (value == val_inv) { out = name_inv; } else if (value == 0) { @@ -77,18 +76,22 @@ inline CStrA ComposeNameT(E value, T &t, } else { for (size_t i = 0; i < ArrayT::length; i++) { if ((value & (1 << i)) == 0) continue; - out.AddFormat("%s%s", (out.Size() > 0 ? "+" : ""), (const char*)t[i]); + out += (!out.empty() ? "+" : ""); + out += t[i]; value &= ~(E)(1 << i); } - if (value != 0) out.AddFormat("%s%s", (out.Size() > 0 ? "+" : ""), t_unk); + if (value != 0) { + out += (!out.empty() ? "+" : ""); + out += t_unk; + } } - return out.Transfer(); + return out; } -CStrA ValueStr(Trackdir td); -CStrA ValueStr(TrackdirBits td_bits); -CStrA ValueStr(DiagDirection dd); -CStrA ValueStr(SignalType t); +std::string ValueStr(Trackdir td); +std::string ValueStr(TrackdirBits td_bits); +std::string ValueStr(DiagDirection dd); +std::string ValueStr(SignalType t); /** Class that represents the dump-into-string target. */ struct DumpTarget { @@ -118,31 +121,31 @@ struct DumpTarget { } }; - typedef std::map KNOWN_NAMES; + typedef std::map KNOWN_NAMES; - CStrA m_out; ///< the output string - int m_indent; ///< current indent/nesting level - std::stack m_cur_struct; ///< here we will track the current structure name - KNOWN_NAMES m_known_names; ///< map of known object instances and their structured names + std::string m_out; ///< the output string + int m_indent; ///< current indent/nesting level + std::stack m_cur_struct; ///< here we will track the current structure name + KNOWN_NAMES m_known_names; ///< map of known object instances and their structured names DumpTarget() : m_indent(0) {} static size_t& LastTypeId(); - CStrA GetCurrentStructName(); - bool FindKnownName(size_t type_id, const void *ptr, CStrA &name); + std::string GetCurrentStructName(); + bool FindKnownName(size_t type_id, const void *ptr, std::string &name); void WriteIndent(); - void CDECL WriteLine(const char *format, ...) WARN_FORMAT(2, 3); + void WriteValue(const char *name, int value); void WriteValue(const char *name, const char *value_str); void WriteTile(const char *name, TileIndex t); /** Dump given enum value (as a number and as named value) */ template void WriteEnumT(const char *name, E e) { - WriteValue(name, ValueStr(e).Data()); + WriteValue(name, ValueStr(e).c_str()); } void BeginStruct(size_t type_id, const char *name, const void *ptr); @@ -155,13 +158,14 @@ struct DumpTarget { if (s == nullptr) { /* No need to dump nullptr struct. */ - WriteLine("%s = ", name); + WriteValue(name, ""); return; } - CStrA known_as; + std::string known_as; if (FindKnownName(type_id, s, known_as)) { /* We already know this one, no need to dump it. */ - WriteLine("%s = known_as.%s", name, known_as.Data()); + std::string known_as_str = std::string("known_as.") + name; + WriteValue(name, known_as_str.c_str()); } else { /* Still unknown, dump it */ BeginStruct(type_id, name, s); diff --git a/src/misc/str.hpp b/src/misc/str.hpp deleted file mode 100644 --- a/src/misc/str.hpp +++ /dev/null @@ -1,149 +0,0 @@ -/* - * This file is part of OpenTTD. - * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2. - * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see . - */ - -/** @file str.hpp String formatting? */ - -#ifndef STR_HPP -#define STR_HPP - -#include -#include -#include "blob.hpp" -#include "../core/math_func.hpp" -#include "../string_func.h" - -/** Blob based case sensitive ANSI/UTF-8 string */ -struct CStrA : public CBlobT -{ - typedef CBlobT base; ///< base class - - /** Create an empty CStrT */ - inline CStrA() - { - } - - /** Copy constructor */ - inline CStrA(const CStrA &src) : base(src) - { - base::FixTail(); - } - - /** Take over ownership constructor */ - inline CStrA(const OnTransfer &ot) - : base(ot) - { - } - - /** Grow the actual buffer and fix the trailing zero at the end. */ - inline char *GrowSizeNC(uint count) - { - char *ret = base::GrowSizeNC(count); - base::FixTail(); - return ret; - } - - /** Append zero-ended C string. */ - inline void AppendStr(const char *str) - { - if (!StrEmpty(str)) { - base::AppendRaw(str, strlen(str)); - base::FixTail(); - } - } - - /** Append another CStrA. */ - inline void Append(const CStrA &src) - { - if (src.Length() > 0) { - base::AppendRaw(src); - base::FixTail(); - } - } - - /** Assignment from C string. */ - inline CStrA &operator=(const char *src) - { - base::Clear(); - AppendStr(src); - return *this; - } - - /** Assignment from another CStrA. */ - inline CStrA &operator=(const CStrA &src) - { - if (&src != this) { - base::Clear(); - base::AppendRaw(src.Data(), src.Size()); - base::FixTail(); - } - return *this; - } - - /** Lower-than operator (to support stl collections) */ - inline bool operator<(const CStrA &other) const - { - return strcmp(base::Data(), other.Data()) < 0; - } - - /** Add formatted string (like vsprintf) at the end of existing contents. */ - int AddFormatL(const char *format, va_list args) WARN_FORMAT(2, 0) - { - size_t addSize = std::max(strlen(format), 16); - addSize += addSize / 2; - int ret; - int err = 0; - for (;;) { - char *buf = MakeFreeSpace(addSize); - ret = vseprintf(buf, buf + base::GetReserve() - 1, format, args); - if (ret >= (int)base::GetReserve()) { - /* Greater return than given count means needed buffer size. */ - addSize = ret + 1; - continue; - } - if (ret >= 0) { - /* success */ - break; - } - err = errno; - if (err != ERANGE && err != ENOENT && err != 0) { - /* some strange failure */ - break; - } - /* small buffer (M$ implementation) */ - addSize *= 2; - } - if (ret > 0) { - GrowSizeNC(ret); - } else { - base::FixTail(); - } - return ret; - } - - /** Add formatted string (like sprintf) at the end of existing contents. */ - int CDECL WARN_FORMAT(2, 3) AddFormat(const char *format, ...) - { - va_list args; - va_start(args, format); - int ret = AddFormatL(format, args); - va_end(args); - return ret; - } - - /** Assign formatted string (like sprintf). */ - int CDECL WARN_FORMAT(2, 3) Format(const char *format, ...) - { - base::Free(); - va_list args; - va_start(args, format); - int ret = AddFormatL(format, args); - va_end(args); - return ret; - } -}; - -#endif /* STR_HPP */ diff --git a/src/pathfinder/yapf/yapf.hpp b/src/pathfinder/yapf/yapf.hpp --- a/src/pathfinder/yapf/yapf.hpp +++ b/src/pathfinder/yapf/yapf.hpp @@ -19,7 +19,6 @@ //#define inline inline #include "../../misc/blob.hpp" -#include "../../misc/str.hpp" #include "../../misc/fixedsizearray.hpp" #include "../../misc/array.hpp" #include "../../misc/hashtable.hpp" diff --git a/src/pathfinder/yapf/yapf_base.hpp b/src/pathfinder/yapf/yapf_base.hpp --- a/src/pathfinder/yapf/yapf_base.hpp +++ b/src/pathfinder/yapf/yapf_base.hpp @@ -317,7 +317,7 @@ public: void DumpBase(DumpTarget &dmp) const { dmp.WriteStructT("m_nodes", &m_nodes); - dmp.WriteLine("m_num_steps = %d", m_num_steps); + dmp.WriteValue("m_num_steps", m_num_steps); } /* methods that should be implemented at derived class Types::Tpf (derived from CYapfBaseT) */ diff --git a/src/pathfinder/yapf/yapf_node.hpp b/src/pathfinder/yapf/yapf_node.hpp --- a/src/pathfinder/yapf/yapf_node.hpp +++ b/src/pathfinder/yapf/yapf_node.hpp @@ -126,8 +126,8 @@ struct CYapfNodeT { { dmp.WriteStructT("m_key", &m_key); dmp.WriteStructT("m_parent", m_parent); - dmp.WriteLine("m_cost = %d", m_cost); - dmp.WriteLine("m_estimate = %d", m_estimate); + dmp.WriteValue("m_cost", m_cost); + dmp.WriteValue("m_estimate", m_estimate); } }; diff --git a/src/pathfinder/yapf/yapf_node_rail.hpp b/src/pathfinder/yapf/yapf_node_rail.hpp --- a/src/pathfinder/yapf/yapf_node_rail.hpp +++ b/src/pathfinder/yapf/yapf_node_rail.hpp @@ -109,7 +109,7 @@ struct CYapfRailSegment dmp.WriteStructT("m_key", &m_key); dmp.WriteTile("m_last_tile", m_last_tile); dmp.WriteEnumT("m_last_td", m_last_td); - dmp.WriteLine("m_cost = %d", m_cost); + dmp.WriteValue("m_cost", m_cost); dmp.WriteTile("m_last_signal_tile", m_last_signal_tile); dmp.WriteEnumT("m_last_signal_td", m_last_signal_td); dmp.WriteEnumT("m_end_segment_reason", m_end_segment_reason); @@ -207,10 +207,10 @@ struct CYapfRailNodeT { base::Dump(dmp); dmp.WriteStructT("m_segment", m_segment); - dmp.WriteLine("m_num_signals_passed = %d", m_num_signals_passed); - dmp.WriteLine("m_targed_seen = %s", flags_u.flags_s.m_targed_seen ? "Yes" : "No"); - dmp.WriteLine("m_choice_seen = %s", flags_u.flags_s.m_choice_seen ? "Yes" : "No"); - dmp.WriteLine("m_last_signal_was_red = %s", flags_u.flags_s.m_last_signal_was_red ? "Yes" : "No"); + dmp.WriteValue("m_num_signals_passed", m_num_signals_passed); + dmp.WriteValue("m_targed_seen", flags_u.flags_s.m_targed_seen ? "Yes" : "No"); + dmp.WriteValue("m_choice_seen", flags_u.flags_s.m_choice_seen ? "Yes" : "No"); + dmp.WriteValue("m_last_signal_was_red", flags_u.flags_s.m_last_signal_was_red ? "Yes" : "No"); dmp.WriteEnumT("m_last_red_signal_type", m_last_red_signal_type); } }; diff --git a/src/pathfinder/yapf/yapf_rail.cpp b/src/pathfinder/yapf/yapf_rail.cpp --- a/src/pathfinder/yapf/yapf_rail.cpp +++ b/src/pathfinder/yapf/yapf_rail.cpp @@ -28,8 +28,8 @@ template void DumpState(T FILE *f2 = fopen("yapf2.txt", "wt"); assert(f1 != nullptr); assert(f2 != nullptr); - fwrite(dmp1.m_out.Data(), 1, dmp1.m_out.Size(), f1); - fwrite(dmp2.m_out.Data(), 1, dmp2.m_out.Size(), f2); + fwrite(dmp1.m_out.c_str(), 1, dmp1.m_out.size(), f1); + fwrite(dmp2.m_out.c_str(), 1, dmp2.m_out.size(), f2); fclose(f1); fclose(f2); } diff --git a/src/pathfinder/yapf/yapf_type.hpp b/src/pathfinder/yapf/yapf_type.hpp --- a/src/pathfinder/yapf/yapf_type.hpp +++ b/src/pathfinder/yapf/yapf_type.hpp @@ -10,6 +10,9 @@ #ifndef YAPF_TYPE_HPP #define YAPF_TYPE_HPP +#include +#include + /* Enum used in PfCalcCost() to see why was the segment closed. */ enum EndSegmentReason { /* The following reasons can be saved into cached segment */ @@ -66,7 +69,7 @@ enum EndSegmentReasonBits { DECLARE_ENUM_AS_BIT_SET(EndSegmentReasonBits) -inline CStrA ValueStr(EndSegmentReasonBits bits) +inline std::string ValueStr(EndSegmentReasonBits bits) { static const char * const end_segment_reason_names[] = { "DEAD_END", "RAIL_TYPE", "INFINITE_LOOP", "SEGMENT_TOO_LONG", "CHOICE_FOLLOWS", @@ -74,9 +77,10 @@ inline CStrA ValueStr(EndSegmentReasonBi "PATH_TOO_LONG", "FIRST_TWO_WAY_RED", "LOOK_AHEAD_END", "TARGET_REACHED" }; - CStrA out; - out.Format("0x%04X (%s)", bits, ComposeNameT(bits, end_segment_reason_names, "UNK", ESRB_NONE, "NONE").Data()); - return out.Transfer(); + std::stringstream ss; + ss << "0x" << std::setfill('0') << std::setw(4) << std::hex << bits; // 0x%04X + ss << " (" << ComposeNameT(bits, end_segment_reason_names, "UNK", ESRB_NONE, "NONE") << ")"; + return ss.str(); } #endif /* YAPF_TYPE_HPP */