GUI: U32: Fix problems with u32strings formatting

- Improve U32's format helper
- Add insertString helper to u32
This commit is contained in:
aryanrawlani28 2020-06-18 20:29:52 +05:30 committed by Eugene Sandulenko
parent 0118839c59
commit 1ca1712b4d
5 changed files with 61 additions and 56 deletions

View file

@ -2464,9 +2464,8 @@ void SurfaceSdlGraphicsManager::handleScalerHotkeys(int scalefactor, int scalerT
g++; g++;
} }
if (newScalerName) { if (newScalerName) {
const Common::U32String message = Common::String::format( const Common::U32String message = Common::U32String::format(
"%s %s\n%d x %d -> %d x %d", _("Active graphics filter: ") + Common::U32String("%s\n%d x %d -> %d x %d"),
_("Active graphics filter:").encode().c_str(),
newScalerName, newScalerName,
_videoMode.screenWidth, _videoMode.screenHeight, _videoMode.screenWidth, _videoMode.screenHeight,
_hwScreen->w, _hwScreen->h); _hwScreen->w, _hwScreen->h);

View file

@ -238,6 +238,12 @@ void U32String::insertChar(value_type c, uint32 p) {
_str[p] = c; _str[p] = c;
} }
void U32String::insertString(String s, uint32 p) {
for (String::iterator i = s.begin(); i != s.end(); i++) {
U32String::insertChar(*i, p++);
}
}
void U32String::deleteChar(uint32 p) { void U32String::deleteChar(uint32 p) {
assert(p < _size); assert(p < _size);
@ -520,68 +526,65 @@ void U32String::trim() {
} }
} }
// static U32String U32String::format(U32String fmt, ...) {
U32String U32String::format(const char *fmt, ...) { U32String output = fmt;
U32String output; int len;
va_list va; va_list va;
va_start(va, fmt); va_start(va, fmt);
output = U32String::vformat(fmt, va); len = U32String::vformat(output, output.begin(), va);
va_end(va); va_end(va);
return output; return output;
} }
// static int U32String::vformat(U32String &output, U32String::iterator fmt, va_list args) {
U32String U32String::vformat(const char *fmt, va_list args) { int int_temp;
U32String output = ""; char char_temp;
assert(output.isStorageIntern()); char *string_temp;
output._str;
va_list va;
scumm_va_copy(va, args);
int len = vsnprintf((char *)output._str, _builtinCapacity, fmt, va);
va_end(va);
if (len == -1 || len == _builtinCapacity - 1) { char ch;
// MSVC and IRIX don't return the size the full string would take up. int length = 0;
// MSVC returns -1, IRIX returns the number of characters actually written, int len = 0;
// which is at the most the size of the buffer minus one, as the string is int pos = 0;
// truncated to fit.
// We assume MSVC failed to output the correct, null-terminated string char buffer[512];
// if the return value is either -1 or size.
// For IRIX, because we lack a better mechanism, we assume failure
// if the return value equals size - 1.
// The downside to this is that whenever we try to format a string where the
// size is 1 below the built-in capacity, the size is needlessly increased.
// Try increasing the size of the string until it fits. while (fmt != output.end() && pos < output.size()) {
int size = _builtinCapacity; ch = *fmt++;
do { if (ch == '%') {
size *= 2; switch (ch = *fmt++)
output.ensureCapacity(size - 1, false); {
assert(!output.isStorageIntern()); case 's':
size = output._extern._capacity; string_temp = va_arg(args, char *);
len = strlen(string_temp);
scumm_va_copy(va, args); length += len;
len = vsnprintf((char *)output._str, size, fmt, va); fmt -= 2;
va_end(va); output.deleteChar(pos); // remove %
} while (len == -1 || len >= size - 1); output.deleteChar(pos); // remove s
output._size = len; output.insertString(string_temp, pos);
} else if (len < (int)_builtinCapacity) { fmt += len;
// vsnprintf succeeded pos += len;
output._size = len; break;
} else { case 'd':
// vsnprintf didn't have enough space, so grow buffer int_temp = va_arg(args, int);
output.ensureCapacity(len, false); fmt -= 2;
scumm_va_copy(va, args); output.deleteChar(pos); // remove %
int len2 = vsnprintf((char *)output._str, len + 1, fmt, va); output.deleteChar(pos); // remove d
va_end(va); itoa(int_temp, buffer, 10);
assert(len == len2); output.insertString(buffer, pos);
output._size = len2; len = strlen(buffer);
length += len;
fmt += len;
break;
default:
break;
}
}
pos++;
} }
return output; return length;
} }
} // End of namespace Common } // End of namespace Common

View file

@ -167,6 +167,7 @@ public:
/** Insert character c before position p. */ /** Insert character c before position p. */
void insertChar(value_type c, uint32 p); void insertChar(value_type c, uint32 p);
void insertString(String s, uint32 p);
/** /**
* Removes the value at position p from the string. * Removes the value at position p from the string.
@ -240,14 +241,14 @@ public:
* except that it stores the result in (variably sized) String * except that it stores the result in (variably sized) String
* instead of a fixed size buffer. * instead of a fixed size buffer.
*/ */
static U32String format(const char *fmt, ...) GCC_PRINTF(1, 2); static U32String format(U32String fmt, ...) GCC_PRINTF(1, 2);
/** /**
* Print formatted data into a String object. Similar to vsprintf, * Print formatted data into a String object. Similar to vsprintf,
* except that it stores the result in (variably sized) String * except that it stores the result in (variably sized) String
* instead of a fixed size buffer. * instead of a fixed size buffer.
*/ */
static U32String vformat(const char *fmt, va_list args); static int vformat(U32String &output, U32String::iterator fmt, va_list args);
private: private:
void makeUnique(); void makeUnique();

View file

@ -99,8 +99,8 @@ AboutDialog::AboutDialog()
version += gScummVMVersion; version += gScummVMVersion;
_lines.push_back(version); _lines.push_back(version);
Common::U32String date = Common::String::format(_("(built on %s)").encode().c_str(), gScummVMBuildDate); Common::U32String date = Common::U32String::format(_("(built on %s)"), gScummVMBuildDate);
_lines.push_back(U32String("C2") + date); _lines.push_back(U32String("C2") + date);
for (i = 0; i < ARRAYSIZE(copyright_text); i++) for (i = 0; i < ARRAYSIZE(copyright_text); i++)
addLine(U32String(copyright_text[i])); addLine(U32String(copyright_text[i]));

View file

@ -25,6 +25,7 @@
#include "gui/dialog.h" #include "gui/dialog.h"
#include "common/str.h" #include "common/str.h"
#include "common/ustr.h"
#include "common/array.h" #include "common/array.h"
#include "common/keyboard.h" #include "common/keyboard.h"
@ -33,6 +34,7 @@ namespace GUI {
class EEHandler; class EEHandler;
class AboutDialog : public Dialog { class AboutDialog : public Dialog {
typedef Common::String String;
typedef Common::U32String U32String; typedef Common::U32String U32String;
typedef Common::Array<Common::U32String> U32StringArray; typedef Common::Array<Common::U32String> U32StringArray;
protected: protected: