]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/lib/Support/VersionTuple.cpp
MFC r343601:
[FreeBSD/FreeBSD.git] / contrib / llvm / lib / Support / VersionTuple.cpp
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 "llvm/Support/VersionTuple.h"
15 #include "llvm/Support/raw_ostream.h"
16
17 using namespace llvm;
18
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
28 raw_ostream &llvm::operator<<(raw_ostream &Out, const VersionTuple &V) {
29   Out << V.getMajor();
30   if (Optional<unsigned> Minor = V.getMinor())
31     Out << '.' << *Minor;
32   if (Optional<unsigned> Subminor = V.getSubminor())
33     Out << '.' << *Subminor;
34   if (Optional<unsigned> Build = V.getBuild())
35     Out << '.' << *Build;
36   return Out;
37 }
38
39 static bool parseInt(StringRef &input, unsigned &value) {
40   assert(value == 0);
41   if (input.empty())
42     return true;
43
44   char next = input[0];
45   input = input.substr(1);
46   if (next < '0' || next > '9')
47     return true;
48   value = (unsigned)(next - '0');
49
50   while (!input.empty()) {
51     next = input[0];
52     if (next < '0' || next > '9')
53       return false;
54     input = input.substr(1);
55     value = value * 10 + (unsigned)(next - '0');
56   }
57
58   return false;
59 }
60
61 bool VersionTuple::tryParse(StringRef input) {
62   unsigned major = 0, minor = 0, micro = 0, build = 0;
63
64   // Parse the major version, [0-9]+
65   if (parseInt(input, major))
66     return true;
67
68   if (input.empty()) {
69     *this = VersionTuple(major);
70     return false;
71   }
72
73   // If we're not done, parse the minor version, \.[0-9]+
74   if (input[0] != '.')
75     return true;
76   input = input.substr(1);
77   if (parseInt(input, minor))
78     return true;
79
80   if (input.empty()) {
81     *this = VersionTuple(major, minor);
82     return false;
83   }
84
85   // If we're not done, parse the micro version, \.[0-9]+
86   if (input[0] != '.')
87     return true;
88   input = input.substr(1);
89   if (parseInt(input, micro))
90     return true;
91
92   if (input.empty()) {
93     *this = VersionTuple(major, minor, micro);
94     return false;
95   }
96
97   // If we're not done, parse the micro version, \.[0-9]+
98   if (input[0] != '.')
99     return true;
100   input = input.substr(1);
101   if (parseInt(input, build))
102     return true;
103
104   // If we have characters left over, it's an error.
105   if (!input.empty())
106     return true;
107
108   *this = VersionTuple(major, minor, micro, build);
109   return false;
110 }