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