1
0
Fork 0

Fix 2dffa7d: fmt::format_to copies the iterator, so some text does not remain during formatting (#10940)

pull/10810/head
rubidium42 2023-06-04 19:55:47 +02:00 committed by GitHub
parent 6a519f5d89
commit bfcb027cb9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 19 additions and 18 deletions

View File

@ -285,7 +285,7 @@ char *GetString(char *buffr, StringID string, const char *last)
{ {
_global_string_params.ClearTypeInformation(); _global_string_params.ClearTypeInformation();
_global_string_params.offset = 0; _global_string_params.offset = 0;
StringBuilder builder(buffr, last); StringBuilder builder(&buffr, last);
GetStringWithArgs(builder, string, &_global_string_params); GetStringWithArgs(builder, string, &_global_string_params);
return builder.GetEnd(); return builder.GetEnd();
} }
@ -313,7 +313,8 @@ std::string GetString(StringID string)
std::string GetStringWithArgs(StringID string, StringParameters *args) std::string GetStringWithArgs(StringID string, StringParameters *args)
{ {
char buffer[DRAW_STRING_BUFFER]; char buffer[DRAW_STRING_BUFFER];
StringBuilder builder(buffer, lastof(buffer)); char *state = buffer;
StringBuilder builder(&state, lastof(buffer));
GetStringWithArgs(builder, string, args); GetStringWithArgs(builder, string, args);
return std::string(buffer, builder.GetEnd()); return std::string(buffer, builder.GetEnd());
} }
@ -845,11 +846,10 @@ static void FormatString(StringBuilder &builder, const char *str_arg, StringPara
* space allocated for type information and thus wants type checks on * space allocated for type information and thus wants type checks on
* the parameters. So, we need to gather the type information via the * the parameters. So, we need to gather the type information via the
* dry run first, before we can continue formatting the string. * dry run first, before we can continue formatting the string.
*
* Create a copy of the state of the builder for the dry run, so we do
* not have to reset it after the dry run has completed.
*/ */
StringBuilder dry_run_builder = builder; char buffer[DRAW_STRING_BUFFER];
char *state = buffer;
StringBuilder dry_run_builder(&state, lastof(buffer));
if (UsingNewGRFTextStack()) { if (UsingNewGRFTextStack()) {
/* Values from the NewGRF text stack are only copied to the normal /* Values from the NewGRF text stack are only copied to the normal
* argv array at the time they are encountered. That means that if * argv array at the time they are encountered. That means that if
@ -1018,9 +1018,10 @@ static void FormatString(StringBuilder &builder, const char *str_arg, StringPara
* enough space for the gender index token, one character * enough space for the gender index token, one character
* for the actual gender and one character for '\0'. */ * for the actual gender and one character for '\0'. */
char buf[MAX_CHAR_LENGTH + 1 + 1]; char buf[MAX_CHAR_LENGTH + 1 + 1];
char *state = buf;
bool old_sgd = _scan_for_gender_data; bool old_sgd = _scan_for_gender_data;
_scan_for_gender_data = true; _scan_for_gender_data = true;
StringBuilder tmp_builder(buf, lastof(buf)); StringBuilder tmp_builder(&state, lastof(buf));
StringParameters tmp_params(args->GetPointerToOffset(offset), args->num_param - offset, nullptr); StringParameters tmp_params(args->GetPointerToOffset(offset), args->num_param - offset, nullptr);
FormatString(tmp_builder, input, &tmp_params); FormatString(tmp_builder, input, &tmp_params);
_scan_for_gender_data = old_sgd; _scan_for_gender_data = old_sgd;

View File

@ -20,7 +20,7 @@
* extra functions to ease the migration from char buffers to std::string. * extra functions to ease the migration from char buffers to std::string.
*/ */
class StringBuilder { class StringBuilder {
char *current; ///< The current location to add strings char **current; ///< The current location to add strings
const char *last; ///< The last element of the buffer. const char *last; ///< The last element of the buffer.
public: public:
@ -36,7 +36,7 @@ public:
* @param start The start location to write to. * @param start The start location to write to.
* @param last The last location to write to. * @param last The last location to write to.
*/ */
StringBuilder(char *start, const char *last) : current(start), last(last) {} StringBuilder(char **start, const char *last) : current(start), last(last) {}
/* Required operators for this to be an output_iterator; mimics std::back_insert_iterator, which has no-ops. */ /* Required operators for this to be an output_iterator; mimics std::back_insert_iterator, which has no-ops. */
StringBuilder &operator++() { return *this; } StringBuilder &operator++() { return *this; }
@ -62,7 +62,7 @@ public:
*/ */
StringBuilder &operator+=(const char value) StringBuilder &operator+=(const char value)
{ {
if (this->current != this->last) *this->current++ = value; if (*this->current != this->last) *(*this->current)++ = value;
return *this; return *this;
} }
@ -73,7 +73,7 @@ public:
*/ */
StringBuilder &operator+=(const char *str) StringBuilder &operator+=(const char *str)
{ {
this->current = strecpy(this->current, str, this->last); *this->current = strecpy(*this->current, str, this->last);
return *this; return *this;
} }
@ -96,7 +96,7 @@ public:
{ {
if (this->Remaining() < Utf8CharLen(c)) return false; if (this->Remaining() < Utf8CharLen(c)) return false;
this->current += ::Utf8Encode(this->current, c); (*this->current) += ::Utf8Encode(*this->current, c);
return true; return true;
} }
@ -108,8 +108,8 @@ public:
*/ */
char *GetEnd() char *GetEnd()
{ {
*this->current = '\0'; **this->current = '\0';
return this->current; return *this->current;
} }
/** /**
@ -118,7 +118,7 @@ public:
*/ */
ptrdiff_t Remaining() ptrdiff_t Remaining()
{ {
return (ptrdiff_t)(this->last - this->current); return (ptrdiff_t)(this->last - *this->current);
} }
/** /**
@ -128,7 +128,7 @@ public:
*/ */
void AddViaStreCallback(std::function<char*(char*, const char*)> function) void AddViaStreCallback(std::function<char*(char*, const char*)> function)
{ {
this->current = function(this->current, this->last); *this->current = function(*this->current, this->last);
} }
}; };

View File

@ -67,7 +67,7 @@ static void GetTownName(StringBuilder &builder, const TownNameParams *par, uint3
*/ */
char *GetTownName(char *buff, const TownNameParams *par, uint32 townnameparts, const char *last) char *GetTownName(char *buff, const TownNameParams *par, uint32 townnameparts, const char *last)
{ {
StringBuilder builder(buff, last); StringBuilder builder(&buff, last);
GetTownName(builder, par, townnameparts); GetTownName(builder, par, townnameparts);
return builder.GetEnd(); return builder.GetEnd();
} }
@ -92,7 +92,7 @@ void GetTownName(StringBuilder &builder, const Town *t)
*/ */
char *GetTownName(char *buff, const Town *t, const char *last) char *GetTownName(char *buff, const Town *t, const char *last)
{ {
StringBuilder builder(buff, last); StringBuilder builder(&buff, last);
GetTownName(builder, t); GetTownName(builder, t);
return builder.GetEnd(); return builder.GetEnd();
} }