13 #ifndef __UT_String_h__
14 #define __UT_String_h__
38 #define strcasecmp stricmp
39 #define strncasecmp strnicmp
47 class ut_PatternRecord;
88 , myIsAlwaysDeep(false)
100 UT_String(
const char *str,
bool deep_copy,
int len = -1);
128 : myIsReference(false),
129 myIsAlwaysDeep(false)
130 { myData = strdup(str.c_str()); }
154 : myIsReference(false),
156 { myData = str ? strdup(str) :
nullptr; }
161 : myIsReference(false),
163 { myData = strdup(str.c_str()); }
178 , myIsReference(str.myIsReference)
179 , myIsAlwaysDeep(str.myIsAlwaysDeep)
181 str.myData =
nullptr;
182 str.myIsReference = !str.myIsAlwaysDeep;
188 myIsReference = str.myIsReference;
189 myIsAlwaysDeep = str.myIsAlwaysDeep;
190 str.myData =
nullptr;
191 str.myIsReference = !str.myIsAlwaysDeep;
199 myIsAlwaysDeep = deep;
200 if (deep && myIsReference)
202 if (myData !=
nullptr)
209 myIsReference =
false;
215 return myIsAlwaysDeep;
224 if (!myIsReference && myData)
226 myData = strdup(myData ? myData :
"");
227 myIsReference =
false;
230 void harden(
const char *
s,
int len = -1);
251 bool isHard()
const {
return !myIsReference; }
267 myData = strdup(myData ? myData :
"");
268 myIsReference =
true;
275 return strdup(myData ? myData :
"");
292 myIsReference =
false;
307 void saveAscii(std::ostream &os)
const { save(os,
false); }
311 void save(std::ostream &os,
bool binary)
const;
319 { *
this = (
const char *)
nullptr; }
323 void prepend(
const char *prefix);
324 void prepend(
char ch);
328 void append(
char ch);
331 void append(
const char *str,
exint len = -1);
336 void truncate(
exint len);
360 bool same = (str == myData);
364 int mylen = (
int)strlen(myData);
365 myData = (
char *)realloc(myData,
366 mylen+strlen(str)+1);
369 strcpy(&myData[mylen], str);
373 memcpy(myData + mylen, myData, mylen);
374 myData[mylen * 2] =
'\0';
383 *
this += (
const char *)str.myData;
389 int compare(
const char *str,
bool case_sensitive=
true)
const
393 if (myData ==
nullptr || str ==
nullptr)
395 if (myData)
return 1;
400 return strcmp(myData, str);
401 return strcasecmp(myData, str);
405 return compare(str.myData,case_sensitive);
409 bool equal(
const char *str,
bool case_sensitive=
true)
const
411 return compare(str,case_sensitive)==0;
415 return compare(str.myData,case_sensitive)==0;
419 return compare(str,case_sensitive)==0;
504 bool case_sensitive =
true,
505 bool allow_subst =
true)
const;
507 operator const char *()
const
508 {
return (
const char *)myData; }
516 const char *
buffer()
const {
return myData; }
546 std::string toStdString()
const;
554 {
return (myData) ? (unsigned)strlen(myData) : 0; }
559 return (inclusive ?
sizeof(*
this) : 0)
560 + (!myIsReference ? (
length() + 1)*
sizeof(
char) : 0);
566 {
return myData ? strchr(myData, c) :
nullptr; }
574 {
return myData ? strpbrk(myData, str) :
nullptr; }
582 {
return myData ? strrchr(myData, c) :
nullptr; }
588 int countChar(
int c)
const;
591 int count(
const char *str,
bool case_sensitive =
true)
const;
593 char *findNonSpace();
594 const char *findNonSpace()
const;
595 const char *findWord(
const char *word)
const;
596 bool findString(
const char *str,
bool fullword,
597 bool usewildcards)
const;
598 int changeWord(
const char *from,
const char *to,
bool all =
true);
599 int changeString(
const char *from,
const char *to,
bool fullword);
600 int changeQuotedWord(
const char *from,
const char *to,
601 int quote =
'`',
bool all =
true);
603 int findLongestCommonSuffix(
const char *
with )
const;
613 bool isFloat(
bool skip_spaces =
false,
615 bool allow_underscore =
false)
const;
617 bool isInteger(
bool skip_spaces =
false)
const;
623 for (ptr=myData; *
ptr; ptr++)
624 *ptr = (
char)toupper(*ptr);
630 for (ptr=myData; *
ptr; ptr++)
631 *ptr = (
char)tolower(*ptr);
643 return file_name.
begin();
652 return myData + (extension.
begin() - myData);
692 int parseNumberedFilename(
UT_String &prefix,
696 bool fractional =
false)
const;
699 {
return (myData && *myData); }
704 int trimSpace(
bool leave_single_space_between_words =
false);
708 int trimBoundingSpace();
713 int strip(
const char *chars);
719 void protectString(
bool protect_empty=
false);
724 static void protectString(std::ostream& os,
char c);
730 void protectPreQuotePythonStringLiteral(
char delimiter=
'\'');
734 bool isQuotedString(
char delimiter=
'\'')
const;
741 UT_String makeQuotedString(
char delimiter=
'\'',
742 bool escape_nonprinting=
false)
const;
749 UT_String makeSmartQuotedString(
char default_delimiter=
'\'',
750 bool escape_nonprinting=
false)
const;
758 void expandControlSequences(
bool expand_extended =
false);
760 bool hasWhiteSpace()
const;
762 void removeTrailingSpace();
763 void removeTrailingChars(
char chr);
765 void removeTrailingDigits();
783 int cshParse(
char *argv[],
int max_args,
786 int *
error =
nullptr,
791 int *
error =
nullptr,
806 int dosParse(
UT_WorkArgs &argv,
bool preserve_backslashes=
false);
807 int dosParse(
char *argv[],
int max_args,
808 bool preserve_backslashes=
false);
812 bool preserve_backslashes);
820 int parse(
char *argv[],
int max_args,
821 const char *quotes =
"\"'",
bool keep_quotes =
false)
824 return parseInPlace(argv, max_args, quotes, keep_quotes);
827 const char *quotes =
"\"'",
bool keep_quotes =
false)
830 return parseInPlace(argv, start_arg, quotes, keep_quotes);
833 const char *quotes =
"\"'",
bool keep_quotes =
false)
836 return parseInPlace(argv, start_arg, quotes, keep_quotes);
840 int parseInPlace(
char *argv[],
int max_args,
841 const char *quotes =
"\"'",
bool keep_quotes =
false);
842 int parseInPlace(
UT_WorkArgs &argv,
int start_arg = 0,
843 const char *quotes =
"\"'",
bool keep_quotes =
false);
845 const char *quotes =
"\"'",
bool keep_quotes =
false);
849 int tokenize(
char *argv[],
int max_args,
char separator)
852 return tokenizeInPlace(argv, max_args, separator);
854 int tokenizeInPlace(
char *argv[],
int max_args,
char separator);
858 return tokenizeInPlace(argv, separator);
860 int tokenizeInPlace(
UT_WorkArgs &argv,
char separator);
862 const char *separators =
" \t\n")
865 return tokenizeInPlace(argv, max_args, separators);
867 int tokenizeInPlace(
char *argv[],
int max_args,
868 const char *separators =
" \t\n");
872 return tokenizeInPlace(argv, separators);
875 const char *separators =
" \t\n");
881 return tokenizeInPlace(list, separators);
886 const char *separators =
" \t\n")
893 if (!(token =
SYSstrtok(myData, separators, &context)))
898 while ((token =
SYSstrtok(
nullptr, separators, &context))
902 return list.entries();
907 void expandVariables();
920 return SYSstring_hashseed(
929 bool match(
const char *
pattern,
bool case_sensitive =
true)
const;
934 bool matchFile(
const char *
pattern)
const;
939 bool matchPath(
const char *
pattern,
bool case_sensitive =
true,
940 bool *excludes_branch =
nullptr)
const;
946 bool multiMatch(
const char *
pattern,
947 bool case_sensitive,
char separator)
const;
948 bool multiMatch(
const char *
pattern,
bool case_sensitive =
true,
949 const char *separators =
", ",
950 bool *explicitly_excluded =
nullptr,
951 int *match_index =
nullptr,
952 ut_PatternRecord *pattern_record =
nullptr)
const;
954 bool *explicitly_excluded =
nullptr,
955 int *match_index =
nullptr,
956 ut_PatternRecord *pattern_record =
nullptr)
const;
960 bool multiMatchRecord(
const char *
pattern,
int maxpatterns,
961 char *singles,
int &nsingles,
962 char **words,
int &nwords,
963 bool case_sensitive =
true,
964 const char *separators =
", ")
const;
967 char *singles,
int &nsingles,
968 char **words,
int &nwords)
const;
969 bool multiMatchRecord(
const char *
pattern,
972 bool case_sensitive =
true,
973 const char *separators =
", ")
const;
982 bool assume_match=
false)
const;
984 static bool multiMatchCheck(
const char *
pattern);
985 static bool wildcardMatchCheck(
const char *
pattern);
992 bool case_sensitive =
true)
const;
996 bool case_sensitive =
true)
const;
1009 int traversePattern(
int max,
void *
data,
1010 int (*
func)(
int num,
int sec,
void *data),
1011 unsigned int (*secfunc)(
int num,
void *data)
1020 return case_sensitive ? strstr(myData, pattern)
1033 bool patternRename(
const char *match_pattern,
const char *
replace);
1042 const char *suffix()
const;
1049 void incrementNumberedName(
bool preserve_padding =
false);
1062 static std::ostream &setFormat(std::ostream &os,
const char *fmt);
1063 std::ostream &setFormat(std::ostream &os);
1065 int replacePrefix(
const char *oldpref,
1066 const char *newpref);
1067 int replaceSuffix(
const char *oldsuffix,
1068 const char *newsuffix);
1077 int expandArrays(
char *names[],
int max);
1092 int substitute(
const char *
find,
const char *replacement,
1096 int substitute(
char find,
char replacement,
bool all =
true );
1100 int replace(
int pos,
int len,
const char *str );
1104 {
return replace(0, len,
""); }
1120 {
return replace(pos, 0, str); }
1126 static int compareNumberedString(
const char *s1,
1128 bool case_sensitive=
true,
1129 bool allow_negatives=
false);
1130 static int qsortCmpNumberedString(
const char *
const*
v1,
1131 const char *
const*
v2);
1135 static int compareNumberedFilename(
const char *s1,
1137 bool case_sensitive=
false);
1138 static int qsortCmpNumberedFilename(
const char *
const*
v1,
1139 const char *
const*
v2);
1143 static int compareNumberedStringWithExceptions(
const char *s1,
1145 bool case_sensitive=
false,
1146 bool allow_negatives=
false,
1147 const char *sorted_first=
nullptr,
1148 const char *sorted_last=
nullptr);
1153 static int compareVersionString(
const char *s1,
const char *s2);
1167 void extractProgramName(
const char *
path,
1168 bool strip_extension=
true,
1169 bool normalize_path=
true);
1181 static bool matchProgramName(
const char *
path,
const char *expected,
1182 bool normalize_path=
false);
1192 static int itoa(
char *str,
int64 i);
1193 static int utoa(
char *str,
uint64 i);
1206 void timeDeltaToPrettyString(
double time_ms);
1210 void timeDeltaToPrettyStringMS(
double time_ms);
1226 int forceValidVariableName(const
char *safechars =
nullptr);
1230 bool isValidVariableName(const
char *safechars =
nullptr) const;
1234 bool forceAlphaNumeric();
1240 void getRelativePath(const
char *src_fullpath,
1241 const
char *dest_fullpath,
1242 bool file_path = false,
1243 bool allow_relative_path_from_root = true);
1252 static
int findLongestCommonPathPrefix(const
char *fullpath1,
int len1,
1253 const
char *fullpath2,
int len2);
1257 bool isAbsolutePath(
bool file_path=false) const;
1263 bool collapseAbsolutePath(
bool file_path=false);
1269 bool truncateMiddle(
int max_length);
1277 static const
UT_String &getEmptyString();
1285 static
int countCshModifiers(const
char *
src);
1292 bool applyCshModifiers(const
char *modifiers);
1303 void formatByteSize(
exint size,
int digits=2);
1309 int getCodePointCount() const;
1329 template <
typename OSTREAM>
1330 void saveInternal(OSTREAM &os,
bool binary)
const;
1342 bool applyNextModifier(
const char *
mod,
bool all);
1349 void doSmartCopyFrom(
const char* other_string);
1351 static int compareNumberedStringInternal(
const char *s1,
const char *s2,
1352 bool case_sensitive,
1353 bool allow_negatives,
1354 const char *sorted_first,
1355 const char *sorted_last);
1359 #if defined(UT_DEBUG) && !defined(_WIN32)
1361 ::memset((
void *)str, 0xDD, ::strlen(str) + 1);
1363 ::free((
void *)str);
1367 bool myIsReference:1,
1406 using UT_String::operator==;
1407 using UT_String::operator!=;
1453 : myIsReference(false)
1454 , myIsAlwaysDeep(true)
1462 : myIsReference(false)
1463 , myIsAlwaysDeep(true)
1466 *
this = std::move(str);
1473 myIsAlwaysDeep =
true;
1480 if (!myIsReference && myData)
1486 UT_String::freeData()
1500 bool temp = myIsReference;
1501 myIsReference = other.myIsReference;
1502 other.myIsReference = temp;
1504 char *tmp_data = myData;
1505 myData = other.myData;
1506 other.myData = tmp_data;
1511 if (other.myIsAlwaysDeep)
1537 bool operator()(
const std::string &s1,
const std::string &s2)
const
1539 return operator()(s1.c_str(), s2.c_str());
bool match(const char *pattern, bool case_sensitive=true) const
int tokenize(char *argv[], int max_args, const char *separators=" \t\n")
UT_String & operator+=(const char *str)
static SYS_FORCE_INLINE uint32 hash(const char *str, uint32 code=0)
int distance(const char *str, bool case_sensitive=true, bool allow_subst=true) const
typedef int(APIENTRYP RE_PFNGLXSWAPINTERVALSGIPROC)(int)
bool isValidVariableName(const char *safechars=nullptr) const
GLenum GLuint GLenum GLsizei const GLchar * buf
bool operator!=(const char *str) const
UT_String & operator+=(const UT_String &str)
UT_API void normalizePath(UT_String &file_path, bool want_marker=false, bool always_want_expanded_path=false)
bool operator>=(const UT_StringRef &str) const
int count(const char *str, bool case_sensitive=true) const
Count the occurrences of the string.
bool matchFileExtension(const char *match_extension) const
void swap(UT_String &other)
void saveAscii(UT_OStream &os) const
bool operator()(const char *s1, const char *s2) const
T negative(const T &val)
Return the unary negation of the given value.
const char * lastChar(int c) const
bool isInteger(bool skip_spaces=false) const
Determine if string can be seen as a single integer number.
that also have some descendant prim *whose name begins with which in turn has a child named baz where *the predicate and *a name There is also one special expression _ which means *the weaker expression when composing expressions together See with
bool operator<=(const char *str) const
bool operator==(const char *str) const
bool operator<=(const UT_String &str) const
CompareResults OIIO_API compare(const ImageBuf &A, const ImageBuf &B, float failthresh, float warnthresh, float failrelative, float warnrelative, ROI roi={}, int nthreads=0)
const GLuint GLenum const void * binary
bool isHard() const
Returns whether this string is hardened already.
GLsizei const GLchar *const * path
SYS_FORCE_INLINE T * SYSconst_cast(const T *foo)
UT_String makeQuotedString(char delimiter='\'', bool escape_nonprinting=false) const
const char * findChar(const char *str) const
GLboolean GLboolean GLboolean GLboolean a
void swap(T &lhs, T &rhs)
void write(unsigned i, char c)
bool operator==(const UT_String &str) const
GLuint GLsizei GLsizei * length
const char * fileExtension() const
const char * data() const
bool isAbsolutePath(bool file_path=false) const
bool findString(const char *str, bool fullword, bool usewildcards) const
**But if you need a result
FMT_CONSTEXPR auto find(Ptr first, Ptr last, T value, Ptr &out) -> bool
char & operator()(unsigned i)
bool equal(const char *str, bool case_sensitive=true) const
GLfloat GLfloat GLfloat v2
const char * findNonSpace() const
unsigned long long uint64
int compare(const char *str, bool case_sensitive=true) const
void clear()
Reset the string to the default constructor.
bool isAlwaysDeep() const
const char * c_str() const
SYS_FORCE_INLINE UT_String(const char *str=nullptr)
Construct UT_String from a C string, using shallow semantics.
bool matchPath(const char *pattern, bool case_sensitive=true, bool *excludes_branch=nullptr) const
SIM_API const UT_StringHolder all
unsigned length() const
Return length of string.
int compare(const UT_String &str, bool case_sensitive=true) const
const char * suffix() const
bool operator<(const char *str) const
bool operator<(const UT_StringRef &str) const
UT_API void UTexprLookup(const char *name, UT_String &result)
bool contains(const char *pattern, bool case_sensitive=true) const
int tokenize(UT_WorkArgs &argv, const char *separators=" \t\n")
std::ostream & operator<<(std::ostream &ostr, const DataType &a)
UT_String(UT_AlwaysDeepType, const std::string &str)
Construct UT_String from a std::string, using ALWAYS_DEEP semantics.
void hardenIfNeeded(const char *s)
Take shallow copy and make it deep.
const char * buffer() const
A utility class to do read-only operations on a subset of an existing string.
SYS_NO_DISCARD_RESULT SYS_FORCE_INLINE bool isEmpty() const
Returns true if the string is empty.
SYS_FORCE_INLINE uint32 hash() const
bool operator==(const UT_StringRef &str) const
char operator()(unsigned i) const
int tokenize(char *argv[], int max_args, char separator)
bool operator>=(const char *str) const
SYS_NO_DISCARD_RESULT UT_StringView UTstringFileName(const StringT &str)
int tokenizeInPlace(T &list, const char *separators=" \t\n")
OIIO_FORCEINLINE const vint4 & operator+=(vint4 &a, const vint4 &b)
bool operator!=(const UT_String &str) const
bool operator>=(const UT_String &str) const
#define SYS_PRINTF_CHECK_ATTRIBUTE(string_index, first_to_check)
std::string OIIO_UTIL_API replace(string_view str, string_view pattern, string_view replacement, bool global=false)
UT_String(UT_AlwaysDeepType, const char *str=nullptr)
Construct UT_String from a C string, using ALWAYS_DEEP semantics.
GLint GLint GLsizei GLint GLenum format
bool matchPattern(const UT_WorkArgs &pattern_args, bool assume_match=false) const
bool operator>(const UT_String &str) const
char * SYSstrtok(char *string, const char *delimit, char **context)
char * findChar(const char *str)
#define UT_ASSERT_SLOW(ZZ)
const char * findChar(int c) const
void harden()
Take shallow copy and make it deep.
void saveAscii(std::ostream &os) const
bool equal(const UT_StringRef &str, bool case_sensitive=true) const
UT_String(UT_String &&str) noexcept
bool equal(const UT_String &str, bool case_sensitive=true) const
void setAlwaysDeep(bool deep)
Make a string always deep.
bool operator>(const UT_StringRef &str) const
const char * findChar(const char *str) const
bool matchFile(const char *pattern) const
bool operator()(const std::string &s1, const std::string &s2) const
GLuint const GLchar * name
void adopt(UT_String &str)
GLboolean GLboolean GLboolean b
SYS_FORCE_INLINE ~UT_StringWrap()
const char * findWord(const char *word) const
bool operator>(const char *str) const
int64 getMemoryUsage(bool inclusive=true) const
Return memory usage in bytes.
void saveBinary(std::ostream &os) const
Save string to binary stream.
bool isFloat(bool skip_spaces=false, bool loose=false, bool allow_underscore=false) const
Determine if string can be seen as a single floating point number.
static int compareNumberedString(const char *s1, const char *s2, bool case_sensitive=true, bool allow_negatives=false)
UT_String pathUpToExtension() const
__hostdev__ bool isInteger(GridType gridType)
Return true if the GridType maps to a POD integer type.
SYS_NO_DISCARD_RESULT UT_StringView UTstringFileExtension(const StringT &str)
int substr(UT_String &buf, int index, int len=0) const
SYS_NO_DISCARD_RESULT bool UTstringMatchFileExtension(const StringT &str, const char *extension)
void save(std::ostream &os, bool binary) const
Save string to stream. Saves as binary if binary is true.
int parse(UT_StringArray &argv, int start_arg=0, const char *quotes="\"'", bool keep_quotes=false)
bool multiMatch(const char *pattern, bool case_sensitive, char separator) const
LeafData & operator=(const LeafData &)=delete
char * SYSstrcasestr(const char *haystack, const char *needle)
Replacement for strcasestr, since no equivalent exists on Win32.
bool multiMatchRecord(const char *pattern, int maxpatterns, char *singles, int &nsingles, char **words, int &nwords, bool case_sensitive=true, const char *separators=", ") const
int parseNumberedFilename(UT_String &prefix, UT_String &frame, UT_String &suff, bool negative=true, bool fractional=false) const
ImageBuf OIIO_API max(Image_or_Const A, Image_or_Const B, ROI roi={}, int nthreads=0)
**If you just want to fire and args
SYS_NO_DISCARD_RESULT SYS_FORCE_INLINE const_iterator begin() const
Returns a constant iterator pointing to the beginning of the string.
const char * lastChar(int c) const
int findLongestCommonSuffix(const char *with) const
void hardenIfNeeded()
Take shallow copy and make it deep.
const char * findChar(int c) const
int parse(char *argv[], int max_args, const char *quotes="\"'", bool keep_quotes=false)
bool operator<(const UT_String &str) const
int erase(int pos=0, int len=-1)
int tokenize(UT_WorkArgs &argv, char separator)
auto sprintf(const S &fmt, const T &...args) -> std::basic_string< Char >
string_view OIIO_UTIL_API strip(string_view str, string_view chars=string_view())
SIM_API const UT_StringHolder distance
bool operator<=(const UT_StringRef &str) const
bool startsWith(const UT_StringView &prefix, bool case_sensitive=true) const
void splitPath(UT_String &dir_name, UT_String &file_name) const
char operator()(unsigned i) const
bool OIIO_UTIL_API contains(string_view a, string_view b)
Does 'a' contain the string 'b' within it?
int parse(UT_WorkArgs &argv, int start_arg=0, const char *quotes="\"'", bool keep_quotes=false)
const char * base(UT_String &buf) const
UT_String & operator=(UT_String &&str) noexcept
void removeLast()
Remove the last character.
UT_API void UTvarLookup(const char *name, UT_String &result)
SYS_FORCE_INLINE UT_StringWrap(const char *str)
bool endsWith(const UT_StringView &suffix, bool case_sensitive=true) const
UT_String(const std::string &str)
Construct UT_String from a std::string, always doing a deep copy. The result will only be a UT_Always...
const char * fileName() const
OIIO_UTIL_API std::string extension(string_view filepath, bool include_dot=true) noexcept
int countChar(int c) const
Return the number of occurrences of the specified character.
UT_API std::ostream & do_setformat(std::ostream &os, const char fmt[])
int tokenize(T &list, const char *separators=" \t\n")
const char * nonNullBuffer() const
int insert(int pos, const char *str)
const char * fcontain(const char *pattern, bool case_sensitive=true) const
bool operator!=(const UT_StringRef &str) const