HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
stringUtils.h
Go to the documentation of this file.
1 //
2 // Copyright 2016 Pixar
3 //
4 // Licensed under the terms set forth in the LICENSE.txt file available at
5 // https://openusd.org/license.
6 //
7 #ifndef PXR_BASE_TF_STRING_UTILS_H
8 #define PXR_BASE_TF_STRING_UTILS_H
9 
10 /// \file tf/stringUtils.h
11 /// \ingroup group_tf_String
12 /// Definitions of basic string utilities in tf.
13 
14 #include "pxr/pxr.h"
15 
17 #include "pxr/base/arch/hints.h"
18 #include "pxr/base/arch/inttypes.h"
19 #include "pxr/base/tf/api.h"
20 #include "pxr/base/tf/enum.h"
21 
22 #include <cstdarg>
23 #include <cstring>
24 #include <list>
25 #include <locale>
26 #include <set>
27 #include <sstream>
28 #include <string>
29 #include <type_traits>
30 #include <vector>
31 
33 
34 class TfToken;
35 
36 /// \addtogroup group_tf_String
37 ///@{
38 
39 /// Returns a string formed by a printf()-like specification.
40 ///
41 /// \c TfStringPrintf() is a memory-safe way of forming a string using
42 /// printf()-like formatting. For example,
43 /// \code
44 /// string formatMsg(const string& caller, int i, double val[])
45 /// {
46 /// return TfStringfPrintf("%s: val[%d] = %g\n", caller.c_str(), i, val[i]);
47 /// }
48 /// \endcode
49 ///
50 /// The function is safe only to the extent that the arguments match the
51 /// formatting string. In particular, be careful to pass strings themselves
52 /// into \c TfStringPrintf() as in the above example (i.e. \c caller.c_str()
53 /// as opposed to just passing \c caller).
54 ///
55 /// \note \c TfStringPrintf() is just a wrapper for \c ArchStringPrintf().
56 TF_API
57 std::string TfStringPrintf(const char *fmt, ...)
58 #ifndef doxygen
59  ARCH_PRINTF_FUNCTION(1, 2)
60 #endif /* doxygen */
61  ;
62 
63 /// Returns a string formed by a printf()-like specification.
64 ///
65 /// \c TfVStringPrintf() is equivalent to \c TfStringPrintf() except that it
66 /// is called with a \c va_list instead of a variable number of arguments. \c
67 /// TfVStringPrintf() does not call the \c va_end macro. Consequently, the
68 /// value of \c ap is undefined after the call. A functions that calls \c
69 /// TfVStringPrintf() should call \c va_end(ap) itself afterwards.
70 ///
71 /// \note \c TfVStringPrintf() is just a wrapper for \c ArchVStringPrintf().
72 TF_API
73 std::string TfVStringPrintf(const std::string& fmt, va_list ap);
74 
75 /// Bloat-avoidance version of TfVStringPrintf()
76 
77 TF_API
78 std::string TfVStringPrintf(const char *fmt, va_list ap)
79 #ifndef doxygen
80  ARCH_PRINTF_FUNCTION(1, 0)
81 #endif /* doxygen */
82  ;
83 
84 /// Safely create a std::string from a (possibly NULL) char*.
85 ///
86 /// If \p ptr is NULL, the empty string is safely returned.
87 inline std::string TfSafeString(const char* ptr) {
88  return ptr ? std::string(ptr) : std::string();
89 }
90 
91 /// Returns the given integer as a string.
92 inline std::string TfIntToString(int i) {
93  return TfStringPrintf("%d", i);
94 }
95 
96 /// Converts text string to double
97 ///
98 /// This method converts strings to floating point numbers. It is similar to
99 /// libc's atof(), but performs the conversion much more quickly.
100 ///
101 /// It expects somewhat valid input: it will continue parsing the input until
102 /// it hits an unrecognized character, as described by the regexp below, and
103 /// at that point will return the results up to that point.
104 ///
105 /// (-?[0-9]+(\.[0-9]*)?|-?\.[0-9]+)([eE][-+]?[0-9]+)?
106 ///
107 /// It will not check to see if there is any input at all, or whitespace
108 /// after the digits. Ie:
109 /// TfStringToDouble("") == 0.0
110 /// TfStringToDouble("blah") == 0.0
111 /// TfStringToDouble("-") == -0.0
112 /// TfStringToDouble("1.2foo") == 1.2
113 ///
114 /// \note \c TfStringToDouble is a wrapper around the extern-c TfStringToDouble
115 TF_API double TfStringToDouble(const std::string& txt);
116 
117 /// \overload
118 TF_API double TfStringToDouble(const char *text);
119 
120 /// \overload
121 TF_API double TfStringToDouble(const char *text, int len);
122 
123 /// Convert a sequence of digits in \p txt to a long int value. Caller is
124 /// responsible for ensuring that \p txt has content matching:
125 ///
126 /// \code
127 /// -?[0-9]+
128 /// \endcode
129 ///
130 /// If the digit sequence's value is out of range, set \p *outOfRange to true
131 /// (if \p outOfRange is not NULL) and return either
132 /// std::numeric_limits<long>::min() or max(), whichever is closest to the
133 /// true value.
134 TF_API
135 long TfStringToLong(const std::string &txt, bool *outOfRange=NULL);
136 
137 /// \overload
138 
139 TF_API
140 long TfStringToLong(const char *txt, bool *outOfRange=NULL);
141 
142 /// Convert a sequence of digits in \p txt to an unsigned long value. Caller
143 /// is responsible for ensuring that \p txt has content matching:
144 ///
145 /// \code
146 /// [0-9]+
147 /// \endcode
148 ///
149 /// If the digit sequence's value is out of range, set \p *outOfRange to true
150 /// (if \p outOfRange is not NULL) and return std::numeric_limits<unsigned
151 /// long>::max().
152 TF_API
153 unsigned long TfStringToULong(const std::string &txt, bool *outOfRange=NULL);
154 
155 /// \overload
156 
157 TF_API
158 unsigned long TfStringToULong(const char *txt, bool *outOfRange=NULL);
159 
160 /// Convert a sequence of digits in \p txt to an int64_t value. Caller must
161 /// ensure that \p txt has content matching:
162 ///
163 /// \code
164 /// -?[0-9]+
165 /// \endcode
166 ///
167 /// If the digit sequence's value is out of range, set \p *outOfRange to true
168 /// (if \p outOfRange is not NULL) and return either
169 /// std::numeric_limits<int64_t>::min() or max(), whichever is closest to the
170 /// true value.
171 TF_API
172 int64_t TfStringToInt64(const std::string &txt, bool *outOfRange=NULL);
173 
174 /// \overload
175 TF_API
176 int64_t TfStringToInt64(const char *txt, bool *outOfRange=NULL);
177 
178 /// Convert a sequence of digits in \p txt to a uint64_t value. Caller is
179 /// responsible for ensuring that \p txt has content matching:
180 ///
181 /// \code
182 /// [0-9]+
183 /// \endcode
184 ///
185 /// If the digit sequence's value is out of range, set \p *outOfRange to true
186 /// (if \p outOfRange is not NULL) and return std::numeric_limits<unsigned
187 /// long>::max().
188 TF_API
189 uint64_t TfStringToUInt64(const std::string &txt, bool *outOfRange=NULL);
190 
191 /// \overload
192 TF_API
193 uint64_t TfStringToUInt64(const char *txt, bool *outOfRange=NULL);
194 
195 inline bool
196 Tf_StringStartsWithImpl(char const *s, size_t slen,
197  char const *prefix, size_t prelen)
198 {
199  return slen >= prelen && strncmp(s, prefix, prelen) == 0;
200 }
201 
202 /// Returns true if \p s starts with \p prefix.
203 inline bool
204 TfStringStartsWith(const std::string& s, const char *prefix)
205 {
207  s.c_str(), s.length(), prefix, strlen(prefix));
208 }
209 
210 /// \overload
211 inline bool
212 TfStringStartsWith(const std::string& s, const std::string& prefix) {
213  return TfStringStartsWith(s, prefix.c_str());
214 }
215 
216 inline bool
217 Tf_StringEndsWithImpl(char const *s, size_t slen,
218  char const *suffix, size_t suflen)
219 {
220  return slen >= suflen && strcmp(s + (slen - suflen), suffix) == 0;
221 }
222 
223 /// Returns true if \p s ends with \p suffix.
224 inline bool TfStringEndsWith(const std::string& s, const char *suffix)
225 {
226  return Tf_StringEndsWithImpl(s.c_str(), s.length(),
227  suffix, strlen(suffix));
228 }
229 
230 /// \overload
231 inline bool
232 TfStringEndsWith(const std::string& s, const std::string& suffix)
233 {
234  return TfStringEndsWith(s, suffix.c_str());
235 }
236 
237 /// Returns true if \p s contains \p substring.
238 // \ingroup group_tf_String
239 TF_API
240 bool TfStringContains(const std::string& s, const char *substring);
241 
242 /// \overload
243 inline bool
244 TfStringContains(const std::string &s, const std::string &substring) {
245  return TfStringContains(s, substring.c_str());
246 }
247 
248 /// \overload
249 TF_API
250 bool TfStringContains(const std::string &s, const TfToken& substring);
251 
252 /// Makes all characters in \p source lowercase, and returns the result.
253 TF_API
254 std::string TfStringToLower(const std::string& source);
255 
256 /// Makes all characters in \p source uppercase, and returns the result.
257 TF_API
258 std::string TfStringToUpper(const std::string& source);
259 
260 /// Returns a copy of the \p source string with only its first character
261 /// capitalized. This emulates the behavior of Python's \c str.capitalize().
262 TF_API
263 std::string TfStringCapitalize(const std::string& source);
264 
265 /// Locale-independent case folding of [A-Z] for ASCII or UTF-8 encoded
266 /// \p source strings
267 ///
268 /// This can be used for case insensitive matching where one of the strings
269 /// being compared either known to be ASCII only by specification (like a URI
270 /// scheme or an explicit token) or where the specification explicitly notes
271 /// that only [A-Z] will be matched case insensitively.
272 ///
273 /// \code
274 /// TfStringEndsWith(TfStringToLowerAscii("ΓΌ.JPG"), ".jpg")
275 /// \endcode
276 TF_API
277 std::string TfStringToLowerAscii(const std::string& source);
278 
279 /// Trims characters (by default, whitespace) from the left.
280 ///
281 /// Characters from the beginning of \p s are removed until a character not in
282 /// \p trimChars is found; the result is returned.
283 TF_API
284 std::string TfStringTrimLeft(const std::string& s,
285  const char* trimChars = " \n\t\r");
286 
287 /// Trims characters (by default, whitespace) from the right.
288 ///
289 /// Characters at the end of \p s are removed until a character not in \p
290 /// trimChars is found; the result is returned.
291 TF_API
292 std::string TfStringTrimRight(const std::string& s,
293  const char* trimChars = " \n\t\r");
294 
295 /// Trims characters (by default, whitespace) from the beginning and end of
296 /// string.
297 ///
298 /// Characters at the beginning and end of \p s are removed until a character
299 /// not in \p trimChars is found; the result is returned.
300 TF_API
301 std::string TfStringTrim(const std::string& s,
302  const char* trimChars = " \n\t\r");
303 
304 /// Returns the common prefix of the input strings, if any.
305 ///
306 /// Copies of the input strings are compared. Returns a new string which is
307 /// the longest prefix common to both input strings. If the strings have no
308 /// common prefix, an empty string is returned.
309 TF_API
310 std::string TfStringGetCommonPrefix(std::string a, std::string b);
311 
312 /// Returns the suffix of a string
313 ///
314 /// Returns characters after the final character \c delimiter (default ".") of
315 /// a string. Thus suffix of "abc.def" is "def" using "." as the delimiter.
316 /// If the delimiter does not occur, the empty string is returned.
317 TF_API
318 std::string TfStringGetSuffix(const std::string& name, char delimiter = '.');
319 
320 /// Returns everything up to the suffix of a string
321 ///
322 /// Returns characters before the final character \c delimiter (default ".")
323 /// of a string. Thus not-suffix of "abc.def" is "abc" using "." as the
324 /// delimiter. If the delimiter does not occur, the original string is
325 /// returned.
326 TF_API
327 std::string TfStringGetBeforeSuffix(const std::string& name, char delimiter = '.');
328 
329 /// Returns the base name of a file (final component of the path, after
330 /// stripping all trailing slashes - forward only on Linux / MacOS, forward
331 /// and backward on Windows).
332 TF_API
333 std::string TfGetBaseName(const std::string& fileName);
334 
335 /// Returns the path component of a file (complement of TfGetBaseName()).
336 ///
337 /// The returned string ends in a '/' (or possibly a '\' on Windows), unless
338 /// none was found in \c fileName, in which case the empty string is returned.
339 /// In particular, \c TfGetPathName(s)+TfGetBaseName(s) == \c s for any string
340 /// \c s which doesn't end with a trailing slash. If \c s does end with a
341 /// trailing slash (forward only on Linux / MacOS, foward and backward on
342 /// Windows), then \c TfGetPathName(s) == \c s, but \c TfGetBaseName(s) will
343 /// only be \c "" if and only if \c s is an empty string or consists of nothing
344 /// but slashes.
345 
346 TF_API
347 std::string TfGetPathName(const std::string& fileName);
348 
349 /// Replaces all occurrences of string \p from with \p to in \p source
350 ///
351 /// Returns a new string which is created by copying \p source and replacing
352 /// every occurrence of \p from with \p to. Correctly handles the case in which
353 /// \p to contains \p from.
354 TF_API
355 std::string TfStringReplace(const std::string& source, const std::string& from,
356  const std::string& to);
357 
358 /// Concatenates the strings (\p begin, \p end), with default separator.
359 ///
360 /// Returns the concatenation of the strings in the range \p begin to \p end,
361 /// with \p separator (by default, a space) added between each successive pair
362 /// of strings.
363 template <class ForwardIterator>
364 std::string TfStringJoin(
365  ForwardIterator begin, ForwardIterator end,
366  const char* separator = " ")
367 {
368  if (begin == end)
369  return std::string();
370 
371  size_t distance = std::distance(begin, end);
372  if (distance == 1)
373  return *begin;
374 
375  std::string retVal;
376 
377  size_t sum = 0;
378  ForwardIterator i = begin;
379  for (i = begin; i != end; ++i)
380  sum += i->size();
381  retVal.reserve(sum + strlen(separator) * (distance - 1));
382 
383  i = begin;
384  retVal.append(*i);
385  while (++i != end) {
386  retVal.append(separator);
387  retVal.append(*i);
388  }
389 
390  return retVal;
391 }
392 
393 /// Concatenates \p strings, with default separator.
394 ///
395 /// Returns the concatenation of the strings in \p strings, with \p separator
396 /// (by default, a space) added between each successive pair of strings.
397 TF_API
398 std::string TfStringJoin(const std::vector<std::string>& strings,
399  const char* separator = " ");
400 
401 /// Concatenates \p strings, with default separator.
402 ///
403 /// Returns the concatenation of the strings in \p strings, with \p separator
404 /// (by default, a space) added between each successive pair of strings.
405 TF_API
406 std::string TfStringJoin(const std::set<std::string>& strings,
407  const char* separator = " ");
408 
409 /// Breaks the given string apart, returning a vector of strings.
410 ///
411 /// The string \p source is broken apart into individual words, where a word
412 /// is delimited by the string \p separator. This function behaves like
413 /// pythons string split method.
414 TF_API
415 std::vector<std::string> TfStringSplit(std::string const &src,
416  std::string const &separator);
417 
418 /// Breaks the given string apart, returning a vector of strings.
419 ///
420 /// The string \p source is broken apart into individual words, where a word
421 /// is delimited by the characters in \p delimiters. Delimiters default to
422 /// white space (space, tab, and newline).
423 ///
424 /// No empty strings are returned: delimiters at the start or end are ignored,
425 /// consecutive delimiters are treated as though they were one, and an empty
426 /// input will result in an empty return vector.
427 TF_API
428 std::vector<std::string> TfStringTokenize(const std::string& source,
429  const char* delimiters = " \t\n");
430 
431 /// Breaks the given string apart, returning a set of strings.
432 ///
433 /// Same as TfStringTokenize, except this one returns a set.
434 TF_API
435 std::set<std::string> TfStringTokenizeToSet(const std::string& source,
436  const char* delimiters = " \t\n");
437 
438 /// Breaks the given quoted string apart, returning a vector of strings.
439 ///
440 /// The string \p source is broken apart into individual words, where a word
441 /// is delimited by the characters in \p delimiters. This function is similar
442 /// to \c TfStringTokenize, except it considers a quoted string as a single
443 /// word. The function will preserve quotes that are nested within other
444 /// quotes or are preceded by a backslash character. \p errors, if provided,
445 /// contains any error messages. Delimiters default to white space (space,
446 /// tab, and newline).
447 TF_API
448 std::vector<std::string>
449 TfQuotedStringTokenize(const std::string& source,
450  const char* delimiters = " \t\n",
451  std::string *errors = NULL);
452 
453 /// Breaks the given string apart by matching delimiters.
454 ///
455 /// The string \p source is broken apart into individual words, where a word
456 /// begins with \p openDelimiter and ends with a matching \p closeDelimiter.
457 /// Any delimiters within the matching delimiters become part of the word, and
458 /// anything outside matching delimiters gets dropped. For example, \c
459 /// TfMatchedStringTokenize("{a} string {to {be} split}", '{', '}') would
460 /// return a vector containing "a" and "to {be} split". If \p openDelimiter and
461 /// \p closeDelimiter cannot be the same. \p errors, if provided, contains any
462 /// error messages.
463 TF_API
464 std::vector<std::string>
465 TfMatchedStringTokenize(const std::string& source,
466  char openDelimiter,
467  char closeDelimiter,
468  char escapeCharacter = '\0',
469  std::string *errors = NULL);
470 
471 /// This overloaded version of \c TfMatchedStringTokenize does not take an \c
472 /// escapeCharacter parameter but does take \param errors. It allows \c
473 /// TfMatchedStringTokenize to be called with or without an \c escapeCharacter
474 /// and with or without \c errors.
475 ///
476 /// \overload
477 inline
478 std::vector<std::string>
479 TfMatchedStringTokenize(const std::string& source,
480  char openDelimiter,
481  char closeDelimiter,
482  std::string *errors)
483 {
484  return TfMatchedStringTokenize(source, openDelimiter,
485  closeDelimiter, '\0', errors);
486 }
487 
488 /// \class TfDictionaryLessThan
489 ///
490 /// Provides dictionary ordering binary predicate function on strings.
491 ///
492 /// The \c TfDictionaryLessThan class is a functor as defined by the STL
493 /// standard. It compares strings using "dictionary" order: for example, the
494 /// following strings are in dictionary order:
495 /// ["abacus", "Albert", "albert", "baby", "Bert", "file01", "file001", "file2",
496 /// "file10"]
497 ///
498 /// Note that capitalization matters only if the strings differ by
499 /// capitalization alone.
500 ///
501 /// Characters whose ASCII value are inbetween upper- and lowercase letters,
502 /// such as underscore, are sorted to come after all letters.
503 ///
504 /// \note This comparison is used for the runtime to give a deterministic
505 /// ordering to strings.
506 ///
507 /// ASCII strings will sort lexicographically according to the rules below.
508 /// Strings with other Unicode characters will follow these same rules until a
509 /// multi-byte codepoint is encountered in which case it will be byte compared
510 /// with the bytes in the other string. Multi-byte encoded characters will
511 /// operate this way for each of the bytes.
512 ///
513 /// Note that this results in a non-lexicographic ordering of strings that
514 /// contain non-ASCII characters. Clients interested in sorting strings
515 /// lexicographically should not rely on this function for doing so and should
516 /// instead use a custom sort function (or use one provided by an already
517 /// existing library such as Qt or ICU).
519  /// Return true if \p lhs is less than \p rhs in dictionary order.
520  ///
521  /// Normally this functor is used to supply an ordering functor for STL
522  /// containers: for example,
523  /// \code
524  /// map<string, DataType, TfDictionaryLessThan> table;
525  /// \endcode
526  ///
527  /// If you simply need to compare two strings, you can do so as follows:
528  /// \code
529  /// bool aIsFirst = TfDictionaryLessThan()(aString, bString);
530  /// \endcode
531  inline bool operator()(const std::string &lhs,
532  const std::string &rhs) const {
533  // Check first chars first. By far, it is most common that these
534  // characters are ASCII letters that differ. It is very rare that we
535  // have to account for different cases, or numerical comparisons, or
536  // UTF-8 characters so we special-case this first.
537  const unsigned char l = lhs.c_str()[0], r = rhs.c_str()[0];
538  const bool bothAscii = l < 0x80 && r < 0x80;
539  const bool differsIgnoringCase = (l & ~0x20) != (r & ~0x20);
540  const bool inLetterZone = (l >= 0x40) && (r >= 0x40);
541  if (ARCH_LIKELY(bothAscii && differsIgnoringCase && inLetterZone)) {
542  // This bit about add 5 mod 32 makes it so that '_' sorts less than
543  // all letters, which preserves existing behavior.
544  return ((l + 5) & 31) < ((r + 5) & 31);
545  }
546  else {
547  return _LessImpl(lhs, rhs);
548  }
549  }
550 private:
551  TF_API bool _LessImpl(const std::string &lhs,
552  const std::string &rhs) const;
553 };
554 
555 /// Convert an arbitrary type into a string
556 ///
557 /// Use the type's stream output operator to convert it into a string. You are
558 /// free to use the stream operators in ostreamMethods.h, but are not required
559 /// to do so.
560 template <typename T>
561 std::string
562 TfStringify(const T& v)
563 {
564  if constexpr (std::is_enum<T>::value) {
565  return TfEnum::GetName(v);
566  }
567  else {
568  std::ostringstream stream;
569  stream.imbue(std::locale::classic());
570  stream << v;
571  return stream.str();
572  }
573 }
574 
575 /// \overload
576 TF_API std::string TfStringify(bool v);
577 /// \overload
578 TF_API std::string TfStringify(std::string const&);
579 /// \overload
580 TF_API std::string TfStringify(float);
581 /// \overload
582 TF_API std::string TfStringify(double);
583 
584 /// Writes the string representation of \c d to \c buffer of length \c len.
585 /// If \c emitTrailingZero is true, the string representation will end with .0
586 /// in the case where d is an integer otherwise it will be omitted.
587 /// The buffer length must be at least 25 in order to ensure that all doubles
588 /// values can be represented.
589 /// Returns whether the conversion was successful.
591  double d, char* buffer, int len, bool emitTrailingZero);
592 
593 /// \struct TfStreamFloat
594 ///
595 /// A type which offers streaming for floats in a canonical
596 /// format that can safely roundtrip with the minimal number of digits.
598  explicit TfStreamFloat(float f) : value(f) {}
599  float value;
600 };
601 
602 TF_API std::ostream& operator<<(std::ostream& o, TfStreamFloat t);
603 
604 /// \struct TfStreamDouble
605 ///
606 /// A type which offers streaming for doubles in a canonical
607 /// format that can safely roundtrip with the minimal number of digits.
609  explicit TfStreamDouble(double d) : value(d) {}
610  double value;
611 };
612 
613 TF_API std::ostream& operator<<(std::ostream& o, TfStreamDouble t);
614 
615 /// Convert a string to an arbitrary type
616 ///
617 /// Use the type's stream input operator to get it from a string. If \p status
618 /// is non-NULL and \p instring cannot be converted to a \c T, \p *status is
619 /// set to \c false; otherwise, \p *status is not modified.
620 template <typename T>
621 T
622 TfUnstringify(const std::string &instring, bool* status = NULL)
623 {
624  T v = T();
625  std::istringstream stream(instring);
626  stream >> v;
627  if (status && !stream)
628  *status = false;
629  return v;
630 }
631 
632 /// \overload
633 template <>
634 TF_API
635 bool TfUnstringify(const std::string &instring, bool* status);
636 /// \overload
637 template <>
638 TF_API
639 std::string TfUnstringify(const std::string &instring, bool* status);
640 
641 /// Returns a string with glob characters converted to their regular
642 /// expression equivalents.
643 ///
644 /// Currently, this transforms strings by replacing all instances of '.' with
645 /// '\.', '*' with '.*', and '?' with '.', in that order.
646 TF_API
647 std::string TfStringGlobToRegex(const std::string& s);
648 
649 /// Process escape sequences in ANSI C string constants.
650 ///
651 /// The following escape sequences are accepted:
652 ///
653 /// \li `\\`: backslash
654 /// \li `\a`: ring the bell
655 /// \li `\b`: backspace
656 /// \li `\f`: form feed
657 /// \li `\n`: new line
658 /// \li `\r`: carriage return
659 /// \li `\t`: tab
660 /// \li `\v`: vertical tab
661 /// \li `\xdd`: hex constant
662 /// \li `\ddd`: octal constant
663 ///
664 /// So, if the two-character sequence `\n` appears in the string, it is
665 /// replaced by an actual newline. Each hex and octal constant translates into
666 /// one character in the output string. Hex constants can be up to 2 digits,
667 /// octal constants can be up to 3 digits. Both are terminated by a character
668 /// that is not a valid constant. Note that it is good practice to encode hex
669 /// and octal constants with maximum width (2 and 3 digits, respectively) using
670 /// leading zeroes if necessary. This avoids problems where characters after
671 /// the hex/octal constant that shouldn't be part of the constant get
672 /// interpreted as part of it. For example, the sequence `\x2defaced` will
673 /// produce the characters "-efaced" when what was probably intended was the
674 /// character 0x02 (STX) followed by "defaced".
675 //
676 /// Illegal escape sequences are replaced by the character following the
677 /// backslash, so the two character sequence `\c` would become "c". Processing
678 /// continues until the input hits a NUL character in the input string -
679 /// anything appearing after the NUL will be ignored.
680 TF_API std::string TfEscapeString(const std::string &in);
681 TF_API void TfEscapeStringReplaceChar(const char** in, char** out);
682 
683 /// Concatenate two strings containing '/' and '..' tokens like a file path or
684 /// scope name. The result is a normalized path string.
685 ///
686 /// Tokenize the input strings using a '/' delimiter. Look for '..' and '.'
687 /// tokens in the input strings and construct the appropriate result.
688 ///
689 /// A trailing '/' character will be stripped from the result if the input
690 /// contained one. If the prefix string is empty, a leading '/' will be
691 /// prepended to the result.
692 ///
693 /// Examples:
694 ///
695 /// \li TfStringCatPaths( "foo/bar", "jive" ) => "foo/bar/jive"
696 /// \li TfStringCatPaths( "foo/bar/.", "../jive" ) => "foo/jive"
697 /// \li TfStringCatPaths( "foo", "bar/" ) => "foo/bar"
698 /// \li TfStringCatPaths( "", "bar" ) => "/bar"
699 TF_API
700 std::string TfStringCatPaths( const std::string &prefix,
701  const std::string &suffix );
702 
703 /// Test whether \a identifier is valid.
704 ///
705 /// An identifier is valid if it follows the C/Python identifier convention;
706 /// that is, it must be at least one character long, must start with a letter
707 /// or underscore, and must contain only letters, underscores, and numerals.
708 inline bool
709 TfIsValidIdentifier(std::string const &identifier)
710 {
711  char const *p = identifier.c_str();
712  auto letter = [](unsigned c) { return ((c-'A') < 26) || ((c-'a') < 26); };
713  auto number = [](unsigned c) { return (c-'0') < 10; };
714  auto under = [](unsigned c) { return c == '_'; };
715  unsigned x = *p;
716  if (!x || number(x)) {
717  return false;
718  }
719  while (letter(x) || number(x) || under(x)) {
720  x = *p++;
721  };
722  return x == 0;
723 }
724 
725 /// Produce a valid identifier (see TfIsValidIdentifier) from \p in by
726 /// replacing invalid characters with '_'. If \p in is empty, return "_".
727 TF_API
728 std::string
729 TfMakeValidIdentifier(const std::string &in);
730 
731 /// Escapes characters in \a in so that they are valid XML.
732 ///
733 /// Returns the name with special characters (&, <, >, ", ') replaced with the
734 /// corresponding escape sequences.
735 TF_API
736 std::string TfGetXmlEscapedString(const std::string &in);
737 
738 ///@}
739 
741 
742 #endif // PXR_BASE_TF_STRING_UTILS_H
#define ARCH_LIKELY(x)
Definition: hints.h:29
TF_API std::string TfGetXmlEscapedString(const std::string &in)
GLuint GLuint stream
Definition: glcorearb.h:1832
TF_API std::string TfStringPrintf(const char *fmt,...)
#define TF_API
Definition: api.h:23
TF_API unsigned long TfStringToULong(const std::string &txt, bool *outOfRange=NULL)
std::string TfSafeString(const char *ptr)
Definition: stringUtils.h:87
bool TfStringEndsWith(const std::string &s, const char *suffix)
Returns true if s ends with suffix.
Definition: stringUtils.h:224
TF_API long TfStringToLong(const std::string &txt, bool *outOfRange=NULL)
const GLdouble * v
Definition: glcorearb.h:837
#define PXR_NAMESPACE_OPEN_SCOPE
Definition: pxr.h:73
TF_API std::string TfStringGetSuffix(const std::string &name, char delimiter= '.')
TF_API std::vector< std::string > TfStringSplit(std::string const &src, std::string const &separator)
GLsizei const GLfloat * value
Definition: glcorearb.h:824
TF_API std::string TfStringTrimRight(const std::string &s, const char *trimChars=" \n\t\r")
TF_API std::ostream & operator<<(std::ostream &o, TfStreamFloat t)
GLboolean GLboolean GLboolean GLboolean a
Definition: glcorearb.h:1222
GLdouble s
Definition: glad.h:3009
bool TfStringStartsWith(const std::string &s, const char *prefix)
Returns true if s starts with prefix.
Definition: stringUtils.h:204
TF_API std::set< std::string > TfStringTokenizeToSet(const std::string &source, const char *delimiters=" \t\n")
TF_API double TfStringToDouble(const std::string &txt)
TF_API std::string TfStringGlobToRegex(const std::string &s)
TF_API std::string TfMakeValidIdentifier(const std::string &in)
TF_API std::string TfStringToLower(const std::string &source)
Makes all characters in source lowercase, and returns the result.
TF_API std::string TfStringTrim(const std::string &s, const char *trimChars=" \n\t\r")
bool operator()(const std::string &lhs, const std::string &rhs) const
Definition: stringUtils.h:531
TfStreamFloat(float f)
Definition: stringUtils.h:598
GLuint buffer
Definition: glcorearb.h:660
TF_API std::vector< std::string > TfQuotedStringTokenize(const std::string &source, const char *delimiters=" \t\n", std::string *errors=NULL)
constexpr auto in(type t, int set) -> bool
Definition: core.h:611
TF_API std::vector< std::string > TfMatchedStringTokenize(const std::string &source, char openDelimiter, char closeDelimiter, char escapeCharacter= '\0', std::string *errors=NULL)
TF_API bool TfDoubleToString(double d, char *buffer, int len, bool emitTrailingZero)
std::string TfIntToString(int i)
Returns the given integer as a string.
Definition: stringUtils.h:92
GLfloat f
Definition: glcorearb.h:1926
Definition: token.h:70
TF_API std::string TfVStringPrintf(const std::string &fmt, va_list ap)
TF_API uint64_t TfStringToUInt64(const std::string &txt, bool *outOfRange=NULL)
GLuint GLuint end
Definition: glcorearb.h:475
GLsizei GLsizei GLchar * source
Definition: glcorearb.h:803
std::string TfStringify(const T &v)
Definition: stringUtils.h:562
TF_API bool TfStringContains(const std::string &s, const char *substring)
Returns true if s contains substring.
GLuint const GLchar * name
Definition: glcorearb.h:786
GLsizei const GLchar *const * strings
Definition: glcorearb.h:1933
GLboolean GLboolean GLboolean b
Definition: glcorearb.h:1222
GLint GLenum GLint x
Definition: glcorearb.h:409
std::string TfStringJoin(ForwardIterator begin, ForwardIterator end, const char *separator=" ")
Definition: stringUtils.h:364
TF_API std::string TfStringCapitalize(const std::string &source)
GLdouble t
Definition: glad.h:2397
TF_API std::string TfStringToUpper(const std::string &source)
Makes all characters in source uppercase, and returns the result.
TF_API std::string TfStringGetCommonPrefix(std::string a, std::string b)
PcpNodeRef_ChildrenIterator begin(const PcpNodeRef::child_const_range &r)
Support for range-based for loops for PcpNodeRef children ranges.
Definition: node.h:587
TfStreamDouble(double d)
Definition: stringUtils.h:609
TF_API std::string TfStringToLowerAscii(const std::string &source)
auto ptr(T p) -> const void *
Definition: format.h:4331
#define PXR_NAMESPACE_CLOSE_SCOPE
Definition: pxr.h:74
T TfUnstringify(const std::string &instring, bool *status=NULL)
Definition: stringUtils.h:622
TF_API std::string TfGetBaseName(const std::string &fileName)
static TF_API std::string GetName(TfEnum val)
bool Tf_StringStartsWithImpl(char const *s, size_t slen, char const *prefix, size_t prelen)
Definition: stringUtils.h:196
TF_API std::string TfStringGetBeforeSuffix(const std::string &name, char delimiter= '.')
GLboolean r
Definition: glcorearb.h:1222
bool TfIsValidIdentifier(std::string const &identifier)
Definition: stringUtils.h:709
TF_API void TfEscapeStringReplaceChar(const char **in, char **out)
SIM_API const UT_StringHolder distance
TF_API std::vector< std::string > TfStringTokenize(const std::string &source, const char *delimiters=" \t\n")
TF_API int64_t TfStringToInt64(const std::string &txt, bool *outOfRange=NULL)
TF_API std::string TfStringReplace(const std::string &source, const std::string &from, const std::string &to)
TF_API std::string TfStringTrimLeft(const std::string &s, const char *trimChars=" \n\t\r")
TF_API std::string TfStringCatPaths(const std::string &prefix, const std::string &suffix)
TF_API std::string TfEscapeString(const std::string &in)
GLenum src
Definition: glcorearb.h:1793
bool Tf_StringEndsWithImpl(char const *s, size_t slen, char const *suffix, size_t suflen)
Definition: stringUtils.h:217
TF_API std::string TfGetPathName(const std::string &fileName)