Merge pull request #4137 from Bumber64/patch-3

New MiscUtils.h functions: random_index, vector_get_random, capitalize_string_words, grab_token_string_pos
develop
Myk 2024-01-05 04:16:37 -08:00 committed by GitHub
commit 1968cffb13
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 115 additions and 7 deletions

@ -74,8 +74,12 @@ Template for new versions:
- `modding-guide`: Add examples for script-only and blueprint-only mods that you can upload to DF's Steam Workshop - `modding-guide`: Add examples for script-only and blueprint-only mods that you can upload to DF's Steam Workshop
## API ## API
- ``random_index``, ``vector_get_random``: new ``MiscUtils`` functions, for getting a random entry in a vector
- ``capitalize_string_words``: new ``MiscUtils`` function, returns string with all words capitalized
- ``grab_token_string_pos``: new ``MiscUtils`` function, used for parsing tokens
## Lua ## Lua
- ``dfhack.capitalizeStringWords``: new function, returns string with all words capitalized
## Removed ## Removed

@ -941,6 +941,10 @@ can be omitted.
Note that the returned string may be longer than the input string. For Note that the returned string may be longer than the input string. For
example, ``ä`` is replaced with ``a``, and ``æ`` is replaced with ``ae``. example, ``ä`` is replaced with ``a``, and ``æ`` is replaced with ``ae``.
* ``dfhack.capitalizeStringWords(string)``
Return a version of the string with each word capitalized.
* ``dfhack.run_command(command[, ...])`` * ``dfhack.run_command(command[, ...])``
Run an arbitrary DFHack command, with the core suspended, and send output to Run an arbitrary DFHack command, with the core suspended, and send output to

