HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
UT_PackageUtils.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  * NAME: UT_PackageUtils.h
7  *
8  * COMMENTS: Package utility classes and helpers.
9  */
10 
11 #ifndef UT_PackageUtils_H
12 #define UT_PackageUtils_H
13 
14 #include "UT_API.h"
15 #include "UT_Array.h"
16 #include "UT_SharedPtr.h"
17 #include "UT_StringMap.h"
18 #include "UT_StringSet.h"
19 #include "UT_StringStream.h"
20 #include "UT_VarScan.h"
21 #include <SYS/SYS_Platform.h>
22 #include <SYS/SYS_VersionUtil.h>
23 #include <hboost/any.hpp>
24 #include <tools/henv.h>
25 #include <tools/hpath.h>
26 
27 #include <cctype>
28 #include <iostream>
29 
30 namespace UT_Package
31 {
32 namespace utils
33 {
34 const UT_StringHolder klog_error = "ERROR";
35 const UT_StringHolder klog_info = "INFO";
36 const UT_StringHolder klog_warning = "WARNING";
38 
39 static const char *path_sep()
40 {
41  return PATH_SEP_STRING;
42 }
43 
44 static char path_sep_char()
45 {
46  return PATH_SEP_CHAR;
47 }
48 
49 static const char *vardef_sep()
50 {
51  return "-";
52 }
53 
54 static UT_StringHolder makeVarRef(const char * var)
55 {
56  // note: this helper is typically used with utils::expandVar
57  UT_WorkBuffer wb;
58  wb.format("${}", var);
59  return wb;
60 }
61 
62 /*
63 Build an array of unset variables found in a given value expression.
64 Update a dependency map to hold dependency information between variables.
65 May returns a list of variables marked as circular dependent.
66 */
67 static bool buildVarDependency(
68  UT_StringHolder const& var_name,
69  const char * var_value,
70  UT_StringArray& unset_vars,
71  UT_StringMap<UT_StringSet>& vars_dep_map,
72  UT_StringMap<UT_StringSet>& vars_circ_dep)
73 {
74  struct Lookup
75  {
76  struct Data
77  {
78  Data(UT_StringHolder const& var_name,
79  UT_StringArray& unset_vars,
80  UT_StringMap<UT_StringSet>& vars_dep_map,
81  UT_StringMap<UT_StringSet>& vars_circ_dep)
82  : myVarName(var_name)
83  , myUnsetVars(unset_vars)
84  , myVarsDepMap(vars_dep_map)
85  , myVarsCircDepMap(vars_circ_dep)
86  {
87  }
88 
89  /*
90  Check if var is set in the environment, if not, we add
91  it to a list of unset vars. Also catch any circular
92  reference between var and myVarName.
93  */
94  const char* process(UT_StringHolder const& var)
95  {
96  if (var == myVarName)
97  {
98  // nothing to do
99  return nullptr;
100  }
101 
102  // Make myVarName dependent of var
103  auto && it = myVarsDepMap.find(myVarName);
104  if (it != myVarsDepMap.end())
105  {
106  it->second.insert(var);
107  }
108  else
109  {
110  UT_StringSet var_dep_set;
111  var_dep_set.insert(var);
112 
113  myVarsDepMap[myVarName] = var_dep_set;
114  }
115 
116  // Check circular reference between the var to process
117  // and myVarName
118  myCircularDependency = false;
119  if (checkCircularDep(myVarName, var))
120  {
121  auto && it = myVarsCircDepMap.find(myVarName);
122  if (it != myVarsCircDepMap.end())
123  {
124  it->second.insert(var);
125  }
126  else
127  {
128  UT_StringSet var_circ_dep_set;
129  var_circ_dep_set.insert(var);
130 
131  myVarsCircDepMap[myVarName] = var_circ_dep_set;
132  }
133 
134  myCircularDependency = true;
135  return nullptr;
136  }
137 
138  const char* value = HoudiniGetenv(var.c_str());
139  if (!value)
140  {
141  myUnsetVars.append(var, true /*check for duplicates*/);
142  }
143 
144  // all fine
145  return value;
146  }
147 
148  /*
149  Returns true is there is a circular dependency between
150  a dependent and a dependee variable.
151  */
152  bool checkCircularDep(UT_StringHolder const& dependent_var, UT_StringHolder const& dependee_var)
153  {
154  auto && dependent = myVarsDepMap.find(dependent_var);
155  if (dependent == myVarsDepMap.end())
156  {
157  return false;
158  }
159 
160  auto && dependee = myVarsDepMap.find(dependee_var);
161  if (dependee == myVarsDepMap.end())
162  {
163  return false;
164  }
165 
166  // Check explicit circular reference
167  if (dependent->second.contains(dependee_var) && dependee->second.contains(dependent_var))
168  {
169  return true;
170  }
171 
172  // Check implicit circular reference
173  return checkImplicitCircularDep(dependent_var, dependent->second);
174  }
175 
176  /*
177  Find an implicit circular dependency between a dependent
178  and a dependee variable. The function looks for a matching
179  dependent in its dependee set. If nothing is found, it
180  continues recursively by querying the dependent map with
181  each dependee of the dependent variable.
182  */
183  bool checkImplicitCircularDep(UT_StringHolder const& dependent_var, UT_StringSet const& dependee_set)
184  {
185  if (dependee_set.contains(dependent_var))
186  {
187  return true;
188  }
189 
190  for (auto && dependee_var : dependee_set)
191  {
192  auto && dependee = myVarsDepMap.find(dependee_var);
193 
194  if (dependee == myVarsDepMap.end())
195  {
196  continue;
197  }
198 
199  if (checkImplicitCircularDep(dependent_var, dependee->second))
200  {
201  return true;
202  }
203  }
204 
205  return false;
206  }
207 
208  bool myCircularDependency = false;
209  UT_StringArray& myUnsetVars;
210  const UT_StringHolder& myVarName;
211  UT_StringMap<UT_StringSet>& myVarsDepMap;
212  UT_StringMap<UT_StringSet>& myVarsCircDepMap;
213  };
214 
215  static const char *
216  callback(const char *arg, void *user_data)
217  {
218  Data& data = *(Data*)user_data;
219 
220  return data.process(arg);
221  }
222  };
223 
224  Lookup::Data data(var_name, unset_vars, vars_dep_map, vars_circ_dep);
225 
227  UTVariableScan(result, var_value, Lookup::callback, &data);
228  return !data.myCircularDependency;
229 }
230 
231 static UT_StringHolder expandVar(const char *arg, bool want_marker)
232 {
233  // Return expanded env var (arg) if set, otherwise return the path
234  // marker (&) if arg is unset.
235 
236  struct Lookup
237  {
238  struct Data
239  {
240  Data() : myWantMarkerFlag(false)
241  {
242  }
243 
244  UT_WorkBuffer myWB;
245  bool myWantMarkerFlag;
246  };
247 
248  // Lookup callback to return the value of an env var (arg) or a
249  // marker if arg is unset.
250  static const char *
251  callback(const char *arg, void *data)
252  {
253  const char *value = Lookup::getValue(arg, data);
254 
255  Lookup::Data* p = (Lookup::Data*)data;
256  if (p->myWantMarkerFlag)
257  {
258  return value ? value : "&";
259  }
260  return value;
261  }
262 
263  // Returns the value of an env var (arg). If arg is formatted with
264  // a default value like VAR-DEFAULT, DEFAULT is expanded if VAR is
265  // unset, otherwise it returns the value of VAR.
266  static const char *
267  getValue(const char *arg, void* data)
268  {
269  Lookup::Data* p = (Lookup::Data*)data;
270  UT_StringArray tokens;
271  UT_String(arg).tokenize(tokens, vardef_sep());
272  if (tokens.size() > 1)
273  {
274  // use left token as var name
275  const char* expanded_var = HoudiniGetenv(tokens[0].c_str());
276  if (expanded_var)
277  {
278  return expanded_var;
279  }
280 
281  // Left token is undefined. Assembles, expands and returns
282  // the right token value.
283  UT_String right_token;
284  right_token = tokens[1];
285  for (exint i=2; i<tokens.size(); i++)
286  {
287  right_token += vardef_sep();
288  right_token += tokens[i];
289  }
290 
291  p->myWB = utils::expandVar(right_token.c_str(), p->myWantMarkerFlag);
292  return p->myWB.buffer();
293  }
294  return HoudiniGetenv(arg);
295  }
296  };
297 
298  Lookup::Data data;
299  data.myWantMarkerFlag = want_marker;
300 
302  UTVariableScan(result, arg, Lookup::callback, &data);
303 
304  return result.buffer();
305 }
306 
307 static UT_StringHolder makeVarRefPlatform(const char * var)
308 {
309  UT_WorkBuffer wb;
310 #if defined(WIN32)
311  wb.format("%%{}%%", var);
312 #else
313  wb.format("${}", var);
314 #endif
315  return wb;
316 }
317 
318 static bool isCmdShell()
319 {
320 #if defined(WIN32)
321  char const * shell = ::HoudiniGetenv("SHELL");
322  if (shell && strstr(shell, "cmd.exe"))
323  {
324  return true;
325  }
326 #endif
327  return false;
328 }
329 
330 static const char *pathSepShell()
331 {
332 #if defined(WIN32)
333  if (isCmdShell())
334  {
335  return ";";
336  }
337 #endif
338  return ":";
339 }
340 
341 // Convert all '\' separators to '/' on all platforms.
342 static void normalizePath( UT_String& path_var)
343 {
344  if (!path_var.length())
345  {
346  return;
347  }
348 
349  path_var.substitute( '\\', '/' );
350 }
351 
352 struct Factory
353 {
354  template <typename T, typename... Args>
355  static UT_SharedPtr<T> make(Args &&... args)
356  {
357  return UTmakeShared<T>(std::forward<Args>(args)...);
358  }
359 };
360 
361 // Helper for handling Houdini version values
362 class HVersion
363 {
364  public:
366  : myMajor(-1)
367  , myMinor(-1)
368  , myBuild(-1)
369  , myPatch(-1)
370  {
371  }
372 
373  int compare( HVersion const & other, bool full=true ) const
374  {
375  if (full)
376  {
377  return SYSversionCompare(
379  other.myMajor, other.myMinor, other.myBuild, other.myPatch);
380  }
381 
382  if (myMajor != other.myMajor)
383  {
384  return myMajor - other.myMajor;
385  }
386 
387  // compare the rest if the other components are provided (!= -1)
388 
389  if (other.myMinor != -1 && myMinor != other.myMinor)
390  {
391  return myMinor - other.myMinor;
392  }
393 
394  if (other.myBuild != -1 && myBuild != other.myBuild)
395  {
396  return myBuild - other.myBuild;
397  }
398  if (other.myPatch != -1 && myPatch != other.myPatch)
399  {
400  return myPatch - other.myPatch;
401  }
402  return 0;
403  }
404 
405  bool operator > (HVersion const & other) const
406  {
407  return compare(other) > 0;
408  }
409 
410  bool operator >= (HVersion const & other) const
411  {
412  return operator>(other) || operator==(other);
413  }
414 
415  bool operator < (HVersion const & other) const
416  {
417  return compare(other) < 0;
418  }
419 
420  bool operator <= (HVersion const & other) const
421  {
422  return operator<(other) || operator==(other);
423  }
424 
425  bool operator == (HVersion const & other) const
426  {
427  return compare(other,false /*full*/) == 0;
428  }
429 
430  static HVersion convert(UT_StringRef const & str)
431  {
432  UT_StringArray tokens;
433  UT_String(str.c_str()).tokenize( tokens, "." );
434 
435  HVersion hver;
436 
437  if (tokens.size() > 4)
438  {
439  // wrong format
440  return hver;
441  }
442  else if (tokens.size()==1)
443  {
444  hver.myMajor = SYSatoi(tokens[0].c_str());
445  }
446  else if (tokens.size()==2)
447  {
448  hver.myMajor = SYSatoi(tokens[0].c_str());
449  hver.myMinor = SYSatoi(tokens[1].c_str());
450  }
451  else if (tokens.size()==3)
452  {
453  hver.myMajor = SYSatoi(tokens[0].c_str());
454  hver.myMinor = SYSatoi(tokens[1].c_str());
455  hver.myBuild = SYSatoi(tokens[2].c_str());
456  }
457  else
458  {
459  hver.myMajor = SYSatoi(tokens[0].c_str());
460  hver.myMinor = SYSatoi(tokens[1].c_str());
461  hver.myBuild = SYSatoi(tokens[2].c_str());
462  hver.myPatch = SYSatoi(tokens[3].c_str());
463  }
464  return hver;
465  }
466 
467  int myMajor;
468  int myMinor;
469  int myBuild;
470  int myPatch;
471 };
472 
473 // Encapsulates variant values used by UT_Package
474 class Value
475 {
476  public:
478 
479  Value() = default;
480  ~Value() = default;
481 
482  explicit Value(const char *value)
483  {
484  if (value)
485  {
486  myValue = std::string(value, strlen(value));
487  }
488  }
489 
490  explicit Value(UT_StringRef const & value)
491  {
492  if (value.isstring())
493  {
494  myValue = std::string(value.c_str(), value.length());
495  }
496  }
497 
498  explicit Value(fpreal64 value)
499  {
500  myValue = value;
501  }
502 
503  explicit Value(int64 value)
504  {
505  myValue = value;
506  }
507 
508  explicit Value(bool value)
509  {
510  myValue = value;
511  }
512 
513  explicit Value(HVersion value)
514  {
515  myValue = value;
516  }
517 
518  hboost::any const & value() const
519  {
520  return myValue;
521  }
522 
523  void set(const char *value)
524  {
525  if (value)
526  {
527  myValue = std::string(value, strlen(value));
528  }
529  }
530 
531  void set(fpreal64 value)
532  {
533  myValue = value;
534  }
535 
536  void set(int64 value)
537  {
538  myValue = value;
539  }
540 
541  void set(bool value)
542  {
543  myValue = value;
544  }
545 
546  void set(HVersion value)
547  {
548  myValue = value;
549  }
550 
552  {
553  return toWorkBuffer().buffer();
554  }
555 
557  {
558  UT_WorkBuffer wb;
559  if (typeid(fpreal64) == myValue.type())
560  {
561  wb.format("{}", hboost::any_cast<fpreal64>(myValue));
562  }
563  else if (typeid(int64) == myValue.type())
564  {
565  wb.format("{}", hboost::any_cast<int64>(myValue));
566  }
567  else if (typeid(bool) == myValue.type())
568  {
569  wb.format("{}", hboost::any_cast<bool>(myValue) ? "1" : "0");
570  }
571  else if (typeid(std::string) == myValue.type())
572  {
573  wb.format("{}",hboost::any_cast<std::string>(myValue));
574  }
575  else if (typeid(HVersion) == myValue.type())
576  {
577  auto && hver = hboost::any_cast<HVersion>(myValue);
578  wb.format("{}.{}.{}.{}",hver.myMajor,hver.myMinor,hver.myBuild,hver.myPatch);
579  }
580 
581  return wb;
582  }
583 
584  template <typename T>
585  T const & get() const
586  {
587  return hboost::any_cast<T const &>(myValue);
588  }
589 
590  template <typename T>
591  bool isA() const
592  {
593  return typeid(T) == myValue.type();
594  }
595 
596  bool valid() const
597  {
598  return !myValue.empty();
599  }
600 
601  bool isEqual(utils::Value const & other, bool ignore_case=false) const
602  {
603  if (isA<std::string>() && other.isA<std::string>())
604  {
605  if (ignore_case)
606  {
607  auto && lhs = hboost::any_cast<std::string>(myValue);
608  auto && rhs = hboost::any_cast<std::string>(other.value());
609  return compareIgnoreCase(lhs, rhs);
610  }
611  else
612  {
613  return get<std::string>() == other.get<std::string>();
614  }
615  }
616 
617  if (isA<int64>() && other.isA<int64>())
618  {
619  return get<int64>() == other.get<int64>();
620  }
621 
622  if (isA<fpreal64>() && other.isA<fpreal64>())
623  {
624  return get<fpreal64>() == other.get<fpreal64>();
625  }
626 
627  if (isA<bool>() && other.isA<bool>())
628  {
629  return get<bool>() == other.get<bool>();
630  }
631 
632  if (isA<HVersion>() && other.isA<HVersion>())
633  {
634  return get<HVersion>() == other.get<HVersion>();
635  }
636 
637  if (isA<HVersion>() && other.isA<std::string>())
638  {
639  HVersion hver = HVersion::convert(other.get<std::string>().c_str());
640  return get<HVersion>() == hver;
641  }
642 
643  if (isA<std::string>() && other.isA<HVersion>())
644  {
645  HVersion hver = HVersion::convert(get<std::string>().c_str());
646  return hver == other.get<HVersion>();
647  }
648 
649  throw std::runtime_error("utils::Value::isEqual: unsupported type");
650  }
651 
652  bool isGreater(utils::Value const & other) const
653  {
654  if ( isA<std::string>() && other.isA<std::string>() )
655  {
656  return get<std::string>() > other.get<std::string>();
657  }
658 
659  if (isA<HVersion>() && other.isA<HVersion>())
660  {
661  return get<HVersion>() > other.get<HVersion>();
662  }
663 
664  if (isA<HVersion>() && other.isA<std::string>())
665  {
666  HVersion hver = HVersion::convert(other.get<std::string>().c_str());
667  return get<HVersion>() > hver;
668  }
669 
670  if (isA<std::string>() && other.isA<HVersion>())
671  {
672  HVersion hver = HVersion::convert(get<std::string>().c_str());
673  return hver > other.get<HVersion>();
674  }
675 
676  if ( isA<std::string>() || other.isA<std::string>() )
677  {
678  throw std::runtime_error("utils::Value::isGreater: unsupported types");
679  }
680 
681  return get<fpreal64>() > other.get<fpreal64>();
682  }
683 
684  bool isGreaterEqual(utils::Value const & other) const
685  {
686  return isGreater(other) || isEqual(other);
687  }
688 
689  bool isLess(utils::Value const & other) const
690  {
691  if ( isA<std::string>() && other.isA<std::string>() )
692  {
693  return get<std::string>() < other.get<std::string>();
694  }
695 
696  if (isA<HVersion>() && other.isA<HVersion>())
697  {
698  return get<HVersion>() < other.get<HVersion>();
699  }
700 
701  if (isA<HVersion>() && other.isA<std::string>())
702  {
703  HVersion hver = HVersion::convert(other.get<std::string>().c_str());
704  return get<HVersion>() < hver;
705  }
706 
707  if (isA<std::string>() && other.isA<HVersion>())
708  {
709  HVersion hver = HVersion::convert(get<std::string>().c_str());
710  return hver < other.get<HVersion>();
711  }
712 
713  if ( isA<std::string>() || other.isA<std::string>() )
714  {
715  throw std::runtime_error("utils::Value::isLess: unsupported types");
716  }
717 
718  return get<fpreal64>() < other.get<fpreal64>();
719  }
720 
721  bool isLessEqual(utils::Value const & other) const
722  {
723  return isLess(other) || isEqual(other);
724  }
725 
726  // Substiture all occurances of find with replace_with
727  bool substitute(char const* find, char const* replace_with)
728  {
729  if (valid() && isA<std::string>())
730  {
731  auto && to_replace = get<std::string>();
732  UT_WorkBuffer wb(to_replace.c_str());
733  if (wb.substitute(find, replace_with))
734  {
735  set(wb.buffer());
736  return true;
737  }
738  }
739  return false;
740  }
741 
742 private:
743  bool compareIgnoreCase(std::string & s1, std::string & s2) const
744  {
745  return ((s1.size() == s2.size()) &&
746  std::equal(s1.begin(), s1.end(), s2.begin(),
747  [](char & c1, char & c2)
748  {
749  return (c1 == c2 || std::toupper(c1) == std::toupper(c2));
750  }
751  ));
752  }
753  hboost::any myValue;
754 }; // Value
755 
756 // Loggger to hold warning/errors/info messages
757 class Logger
758 {
759  public:
762 
763  enum class Flags : unsigned
764  {
765  all,
766  info,
767  warning,
768  error
769  };
770 
772  : myHasErrorFlag(false)
773  , myLog(&myDefaultLog)
774  {
775  }
776 
777  ~Logger() = default;
778 
779  void error(char const* msg)
780  {
781  addToBuffer(klog_error, msg);
782  myHasErrorFlag = true;
783  }
784 
785  template< typename ...Args >
786  void error(char const* msg, Args&&... args)
787  {
788  addToBuffer(klog_error, formatMsg(msg, std::forward<Args>(args)...));
789  myHasErrorFlag = true;
790  }
791 
792  void info(char const* msg)
793  {
794  addToBuffer(klog_info, msg);
795  }
796 
797  template< typename ...Args >
798  void info(char const* msg, Args&&... args)
799  {
800  addToBuffer(klog_info, formatMsg(msg, std::forward<Args>(args)...));
801  }
802 
803  void message(char const* msg)
804  {
805  addToBuffer(nullptr, msg);
806  }
807 
808  template< typename ...Args >
809  void message(char const* msg, Args&&... args)
810  {
811  addToBuffer(nullptr, formatMsg(msg, std::forward<Args>(args)...));
812  }
813 
814  void warning(char const* msg)
815  {
816  addToBuffer(klog_warning, msg);
817  }
818 
819  template< typename ...Args >
820  void warning(char const* msg, Args&&... args)
821  {
822  addToBuffer(klog_warning, formatMsg(msg, std::forward<Args>(args)...));
823  }
824 
825  void clear()
826  {
827  myDefaultLog.clear();
828  myEntryMap.clear();
829  myEntryArray.clear();
830  }
831 
832  void toStream(std::ostream &os) const
833  {
834  for (auto && entry : myEntryArray)
835  {
836  os << entry.c_str() << std::endl;
837  auto && it = myEntryMap.find(entry);
838  os << it->second.c_str() << std::endl;
839  }
840 
841  if (myDefaultLog)
842  {
843  os << myDefaultLog.c_str() << std::endl;
844  }
845  }
846 
848  {
849  UT_OStringStream ss;
850  toStream(ss);
851  UT_StringHolder log = "= = = Houdini Package log = = =\n";
852  log += ss.str().buffer();
853  return log;
854  }
855 
856  void log(char const* title, Flags flags=Flags::all) const
857  {
858  if (flags == Flags::all)
859  {
860  std::cout << title << std::endl;
861  toStream(std::cout);
862  }
863  else if (myHasErrorFlag && flags == Flags::error)
864  {
865  std::cerr << title << std::endl;
866  toStream(std::cerr);
867  }
868  }
869 
870  void start(char const * entry)
871  {
872  if (!entry)
873  {
874  // global logging
875  myLog = &myDefaultLog;
876  return;
877  }
878 
879  // logging done per entry
880  if (!myEntryMap.count(entry))
881  {
882  myEntryMap[entry] = UT_StringHolder();
883  myEntryArray.append(entry);
884  }
885  myLog = &myEntryMap[entry];
886  }
887 
888  bool hasErrors() const
889  {
890  return myHasErrorFlag;
891  }
892 
893  void append(Logger const & logger)
894  {
895  UT_OStringStream ss;
896  logger.toStream(ss);
897 
898  UT_WorkBuffer wb;
899  wb += ss.str().buffer();
900 
901  if (wb.buffer())
902  {
903  buffer() += wb.buffer();
904  }
905  }
906 
907  private:
908  template< typename ...Args >
909  UT_StringHolder formatMsg( const char* format, Args &&... args )
910  {
911  UT_WorkBuffer wb;
912  wb.format(format, args...);
913  return wb;
914  }
915 
916  void addToBuffer(const char* prefix, const char* msg)
917  {
918  if (prefix)
919  {
920  buffer() += prefix;
921  buffer() += ": ";
922  }
923  buffer() += msg;
924  buffer() += "\n";
925  }
926 
928  {
929  return *myLog;
930  }
931 
932  UT_StringHolder const & buffer() const
933  {
934  return *myLog;
935  }
936 
937  EntryArray myEntryArray;
938  EntryMap myEntryMap;
939  UT_StringHolder* myLog;
940  UT_StringHolder myDefaultLog;
941  bool myHasErrorFlag;
942 }; // Logger
943 
944 } // utils
945 } // UT_Package
946 
947 #endif // UT_PackageUtils_H
bool isGreaterEqual(utils::Value const &other) const
bool isGreater(utils::Value const &other) const
bool operator>(HVersion const &other) const
const UT_StringHolder klog_warning
void start(char const *entry)
#define PATH_SEP_STRING
Definition: hpath.h:33
void set(HVersion value)
const Args & args
Definition: printf.h:628
bool operator>=(HVersion const &other) const
SYS_FORCE_INLINE void clear()
int compare(HVersion const &other, bool full=true) const
internal::named_arg< T, char > arg(string_view name, const T &arg)
Definition: core.h:1393
bool operator<(HVersion const &other) const
GLenum GLsizei GLsizei GLsizei GLsizei GLbitfield flags
Definition: glew.h:2864
int64 exint
Definition: SYS_Types.h:125
SYS_FORCE_INLINE const char * buffer() const
void info(char const *msg, Args &&...args)
An output stream object that owns its own string buffer storage.
bool contains(const UT_StringRef &ref) const
Definition: UT_StringSet.h:66
void message(char const *msg)
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: glew.h:1254
void message(char const *msg, Args &&...args)
bool substitute(char const *find, char const *replace_with)
#define PATH_SEP_CHAR
Definition: hpath.h:32
bool operator<=(HVersion const &other) const
const UT_WorkBuffer & str()
Returns a read-only reference to the underlying UT_WorkBuffer.
exint size() const
Definition: UT_Array.h:458
UT_StringHolder toString() const
const char * c_str() const
Definition: UT_String.h:505
unsigned length() const
Return length of string.
Definition: UT_String.h:543
void toStream(std::ostream &os) const
double fpreal64
Definition: SYS_Types.h:201
void error(char const *msg, Args &&...args)
UT_StringHolder toString() const
int tokenize(char *argv[], int max_args, char separator)
Definition: UT_String.h:839
bool any(const vbool4 &v)
Definition: simd.h:3372
exint length() const
std::shared_ptr< T > UT_SharedPtr
Wrapper around std::shared_ptr.
Definition: UT_SharedPtr.h:28
GLuint buffer
Definition: glew.h:1680
GLint GLenum GLsizei GLint GLsizei const void * data
Definition: glew.h:1379
UT_WorkBuffer toWorkBuffer() const
bool isLess(utils::Value const &other) const
hboost::any const & value() const
Value(UT_StringRef const &value)
static UT_SharedPtr< T > make(Args &&...args)
void set(const char *value)
long long int64
Definition: SYS_Types.h:116
UT_API int UTVariableScan(UT_WorkBuffer &outstr, const char *instr, UTVarCallback lookup, void *userdata, bool tildeexpand=true, bool commentsexpand=true)
bool isEqual(utils::Value const &other, bool ignore_case=false) const
SYS_FORCE_INLINE const char * c_str() const
void error(char const *msg)
void warning(char const *msg, Args &&...args)
exint append()
Definition: UT_Array.h:95
unsigned int substitute(const char *find, const char *replacement, bool all=true)
bool operator==(HVersion const &other) const
const UT_StringHolder klog_info
void append(Logger const &logger)
GLfloat GLfloat p
Definition: glew.h:16321
UT_StringMap< UT_StringHolder > EntryMap
GLsizei const GLchar *const * string
Definition: glew.h:1844
size_t format(const char *fmt, const Args &...args)
int substitute(const char *find, const char *replacement, bool all=true)
void log(char const *title, Flags flags=Flags::all) const
GLuint GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat s1
Definition: glew.h:12681
FMT_CONSTEXPR bool find(Ptr first, Ptr last, T value, Ptr &out)
Definition: format.h:2104
Value(const char *value)
bool equal(T1 a, T2 b, T3 t)
Definition: ImathFun.h:143
const UT_StringHolder klog_error
GLuint64EXT * result
Definition: glew.h:14007
void info(char const *msg)
void clear()
Resets list to an empty list.
Definition: UT_Array.h:528
static HVersion convert(UT_StringRef const &str)
void warning(char const *msg)
const UT_StringHolder kvardef_sep
T const & get() const
void set(fpreal64 value)
GLsizei const GLfloat * value
Definition: glew.h:1849
bool isLessEqual(utils::Value const &other) const
tools_API const char * HoudiniGetenv(const char *name)
SYS_FORCE_INLINE bool isstring() const