static const char *if_exists_spec_function (int, const char **);
static const char *if_exists_else_spec_function (int, const char **);
+static const char *replace_outfile_spec_function (int, const char **);
\f
/* The Specs Language
options used to set target flags. Those special target flags settings may
in turn cause preprocessor symbols to be defined specially. */
static const char *cpp_options =
-"%(cpp_unique_options) %1 %{m*} %{std*} %{ansi} %{W*&pedantic*} %{w} %{f*}\
+"%(cpp_unique_options) %1 %{m*} %{std*&ansi} %{W*&pedantic*} %{w} %{f*}\
%{g*:%{!g0:%{!fno-working-directory:-fworking-directory}}} %{O*} %{undef}\
%{save-temps:-fpch-preprocess}";
"%{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}}\
%1 %{!Q:-quiet} -dumpbase %B %{d*} %{m*} %{a*}\
%{c|S:%{o*:-auxbase-strip %*}%{!o*:-auxbase %b}}%{!c:%{!S:-auxbase %b}}\
- %{g*} %{O*} %{W*&pedantic*} %{w} %{std*} %{ansi}\
+ %{g*} %{O*} %{W*&pedantic*} %{w} %{std*&ansi}\
%{v:-version} %{pg:-p} %{p} %{f*} %{undef}\
%{Qn:-fno-ident} %{--help:--help}\
%{--target-help:--target-help}\
and be given a more meaningful error than "file not used since
linking is not done". */
{".m", "#Objective-C", 0, 0, 0}, {".mi", "#Objective-C", 0, 0, 0},
+ {".mm", "#Objective-C++", 0, 0, 0}, {".M", "#Objective-C++", 0, 0, 0},
+ {".mii", "#Objective-C++", 0, 0, 0},
{".cc", "#C++", 0, 0, 0}, {".cxx", "#C++", 0, 0, 0},
{".cpp", "#C++", 0, 0, 0}, {".cp", "#C++", 0, 0, 0},
{".c++", "#C++", 0, 0, 0}, {".C", "#C++", 0, 0, 0},
{"--dependencies", "-M", 0},
{"--dump", "-d", "a"},
{"--dumpbase", "-dumpbase", "a"},
+ {"--encoding", "-fencoding=", "aj"},
{"--entry", "-e", 0},
{"--extra-warnings", "-W", 0},
+ {"--extdirs", "-fextdirs=", "aj"},
{"--for-assembler", "-Wa", "a"},
{"--for-linker", "-Xlinker", "a"},
{"--force-link", "-u", "a"},
else if (strchr (arginfo, '*') != 0)
{
- error ("incomplete `%s' option", option_map[j].name);
+ error ("incomplete '%s' option", option_map[j].name);
break;
}
{
if (i + 1 == argc)
{
- error ("missing argument to `%s' option",
+ error ("missing argument to '%s' option",
option_map[j].name);
break;
}
else if (strchr (arginfo, 'o') == 0)
{
if (arg != 0)
- error ("extraneous argument to `%s' option",
+ error ("extraneous argument to '%s' option",
option_map[j].name);
arg = 0;
}
{
{ "if-exists", if_exists_spec_function },
{ "if-exists-else", if_exists_else_spec_function },
+ { "replace-outfile", replace_outfile_spec_function },
{ 0, 0 }
};
#else
"-lgcc_s%M"
#endif
+#ifdef USE_LIBUNWIND_EXCEPTIONS
+ " -lunwind"
+#endif
,
"-lgcc",
"-lgcc_eh"
int require_machine_suffix, int os_multilib)
{
if (!IS_ABSOLUTE_PATH (prefix))
- abort ();
+ fatal ("system path '%s' is not absolute", prefix);
if (target_system_root)
{
struct command *commands; /* each command buffer with above info. */
- if (processing_spec_function)
- abort ();
+ gcc_assert (!processing_spec_function);
/* Count # of piped commands. */
for (n_commands = 1, i = 0; i < argbuf_index; i++)
int pid;
pid = pwait (commands[i].pid, &status, 0);
- if (pid < 0)
- abort ();
+ gcc_assert (pid >= 0);
#ifdef HAVE_GETRUSAGE
if (report_times)
argv += 2;
}
else
- fatal ("`-%c' option must have argument", opt);
+ fatal ("'-%c' option must have argument", opt);
if (opt == 'V')
new_version = arg;
else
new_argv[0] = new_argv0;
execvp (new_argv0, new_argv);
- fatal ("couldn't run `%s': %s", new_argv0, xstrerror (errno));
+ fatal ("couldn't run '%s': %s", new_argv0, xstrerror (errno));
}
/* Set up the default search paths. If there is no GCC_EXEC_PREFIX,
else if (strcmp (argv[i], "-Xlinker") == 0)
{
if (i + 1 == argc)
- fatal ("argument to `-Xlinker' is missing");
+ fatal ("argument to '-Xlinker' is missing");
n_infiles++;
i++;
else if (strcmp (argv[i], "-Xpreprocessor") == 0)
{
if (i + 1 == argc)
- fatal ("argument to `-Xpreprocessor' is missing");
+ fatal ("argument to '-Xpreprocessor' is missing");
add_preprocessor_option (argv[i+1], strlen (argv[i+1]));
}
else if (strcmp (argv[i], "-Xassembler") == 0)
{
if (i + 1 == argc)
- fatal ("argument to `-Xassembler' is missing");
+ fatal ("argument to '-Xassembler' is missing");
add_assembler_option (argv[i+1], strlen (argv[i+1]));
}
else if (strcmp (argv[i], "-l") == 0)
{
if (i + 1 == argc)
- fatal ("argument to `-l' is missing");
+ fatal ("argument to '-l' is missing");
n_infiles++;
i++;
{
struct user_specs *user = xmalloc (sizeof (struct user_specs));
if (++i >= argc)
- fatal ("argument to `-specs' is missing");
+ fatal ("argument to '-specs' is missing");
user->next = (struct user_specs *) 0;
user->filename = argv[i];
{
struct user_specs *user = xmalloc (sizeof (struct user_specs));
if (strlen (argv[i]) == 7)
- fatal ("argument to `-specs=' is missing");
+ fatal ("argument to '-specs=' is missing");
user->next = (struct user_specs *) 0;
user->filename = argv[i] + 7;
{
case 'b':
case 'V':
- fatal ("`-%c' must come at the start of the command line", c);
+ fatal ("'-%c' must come at the start of the command line", c);
break;
case 'B':
int len;
if (p[1] == 0 && i + 1 == argc)
- fatal ("argument to `-B' is missing");
+ fatal ("argument to '-B' is missing");
if (p[1] == 0)
value = argv[++i];
else
if (c == 'x')
{
if (p[1] == 0 && i + 1 == argc)
- fatal ("argument to `-x' is missing");
+ fatal ("argument to '-x' is missing");
if (p[1] == 0)
spec_lang = argv[++i];
else
n_args = SWITCH_TAKES_ARG (c) - (p[1] != 0);
}
if (i + n_args >= argc)
- fatal ("argument to `-%s' is missing", p);
+ fatal ("argument to '-%s' is missing", p);
switches[n_switches].args
= xmalloc ((n_args + 1) * sizeof(const char *));
while (j < n_args)
}
if (n_infiles == last_language_n_infiles && spec_lang != 0)
- error ("warning: `-x %s' after last input file has no effect", spec_lang);
+ error ("warning: '-x %s' after last input file has no effect", spec_lang);
/* Ensure we only invoke each subprocess once. */
if (target_help_flag || print_help_list)
static int suffixed_basename_length;
static const char *input_basename;
static const char *input_suffix;
+#ifndef HOST_LACKS_INODE_NUMBERS
static struct stat input_stat;
+#endif
static int input_stat_set;
/* The compiler used to process the current input file. */
/* Each switch should start with '-'. */
if (argbuf[i][0] != '-')
- abort ();
+ fatal ("switch '%s' does not start with '-'", argbuf[i]);
sw = &switches[i + first];
sw->part1 = &argbuf[i][1];
switch (c = *p++)
{
case 0:
- fatal ("invalid specification! Bug in cc");
+ fatal ("spec '%s' invalid", spec);
case 'b':
obstack_grow (&obstack, input_basename, basename_length);
p += 2;
/* We don't support extra suffix characters after %O. */
if (*p == '.' || ISALPHA ((unsigned char) *p))
- abort ();
+ fatal ("spec '%s' has invalid '%%0%c'", spec, *p);
if (suffix_length == 0)
suffix = TARGET_OBJECT_SUFFIX;
else
*((char *) temp_filename + temp_filename_length) = '\0';
if (strcmp (temp_filename, input_filename) != 0)
{
+#ifndef HOST_LACKS_INODE_NUMBERS
struct stat st_temp;
/* Note, set_input() resets input_stat_set to 0. */
and we can do the stat for the temp_filename
then the they could still refer to the same
file if st_dev/st_ino's are the same. */
-
if (input_stat_set != 1
|| stat (temp_filename, &st_temp) < 0
|| input_stat.st_dev != st_temp.st_dev
|| input_stat.st_ino != st_temp.st_ino)
+#else
+ /* Just compare canonical pathnames. */
+ char* input_realname = lrealpath (input_filename);
+ char* temp_realname = lrealpath (temp_filename);
+ bool files_differ = strcmp (input_realname, temp_realname);
+ free (input_realname);
+ free (temp_realname);
+ if (files_differ)
+#endif
{
temp_filename = save_string (temp_filename,
temp_filename_length + 1);
int cur_index = argbuf_index;
/* Handle the {...} following the %W. */
if (*p != '{')
- abort ();
+ fatal ("spec '%s' has invalid '%%W%c", spec, *p);
p = handle_braces (p + 1);
if (p == 0)
return -1;
/* Skip past the option value and make a copy. */
if (*p != '{')
- abort ();
+ fatal ("spec '%s' has invalid '%%x%c'", spec, *p);
while (*p++ != '}')
;
string = save_string (p1 + 1, p - p1 - 2);
}
else
/* Catch the case where a spec string contains something like
- '%{foo:%*}'. ie there is no * in the pattern on the left
+ '%{foo:%*}'. i.e. there is no * in the pattern on the left
hand side of the :. */
error ("spec failure: '%%*' has not been initialized by pattern match");
break;
sf = lookup_spec_function (func);
if (sf == NULL)
- fatal ("unknown spec function `%s'", func);
+ fatal ("unknown spec function '%s'", func);
/* Push the spec processing context. */
save_argbuf_index = argbuf_index;
alloc_args ();
if (do_spec_2 (args) < 0)
- fatal ("error in args to spec function `%s'", func);
+ fatal ("error in args to spec function '%s'", func);
/* argbuf_index is an index for the next argument to be inserted, and
so contains the count of the args already inserted. */
{
const char *atom, *end_atom;
const char *d_atom = NULL, *d_end_atom = NULL;
+ const char *orig = p;
bool a_is_suffix;
bool a_is_starred;
do
{
if (a_must_be_last)
- abort ();
+ goto invalid;
/* Scan one "atom" (S in the description above of %{}, possibly
with !, ., or * modifiers). */
p++, a_is_starred = 1;
SKIP_WHITE();
- if (*p == '&' || *p == '}')
+ switch (*p)
{
+ case '&': case '}':
/* Substitute the switch(es) indicated by the current atom. */
ordered_set = true;
if (disjunct_set || n_way_choice || a_is_negated || a_is_suffix
|| atom == end_atom)
- abort ();
+ goto invalid;
mark_matching_switches (atom, end_atom, a_is_starred);
if (*p == '}')
process_marked_switches ();
- }
- else if (*p == '|' || *p == ':')
- {
+ break;
+
+ case '|': case ':':
/* Substitute some text if the current atom appears as a switch
or suffix. */
disjunct_set = true;
if (ordered_set)
- abort ();
+ goto invalid;
if (atom == end_atom)
{
if (!n_way_choice || disj_matched || *p == '|'
|| a_is_negated || a_is_suffix || a_is_starred)
- abort ();
+ goto invalid;
/* An empty term may appear as the last choice of an
N-way choice set; it means "otherwise". */
else
{
if (a_is_suffix && a_is_starred)
- abort ();
+ goto invalid;
if (!a_is_starred)
disj_starred = false;
d_atom = d_end_atom = NULL;
}
}
+ break;
+
+ default:
+ goto invalid;
}
- else
- abort ();
}
while (*p++ != '}');
return p;
-
+
+ invalid:
+ fatal ("braced spec '%s' is invalid at '%c'", orig, *p);
+
#undef SKIP_WHITE
}
else if (*p == '%' && p[1] == '*' && nesting_level == 1)
have_subst = true;
else if (*p == '\0')
- abort ();
+ goto invalid;
p++;
}
end_body--;
if (have_subst && !starred)
- abort ();
+ goto invalid;
if (matched)
{
}
return p;
+
+ invalid:
+ fatal ("braced spec body '%s' is invalid", body);
}
\f
/* Return 0 iff switch number SWITCHNUM is obsoleted by a later switch
for (i = 0; (int) i < n_switches; i++)
if (! switches[i].validated)
- error ("unrecognized option `-%s'", switches[i].part1);
+ error ("unrecognized option '-%s'", switches[i].part1);
/* Obey some of the options. */
{
value = do_spec (input_file_compiler->spec);
infiles[i].preprocessed = true;
- if (have_o_argbuf_index)
- infiles[i].name = argbuf[have_o_argbuf_index];
- else
- abort ();
- infiles[i].incompiler = lookup_compiler (infiles[i].name,
- strlen (infiles[i].name),
- infiles[i].language);
+ if (!have_o_argbuf_index)
+ fatal ("spec '%s' is invalid", input_file_compiler->spec);
+ infiles[i].name = argbuf[have_o_argbuf_index];
+ infiles[i].incompiler
+ = lookup_compiler (infiles[i].name,
+ strlen (infiles[i].name),
+ infiles[i].language);
if (value < 0)
this_file_error = 1;
/* Output an error message and exit. */
void
-fancy_abort (void)
+fancy_abort (const char *file, int line, const char *func)
{
- fatal ("internal gcc abort");
+ fatal ("internal gcc abort in %s, at %s:%d", func, file, line);
}
\f
/* Output an error message and exit. */
while (*q != ' ')
{
if (*q == '\0')
- abort ();
+ {
+ invalid_matches:
+ fatal ("multilib spec '%s' is invalid", multilib_matches);
+ }
q++;
}
matches[i].len = q - matches[i].str;
while (*q != ';' && *q != '\0')
{
if (*q == ' ')
- abort ();
+ goto invalid_matches;
q++;
}
matches[i].rep_len = q - matches[i].replace;
while (*p != ';')
{
if (*p == '\0')
- abort ();
+ {
+ invalid_exclusions:
+ fatal ("multilib exclusions '%s' is invalid",
+ multilib_exclusions);
+ }
if (! ok)
{
while (*p != ' ' && *p != ';')
{
if (*p == '\0')
- abort ();
+ goto invalid_exclusions;
++p;
}
while (*p != ' ')
{
if (*p == '\0')
- abort ();
+ {
+ invalid_select:
+ fatal ("multilib select '%s' is invalid",
+ multilib_select);
+ }
++p;
}
this_path_len = p - this_path;
while (*p != ';')
{
if (*p == '\0')
- abort ();
+ goto invalid_select;
if (! ok)
{
while (*p != ' ' && *p != ';')
{
if (*p == '\0')
- abort ();
+ goto invalid_select;
++p;
}
while (*p != ' ')
{
if (*p == '\0')
- abort ();
+ {
+ invalid_select:
+ fatal ("multilib select '%s' is invalid", multilib_select);
+ }
+
++p;
}
int mp = 0;
if (*e == '\0')
- abort ();
+ {
+ invalid_exclusion:
+ fatal ("multilib exclusion '%s' is invalid",
+ multilib_exclusions);
+ }
if (! m)
{
while (*e != ' ' && *e != ';')
{
if (*e == '\0')
- abort ();
+ goto invalid_exclusion;
++e;
}
int len = e - this_arg;
if (*q == '\0')
- abort ();
+ goto invalid_select;
arg = q;
while (*q != ' ' && *q != ';')
{
if (*q == '\0')
- abort ();
+ goto invalid_select;
++q;
}
- if (! strncmp (arg, this_arg, (len < q - arg) ? q - arg : len) ||
- default_arg (this_arg, e - this_arg))
+ if (! strncmp (arg, this_arg,
+ (len < q - arg) ? q - arg : len)
+ || default_arg (this_arg, e - this_arg))
{
mp = 1;
break;
if (! skip)
{
/* If this is a duplicate, skip it. */
- skip = (last_path != 0 && (unsigned int) (p - this_path) == last_path_len
+ skip = (last_path != 0
+ && (unsigned int) (p - this_path) == last_path_len
&& ! strncmp (last_path, this_path, last_path_len));
last_path = this_path;
const char *arg;
if (*q == '\0')
- abort ();
+ goto invalid_select;
if (*q == '!')
arg = NULL;
while (*q != ' ' && *q != ';')
{
if (*q == '\0')
- abort ();
+ goto invalid_select;
++q;
}
int use_arg;
if (*p == '\0')
- abort ();
+ goto invalid_select;
if (skip)
{
while (*p != ' ' && *p != ';')
{
if (*p == '\0')
- abort ();
+ goto invalid_select;
if (use_arg)
putchar (*p);
++p;
return argv[1];
}
+
+/* replace-outfile built-in spec function.
+ This looks for the first argument in the outfiles array's name and replaces it
+ with the second argument. */
+
+static const char *
+replace_outfile_spec_function (int argc, const char **argv)
+{
+ int i;
+ /* Must have exactly two arguments. */
+ if (argc != 2)
+ abort ();
+
+ for (i = 0; i < n_infiles; i++)
+ {
+ if (outfiles[i] && !strcmp (outfiles[i], argv[0]))
+ outfiles[i] = xstrdup (argv[1]);
+ }
+ return NULL;
+}
+