@ -1450,6 +1450,7 @@ static std::string df2utf(std::string s) { return DF2UTF(s); }
static std::string utf2df(std::string s) { return UTF2DF(s); } static std::string utf2df(std::string s) { return UTF2DF(s); }
static std::string df2console(color_ostream &out, std::string s) { return DF2CONSOLE(out, s); } static std::string df2console(color_ostream &out, std::string s) { return DF2CONSOLE(out, s); }
static std::string toSearchNormalized(std::string s) { return to_search_normalized(s); } static std::string toSearchNormalized(std::string s) { return to_search_normalized(s); }
static std::string capitalizeStringWords(std::string s) { return capitalize_string_words(s); }
#define WRAP_VERSION_FUNC(name, function) WRAPN(name, DFHack::Version::function) #define WRAP_VERSION_FUNC(name, function) WRAPN(name, DFHack::Version::function)
@ -1468,6 +1469,7 @@ static const LuaWrapper::FunctionReg dfhack_module[] = {
WRAP(utf2df), WRAP(utf2df),
WRAP(df2console), WRAP(df2console),
WRAP(toSearchNormalized), WRAP(toSearchNormalized),
WRAP(capitalizeStringWords),
WRAP_VERSION_FUNC(getDFHackVersion, dfhack_version), WRAP_VERSION_FUNC(getDFHackVersion, dfhack_version),
WRAP_VERSION_FUNC(getDFHackRelease, dfhack_release), WRAP_VERSION_FUNC(getDFHackRelease, dfhack_release),
WRAP_VERSION_FUNC(getDFHackBuildID, dfhack_build_id), WRAP_VERSION_FUNC(getDFHackBuildID, dfhack_build_id),

@ -48,6 +48,11 @@ distribution.
#include <map> #include <map>
#include <array> #include <array>
int random_int(int max)
{
return int(int64_t(rand()) * max / (int64_t(RAND_MAX) + 1));
}
std::string stl_sprintf(const char *fmt, ...) { std::string stl_sprintf(const char *fmt, ...) {
va_list lst; va_list lst;
va_start(lst, fmt); va_start(lst, fmt);
@ -171,6 +176,64 @@ std::string to_search_normalized(const std::string &str)
return result; return result;
} }
std::string capitalize_string_words(const std::string& str)
{ // Cleaned up from g_src/basics.cpp, and returns new string
std::string out = str;
bool starting = true;
int32_t bracket_count = 0;
bool conf;
for (size_t s = 0; s < out.length(); s++)
{
if (out[s] == '[') { ++bracket_count; continue; }
else if (out[s] == ']') { --bracket_count; continue; }
else if (bracket_count > 0) continue;
conf = false;
if (!starting)
{
if (out[s - 1] == ' ' || out[s - 1] == '\"')
conf = true;
// Discount single quote if it isn't preceded by space, comma, or nothing
else if (out[s - 1] == '\'' && s >= 2 && (out[s - 2] == ' ' || out[s - 2] == ','))
conf = true;
}
if (starting || conf)
{
// Capitalize
if (out[s] >= 'a' && out[s] <= 'z')
out[s] += 'A' - 'a';
else
{
switch (out[s])
{
case (char)129: // 'ü'
out[s] = (char)154; break; // 'Ü'
case (char)164: // 'ñ'
out[s] = (char)165; break; // 'Ñ'
case (char)132: // 'ä'
out[s] = (char)142; break; // 'Ä'
case (char)134: // 'å'
out[s] = (char)143; break; // 'Å'
case (char)130: // 'é'
out[s] = (char)144; break; // 'É'
case (char)148: // 'ö'
out[s] = (char)153; break; // 'Ö'
case (char)135: // 'ç'
out[s] = (char)128; break; // 'Ç'
case (char)145: // 'æ'
out[s] = (char)146; break; // 'Æ'
}
}
starting = false;
}
}
return out;
}
bool word_wrap(std::vector<std::string> *out, const std::string &str, size_t line_length, bool word_wrap(std::vector<std::string> *out, const std::string &str, size_t line_length,
word_wrap_whitespace_mode mode) word_wrap_whitespace_mode mode)
{ {
@ -230,6 +293,21 @@ bool word_wrap(std::vector<std::string> *out, const std::string &str, size_t lin
return true; return true;
} }
std::string grab_token_string_pos(const std::string& source, int32_t pos, char compc)
{ // Cleaned up from g_src/basics.cpp, return string instead of bool
std::string out;
// Go until you hit compc, ']', or the end
for (auto s = source.begin() + pos; s < source.end(); ++s)
{
if (*s == compc || *s == ']')
break;
out += *s;
}
return out;
}
bool prefix_matches(const std::string &prefix, const std::string &key, std::string *tail) bool prefix_matches(const std::string &prefix, const std::string &key, std::string *tail)
{ {
size_t ksize = key.size(); size_t ksize = key.size();
@ -253,11 +331,6 @@ bool prefix_matches(const std::string &prefix, const std::string &key, std::stri
return false; return false;
} }
int random_int(int max)
{
return int(int64_t(rand())*max/(int64_t(RAND_MAX)+1));
}
#ifdef LINUX_BUILD // Linux #ifdef LINUX_BUILD // Linux
uint64_t GetTimeMs64() uint64_t GetTimeMs64()
{ {

@ -61,6 +61,8 @@ namespace DFHack {
class color_ostream; class color_ostream;
} }
DFHACK_EXPORT int random_int(int max);
template <typename T> template <typename T>
void print_bits ( T val, std::ostream& out ) void print_bits ( T val, std::ostream& out )
{ {
@ -178,6 +180,17 @@ inline int binsearch_index(const std::vector<CT*> &vec, typename CT::key_pointer
return CT::binsearch_index(vec, key, exact); return CT::binsearch_index(vec, key, exact);
} }
template <typename FT>
int random_index(const std::vector<FT>& vec)
{
if (vec.empty())
return -1;
else if (vec.size() == 1)
return 0;
return random_int(vec.size());
}
template<typename FT, typename KT> template<typename FT, typename KT>
inline bool vector_contains(const std::vector<FT> &vec, KT key) inline bool vector_contains(const std::vector<FT> &vec, KT key)
{ {
@ -199,6 +212,12 @@ inline T vector_get(const std::vector<T> &vec, unsigned idx, const T &defval = T
return defval; return defval;
} }
template<typename T>
inline T vector_get_random(const std::vector<T>& vec, const T& defval = T())
{
return vector_get(vec, random_index(vec), defval);
}
template<typename T> template<typename T>
inline void vector_insert_at(std::vector<T> &vec, unsigned idx, const T &val) inline void vector_insert_at(std::vector<T> &vec, unsigned idx, const T &val)
{ {
@ -401,6 +420,7 @@ inline std::string join_strings(const std::string &separator, T &items) {
DFHACK_EXPORT std::string toUpper(const std::string &str); DFHACK_EXPORT std::string toUpper(const std::string &str);
DFHACK_EXPORT std::string toLower(const std::string &str); DFHACK_EXPORT std::string toLower(const std::string &str);
DFHACK_EXPORT std::string to_search_normalized(const std::string &str); DFHACK_EXPORT std::string to_search_normalized(const std::string &str);
DFHACK_EXPORT std::string capitalize_string_words(const std::string& str);
static inline std::string int_to_string(const int n) { static inline std::string int_to_string(const int n) {
std::ostringstream ss; std::ostringstream ss;
@ -444,6 +464,13 @@ DFHACK_EXPORT bool word_wrap(std::vector<std::string> *out,
const std::string &str, const std::string &str,
size_t line_length = 80, size_t line_length = 80,
word_wrap_whitespace_mode mode = WSMODE_KEEP_ALL); word_wrap_whitespace_mode mode = WSMODE_KEEP_ALL);
/**
* Function to assist in parsing tokens. Returns string from source pos until next compc, ']', or end.
* pos should be set to position after '[' to start with, then incremented by the result's size+1 before subsequent calls.
* compc is usually ':', but can be '.' for parsing number ranges.
* Based on Bay12's g_src/basics.cpp
*/
std::string grab_token_string_pos(const std::string& source, int32_t pos, char compc = ':');
inline bool bits_match(unsigned required, unsigned ok, unsigned mask) inline bool bits_match(unsigned required, unsigned ok, unsigned mask)
{ {
@ -457,8 +484,6 @@ inline T clip_range(T a, T1 minv, T2 maxv) {
return a; return a;
} }
DFHACK_EXPORT int random_int(int max);
/** /**
* Returns the amount of milliseconds elapsed since the UNIX epoch. * Returns the amount of milliseconds elapsed since the UNIX epoch.
* Works on both windows and linux. * Works on both windows and linux.