/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/tools/clang/lib/Basic/VersionTuple.cpp
Line | Count | Source (jump to first uncovered line) |
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 | | using namespace clang; |
18 | | |
19 | 25.4k | std::string VersionTuple::getAsString() const { |
20 | 25.4k | std::string Result; |
21 | 25.4k | { |
22 | 25.4k | llvm::raw_string_ostream Out(Result); |
23 | 25.4k | Out << *this; |
24 | 25.4k | } |
25 | 25.4k | return Result; |
26 | 25.4k | } |
27 | | |
28 | | raw_ostream& clang::operator<<(raw_ostream &Out, |
29 | 42.8k | const VersionTuple &V) { |
30 | 42.8k | Out << V.getMajor(); |
31 | 42.8k | if (Optional<unsigned> Minor = V.getMinor()) |
32 | 42.7k | Out << '.' << *Minor; |
33 | 42.8k | if (Optional<unsigned> Subminor = V.getSubminor()) |
34 | 40.6k | Out << '.' << *Subminor; |
35 | 42.8k | if (Optional<unsigned> Build = V.getBuild()) |
36 | 1 | Out << '.' << *Build; |
37 | 42.8k | return Out; |
38 | 42.8k | } |
39 | | |
40 | 2.64k | static bool parseInt(StringRef &input, unsigned &value) { |
41 | 2.64k | assert(value == 0); |
42 | 2.64k | if (input.empty()) return true0 ; |
43 | 2.64k | |
44 | 2.64k | char next = input[0]; |
45 | 2.64k | input = input.substr(1); |
46 | 2.64k | if (next < '0' || next > '9') return true0 ; |
47 | 2.64k | value = (unsigned) (next - '0'); |
48 | 2.64k | |
49 | 4.25k | while (!input.empty()) { |
50 | 3.21k | next = input[0]; |
51 | 3.21k | if (next < '0' || next > '9'1.61k ) return false1.60k ; |
52 | 1.61k | input = input.substr(1); |
53 | 1.61k | value = value * 10 + (unsigned) (next - '0'); |
54 | 1.61k | } |
55 | 2.64k | |
56 | 2.64k | return false1.04k ; |
57 | 2.64k | } |
58 | | |
59 | 1.04k | bool VersionTuple::tryParse(StringRef input) { |
60 | 1.04k | unsigned major = 0, minor = 0, micro = 0, build = 0; |
61 | 1.04k | |
62 | 1.04k | // Parse the major version, [0-9]+ |
63 | 1.04k | if (parseInt(input, major)) return true0 ; |
64 | 1.04k | |
65 | 1.04k | if (input.empty()) { |
66 | 29 | *this = VersionTuple(major); |
67 | 29 | return false; |
68 | 29 | } |
69 | 1.01k | |
70 | 1.01k | // If we're not done, parse the minor version, \.[0-9]+ |
71 | 1.01k | if (input[0] != '.') return true0 ; |
72 | 1.01k | input = input.substr(1); |
73 | 1.01k | if (parseInt(input, minor)) return true0 ; |
74 | 1.01k | |
75 | 1.01k | if (input.empty()) { |
76 | 425 | *this = VersionTuple(major, minor); |
77 | 425 | return false; |
78 | 425 | } |
79 | 587 | |
80 | 587 | // If we're not done, parse the micro version, \.[0-9]+ |
81 | 587 | if (input[0] != '.') return true0 ; |
82 | 587 | input = input.substr(1); |
83 | 587 | if (parseInt(input, micro)) return true0 ; |
84 | 587 | |
85 | 587 | if (input.empty()) { |
86 | 584 | *this = VersionTuple(major, minor, micro); |
87 | 584 | return false; |
88 | 584 | } |
89 | 3 | |
90 | 3 | // If we're not done, parse the micro version, \.[0-9]+ |
91 | 3 | if (input[0] != '.') return true0 ; |
92 | 3 | input = input.substr(1); |
93 | 3 | if (parseInt(input, build)) return true0 ; |
94 | 3 | |
95 | 3 | // If we have characters left over, it's an error. |
96 | 3 | if (!input.empty()) return true0 ; |
97 | 3 | |
98 | 3 | *this = VersionTuple(major, minor, micro, build); |
99 | 3 | return false; |
100 | 3 | } |