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);
121 : myIsReference(false),
122 myIsAlwaysDeep(false)
123 { myData = strdup(str.c_str()); }
147 : myIsReference(false),
149 { myData = str ? strdup(str) : 0; }
154 : myIsReference(false),
156 { myData = strdup(str.c_str()); }
171 , myIsReference(str.myIsReference)
172 , myIsAlwaysDeep(str.myIsAlwaysDeep)
174 str.myData =
nullptr;
175 str.myIsReference = !str.myIsAlwaysDeep;
181 myIsReference = str.myIsReference;
182 myIsAlwaysDeep = str.myIsAlwaysDeep;
183 str.myData =
nullptr;
184 str.myIsReference = !str.myIsAlwaysDeep;
192 myIsAlwaysDeep = deep;
193 if (deep && myIsReference)
202 myIsReference =
false;
208 return myIsAlwaysDeep;
217 if (!myIsReference && myData)
219 myData = strdup(myData ? myData :
"");
220 myIsReference =
false;
223 void harden(
const char *
s,
int len = -1);
244 bool isHard()
const {
return !myIsReference; }
260 myData = strdup(myData ? myData :
"");
261 myIsReference =
true;
268 return strdup(myData ? myData :
"");
285 myIsReference =
false;
300 void saveAscii(std::ostream &os)
const { save(os,
false); }
304 void save(std::ostream &os,
bool binary)
const;
312 { *
this = (
const char *)NULL; }
316 void prepend(
const char *prefix);
317 void prepend(
char ch);
321 void append(
char ch);
324 void append(
const char *str,
exint len = -1);
329 void truncate(
exint len);
353 bool same = (str == myData);
357 int mylen = (
int)strlen(myData);
358 myData = (
char *)realloc(myData,
359 mylen+strlen(str)+1);
362 strcpy(&myData[mylen], str);
366 memcpy(myData + mylen, myData, mylen);
367 myData[mylen * 2] =
'\0';
376 *
this += (
const char *)str.myData;
382 int compare(
const char *str,
bool case_sensitive=
true)
const
386 if (myData==0 || str==0)
388 if (myData)
return 1;
393 return strcmp(myData, str);
394 return strcasecmp(myData, str);
398 return compare(str.myData,case_sensitive);
402 bool equal(
const char *str,
bool case_sensitive=
true)
const
404 return compare(str,case_sensitive)==0;
408 return compare(str.myData,case_sensitive)==0;
412 return compare(str,case_sensitive)==0;
497 bool case_sensitive =
true,
498 bool allow_subst =
true)
const;
500 operator const char *()
const
501 {
return (
const char *)myData; }
509 const char *
buffer()
const {
return myData; }
547 {
return (myData) ? (unsigned)strlen(myData) : 0; }
552 return (inclusive ?
sizeof(*
this) : 0)
553 + (!myIsReference ? (
length() + 1)*
sizeof(
char) : 0);
559 {
return myData ? strchr(myData, c) :
nullptr; }
567 {
return myData ? strpbrk(myData, str) :
nullptr; }
575 {
return myData ? strrchr(myData, c) :
nullptr; }
581 int countChar(
int c)
const;
584 int count(
const char *str,
bool case_sensitive =
true)
const;
586 char *findNonSpace();
587 const char *findNonSpace()
const;
588 const char *findWord(
const char *word)
const;
589 bool findString(
const char *str,
bool fullword,
590 bool usewildcards)
const;
591 int changeWord(
const char *from,
const char *to,
bool all =
true);
592 int changeString(
const char *from,
const char *to,
bool fullword);
593 int changeQuotedWord(
const char *from,
const char *to,
594 int quote =
'`',
bool all =
true);
596 int findLongestCommonSuffix(
const char *
with )
const;
606 bool isFloat(
bool skip_spaces =
false,
608 bool allow_underscore =
false)
const;
610 bool isInteger(
bool skip_spaces =
false)
const;
616 for (ptr=myData; *
ptr; ptr++)
617 *ptr = (
char)toupper(*ptr);
623 for (ptr=myData; *
ptr; ptr++)
624 *ptr = (
char)tolower(*ptr);
636 return file_name.
begin();
645 return myData + (extension.
begin() - myData);
685 int parseNumberedFilename(
UT_String &prefix,
689 bool fractional =
false)
const;
692 {
return (myData && *myData); }
697 int trimSpace(
bool leave_single_space_between_words =
false);
701 int trimBoundingSpace();
706 int strip(
const char *chars);
712 void protectString(
bool protect_empty=
false);
717 static void protectString(std::ostream& os,
char c);
723 void protectPreQuotePythonStringLiteral(
char delimiter=
'\'');
727 bool isQuotedString(
char delimiter=
'\'')
const;
734 UT_String makeQuotedString(
char delimiter=
'\'',
735 bool escape_nonprinting=
false)
const;
742 UT_String makeSmartQuotedString(
char default_delimiter=
'\'',
743 bool escape_nonprinting=
false)
const;
751 void expandControlSequences(
bool expand_extended =
false);
753 bool hasWhiteSpace()
const;
755 void removeTrailingSpace();
756 void removeTrailingChars(
char chr);
758 void removeTrailingDigits();
776 int cshParse(
char *argv[],
int max_args,
799 int dosParse(
UT_WorkArgs &argv,
bool preserve_backslashes=
false);
800 int dosParse(
char *argv[],
int max_args,
801 bool preserve_backslashes=
false);
805 bool preserve_backslashes);
813 int parse(
char *argv[],
int max_args,
814 const char *quotes =
"\"'",
bool keep_quotes =
false)
817 return parseInPlace(argv, max_args, quotes, keep_quotes);
820 const char *quotes =
"\"'",
bool keep_quotes =
false)
823 return parseInPlace(argv, start_arg, quotes, keep_quotes);
826 const char *quotes =
"\"'",
bool keep_quotes =
false)
829 return parseInPlace(argv, start_arg, quotes, keep_quotes);
833 int parseInPlace(
char *argv[],
int max_args,
834 const char *quotes =
"\"'",
bool keep_quotes =
false);
835 int parseInPlace(
UT_WorkArgs &argv,
int start_arg = 0,
836 const char *quotes =
"\"'",
bool keep_quotes =
false);
838 const char *quotes =
"\"'",
bool keep_quotes =
false);
842 int tokenize(
char *argv[],
int max_args,
char separator)
845 return tokenizeInPlace(argv, max_args, separator);
847 int tokenizeInPlace(
char *argv[],
int max_args,
char separator);
851 return tokenizeInPlace(argv, separator);
853 int tokenizeInPlace(
UT_WorkArgs &argv,
char separator);
855 const char *separators =
" \t\n")
858 return tokenizeInPlace(argv, max_args, separators);
860 int tokenizeInPlace(
char *argv[],
int max_args,
861 const char *separators =
" \t\n");
865 return tokenizeInPlace(argv, separators);
868 const char *separators =
" \t\n");
874 return tokenizeInPlace(list, separators);
879 const char *separators =
" \t\n")
886 if (!(token =
SYSstrtok(myData, separators, &context)))
891 while ((token =
SYSstrtok(0, separators, &context)) != NULL)
894 return list.entries();
899 void expandVariables();
912 return SYSstring_hashseed(
921 bool match(
const char *
pattern,
bool case_sensitive =
true)
const;
926 bool matchFile(
const char *
pattern)
const;
931 bool matchPath(
const char *
pattern,
bool case_sensitive =
true,
932 bool *excludes_branch =
nullptr)
const;
938 bool multiMatch(
const char *
pattern,
939 bool case_sensitive,
char separator)
const;
940 bool multiMatch(
const char *
pattern,
bool case_sensitive =
true,
941 const char *separators =
", ",
942 bool *explicitly_excluded = 0,
943 int *match_index = 0,
944 ut_PatternRecord *pattern_record=NULL)
const;
946 bool *explicitly_excluded = 0,
947 int *match_index = 0,
948 ut_PatternRecord *pattern_record=NULL)
const;
952 bool multiMatchRecord(
const char *
pattern,
int maxpatterns,
953 char *singles,
int &nsingles,
954 char **words,
int &nwords,
955 bool case_sensitive =
true,
956 const char *separators =
", ")
const;
959 char *singles,
int &nsingles,
960 char **words,
int &nwords)
const;
961 bool multiMatchRecord(
const char *
pattern,
964 bool case_sensitive =
true,
965 const char *separators =
", ")
const;
974 bool assume_match=
false)
const;
976 static bool multiMatchCheck(
const char *
pattern);
977 static bool wildcardMatchCheck(
const char *
pattern);
984 bool case_sensitive =
true)
const;
988 bool case_sensitive =
true)
const;
1001 int traversePattern(
int max,
void *
data,
1002 int (*
func)(
int num,
int sec,
void *data),
1003 unsigned int (*secfunc)(
int num,
void *data)=0,
1009 if (!myData)
return NULL;
1010 return case_sensitive ? strstr(myData, pattern)
1023 bool patternRename(
const char *match_pattern,
const char *
replace);
1032 const char *suffix()
const;
1039 void incrementNumberedName(
bool preserve_padding =
false);
1052 static std::ostream &setFormat(std::ostream &os,
const char *fmt);
1053 std::ostream &setFormat(std::ostream &os);
1055 int replacePrefix(
const char *oldpref,
1056 const char *newpref);
1057 int replaceSuffix(
const char *oldsuffix,
1058 const char *newsuffix);
1067 int expandArrays(
char *names[],
int max);
1082 int substitute(
const char *
find,
const char *replacement,
1086 int substitute( const
char *
find, const
char *replacement,
1088 {
return substitute(find, replacement, !all ? 1 : -1); }
1091 int substitute(
char find,
char replacement,
bool all =
true );
1095 int replace(
int pos,
int len,
const char *str );
1099 {
return replace(0, len,
""); }
1115 {
return replace(pos, 0, str); }
1121 static int compareNumberedString(
const char *s1,
1123 bool case_sensitive=
true,
1124 bool allow_negatives=
false);
1125 static int qsortCmpNumberedString(
const char *
const*
v1,
1126 const char *
const*
v2);
1130 static int compareNumberedFilename(
const char *s1,
1132 bool case_sensitive=
false);
1133 static int qsortCmpNumberedFilename(
const char *
const*
v1,
1134 const char *
const*
v2);
1138 static int compareNumberedStringWithExceptions(
const char *s1,
1140 bool case_sensitive=
false,
1141 bool allow_negatives=
false,
1142 const char *sorted_first=
nullptr,
1143 const char *sorted_last=
nullptr);
1148 static int compareVersionString(
const char *s1,
const char *s2);
1162 void extractProgramName(
const char *
path,
1163 bool strip_extension=
true,
1164 bool normalize_path=
true);
1176 static bool matchProgramName(
const char *
path,
const char *expected,
1177 bool normalize_path=
false);
1187 static int itoa(
char *str,
int64 i);
1188 static int utoa(
char *str,
uint64 i);
1201 void timeDeltaToPrettyString(
double time_ms);
1205 void timeDeltaToPrettyStringMS(
double time_ms);
1221 int forceValidVariableName(const
char *safechars = NULL);
1225 bool isValidVariableName(const
char *safechars = NULL) const;
1229 bool forceAlphaNumeric();
1235 void getRelativePath(const
char *src_fullpath,
1236 const
char *dest_fullpath,
1237 bool file_path = false);
1246 static
int findLongestCommonPathPrefix(const
char *fullpath1,
int len1,
1247 const
char *fullpath2,
int len2);
1251 bool isAbsolutePath(
bool file_path=false) const;
1257 bool collapseAbsolutePath(
bool file_path=false);
1263 bool truncateMiddle(
int max_length);
1271 static const
UT_String &getEmptyString();
1279 static
int countCshModifiers(const
char *
src);
1286 bool applyCshModifiers(const
char *modifiers);
1297 void formatByteSize(
exint size,
int digits=2);
1303 int getCodePointCount() const;
1323 template <
typename OSTREAM>
1324 void saveInternal(OSTREAM &os,
bool binary)
const;
1336 bool applyNextModifier(
const char *mod,
bool all);
1343 void doSmartCopyFrom(
const char* other_string);
1345 static int compareNumberedStringInternal(
const char *s1,
const char *s2,
1346 bool case_sensitive,
1347 bool allow_negatives,
1348 const char *sorted_first,
1349 const char *sorted_last);
1353 #if defined(UT_DEBUG) && !defined(_WIN32)
1355 ::memset((
void *)str, 0xDD, ::strlen(str) + 1);
1357 ::free((
void *)str);
1361 bool myIsReference:1,
1400 using UT_String::operator==;
1401 using UT_String::operator!=;
1446 : myIsReference(false)
1447 , myIsAlwaysDeep(true)
1455 : myIsReference(false)
1456 , myIsAlwaysDeep(true)
1459 *
this = std::move(str);
1466 myIsAlwaysDeep =
true;
1473 if (!myIsReference && myData)
1479 UT_String::freeData()
1493 bool temp = myIsReference;
1494 myIsReference = other.myIsReference;
1495 other.myIsReference = temp;
1497 char *tmp_data = myData;
1498 myData = other.myData;
1499 other.myData = tmp_data;
1504 if (other.myIsAlwaysDeep)
1531 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)
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
GLsizei const GLchar *const * string
bool operator==(const char *str) const
bool operator<=(const UT_String &str) const
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
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
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")
#define SYS_DEPRECATED_REPLACE(__V__, __R__)
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
CompareResults OIIO_API compare(const ImageBuf &A, const ImageBuf &B, float failthresh, float warnthresh, ROI roi={}, int nthreads=0)
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
UT_String & operator=(UT_String &&str)
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)
GLint GLint GLsizei GLint GLenum format
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
SYS_FORCE_INLINE UT_String(const char *str=0)
Construct UT_String from a C string, using shallow semantics.
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.
bool isValidVariableName(const char *safechars=NULL) const
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)
UT_String(UT_AlwaysDeepType, const char *str=0)
Construct UT_String from a C string, using ALWAYS_DEEP semantics.
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
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")
FMT_CONSTEXPR auto find(Ptr first, Ptr last, T value, Ptr &out) -> bool
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