xref: /minix3/external/bsd/llvm/dist/clang/lib/Basic/VersionTuple.cpp (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
1f4a2713aSLionel Sambuc //===- VersionTuple.cpp - Version Number Handling ---------------*- C++ -*-===//
2f4a2713aSLionel Sambuc //
3f4a2713aSLionel Sambuc //                     The LLVM Compiler Infrastructure
4f4a2713aSLionel Sambuc //
5f4a2713aSLionel Sambuc // This file is distributed under the University of Illinois Open Source
6f4a2713aSLionel Sambuc // License. See LICENSE.TXT for details.
7f4a2713aSLionel Sambuc //
8f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
9f4a2713aSLionel Sambuc //
10f4a2713aSLionel Sambuc // This file implements the VersionTuple class, which represents a version in
11f4a2713aSLionel Sambuc // the form major[.minor[.subminor]].
12f4a2713aSLionel Sambuc //
13f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
14f4a2713aSLionel Sambuc #include "clang/Basic/VersionTuple.h"
15f4a2713aSLionel Sambuc #include "llvm/Support/raw_ostream.h"
16f4a2713aSLionel Sambuc 
17f4a2713aSLionel Sambuc using namespace clang;
18f4a2713aSLionel Sambuc 
getAsString() const19f4a2713aSLionel Sambuc std::string VersionTuple::getAsString() const {
20f4a2713aSLionel Sambuc   std::string Result;
21f4a2713aSLionel Sambuc   {
22f4a2713aSLionel Sambuc     llvm::raw_string_ostream Out(Result);
23f4a2713aSLionel Sambuc     Out << *this;
24f4a2713aSLionel Sambuc   }
25f4a2713aSLionel Sambuc   return Result;
26f4a2713aSLionel Sambuc }
27f4a2713aSLionel Sambuc 
operator <<(raw_ostream & Out,const VersionTuple & V)28f4a2713aSLionel Sambuc raw_ostream& clang::operator<<(raw_ostream &Out,
29f4a2713aSLionel Sambuc                                      const VersionTuple &V) {
30f4a2713aSLionel Sambuc   Out << V.getMajor();
31f4a2713aSLionel Sambuc   if (Optional<unsigned> Minor = V.getMinor())
32*0a6a1f1dSLionel Sambuc     Out << (V.usesUnderscores() ? '_' : '.') << *Minor;
33f4a2713aSLionel Sambuc   if (Optional<unsigned> Subminor = V.getSubminor())
34*0a6a1f1dSLionel Sambuc     Out << (V.usesUnderscores() ? '_' : '.') << *Subminor;
35f4a2713aSLionel Sambuc   return Out;
36f4a2713aSLionel Sambuc }
37f4a2713aSLionel Sambuc 
parseInt(StringRef & input,unsigned & value)38f4a2713aSLionel Sambuc static bool parseInt(StringRef &input, unsigned &value) {
39f4a2713aSLionel Sambuc   assert(value == 0);
40f4a2713aSLionel Sambuc   if (input.empty()) return true;
41f4a2713aSLionel Sambuc 
42f4a2713aSLionel Sambuc   char next = input[0];
43f4a2713aSLionel Sambuc   input = input.substr(1);
44f4a2713aSLionel Sambuc   if (next < '0' || next > '9') return true;
45f4a2713aSLionel Sambuc   value = (unsigned) (next - '0');
46f4a2713aSLionel Sambuc 
47f4a2713aSLionel Sambuc   while (!input.empty()) {
48f4a2713aSLionel Sambuc     next = input[0];
49f4a2713aSLionel Sambuc     if (next < '0' || next > '9') return false;
50f4a2713aSLionel Sambuc     input = input.substr(1);
51f4a2713aSLionel Sambuc     value = value * 10 + (unsigned) (next - '0');
52f4a2713aSLionel Sambuc   }
53f4a2713aSLionel Sambuc 
54f4a2713aSLionel Sambuc   return false;
55f4a2713aSLionel Sambuc }
56f4a2713aSLionel Sambuc 
tryParse(StringRef input)57f4a2713aSLionel Sambuc bool VersionTuple::tryParse(StringRef input) {
58f4a2713aSLionel Sambuc   unsigned major = 0, minor = 0, micro = 0;
59f4a2713aSLionel Sambuc 
60f4a2713aSLionel Sambuc   // Parse the major version, [0-9]+
61f4a2713aSLionel Sambuc   if (parseInt(input, major)) return true;
62f4a2713aSLionel Sambuc 
63f4a2713aSLionel Sambuc   if (input.empty()) {
64f4a2713aSLionel Sambuc     *this = VersionTuple(major);
65f4a2713aSLionel Sambuc     return false;
66f4a2713aSLionel Sambuc   }
67f4a2713aSLionel Sambuc 
68f4a2713aSLionel Sambuc   // If we're not done, parse the minor version, \.[0-9]+
69f4a2713aSLionel Sambuc   if (input[0] != '.') return true;
70f4a2713aSLionel Sambuc   input = input.substr(1);
71f4a2713aSLionel Sambuc   if (parseInt(input, minor)) return true;
72f4a2713aSLionel Sambuc 
73f4a2713aSLionel Sambuc   if (input.empty()) {
74f4a2713aSLionel Sambuc     *this = VersionTuple(major, minor);
75f4a2713aSLionel Sambuc     return false;
76f4a2713aSLionel Sambuc   }
77f4a2713aSLionel Sambuc 
78f4a2713aSLionel Sambuc   // If we're not done, parse the micro version, \.[0-9]+
79f4a2713aSLionel Sambuc   if (input[0] != '.') return true;
80f4a2713aSLionel Sambuc   input = input.substr(1);
81f4a2713aSLionel Sambuc   if (parseInt(input, micro)) return true;
82f4a2713aSLionel Sambuc 
83f4a2713aSLionel Sambuc   // If we have characters left over, it's an error.
84f4a2713aSLionel Sambuc   if (!input.empty()) return true;
85f4a2713aSLionel Sambuc 
86f4a2713aSLionel Sambuc   *this = VersionTuple(major, minor, micro);
87f4a2713aSLionel Sambuc   return false;
88f4a2713aSLionel Sambuc }
89