]> git.ipfire.org Git - thirdparty/ccache.git/commitdiff
Recognize concatenated form of some long compiler options
authorJoel Rosdahl <joel@rosdahl.net>
Sat, 6 Feb 2016 16:05:24 +0000 (17:05 +0100)
committerJoel Rosdahl <joel@rosdahl.net>
Sat, 6 Feb 2016 16:05:24 +0000 (17:05 +0100)
NEWS.txt
ccache.c
compopt.c
compopt.h
test/test_argument_processing.c

index 28708a6ae38ddf504a61072ec7b9dd3ba5813823..109084067ee5c3cbc9316f510d4a4dc896a61eb9 100644 (file)
--- a/NEWS.txt
+++ b/NEWS.txt
@@ -22,6 +22,9 @@ New features and improvements
   which specifies one or several prefixes to add to the command line ccache
   uses when invoking the preprocessor.
 
+- The concatenated form of some long compiler options is now recognized, for
+  example when using `-isystemPATH` instead of `-isystem PATH`.
+
 
 Bug fixes
 ~~~~~~~~~
index 0620a507c779902d7e639747af60cfe22ee0d609..d7eb87ef5d3dcb44b713fb00c3dc78398c4dac37 100644 (file)
--- a/ccache.c
+++ b/ccache.c
@@ -2512,7 +2512,7 @@ cc_process_args(struct args *args, struct args **preprocessor_args,
                        continue;
                }
 
