2 * Copyright (C) 2010-2015 Joel Rosdahl
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)
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
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
22 #define TOO_HARD (1 << 0)
23 #define TOO_HARD_DIRECT (1 << 1)
24 #define TAKES_ARG (1 << 2)
25 #define TAKES_CONCAT_ARG (1 << 3)
26 #define TAKES_PATH (1 << 4)
27 #define AFFECTS_CPP (1 << 5)
34 static const struct compopt compopts[] = {
35 {"--param", TAKES_ARG},
36 {"--save-temps", TOO_HARD},
37 {"--serialize-diagnostics", TAKES_ARG | TAKES_PATH},
39 {"-D", AFFECTS_CPP | TAKES_ARG | TAKES_CONCAT_ARG},
41 {"-F", AFFECTS_CPP | TAKES_ARG | TAKES_CONCAT_ARG | TAKES_PATH},
43 {"-I", AFFECTS_CPP | TAKES_ARG | TAKES_CONCAT_ARG | TAKES_PATH},
50 {"-U", AFFECTS_CPP | TAKES_ARG | TAKES_CONCAT_ARG},
52 {"-Xassembler", TAKES_ARG},
53 {"-Xclang", TAKES_ARG},
54 {"-Xlinker", TAKES_ARG},
55 {"-Xpreprocessor", AFFECTS_CPP | TOO_HARD_DIRECT | TAKES_ARG},
57 {"-aux-info", TAKES_ARG},
59 {"-fmodules", TOO_HARD},
60 {"-fno-working-directory", AFFECTS_CPP},
61 {"-fplugin=libcc1plugin", TOO_HARD}, /* interaction with GDB */
63 {"-fworking-directory", AFFECTS_CPP},
64 {"-idirafter", AFFECTS_CPP | TAKES_ARG | TAKES_PATH},
65 {"-iframework", AFFECTS_CPP | TAKES_ARG | TAKES_CONCAT_ARG | TAKES_PATH},
66 {"-imacros", AFFECTS_CPP | TAKES_ARG | TAKES_PATH},
67 {"-imultilib", AFFECTS_CPP | TAKES_ARG | TAKES_PATH},
68 {"-include", AFFECTS_CPP | TAKES_ARG | TAKES_PATH},
69 {"-include-pch", AFFECTS_CPP | TAKES_ARG | TAKES_PATH},
70 {"-install_name", TAKES_ARG}, /* Darwin linker option */
71 {"-iprefix", AFFECTS_CPP | TAKES_ARG | TAKES_PATH},
72 {"-iquote", AFFECTS_CPP | TAKES_ARG | TAKES_PATH},
73 {"-isysroot", AFFECTS_CPP | TAKES_ARG | TAKES_PATH},
74 {"-isystem", AFFECTS_CPP | TAKES_ARG | TAKES_PATH},
75 {"-iwithprefix", AFFECTS_CPP | TAKES_ARG | TAKES_PATH},
76 {"-iwithprefixbefore", AFFECTS_CPP | TAKES_ARG | TAKES_PATH},
77 {"-nostdinc", AFFECTS_CPP},
78 {"-nostdinc++", AFFECTS_CPP},
79 {"-remap", AFFECTS_CPP},
80 {"-save-temps", TOO_HARD},
81 {"-trigraphs", AFFECTS_CPP},
87 compare_compopts(const void *key1, const void *key2)
89 const struct compopt *opt1 = (const struct compopt *)key1;
90 const struct compopt *opt2 = (const struct compopt *)key2;
91 return strcmp(opt1->name, opt2->name);
95 compare_prefix_compopts(const void *key1, const void *key2)
97 const struct compopt *opt1 = (const struct compopt *)key1;
98 const struct compopt *opt2 = (const struct compopt *)key2;
99 return strncmp(opt1->name, opt2->name, strlen(opt2->name));
102 static const struct compopt *
103 find(const char *option)
108 &key, compopts, sizeof(compopts) / sizeof(compopts[0]),
109 sizeof(compopts[0]), compare_compopts);
112 static const struct compopt *
113 find_prefix(const char *option)
118 &key, compopts, sizeof(compopts) / sizeof(compopts[0]),
119 sizeof(compopts[0]), compare_prefix_compopts);
122 /* Runs fn on the first two characters of option. */
124 compopt_short(bool (*fn)(const char *), const char *option)
126 char *short_opt = x_strndup(option, 2);
127 bool retval = fn(short_opt);
132 /* For test purposes. */
134 compopt_verify_sortedness(void)
137 for (i = 1; i < sizeof(compopts)/sizeof(compopts[0]); i++) {
138 if (strcmp(compopts[i-1].name, compopts[i].name) >= 0) {
140 "compopt_verify_sortedness: %s >= %s\n",
150 compopt_affects_cpp(const char *option)
152 const struct compopt *co = find(option);
153 return co && (co->type & AFFECTS_CPP);
157 compopt_too_hard(const char *option)
159 const struct compopt *co = find(option);
160 return co && (co->type & TOO_HARD);
164 compopt_too_hard_for_direct_mode(const char *option)
166 const struct compopt *co = find(option);
167 return co && (co->type & TOO_HARD_DIRECT);
171 compopt_takes_path(const char *option)
173 const struct compopt *co = find(option);
174 return co && (co->type & TAKES_PATH);
178 compopt_takes_arg(const char *option)
180 const struct compopt *co = find(option);
181 return co && (co->type & TAKES_ARG);
184 /* Determines if argument takes a concatentated argument by comparing prefixes.
187 compopt_takes_concat_arg(const char *option)
189 const struct compopt *co = find_prefix(option);
190 return co && (co->type & TAKES_CONCAT_ARG);
193 /* Determines if the prefix of the option matches any option and affects the
197 compopt_prefix_affects_cpp(const char *option)
199 /* prefix options have to take concatentated args */
200 const struct compopt *co = find_prefix(option);
201 return co && (co->type & TAKES_CONCAT_ARG) && (co->type & AFFECTS_CPP);