120 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8//9// Implements the Mach-O packed version.10//11//===----------------------------------------------------------------------===//12 13#include "llvm/TextAPI/PackedVersion.h"14#include "llvm/ADT/SmallVector.h"15#include "llvm/ADT/StringExtras.h"16#include "llvm/Support/Format.h"17#include "llvm/Support/raw_ostream.h"18 19namespace llvm {20namespace MachO {21 22bool PackedVersion::parse32(StringRef Str) {23 Version = 0;24 25 if (Str.empty())26 return false;27 28 SmallVector<StringRef, 3> Parts;29 SplitString(Str, Parts, ".");30 31 if (Parts.size() > 3 || Parts.empty())32 return false;33 34 unsigned long long Num;35 if (getAsUnsignedInteger(Parts[0], 10, Num))36 return false;37 38 if (Num > UINT16_MAX)39 return false;40 41 Version = Num << 16;42 43 for (unsigned i = 1, ShiftNum = 8; i < Parts.size(); ++i, ShiftNum -= 8) {44 if (getAsUnsignedInteger(Parts[i], 10, Num))45 return false;46 47 if (Num > UINT8_MAX)48 return false;49 50 Version |= (Num << ShiftNum);51 }52 53 return true;54}55 56std::pair<bool, bool> PackedVersion::parse64(StringRef Str) {57 bool Truncated = false;58 Version = 0;59 60 if (Str.empty())61 return std::make_pair(false, Truncated);62 63 SmallVector<StringRef, 5> Parts;64 SplitString(Str, Parts, ".");65 66 if (Parts.size() > 5 || Parts.empty())67 return std::make_pair(false, Truncated);68 69 unsigned long long Num;70 if (getAsUnsignedInteger(Parts[0], 10, Num))71 return std::make_pair(false, Truncated);72 73 if (Num > 0xFFFFFFULL)74 return std::make_pair(false, Truncated);75 76 if (Num > 0xFFFFULL) {77 Num = 0xFFFFULL;78 Truncated = true;79 }80 Version = Num << 16;81 82 for (unsigned i = 1, ShiftNum = 8; i < Parts.size() && i < 3;83 ++i, ShiftNum -= 8) {84 if (getAsUnsignedInteger(Parts[i], 10, Num))85 return std::make_pair(false, Truncated);86 87 if (Num > 0x3FFULL)88 return std::make_pair(false, Truncated);89 90 if (Num > 0xFFULL) {91 Num = 0xFFULL;92 Truncated = true;93 }94 Version |= (Num << ShiftNum);95 }96 97 if (Parts.size() > 3)98 Truncated = true;99 100 return std::make_pair(true, Truncated);101}102 103PackedVersion::operator std::string() const {104 SmallString<32> Str;105 raw_svector_ostream OS(Str);106 print(OS);107 return std::string(Str);108}109 110void PackedVersion::print(raw_ostream &OS) const {111 OS << format("%d", getMajor());112 if (getMinor() || getSubminor())113 OS << format(".%d", getMinor());114 if (getSubminor())115 OS << format(".%d", getSubminor());116}117 118} // end namespace MachO.119} // end namespace llvm.120