//===- VersionTuple.cpp - Version Number Handling ---------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // // This file implements the VersionTuple class, which represents a version in // the form major[.minor[.subminor]]. // //===----------------------------------------------------------------------===// #include "clang/Basic/VersionTuple.h" #include "llvm/Support/raw_ostream.h" using namespace clang; std::string VersionTuple::getAsString() const { std::string Result; { llvm::raw_string_ostream Out(Result); Out << *this; } return Result; } raw_ostream& clang::operator<<(raw_ostream &Out, const VersionTuple &V) { Out << V.getMajor(); if (Optional<unsigned> Minor = V.getMinor()) Out << (V.usesUnderscores() ? '_' : '.') << *Minor; if (Optional<unsigned> Subminor = V.getSubminor()) Out << (V.usesUnderscores() ? '_' : '.') << *Subminor; if (Optional<unsigned> Build = V.getBuild()) Out << (V.usesUnderscores() ? '_' : '.') << *Build; return Out; } static bool parseInt(StringRef &input, unsigned &value) { assert(value == 0); if (input.empty()) return true; char next = input[0]; input = input.substr(1); if (next < '0' || next > '9') return true; value = (unsigned) (next - '0'); while (!input.empty()) { next = input[0]; if (next < '0' || next > '9') return false; input = input.substr(1); value = value * 10 + (unsigned) (next - '0'); } return false; } bool VersionTuple::tryParse(StringRef input) { unsigned major = 0, minor = 0, micro = 0, build = 0; // Parse the major version, [0-9]+ if (parseInt(input, major)) return true; if (input.empty()) { *this = VersionTuple(major); return false; } // If we're not done, parse the minor version, \.[0-9]+ if (input[0] != '.') return true; input = input.substr(1); if (parseInt(input, minor)) return true; if (input.empty()) { *this = VersionTuple(major, minor); return false; } // If we're not done, parse the micro version, \.[0-9]+ if (input[0] != '.') return true; input = input.substr(1); if (parseInt(input, micro)) return true; if (input.empty()) { *this = VersionTuple(major, minor, micro); return false; } // If we're not done, parse the micro version, \.[0-9]+ if (input[0] != '.') return true; input = input.substr(1); if (parseInt(input, build)) return true; // If we have characters left over, it's an error. if (!input.empty()) return true; *this = VersionTuple(major, minor, micro, build); return false; }