1 // Copyright (C) 2010-2018 Joel Rosdahl
3 // This program is free software; you can redistribute it and/or modify it
4 // under the terms of the GNU General Public License as published by the Free
5 // Software Foundation; either version 3 of the License, or (at your option)
8 // This program is distributed in the hope that it will be useful, but WITHOUT
9 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 // You should have received a copy of the GNU General Public License along with
14 // this program; if not, write to the Free Software Foundation, Inc., 51
15 // Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 #define TOO_HARD (1 << 0)
21 #define TOO_HARD_DIRECT (1 << 1)
22 #define TAKES_ARG (1 << 2)
23 #define TAKES_CONCAT_ARG (1 << 3)
24 #define TAKES_PATH (1 << 4)
25 #define AFFECTS_CPP (1 << 5)
32 static const struct compopt compopts[] = {
33 {"--compiler-bindir", AFFECTS_CPP | TAKES_ARG}, // nvcc
34 {"--libdevice-directory", AFFECTS_CPP | TAKES_ARG}, // nvcc
35 {"--output-directory", AFFECTS_CPP | TAKES_ARG}, // nvcc
36 {"--param", TAKES_ARG},
37 {"--save-temps", TOO_HARD},
38 {"--save-temps=cwd", TOO_HARD},
39 {"--save-temps=obj", TOO_HARD},
40 {"--serialize-diagnostics", TAKES_ARG | TAKES_PATH},
42 {"-B", TAKES_ARG | TAKES_CONCAT_ARG | TAKES_PATH},
43 {"-D", AFFECTS_CPP | TAKES_ARG | TAKES_CONCAT_ARG},
45 {"-F", AFFECTS_CPP | TAKES_ARG | TAKES_CONCAT_ARG | TAKES_PATH},
47 {"-I", AFFECTS_CPP | TAKES_ARG | TAKES_CONCAT_ARG | TAKES_PATH},
51 {"-MJ", TAKES_ARG | TOO_HARD},
56 {"-U", AFFECTS_CPP | TAKES_ARG | TAKES_CONCAT_ARG},
58 {"-Xassembler", TAKES_ARG},
59 {"-Xclang", TAKES_ARG},
60 {"-Xlinker", TAKES_ARG},
61 {"-Xpreprocessor", AFFECTS_CPP | TOO_HARD_DIRECT | TAKES_ARG},
63 {"-aux-info", TAKES_ARG},
65 {"-ccbin", AFFECTS_CPP | TAKES_ARG}, // nvcc
66 {"-fmodules", TOO_HARD},
67 {"-fno-working-directory", AFFECTS_CPP},
68 {"-fplugin=libcc1plugin", TOO_HARD}, // interaction with GDB
70 {"-fworking-directory", AFFECTS_CPP},
71 {"-idirafter", AFFECTS_CPP | TAKES_ARG | TAKES_CONCAT_ARG | TAKES_PATH},
72 {"-iframework", AFFECTS_CPP | TAKES_ARG | TAKES_CONCAT_ARG | TAKES_PATH},
73 {"-imacros", AFFECTS_CPP | TAKES_ARG | TAKES_CONCAT_ARG | TAKES_PATH},
74 {"-imultilib", AFFECTS_CPP | TAKES_ARG | TAKES_CONCAT_ARG | TAKES_PATH},
75 {"-include", AFFECTS_CPP | TAKES_ARG | TAKES_CONCAT_ARG | TAKES_PATH},
76 {"-include-pch", AFFECTS_CPP | TAKES_ARG | TAKES_CONCAT_ARG | TAKES_PATH},
77 {"-install_name", TAKES_ARG}, // Darwin linker option
78 {"-iprefix", AFFECTS_CPP | TAKES_ARG | TAKES_CONCAT_ARG | TAKES_PATH},
79 {"-iquote", AFFECTS_CPP | TAKES_ARG | TAKES_CONCAT_ARG | TAKES_PATH},
80 {"-isysroot", AFFECTS_CPP | TAKES_ARG | TAKES_CONCAT_ARG | TAKES_PATH},
81 {"-isystem", AFFECTS_CPP | TAKES_ARG | TAKES_CONCAT_ARG | TAKES_PATH},
82 {"-iwithprefix", AFFECTS_CPP | TAKES_ARG | TAKES_CONCAT_ARG | TAKES_PATH},
83 {"-iwithprefixbefore",
84 AFFECTS_CPP | TAKES_ARG | TAKES_CONCAT_ARG | TAKES_PATH},
85 {"-ldir", AFFECTS_CPP | TAKES_ARG}, // nvcc
86 {"-nostdinc", AFFECTS_CPP},
87 {"-nostdinc++", AFFECTS_CPP},
88 {"-odir", AFFECTS_CPP | TAKES_ARG}, // nvcc
89 {"-remap", AFFECTS_CPP},
90 {"-save-temps", TOO_HARD},
91 {"-save-temps=cwd", TOO_HARD},
92 {"-save-temps=obj", TOO_HARD},
93 {"-stdlib=", AFFECTS_CPP | TAKES_CONCAT_ARG},
94 {"-trigraphs", AFFECTS_CPP},
95 {"-u", TAKES_ARG | TAKES_CONCAT_ARG},
100 compare_compopts(const void *key1, const void *key2)
102 const struct compopt *opt1 = (const struct compopt *)key1;
103 const struct compopt *opt2 = (const struct compopt *)key2;
104 return strcmp(opt1->name, opt2->name);
108 compare_prefix_compopts(const void *key1, const void *key2)
110 const struct compopt *opt1 = (const struct compopt *)key1;
111 const struct compopt *opt2 = (const struct compopt *)key2;
112 return strncmp(opt1->name, opt2->name, strlen(opt2->name));
115 static const struct compopt *
116 find(const char *option)
121 &key, compopts, ARRAY_SIZE(compopts), sizeof(compopts[0]),
125 static const struct compopt *
126 find_prefix(const char *option)
131 &key, compopts, ARRAY_SIZE(compopts), sizeof(compopts[0]),
132 compare_prefix_compopts);
135 // Runs fn on the first two characters of option.
137 compopt_short(bool (*fn)(const char *), const char *option)
139 char *short_opt = x_strndup(option, 2);
140 bool retval = fn(short_opt);
145 // Used by unittest/test_compopt.c.
146 bool compopt_verify_sortedness(void);
148 // For test purposes.
150 compopt_verify_sortedness(void)
152 for (size_t i = 1; i < ARRAY_SIZE(compopts); i++) {
153 if (strcmp(compopts[i-1].name, compopts[i].name) >= 0) {
155 "compopt_verify_sortedness: %s >= %s\n",
165 compopt_affects_cpp(const char *option)
167 const struct compopt *co = find(option);
168 return co && (co->type & AFFECTS_CPP);
172 compopt_too_hard(const char *option)
174 const struct compopt *co = find(option);
175 return co && (co->type & TOO_HARD);
179 compopt_too_hard_for_direct_mode(const char *option)
181 const struct compopt *co = find(option);
182 return co && (co->type & TOO_HARD_DIRECT);
186 compopt_takes_path(const char *option)
188 const struct compopt *co = find(option);
189 return co && (co->type & TAKES_PATH);
193 compopt_takes_arg(const char *option)
195 const struct compopt *co = find(option);
196 return co && (co->type & TAKES_ARG);
200 compopt_takes_concat_arg(const char *option)
202 const struct compopt *co = find(option);
203 return co && (co->type & TAKES_CONCAT_ARG);
206 // Determines if the prefix of the option matches any option and affects the
209 compopt_prefix_affects_cpp(const char *option)
211 // Prefix options have to take concatentated args.
212 const struct compopt *co = find_prefix(option);
213 return co && (co->type & TAKES_CONCAT_ARG) && (co->type & AFFECTS_CPP);