5f75654a05a7d1d87fc1b7ce99e408d90cdd47e6
[platform/upstream/ccache.git] / test / test_argument_processing.c
1 /*
2  * Copyright (C) 2010-2013 Joel Rosdahl
3  *
4  * This program is free software; you can redistribute it and/or modify it
5  * under the terms of the GNU General Public License as published by the Free
6  * Software Foundation; either version 3 of the License, or (at your option)
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12  * more details.
13  *
14  * You should have received a copy of the GNU General Public License along with
15  * this program; if not, write to the Free Software Foundation, Inc., 51
16  * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17  */
18
19 /*
20  * This file contains tests for the processing of compiler arguments.
21  */
22
23 #include "ccache.h"
24 #include "conf.h"
25 #include "test/framework.h"
26 #include "test/util.h"
27
28 extern struct conf *conf;
29
30 TEST_SUITE(argument_processing)
31
32 TEST(dash_E_should_result_in_called_for_preprocessing)
33 {
34         struct args *orig = args_init_from_string("cc -c foo.c -E");
35         struct args *preprocessed, *compiler;
36
37         create_file("foo.c", "");
38         CHECK(!cc_process_args(orig, &preprocessed, &compiler));
39         CHECK_INT_EQ(1, stats_get_pending(STATS_PREPROCESSING));
40
41         args_free(orig);
42 }
43
44 TEST(dash_M_should_be_unsupported)
45 {
46         struct args *orig = args_init_from_string("cc -c foo.c -M");
47         struct args *preprocessed, *compiler;
48
49         create_file("foo.c", "");
50         CHECK(!cc_process_args(orig, &preprocessed, &compiler));
51         CHECK_INT_EQ(1, stats_get_pending(STATS_UNSUPPORTED));
52
53         args_free(orig);
54 }
55
56 TEST(dependency_flags_should_only_be_sent_to_the_preprocessor)
57 {
58 #define CMD \
59         "cc -MD -MMD -MP -MF foo.d -MT mt1 -MT mt2 -MQ mq1 -MQ mq2" \
60         " -Wp,-MD,wpmd -Wp,-MMD,wpmmd"
61         struct args *orig = args_init_from_string(CMD " -c foo.c -o foo.o");
62         struct args *exp_cpp = args_init_from_string(CMD);
63 #undef CMD
64         struct args *exp_cc = args_init_from_string("cc -c");
65         struct args *act_cpp = NULL, *act_cc = NULL;
66         create_file("foo.c", "");
67
68         CHECK(cc_process_args(orig, &act_cpp, &act_cc));
69         CHECK_ARGS_EQ_FREE12(exp_cpp, act_cpp);
70         CHECK_ARGS_EQ_FREE12(exp_cc, act_cc);
71
72         args_free(orig);
73 }
74
75 TEST(preprocessor_only_flags_should_only_be_sent_to_the_preprocessor)
76 {
77 #define CMD \
78         "cc -I. -idirafter . -iframework. -imacros . -imultilib ." \
79         " -include test.h -include-pch test.pch -iprefix . -iquote ." \
80         " -isysroot . -isystem . -iwithprefix . -iwithprefixbefore ." \
81         " -DTEST_MACRO -DTEST_MACRO2=1 -F. -trigraphs -fworking-directory" \
82         " -fno-working-directory -MD -MMD -MP -MF foo.d -MT mt1 -MT mt2 " \
83         " -MQ mq1 -MQ mq2 -Wp,-MD,wpmd -Wp,-MMD,wpmmd"
84         struct args *orig = args_init_from_string(CMD " -c foo.c -o foo.o");
85         struct args *exp_cpp = args_init_from_string(CMD);
86 #undef CMD
87         struct args *exp_cc = args_init_from_string("cc -c");
88         struct args *act_cpp = NULL, *act_cc = NULL;
89         create_file("foo.c", "");
90
91         CHECK(cc_process_args(orig, &act_cpp, &act_cc));
92         CHECK_ARGS_EQ_FREE12(exp_cpp, act_cpp);
93         CHECK_ARGS_EQ_FREE12(exp_cc, act_cc);
94
95         args_free(orig);
96 }
97
98 TEST(dependency_flags_that_take_an_argument_should_not_require_space_delimiter)
99 {
100         struct args *orig = args_init_from_string(
101           "cc -c -MMD -MFfoo.d -MT mt -MTmt -MQmq foo.c -o foo.o");
102         struct args *exp_cpp = args_init_from_string(
103           "cc -MMD -MFfoo.d -MT mt -MTmt -MQmq");
104         struct args *exp_cc = args_init_from_string("cc -c");
105         struct args *act_cpp = NULL, *act_cc = NULL;
106         create_file("foo.c", "");
107
108         CHECK(cc_process_args(orig, &act_cpp, &act_cc));
109         CHECK_ARGS_EQ_FREE12(exp_cpp, act_cpp);
110         CHECK_ARGS_EQ_FREE12(exp_cc, act_cc);
111
112         args_free(orig);
113 }
114
115 TEST(sysroot_should_be_rewritten_if_basedir_is_used)
116 {
117         extern char *current_working_dir;
118         char *arg_string;
119         struct args *orig;
120         struct args *act_cpp = NULL, *act_cc = NULL;
121
122         create_file("foo.c", "");
123         free(conf->base_dir);
124         conf->base_dir = x_strdup("/");
125         current_working_dir = get_cwd();
126         arg_string = format("cc --sysroot=%s/foo -c foo.c", current_working_dir);
127         orig = args_init_from_string(arg_string);
128
129         CHECK(cc_process_args(orig, &act_cpp, &act_cc));
130         CHECK(str_startswith(act_cpp->argv[1], "--sysroot=./foo"));
131
132         args_free(orig);
133         args_free(act_cpp);
134         args_free(act_cc);
135 }
136
137 TEST(MF_flag_with_immediate_argument_should_work_as_last_argument)
138 {
139         struct args *orig = args_init_from_string(
140           "cc -c foo.c -o foo.o -MMD -MT bar -MFfoo.d");
141         struct args *exp_cpp = args_init_from_string(
142           "cc -MMD -MT bar -MFfoo.d");
143         struct args *exp_cc = args_init_from_string("cc -c");
144         struct args *act_cpp = NULL, *act_cc = NULL;
145         create_file("foo.c", "");
146
147         CHECK(cc_process_args(orig, &act_cpp, &act_cc));
148         CHECK_ARGS_EQ_FREE12(exp_cpp, act_cpp);
149         CHECK_ARGS_EQ_FREE12(exp_cc, act_cc);
150
151         args_free(orig);
152 }
153
154 TEST(MT_flag_with_immediate_argument_should_work_as_last_argument)
155 {
156         struct args *orig = args_init_from_string(
157           "cc -c foo.c -o foo.o -MMD -MFfoo.d -MT foo -MTbar");
158         struct args *exp_cpp = args_init_from_string(
159           "cc -MMD -MFfoo.d -MT foo -MTbar");
160         struct args *exp_cc = args_init_from_string("cc -c");
161         struct args *act_cpp = NULL, *act_cc = NULL;
162         create_file("foo.c", "");
163
164         CHECK(cc_process_args(orig, &act_cpp, &act_cc));
165         CHECK_ARGS_EQ_FREE12(exp_cpp, act_cpp);
166         CHECK_ARGS_EQ_FREE12(exp_cc, act_cc);
167
168         args_free(orig);
169 }
170
171 TEST(MQ_flag_with_immediate_argument_should_work_as_last_argument)
172 {
173         struct args *orig = args_init_from_string(
174           "cc -c foo.c -o foo.o -MMD -MFfoo.d -MQ foo -MQbar");
175         struct args *exp_cpp = args_init_from_string(
176           "cc -MMD -MFfoo.d -MQ foo -MQbar");
177         struct args *exp_cc = args_init_from_string("cc -c");
178         struct args *act_cpp = NULL, *act_cc = NULL;
179         create_file("foo.c", "");
180
181         CHECK(cc_process_args(orig, &act_cpp, &act_cc));
182         CHECK_ARGS_EQ_FREE12(exp_cpp, act_cpp);
183         CHECK_ARGS_EQ_FREE12(exp_cc, act_cc);
184
185         args_free(orig);
186 }
187
188 TEST(MQ_flag_without_immediate_argument_should_not_add_MQobj)
189 {
190         struct args *orig = args_init_from_string(
191           "gcc -c -MD -MP -MFfoo.d -MQ foo.d foo.c");
192         struct args *exp_cpp = args_init_from_string(
193           "gcc -MD -MP -MFfoo.d -MQ foo.d");
194         struct args *exp_cc = args_init_from_string("gcc -c");
195         struct args *act_cpp = NULL, *act_cc = NULL;
196         create_file("foo.c", "");
197
198         CHECK(cc_process_args(orig, &act_cpp, &act_cc));
199         CHECK_ARGS_EQ_FREE12(exp_cpp, act_cpp);
200         CHECK_ARGS_EQ_FREE12(exp_cc, act_cc);
201
202         args_free(orig);
203 }
204
205 TEST(MT_flag_without_immediate_argument_should_not_add_MTobj)
206 {
207         struct args *orig = args_init_from_string(
208           "gcc -c -MD -MP -MFfoo.d -MT foo.d foo.c");
209         struct args *exp_cpp = args_init_from_string(
210           "gcc -MD -MP -MFfoo.d -MT foo.d");
211         struct args *exp_cc = args_init_from_string("gcc -c");
212         struct args *act_cpp = NULL, *act_cc = NULL;
213         create_file("foo.c", "");
214
215         CHECK(cc_process_args(orig, &act_cpp, &act_cc));
216         CHECK_ARGS_EQ_FREE12(exp_cpp, act_cpp);
217         CHECK_ARGS_EQ_FREE12(exp_cc, act_cc);
218
219         args_free(orig);
220 }
221
222 TEST(MQ_flag_with_immediate_argument_should_not_add_MQobj)
223 {
224         struct args *orig = args_init_from_string(
225           "gcc -c -MD -MP -MFfoo.d -MQfoo.d foo.c");
226         struct args *exp_cpp = args_init_from_string(
227           "gcc -MD -MP -MFfoo.d -MQfoo.d");
228         struct args *exp_cc = args_init_from_string("gcc -c");
229         struct args *act_cpp = NULL, *act_cc = NULL;
230         create_file("foo.c", "");
231
232         CHECK(cc_process_args(orig, &act_cpp, &act_cc));
233         CHECK_ARGS_EQ_FREE12(exp_cpp, act_cpp);
234         CHECK_ARGS_EQ_FREE12(exp_cc, act_cc);
235
236         args_free(orig);
237 }
238
239 TEST(MT_flag_with_immediate_argument_should_not_add_MQobj)
240 {
241         struct args *orig = args_init_from_string(
242           "gcc -c -MD -MP -MFfoo.d -MTfoo.d foo.c");
243         struct args *exp_cpp = args_init_from_string(
244           "gcc -MD -MP -MFfoo.d -MTfoo.d");
245         struct args *exp_cc = args_init_from_string("gcc -c");
246         struct args *act_cpp = NULL, *act_cc = NULL;
247         create_file("foo.c", "");
248
249         CHECK(cc_process_args(orig, &act_cpp, &act_cc));
250         CHECK_ARGS_EQ_FREE12(exp_cpp, act_cpp);
251         CHECK_ARGS_EQ_FREE12(exp_cc, act_cc);
252
253         args_free(orig);
254 }
255
256 TEST(fprofile_flag_with_existing_dir_should_be_rewritten_to_real_path)
257 {
258         struct args *orig = args_init_from_string(
259           "gcc -c -fprofile-generate=some/dir foo.c");
260         struct args *exp_cpp = args_init_from_string("gcc");
261         struct args *exp_cc = args_init_from_string("gcc");
262         struct args *act_cpp = NULL, *act_cc = NULL;
263         char *s;
264
265         create_file("foo.c", "");
266         mkdir("some", 0777);
267         mkdir("some/dir", 0777);
268         s = format("-fprofile-generate=%s", x_realpath("some/dir"));
269         args_add(exp_cpp, s);
270         args_add(exp_cc, s);
271         args_add(exp_cc, "-c");
272         free(s);
273
274         CHECK(cc_process_args(orig, &act_cpp, &act_cc));
275         CHECK_ARGS_EQ_FREE12(exp_cpp, act_cpp);
276         CHECK_ARGS_EQ_FREE12(exp_cc, act_cc);
277
278         args_free(orig);
279 }
280
281 TEST(fprofile_flag_with_nonexisting_dir_not_be_rewritten)
282 {
283         struct args *orig = args_init_from_string(
284           "gcc -c -fprofile-generate=some/dir foo.c");
285         struct args *exp_cpp = args_init_from_string(
286           "gcc -fprofile-generate=some/dir");
287         struct args *exp_cc = args_init_from_string(
288           "gcc -fprofile-generate=some/dir -c");
289         struct args *act_cpp = NULL, *act_cc = NULL;
290
291         create_file("foo.c", "");
292
293         CHECK(cc_process_args(orig, &act_cpp, &act_cc));
294         CHECK_ARGS_EQ_FREE12(exp_cpp, act_cpp);
295         CHECK_ARGS_EQ_FREE12(exp_cc, act_cc);
296
297         args_free(orig);
298 }
299
300 TEST_SUITE_END