Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions core/libs/prx/libc/src/StringExtensions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,4 +73,28 @@ char* APS5_VABI strtok_nid_postfix(char* text, const char* delimiters) {
return strtok_r_nid_postfix(text, delimiters, &state);
}

char* APS5_VABI strsep_nid_postfix(char** stringp, const char* delimiters) {
char* token = *stringp;
if (token == nullptr) return nullptr;
char* end = token + std::strcspn(token, delimiters);
if (*end != '\0') {
*end = '\0';
*stringp = end + 1;
} else {
*stringp = nullptr;
}
return token;
}

void* APS5_VABI memccpy_nid_postfix(void* destination, const void* source, int stop, std::size_t count) {
const auto found = static_cast<const unsigned char*>(std::memchr(source, static_cast<unsigned char>(stop), count));
if (found == nullptr) {
std::memcpy(destination, source, count);
return nullptr;
}
const auto copied = static_cast<std::size_t>(found - static_cast<const unsigned char*>(source)) + 1;
std::memcpy(destination, source, copied);
return static_cast<unsigned char*>(destination) + copied;
}

}
17 changes: 17 additions & 0 deletions core/libs/tests/GuestStrings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ std::size_t APS5_VABI strcspn_nid_postfix(const char*, const char*);
std::size_t APS5_VABI strlcat_nid_postfix(char*, const char*, std::size_t);
char* APS5_VABI strtok_r_nid_postfix(char*, const char*, char**);
char* APS5_VABI strtok_nid_postfix(char*, const char*);
char* APS5_VABI strsep_nid_postfix(char**, const char*);
void* APS5_VABI memccpy_nid_postfix(void*, const void*, int, std::size_t);
char* APS5_VABI strcasestr_nid_postfix(const char*, const char*);
int APS5_VABI strcpy_s_nid_postfix(char*, std::size_t, const char*);
int APS5_VABI strcat_s_nid_postfix(char*, std::size_t, const char*);
Expand Down Expand Up @@ -163,5 +165,20 @@ int main() {
Require(strcasestr_nid_postfix("", "a") == nullptr);
const char highBytes[] = {static_cast<char>(0xff), 'A', 0};
Require(strcasestr_nid_postfix(highBytes, "a") == highBytes + 1);
char separated[] = "a,,b:c";
char* cursor = separated;
Require(std::strcmp(strsep_nid_postfix(&cursor, ",:"), "a") == 0);
Require(std::strcmp(strsep_nid_postfix(&cursor, ",:"), "") == 0);
Require(std::strcmp(strsep_nid_postfix(&cursor, ",:"), "b") == 0);
Require(std::strcmp(strsep_nid_postfix(&cursor, ",:"), "c") == 0);
Require(cursor == nullptr && strsep_nid_postfix(&cursor, ",") == nullptr);
char* nothing = nullptr;
Require(strsep_nid_postfix(&nothing, ",") == nullptr);
char copy[8] = {};
Require(memccpy_nid_postfix(copy, "abcdef", 'c', 6) == copy + 3 && std::memcmp(copy, "abc", 3) == 0);
char partial[4] = {};
Require(memccpy_nid_postfix(partial, "abcd", 'z', 4) == nullptr && std::memcmp(partial, "abcd", 4) == 0);
Require(memccpy_nid_postfix(copy, "xyz", 'x' + 256, 3) == copy + 1);
Require(memccpy_nid_postfix(copy, "xyz", 'x', 0) == nullptr);
return CheckMemcpyOverlap() ? 0 : 1;
}