-               /* Same as above but options with concatenated argument. */
+               /* Same as above but short options with concatenated argument. */
                if (compopt_short(compopt_takes_path, argv[i])) {
                        char *relpath;
                        char *option;
@@ -2530,6 +2530,30 @@ cc_process_args(struct args *args, struct args **preprocessor_args,
                        continue;
                }
 
+               /* Same as above but long options with concatenated argument beginning with
+                * a slash. */
+               if (argv[i][0] == '-') {
+                       char *slash_pos = strchr(argv[i], '/');
+                       if (slash_pos) {
+                               char *option = x_strndup(argv[i], slash_pos - argv[i]);
+                               if (compopt_affects_cpp(option)) {
+                                       if (compopt_takes_concat_arg(option)) {
+                                               char *relpath = make_relative_path(x_strdup(slash_pos));
+                                               args_add(cpp_args, option);
+                                               args_add(cpp_args, relpath);
+                                               free(relpath);
+                                       } else {
+                                               args_add(cpp_args, argv[i]);
+                                       }
+                               } else {
+                                       args_add(stripped_args, argv[i]);
+                               }
+
+                               free(option);
+                               continue;
+                       }
+               }
+
                /* options that take an argument */
                if (compopt_takes_arg(argv[i])) {
                        if (i == argc-1) {
index 87166df4ec2b1f2964dc0bfab6313ca0ad0307ee..4516c51735e365dfcd99eb3f1b8e3a4aeb33ccbd 100644 (file)
--- a/compopt.c
+++ b/compopt.c
@@ -61,26 +61,27 @@ static const struct compopt compopts[] = {
        {"-fplugin=libcc1plugin", TOO_HARD}, /* interaction with GDB */
        {"-frepo",          TOO_HARD},
        {"-fworking-directory", AFFECTS_CPP},
-       {"-idirafter",      AFFECTS_CPP | TAKES_ARG | TAKES_PATH},
+       {"-idirafter",      AFFECTS_CPP | TAKES_ARG | TAKES_CONCAT_ARG | TAKES_PATH},
        {"-iframework",     AFFECTS_CPP | TAKES_ARG | TAKES_CONCAT_ARG | TAKES_PATH},
-       {"-imacros",        AFFECTS_CPP | TAKES_ARG | TAKES_PATH},
-       {"-imultilib",      AFFECTS_CPP | TAKES_ARG | TAKES_PATH},
-       {"-include",        AFFECTS_CPP | TAKES_ARG | TAKES_PATH},
-       {"-include-pch",    AFFECTS_CPP | TAKES_ARG | TAKES_PATH},
+       {"-imacros",        AFFECTS_CPP | TAKES_ARG | TAKES_CONCAT_ARG | TAKES_PATH},
+       {"-imultilib",      AFFECTS_CPP | TAKES_ARG | TAKES_CONCAT_ARG | TAKES_PATH},
+       {"-include",        AFFECTS_CPP | TAKES_ARG | TAKES_CONCAT_ARG | TAKES_PATH},
+       {"-include-pch",    AFFECTS_CPP | TAKES_ARG | TAKES_CONCAT_ARG | TAKES_PATH},
        {"-install_name",   TAKES_ARG}, /* Darwin linker option */
-       {"-iprefix",        AFFECTS_CPP | TAKES_ARG | TAKES_PATH},
-       {"-iquote",         AFFECTS_CPP | TAKES_ARG | TAKES_PATH},
-       {"-isysroot",       AFFECTS_CPP | TAKES_ARG | TAKES_PATH},
-       {"-isystem",        AFFECTS_CPP | TAKES_ARG | TAKES_PATH},
-       {"-iwithprefix",    AFFECTS_CPP | TAKES_ARG | TAKES_PATH},
-       {"-iwithprefixbefore", AFFECTS_CPP | TAKES_ARG | TAKES_PATH},
+       {"-iprefix",        AFFECTS_CPP | TAKES_ARG | TAKES_CONCAT_ARG | TAKES_PATH},
+       {"-iquote",         AFFECTS_CPP | TAKES_ARG | TAKES_CONCAT_ARG | TAKES_PATH},
+       {"-isysroot",       AFFECTS_CPP | TAKES_ARG | TAKES_CONCAT_ARG | TAKES_PATH},
+       {"-isystem",        AFFECTS_CPP | TAKES_ARG | TAKES_CONCAT_ARG | TAKES_PATH},
+       {"-iwithprefix",    AFFECTS_CPP | TAKES_ARG | TAKES_CONCAT_ARG | TAKES_PATH},
+       {"-iwithprefixbefore",
+                           AFFECTS_CPP | TAKES_ARG | TAKES_CONCAT_ARG | TAKES_PATH},
        {"-nostdinc",       AFFECTS_CPP},
        {"-nostdinc++",     AFFECTS_CPP},
        {"-remap",          AFFECTS_CPP},
        {"-save-temps",     TOO_HARD},
        {"-stdlib=",        AFFECTS_CPP | TAKES_CONCAT_ARG},
        {"-trigraphs",      AFFECTS_CPP},
-       {"-u",              TAKES_ARG},
+       {"-u",              TAKES_ARG | TAKES_CONCAT_ARG},
 };
 
 
@@ -182,6 +183,13 @@ compopt_takes_arg(const char *option)
        return co && (co->type & TAKES_ARG);
 }
 
+bool
+compopt_takes_concat_arg(const char *option)
+{
+       const struct compopt *co = find(option);
+       return co && (co->type & TAKES_CONCAT_ARG);
+}
+
 /* Determines if the prefix of the option matches any option and affects the
  * preprocessor.
  */
index 882187dbc06e1c280f8090910f788c01e9bb5a62..109094b66a135352230a461c958789564b4540bb 100644 (file)
--- a/compopt.h
+++ b/compopt.h
@@ -9,6 +9,7 @@ bool compopt_too_hard(const char *option);
 bool compopt_too_hard_for_direct_mode(const char *option);
 bool compopt_takes_path(const char *option);
 bool compopt_takes_arg(const char *option);
+bool compopt_takes_concat_arg(const char *option);
 bool compopt_prefix_affects_cpp(const char *option);
 
 #endif /* CCACHE_COMPOPT_H */
index 0ecefd1b3607decb31ac5aad78bc6578448180f1..20ae65a07d79985718a8174d316528379b4aa09a 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010-2015 Joel Rosdahl
+ * Copyright (C) 2010-2016 Joel Rosdahl
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
@@ -297,4 +297,49 @@ TEST(fprofile_flag_with_nonexisting_dir_should_not_be_rewritten)
        args_free(orig);
 }
 
+TEST(isystem_flag_with_separate_arg_should_be_rewritten_if_basedir_is_used)
+{
+       extern char *current_working_dir;
+       char *arg_string;
+       struct args *orig;
+       struct args *act_cpp = NULL, *act_cc = NULL;
+
+       create_file("foo.c", "");
+       free(conf->base_dir);
+       conf->base_dir = x_strdup("/");
+       current_working_dir = get_cwd();
+       arg_string = format("cc -isystem %s/foo -c foo.c", current_working_dir);
+       orig = args_init_from_string(arg_string);
+
+       CHECK(cc_process_args(orig, &act_cpp, &act_cc));
+       CHECK_STR_EQ("./foo", act_cpp->argv[2]);
+
+       args_free(orig);
+       args_free(act_cpp);
+       args_free(act_cc);
+}
+
+TEST(isystem_flag_with_concat_arg_should_be_rewritten_if_basedir_is_used)
+{
+       extern char *current_working_dir;
+       char *arg_string;
+       struct args *orig;
+       struct args *act_cpp = NULL, *act_cc = NULL;
+
+       create_file("foo.c", "");
+       free(conf->base_dir);
+       conf->base_dir = x_strdup("/");
+       current_working_dir = get_cwd();
+       arg_string = format("cc -isystem%s/foo -c foo.c", current_working_dir);
+       orig = args_init_from_string(arg_string);
+
+       CHECK(cc_process_args(orig, &act_cpp, &act_cc));
+       CHECK_STR_EQ("-isystem", act_cpp->argv[1]);
+       CHECK_STR_EQ("./foo", act_cpp->argv[2]);
+
+       args_free(orig);
+       args_free(act_cpp);
+       args_free(act_cc);
+}
+
 TEST_SUITE_END