blob: 3f219bfbedfa9df827a1d2ea6a69a4cd833f1f6c [file] [log] [blame]
Douglas Gregor20b2ebd2011-03-23 00:50:03 +00001//===- 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//===----------------------------------------------------------------------===//
Pavel Labathd8c62902018-06-11 10:28:04 +000014#include "llvm/Support/VersionTuple.h"
Douglas Gregor20b2ebd2011-03-23 00:50:03 +000015#include "llvm/Support/raw_ostream.h"
16
Pavel Labathd8c62902018-06-11 10:28:04 +000017using namespace llvm;
Douglas Gregor20b2ebd2011-03-23 00:50:03 +000018
19std::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
Pavel Labathd8c62902018-06-11 10:28:04 +000028raw_ostream &llvm::operator<<(raw_ostream &Out, const VersionTuple &V) {
Douglas Gregor20b2ebd2011-03-23 00:50:03 +000029 Out << V.getMajor();
David Blaikie05785d12013-02-20 22:23:23 +000030 if (Optional<unsigned> Minor = V.getMinor())
Jan Korous23255692018-05-17 11:51:49 +000031 Out << '.' << *Minor;
David Blaikie05785d12013-02-20 22:23:23 +000032 if (Optional<unsigned> Subminor = V.getSubminor())
Jan Korous23255692018-05-17 11:51:49 +000033 Out << '.' << *Subminor;
David Majnemerc371ff02015-03-22 08:39:22 +000034 if (Optional<unsigned> Build = V.getBuild())
Jan Korous23255692018-05-17 11:51:49 +000035 Out << '.' << *Build;
Douglas Gregor20b2ebd2011-03-23 00:50:03 +000036 return Out;
37}
John McCall5fb5df92012-06-20 06:18:46 +000038
39static bool parseInt(StringRef &input, unsigned &value) {
40 assert(value == 0);
Pavel Labathd8c62902018-06-11 10:28:04 +000041 if (input.empty())
42 return true;
John McCall5fb5df92012-06-20 06:18:46 +000043
44 char next = input[0];
45 input = input.substr(1);
Pavel Labathd8c62902018-06-11 10:28:04 +000046 if (next < '0' || next > '9')
47 return true;
48 value = (unsigned)(next - '0');
John McCall5fb5df92012-06-20 06:18:46 +000049
50 while (!input.empty()) {
51 next = input[0];
Pavel Labathd8c62902018-06-11 10:28:04 +000052 if (next < '0' || next > '9')
53 return false;
John McCall5fb5df92012-06-20 06:18:46 +000054 input = input.substr(1);
Pavel Labathd8c62902018-06-11 10:28:04 +000055 value = value * 10 + (unsigned)(next - '0');
John McCall5fb5df92012-06-20 06:18:46 +000056 }
57
58 return false;
59}
60
61bool VersionTuple::tryParse(StringRef input) {
David Majnemerc371ff02015-03-22 08:39:22 +000062 unsigned major = 0, minor = 0, micro = 0, build = 0;
John McCall5fb5df92012-06-20 06:18:46 +000063
64 // Parse the major version, [0-9]+
Pavel Labathd8c62902018-06-11 10:28:04 +000065 if (parseInt(input, major))
66 return true;
John McCall5fb5df92012-06-20 06:18:46 +000067
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]+
Pavel Labathd8c62902018-06-11 10:28:04 +000074 if (input[0] != '.')
75 return true;
John McCall5fb5df92012-06-20 06:18:46 +000076 input = input.substr(1);
Pavel Labathd8c62902018-06-11 10:28:04 +000077 if (parseInt(input, minor))
78 return true;
John McCall5fb5df92012-06-20 06:18:46 +000079
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]+
Pavel Labathd8c62902018-06-11 10:28:04 +000086 if (input[0] != '.')
87 return true;
John McCall5fb5df92012-06-20 06:18:46 +000088 input = input.substr(1);
Pavel Labathd8c62902018-06-11 10:28:04 +000089 if (parseInt(input, micro))
90 return true;
John McCall5fb5df92012-06-20 06:18:46 +000091
David Majnemerc371ff02015-03-22 08:39:22 +000092 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]+
Pavel Labathd8c62902018-06-11 10:28:04 +000098 if (input[0] != '.')
99 return true;
David Majnemerc371ff02015-03-22 08:39:22 +0000100 input = input.substr(1);
Pavel Labathd8c62902018-06-11 10:28:04 +0000101 if (parseInt(input, build))
102 return true;
David Majnemerc371ff02015-03-22 08:39:22 +0000103
John McCall5fb5df92012-06-20 06:18:46 +0000104 // If we have characters left over, it's an error.
Pavel Labathd8c62902018-06-11 10:28:04 +0000105 if (!input.empty())
106 return true;
John McCall5fb5df92012-06-20 06:18:46 +0000107
David Majnemerc371ff02015-03-22 08:39:22 +0000108 *this = VersionTuple(major, minor, micro, build);
John McCall5fb5df92012-06-20 06:18:46 +0000109 return false;
110}