HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
UT_String.h
Go to the documentation of this file.
1 /*
2  * PROPRIETARY INFORMATION. This software is proprietary to
3  * Side Effects Software Inc., and is not to be reproduced,
4  * transmitted, or disclosed in any way without written permission.
5  *
6  *
7  * NAME: Utility Library (C++)
8  *
9  * COMMENTS: String class
10  *
11  */
12 
13 #ifndef __UT_String_h__
14 #define __UT_String_h__
15 
16 #include "UT_API.h"
17 
18 #include "UT_Assert.h"
19 #include "UT_Swap.h"
20 #include "UT_VectorTypes.h"
21 
22 #include <SYS/SYS_Compiler.h>
23 #include <SYS/SYS_Inline.h>
24 #include <SYS/SYS_String.h>
25 #include <SYS/SYS_Types.h>
26 
27 #include <functional>
28 #include <iosfwd>
29 #include <string>
30 
31 #include <ctype.h>
32 #include <stdlib.h>
33 #include <string.h>
34 
35 #ifdef WIN32
36  #define strcasecmp stricmp
37  #define strncasecmp strnicmp
38 #endif
39 
40 class UT_OStream;
41 class UT_String;
42 class UT_StringCshIO;
43 class UT_WorkArgs;
44 class UT_IStream;
45 class ut_PatternRecord;
46 class UT_StringMMPattern;
47 class UT_StringArray;
48 class UT_StringHolder;
49 class UT_StringRef;
50 class UT_StringView;
51 
52 // The following lookup functions are used by cshParse. By default,
53 // varLookup simply uses getenv, exprLookup opens the command as
54 // a pipe and uses the result.
55 UT_API extern void UTvarLookup(const char *name, UT_String &result);
56 UT_API extern void UTexprLookup(const char *name, UT_String &result);
57 
58 SYS_FORCE_INLINE bool UTisstring(const char *s) { return s && *s; }
59 
60 // Because invoking isdigit with a negative value is undefined,
61 // some MSVC compilers decide to crash. Thus we cast explicitly
62 // to unsigned.
64  { return isdigit((unsigned char) c); }
65 
66 /// @file
67 /// @class UT_String
68 ///
69 /// UT_String is a string class that support two different types of assignment
70 /// semantics:
71 /// - Shallow (default): Just reference the given string and NOT take
72 /// ownership.
73 /// - Deep: Make a copy of the given string, taking ownership in the
74 /// process (aka it making it "hard").
75 ///
76 /// If UT_String::harden() is called, or any other UT_String method that
77 /// requires modifying the string, it will make a copy of its reference pointer
78 /// (and take ownership) first.
79 ///
81 {
82 public:
83 
84  /// UT_String can be constructed with UT_String::ALWAYS_DEEP to create an
85  /// object that will always perform deep copies when assigned to.
86  enum UT_AlwaysDeepType { ALWAYS_DEEP };
87 
88  /// @brief Construct UT_String from a C string, using shallow semantics
89  ///
90  /// @param str The initial string.
91  /// @param deepCopy If true, a copy of @em str will be used.
92  /// @param len Number of characters to use from @em str. Use -1 to
93  /// use the entire string. If len is non-negative, then
94  /// deepCopy will be implicitly set to true. If str is NULL
95  /// and len is non-negative, then it will be initialized
96  /// with "".
97  UT_String(const char *str = 0)
98  : myIsReference(true)
99  , myIsAlwaysDeep(false)
100  , myData(SYSconst_cast(str))
101  {}
102  UT_String(const char *str, int deepCopy, int len = -1);
103 
104  /// @brief Construct UT_String from a std::string, always doing
105  /// a deep copy. The result will only be a UT_AlwaysDeep if the
106  /// appropriate version is used, however!
107  ///
108  /// NOTE: You cannot do:
109  /// UT_String foo;
110  /// std::string bar = "hello world";
111  /// foo = UT_String(bar.substr(2, 5));
112  ///
113  /// It provides an shortcut for constructing a UT_String from a function
114  /// that returns a std::string by value. For example, it lets you write
115  /// @code
116  /// UT_String str(func());
117  /// @endcode
118  /// instead of
119  /// @code
120  /// UT_String str(func().c_str(), /*harden=*/true);
121  /// @endcode
122  explicit UT_String(const std::string &str)
123  : myIsReference(false),
124  myIsAlwaysDeep(false)
125  { myData = strdup(str.c_str()); }
126 
127  /// @brief Construct UT_String from a UT_StringHolder.
128  /// This always duplicates and uses ALWAYS_DEEP semantics.
129  explicit UT_String(const UT_StringHolder &str);
130 
131 private:
132  /// This is intentionally not implemented - callers should choose between
133  /// the const char * and UT_StringHolder constructors, depending on whether
134  /// they want to make a deep copy.
135  /// @see UT_StringWrap.
136  UT_String(const UT_StringRef &);
137 
138 public:
139  /// @brief Construct UT_String from a UT_StringView.
140  /// This always duplicates and uses ALWAYS_DEEP semantics.
141  explicit UT_String(const UT_StringView &sv);
142 
143  /// @brief Construct UT_String from a C string, using ALWAYS_DEEP semantics
144  UT_String(UT_AlwaysDeepType, const char *str = 0)
145  : myIsReference(false),
146  myIsAlwaysDeep(true)
147  { myData = str ? strdup(str) : 0; }
148 
149  /// @brief Construct UT_String from a std::string, using ALWAYS_DEEP
150  /// semantics
152  : myIsReference(false),
153  myIsAlwaysDeep(true)
154  { myData = strdup(str.c_str()); }
155 
156  /// Copy constructor
157  ///
158  /// If the string we're copying from is ALWAYS_DEEP, then this object will
159  /// also become ALWAYS_DEEP. This way, you can pass/return a string by
160  /// value.
161  UT_String(const UT_String &str);
162 
163  ~UT_String();
164 
165  /// Move operators
166  /// @{
168  : myData(str.myData)
169  , myIsReference(str.myIsReference)
170  , myIsAlwaysDeep(str.myIsAlwaysDeep)
171  {
172  str.myData = nullptr;
173  str.myIsReference = !str.myIsAlwaysDeep;
174  }
176  {
177  freeData();
178  myData = str.myData;
179  myIsReference = str.myIsReference;
180  myIsAlwaysDeep = str.myIsAlwaysDeep;
181  str.myData = nullptr;
182  str.myIsReference = !str.myIsAlwaysDeep;
183  return *this;
184  }
185  /// @}
186 
187  /// Make a string always deep
188  void setAlwaysDeep(bool deep)
189  {
190  myIsAlwaysDeep = deep;
191  if (deep && myIsReference)
192  {
193  if (myData != NULL)
194  harden();
195  else
196  {
197  // This takes the same semantic as
198  // str = NULL;
199  // where str is an always deep string
200  myIsReference = false;
201  }
202  }
203  }
204  bool isAlwaysDeep() const
205  {
206  return myIsAlwaysDeep;
207  }
208 
209  void swap( UT_String &other );
210 
211  /// Take shallow copy and make it deep.
212  // @{
213  void harden()
214  {
215  if (!myIsReference && myData)
216  return;
217  myData = strdup(myData ? myData : "");
218  myIsReference = false;
219  }
220 
221  void harden(const char *s, int len = -1);
223  {
224  if (myIsReference)
225  {
226  if (isstring())
227  harden();
228  else
229  *this = "";
230  }
231  }
232  void hardenIfNeeded(const char *s)
233  {
234  if (s && *s)
235  harden(s);
236  else
237  *this = "";
238  }
239  // @}
240 
241  /// Returns whether this string is hardened already.
242  bool isHard() const { return !myIsReference; }
243 
244  /// Give up ownership of string
245  ///
246  /// Take a hard reference and make it shallow. This method makes sure
247  /// it gives back something you can delete, because this UT_String is
248  /// taking its hands off the data. Use it with care since it may lead
249  /// to memory leaks if, for example, you harden it again later.
250  ///
251  /// In the case of ALWAYS_DEEP strings, this is disallowed so it will
252  /// just return a copy of the data.
253  char * steal(void)
254  {
255  if (!myIsAlwaysDeep)
256  {
257  if (myIsReference)
258  myData = strdup(myData ? myData : ""); // harden
259  myIsReference = true; // but say it's soft
260  return myData;
261  }
262  else
263  {
264  // return a new copy of the data without releasing
265  // ownership for always deep strings
266  return strdup(myData ? myData : "");
267  }
268  }
269 
270  /// Take ownership of given string
271  ///
272  /// adopt() is the opposite of steal(). Basically, you're giving
273  /// the UT_String ownership of the string.
274  // @{
275  void adopt(char *s)
276  {
277  if (!myIsReference)
278  {
279  if (s != myData)
280  free(myData);
281  }
282  myData = s;
283  myIsReference = false;
284  }
285  void adopt(UT_String &str)
286  {
287  adopt(str.steal());
288  }
289  void adopt(UT_StringHolder &holder);
290 
291  // @}
292 
293  /// Save string to binary stream.
294  void saveBinary(std::ostream &os) const { save(os, true); }
295 
296  /// Save string to ASCII stream. This will add double quotes and escape to
297  /// the stream if necessary (empty string or contains spaces).
298  void saveAscii(std::ostream &os) const { save(os, false); }
299  void saveAscii(UT_OStream &os) const { save(os, false); }
300 
301  /// Save string to stream. Saves as binary if @em binary is true.
302  void save(std::ostream &os, bool binary) const;
303  void save(UT_OStream &os, bool binary) const;
304 
305  /// Load string from stream. Use is.eof() to check eof status
306  bool load(UT_IStream &is);
307 
308  /// Reset the string to the default constructor.
309  void clear()
310  { *this = (const char *)NULL; }
311 
312  /// Prepend a string (or character)
313  // @{
314  void prepend(const char *prefix);
315  void prepend(char ch);
316  // @}
317 
318  /// Append a character
319  void append(char ch);
320 
321  /// Append a string or a section of a string.
322  void append(const char *str, exint len = -1);
323 
324  /// Remove the last character
325  void removeLast() { truncate(length()-1); }
326  /// Truncate the string at the Nth character
327  void truncate(exint len);
328 
329  UT_String &operator=(const UT_String &str);
330  UT_String &operator=(const char *str);
331  UT_String &operator=(const std::string &str);
332  UT_String &operator=(const UT_StringHolder &str);
333  UT_String &operator=(const UT_StringView &str);
334 private:
335  /// Not implemented - see UT_String(const UT_StringRef &).
336  UT_String &operator=(const UT_StringRef);
337 
338 public:
339  UT_String &operator+=(const char *str)
340  {
341  if (!isstring())
342  {
343  // We are an empty string, so we merely copy
344  // the incoming string rather than trying to append
345  // to it.
346  harden(str);
347  }
348  else
349  {
350  bool same = (str == myData);
351  harden();
352  if (str)
353  {
354  int mylen = (int)strlen(myData);
355  myData = (char *)realloc(myData,
356  mylen+strlen(str)+1);
357  if (!same)
358  {
359  strcpy(&myData[mylen], str);
360  }
361  else
362  {
363  memcpy(myData + mylen, myData, mylen);
364  myData[mylen * 2] = '\0';
365  }
366  }
367  }
368  return *this;
369  }
370 
372  {
373  *this += (const char *)str.myData;
374  return *this;
375  }
376  UT_String &operator+=(const UT_StringRef &str);
377 
378  // Basic equality functions and operators
379  int compare(const char *str, bool case_sensitive=true) const
380  {
381  // Unlike std::string, UT_String treats NULL and
382  // the empty string as distinct (empty has precedence).
383  if (myData==0 || str==0)
384  {
385  if (myData) return 1;
386  if(str) return -1;
387  return 0;
388  }
389  if (case_sensitive)
390  return strcmp(myData, str);
391  return strcasecmp(myData, str);
392  }
393  int compare(const UT_String &str, bool case_sensitive=true) const
394  {
395  return compare(str.myData,case_sensitive);
396  }
397  int compare(const UT_StringRef &str, bool case_sensitive=true) const;
398 
399  bool equal(const char *str, bool case_sensitive=true) const
400  {
401  return compare(str,case_sensitive)==0;
402  }
403  bool equal(const UT_String &str, bool case_sensitive=true) const
404  {
405  return compare(str.myData,case_sensitive)==0;
406  }
407  bool equal(const UT_StringRef &str, bool case_sensitive=true) const
408  {
409  return compare(str,case_sensitive)==0;
410  }
411 
412  bool operator==(const char *str) const
413  {
414  return compare(str)==0;
415  }
416  bool operator==(const UT_String &str) const
417  {
418  return compare(str.myData)==0;
419  }
420  bool operator==(const UT_StringRef &str) const
421  {
422  return compare(str)==0;
423  }
424  bool operator!=(const char *str) const
425  {
426  return compare(str)!=0;
427  }
428  bool operator!=(const UT_String &str) const
429  {
430  return compare(str.myData)!=0;
431  }
432  bool operator!=(const UT_StringRef &str) const
433  {
434  return compare(str)!=0;
435  }
436  bool operator<(const char *str) const
437  {
438  return compare(str)<0;
439  }
440  bool operator<(const UT_String &str) const
441  {
442  return compare(str.myData)<0;
443  }
444  bool operator<(const UT_StringRef &str) const
445  {
446  return compare(str)<0;
447  }
448  bool operator<=(const char *str) const
449  {
450  return compare(str)<=0;
451  }
452  bool operator<=(const UT_String &str) const
453  {
454  return compare(str.myData)<=0;
455  }
456  bool operator<=(const UT_StringRef &str) const
457  {
458  return compare(str)<=0;
459  }
460  bool operator>(const char *str) const
461  {
462  return compare(str)>0;
463  }
464  bool operator>(const UT_String &str) const
465  {
466  return compare(str.myData)>0;
467  }
468  bool operator>(const UT_StringRef &str) const
469  {
470  return compare(str)>0;
471  }
472  bool operator>=(const char *str) const
473  {
474  return compare(str)>=0;
475  }
476  bool operator>=(const UT_String &str) const
477  {
478  return compare(str.myData)>=0;
479  }
480  bool operator>=(const UT_StringRef &str) const
481  {
482  return compare(str)>=0;
483  }
484 
485  /// Test whether the string is defined or not
486  SYS_SAFE_BOOL operator bool() const { return isstring(); }
487 
488  /// Return the edit distance between two strings.
489  /// See http://en.wikipedia.org/wiki/Levenshtein_distance for details.
490  /// allow_subst controls whether a substitution of a character with
491  /// another is a single operation, rather than two operations of
492  /// insert and delete.
493  int distance(const char *str,
494  bool case_sensitive = true,
495  bool allow_subst = true) const;
496 
497  operator const char *() const
498  { return (const char *)myData; }
499  operator char *()
500  { return myData; }
501 
502  const char *c_str() const { return buffer(); }
503  const char *buffer() const { return myData; }
504  const char *nonNullBuffer() const { return myData ? myData : ""; }
505 
506  char operator()(unsigned i) const
507  {
508  UT_ASSERT_P( isstring() );
509  UT_ASSERT_SLOW(i <= strlen(myData));
510  return myData[i];
511  }
512 
513  char &operator()(unsigned i)
514  {
515  harden();
516  return myData[i];
517  }
518 
519  // Prefer using write() since ideally the non-const operator() is removed
520  inline void write(unsigned i, char c)
521  {
522  hardenIfNeeded();
523  myData[i] = c;
524  }
525 
526  int toInt() const;
527  fpreal toFloat() const;
528 
529  /// Converts the contents of this UT_String to a std::string. Note that
530  /// std::string can't be constructed with a null pointer, so you can't
531  /// just write std::string s = ut_string.buffer();
532  std::string toStdString() const;
533 
534  //
535  // Here, we're finished with operators
536  //
537 
538  /// Return length of string
539  unsigned length(void) const
540  { return (myData) ? (unsigned)strlen(myData) : 0; }
541 
542  /// Return memory usage in bytes
543  int64 getMemoryUsage(bool inclusive=true) const
544  {
545  return (inclusive ? sizeof(*this) : 0)
546  + (!myIsReference ? (length() + 1)*sizeof(char) : 0);
547  }
548 
549  /// Find first occurrance of character. Returns NULL upon failure.
550  char *findChar(int c) const
551  { return (myData) ? strchr(myData, c) : 0; }
552 
553  /// Find first occurrance of any character in @em str
554  // @{
555  char *findChar(const char *str) const
556  { return (myData) ? strpbrk(myData, str) : NULL; }
557  char *findChar(const UT_String &str) const
558  { return findChar((const char *) str); }
559  // @}
560 
561  /// Find last occurance of character
562  char *lastChar(int c) const
563  { return myData ? strrchr(myData, c):0; }
564 
565  /// Return the number of occurrences of the specified character.
566  int countChar(int c) const;
567 
568  /// Count the occurrences of the string
569  int count(const char *str, bool case_sensitive = true) const;
570 
571  char *findNonSpace() const;
572  const char *findWord(const char *word) const;
573  bool findString(const char *str, bool fullword,
574  bool usewildcards) const;
575  int changeWord(const char *from, const char *to, int all=1);
576  int changeString(const char *from, const char *to, bool fullword);
577  int changeQuotedWord(const char *from, const char *to,
578  int quote = '`', int all = 1);
579 
580  int findLongestCommonSuffix( const char *with );
581 
582  /// Perform deep copy of the substring starting from @em index
583  /// for @em len characters into the specified UT_String.
584  /// If @em len is too long, then a substring starting from @em index to
585  /// the end of the string is copied.
586  /// Returns the length of the copied substring.
587  int substr(UT_String &buf, int index, int len=0) const;
588 
589  /// Determine if string can be seen as a single floating point number
590  unsigned isFloat(int skip_spaces = 0, int loose = 0) const;
591  /// Determine if string can be seen as a single integer number
592  unsigned isInteger(int skip_spaces = 0) const;
593 
594  void toUpper()
595  {
596  char *ptr;
597  harden();
598  for (ptr=myData; *ptr; ptr++)
599  *ptr = (char)toupper(*ptr);
600  }
601  void toLower()
602  {
603  char *ptr;
604  harden();
605  for (ptr=myData; *ptr; ptr++)
606  *ptr = (char)tolower(*ptr);
607  }
608 
609 
610  /// Return last component of forward slash separated path string
611  ///
612  /// If there is a slash in the string, fileName() returns the string
613  /// starting after the slash. Otherwise, it returns the contents of
614  /// this string. Note that it returns a pointer into this string.
615  const char *fileName() const
616  {
617  const char *fname;
618 
619  if (!myData)
620  return 0;
621 
622  fname = lastChar('/');
623 
624  if (!fname)
625  {
626  fname = myData;
627  }
628  else
629  {
630  fname++; // Get past the /
631  }
632  return fname;
633  }
634  /// Return the extension of a file path string
635  const char *fileExtension( ) const
636  {
637  if( !isstring() )
638  return 0;
639 
640  const char *dot = lastChar('.');
641  if (dot)
642  {
643  const char *slash = lastChar('/');
644 
645  if (slash && slash > dot)
646  dot = NULL;
647  }
648  return dot;
649  }
650  /// Return whether the file extension matches. The extension passed in
651  /// should include the '.' separator. For example: @code
652  /// matchFileExtension(".jpg")
653  /// @endcode
654  bool matchFileExtension(const char *match_extension) const
655  {
656  const char *ext = fileExtension();
657  return ext && !SYSstrcasecmp(ext, match_extension);
658  }
659  /// Return path terminated just before the extension.
660  /// If the filename starts with '.' and no path is provided,
661  /// returns NULL
662  UT_String pathUpToExtension() const;
663 
664  /// Replace the file extension and return the new string
665  UT_String replaceExtension(const UT_String &new_ext) const;
666 
667  /// Split a path into @em dir_name and @em file_name, where @em file_name
668  /// is everything after the final slash (i.e. the same as fileName()).
669  /// Either part may be empty. Note that if the string starts with / and
670  /// only contains that one slash, the @em dir_name will be / and not blank.
671  /// @em dir_name and @em file_name will either be set to hardened strings
672  /// or an empty string.
673  void splitPath(UT_String &dir_name, UT_String &file_name) const;
674 
675  /// Decompose a filename into various parts
676  ///
677  /// parseNumberedFileName will breakup a filename into its various
678  /// parts: file = prefix$Fsuffix (note: suffix is
679  /// not the same as file extension.) 0 is returned if there is
680  /// no frame number. 'negative' allows -[frame] to be interpreted as a
681  /// negative number. 'fractional' allows [frame].[number] to be interpreted
682  /// as a fractional frame.
683  int parseNumberedFilename(UT_String &prefix,
684  UT_String &frame,
685  UT_String &suff,
686  bool negative = true,
687  bool fractional = false) const;
688 
689  bool isstring() const
690  { return (myData && *myData); }
691 
692  /// trimSpace() will remove all space characters (leading and following)
693  /// from a string. If the string consists of multiple words, the words will
694  /// be collapsed. The function returns 1 if space was trimmed.
695  int trimSpace(bool leaveSingleSpaceBetweenWords = false);
696 
697  /// A version of trimSpace() that only removes leading and following spaces
698  /// from a string, leaving any between words intact.
699  int trimBoundingSpace();
700 
701  /// strips out all characters found in 'chars'. The string length will be
702  /// reduced by the number of characters removed. The number of characters
703  /// removed is returned.
704  int strip(const char *chars);
705 
706  /// protectString() will modify the existing string to escape double quotes
707  /// and backslashes. It will only wrap the string in double quotes if
708  /// it has spaces in it. If 'protect_empty' is true, the string will
709  /// become '""', otherwise it will stay empty.
710  void protectString(bool protect_empty=false);
711 
712  /// returns true if the string begins and ends with a (non-escaped) quote
713  /// 'delimiter'.
714  bool isQuotedString(char delimiter='\'') const;
715 
716  /// makeQuotedString() is similar to protectString() except it returns a
717  /// new string instead of changing this string, it does wrap the string
718  /// in quotes, and it lets you use either ' or " as the delimiter.
719  /// The quoted string can also be optionally be made to escape non-printing
720  /// characters. The string that's returned is UT_String::ALWAYS_DEEP.
721  UT_String makeQuotedString(char delimiter='\'',
722  bool escape_nonprinting=false) const;
723 
724  /// makeSmartQuotedString() will use either ' or " as the delimiter to
725  /// avoid escaped quotes, using the default delimiter if it doesn't
726  /// matter. The quoted string can also be optionally be made to escape
727  /// non-printing characters. The string that's returned is
728  /// UT_String::ALWAYS_DEEP.
729  UT_String makeSmartQuotedString(char default_delimiter='\'',
730  bool escape_nonprinting=false) const;
731 
732  /// Expands standard control sequences ('\\n', '\\r', '\\t', '\\0') to their
733  /// corresponding ASCII values (10, 13, 9, 0, respectively).
734  /// If the expand_extended flag is enabled, an extended expansion is enabled
735  /// which adds hexadecimal, decimal and Unicode control sequence expansion.
736  /// Any values resulting from that expansion, which are outside the standard
737  /// ASCII range, will be encoded as UTF8-encoded control points.
738  void expandControlSequences(bool expand_extended = false);
739 
740  bool hasWhiteSpace() const;
741 
742  void removeTrailingSpace();
743  void removeTrailingChars(char chr);
744 
745  void removeTrailingDigits();
746 
747  // cshParse() does not need to harden the string. It does very robust
748  // parsing in the style of csh. It actually does better parsing than
749  // csh. Variable expansion & backquote expansion are done in the
750  // correct order for the correct arguments. One caveat is that the
751  // string cannot have \0377 (0xff) as a character in it.
752  //
753  // If there is an error in parsing, the error flag (if passed in) will be
754  // set to:
755  // 0 = no error
756  // 1 = line too long
757  int cshParse(char *argv[], int maxArgs,
758  void (*vlookup)(const char *, UT_String&)=UTvarLookup,
759  void (*elookup)(const char *, UT_String&)=UTexprLookup,
760  int *error = 0,
761  UT_StringCshIO *io=0);
762 
763  int cshParse(UT_WorkArgs &argv,
764  void (*vlookup)(const char *, UT_String&)=UTvarLookup,
765  void (*elookup)(const char *, UT_String&)=UTexprLookup,
766  int *error = 0,
767  UT_StringCshIO *io=0);
768 
769  // dosParse() uses the semi-braindead approach of ms-dos to argument
770  // parsing. That is, arguments are separated by a double quote or space
771  // (being a space or a tab). If 'preserve_backslashes' is set to
772  // false (the default), back-slashes are passed through verbatim, unless
773  // the following character is a double quote. Likewise, any pairs of
774  // back-slashes preceding a double quote are turned into single
775  // back-slashes.
776  int dosParse(UT_WorkArgs &argv, bool preserve_backslashes=false);
777  int dosParse(char *argv[], int maxArgs,
778  bool preserve_backslashes=false);
779 
780  /// Perform dos parsing modifying the buffer passed in. The args will be
781  /// stored as raw pointers into the given buffer
782  static int dosParse(char *buffer, UT_WorkArgs &args,
783  bool preserve_backslashes);
784 
785  // parse will insert nulls into the string.
786  // NB: The argv array is null terminated, thus the effective
787  // maximum number of arguments is one less than maxArgs.
788  // NB: The maxArgs variants are all deprecated, use UT_WorkArgs
789  // instead.
790  int parse(char *argv[], int maxArgs)
791  {
792  harden();
793  return parseInPlace(argv, maxArgs);
794  }
795  // Warning: the following method inserts nulls into the
796  // string without hardening.
797  int parseInPlace(char *argv[], int maxArgs);
798  int parse(UT_WorkArgs &argv, int start_arg = 0)
799  {
800  harden();
801  return parseInPlace(argv, start_arg);
802  }
803  int parseInPlace(UT_WorkArgs &argv, int start_arg = 0);
804 
805  int tokenize(char *argv[], int maxArgs, char separator)
806  {
807  harden();
808  return tokenizeInPlace(argv, maxArgs, separator);
809  }
810  int tokenizeInPlace(char *argv[], int maxArgs, char separator);
811  int tokenize(UT_WorkArgs &argv, char separator)
812  {
813  harden();
814  return tokenizeInPlace(argv, separator);
815  }
816  int tokenizeInPlace(UT_WorkArgs &argv, char separator);
817  int tokenize(char *argv[], int maxArgs,
818  const char *separators = " \t\n")
819  {
820  harden();
821  return tokenizeInPlace(argv, maxArgs, separators);
822  }
823  int tokenizeInPlace(char *argv[], int maxArgs,
824  const char *separators = " \t\n");
825  int tokenize(UT_WorkArgs &argv, const char *separators = " \t\n")
826  {
827  harden();
828  return tokenizeInPlace(argv, separators);
829  }
830  int tokenizeInPlace(UT_WorkArgs &argv,
831  const char *separators = " \t\n");
832 
833  template<typename T>
834  int tokenize(T &list, const char *separators = " \t\n")
835  {
836  harden();
837  return tokenizeInPlace(list, separators);
838  }
839 
840  template<typename T>
841  int tokenizeInPlace(T &list,
842  const char *separators = " \t\n")
843  {
844  char *token;
845  char *context;
846 
847  if (!isstring())
848  return 0;
849  if (!(token = SYSstrtok(myData, separators, &context)))
850  return 0;
851 
852  list.append(token);
853 
854  while ((token = SYSstrtok(0, separators, &context)) != NULL)
855  list.append(token);
856 
857  return list.entries();
858  }
859 
860 
861  // Replaces the contents with variables expanded.
862  void expandVariables();
863 
864  // Functions to hash a string
866  {
867  return hash(myData);
868  }
869 
870  static SYS_FORCE_INLINE uint32 hash(const char *str, uint32 code = 0)
871  {
872  return SYSstring_hashseed(str, SYS_EXINT_MAX, code);
873  }
874 
875  // This does pattern matching on a string. The pattern may include
876  // the following syntax:
877  // ? = match a single character
878  // * = match any number of characters
879  // [char_set] = matches any character in the set
880  unsigned match(const char *pattern, int caseSensitive=1) const;
881 
882  // Similar to match() except it assumes that we're dealing with file paths
883  // so that it determines whether to do a case-sensitive match depending on
884  // the platform.
885  unsigned matchFile(const char *pattern) const;
886 
887  // Similar to match() but uses rsync style matching:
888  // * = match any number of characters up to a slash
889  // ** = match any number of characters, including a slash
890  unsigned matchPath(const char *pattern, int caseSensitive=1) const;
891 
892  // multiMatch will actually check multiple patterns all separated
893  // by the separator character: i.e. geo1,geo2,foot*
894  //
895  // NOTE: No pattern or may contain the separator
896  unsigned multiMatch(const char *pattern,
897  int caseSensitive, char separator) const;
898  unsigned multiMatch(const char *pattern, int caseSensitive = 1,
899  const char *separators = ", ",
900  bool *explicitlyExcluded = 0,
901  int *matchIndex = 0,
902  ut_PatternRecord *pattern_record=NULL) const;
903  unsigned multiMatch(const UT_StringMMPattern &pattern,
904  bool *explicitlyExcluded = 0,
905  int *matchIndex = 0,
906  ut_PatternRecord *pattern_record=NULL) const;
907 
908  // this method matches a pattern while recording any wildcard
909  // patterns used.
910  unsigned multiMatchRecord(const char *pattern, int maxpatterns,
911  char *singles, int &nsingles,
912  char **words, int &nwords,
913  int case_sensitive = 1,
914  const char *separators = ", ") const;
915  unsigned multiMatchRecord(const UT_StringMMPattern &pattern,
916  int maxpatterns,
917  char *singles, int &nsingles,
918  char **words, int &nwords) const;
919  unsigned multiMatchRecord(const char *pattern,
920  UT_StringHolder &singles,
921  UT_StringArray &words,
922  int case_sensitive = 1,
923  const char *separators = ", ") const;
924 
925  /// matchPattern(UT_WorkArgs &) assumes that the arguments contain the
926  /// components of a pattern to be matched against. The method returns
927  /// true if the pattern matches, false if it doesn't. This matching
928  /// process handles ^ expansion properly (and efficiently).
929  /// If the string doesn't match any components of the pattern, then the
930  /// assumed value is returned.
931  bool matchPattern(const UT_WorkArgs &pattern_args,
932  bool assume_match=false) const;
933 
934  static int multiMatchCheck(const char *pattern);
935  static int wildcardMatchCheck(const char *pattern);
936 
937  // Same as match but equivalent to "*pattern*"
938  bool contains(const char *pattern, bool case_sensitive=true) const;
939 
940  // Returns true if our string starts with the specified prefix.
941  bool startsWith(const char *prefix,
942  bool case_sensitive = true,
943  exint len = -1) const;
944 
945  // Returns true if our string ends with the specified suffix.
946  bool endsWith(const char *suffix,
947  bool case_sensitive = true,
948  exint len = -1) const;
949 
950  /// Pluralize an English noun ending (i.e. box->boxes or tube->tubes). The
951  /// ending must be lower case to be processed properly.
952  void pluralize();
953 
954  // Will parse strings like 1-10:2,3 and call func for every element
955  // implied. It will stop when the func returns 0 or the parsing
956  // is complete, in which case it returns 1.
957  // Parsing also allows secondary elements to be specified eg 3.4 0.12
958  // The secfunc is used to find the maximum index of secondary elements
959  // for each compound num. The elements are assumed to be
960  // non-negative integers.
961  int traversePattern(int max, void *data,
962  int (*func)(int num, int sec, void *data),
963  unsigned int (*secfunc)(int num,void *data)=0,
964  int offset=0) const;
965 
966  // Fast containment, assumes no special characters
967  const char *fcontain(const char *pattern, bool case_sensitive=true) const
968  {
969  if (!myData) return NULL;
970  return case_sensitive ? strstr(myData, pattern)
971  : SYSstrcasestr(myData, pattern);
972  }
973 
974  // Given the match pattern which fits our contents, any assigned wildcards
975  // are subsitituted. The wildcards may also be indexed.
976  // Returns true if rename was successful.
977  //
978  // @note This code was adapted from CHOP_Rename::subPatterns() and
979  // works the same way.
980  //
981  // eg. this = apple, match = a*le, replace = b* ---> bpp
982  // this = a_to_b, match = *_to_*, replace = *(1)_to_*(0) ---> b_to_a
983  bool patternRename(const char *match_pattern, const char *replace);
984 
985  // Given the name rule according to which a name consists of a base name
986  // (char sequence ending in a non-digit) and a numerical suffix, the
987  // following two methods return the base and the suffix respectively.
988  // base() needs a string buffer and will return a const char* pointing to it.
989  // base() always returns a non-zero pointer,
990  // while suffix() returns 0 if no suffix is found.
991  const char *base(UT_String &buf) const;
992  const char *suffix(void) const;
993 
994  // incrementNumberedName will increment a name. If it has a numerical
995  // suffix, that suffix is incremented. If not, "2" is appended to the
996  // name.
997  void incrementNumberedName();
998 
999  // setFormat is used to set how an outstream formats its ascii output.
1000  // So you can use printf style formatting. eg:
1001  // UT_String::setFormat(cout, "%08d") << 100;
1002  //
1003  // Note: Don't do:
1004  // cout << UT_String::setFormat(cout, "%08d") << 100;
1005  // ^^^^
1006  // Also: The formating changes (except for field width) are permanent,
1007  // so you'll have to reset them manually.
1008  //
1009  // TODO: A resetFormat, and a push/pop format pair.
1010  static std::ostream &setFormat(std::ostream &os, const char *fmt);
1011  std::ostream &setFormat(std::ostream &os);
1012 
1013  int replacePrefix(const char *oldpref,
1014  const char *newpref);
1015  int replaceSuffix(const char *oldsuffix,
1016  const char *newsuffix);
1017 
1018  // expandArrays will expand a series of tokens of the
1019  // form prefix[pattern]suffix into the names array
1020  //
1021  // Note: Each names[i] must be free'd after use
1022  // and label is used on the non-const parse method
1023  int expandArrays(char *names[], int max);
1024 
1025  // This routine will ensure no line is over the specified
1026  // number of columns. Offending lines will be wrapped at
1027  // the first spaceChar or cut at exactly cols if spaceChar
1028  // is not found.
1029  // It returns one if any changes were done.
1030  // It currently treats tabs as single characters which should be
1031  // changed.
1032  // It will break words at hyphens if possible.
1033  int format(int cols);
1034 
1035  // this method is similar to changeWord.. This method performs
1036  // a "dumb" substitution. Return's the # of substitutions
1037  int substitute( const char *find, const char *replacement,
1038  bool all = true );
1039 
1040  // This function replaces the character found with another character.
1041  int substitute( char find, char replacement, bool all = true );
1042 
1043  // this function removes the substring at pos and len, and inserts str
1044  // at pos. it returns the difference (new_length - old_length)
1045  int replace( int pos, int len, const char *str );
1046 
1047  // remove the first len characters of this string
1048  int eraseHead(int len)
1049  { return replace(0, len, ""); }
1050 
1051  // remove the last len characters of this string
1052  int eraseTail(int len)
1053  { return replace(length() - len, len, ""); }
1054 
1055  // remove the substring start at pos for len characters
1056  int erase(int pos = 0, int len = -1)
1057  {
1058  if (len < 0)
1059  len = length() - pos;
1060  return replace(pos, len, "");
1061  }
1062 
1063  // insert the given string at pos into this string
1064  int insert(int pos, const char *str)
1065  { return replace(pos, 0, str); }
1066 
1067  // Does a "smart" string compare which will sort based on numbered names.
1068  // That is "text20" is bigger than "text3". In a strictly alphanumeric
1069  // comparison, this would not be the case. Zero is only returned if both
1070  // strings are identical.
1071  static int compareNumberedString(const char *s1, const char *s2,
1072  bool case_sensitive=true,
1073  bool allow_negatives=false);
1074  static int qsortCmpNumberedString(const char *const*v1, const char *const*v2);
1075 
1076  // Like compare numbered strings, but it sorts better when there are
1077  // .ext extensions (i.e. it handles '.' as a special case)
1078  static int compareNumberedFilename(const char *s1, const char *s2,
1079  bool case_sensitive=false);
1080  static int qsortCmpNumberedFilename(const char *const*v1, const char *const*v2);
1081 
1082  /// Compare two version strings which have numbered components separated by
1083  /// dots. eg. "X.Y.Z". Assumes the components go from most to least
1084  /// significant in left to right order.
1085  static int compareVersionString(const char *s1, const char *s2);
1086 
1087  /// Given a path, set the value of the string to the program name. For
1088  /// example: @code
1089  /// str.extractProgramName(argv[0]);
1090  /// str.extractProgramName("c:/Path/program.exe");
1091  /// str.extractProgramName("/usr/bin/program");
1092  /// @endcode
1093  /// This will extract the last path component. Program names may also have
1094  /// their extensions stripped. For example ".exe" on Windows and "-bin" to
1095  /// strip the Houdini wrappers on other platforms.
1096  ///
1097  /// @note The path should be normalized to have forward slashes as the path
1098  /// separator.
1099  void extractProgramName(const char *path,
1100  bool strip_extension=true,
1101  bool normalize_path=true);
1102 
1103  /// Given a path, check to see whether the program name matches the
1104  /// expected. For example: @code
1105  /// if (UT_String::matchProgramname(argv[0], "houdini"))
1106  /// if (UT_String::matchProgramname("c:/Path/houdini.exe", "houdini"))
1107  /// if (UT_String::matchProgramname("/usr/bin/houdini", "houdini"))
1108  /// @endcode
1109  /// The matching is always case-insensitive.
1110  ///
1111  /// @note The path should be normalized to have forward slashes as the path
1112  /// separator.
1113  static bool matchProgramName(const char *path, const char *expected,
1114  bool normalize_path=false);
1115 
1116  /// Convert a path to a "normalized" path. That is, all back-slashes will
1117  /// be converted to forward slashes. On some operating systems, this will
1118  /// leave the string unchanged.
1119  void normalizePath();
1120 
1121  // A very fast integer to string converter. This is faster (at least on
1122  // SGI) than using sprintf("%d"). About two to three times as fast. Both
1123  // of these methods return the length of the string generated.
1124  static int itoa(char *str, int64 i);
1125  static int utoa(char *str, uint64 i);
1126 
1127  // Versions of the above functions which set into this string object
1128  void itoa(int64 i);
1129  void utoa(uint64 i);
1130 
1131  // A reader-friendly version of itoa. This places commas appropriately
1132  // to ensure the person can pick out the kilo points easily.
1133  // This can handle numbers up to 999,999,999,999,999,999.
1134  void itoa_pretty(int64 val);
1135 
1136  /// Convert the given time delta (in milliseconds)
1137  /// to a reader-friendly string.
1138  void timeDeltaToPrettyString(double time_ms);
1139 
1140  // Do an sprintf into this string. This method will allocate exactly the
1141  // number of bytes required for the final string. If the format string is
1142  // bad, isstring() will return false afterwards.
1143  int sprintf(const char *fmt, ...) SYS_PRINTF_CHECK_ATTRIBUTE(2, 3);
1144 
1145  // This will change the string into a valid C style variable name.
1146  // All non-alpha numerics will be converted to _.
1147  // If the first letter is a digit, it is prefixed with an _.
1148  // This returns 0 if no changes occurred, 1 if something had to
1149  // be adjusted.
1150  // Note that this does NOT force the name to be non-zero in length.
1151  // The safechars parameter is a string containing extra characters
1152  // that should be considered safe. These characters are not
1153  // converted to underscores.
1154  int forceValidVariableName(const char *safechars = NULL);
1155  // Returns true if the string matches a C-style varaible name.
1156  // The safechars are not allowed to be the start.
1157  // Matching forceValid, empty strings are considered valid!
1158  bool isValidVariableName(const char *safechars = NULL) const;
1159 
1160  // This will force all non-alphanumeric characters to be underscores.
1161  // Returns true if any changes were required.
1162  bool forceAlphaNumeric();
1163 
1164  // This function will calculate the relative path to get from src to dest.
1165  // NB: This function DOES NOT handle NT style drive names! It is currently
1166  // only used for op paths. If you want to add support for this, you
1167  // should add a third default parameter to do this.
1168  void getRelativePath(const char *src_fullpath,
1169  const char *dest_fullpath);
1170 
1171  // This function takes two absolute paths and returns the length of the
1172  // longest common path prefix, up to and including the last '/'. This
1173  // means, for instance, that if fullpath1[len1-1] == '/' then all of
1174  // fullpath1 is eligible as a common prefix.
1175  // NB: This function DOES NOT handle NT style drive names! It is currently
1176  // only used for op paths. If you want to add support for this, you
1177  // should add another default parameter to do this.
1178  static int findLongestCommonPathPrefix(const char *fullpath1, int len1,
1179  const char *fullpath2, int len2);
1180 
1181  // This function tests whether we are an absolute path, and returns true or
1182  // false depending on whether we are.
1183  bool isAbsolutePath(bool file_path=false) const;
1184 
1185  // This function assumes that we are an absolute path and will remove all
1186  // un-necessary components from it as long as we remain an absolute path.
1187  // We return false if an error was encountered, in which case the results
1188  // are unpredictable.
1189  bool collapseAbsolutePath(bool file_path=false);
1190 
1191  // This function will make sure that the string is at most max_length
1192  // characters long. If the string is longer than that, it will
1193  // replace the middle of the string by "...". Returns true if the string
1194  // has changed and false otherwise. max_length must be greater than 3.
1195  bool truncateMiddle(int max_length);
1196 
1197  // This function is an abomination when you can just write:
1198  // UT_String foo("");
1199  // ...
1200  // if (foo.isstring())
1201  // ...
1202  // Avoid using it and do not write functions that return "const UT_String&"
1203  static const UT_String &getEmptyString();
1204 
1205  /// Count the number of valid characters in the : modifier for variable
1206  /// expansion. For example, the string ":r" will return 2, the string
1207  /// ":r:t" will return 4, the string ":z" will return 0. These use the csh
1208  /// expansion modifiers.
1209  ///
1210  /// If the string doesn't start with a ':', the method will return 0.
1211  static int countCshModifiers(const char *src);
1212 
1213  /// Applies a "csh" style modifier string to this string. For example, a
1214  /// modifier string of ":e" would replace the string with the file
1215  /// extension of the string.
1216  ///
1217  /// Returns true if any modifications were performed
1218  bool applyCshModifiers(const char *modifiers);
1219 
1220 
1221  /// This will remove the range from a string of the form foo$Fbar.ext (#-#)
1222  /// and return the first number from the range. If there is only 1 range
1223  /// number, it will be returned. If there is no range, 0 is returned.
1224  /// The returned string is hardened.
1225  UT_String removeRange ();
1226 
1227  /// This will format a value to represent a given size in bytes, kilobytes,
1228  /// megabytes, etc.
1229  void formatByteSize(exint size, int digits=2);
1230 
1231  // UTF-8 helpers
1232 
1233  /// Returns the number of Unicode codepoints in the string, assuming it's
1234  /// encoded as UTF-8.
1235  int getCodePointCount() const;
1236 
1237  /// Returns a list of Unicode code points from this string.
1238  void getAsCodePoints(UT_Int32Array &cp_list) const;
1239 
1240  /// Friend specialization of std::swap() to use UT_String::swap()
1241  /// @internal This is needed because standard std::swap() implementations
1242  /// will try to copy the UT_String objects, causing hardened strings to
1243  /// become weak.
1244  friend void swap(UT_String& a, UT_String& b) { a.swap(b); }
1245 
1246 private:
1247  template <typename OSTREAM>
1248  void saveInternal(OSTREAM &os, bool binary) const;
1249 
1250  void freeData();
1251 
1252  /// implements a few csh-style modifiers.
1253  /// @param mod pointer to a string starting with the modifier to apply.
1254  /// so, to apply a global substitute modifier :gs/l/r/
1255  /// mod should be: s/l/r
1256  /// @param all True if all possible modifications should be
1257  /// (recursively) performed.
1258  /// Otherwise, at most one modification is applied.
1259  /// @return whether any modification was performed
1260  bool applyNextModifier(const char *mod, bool all);
1261 
1262 
1263  /// Sets myIsReference to false and copies the other_string into myData,
1264  /// but attempts to avoid unnecessary memory reallocations. Frees up
1265  /// any previous data, if necessary. If other_string is NULL, the call
1266  /// is equivalent to freeData().
1267  void doSmartCopyFrom(const char* other_string);
1268 
1269  static int compareNumberedStringInternal(const char *s1, const char *s2,
1270  bool case_sensitive,
1271  bool allow_negatives,
1272  bool dot_first);
1273 
1274  static inline void utStrFree(char *str)
1275  {
1276 #if defined(UT_DEBUG) && !defined(_WIN32)
1277  if (str)
1278  ::memset((void *)str, 0xDD, ::strlen(str) + 1);
1279 #endif
1280  ::free((void *)str);
1281  }
1282 
1283  char *myData;
1284  bool myIsReference:1,
1285  myIsAlwaysDeep:1;
1286 
1287  /// This operator saves the string to the stream via the string's
1288  /// saveAscii() method, protecting any whitespace (by adding quotes),
1289  /// backslashes or quotes in the string.
1290  friend UT_API std::ostream &operator<<(std::ostream &os, const UT_String &d);
1291  friend UT_API UT_OStream &operator<<(UT_OStream &os, const UT_String &d);
1292 
1293  friend class UT_API UT_StringRef;
1294 };
1295 
1297 {
1298 public:
1299  // We only have a single constructor which is always shallow.
1300  UT_StringWrap(const char *str = 0)
1301  : UT_String(str)
1302  {}
1303 };
1304 
1306 {
1307  if (!myIsReference && myData)
1308  utStrFree(myData);
1309 }
1310 
1311 inline void
1312 UT_String::freeData()
1313 {
1314  if (myData)
1315  {
1316  if (!myIsReference)
1317  utStrFree(myData);
1318  myData = 0;
1319  }
1320 }
1321 
1322 inline void
1324 {
1325  // We can't use UTswap because it doesn't work with bit fields.
1326  bool temp = myIsReference;
1327  myIsReference = other.myIsReference;
1328  other.myIsReference = temp;
1329 
1330  UTswap( myData, other.myData );
1331 
1332  if (myIsAlwaysDeep)
1333  harden();
1334 
1335  if (other.myIsAlwaysDeep)
1336  other.harden();
1337 }
1338 
1340 public:
1341  UT_String myOut; // Points to argument following '>'
1342  UT_String myErr; // Points to argument following '>&'
1343  UT_String myIn; // Points to argument following '<'
1344  short myDoubleOut; // If the argument is '>>' or '>>&'
1345  short myDoubleIn; // If the argument is '<<'
1346 };
1347 
1348 UT_API std::ostream & do_setformat(std::ostream &os, const char fmt[]);
1349 
1350 /// Does a "smart" string compare which will sort based on numbered names.
1351 /// That is "text20" is bigger than "text3". In a strictly alphanumeric
1352 /// comparison, this would not be the case.
1354 {
1355  bool operator()(const char *s1, const char *s2) const
1356  {
1357  return UT_String::compareNumberedString(s1, s2) < 0;
1358  }
1359 
1360  bool operator()(const std::string &s1, const std::string &s2) const
1361  {
1362  return operator()(s1.c_str(), s2.c_str());
1363  }
1364 };
1365 
1367 
1368 #endif
UT_String(const char *str=0)
Construct UT_String from a C string, using shallow semantics.
Definition: UT_String.h:97
UT_String & operator+=(const char *str)
Definition: UT_String.h:339
static SYS_FORCE_INLINE uint32 hash(const char *str, uint32 code=0)
Definition: UT_String.h:870
bool operator!=(const char *str) const
Definition: UT_String.h:424
UT_String & operator+=(const UT_String &str)
Definition: UT_String.h:371
bool operator>=(const UT_StringRef &str) const
Definition: UT_String.h:480
png_voidp s1
Definition: png.h:2193
bool matchFileExtension(const char *match_extension) const
Definition: UT_String.h:654
char * findChar(const UT_String &str) const
Find first occurrance of any character in str.
Definition: UT_String.h:557
void swap(UT_String &other)
Definition: UT_String.h:1323
void UTswap(T &a, T &b)
Definition: UT_Swap.h:35
void saveAscii(UT_OStream &os) const
Definition: UT_String.h:299
bool operator()(const char *s1, const char *s2) const
Definition: UT_String.h:1355
T negative(const T &val)
Return the unary negation of the given value.
Definition: Math.h:116
void swap(UT::ArraySet< Key, MULTI, MAX_LOAD_FACTOR_256, Clearer, Hash, KeyEqual > &a, UT::ArraySet< Key, MULTI, MAX_LOAD_FACTOR_256, Clearer, Hash, KeyEqual > &b)
Definition: UT_ArraySet.h:1561
UT_String(UT_String &&str) SYS_NOEXCEPT
Definition: UT_String.h:167
bool operator<=(const char *str) const
Definition: UT_String.h:448
unsigned length(void) const
Return length of string.
Definition: UT_String.h:539
UT_String myIn
Definition: UT_String.h:1343
GLsizei const GLchar *const * string
Definition: glcorearb.h:813
png_voidp ptr
Definition: png.h:2145
bool operator==(const char *str) const
Definition: UT_String.h:412
bool operator<=(const UT_String &str) const
Definition: UT_String.h:452
const GLuint GLenum const void * binary
Definition: glcorearb.h:1923
bool isHard() const
Returns whether this string is hardened already.
Definition: UT_String.h:242
GLsizei const GLchar *const * path
Definition: glcorearb.h:3340
SYS_FORCE_INLINE T * SYSconst_cast(const T *foo)
Definition: SYS_Types.h:120
GLboolean GLboolean GLboolean GLboolean a
Definition: glcorearb.h:1221
void write(unsigned i, char c)
Definition: UT_String.h:520
bool operator==(const UT_String &str) const
Definition: UT_String.h:416
int tokenize(char *argv[], int maxArgs, char separator)
Definition: UT_String.h:805
int parse(UT_WorkArgs &argv, int start_arg=0)
Definition: UT_String.h:798
#define UT_API
Definition: UT_API.h:12
const char * fileExtension() const
Return the extension of a file path string.
Definition: UT_String.h:635
#define SYS_EXINT_MAX
Definition: SYS_Types.h:165
char & operator()(unsigned i)
Definition: UT_String.h:513
bool equal(const char *str, bool case_sensitive=true) const
Definition: UT_String.h:399
GLfloat GLfloat GLfloat v2
Definition: glcorearb.h:817
int compare(const char *str, bool case_sensitive=true) const
Definition: UT_String.h:379
GLuint buffer
Definition: glcorearb.h:659
png_uint_32 i
Definition: png.h:2877
void clear()
Reset the string to the default constructor.
Definition: UT_String.h:309
bool isAlwaysDeep() const
Definition: UT_String.h:204
const char * c_str() const
Definition: UT_String.h:502
GLsizeiptr size
Definition: glcorearb.h:663
#define UT_ASSERT_P(ZZ)
Definition: UT_Assert.h:101
int compare(const UT_String &str, bool case_sensitive=true) const
Definition: UT_String.h:393
bool operator<(const char *str) const
Definition: UT_String.h:436
const hboost::disable_if_c< VecTraits< T >::IsVec, T >::type & max(const T &a, const T &b)
Definition: Composite.h:132
bool operator<(const UT_StringRef &str) const
Definition: UT_String.h:444
UT_API void UTexprLookup(const char *name, UT_String &result)
int tokenize(UT_WorkArgs &argv, const char *separators=" \t\n")
Definition: UT_String.h:825
std::ostream & operator<<(std::ostream &ostr, const DataType &a)
Definition: DataType.h:133
UT_String(UT_AlwaysDeepType, const std::string &str)
Construct UT_String from a std::string, using ALWAYS_DEEP semantics.
Definition: UT_String.h:151
void hardenIfNeeded(const char *s)
Take shallow copy and make it deep.
Definition: UT_String.h:232
long long int64
Definition: SYS_Types.h:100
const char * buffer() const
Definition: UT_String.h:503
A utility class to do read-only operations on a subset of an existing string.
Definition: UT_StringView.h:30
SYS_FORCE_INLINE uint32 hash() const
Definition: UT_String.h:865
bool operator==(const UT_StringRef &str) const
Definition: UT_String.h:420
unsigned long long uint64
Definition: SYS_Types.h:101
bool operator>=(const char *str) const
Definition: UT_String.h:472
UT_String & operator=(UT_String &&str)
Definition: UT_String.h:175
char * findChar(int c) const
Find first occurrance of character. Returns NULL upon failure.
Definition: UT_String.h:550
int tokenizeInPlace(T &list, const char *separators=" \t\n")
Definition: UT_String.h:841
#define SYS_SAFE_BOOL
Definition: SYS_Compiler.h:56
T distance(const UT_Vector4T< T > &v1, const UT_Vector4T< T > &v2)
Definition: UT_Vector4.h:634
int64 exint
Definition: SYS_Types.h:109
bool operator!=(const UT_String &str) const
Definition: UT_String.h:428
bool operator>=(const UT_String &str) const
Definition: UT_String.h:476
#define SYS_PRINTF_CHECK_ATTRIBUTE(string_index, first_to_check)
Definition: SYS_Types.h:419
fpreal64 dot(const CE_VectorT< T > &a, const CE_VectorT< T > &b)
Definition: CE_Vector.h:218
#define SYS_FORCE_INLINE
Definition: SYS_Inline.h:45
bool operator>(const UT_String &str) const
Definition: UT_String.h:464
GLintptr offset
Definition: glcorearb.h:664
char * SYSstrtok(char *string, const char *delimit, char **context)
Definition: SYS_String.h:110
void harden()
Take shallow copy and make it deep.
Definition: UT_String.h:213
void saveAscii(std::ostream &os) const
Definition: UT_String.h:298
bool equal(const UT_StringRef &str, bool case_sensitive=true) const
Definition: UT_String.h:407
bool equal(const UT_String &str, bool case_sensitive=true) const
Definition: UT_String.h:403
SYS_FORCE_INLINE bool UTisdigit(char c)
Definition: UT_String.h:63
void setAlwaysDeep(bool deep)
Make a string always deep.
Definition: UT_String.h:188
bool operator>(const UT_StringRef &str) const
Definition: UT_String.h:468
bool operator()(const std::string &s1, const std::string &s2) const
Definition: UT_String.h:1360
GLboolean * data
Definition: glcorearb.h:130
GLuint const GLchar * name
Definition: glcorearb.h:785
int eraseHead(int len)
Definition: UT_String.h:1048
void toUpper()
Definition: UT_String.h:594
void adopt(UT_String &str)
Definition: UT_String.h:285
GLboolean GLboolean GLboolean b
Definition: glcorearb.h:1221
bool operator>(const char *str) const
Definition: UT_String.h:460
int64 getMemoryUsage(bool inclusive=true) const
Return memory usage in bytes.
Definition: UT_String.h:543
GLint GLsizei count
Definition: glcorearb.h:404
void saveBinary(std::ostream &os) const
Save string to binary stream.
Definition: UT_String.h:294
char * lastChar(int c) const
Find last occurance of character.
Definition: UT_String.h:562
UT_SWAPPER_CLASS(UT_String)
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glcorearb.h:2539
int tokenize(char *argv[], int maxArgs, const char *separators=" \t\n")
Definition: UT_String.h:817
char * steal(void)
Definition: UT_String.h:253
static int compareNumberedString(const char *s1, const char *s2, bool case_sensitive=true, bool allow_negatives=false)
short myDoubleIn
Definition: UT_String.h:1345
GLint GLint GLsizei GLint GLenum format
Definition: glcorearb.h:107
void adopt(char *s)
Definition: UT_String.h:275
double fpreal
Definition: SYS_Types.h:263
png_voidp png_voidp s2
Definition: png.h:2193
GLenum func
Definition: glcorearb.h:782
typedef int
Definition: png.h:1175
SYS_FORCE_INLINE bool UTisstring(const char *s)
Definition: UT_String.h:58
short myDoubleOut
Definition: UT_String.h:1344
#define SYS_NOEXCEPT
Definition: SYS_Compiler.h:49
UT_StringWrap(const char *str=0)
Definition: UT_String.h:1300
char * SYSstrcasestr(const char *haystack, const char *needle)
Replacement for strcasestr, since no equivalent exists on Win32.
Definition: SYS_String.h:245
int SYSstrcasecmp(const char *a, const char *b)
Definition: SYS_String.h:224
GLuint index
Definition: glcorearb.h:785
#define UT_ASSERT_SLOW(ZZ)
Definition: UT_Assert.h:100
UT_AlwaysDeepType
Definition: UT_String.h:86
GLfloat GLfloat v1
Definition: glcorearb.h:816
GLuint GLfloat * val
Definition: glcorearb.h:1607
UT_String myOut
Definition: UT_String.h:1341
UT_String myErr
Definition: UT_String.h:1342
bool isstring() const
Definition: UT_String.h:689
png_infop png_uint_32 int num
Definition: png.h:2158
void hardenIfNeeded()
Take shallow copy and make it deep.
Definition: UT_String.h:222
UT_String(UT_AlwaysDeepType, const char *str=0)
Construct UT_String from a C string, using ALWAYS_DEEP semantics.
Definition: UT_String.h:144
bool operator<(const UT_String &str) const
Definition: UT_String.h:440
int erase(int pos=0, int len=-1)
Definition: UT_String.h:1056
#define const
Definition: zconf.h:214
int tokenize(UT_WorkArgs &argv, char separator)
Definition: UT_String.h:811
bool operator<=(const UT_StringRef &str) const
Definition: UT_String.h:456
char operator()(unsigned i) const
Definition: UT_String.h:506
void removeLast()
Remove the last character.
Definition: UT_String.h:325
UT_API void UTvarLookup(const char *name, UT_String &result)
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...
Definition: UT_String.h:122
int parse(char *argv[], int maxArgs)
Definition: UT_String.h:790
int eraseTail(int len)
Definition: UT_String.h:1052
const char * fileName() const
Definition: UT_String.h:615
char * findChar(const char *str) const
Find first occurrance of any character in str.
Definition: UT_String.h:555
UT_API std::ostream & do_setformat(std::ostream &os, const char fmt[])
int tokenize(T &list, const char *separators=" \t\n")
Definition: UT_String.h:834
const char * nonNullBuffer() const
Definition: UT_String.h:504
GLuint GLsizei GLsizei * length
Definition: glcorearb.h:794
void toLower()
Definition: UT_String.h:601
GLenum src
Definition: glcorearb.h:1792
unsigned int uint32
Definition: SYS_Types.h:29
int insert(int pos, const char *str)
Definition: UT_String.h:1064
const char * fcontain(const char *pattern, bool case_sensitive=true) const
Definition: UT_String.h:967
bool operator!=(const UT_StringRef &str) const
Definition: UT_String.h:432