summaryrefslogtreecommitdiff
path: root/rld-cc.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'rld-cc.cpp')
-rw-r--r--rld-cc.cpp181
1 files changed, 181 insertions, 0 deletions
diff --git a/rld-cc.cpp b/rld-cc.cpp
index 56dc6ad..f69b7c9 100644
--- a/rld-cc.cpp
+++ b/rld-cc.cpp
@@ -33,6 +33,10 @@ namespace rld
std::string cflags;
std::string cxxflags;
std::string ldflags;
+ std::string warning_cflags;
+ std::string include_cflags;
+ std::string machine_cflags;
+ std::string spec_cflags;
std::string install_path;
std::string programs_path;
std::string libraries_path;
@@ -89,6 +93,183 @@ namespace rld
args.push_back (ldflags);
}
+ const std::string
+ strip_cflags (const std::string& flags)
+ {
+ std::string oflags;
+ rld::strings flags_;
+ rld::split (flags_, flags);
+
+ for (rld::strings::iterator si = flags_.begin ();
+ si != flags_.end ();
+ ++si)
+ {
+ if (!rld::starts_with ((*si), "-O") && !rld::starts_with ((*si), "-g"))
+ oflags += ' ' + *si;
+ }
+
+ return rld::trim (oflags);
+ }
+
+ const std::string
+ filter_flags (const std::string& flags,
+ const std::string& ,
+ const std::string& ,
+ flag_type type,
+ std::string& warnings,
+ std::string& includes,
+ std::string& machines,
+ std::string& specs)
+ {
+ /*
+ * Defintion of flags to be filtered.
+ */
+ enum flag_group
+ {
+ fg_warning,
+ fg_include,
+ fg_machine,
+ fg_specs
+ };
+ struct flag_def
+ {
+ flag_group group; ///< The group this flag belong to.
+ const char* opt; ///< Option start.
+ int count; ///< Number of arguments with the option.
+ bool path; ///< Is this a path ?
+ int out; ///< If the flag type is set drop the opt..
+ };
+ const flag_def flag_defs[] =
+ {
+ { fg_warning, "-W", 1, false, ft_cppflags | ft_cflags | ft_ldflags },
+ { fg_include, "-I", 2, true, 0 },
+ { fg_include, "-isystem", 2, true, 0 },
+ { fg_include, "-sysroot", 2, true, 0 },
+ { fg_machine, "-O", 1, false, 0 },
+ { fg_machine, "-m", 1, false, 0 },
+ { fg_machine, "-f", 1, false, 0 },
+ { fg_specs, "-q", 1, false, 0 },
+ { fg_specs, "-B", 2, true, 0 },
+ { fg_specs, "--specs", 2, false, 0 }
+ };
+ const int flag_def_size = sizeof (flag_defs) / sizeof (flag_def);
+
+ std::string oflags;
+ rld::strings flags_;
+
+ rld::split (flags_, strip_cflags (flags));
+
+ warnings.clear ();
+ includes.clear ();
+ machines.clear ();
+ specs.clear ();
+
+ for (rld::strings::iterator si = flags_.begin ();
+ si != flags_.end ();
+ ++si)
+ {
+ std::string opts;
+ std::string& opt = *(si);
+ bool in = true;
+
+ for (int fd = 0; fd < flag_def_size; ++fd)
+ {
+ if (rld::starts_with (opt, flag_defs[fd].opt))
+ {
+ int opt_count = flag_defs[fd].count;
+ if (opt_count > 1)
+ {
+ /*
+ * See if the flag is just the option. If is not take one less
+ * because the option's argument is joined to the option.
+ */
+ if (opt != flag_defs[fd].opt)
+ {
+ opt_count -= 1;
+ /*
+ * @todo Path processing here. Not sure what it is needed for.
+ */
+ }
+ }
+ opts += ' ' + opt;
+ while (opt_count > 1)
+ {
+ ++si;
+ /*
+ * @todo Path processing here. Not sure what it is needed for.
+ */
+ opts += ' ' + (*si);
+ --opt_count;
+ }
+ switch (flag_defs[fd].group)
+ {
+ case fg_warning:
+ warnings += ' ' + opts;
+ break;
+ case fg_include:
+ includes += ' ' + opts;
+ break;
+ case fg_machine:
+ machines += ' ' + opts;
+ break;
+ case fg_specs:
+ specs += ' ' + opts;
+ break;
+ default:
+ throw rld::error ("Invalid group", "flag group");
+ }
+ if ((flag_defs[fd].out & type) != 0)
+ in = false;
+ break;
+ }
+ }
+
+ if (in)
+ oflags += ' ' + opts;
+ }
+
+ rld::trim (warnings);
+ rld::trim (includes);
+ rld::trim (machines);
+ rld::trim (specs);
+
+ return rld::trim (oflags);
+ }
+
+ const std::string
+ filter_flags (const std::string& flags,
+ const std::string& arch,
+ const std::string& path,
+ flag_type type)
+ {
+ if (type != ft_cflags)
+ {
+ std::string warnings;
+ std::string includes;
+ std::string machines;
+ std::string specs;
+ return filter_flags (flags,
+ arch,
+ path,
+ type,
+ warnings,
+ includes,
+ machines,
+ specs);
+ }
+ else
+ {
+ return filter_flags (flags,
+ arch,
+ path,
+ type,
+ warning_cflags,
+ include_cflags,
+ machine_cflags,
+ spec_cflags);
+ }
+ }
+
static bool
match_and_trim (const char* prefix, std::string& line, std::string& result)
{