GDB (xrefs)
/tmp/gdb-8.1/gdb/producer.c
Go to the documentation of this file.
1 /* Producer string parsers for GDB.
2 
3  Copyright (C) 2012-2018 Free Software Foundation, Inc.
4 
5  This file is part of GDB.
6 
7  This program is free software; you can redistribute it and/or modify
8  it under the terms of the GNU General Public License as published by
9  the Free Software Foundation; either version 3 of the License, or
10  (at your option) any later version.
11 
12  This program is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU General Public License for more details.
16 
17  You should have received a copy of the GNU General Public License
18  along with this program. If not, see <http://www.gnu.org/licenses/>. */
19 
20 #include "defs.h"
21 #include "producer.h"
22 #include "selftest.h"
23 
24 /* See producer.h. */
25 
26 int
27 producer_is_gcc_ge_4 (const char *producer)
28 {
29  int major, minor;
30 
31  if (! producer_is_gcc (producer, &major, &minor))
32  return -1;
33  if (major < 4)
34  return -1;
35  if (major > 4)
36  return INT_MAX;
37  return minor;
38 }
39 
40 /* See producer.h. */
41 
42 int
43 producer_is_gcc (const char *producer, int *major, int *minor)
44 {
45  const char *cs;
46 
47  if (producer != NULL && startswith (producer, "GNU "))
48  {
49  int maj, min;
50 
51  if (major == NULL)
52  major = &maj;
53  if (minor == NULL)
54  minor = &min;
55 
56  /* Skip any identifier after "GNU " - such as "C11" "C++" or "Java".
57  A full producer string might look like:
58  "GNU C 4.7.2"
59  "GNU Fortran 4.8.2 20140120 (Red Hat 4.8.2-16) -mtune=generic ..."
60  "GNU C++14 5.0.0 20150123 (experimental)"
61  */
62  cs = &producer[strlen ("GNU ")];
63  while (*cs && !isspace (*cs))
64  cs++;
65  if (*cs && isspace (*cs))
66  cs++;
67  if (sscanf (cs, "%d.%d", major, minor) == 2)
68  return 1;
69  }
70 
71  /* Not recognized as GCC. */
72  return 0;
73 }
74 
75 
76 /* See producer.h. */
77 
78 bool
79 producer_is_icc (const char *producer, int *major, int *minor)
80 {
81  if (producer == NULL || !startswith (producer, "Intel(R)"))
82  return false;
83 
84  /* Prepare the used fields. */
85  int maj, min;
86  if (major == NULL)
87  major = &maj;
88  if (minor == NULL)
89  minor = &min;
90 
91  *minor = 0;
92  *major = 0;
93 
94  /* Consumes the string till a "Version" is found. */
95  const char *cs = strstr (producer, "Version");
96  if (cs != NULL)
97  {
98  cs = skip_to_space (cs);
99 
100  int intermediate = 0;
101  int nof = sscanf (cs, "%d.%d.%d.%*d", major, &intermediate, minor);
102 
103  /* Internal versions are represented only as MAJOR.MINOR, where
104  minor is usually 0.
105  Public versions have 3 fields as described with the command
106  above. */
107  if (nof == 3)
108  return true;
109 
110  if (nof == 2)
111  {
112  *minor = intermediate;
113  return true;
114  }
115  }
116 
117  static bool warning_printed = false;
118  /* Not recognized as Intel, let the user know. */
119  if (!warning_printed)
120  {
121  warning (_("Could not recognize version of Intel Compiler in: \"%s\""),
122  producer);
123  warning_printed = true;
124  }
125  return false;
126 }
127 
128 #if defined GDB_SELF_TEST
129 namespace selftests {
130 namespace producer {
131 
132 static void
133 producer_parsing_tests ()
134 {
135  {
136  /* Check that we don't crash if "Version" is not found in what
137  looks like an ICC producer string. */
138  static const char icc_no_version[] = "Intel(R) foo bar";
139 
140  int major = 0, minor = 0;
141  SELF_CHECK (!producer_is_icc (icc_no_version, &major, &minor));
142  SELF_CHECK (!producer_is_gcc (icc_no_version, &major, &minor));
143  }
144 
145  {
146  static const char extern_f_14_1[] = "\
147 Intel(R) Fortran Intel(R) 64 Compiler XE for applications running on \
148 Intel(R) 64, \
149 Version 14.0.1.074 Build 20130716";
150 
151  int major = 0, minor = 0;
152  SELF_CHECK (producer_is_icc (extern_f_14_1, &major, &minor)
153  && major == 14 && minor == 1);
154  SELF_CHECK (!producer_is_gcc (extern_f_14_1, &major, &minor));
155  }
156 
157  {
158  static const char intern_f_14[] = "\
159 Intel(R) Fortran Intel(R) 64 Compiler XE for applications running on \
160 Intel(R) 64, \
161 Version 14.0";
162 
163  int major = 0, minor = 0;
164  SELF_CHECK (producer_is_icc (intern_f_14, &major, &minor)
165  && major == 14 && minor == 0);
166  SELF_CHECK (!producer_is_gcc (intern_f_14, &major, &minor));
167  }
168 
169  {
170  static const char intern_c_14[] = "\
171 Intel(R) C++ Intel(R) 64 Compiler XE for applications running on \
172 Intel(R) 64, \
173 Version 14.0";
174  int major = 0, minor = 0;
175  SELF_CHECK (producer_is_icc (intern_c_14, &major, &minor)
176  && major == 14 && minor == 0);
177  SELF_CHECK (!producer_is_gcc (intern_c_14, &major, &minor));
178  }
179 
180  {
181  static const char intern_c_18[] = "\
182 Intel(R) C++ Intel(R) 64 Compiler for applications running on \
183 Intel(R) 64, \
184 Version 18.0 Beta";
185  int major = 0, minor = 0;
186  SELF_CHECK (producer_is_icc (intern_c_18, &major, &minor)
187  && major == 18 && minor == 0);
188  }
189 
190  {
191  static const char gnu[] = "GNU C 4.7.2";
192  SELF_CHECK (!producer_is_icc (gnu, NULL, NULL));
193 
194  int major = 0, minor = 0;
195  SELF_CHECK (producer_is_gcc (gnu, &major, &minor)
196  && major == 4 && minor == 7);
197  }
198 
199  {
200  static const char gnu_exp[] = "GNU C++14 5.0.0 20150123 (experimental)";
201  int major = 0, minor = 0;
202  SELF_CHECK (!producer_is_icc (gnu_exp, NULL, NULL));
203  SELF_CHECK (producer_is_gcc (gnu_exp, &major, &minor)
204  && major == 5 && minor == 0);
205  }
206 }
207 }
208 }
209 #endif
210 
211 void
213 {
214 #if defined GDB_SELF_TEST
216  ("producer-parser", selftests::producer::producer_parsing_tests);
217 #endif
218 }
#define INT_MAX
Definition: defs.h:477
void warning(const char *fmt,...)
Definition: errors.c:26
void _initialize_producer()
Definition: producer.c:212
#define _(String)
Definition: gdb_locale.h:35
static int startswith(const char *string, const char *pattern)
Definition: common-utils.h:107
int producer_is_gcc_ge_4(const char *producer)
Definition: producer.c:27
const char * skip_to_space(const char *chp)
Definition: common-utils.c:361
int producer_is_gcc(const char *producer, int *major, int *minor)
Definition: producer.c:43
bool producer_is_icc(const char *producer, int *major, int *minor)
Definition: producer.c:79
void register_test(const std::string &name, selftest *test)
Definition: selftest.c:52
#define SELF_CHECK(VALUE)
Definition: selftest.h:67