10a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor//===- VersionTuple.cpp - Version Number Handling ---------------*- C++ -*-===// 20a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor// 30a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor// The LLVM Compiler Infrastructure 40a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor// 50a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor// This file is distributed under the University of Illinois Open Source 60a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor// License. See LICENSE.TXT for details. 70a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor// 80a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor//===----------------------------------------------------------------------===// 90a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor// 100a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor// This file implements the VersionTuple class, which represents a version in 110a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor// the form major[.minor[.subminor]]. 120a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor// 130a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor//===----------------------------------------------------------------------===// 140a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor#include "clang/Basic/VersionTuple.h" 150a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor#include "llvm/Support/raw_ostream.h" 160a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor 170a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregorusing namespace clang; 180a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor 190a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregorstd::string VersionTuple::getAsString() const { 200a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor std::string Result; 210a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor { 220a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor llvm::raw_string_ostream Out(Result); 230a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor Out << *this; 240a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor } 250a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor return Result; 260a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor} 270a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor 285f9e272e632e951b1efe824cd16acb4d96077930Chris Lattnerraw_ostream& clang::operator<<(raw_ostream &Out, 290a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor const VersionTuple &V) { 300a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor Out << V.getMajor(); 31dc84cd5efdd3430efb22546b4ac656aa0540b210David Blaikie if (Optional<unsigned> Minor = V.getMinor()) 32176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines Out << (V.usesUnderscores() ? '_' : '.') << *Minor; 33dc84cd5efdd3430efb22546b4ac656aa0540b210David Blaikie if (Optional<unsigned> Subminor = V.getSubminor()) 34176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines Out << (V.usesUnderscores() ? '_' : '.') << *Subminor; 353ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar if (Optional<unsigned> Build = V.getBuild()) 363ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar Out << (V.usesUnderscores() ? '_' : '.') << *Build; 370a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor return Out; 380a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor} 39260611a32535c851237926bfcf78869b13c07d5bJohn McCall 40260611a32535c851237926bfcf78869b13c07d5bJohn McCallstatic bool parseInt(StringRef &input, unsigned &value) { 41260611a32535c851237926bfcf78869b13c07d5bJohn McCall assert(value == 0); 42260611a32535c851237926bfcf78869b13c07d5bJohn McCall if (input.empty()) return true; 43260611a32535c851237926bfcf78869b13c07d5bJohn McCall 44260611a32535c851237926bfcf78869b13c07d5bJohn McCall char next = input[0]; 45260611a32535c851237926bfcf78869b13c07d5bJohn McCall input = input.substr(1); 46260611a32535c851237926bfcf78869b13c07d5bJohn McCall if (next < '0' || next > '9') return true; 47260611a32535c851237926bfcf78869b13c07d5bJohn McCall value = (unsigned) (next - '0'); 48260611a32535c851237926bfcf78869b13c07d5bJohn McCall 49260611a32535c851237926bfcf78869b13c07d5bJohn McCall while (!input.empty()) { 50260611a32535c851237926bfcf78869b13c07d5bJohn McCall next = input[0]; 51260611a32535c851237926bfcf78869b13c07d5bJohn McCall if (next < '0' || next > '9') return false; 52260611a32535c851237926bfcf78869b13c07d5bJohn McCall input = input.substr(1); 53260611a32535c851237926bfcf78869b13c07d5bJohn McCall value = value * 10 + (unsigned) (next - '0'); 54260611a32535c851237926bfcf78869b13c07d5bJohn McCall } 55260611a32535c851237926bfcf78869b13c07d5bJohn McCall 56260611a32535c851237926bfcf78869b13c07d5bJohn McCall return false; 57260611a32535c851237926bfcf78869b13c07d5bJohn McCall} 58260611a32535c851237926bfcf78869b13c07d5bJohn McCall 59260611a32535c851237926bfcf78869b13c07d5bJohn McCallbool VersionTuple::tryParse(StringRef input) { 603ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar unsigned major = 0, minor = 0, micro = 0, build = 0; 61260611a32535c851237926bfcf78869b13c07d5bJohn McCall 62260611a32535c851237926bfcf78869b13c07d5bJohn McCall // Parse the major version, [0-9]+ 63260611a32535c851237926bfcf78869b13c07d5bJohn McCall if (parseInt(input, major)) return true; 64260611a32535c851237926bfcf78869b13c07d5bJohn McCall 65260611a32535c851237926bfcf78869b13c07d5bJohn McCall if (input.empty()) { 66260611a32535c851237926bfcf78869b13c07d5bJohn McCall *this = VersionTuple(major); 67260611a32535c851237926bfcf78869b13c07d5bJohn McCall return false; 68260611a32535c851237926bfcf78869b13c07d5bJohn McCall } 69260611a32535c851237926bfcf78869b13c07d5bJohn McCall 70260611a32535c851237926bfcf78869b13c07d5bJohn McCall // If we're not done, parse the minor version, \.[0-9]+ 71260611a32535c851237926bfcf78869b13c07d5bJohn McCall if (input[0] != '.') return true; 72260611a32535c851237926bfcf78869b13c07d5bJohn McCall input = input.substr(1); 73260611a32535c851237926bfcf78869b13c07d5bJohn McCall if (parseInt(input, minor)) return true; 74260611a32535c851237926bfcf78869b13c07d5bJohn McCall 75260611a32535c851237926bfcf78869b13c07d5bJohn McCall if (input.empty()) { 76260611a32535c851237926bfcf78869b13c07d5bJohn McCall *this = VersionTuple(major, minor); 77260611a32535c851237926bfcf78869b13c07d5bJohn McCall return false; 78260611a32535c851237926bfcf78869b13c07d5bJohn McCall } 79260611a32535c851237926bfcf78869b13c07d5bJohn McCall 80260611a32535c851237926bfcf78869b13c07d5bJohn McCall // If we're not done, parse the micro version, \.[0-9]+ 81260611a32535c851237926bfcf78869b13c07d5bJohn McCall if (input[0] != '.') return true; 82260611a32535c851237926bfcf78869b13c07d5bJohn McCall input = input.substr(1); 83260611a32535c851237926bfcf78869b13c07d5bJohn McCall if (parseInt(input, micro)) return true; 84260611a32535c851237926bfcf78869b13c07d5bJohn McCall 853ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar if (input.empty()) { 863ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar *this = VersionTuple(major, minor, micro); 873ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar return false; 883ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar } 893ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar 903ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // If we're not done, parse the micro version, \.[0-9]+ 913ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar if (input[0] != '.') return true; 923ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar input = input.substr(1); 933ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar if (parseInt(input, build)) return true; 943ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar 95260611a32535c851237926bfcf78869b13c07d5bJohn McCall // If we have characters left over, it's an error. 96260611a32535c851237926bfcf78869b13c07d5bJohn McCall if (!input.empty()) return true; 97260611a32535c851237926bfcf78869b13c07d5bJohn McCall 983ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar *this = VersionTuple(major, minor, micro, build); 99260611a32535c851237926bfcf78869b13c07d5bJohn McCall return false; 100260611a32535c851237926bfcf78869b13c07d5bJohn McCall} 101