Skip to content

Commit 276fbde

Browse files
author
Daniel Kroening
committed
added gcc_versiont
1 parent d6bfd40 commit 276fbde

File tree

3 files changed

+158
-0
lines changed

3 files changed

+158
-0
lines changed

src/goto-cc/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ SRC = armcc_cmdline.cpp \
88
cw_mode.cpp \
99
gcc_cmdline.cpp \
1010
gcc_mode.cpp \
11+
gcc_version.cpp \
1112
goto_cc_cmdline.cpp \
1213
goto_cc_languages.cpp \
1314
goto_cc_main.cpp \

src/goto-cc/gcc_version.cpp

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
#include "gcc_version.h"
2+
3+
#include <util/prefix.h>
4+
#include <util/run.h>
5+
#include <util/string2int.h>
6+
#include <util/tempfile.h>
7+
8+
#include <fstream>
9+
10+
void gcc_versiont::get(const std::string &executable)
11+
{
12+
temporary_filet tmp_file_out("goto-gcc.", ".out");
13+
temporary_filet tmp_file_err("goto-gcc.", ".err");
14+
15+
// some variants output stuff on stderr, say Apple LLVM,
16+
// which we silence.
17+
int result = run(
18+
executable, {executable, "--version"}, "", tmp_file_out(), tmp_file_err());
19+
20+
v_major = v_minor = v_micro = 0;
21+
22+
if(result >= 0)
23+
{
24+
std::ifstream in(tmp_file_out());
25+
std::string line;
26+
if(!in.fail() && std::getline(in, line))
27+
{
28+
if(has_prefix(line, "gcc"))
29+
{
30+
flavor = flavort::GCC;
31+
// e.g. gcc-6 (Debian 6.4.0-12) 6.4.0 20180123
32+
// The date is optional. We want 6, 4, 0.
33+
std::size_t cp = line.find(") ");
34+
std::size_t first_dot = line.find('.', cp);
35+
std::size_t second_dot = first_dot == std::string::npos
36+
? first_dot
37+
: line.find('.', first_dot + 1);
38+
39+
if(
40+
cp != std::string::npos && first_dot != std::string::npos &&
41+
second_dot != std::string::npos)
42+
{
43+
v_major = unsafe_string2unsigned(
44+
std::string(line, cp + 2, first_dot - cp - 2));
45+
v_minor = unsafe_string2unsigned(
46+
std::string(line, first_dot + 1, second_dot - first_dot - 1));
47+
v_micro = unsafe_string2unsigned(std::string(line, second_dot + 1));
48+
}
49+
}
50+
else if(has_prefix(line, "bcc"))
51+
{
52+
flavor = flavort::GCC;
53+
// e.g. bcc: version 0.16.17
54+
55+
std::size_t v = line.find("version ");
56+
std::size_t first_dot = line.find('.', v);
57+
std::size_t second_dot = first_dot == std::string::npos
58+
? first_dot
59+
: line.find('.', first_dot + 1);
60+
61+
if(
62+
v != std::string::npos && first_dot != std::string::npos &&
63+
second_dot != std::string::npos)
64+
{
65+
v_major =
66+
unsafe_string2unsigned(std::string(line, v + 8, first_dot - v - 8));
67+
v_minor = unsafe_string2unsigned(
68+
std::string(line, first_dot + 1, second_dot - first_dot - 1));
69+
v_micro = unsafe_string2unsigned(std::string(line, second_dot + 1));
70+
}
71+
}
72+
else if(has_prefix(line, "Apple LLVM") || has_prefix(line, "clang"))
73+
{
74+
flavor = flavort::CLANG;
75+
// e.g. Apple LLVM version 9.1.0 (clang-902.0.39.1)
76+
// e.g. clang version 4.0.1-10 (tags/RELEASE_401/final)
77+
78+
std::size_t v = line.find("version ");
79+
std::size_t first_dot = line.find('.', v);
80+
std::size_t second_dot = first_dot == std::string::npos
81+
? first_dot
82+
: line.find('.', first_dot + 1);
83+
84+
if(
85+
v != std::string::npos && first_dot != std::string::npos &&
86+
second_dot != std::string::npos)
87+
{
88+
v_major =
89+
unsafe_string2unsigned(std::string(line, v + 8, first_dot - v - 8));
90+
v_minor = unsafe_string2unsigned(
91+
std::string(line, first_dot + 1, second_dot - first_dot - 1));
92+
v_micro = unsafe_string2unsigned(std::string(line, second_dot + 1));
93+
}
94+
}
95+
else
96+
flavor = flavort::UNKNOWN;
97+
}
98+
}
99+
else
100+
flavor = flavort::UNKNOWN;
101+
}
102+
103+
bool gcc_versiont::is_at_least(
104+
unsigned _major,
105+
unsigned _minor,
106+
unsigned _micro) const
107+
{
108+
return v_major > _major || (v_major == _major && v_minor > _minor) ||
109+
(v_major == _major && v_minor == _minor && v_micro >= _micro);
110+
}
111+
112+
std::ostream &operator<<(std::ostream &out, const gcc_versiont &v)
113+
{
114+
return out << v.v_major << '.' << v.v_minor << '.' << v.v_micro;
115+
}

src/goto-cc/gcc_version.h

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/*******************************************************************\
2+
3+
Module: gcc version numbering scheme
4+
5+
Author: Daniel Kroening
6+
7+
Date: May 2018
8+
9+
\*******************************************************************/
10+
11+
#ifndef CPROVER_GOTO_CC_GCC_VERSION_H
12+
#define CPROVER_GOTO_CC_GCC_VERSION_H
13+
14+
#include <iosfwd>
15+
#include <string>
16+
17+
class gcc_versiont
18+
{
19+
public:
20+
unsigned v_major, v_minor, v_micro;
21+
22+
void get(const std::string &executable);
23+
24+
bool is_at_least(unsigned v_major, unsigned v_minor = 0, unsigned v_micro = 0)
25+
const;
26+
27+
enum class flavort
28+
{
29+
UNKNOWN,
30+
CLANG,
31+
GCC,
32+
BCC
33+
} flavor;
34+
35+
gcc_versiont() : v_major(0), v_minor(0), v_micro(0), flavor(flavort::UNKNOWN)
36+
{
37+
}
38+
};
39+
40+
std::ostream &operator<<(std::ostream &, const gcc_versiont &);
41+
42+
#endif

0 commit comments

Comments
 (0)