Add function UnescapeMenuString

Turns E&dit into Edit and 'd'. Double ampersands are translated to just a single one,
hence the unescaping part of this.

Useful in the Mac port to deal with desktop UI translation strings with included
Windows hotkeys.
This commit is contained in:
Henrik Rydgård
2023-04-23 14:36:34 +02:00
parent 3d7e73a37a
commit 91d4ded3fd
3 changed files with 49 additions and 0 deletions
+24
View File
@@ -342,3 +342,27 @@ std::string ReplaceAll(std::string result, const std::string& src, const std::st
}
return result;
}
std::string UnescapeMenuString(const char *input, char *shortcutChar) {
size_t len = strlen(input);
std::string output;
output.reserve(len);
bool escaping = false;
for (size_t i = 0; i < len; i++) {
if (input[i] == '&') {
if (escaping) {
output.push_back(input[i]);
escaping = false;
} else {
escaping = true;
}
} else {
output.push_back(input[i]);
if (escaping && shortcutChar) {
*shortcutChar = input[i];
}
escaping = false;
}
}
return output;
}
+4
View File
@@ -76,6 +76,10 @@ void GetQuotedStrings(const std::string& str, std::vector<std::string>& output);
std::string ReplaceAll(std::string input, const std::string& src, const std::string& dest);
// Takes something like R&eplace and returns Replace, plus writes 'e' to *shortcutChar
// if not nullptr. Useful for Windows menu strings.
std::string UnescapeMenuString(const char *input, char *shortcutChar);
void SkipSpace(const char **ptr);
size_t truncate_cpy(char *dest, size_t destSize, const char *src);
+21
View File
@@ -26,6 +26,11 @@
//
// To use, set command line parameter to one or more of the tests below, or "all".
// Search for "availableTests".
//
// Example of how to run with CMake:
//
// ./b.sh --unittest
// build/unittest EscapeMenuString
#include "ppsspp_config.h"
@@ -57,6 +62,7 @@
#include "Common/BitScan.h"
#include "Common/CPUDetect.h"
#include "Common/Log.h"
#include "Common/StringUtils.h"
#include "Core/Config.h"
#include "Common/File/VFS/VFS.h"
#include "Common/File/VFS/DirectoryReader.h"
@@ -890,6 +896,20 @@ bool TestInputMapping() {
return true;
}
bool TestEscapeMenuString() {
char c;
std::string temp = UnescapeMenuString("&File", &c);
EXPECT_EQ_INT((int)c, (int)'F');
EXPECT_EQ_STR(temp, std::string("File"));
temp = UnescapeMenuString("U&til", &c);
EXPECT_EQ_INT((int)c, (int)'t');
EXPECT_EQ_STR(temp, std::string("Util"));
temp = UnescapeMenuString("Ed&it", nullptr);
EXPECT_EQ_STR(temp, std::string("Edit"));
temp = UnescapeMenuString("Cut && Paste", nullptr);
EXPECT_EQ_STR(temp, std::string("Cut & Paste"));
return true;
}
typedef bool (*TestFunc)();
struct TestItem {
@@ -944,6 +964,7 @@ TestItem availableTests[] = {
TEST_ITEM(SmallDataConvert),
TEST_ITEM(DepthMath),
TEST_ITEM(InputMapping),
TEST_ITEM(EscapeMenuString),
};
int main(int argc, const char *argv[]) {