Home | History | Annotate | Download | only in Basic
      1 //===- 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 //===----------------------------------------------------------------------===//
     14 #include "clang/Basic/VersionTuple.h"
     15 #include "llvm/Support/raw_ostream.h"
     16 
     17 using namespace clang;
     18 
     19 std::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 
     28 raw_ostream& clang::operator<<(raw_ostream &Out,
     29                                      const VersionTuple &V) {
     30   Out << V.getMajor();
     31   if (Optional<unsigned> Minor = V.getMinor())
     32     Out << '.' << *Minor;
     33   if (Optional<unsigned> Subminor = V.getSubminor())
     34     Out << '.' << *Subminor;
     35   return Out;
     36 }
     37 
     38 static bool parseInt(StringRef &input, unsigned &value) {
     39   assert(value == 0);
     40   if (input.empty()) return true;
     41 
     42   char next = input[0];
     43   input = input.substr(1);
     44   if (next < '0' || next > '9') return true;
     45   value = (unsigned) (next - '0');
     46 
     47   while (!input.empty()) {
     48     next = input[0];
     49     if (next < '0' || next > '9') return false;
     50     input = input.substr(1);
     51     value = value * 10 + (unsigned) (next - '0');
     52   }
     53 
     54   return false;
     55 }
     56 
     57 bool VersionTuple::tryParse(StringRef input) {
     58   unsigned major = 0, minor = 0, micro = 0;
     59 
     60   // Parse the major version, [0-9]+
     61   if (parseInt(input, major)) return true;
     62 
     63   if (input.empty()) {
     64     *this = VersionTuple(major);
     65     return false;
     66   }
     67 
     68   // If we're not done, parse the minor version, \.[0-9]+
     69   if (input[0] != '.') return true;
     70   input = input.substr(1);
     71   if (parseInt(input, minor)) return true;
     72 
     73   if (input.empty()) {
     74     *this = VersionTuple(major, minor);
     75     return false;
     76   }
     77 
     78   // If we're not done, parse the micro version, \.[0-9]+
     79   if (input[0] != '.') return true;
     80   input = input.substr(1);
     81   if (parseInt(input, micro)) return true;
     82 
     83   // If we have characters left over, it's an error.
     84   if (!input.empty()) return true;
     85 
     86   *this = VersionTuple(major, minor, micro);
     87   return false;
     88 }
     89