VersionTuple.cpp 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. //===- VersionTuple.cpp - Version Number Handling ---------------*- C++ -*-===//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is distributed under the University of Illinois Open Source
  6. // License. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. //
  10. // This file implements the VersionTuple class, which represents a version in
  11. // the form major[.minor[.subminor]].
  12. //
  13. //===----------------------------------------------------------------------===//
  14. #include "clang/Basic/VersionTuple.h"
  15. #include "llvm/Support/raw_ostream.h"
  16. // //
  17. ///////////////////////////////////////////////////////////////////////////////
  18. using namespace clang;
  19. std::string VersionTuple::getAsString() const {
  20. std::string Result;
  21. {
  22. llvm::raw_string_ostream Out(Result);
  23. Out << *this;
  24. }
  25. return Result;
  26. }
  27. raw_ostream& clang::operator<<(raw_ostream &Out,
  28. const VersionTuple &V) {
  29. Out << V.getMajor();
  30. if (Optional<unsigned> Minor = V.getMinor())
  31. Out << (V.usesUnderscores() ? '_' : '.') << *Minor;
  32. if (Optional<unsigned> Subminor = V.getSubminor())
  33. Out << (V.usesUnderscores() ? '_' : '.') << *Subminor;
  34. if (Optional<unsigned> Build = V.getBuild())
  35. Out << (V.usesUnderscores() ? '_' : '.') << *Build;
  36. return Out;
  37. }
  38. static bool parseInt(StringRef &input, unsigned &value) {
  39. assert(value == 0);
  40. if (input.empty()) return true;
  41. char next = input[0];
  42. input = input.substr(1);
  43. if (next < '0' || next > '9') return true;
  44. value = (unsigned) (next - '0');
  45. while (!input.empty()) {
  46. next = input[0];
  47. if (next < '0' || next > '9') return false;
  48. input = input.substr(1);
  49. value = value * 10 + (unsigned) (next - '0');
  50. }
  51. return false;
  52. }
  53. bool VersionTuple::tryParse(StringRef input) {
  54. unsigned major = 0, minor = 0, micro = 0, build = 0;
  55. // Parse the major version, [0-9]+
  56. if (parseInt(input, major)) return true;
  57. if (input.empty()) {
  58. *this = VersionTuple(major);
  59. return false;
  60. }
  61. // If we're not done, parse the minor version, \.[0-9]+
  62. if (input[0] != '.') return true;
  63. input = input.substr(1);
  64. if (parseInt(input, minor)) return true;
  65. if (input.empty()) {
  66. *this = VersionTuple(major, minor);
  67. return false;
  68. }
  69. // If we're not done, parse the micro version, \.[0-9]+
  70. if (input[0] != '.') return true;
  71. input = input.substr(1);
  72. if (parseInt(input, micro)) return true;
  73. if (input.empty()) {
  74. *this = VersionTuple(major, minor, micro);
  75. return false;
  76. }
  77. // If we're not done, parse the micro version, \.[0-9]+
  78. if (input[0] != '.') return true;
  79. input = input.substr(1);
  80. if (parseInt(input, build)) return true;
  81. // If we have characters left over, it's an error.
  82. if (!input.empty()) return true;
  83. *this = VersionTuple(major, minor, micro, build);
  84. return false;
  85. }