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