clang API Documentation
00001 //===- VersionTuple.cpp - Version Number Handling ---------------*- C++ -*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file implements the VersionTuple class, which represents a version in 00011 // the form major[.minor[.subminor]]. 00012 // 00013 //===----------------------------------------------------------------------===// 00014 #include "clang/Basic/VersionTuple.h" 00015 #include "llvm/Support/raw_ostream.h" 00016 00017 using namespace clang; 00018 00019 std::string VersionTuple::getAsString() const { 00020 std::string Result; 00021 { 00022 llvm::raw_string_ostream Out(Result); 00023 Out << *this; 00024 } 00025 return Result; 00026 } 00027 00028 raw_ostream& clang::operator<<(raw_ostream &Out, 00029 const VersionTuple &V) { 00030 Out << V.getMajor(); 00031 if (Optional<unsigned> Minor = V.getMinor()) 00032 Out << (V.usesUnderscores() ? '_' : '.') << *Minor; 00033 if (Optional<unsigned> Subminor = V.getSubminor()) 00034 Out << (V.usesUnderscores() ? '_' : '.') << *Subminor; 00035 return Out; 00036 } 00037 00038 static bool parseInt(StringRef &input, unsigned &value) { 00039 assert(value == 0); 00040 if (input.empty()) return true; 00041 00042 char next = input[0]; 00043 input = input.substr(1); 00044 if (next < '0' || next > '9') return true; 00045 value = (unsigned) (next - '0'); 00046 00047 while (!input.empty()) { 00048 next = input[0]; 00049 if (next < '0' || next > '9') return false; 00050 input = input.substr(1); 00051 value = value * 10 + (unsigned) (next - '0'); 00052 } 00053 00054 return false; 00055 } 00056 00057 bool VersionTuple::tryParse(StringRef input) { 00058 unsigned major = 0, minor = 0, micro = 0; 00059 00060 // Parse the major version, [0-9]+ 00061 if (parseInt(input, major)) return true; 00062 00063 if (input.empty()) { 00064 *this = VersionTuple(major); 00065 return false; 00066 } 00067 00068 // If we're not done, parse the minor version, \.[0-9]+ 00069 if (input[0] != '.') return true; 00070 input = input.substr(1); 00071 if (parseInt(input, minor)) return true; 00072 00073 if (input.empty()) { 00074 *this = VersionTuple(major, minor); 00075 return false; 00076 } 00077 00078 // If we're not done, parse the micro version, \.[0-9]+ 00079 if (input[0] != '.') return true; 00080 input = input.substr(1); 00081 if (parseInt(input, micro)) return true; 00082 00083 // If we have characters left over, it's an error. 00084 if (!input.empty()) return true; 00085 00086 *this = VersionTuple(major, minor, micro); 00087 return false; 00088 }