PackedVersion.cpp 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. //===- PackedVersion.cpp --------------------------------------------------===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. //
  9. // Implements the Mach-O packed version.
  10. //
  11. //===----------------------------------------------------------------------===//
  12. #include "llvm/TextAPI/PackedVersion.h"
  13. #include "llvm/ADT/SmallVector.h"
  14. #include "llvm/ADT/StringExtras.h"
  15. #include "llvm/Support/Format.h"
  16. #include "llvm/Support/raw_ostream.h"
  17. namespace llvm {
  18. namespace MachO {
  19. bool PackedVersion::parse32(StringRef Str) {
  20. Version = 0;
  21. if (Str.empty())
  22. return false;
  23. SmallVector<StringRef, 3> Parts;
  24. SplitString(Str, Parts, ".");
  25. if (Parts.size() > 3)
  26. return false;
  27. unsigned long long Num;
  28. if (getAsUnsignedInteger(Parts[0], 10, Num))
  29. return false;
  30. if (Num > UINT16_MAX)
  31. return false;
  32. Version = Num << 16;
  33. for (unsigned i = 1, ShiftNum = 8; i < Parts.size(); ++i, ShiftNum -= 8) {
  34. if (getAsUnsignedInteger(Parts[i], 10, Num))
  35. return false;
  36. if (Num > UINT8_MAX)
  37. return false;
  38. Version |= (Num << ShiftNum);
  39. }
  40. return true;
  41. }
  42. std::pair<bool, bool> PackedVersion::parse64(StringRef Str) {
  43. bool Truncated = false;
  44. Version = 0;
  45. if (Str.empty())
  46. return std::make_pair(false, Truncated);
  47. SmallVector<StringRef, 5> Parts;
  48. SplitString(Str, Parts, ".");
  49. if (Parts.size() > 5)
  50. return std::make_pair(false, Truncated);
  51. unsigned long long Num;
  52. if (getAsUnsignedInteger(Parts[0], 10, Num))
  53. return std::make_pair(false, Truncated);
  54. if (Num > 0xFFFFFFULL)
  55. return std::make_pair(false, Truncated);
  56. if (Num > 0xFFFFULL) {
  57. Num = 0xFFFFULL;
  58. Truncated = true;
  59. }
  60. Version = Num << 16;
  61. for (unsigned i = 1, ShiftNum = 8; i < Parts.size() && i < 3;
  62. ++i, ShiftNum -= 8) {
  63. if (getAsUnsignedInteger(Parts[i], 10, Num))
  64. return std::make_pair(false, Truncated);
  65. if (Num > 0x3FFULL)
  66. return std::make_pair(false, Truncated);
  67. if (Num > 0xFFULL) {
  68. Num = 0xFFULL;
  69. Truncated = true;
  70. }
  71. Version |= (Num << ShiftNum);
  72. }
  73. if (Parts.size() > 3)
  74. Truncated = true;
  75. return std::make_pair(true, Truncated);
  76. }
  77. void PackedVersion::print(raw_ostream &OS) const {
  78. OS << format("%d", getMajor());
  79. if (getMinor() || getSubminor())
  80. OS << format(".%d", getMinor());
  81. if (getSubminor())
  82. OS << format(".%d", getSubminor());
  83. }
  84. } // end namespace MachO.
  85. } // end namespace llvm.