13 #ifndef __UT_String_h__
14 #define __UT_String_h__
37 #define strcasecmp stricmp
38 #define strncasecmp strnicmp
46 class ut_PatternRecord;
93 , myIsAlwaysDeep(false)
95 UT_String(
const char *str,
bool deep_copy,
int len = -1);
116 : myIsReference(false),
117 myIsAlwaysDeep(false)
118 { myData = strdup(str.c_str()); }
138 : myIsReference(false),
140 { myData = str ? strdup(str) : 0; }
145 : myIsReference(false),
147 { myData = strdup(str.c_str()); }
162 , myIsReference(str.myIsReference)
163 , myIsAlwaysDeep(str.myIsAlwaysDeep)
165 str.myData =
nullptr;
166 str.myIsReference = !str.myIsAlwaysDeep;
172 myIsReference = str.myIsReference;
173 myIsAlwaysDeep = str.myIsAlwaysDeep;
174 str.myData =
nullptr;
175 str.myIsReference = !str.myIsAlwaysDeep;
183 myIsAlwaysDeep = deep;
184 if (deep && myIsReference)
193 myIsReference =
false;
199 return myIsAlwaysDeep;
208 if (!myIsReference && myData)
210 myData = strdup(myData ? myData :
"");
211 myIsReference =
false;
214 void harden(
const char *
s,
int len = -1);
235 bool isHard()
const {
return !myIsReference; }
251 myData = strdup(myData ? myData :
"");
252 myIsReference =
true;
259 return strdup(myData ? myData :
"");
276 myIsReference =
false;
291 void saveAscii(std::ostream &os)
const { save(os,
false); }
295 void save(std::ostream &os,
bool binary)
const;
303 { *
this = (
const char *)NULL; }
307 void prepend(
const char *prefix);
308 void prepend(
char ch);
312 void append(
char ch);
315 void append(
const char *str,
exint len = -1);
343 bool same = (str == myData);
347 int mylen = (
int)strlen(myData);
348 myData = (
char *)realloc(myData,
349 mylen+strlen(str)+1);
352 strcpy(&myData[mylen], str);
356 memcpy(myData + mylen, myData, mylen);
357 myData[mylen * 2] =
'\0';
366 *
this += (
const char *)str.myData;
372 int compare(
const char *str,
bool case_sensitive=
true)
const
376 if (myData==0 || str==0)
378 if (myData)
return 1;
383 return strcmp(myData, str);
384 return strcasecmp(myData, str);
388 return compare(str.myData,case_sensitive);
392 bool equal(
const char *str,
bool case_sensitive=
true)
const
394 return compare(str,case_sensitive)==0;
398 return compare(str.myData,case_sensitive)==0;
402 return compare(str,case_sensitive)==0;
487 bool case_sensitive =
true,
488 bool allow_subst =
true)
const;
490 operator const char *()
const
491 {
return (
const char *)myData; }
499 const char *
buffer()
const {
return myData; }
537 {
return (myData) ? (unsigned)strlen(myData) : 0; }
542 return (inclusive ?
sizeof(*
this) : 0)
543 + (!myIsReference ? (
length() + 1)*
sizeof(
char) : 0);
549 {
return myData ? strchr(myData, c) :
nullptr; }
557 {
return myData ? strpbrk(myData, str) :
nullptr; }
565 {
return myData ? strrchr(myData, c) :
nullptr; }
571 int countChar(
int c)
const;
574 int count(
const char *str,
bool case_sensitive =
true)
const;
576 char *findNonSpace();
577 const char *findNonSpace()
const;
578 const char *findWord(
const char *word)
const;
579 bool findString(
const char *str,
bool fullword,
580 bool usewildcards)
const;
581 int changeWord(
const char *from,
const char *to,
bool all =
true);
582 int changeString(
const char *from,
const char *to,
bool fullword);
583 int changeQuotedWord(
const char *from,
const char *to,
584 int quote =
'`',
bool all =
true);
586 int findLongestCommonSuffix(
const char *with )
const;
596 bool isFloat(
bool skip_spaces =
false,
598 bool allow_underscore =
false)
const;
600 bool isInteger(
bool skip_spaces =
false)
const;
606 for (ptr=myData; *
ptr; ptr++)
607 *ptr = (
char)toupper(*ptr);
613 for (ptr=myData; *
ptr; ptr++)
614 *ptr = (
char)tolower(*ptr);
626 return file_name.
begin();
635 return myData + (extension.
begin() - myData);
675 int parseNumberedFilename(
UT_String &prefix,
679 bool fractional =
false)
const;
682 {
return (myData && *myData); }
687 int trimSpace(
bool leave_single_space_between_words =
false);
691 int trimBoundingSpace();
696 int strip(
const char *chars);
702 void protectString(
bool protect_empty=
false);
707 static void protectString(std::ostream& os,
char c);
713 void protectPreQuotePythonStringLiteral(
char delimiter=
'\'');
717 bool isQuotedString(
char delimiter=
'\'')
const;
724 UT_String makeQuotedString(
char delimiter=
'\'',
725 bool escape_nonprinting=
false)
const;
732 UT_String makeSmartQuotedString(
char default_delimiter=
'\'',
733 bool escape_nonprinting=
false)
const;
741 void expandControlSequences(
bool expand_extended =
false);
743 bool hasWhiteSpace()
const;
745 void removeTrailingSpace();
746 void removeTrailingChars(
char chr);
748 void removeTrailingDigits();
760 int cshParse(
char *argv[],
int max_args,
779 int dosParse(
UT_WorkArgs &argv,
bool preserve_backslashes=
false);
780 int dosParse(
char *argv[],
int max_args,
781 bool preserve_backslashes=
false);
786 bool preserve_backslashes);
793 int parse(
char *argv[],
int max_args,
794 const char *quotes =
"\"'",
bool keep_quotes =
false)
797 return parseInPlace(argv, max_args, quotes, keep_quotes);
800 const char *quotes =
"\"'",
bool keep_quotes =
false)
803 return parseInPlace(argv, start_arg, quotes, keep_quotes);
806 const char *quotes =
"\"'",
bool keep_quotes =
false)
809 return parseInPlace(argv, start_arg, quotes, keep_quotes);
813 int parseInPlace(
char *argv[],
int max_args,
814 const char *quotes =
"\"'",
bool keep_quotes =
false);
815 int parseInPlace(
UT_WorkArgs &argv,
int start_arg = 0,
816 const char *quotes =
"\"'",
bool keep_quotes =
false);
818 const char *quotes =
"\"'",
bool keep_quotes =
false);
822 int tokenize(
char *argv[],
int max_args,
char separator)
825 return tokenizeInPlace(argv, max_args, separator);
827 int tokenizeInPlace(
char *argv[],
int max_args,
char separator);
831 return tokenizeInPlace(argv, separator);
833 int tokenizeInPlace(
UT_WorkArgs &argv,
char separator);
835 const char *separators =
" \t\n")
838 return tokenizeInPlace(argv, max_args, separators);
840 int tokenizeInPlace(
char *argv[],
int max_args,
841 const char *separators =
" \t\n");
845 return tokenizeInPlace(argv, separators);
848 const char *separators =
" \t\n");
854 return tokenizeInPlace(list, separators);
859 const char *separators =
" \t\n")
866 if (!(token =
SYSstrtok(myData, separators, &context)))
871 while ((token =
SYSstrtok(0, separators, &context)) != NULL)
874 return list.entries();
879 void expandVariables();
892 return SYSstring_hashseed(
901 bool match(
const char *
pattern,
bool case_sensitive =
true)
const;
906 bool matchFile(
const char *
pattern)
const;
911 bool matchPath(
const char *
pattern,
bool case_sensitive =
true,
912 bool *excludes_branch =
nullptr)
const;
918 bool multiMatch(
const char *
pattern,
919 bool case_sensitive,
char separator)
const;
920 bool multiMatch(
const char *
pattern,
bool case_sensitive =
true,
921 const char *separators =
", ",
922 bool *explicitly_excluded = 0,
923 int *match_index = 0,
924 ut_PatternRecord *pattern_record=NULL)
const;
926 bool *explicitly_excluded = 0,
927 int *match_index = 0,
928 ut_PatternRecord *pattern_record=NULL)
const;
932 bool multiMatchRecord(
const char *
pattern,
int maxpatterns,
933 char *singles,
int &nsingles,
934 char **words,
int &nwords,
935 bool case_sensitive =
true,
936 const char *separators =
", ")
const;
939 char *singles,
int &nsingles,
940 char **words,
int &nwords)
const;
941 bool multiMatchRecord(
const char *
pattern,
944 bool case_sensitive =
true,
945 const char *separators =
", ")
const;
954 bool assume_match=
false)
const;
956 static bool multiMatchCheck(
const char *
pattern);
957 static bool wildcardMatchCheck(
const char *
pattern);
964 bool case_sensitive =
true)
const;
968 bool case_sensitive =
true)
const;
981 int traversePattern(
int max,
void *
data,
982 int (*
func)(
int num,
int sec,
void *data),
983 unsigned int (*secfunc)(
int num,
void *data)=0,
989 if (!myData)
return NULL;
990 return case_sensitive ? strstr(myData, pattern)
1003 bool patternRename(
const char *match_pattern,
const char *
replace);
1012 const char *suffix()
const;
1019 void incrementNumberedName(
bool preserve_padding =
false);
1032 static std::ostream &setFormat(std::ostream &os,
const char *fmt);
1033 std::ostream &setFormat(std::ostream &os);
1035 int replacePrefix(
const char *oldpref,
1036 const char *newpref);
1037 int replaceSuffix(
const char *oldsuffix,
1038 const char *newsuffix);
1047 int expandArrays(
char *
names[],
int max);
1062 int substitute(
const char *
find,
const char *replacement,
1068 {
return substitute(find, replacement, !all ? 1 : -1); }
1071 int substitute(
char find,
char replacement,
bool all =
true );
1075 int replace(
int pos,
int len,
const char *str );
1079 {
return replace(0, len,
""); }
1095 {
return replace(pos, 0, str); }
1101 static int compareNumberedString(
const char *
s1,
1103 bool case_sensitive=
true,
1104 bool allow_negatives=
false);
1105 static int qsortCmpNumberedString(
const char *
const*
v1,
1106 const char *
const*
v2);
1110 static int compareNumberedFilename(
const char *
s1,
1112 bool case_sensitive=
false);
1113 static int qsortCmpNumberedFilename(
const char *
const*
v1,
1114 const char *
const*
v2);
1118 static int compareNumberedStringWithExceptions(
const char *
s1,
1120 bool case_sensitive=
false,
1121 bool allow_negatives=
false,
1122 const char *sorted_first=
nullptr,
1123 const char *sorted_last=
nullptr);
1128 static int compareVersionString(
const char *
s1,
const char *s2);
1142 void extractProgramName(
const char *
path,
1143 bool strip_extension=
true,
1144 bool normalize_path=
true);
1156 static bool matchProgramName(
const char *
path,
const char *expected,
1157 bool normalize_path=
false);
1167 static int itoa(
char *str,
int64 i);
1168 static int utoa(
char *str,
uint64 i);
1181 void timeDeltaToPrettyString(
double time_ms);
1185 void timeDeltaToPrettyStringMS(
double time_ms);
1201 int forceValidVariableName(
const char *safechars = NULL);
1205 bool isValidVariableName(
const char *safechars = NULL)
const;
1209 bool forceAlphaNumeric();
1215 void getRelativePath(const
char *src_fullpath,
1216 const
char *dest_fullpath,
1217 bool file_path = false);
1226 static
int findLongestCommonPathPrefix(const
char *fullpath1,
int len1,
1227 const
char *fullpath2,
int len2);
1231 bool isAbsolutePath(
bool file_path=false) const;
1237 bool collapseAbsolutePath(
bool file_path=false);
1243 bool truncateMiddle(
int max_length);
1251 static const
UT_String &getEmptyString();
1259 static
int countCshModifiers(const
char *
src);
1266 bool applyCshModifiers(const
char *modifiers);
1277 void formatByteSize(
exint size,
int digits=2);
1283 int getCodePointCount() const;
1303 template <
typename OSTREAM>
1304 void saveInternal(OSTREAM &os,
bool binary)
const;
1316 bool applyNextModifier(
const char *mod,
bool all);
1323 void doSmartCopyFrom(
const char* other_string);
1325 static int compareNumberedStringInternal(
const char *
s1,
const char *s2,
1326 bool case_sensitive,
1327 bool allow_negatives,
1328 const char *sorted_first,
1329 const char *sorted_last);
1333 #if defined(UT_DEBUG) && !defined(_WIN32)
1335 ::memset((
void *)str, 0xDD, ::strlen(str) + 1);
1337 ::free((
void *)str);
1341 bool myIsReference:1,
1377 using UT_String::operator==;
1378 using UT_String::operator!=;
1424 if (!myIsReference && myData)
1430 UT_String::freeData()
1444 bool temp = myIsReference;
1445 myIsReference = other.myIsReference;
1446 other.myIsReference = temp;
1448 char *tmp_data = myData;
1449 myData = other.myData;
1450 other.myData = tmp_data;
1455 if (other.myIsAlwaysDeep)
1482 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
GLboolean GLboolean GLboolean b
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.
bool operator<=(const char *str) const
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
void swap(T &lhs, T &rhs)
void write(unsigned i, char c)
bool operator==(const UT_String &str) const
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
GLuint const GLchar * name
char & operator()(unsigned i)
bool equal(const char *str, bool case_sensitive=true) const
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
GLuint GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat s1
bool matchPath(const char *pattern, bool case_sensitive=true, bool *excludes_branch=nullptr) const
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)
GLfloat GLfloat GLfloat v2
GLsizei GLsizei GLfloat distance
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)
GLboolean GLboolean GLboolean GLboolean a
GLsizei const GLchar *const * string
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
typedef int(WINAPI *PFNWGLRELEASEPBUFFERDCARBPROC)(HPBUFFERARB hPbuffer
void setAlwaysDeep(bool deep)
Make a string always deep.
bool operator>(const UT_StringRef &str) const
GLuint const GLuint * names
const char * findChar(const char *str) const
bool matchFile(const char *pattern) const
bool operator()(const std::string &s1, const std::string &s2) const
void adopt(UT_String &str)
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.
GLenum GLuint GLenum GLsizei const GLchar * buf
bool isValidVariableName(const char *safechars=NULL) const
static int compareNumberedString(const char *s1, const char *s2, bool case_sensitive=true, bool allow_negatives=false)
GLuint GLsizei GLsizei * length
GLint GLint GLsizei GLint GLenum format
UT_String pathUpToExtension() const
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
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())
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.
bool all(const vbool4 &v)
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