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