diff --git a/UI/obs-app.cpp b/UI/obs-app.cpp index 6fd9341b1..b7d08d9f0 100644 --- a/UI/obs-app.cpp +++ b/UI/obs-app.cpp @@ -1110,79 +1110,9 @@ string GenerateTimeDateFilename(const char *extension, bool noSpace) string GenerateSpecifiedFilename(const char *extension, bool noSpace, const char *format) { - time_t now = time(0); - struct tm *cur_time; - cur_time = localtime(&now); - - const size_t spec_count = 23; - const char *spec[][2] = { - {"%CCYY", "%Y"}, - {"%YY", "%y"}, - {"%MM", "%m"}, - {"%DD", "%d"}, - {"%hh", "%H"}, - {"%mm", "%M"}, - {"%ss", "%S"}, - {"%%", "%%"}, - - {"%a", ""}, - {"%A", ""}, - {"%b", ""}, - {"%B", ""}, - {"%d", ""}, - {"%H", ""}, - {"%I", ""}, - {"%m", ""}, - {"%M", ""}, - {"%p", ""}, - {"%S", ""}, - {"%y", ""}, - {"%Y", ""}, - {"%z", ""}, - {"%Z", ""}, - }; - - char convert[128] = {}; - string sf = format; - string c; - size_t pos = 0, len; - - while (pos < sf.length()) { - len = 0; - for (size_t i = 0; i < spec_count && len == 0; i++) { - - if (sf.find(spec[i][0], pos) == pos) { - if (strlen(spec[i][1])) - strftime(convert, sizeof(convert), - spec[i][1], cur_time); - else - strftime(convert, sizeof(convert), - spec[i][0], cur_time); - - len = strlen(spec[i][0]); - - c = convert; - if (c.length() && c.find_first_not_of(' ') != - std::string::npos) - sf.replace(pos, len, convert); - } - } - - if (len) - pos += strlen(convert); - else if (!len && sf.at(pos) == '%') - sf.erase(pos,1); - else - pos++; - } - - if (noSpace) - replace(sf.begin(), sf.end(), ' ', '_'); - - sf += '.'; - sf += extension; - - return (sf.length() < 256) ? sf : sf.substr(0, 255); + BPtr filename = os_generate_formatted_filename(extension, + !noSpace, format); + return string(filename); } vector> GetLocaleNames() diff --git a/libobs/util/platform.c b/libobs/util/platform.c index 8d8669ecc..cfed355f0 100644 --- a/libobs/util/platform.c +++ b/libobs/util/platform.c @@ -16,6 +16,7 @@ #define _FILE_OFFSET_BITS 64 +#include #include #include #include @@ -657,3 +658,123 @@ const char *os_get_path_extension(const char *path) return path + pos; } + +static inline bool valid_string(const char *str) +{ + while (str && *str) { + if (*(str++) != ' ') + return true; + } + + return false; +} + +static void replace_text(struct dstr *str, size_t pos, size_t len, + const char *new_text) +{ + struct dstr front = {0}; + struct dstr back = {0}; + + dstr_left(&front, str, pos); + dstr_right(&back, str, pos + len); + dstr_copy_dstr(str, &front); + dstr_cat(str, new_text); + dstr_cat_dstr(str, &back); + dstr_free(&front); + dstr_free(&back); +} + +static void erase_ch(struct dstr *str, size_t pos) +{ + struct dstr new_str = {0}; + dstr_left(&new_str, str, pos); + dstr_cat(&new_str, str->array + pos + 1); + dstr_free(str); + *str = new_str; +} + +char *os_generate_formatted_filename(const char *extension, bool space, + const char *format) +{ + time_t now = time(0); + struct tm *cur_time; + cur_time = localtime(&now); + + const size_t spec_count = 23; + static const char *spec[][2] = { + {"%CCYY", "%Y"}, + {"%YY", "%y"}, + {"%MM", "%m"}, + {"%DD", "%d"}, + {"%hh", "%H"}, + {"%mm", "%M"}, + {"%ss", "%S"}, + {"%%", "%%"}, + + {"%a", ""}, + {"%A", ""}, + {"%b", ""}, + {"%B", ""}, + {"%d", ""}, + {"%H", ""}, + {"%I", ""}, + {"%m", ""}, + {"%M", ""}, + {"%p", ""}, + {"%S", ""}, + {"%y", ""}, + {"%Y", ""}, + {"%z", ""}, + {"%Z", ""}, + }; + + char convert[128] = {0}; + struct dstr sf; + struct dstr c = {0}; + size_t pos = 0; + + dstr_init_copy(&sf, format); + + while (pos < sf.len) { + for (size_t i = 0; i < spec_count && !convert[0]; i++) { + size_t len = strlen(spec[i][0]); + + const char *cmp = sf.array + pos; + + if (astrcmp_n(cmp, spec[i][0], len) == 0) { + if (strlen(spec[i][1])) + strftime(convert, sizeof(convert), + spec[i][1], cur_time); + else + strftime(convert, sizeof(convert), + spec[i][0], cur_time); + + + dstr_copy(&c, convert); + if (c.len && valid_string(c.array)) + replace_text(&sf, pos, len, convert); + } + } + + if (convert[0]) { + pos += strlen(convert); + convert[0] = 0; + } else if (!convert[0] && sf.array[pos] == '%') { + erase_ch(&sf, pos); + } else { + pos++; + } + } + + if (!space) + dstr_replace(&sf, " ", "_"); + + dstr_cat_ch(&sf, '.'); + dstr_cat(&sf, extension); + dstr_free(&c); + + if (sf.len > 255) + dstr_mid(&sf, &sf, 0, 255); + + return sf.array; +} diff --git a/libobs/util/platform.h b/libobs/util/platform.h index b08c40a47..77d0ea6ec 100644 --- a/libobs/util/platform.h +++ b/libobs/util/platform.h @@ -162,6 +162,9 @@ EXPORT int os_mkdirs(const char *path); EXPORT int os_rename(const char *old_path, const char *new_path); EXPORT int os_copyfile(const char *file_in, const char *file_out); +EXPORT char *os_generate_formatted_filename(const char *extension, bool space, + const char *format); + struct os_inhibit_info; typedef struct os_inhibit_info os_inhibit_t;